最近在项目中碰到移动并旋转组件的问题,移动和旋转的输入条件是6个参数,分别是X、Y、Z轴的坐标和角度(6自由度)。例如,组件初始位置在绝对坐标系的(0,0,0)点,当输入[300,300,300,0,90,0],即将组件移动至(300,300,300)点并绕Y轴正向(所谓正向反向,遵守的是右手定则,大拇指指向基准轴方向,四指方向即正向,反之是反向)旋转90度。
总结为函数形式如下:
void RepositionComponent(tag_t instance, double x, double y, double z, double xa, double ya, double za);
研究了好些天,今天终于解决了,代码分享给大家!
#include "stdafx.h" #include <uf_attr.h> #include <uf_modl.h> #include <uf.h> #include <uf_part.h> #include <uf_assem.h> #include <uf_ui_ugopen.h> #include <uf_obj.h> #include <uf_defs.h> #include <uf_mtx.h> #include <uf_vec.h> #include <uf_csys.h> #include <uf_trns.h> void Rotate(tag_t instance, double axis[3], double angle) { int one = 1; int resp = 0; int two = 2; int zero = 0; tag_t csys = NULL_TAG; tag_t mx = NULL_TAG; double instance_origin[3] = {0}; double instance_matrix[9] = {0}; double instance_transform[4][4] = {0}; double rotation[12] = {0}; char part_name[MAX_FSPEC_SIZE+1] = {0}; char refset_name[MAX_ENTITY_NAME_SIZE+1] = {0}; char instance_name[MAX_ENTITY_NAME_SIZE+1] = {0}; UF_ASSEM_ask_component_data(instance, part_name, refset_name,instance_name, instance_origin, instance_matrix, instance_transform); UF_MTX3_ortho_normalize(instance_matrix); UF_CSYS_create_matrix(instance_matrix, &mx); UF_CSYS_create_temp_csys(instance_origin, mx, &csys); uf5945(instance_origin, axis, &angle, rotation, &resp); uf5947(rotation, &csys, &one, &one, &zero, &two, NULL, NULL, &resp); UF_CSYS_ask_csys_info(csys, &mx, instance_origin); UF_CSYS_ask_matrix_values(mx, instance_matrix); UF_ASSEM_reposition_instance(instance, instance_origin,instance_matrix); } void RotateComponent(tag_t instance, double xa, double ya, double za) { double axis_x[3] = {1, 0, 0}; double axis_y[3] = {0, 1, 0}; double axis_z[3] = {0, 0, 1}; Rotate(instance, axis_x, xa); Rotate(instance, axis_y, ya); Rotate(instance, axis_z, za); } void MoveComponent(tag_t instance, double x, double y, double z) { double instance_origin[3] = {0}; double instance_matrix[9] = {0}; double instance_transform[4][4] = {0}; double vec[3] = {x, y, z}; char part_name[MAX_FSPEC_SIZE+1] = {0}; char refset_name[MAX_ENTITY_NAME_SIZE+1] = {0}; char instance_name[MAX_ENTITY_NAME_SIZE+1] = {0}; UF_ASSEM_ask_component_data( instance, part_name, refset_name, instance_name, instance_origin, instance_matrix, instance_transform); UF_ASSEM_reposition_instance(instance, vec, instance_matrix); } void RepositionComponent(tag_t instance, double x, double y, double z, double xa, double ya, double za) { //移动 MoveComponent(instance, x, y, z); //旋转 RotateComponent(instance, xa, ya, za); } int _tmain(int argc, _TCHAR* argv[]) { if (UF_initialize() != 0) { return 0; } tag_t tag = NULL_TAG; UF_PART_load_status_t status; UF_PART_open("E:\test1\_asm1.prt",&tag,&status); if (status.failed) { UF_terminate(); return 0; } tag_t occ = UF_ASSEM_ask_root_part_occ(tag); tag_t *child_part_occs = NULL; int number = UF_ASSEM_ask_part_occ_children(occ, &child_part_occs); for (int i = 0; i < number; ++i) { tag_t instance = UF_ASSEM_ask_inst_of_part_occ(*(child_part_occs + i)); double x = 300; double y = 300; double z = 300; double xa = 0; double ya = 0; double za = 0; //根据6个参数移动模型 //获取当前实例的orgin char part_name[MAX_FSPEC_SIZE+1] = {0}; char refset_name[MAX_ENTITY_NAME_SIZE+1] = {0}; char instance_name[UF_CFI_MAX_FILE_NAME_SIZE] = {0}; double origin[3] = {0}; double csys_matrix[9] = {0}; double transform[4][4] = {0}; UF_ASSEM_ask_component_data(instance, part_name, refset_name, instance_name, origin, csys_matrix, transform ); if (0 == strcmp(instance_name, "_MODEL2")) { ya = 90; //绕y轴正向旋转90度 } //重定位组件 RepositionComponent(instance, x, y, z, xa, ya, za); } UF_free(child_part_occs); UF_PART_save(); UF_terminate(); return 0; }
执行前:
执行后:
PS:我将移动和旋转单独提成了函数,在只需要移动或旋转的情况下,方便调用。
顺便用C#封装成了类RepositionComponent.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using NXOpen; using NXOpen.Utilities; using NXOpen.UF; class RepositionComponent { UFSession theUfSession = null; public RepositionComponent(UFSession _ufSession) { theUfSession = _ufSession; } public void Reposition(Tag component, double x, double y, double z, double xa, double ya, double za) { if ((null == theUfSession) || (NXOpen.Tag.Null == component)) { return; } //移动 MoveComponent(component, x, y, z); //旋转 RotateComponent(component, xa, ya, za); } void MoveComponent(Tag component, double x, double y, double z) { string part_name; string refset_name; string instance_name; double[] origin = new double[3]; double[] csys_matrix = new double[9]; double[,] transform = new double[4, 4]; double[] position = new double[3] { x, y, z }; theUfSession.Assem.AskComponentData(component, out part_name, out refset_name, out instance_name, origin, csys_matrix, transform); theUfSession.Assem.RepositionInstance(component, position, csys_matrix); } void RotateComponent(Tag component, double xa, double ya, double za) { double[] axis_x = new double[3] { 1, 0, 0 }; double[] axis_y = new double[3] { 0, 1, 0 }; double[] axis_z = new double[3] { 0, 0, 1 }; Rotate(component, axis_x, xa); Rotate(component, axis_y, ya); Rotate(component, axis_z, za); } void Rotate(Tag component, double[] axis, double angle) { string part_name; string refset_name; string instance_name; double[] origin = new double[3]; double[] csys_matrix = new double[9]; double[,] transform = new double[4, 4]; theUfSession.Assem.AskComponentData(component, out part_name, out refset_name, out instance_name, origin, csys_matrix, transform); theUfSession.Mtx3.OrthoNormalize(csys_matrix); Tag matrix_id; theUfSession.Csys.CreateMatrix(csys_matrix, out matrix_id); Tag csys_id; theUfSession.Csys.CreateTempCsys(origin, matrix_id, out csys_id); double[] rotation = new double[12]; int resp = 0; theUfSession.Trns.CreateRotationMatrix(origin, axis, ref angle, rotation, out resp); //变换矩阵 Tag[] objects = new Tag[1] { csys_id }; int n_objects = 1; int move_or_copy = 1; int dest_layer = 0; int trace_curves = 2; Tag[] copies = new Tag[1] { 0 }; Tag trace_curve_group = NXOpen.Tag.Null; theUfSession.Trns.TransformObjects(rotation, objects, ref n_objects, ref move_or_copy, ref dest_layer, ref trace_curves, copies, out trace_curve_group, out resp); theUfSession.Csys.AskCsysInfo(csys_id, out matrix_id, origin); theUfSession.Csys.AskMatrixValues(matrix_id, csys_matrix); theUfSession.Assem.RepositionInstance(component, origin, csys_matrix); } }