NX二次开发实现组件移动并旋转(UFUN、C#版本)

最近在项目中碰到移动并旋转组件的问题,移动和旋转的输入条件是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);
    }
}
作者:快雪
本文版权归作者所有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/kuaixue/p/14139220.html