【UG\NX二次开发】PK 布尔运算 PK_BODY_boolean_2 问题记录

最近想用pk函数,对控件选择的目标体和工具体进行布尔运算PK_BODY_boolean_2。

后来发现pk对于需要布尔运算的对象,需要在同一Parasolid分区才能进行布尔操作

使用PK_BODY_change_partition设置到同一分区时,控件选择的体:UG已有的体会报错:PK_ERROR_entity_not_new。(实体不是),无法设置在同一分区

后来通过PK_ENTITY_copy复制出一个PK对象,才能进行求差,但颜色什么的都丢失了,又要编写重新上色逻辑的话,则偏离了我用pk的初衷(节约时间,快速生成)。

哎,好歹是成功生成了。有没有不需要复制出PK对象,或者颜色不丢失的方法呢?希望大神们给予指点。

cpp文件

#include "pk_bool.hpp"
using namespace NXOpen;
using namespace NXOpen::BlockStyler;

//------------------------------------------------------------------------------
// Initialize static variables
//------------------------------------------------------------------------------
Session *(pk_bool::theSession) = NULL;
UI *(pk_bool::theUI) = NULL;
//------------------------------------------------------------------------------
// Constructor for NX Styler class
//------------------------------------------------------------------------------
/*获取dll完整路径*/
string GetProgramPath()
{
    char filePath[MAX_PATH];
    GetModuleFileNameA(_AtlBaseModule.GetModuleInstance(), filePath, MAX_PATH);
    std::string strDllPath(filePath);
    strDllPath = strDllPath.substr(0, strDllPath.find_last_of("\\") + 1);
    return strDllPath;
}


bool PK_BOOL_Bodies(const PK_BODY_t pk_target_body, const std::vector<PK_BODY_t> pkToolBodys, std::vector<PK_BODY_t>& pkBodys)
{
    pkBodys.clear();
    if (PK_ENTITY_null == pk_target_body)
        return false;
    if (0 == (int)pkToolBodys.size())
        return false;
    int                 i = 0, num = 0;
    PK_boolean_r_t      results;
    PK_TOPOL_track_r_t  tracking;
    PK_BODY_boolean_o_t options;
    PK_BODY_t* pk_tool_bodys = NULL;
    num = (int)pkToolBodys.size();
    pk_tool_bodys = new PK_BODY_t[num];
    for (i = 0; i < num; i++)
    {
        pk_tool_bodys[i] = pkToolBodys[i];
    }
    PK_BODY_boolean_o_m(options);
    options.function = PK_boolean_subtract_c;
    PK_ERROR_code_t pkErr = PK_BODY_boolean_2(pk_target_body, num, pk_tool_bodys, &options, &tracking, &results);
    if (pkErr != PK_ERROR_no_errors)
    {
        char msg[256];
        sprintf(msg, "%d", pkErr);
        uc1601(msg, 1);
    }
    delete[]pk_tool_bodys;
    if (results.n_bodies > 0)
    {
        for (i = 0; i < results.n_bodies; i++)
        {
            pkBodys.push_back(results.bodies[i]);
        }
    }
    PK_TOPOL_track_r_f(&tracking);
    PK_boolean_r_f(&results);
    return true;
}


pk_bool::pk_bool()
{
    try
    {
        // Initialize the NX Open C++ API environment
        pk_bool::theSession = NXOpen::Session::GetSession();
        pk_bool::theUI = UI::GetUI();

        //拼接好dlx的绝对路径
        string dllPath = GetProgramPath();
        theDlxFileName = dllPath.append("pk_bool.dlx").c_str();

        theDialog = pk_bool::theUI->CreateDialog(theDlxFileName);
        // Registration of callback functions
        theDialog->AddApplyHandler(make_callback(this, &pk_bool::apply_cb));
        theDialog->AddOkHandler(make_callback(this, &pk_bool::ok_cb));
        theDialog->AddUpdateHandler(make_callback(this, &pk_bool::update_cb));
        theDialog->AddInitializeHandler(make_callback(this, &pk_bool::initialize_cb));
        theDialog->AddDialogShownHandler(make_callback(this, &pk_bool::dialogShown_cb));
    }
    catch(exception& ex)
    {
        //---- Enter your exception handling code here -----
        throw;
    }
}

//------------------------------------------------------------------------------
// Destructor for NX Styler class
//------------------------------------------------------------------------------
pk_bool::~pk_bool()
{
    if (theDialog != NULL)
    {
        delete theDialog;
        theDialog = NULL;
    }
}
//------------------------------- DIALOG LAUNCHING ---------------------------------
//
//    Before invoking this application one needs to open any part/empty part in NX
//    because of the behavior of the blocks.
//
//    Make sure the dlx file is in one of the following locations:
//        1.) From where NX session is launched
//        2.) $UGII_USER_DIR/application
//        3.) For released applications, using UGII_CUSTOM_DIRECTORY_FILE is highly
//            recommended. This variable is set to a full directory path to a file 
//            containing a list of root directories for all custom applications.
//            e.g., UGII_CUSTOM_DIRECTORY_FILE=$UGII_ROOT_DIR\menus\custom_dirs.dat
//
//    You can create the dialog using one of the following way:
//
//    1. USER EXIT
//
//        1) Create the Shared Library -- Refer "Block UI Styler programmer's guide"
//        2) Invoke the Shared Library through File->Execute->NX Open menu.
//
//------------------------------------------------------------------------------
extern "C" DllExport void  ufusr(char *param, int *retcod, int param_len)
{
    pk_bool *thepk_bool = NULL;
    try
    {
        UF_initialize();
        thepk_bool = new pk_bool();
        // The following method shows the dialog immediately
        thepk_bool->Show();
        UF_terminate();
    }
    catch(exception& ex)
    {
        //---- Enter your exception handling code here -----
        pk_bool::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what());
    }
    if(thepk_bool != NULL)
    {
        delete thepk_bool;
        thepk_bool = NULL;
    }
}

//------------------------------------------------------------------------------
// This method specifies how a shared image is unloaded from memory
// within NX. This method gives you the capability to unload an
// internal NX Open application or user  exit from NX. Specify any
// one of the three constants as a return value to determine the type
// of unload to perform:
//
//
//    Immediately : unload the library as soon as the automation program has completed
//    Explicitly  : unload the library from the "Unload Shared Image" dialog
//    AtTermination : unload the library when the NX session terminates
//
//
// NOTE:  A program which associates NX Open applications with the menubar
// MUST NOT use this option since it will UNLOAD your NX Open application image
// from the menubar.
//------------------------------------------------------------------------------
extern "C" DllExport int ufusr_ask_unload()
{
    //return (int)Session::LibraryUnloadOptionExplicitly;
    return (int)Session::LibraryUnloadOptionImmediately;
    //return (int)Session::LibraryUnloadOptionAtTermination;
}

//------------------------------------------------------------------------------
// Following method cleanup any housekeeping chores that may be needed.
// This method is automatically called by NX.
//------------------------------------------------------------------------------
extern "C" DllExport void ufusr_cleanup(void)
{
    try
    {
        //---- Enter your callback code here -----
    }
    catch(exception& ex)
    {
        //---- Enter your exception handling code here -----
        pk_bool::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what());
    }
}

int pk_bool::Show()
{
    try
    {
        theDialog->Show();
    }
    catch(exception& ex)
    {
        //---- Enter your exception handling code here -----
        pk_bool::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what());
    }
    return 0;
}

//------------------------------------------------------------------------------
//---------------------Block UI Styler Callback Functions--------------------------
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//Callback Name: initialize_cb
//------------------------------------------------------------------------------
void pk_bool::initialize_cb()
{
    try
    {
        group0 = dynamic_cast<NXOpen::BlockStyler::Group*>(theDialog->TopBlock()->FindBlock("group0"));
        selection0 = dynamic_cast<NXOpen::BlockStyler::SelectObject*>(theDialog->TopBlock()->FindBlock("selection0"));
        selection01 = dynamic_cast<NXOpen::BlockStyler::SelectObject*>(theDialog->TopBlock()->FindBlock("selection01"));
    }
    catch(exception& ex)
    {
        //---- Enter your exception handling code here -----
        pk_bool::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what());
    }
}

//------------------------------------------------------------------------------
//Callback Name: dialogShown_cb
//This callback is executed just before the dialog launch. Thus any value set 
//here will take precedence and dialog will be launched showing that value. 
//------------------------------------------------------------------------------
void pk_bool::dialogShown_cb()
{
    try
    {
        //---- Enter your callback code here -----
    }
    catch(exception& ex)
    {
        //---- Enter your exception handling code here -----
        pk_bool::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what());
    }
}

//------------------------------------------------------------------------------
//Callback Name: apply_cb
//------------------------------------------------------------------------------
int pk_bool::apply_cb()
{
    int errorCode = 0;
    try
    {
        //--------------------PK创建目标体和工具体------------------------------
        if (0)
        {
            // PK创建块 10*20*30 位置10.0,10.0,10.0
            double dMillimeter = 0.001;//单位mm
            tag_t  tagPartition = NULL_TAG;
            //创建Parasolid分区并将其设置为当前分区(目标体)
            UF_PS_create_partition(&tagPartition);
            PK_BODY_t pkBody = PK_ENTITY_null;
            PK_BODY_t pkBody1 = PK_ENTITY_null;
            PK_AXIS2_sf_s pkBasisSet;
            PK_VECTOR_t dOrigPoint = { 10.0 * dMillimeter,10.0 * dMillimeter,10.0 * dMillimeter }; //点位置 10,10,10
            PK_VECTOR1_t dDir = { 0.0,0.0,1.0 };   //z尺寸的边的方向
            PK_VECTOR1_t dRefDir = { 1.0,1.0,0.0 };//x尺寸的边的方向

            pkBasisSet.location = dOrigPoint;
            pkBasisSet.axis = dDir;
            pkBasisSet.ref_direction = dRefDir;
            PK_ERROR_code_t pkErr = PK_BODY_create_solid_block(10.0 * dMillimeter, 20.0 * dMillimeter, 30.0 * dMillimeter, &pkBasisSet, &pkBody);//长宽高

            //创建Parasolid分区并将其设置为当前分区(工具体)
            UF_PS_create_partition(&tagPartition);
            dOrigPoint.coord[0] = 9.0 * dMillimeter;
            dOrigPoint.coord[1] = 9.0 * dMillimeter;
            dOrigPoint.coord[2] = 9.0 * dMillimeter;

            pkBasisSet.location = dOrigPoint;
            pkErr = PK_BODY_create_solid_block(7.0 * dMillimeter, 17.0 * dMillimeter, 27.0 * dMillimeter, &pkBasisSet, &pkBody1);//长宽高

            //将布尔对象设置在同一分区下,才可以进行布尔操作
            PK_PARTITION_t aa;
            PK_SESSION_ask_curr_partition(&aa);
            PK_BODY_change_partition(pkBody, aa);
            PK_BODY_change_partition(pkBody1, aa);

            std::vector<PK_BODY_t> pkToolBodys;
            pkToolBodys.push_back(pkBody1);
            std::vector<PK_BODY_t> getpkBodys;
            PK_BOOL_Bodies(pkBody, pkToolBodys, getpkBodys);//原来的目标体工具体都会被删除
            for (size_t i = 0; i < getpkBodys.size(); i++)
            {
                tag_t tagUgObj = NULL_TAG;
                UF_PS_create_obj_from_ps_tag(getpkBodys[i], &tagUgObj);//通过Parasolid创建一个NX对象tag
                UF_DISP_regenerate_display(); //更新显示
            }

        }
        //------------从选择对象控件里获取工具体和目标体----------------
        else
        {
            vector<TaggedObject*> sel = selection0->GetSelectedObjects();
            vector<TaggedObject*> sel1 = selection01->GetSelectedObjects();

            PK_BODY_t pkBody = PK_ENTITY_null;
            PK_BODY_t pkBody1 = PK_ENTITY_null;

            tag_t PKtag;
            UF_PS_ask_ps_tag_of_object(sel[0]->Tag(), &PKtag);
            pkBody = (PK_BODY_t)PKtag;

            tag_t PKtag1;
            UF_PS_ask_ps_tag_of_object(sel1[0]->Tag(), &PKtag1);
            pkBody1 = (PK_BODY_t)PKtag1;

            PK_ENTITY_copy(pkBody, &pkBody);//复制出PK对象,才能进行求差
            PK_ENTITY_copy(pkBody1, &pkBody1);//复制出PK对象,才能进行求差


            //将布尔对象设置在同一分区下,才可以进行布尔操作
            PK_PARTITION_t aa;
            PK_SESSION_ask_curr_partition(&aa);
            PK_BODY_change_partition(pkBody, aa);
            PK_BODY_change_partition(pkBody1, aa);//如果上面不进行PK_ENTITY_copy复制出PK对象,则报错:PK_ERROR_entity_not_new

            std::vector<PK_BODY_t> pkToolBodys;
            pkToolBodys.push_back(pkBody1);
            std::vector<PK_BODY_t> getpkBodys;
            PK_BOOL_Bodies(pkBody, pkToolBodys, getpkBodys);//原来的目标体工具体都会被删除
            for (size_t i = 0; i < getpkBodys.size(); i++)
            {
                tag_t tagUgObj = NULL_TAG;
                UF_PS_create_obj_from_ps_tag(getpkBodys[i], &tagUgObj);//通过Parasolid创建一个NX对象tag
                UF_DISP_regenerate_display(); //更新显示
            }
        }


    }
    catch(exception& ex)
    {
        //---- Enter your exception handling code here -----
        errorCode = 1;
        pk_bool::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what());
    }
    return errorCode;
}

//------------------------------------------------------------------------------
//Callback Name: update_cb
//------------------------------------------------------------------------------
int pk_bool::update_cb(NXOpen::BlockStyler::UIBlock* block)
{
    try
    {
        if(block == selection0)
        {
        //---------Enter your code here-----------
        }
        else if(block == selection01)
        {
        //---------Enter your code here-----------
        }
    }
    catch(exception& ex)
    {
        //---- Enter your exception handling code here -----
        pk_bool::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what());
    }
    return 0;
}

//------------------------------------------------------------------------------
//Callback Name: ok_cb
//------------------------------------------------------------------------------
int pk_bool::ok_cb()
{
    int errorCode = 0;
    try
    {
        errorCode = apply_cb();
    }
    catch(exception& ex)
    {
        //---- Enter your exception handling code here -----
        errorCode = 1;
        pk_bool::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what());
    }
    return errorCode;
}

//------------------------------------------------------------------------------
//Function Name: GetBlockProperties
//Description: Returns the propertylist of the specified BlockID
//------------------------------------------------------------------------------
PropertyList* pk_bool::GetBlockProperties(const char *blockID)
{
    return theDialog->GetBlockProperties(blockID);
}

hpp文件

#ifndef PK_BOOL_H_INCLUDED
#define PK_BOOL_H_INCLUDED

//------------------------------------------------------------------------------
//These includes are needed for the following template code
//------------------------------------------------------------------------------
#include <uf_defs.h>
#include <uf_ui_types.h>
#include <iostream>
#include <NXOpen/Session.hxx>
#include <NXOpen/UI.hxx>
#include <NXOpen/NXMessageBox.hxx>
#include <NXOpen/Callback.hxx>
#include <NXOpen/NXException.hxx>
#include <NXOpen/BlockStyler_UIBlock.hxx>
#include <NXOpen/BlockStyler_BlockDialog.hxx>
#include <NXOpen/BlockStyler_PropertyList.hxx>
#include <NXOpen/BlockStyler_Group.hxx>
#include <NXOpen/BlockStyler_SelectObject.hxx>

#include <uf.h>
#include <uf_ui.h>
#include <uf_ps.h>
#include "parasolid_kernel.h"
#pragma comment(lib,"pskernel_x64.lib")

#include <atlbase.h>
#undef CreateDialog

//------------------------------------------------------------------------------
//Bit Option for Property: SnapPointTypesEnabled
//------------------------------------------------------------------------------
#define              SnapPointTypesEnabled_UserDefined (1 << 0);
#define                 SnapPointTypesEnabled_Inferred (1 << 1);
#define           SnapPointTypesEnabled_ScreenPosition (1 << 2);
#define                 SnapPointTypesEnabled_EndPoint (1 << 3);
#define                 SnapPointTypesEnabled_MidPoint (1 << 4);
#define             SnapPointTypesEnabled_ControlPoint (1 << 5);
#define             SnapPointTypesEnabled_Intersection (1 << 6);
#define                SnapPointTypesEnabled_ArcCenter (1 << 7);
#define            SnapPointTypesEnabled_QuadrantPoint (1 << 8);
#define            SnapPointTypesEnabled_ExistingPoint (1 << 9);
#define             SnapPointTypesEnabled_PointonCurve (1 <<10);
#define           SnapPointTypesEnabled_PointonSurface (1 <<11);
#define         SnapPointTypesEnabled_PointConstructor (1 <<12);
#define     SnapPointTypesEnabled_TwocurveIntersection (1 <<13);
#define             SnapPointTypesEnabled_TangentPoint (1 <<14);
#define                    SnapPointTypesEnabled_Poles (1 <<15);
#define         SnapPointTypesEnabled_BoundedGridPoint (1 <<16);
//------------------------------------------------------------------------------
//Bit Option for Property: SnapPointTypesOnByDefault
//------------------------------------------------------------------------------
#define             SnapPointTypesOnByDefault_EndPoint (1 << 3);
#define             SnapPointTypesOnByDefault_MidPoint (1 << 4);
#define         SnapPointTypesOnByDefault_ControlPoint (1 << 5);
#define         SnapPointTypesOnByDefault_Intersection (1 << 6);
#define            SnapPointTypesOnByDefault_ArcCenter (1 << 7);
#define        SnapPointTypesOnByDefault_QuadrantPoint (1 << 8);
#define        SnapPointTypesOnByDefault_ExistingPoint (1 << 9);
#define         SnapPointTypesOnByDefault_PointonCurve (1 <<10);
#define       SnapPointTypesOnByDefault_PointonSurface (1 <<11);
#define     SnapPointTypesOnByDefault_PointConstructor (1 <<12);
#define     SnapPointTypesOnByDefault_BoundedGridPoint (1 <<16);
//------------------------------------------------------------------------------
// Namespaces needed for following template
//------------------------------------------------------------------------------
using namespace std;
using namespace NXOpen;
using namespace NXOpen::BlockStyler;

class DllExport pk_bool
{
    // class members
public:
    static Session *theSession;
    static UI *theUI;
    pk_bool();
    ~pk_bool();
    int Show();
    
    //----------------------- BlockStyler Callback Prototypes ---------------------
    // The following member function prototypes define the callbacks 
    // specified in your BlockStyler dialog.  The empty implementation
    // of these prototypes is provided in the pk_bool.cpp file. 
    // You are REQUIRED to write the implementation for these functions.
    //------------------------------------------------------------------------------
    void initialize_cb();
    void dialogShown_cb();
    int apply_cb();
    int ok_cb();
    int update_cb(NXOpen::BlockStyler::UIBlock* block);
    PropertyList* GetBlockProperties(const char *blockID);
    
private:
    const char* theDlxFileName;
    NXOpen::BlockStyler::BlockDialog* theDialog;
    NXOpen::BlockStyler::Group* group0;// Block type: Group
    NXOpen::BlockStyler::SelectObject* selection0;// Block type: Selection
    NXOpen::BlockStyler::SelectObject* selection01;// Block type: Selection
    
};
#endif //PK_BOOL_H_INCLUDED

选择操作:

效果:生成的求差体(相当于重新创建的体一样,原来的颜色都丢失了)

  • 12
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

社恐猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值