NX二次开发 创建实体最小包容块

环境:Win7 x64,VS2015,NX12


内容:创建实体最小包容块


实现原理

根据输入对象,创建一个辅助实体,然后遍历实体所有平面上的直线边,

以直线边和面法向创建坐标系,求此坐标系下求到的包容块体积,包容块最小者就是合适的坐标系。


代码

#include <NXOpen/BasePart.hxx>
#include <NXOpen/CartesianCoordinateSystem.hxx>
#include <NXOpen/DisplayableObject.hxx>
#include <NXOpen/Layer_LayerManager.hxx>
#include <NXOpen/ModelingView.hxx>
#include <NXOpen/ModelingViewCollection.hxx>
#include <NXOpen/NXException.hxx>
#include <NXOpen/Part.hxx>
#include <NXOpen/PartCollection.hxx>
#include <NXOpen/Session.hxx>
#include <NXOpen/TaggedObject.hxx>
#include <NXOpen/View.hxx>
#include <NXOpen/WCS.hxx>
#include <NXOpen\NXObject.hxx>
#include <NXOpen\Point.hxx>
#include <NXOpen\PointCollection.hxx>
#include <UF_EVAL.h>
#include <UF_LAYER.h>
#include <UF_MTX.h> 
#include <UF_VEC.h> 
#include <iostream>
#include <string.h>
#include <strstream>
#include <uf.h>
#include <uf_csys.h>
#include <uf_defs.h>
#include <uf_exit.h>
#include <uf_modl.h>
#include <uf_obj.h>
#include <uf_part.h>
#include <uf_trns.h>
#include <uf_ui.h>
using namespace NXOpen;


const double tol = 0.01;
const double maxValue = 99999999.99;

double GetDisTol()
{
    double tol = 0.0001;
    int err_flag = 0;
    UF_MODL_ask_distance_tolerance(&tol);

    return tol;
}

bool SetDisTol(double tol)
{
    int err_flag = -1;
    UF_MODL_set_distance_tolerance(&tol, &err_flag);

    return (err_flag == 0);
}

bool IsZero(double val)
{
    return (fabs(val) < tol);
}

double CalVolume(double lengthWidthHeight[3])
{
    return lengthWidthHeight[0] * lengthWidthHeight[1] * lengthWidthHeight[2];
}

double GetMinVolume(double lengthWidthHeight[3])
{ 
    double stand = 10000.0;
    double vol = CalVolume(lengthWidthHeight);
    if (vol >stand)
    {
        vol /= stand;
    }

    return vol;
}

static int init_proc(UF_UI_selection_p_t select, void *user_data)
{
    //int  errorCode = 0;
    //int  num_triples = 2; 
    //UF_UI_mask_t mask_triples[] = { UF_solid_type,UF_solid_face_subtype,UF_UI_SEL_FEATURE_BODY,UF_face_type,UF_solid_face_subtype,UF_UI_SEL_NOT_A_FEATURE }; //定义选择类型
    //errorCode = UF_UI_set_sel_mask(select, UF_UI_SEL_MASK_CLEAR_AND_ENABLE_SPECIFIC, num_triples, mask_triples);
    int  errorCode = 0;
    int  num_triples = 1;
    UF_UI_mask_t mask_triples[] = { UF_solid_type,UF_solid_face_subtype,UF_UI_SEL_FEATURE_BODY }; //定义选择类型
    errorCode = UF_UI_set_sel_mask(select, UF_UI_SEL_MASK_CLEAR_AND_ENABLE_SPECIFIC, num_triples, mask_triples);

    return  (errorCode == 0);
}

std::vector<tag_t> GetSelectedBodies()
{
    char message[132] = "请选择实体";
    char title[132] = "选择对象";
    int  scope = UF_UI_SEL_SCOPE_WORK_PART;
    int  response;
    int count = 0;
    tag_p_t objects = NULL_TAG;
    double  cursor[3] = { 0,0,0 };
    tag_t view = NULL_TAG;
    UF_UI_select_with_class_dialog(message, title, scope, init_proc, NULL, &response, &count, &objects);

    std::vector<tag_t> selectedBodies;
    for (int i = 0; i < count; ++i)
    {
        selectedBodies.push_back(objects[i]);
    }

    return selectedBodies;
}

tag_t GetWCS()
{
    tag_t csys_id = NULL_TAG;
    UF_CSYS_ask_wcs(&csys_id);

    return csys_id;
}

void AskCsysInfo(tag_t csys_id, double origin[3], double mtx[9])
{
    tag_t matrix_id = NULL_TAG; 
    UF_CSYS_ask_csys_info(csys_id, &matrix_id, origin);
    UF_CSYS_ask_matrix_values(matrix_id, mtx);
}

void GetMaxMinEdge(double edges[3], double &maxEdge, double &minEdge)
{
    std::vector<double> tmpVec;
    for (int i = 0; i < 3; ++i)
    {
        tmpVec.push_back(edges[i]);
    }
    std::sort(tmpVec.begin(), tmpVec.end());

    maxEdge = tmpVec[2];
    minEdge = tmpVec[0];
}

void MapPointFromAcsToCS(double csOrg[3], double csMtx[9], double pnt[3])
{
    UF_VEC3_sub(pnt, csOrg, pnt);
    UF_MTX3_vec_multiply(pnt, csMtx, pnt);
}

void MapPointFromCsToAcs(double csOrg[3], double csMtx[9], double pnt[3])
{
    UF_MTX3_vec_multiply_t(pnt, csMtx, pnt);
    UF_VEC3_add(pnt, csOrg, pnt);
}

bool AskBoundingBox(double inputOri[3], double inputMat[9], std::vector<tag_t> inputObjects, double output_acs_min_corner[3], double output_acs_max_corner[3], double output_wcs_length_width_height[3])
{
    if (inputObjects.empty())
    {
        return false;
    }

    tag_t OriWcs = NULL_TAG;
    UF_CSYS_ask_wcs(&OriWcs);

    Point3d origin(inputOri[0], inputOri[1], inputOri[2]);
    Matrix3x3 matrix(inputMat[0], inputMat[1], inputMat[2],inputMat[3], inputMat[4], inputMat[5], inputMat[6], inputMat[7], inputMat[8]);
    NXOpen::Session *theSession = NXOpen::Session::GetSession();
    Part *workPart = theSession->Parts()->Work();
    workPart->WCS()->SetOriginAndMatrix(origin, matrix);
    tag_t wcsTag = NULL_TAG;
    UF_CSYS_ask_wcs(&wcsTag);

    double objsBoxInWCS[6] = { 0 };
    for (int i = 0; i < inputObjects.size(); ++i)
    {
        double min_corner[3] = { 0 };
        double dir[3][3] = { 0 };
        double dis[3] = { 0 };
        UF_MODL_ask_bounding_box_exact(inputObjects[i], wcsTag, min_corner, dir, dis);
        if (IsZero(fabs(dis[0]) + fabs(dis[1]) + fabs(dis[2])))
        {
            continue;
        }

        double minPoint[3] = { 0 };
        double maxPoint[3] = { 0 };
        minPoint[0] = min_corner[0];
        minPoint[1] = min_corner[1];
        minPoint[2] = min_corner[2];
        maxPoint[0] = min_corner[0] + dir[0][0] * dis[0] + dir[1][0] * dis[1] + dir[2][0] * dis[2];
        maxPoint[1] = min_corner[1] + dir[0][1] * dis[0] + dir[1][1] * dis[1] + dir[2][1] * dis[2];
        maxPoint[2] = min_corner[2] + dir[0][2] * dis[0] + dir[1][2] * dis[1] + dir[2][2] * dis[2];
        MapPointFromAcsToCS(inputOri, inputMat, minPoint);
        MapPointFromAcsToCS(inputOri, inputMat, maxPoint);

        double tmpObjBoxInWCS[6] = { 0 };
        tmpObjBoxInWCS[0] = minPoint[0];
        tmpObjBoxInWCS[1] = minPoint[1];
        tmpObjBoxInWCS[2] = minPoint[2];
        tmpObjBoxInWCS[3] = maxPoint[0];
        tmpObjBoxInWCS[4] = maxPoint[1];
        tmpObjBoxInWCS[5] = maxPoint[2];

        if (i == 0)
        {
            objsBoxInWCS[0] = tmpObjBoxInWCS[0];
            objsBoxInWCS[1] = tmpObjBoxInWCS[1];
            objsBoxInWCS[2] = tmpObjBoxInWCS[2];
            objsBoxInWCS[3] = tmpObjBoxInWCS[3];
            objsBoxInWCS[4] = tmpObjBoxInWCS[4];
            objsBoxInWCS[5] = tmpObjBoxInWCS[5];
        }
        else
        {
            if (objsBoxInWCS[0] > tmpObjBoxInWCS[0])
            {
                objsBoxInWCS[0] = tmpObjBoxInWCS[0];
            }

            if (objsBoxInWCS[0] > tmpObjBoxInWCS[3])
            {
                objsBoxInWCS[0] = tmpObjBoxInWCS[3];
            }

            if (objsBoxInWCS[1] > tmpObjBoxInWCS[1])
            {
                objsBoxInWCS[1] = tmpObjBoxInWCS[1];
            }

            if (objsBoxInWCS[1] > tmpObjBoxInWCS[4])
            {
                objsBoxInWCS[1] = tmpObjBoxInWCS[4];
            }

            if (objsBoxInWCS[2] > tmpObjBoxInWCS[2])
            {
                objsBoxInWCS[2] = tmpObjBoxInWCS[2];
            }

            if (objsBoxInWCS[2] > tmpObjBoxInWCS[5])
            {
                objsBoxInWCS[2] = tmpObjBoxInWCS[5];
            }

            if (objsBoxInWCS[3] < tmpObjBoxInWCS[0])
            {
                objsBoxInWCS[3] = tmpObjBoxInWCS[0];
            }

            if (objsBoxInWCS[3] < tmpObjBoxInWCS[3])
            {
                objsBoxInWCS[3] = tmpObjBoxInWCS[3];
            }

            if (objsBoxInWCS[4] < tmpObjBoxInWCS[1])
            {
                objsBoxInWCS[4] = tmpObjBoxInWCS[1];
            }

            if (objsBoxInWCS[4] < tmpObjBoxInWCS[4])
            {
                objsBoxInWCS[4] = tmpObjBoxInWCS[4];
            }

            if (objsBoxInWCS[5] < tmpObjBoxInWCS[2])
            {
                objsBoxInWCS[5] = tmpObjBoxInWCS[2];
            }

            if (objsBoxInWCS[5] < tmpObjBoxInWCS[5])
            {
                objsBoxInWCS[5] = tmpObjBoxInWCS[5];
            }
        }
    }


    output_wcs_length_width_height[0] = fabs(objsBoxInWCS[3] - objsBoxInWCS[0]);
    output_wcs_length_width_height[1] = fabs(objsBoxInWCS[4] - objsBoxInWCS[1]);
    output_wcs_length_width_height[2] = fabs(objsBoxInWCS[5] - objsBoxInWCS[2]);

    double minPoint[3] = { objsBoxInWCS[0], objsBoxInWCS[1], objsBoxInWCS[2] };
    double maxPoint[3] = { objsBoxInWCS[3], objsBoxInWCS[4], objsBoxInWCS[5] };
    MapPointFromCsToAcs(inputOri, inputMat, minPoint);
    MapPointFromCsToAcs(inputOri, inputMat, maxPoint);

    output_acs_min_corner[0] = minPoint[0];
    output_acs_min_corner[1] = minPoint[1];
    output_acs_min_corner[2] = minPoint[2];

    output_acs_max_corner[0] = maxPoint[0];
    output_acs_max_corner[1] = maxPoint[1];
    output_acs_max_corner[2] = maxPoint[2];

    UF_CSYS_set_wcs(OriWcs);
    return true;
}

std::vector<tag_t> GetBodyFaces(tag_t body)
{
    std::vector<tag_t> faces;

    uf_list_p_t face_list;
    UF_MODL_create_list(&face_list);
    UF_MODL_ask_body_faces(body, &face_list); 
    int count = 0;
    int err = UF_MODL_ask_list_count(face_list, &count);
    for (int i = 0; i < count; ++i)
    {
        tag_t tmpFace = NULL_TAG;
        UF_MODL_ask_list_item(face_list, i, &tmpFace);
        faces.push_back(tmpFace);
    }

    UF_MODL_delete_list(&face_list);
    return faces;
}

std::vector<tag_t> GetFaceEdges(tag_t face)
{
    std::vector<tag_t> edges;

    uf_list_p_t edge_list;
    UF_MODL_create_list(&edge_list);
    UF_MODL_ask_face_edges(face, &edge_list);
    int count = 0;
    int err = UF_MODL_ask_list_count(edge_list, &count);
    for (int i = 0; i < count; ++i)
    {
        tag_t tmpEdge = NULL_TAG;
        UF_MODL_ask_list_item(edge_list, i, &tmpEdge);
        edges.push_back(tmpEdge);
    }

    UF_MODL_delete_list(&edge_list);
    return edges;
}

bool IsPlanarFace(tag_t face)
{
    int type = 0;
    int err = UF_MODL_ask_face_type(face, &type);

    return  (err == 0 && type == UF_MODL_PLANAR_FACE);
}

bool GetFaceNormal(tag_t face, double normal[3])
{
    int type = 0;
    int err = UF_MODL_ask_face_type(face, &type);
    if (err != 0)
    {
        return false;
    }

    double uv_min_max[4] = { 0 };
    UF_MODL_ask_face_uv_minmax(face, uv_min_max); 

    double uvCenter[2] = { 0 };
    uvCenter[0] = (uv_min_max[0] + uv_min_max[1]) / 2;
    uvCenter[1] = (uv_min_max[2] + uv_min_max[3]) / 2;

    double centerPnt[3] = { 0 };
    double u1[3];   
    double v1[3]; 
    double u2[3]; 
    double v2[3]; 
    double radii[2]; 
    UF_MODL_ask_face_props(face, uvCenter, centerPnt, u1, v1, u2, v2, normal, radii);

    return true;
}

bool IsLinearEdge(tag_t edge)
{
    int edge_type = 0;
    int err = UF_MODL_ask_edge_type(edge, &edge_type);
    return (err == 0 && edge_type == UF_MODL_LINEAR_EDGE);
}

bool GetLinearEdgeEndPnt(tag_t edge, double startPnt[3], double endPnt[3])
{
    if (!IsLinearEdge(edge))
    {
        return false;
    }

    double tangent[3] = {0};
    double p_norm[3] = {0};
    double b_norm[3] = {0};
    double torsion = 0;
    double  rad_of_cur = 0;
    UF_MODL_ask_curve_props(edge, 0, startPnt, tangent, p_norm, b_norm, &torsion, &rad_of_cur);
    UF_MODL_ask_curve_props(edge, 1, endPnt, tangent, p_norm, b_norm, &torsion, &rad_of_cur);

    return true;
}

bool GetLinearEdgeMtx(tag_t edge, double faceNormal[3], double mtx[9])
{
    bool res = false;

    double startPnt[3] = { 0 };
    double endPnt[3] = { 0 };
    if (GetLinearEdgeEndPnt(edge, startPnt, endPnt))
    {
        double linearDir[3] = { endPnt[0] - startPnt[0],endPnt[1] - startPnt[1] ,endPnt[2] - startPnt[2] };
        double magnitude = 0.0;
        double unitDir[3] = { 0 };
        UF_VEC3_unitize(linearDir, tol, &magnitude, unitDir);
        int is_parallelar = -1;
        UF_VEC3_is_parallel(unitDir, faceNormal, tol, &is_parallelar);
        if (is_parallelar == 0)
        {
            int err = UF_MTX3_initialize(unitDir,faceNormal,mtx);
            res = (err == 0);
        }
    }

    return res;
}

Matrix3x3 TransArrayToMat(double mtx[9])
{
    return Matrix3x3(mtx[0], mtx[1], mtx[2], mtx[3], mtx[4], mtx[5], mtx[6], mtx[7], mtx[8]);
}

void TransMatToArray(Matrix3x3 mat, double mtx[9])
{
    mtx[0] = mat.Xx;
    mtx[1] = mat.Xy;
    mtx[2] = mat.Xz;

    mtx[3] = mat.Yx;
    mtx[4] = mat.Yy;
    mtx[5] = mat.Yz;

    mtx[6] = mat.Zx;
    mtx[7] = mat.Zy;
    mtx[8] = mat.Zz;
    
}

bool IsMatVecHasMatInParallelOrPerpendicularStyle(std::vector<Matrix3x3> &mats, Matrix3x3 mat)
{
    double compareMatXAxis[3] = { mat.Xx,mat.Xy, mat.Xz };
    double compareMatYAxis[3] = { mat.Yx,mat.Yy, mat.Yz };
    for (int i = 0; i < mats.size(); ++i)
    {
        double tmpMatXAxis[3] = { mats[i].Xx,mats[i].Xy, mats[i].Xz };
        double tmpMatYAxis[3] = { mats[i].Yx,mats[i].Yy, mats[i].Yz };

        int isXXParallel = -1;
        int isYYParallel = -1;
        int isXYParallel = -1;
        int isYXParallel = -1;
        UF_VEC3_is_parallel(tmpMatXAxis, compareMatXAxis, tol, &isXXParallel);
        UF_VEC3_is_parallel(tmpMatYAxis, compareMatYAxis, tol, &isYYParallel);
        UF_VEC3_is_parallel(tmpMatXAxis, compareMatYAxis, tol, &isXYParallel);
        UF_VEC3_is_parallel(tmpMatYAxis, compareMatXAxis, tol, &isYXParallel);

        int isXXPerpendicular = -1;
        int isYYPerpendicular = -1;
        int isXYPerpendicular = -1;
        int isYXPerpendicular = -1;
        UF_VEC3_is_perpendicular(tmpMatXAxis, compareMatXAxis, tol, &isXXPerpendicular);
        UF_VEC3_is_perpendicular(tmpMatYAxis, compareMatYAxis, tol, &isYYPerpendicular);
        UF_VEC3_is_perpendicular(tmpMatXAxis, compareMatYAxis, tol, &isXYPerpendicular);
        UF_VEC3_is_perpendicular(tmpMatYAxis, compareMatXAxis, tol, &isYXPerpendicular);

        if (isXXParallel && isYYParallel)
        {
            return true;
        }

        if (isXYParallel && isYXParallel)
        {
            return true;
        }

        if (isXXParallel && isYYPerpendicular)
        {
            return true;
        }

        if (isXYParallel && isYXPerpendicular)
        {
            return true;
        }

        if (isYYParallel && isXXPerpendicular)
        {
            return true;
        }

        if (isYXParallel && isXYPerpendicular)
        {
            return true;
        }
    }

    return false;
}

bool CreateWrapGeometry(std::vector<tag_t> bodies,double disTol,tag_t &resultBody)
{
    resultBody = NULL_TAG;
    if (bodies.empty())
    {
        return false;
    }
    
    tag_t *objects = new tag_t[sizeof(bodies)];
    memcpy(objects, &bodies[0], bodies.size() * sizeof(tag_t));

    UF_MODL_wrap_geom_t wrap_data;
    wrap_data.close_gap = UF_WRAP_GEOM_CLOSE_NONE;
    wrap_data.dist_tol = disTol;//顶点公差 UG默认2.45 ,越小越精确
    wrap_data.add_offset = "0";
    wrap_data.split_offset = "0";
    wrap_data.num_geoms = bodies.size();
    wrap_data.geometry = objects;
    wrap_data.num_splits = 0;
    wrap_data.splits = NULL_TAG;

    tag_t feature_tag = NULL_TAG;
    int err = UF_MODL_create_wrap_geometry(&wrap_data, &feature_tag); 
    if (err == 0)
    {
        UF_MODL_ask_feat_body(feature_tag, &resultBody);
    }

    return (resultBody != NULL_TAG);
}

tag_t CreateBlock(double inputOri[3], double inputMat[9],double input_acs_min_corner[3], double edges[3])
{
    tag_t OriWcs = NULL_TAG;
    UF_CSYS_ask_wcs(&OriWcs);

    Point3d origin(inputOri[0], inputOri[1], inputOri[2]);
    Matrix3x3 matrix(inputMat[0], inputMat[1], inputMat[2], inputMat[3], inputMat[4], inputMat[5], inputMat[6], inputMat[7], inputMat[8]);
    NXOpen::Session *theSession = NXOpen::Session::GetSession();
    Part *workPart = theSession->Parts()->Work();
    workPart->WCS()->SetOriginAndMatrix(origin, matrix);


    char s1[133], s2[133], s3[133];
    sprintf(s1, "%f", edges[0]);
    sprintf(s2, "%f", edges[1]);
    sprintf(s3, "%f", edges[2]);

    char* edgesStr[3] = { s1, s2, s3 };

    tag_t obj = NULL_TAG;
    UF_MODL_create_block1(UF_NULLSIGN, input_acs_min_corner, edgesStr, &obj);
    UF_MODL_ask_feat_body(obj, &obj);

    UF_CSYS_set_wcs(OriWcs);

    return obj;
}

bool CreateSolidBodyMinBoxBlock(std::vector<tag_t> solidBodies)
{
    if (solidBodies.empty())
    {
        return false;
    }

    tag_t originWcs = GetWCS();
    double orginOrigin[3] = { 0 };
    double originMatrix[9] = { 0 };
    AskCsysInfo(originWcs, orginOrigin, originMatrix);

    std::vector<Matrix3x3> solidBodyCalculatedMats;
    double min_volume = 0;
    double origin[3] = { 0 };
    double matrix[9] = { 0 };
    double min_corner[3] = { 0 };
    double max_corner[3] = { 0 };
    double distances[3] = { 0 };
    tag_t csys = originWcs;
    int standFaceEdgesCount = 3;
    AskCsysInfo(csys, origin, matrix);
    Matrix3x3 mat = TransArrayToMat(matrix);
    solidBodyCalculatedMats.push_back(mat);

    //body init box
    AskBoundingBox(origin,matrix, solidBodies, min_corner, max_corner, distances);
    min_volume = GetMinVolume(distances);
    double minEdgeLen = 0;
    double maxEdgeLen = 0;
    GetMaxMinEdge(distances, maxEdgeLen, minEdgeLen);
    double disTol = minEdgeLen / 120;

    //warp geometry
    tag_t auxBody = NULL_TAG;
    if (!CreateWrapGeometry(solidBodies, disTol, auxBody))
    {
        return false;
    }

    std::vector<tag_t> faces = GetBodyFaces(auxBody);
    for (int i = 0; i < faces.size(); ++i)
    {
        std::vector<tag_t> edges = GetFaceEdges(faces[i]);
        if (edges.size() < standFaceEdgesCount)
        {
            continue;
        }

        double faceNormal[3] = { 0 };
        GetFaceNormal(faces[i], faceNormal);
        for (int j = 0; j < edges.size(); ++j)
        {
            double tmpMtx[9] = { 0 };
            if (GetLinearEdgeMtx(edges[j], faceNormal, tmpMtx))
            {
                Matrix3x3 tmpLinearEdgeMat = TransArrayToMat(tmpMtx);
                if (!IsMatVecHasMatInParallelOrPerpendicularStyle(solidBodyCalculatedMats, tmpLinearEdgeMat))
                {
                    AskBoundingBox(origin, tmpMtx, solidBodies, min_corner, max_corner, distances);
                    double tmpVolume = GetMinVolume(distances);
                    if (!IsZero(tmpVolume) && tmpVolume < min_volume)
                    {
                        min_volume = tmpVolume;
                        solidBodyCalculatedMats.push_back(tmpLinearEdgeMat);
                    }
                }
            }
        }
    }

    //create block
    Matrix3x3 minBoxMat = solidBodyCalculatedMats.back();
    double minBoxMatArray[9] = { 0 };
    TransMatToArray(minBoxMat, minBoxMatArray);
    AskBoundingBox(origin, minBoxMatArray, solidBodies, min_corner, max_corner, distances);
    tag_t block = CreateBlock(origin, minBoxMatArray,min_corner, distances); //坐标点不需要转换,就是用绝对坐标系

    if (auxBody != NULL_TAG)
    {
        UF_OBJ_delete_object(auxBody);
    }
    
    return true;
}

void MinBoxTest()
{
    std::vector<tag_t> selectedBodies = GetSelectedBodies();
    CreateSolidBodyMinBoxBlock(selectedBodies);
}

 

  • 1
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
NX二次开发中,使用FDH(k-DOP)算法创建实体的最小包容盒可以通过以下步骤完成: 1. 获取实体的边界框(bounding box):可以使用NXOpen.UF.BoundingBox.AskBoundingBox函数获取实体的边界框。 2. 将边界框转换为k-DOP表示法:k-DOP是一种基于凸包的多面体表示方法,可以用于快速计算实体的最小包容盒。可以使用NXOpen.UF.Kdop.Create函数将边界框转换为k-DOP表示法。 3. 使用FDH算法计算最小包容盒:FDH算法是一种基于k-DOP表示法的快速包容盒计算方法。可以使用NXOpen.UF.Kdop.Fdh函数计算实体的最小包容盒。 以下是一个示例代码: ``` using System; using NXOpen; using NXOpen.UF; class KdopDemo { static void Main(string[] args) { Tag partTag = Session.GetSession().Parts.Work.Tag; Tag[] bodyTags = GetSelectedBodies(); UFSession ufSession = UFSession.GetUFSession(); foreach (Tag bodyTag in bodyTags) { // 获取实体的边界框 double[] bbox = new double[6]; ufSession.Modl.AskBoundingBox(bodyTag, bbox); // 将边界框转换为k-DOP表示法 int kdopOrder = 8; // 8表示八面体 double[] kdop = new double[kdopOrder * 2]; ufSession.Kdop.Create(kdopOrder, bbox, kdop); // 使用FDH算法计算最小包容盒 double[] mbb = new double[kdopOrder * 2]; int retcode = ufSession.Kdop.Fdh(kdopOrder, kdop, mbb); if (retcode == 0) { // 创建最小包容盒 Tag mbbTag = ufSession.Modl.CreateBox1(partTag, FeatureSigns.Nullsign, mbb); } } } static Tag[] GetSelectedBodies() { Selection sel = Session.GetSession().SelectionManager; sel.SingleObjectPerSelection = true; sel.Scope = Selection.SelectionScope.OnlyVisible; sel.SelectionScope = Selection.SelectionScopeIndivisible.SelectionScopeAnyInAssembly; sel.Clear(); sel.DialogTitle = "Select bodies"; sel.Filters = new Selection.MaskTriple[] { new Selection.MaskTriple(ObjectType.Body, 0, 0) }; sel.EnableMultiple = true; sel.EnableSearch = true; sel.MaxNumberOfPicks = 0; sel.SetSwitchMask((int)(Selection.SelectionAction.ClearAndEnableSpecific)); sel.SetSwitchMask((int)(Selection.SelectionAction.AddToExisting)); sel.SetSwitchMask((int)(Selection.SelectionAction.RemoveFromExisting)); sel.SetSwitchMask((int)(Selection.SelectionAction.InvertExisting)); sel.SetSwitchMask((int)(Selection.SelectionAction.Toggle)); sel.ClearMenu(); sel.UpdateView(); sel.ResetButtonName(); sel.SetButtonName("Done"); sel.SetFilterText("Select bodies"); if (sel.CanSelect()) { sel.StartSelection(); } int count = sel.Count; if (count == 0) { throw new Exception("No bodies selected."); } Tag[] tags = new Tag[count]; for (int i = 0; i < count; ++i) { Tag tag = sel.SelectedTag(i); tags[i] = tag; } return tags; } } ``` 这个代码示例可以让用户选择一个或多个实体,然后计算它们的最小包容盒,并在Part Navigator中创建一个新的最小包容实体。注意,这个代码示例仅仅是用来演示如何使用FDH算法计算最小包容盒,实际应用中可能需要根据具体需求进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值