如何通过SolidWorks API获取MotionStudy各关键帧零件的位姿信息
提取SolidWorks MotionStudy关键帧数据用于Unity动画复现
我之前也遇到过一模一样的需求——要把SolidWorks Motion里的动画搬到Unity里,一开始也觉得API找不到门道,后来折腾出来两个可行的方案,分享给你:
方案1:导出结果文件再解析(快速上手)
这是最省心的方法,不用写太多API代码:
- 打开你的Motion Study,点击结果选项(Results Options),选择要导出的零件的位移、旋转数据,导出成CSV或者XML格式
- 用代码解析这个文件,提取每个时间点对应的位置和旋转值
- 重点注意:SolidWorks是右手坐标系,Unity是左手坐标系,导出后要把Z轴(或者X轴,看你的模型朝向)翻转,同时单位要统一(比如SolidWorks用毫米的话,要转成Unity的米)
给个简单的C#解析CSV示例:
using System.IO; using System.Linq; // 读取导出的Motion结果CSV var allLines = File.ReadAllLines("motion_export.csv"); // 跳过表头行 foreach (var line in allLines.Skip(1)) { var data = line.Split(','); double timestamp = double.Parse(data[0]); string partName = data[1].Trim('"'); // 位置数据(SolidWorks坐标系) double swPosX = double.Parse(data[2]); double swPosY = double.Parse(data[3]); double swPosZ = double.Parse(data[4]); // 旋转数据(弧度) double swRotX = double.Parse(data[5]); double swRotY = double.Parse(data[6]); double swRotZ = double.Parse(data[7]); // 转换为Unity坐标系(示例:翻转Z轴,单位转米) float unityPosX = (float)(swPosX / 1000); float unityPosY = (float)(swPosY / 1000); float unityPosZ = (float)(-swPosZ / 1000); // 弧度转角度,调整旋转轴 float unityRotX = (float)(swRotX * 180 / Math.PI); float unityRotY = (float)(swRotY * 180 / Math.PI); float unityRotZ = (float)(-swRotZ * 180 / Math.PI); // 这里可以把数据存成Unity用的动画曲线或者关键帧数据 }
方案2:直接用SolidWorks API提取(更灵活)
如果需要实时或者批量处理多个模型,用API更合适,之前我踩过的坑是没注意要先运行Motion Study才能获取结果:
- 先拿到MotionStudy对象,然后调用
RunStudy()确保分析完成 - 通过
CreateMotionStudyResults()获取结果对象,然后用GetDisplacement()和GetRotation()获取指定零件在任意时间点的数据
C# API示例:
using SolidWorks.Interop.sldworks; using SolidWorks.Interop.swconst; public void ExtractMotionData(IModelDoc2 swModel) { // 获取第一个Motion Study(根据实际索引调整) IMotionStudy motionStudy = swModel.GetMotionStudy(0); if (motionStudy == null) return; // 先运行Motion分析 motionStudy.RunStudy(); // 获取结果对象 IMotionStudyResults motionResults = motionStudy.CreateMotionStudyResults(); if (motionResults == null) return; // 获取时间范围 double[] timeRange = motionResults.GetTimeRange(); double startTime = timeRange[0]; double endTime = timeRange[1]; double timeStep = 0.05; // 每0.05秒取一个关键帧 // 获取目标零件(这里按名称获取,也可以遍历所有零件) Component2 targetPart = swModel.GetComponentByName("你的零件名称"); if (targetPart == null) return; IModelDoc2 partDoc = targetPart.GetModelDoc(); // 遍历所有时间点 for (double currentTime = startTime; currentTime <= endTime; currentTime += timeStep) { // 获取位移(绝对位置) double[] translation = motionResults.GetDisplacement( partDoc, (int)swMotionDisplacementType_e.swMotionDisplacement_Translation, currentTime ); // 获取欧拉角旋转(弧度) double[] rotation = motionResults.GetRotation( partDoc, (int)swMotionRotationType_e.swMotionRotation_EulerAngles, currentTime ); // 这里处理坐标系转换和单位转换,和方案1逻辑一致 // ... } }
几个关键注意事项
- 坐标系转换:一定要注意左右手系的差异,不然动画会是反向的,建议先导出一个简单零件测试轴的方向
- 零件对象:要确保拿到的是底层的零件文档(
GetModelDoc()),而不是装配体的组件对象,否则API会返回错误数据 - 分析状态:如果Motion Study没运行过,
CreateMotionStudyResults()会返回null,所以必须先调用RunStudy() - 旋转格式:SolidWorks API返回的是弧度,Unity里可以直接转成四元数更稳定,避免欧拉角万向节问题
内容的提问来源于stack exchange,提问作者Max




