测试环境是maya2019 3dmax2021 首先在maya中执行下面的监听脚本,然后在max中选择模型,执行导出脚本,3dmax会先将模型导入d:\tmp\max_to_maya.fbx,maya收到信号后会执行导入脚本导入max_to_maya.fbx

import socket
import threading
import json
import maya.cmds as cmds
import maya.utils

def import_fbx():
    """
    导入FBX文件到Maya场景 - 在主线程中执行
    """
    try:
        import_path = "D:/tmp/max_to_maya.fbx"
        print("准备导入FBX文件: {}".format(import_path))

        # 检查文件是否存在
        import os
        if not os.path.exists(import_path):
            print("文件不存在: {}".format(import_path))
            return False

        # 使用Maya的主线程执行导入
        result = cmds.file(import_path, i=True, type="FBX", ignoreVersion=True,
                           mergeNamespacesOnClash=False, namespace=":")
        print("导入成功: {}".format(result))
        return True

    except Exception as e:
        print("导入失败: {}".format(str(e)))
        import traceback
        traceback.print_exc()
        return False

def handle_client_data(data):
    """
    在主线程中处理客户端数据
    """
    try:
        json_data = json.loads(data.decode('utf-8'))
        print("接收到数据: {}".format(json_data))

        if json_data.get("action") == "import_fbx":
            # 使用Maya的executeInMainThreadWithResult来确保在主线程中执行
            result = maya.utils.executeInMainThreadWithResult(import_fbx)
            print("导入函数执行结果: {}".format(result))

    except Exception as e:
        print("处理数据失败: {}".format(str(e)))
        import traceback
        traceback.print_exc()

def simple_listen():
    """
    监听服务主函数
    """
    # 创建socket服务器
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    # 绑定到指定端口
    HOST = '127.0.0.1'
    PORT = 23456

    try:
        print("绑定到 {}:{}".format(HOST, PORT))
        server_socket.bind((HOST, PORT))
        server_socket.listen(5)  # 增加监听队列
        print("监听服务已启动...")

        while True:
            try:
                print("等待连接...")
                client_socket, address = server_socket.accept()
                print("收到连接:", address)

                # 接收数据
                data = client_socket.recv(4096)
                if data:
                    print("收到数据:", data.decode('utf-8'))

                    # 发送响应
                    client_socket.sendall(b"OK")
                    print("已发送响应")

                    # 在主线程中处理数据
                    maya.utils.executeDeferred(lambda: handle_client_data(data))

                client_socket.close()
                print("连接已关闭")

            except Exception as e:
                print("处理连接时出错:", str(e))
                import traceback
                traceback.print_exc()

    except Exception as e:
        print("绑定失败:", str(e))
    finally:
        try:
            server_socket.close()
            print("服务器已关闭")
        except:
            pass

def start_simple_maya_listener():
    """
    启动Maya监听服务
    """
    # 先停止现有的监听服务
    stop_simple_maya_listener()

    # 在后台线程中启动监听
    global listener_thread
    listener_thread = threading.Thread(target=simple_listen)
    listener_thread.daemon = True
    listener_thread.start()
    print("监听服务已在后台启动")

def stop_simple_maya_listener():
    """
    停止Maya监听服务
    """
    global listener_thread
    if 'listener_thread' in globals() and listener_thread and listener_thread.is_alive():
        # 注意:这里无法直接停止线程,但可以设置标志位
        print("监听服务正在运行中,需要重启请重新调用start_simple_maya_listener()")

# 启动监听服务
start_simple_maya_listener()
# <editor-fold desc="max端">
def send_simple_test():
    """
    简化版发送测试
    """
    

    def export_fbx():
        """
        导出当前选择的模型为FBX文件(适用于3ds Max 2021)
        """
        try:
            # 检查是否有选择的对象
            # 使用3ds Max原生MAXScript命令
            import pymxs
            runtime = pymxs.runtime

            if len(runtime.selection) == 0:
                print("没有选择任何对象")
                return False

            # 设置导出路径
            export_path = "D:/tmp/max_to_maya.fbx"

            # 确保导出目录存在
            import os
            export_dir = os.path.dirname(export_path)
            if not os.path.exists(export_dir):
                os.makedirs(export_dir)

            # 使用3ds Max的FBX导出功能
            # 设置FBX导出参数并导出
            result = runtime.exportFile(
                export_path,
                runtime.name('noPrompt'),
                selectedOnly=True,
                using=runtime.FBXEXP
            )

            if result:
                print("成功导出FBX到: {}".format(export_path))
                return True
            else:
                print("FBX导出失败")
                return False

        except Exception as e:
            print("导出FBX失败:", str(e))
            import traceback
            traceback.print_exc()
            return False


    try:
        import socket
        import json

        # 准备简单测试数据
        data = {
            "action" : "import_fbx",
            "format" : "FBX",
            "file" : "max_to_maya.fbx",
            "folder" : "D:/tmp"
        }

        # 先导出FBX文件
        if not export_fbx():
            print("FBX导出失败,终止发送")
            return

        # 发送到Maya
        HOST = '127.0.0.1'
        PORT = 23456

        print("连接到 {}:{}".format(HOST, PORT))
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            s.connect((HOST, PORT))
            print("连接成功")

            json_data = json.dumps(data)
            print("发送数据:", json_data)
            s.sendall(json_data.encode('utf-8'))

            response = s.recv(1024)
            print("收到响应:", response.decode('utf-8'))

    except Exception as e:
        print("发送失败:", str(e))
        import traceback
        traceback.print_exc()
# 执行简化版测试
send_simple_test()
# </editor-fold>
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐