1. 程式人生 > 其它 >NX二次開發-一個簡單例子剖析學會如何使用NXOPEN做二次開發

NX二次開發-一個簡單例子剖析學會如何使用NXOPEN做二次開發

昨天晚上半夜12點半。看到我龍哥哥在QQ群裡問問題,他想做一個連線曲線的功能,但是連線曲線的UFUN函式不會用,

錄製連線曲線NXOPEN程式碼又不會錄製,自己在谷歌上面找的一段程式碼,抄下來改,還做出來了。但是曲線的顏色不是他想要的。

自己不會改顏色,跟他嘮了一會,我覺得蠻好玩的,就寫了個例子給他。也記錄下錄程式碼,改程式碼,轉換等問題。

這個例子很簡單,但是卻很好的運用各種型別的轉換。很多人不會用NXOPEN絕對不是因為不會錄程式碼而不會,

絕大部分應該都是錄出來的程式碼太多,不會改程式碼,不會資料型別轉換,不會和UFUN結合傳參。

而卡在門外,只默默的用UFUN。

例子中的所有程式碼,在幫助文件裡全部可以查的到出處。

  • 版本

NX11+VS2013

  • 例子

建立連線曲線,並設定顏色。

UFUN C + NXOPEN C++ 混合程式設計

  • 演示
  • 原始碼
//Demo

// Mandatory UF Includes
#include <uf.h>
#include <uf_object_types.h>

// Internal Includes
#include <NXOpen/ListingWindow.hxx>
#include <NXOpen/NXMessageBox.hxx>
#include <NXOpen/UI.hxx>

// Internal+External Includes
#include <NXOpen/Annotations.hxx> #include <NXOpen/Assemblies_Component.hxx> #include <NXOpen/Assemblies_ComponentAssembly.hxx> #include <NXOpen/Body.hxx> #include <NXOpen/BodyCollection.hxx> #include <NXOpen/Face.hxx> #include <NXOpen/Line.hxx> #include <NXOpen/NXException.hxx> #include
<NXOpen/NXObject.hxx> #include <NXOpen/Part.hxx> #include <NXOpen/PartCollection.hxx> #include <NXOpen/Session.hxx> //標頭檔案 #include <uf.h> #include <uf_ui.h> #include <uf_modl.h> #include <uf_obj.h> #include <uf_disp.h> #include <uf_curve.h> #include <NXOpen/Edge.hxx> #include <NXOpen/EdgeTangentRule.hxx> #include <NXOpen/Features_Block.hxx> #include <NXOpen/Features_FeatureCollection.hxx> #include <NXOpen/ScRuleFactory.hxx> #include <NXOpen/NXObjectManager.hxx> #include <NXOpen/Features_JoinCurves.hxx> #include <NXOpen/Features_JoinCurvesBuilder.hxx> #include <NXOpen/Preferences_ObjectPreferences.hxx> #include <NXOpen/Preferences_PartObject.hxx> #include <NXOpen/Preferences_PartPreferences.hxx> #include <NXOpen/Spline.hxx> #include <NXOpen/DisplayManager.hxx> #include <NXOpen/DisplayModification.hxx> #include <NXOpen/DisplayableObject.hxx> // Std C++ Includes #include <iostream> #include <sstream> using namespace NXOpen; using std::string; using std::exception; using std::stringstream; using std::endl; using std::cout; using std::cerr; //------------------------------------------------------------------------------ // NXOpen c++ test class //------------------------------------------------------------------------------ class MyClass { // class members public: static Session *theSession; static UI *theUI; MyClass(); ~MyClass(); void do_it(); void print(const NXString &); void print(const string &); void print(const char*); private: Part *workPart, *displayPart; NXMessageBox *mb; ListingWindow *lw; LogFile *lf; }; //------------------------------------------------------------------------------ // Initialize static variables //------------------------------------------------------------------------------ Session *(MyClass::theSession) = NULL; UI *(MyClass::theUI) = NULL; //------------------------------------------------------------------------------ // Constructor //------------------------------------------------------------------------------ MyClass::MyClass() { // Initialize the NX Open C++ API environment MyClass::theSession = NXOpen::Session::GetSession(); MyClass::theUI = UI::GetUI(); mb = theUI->NXMessageBox(); lw = theSession->ListingWindow(); lf = theSession->LogFile(); workPart = theSession->Parts()->Work(); displayPart = theSession->Parts()->Display(); } //------------------------------------------------------------------------------ // Destructor //------------------------------------------------------------------------------ MyClass::~MyClass() { } //------------------------------------------------------------------------------ // Print string to listing window or stdout //------------------------------------------------------------------------------ void MyClass::print(const NXString &msg) { if(! lw->IsOpen() ) lw->Open(); lw->WriteLine(msg); } void MyClass::print(const string &msg) { if(! lw->IsOpen() ) lw->Open(); lw->WriteLine(msg); } void MyClass::print(const char * msg) { if(! lw->IsOpen() ) lw->Open(); lw->WriteLine(msg); } static int init_proc(UF_UI_selection_p_t select, void* user_data) { int errorCode = 0; int num_triples = 1; UF_UI_mask_t mask_triples[1] = { { UF_solid_type, UF_all_subtype, UF_UI_SEL_FEATURE_ANY_EDGE }//定義選擇邊型別 }; errorCode = UF_UI_set_sel_mask(select, UF_UI_SEL_MASK_CLEAR_AND_ENABLE_SPECIFIC, num_triples, mask_triples); if (errorCode == 0) { return UF_UI_SEL_SUCCESS; } else { return UF_UI_SEL_FAILURE; } } //------------------------------------------------------------------------------ // Do something //------------------------------------------------------------------------------ void MyClass::do_it() { // TODO: add your code here UF_initialize(); L10: //開啟單物件選擇對話方塊 char sCue[] = "請選擇實體的邊"; char sTitle[] = "選擇邊"; int iScope = UF_UI_SEL_SCOPE_WORK_PART; int iResponse = 0; tag_t tObject = NULL_TAG; double adCursor[3]; tag_t tView = NULL_TAG; UF_UI_select_with_single_dialog(sCue, sTitle, iScope, init_proc, NULL, &iResponse, &tObject, adCursor, &tView); if (iResponse == UF_UI_OK || iResponse == UF_UI_OBJECT_SELECTED || iResponse == UF_UI_OBJECT_SELECTED_BY_NAME) { //取消高亮 UF_DISP_set_highlight(tObject, 0); //建立連線曲線 NXOpen::Features::Feature *nullNXOpen_Features_Feature(NULL); NXOpen::Features::JoinCurvesBuilder *joinCurvesBuilder1; joinCurvesBuilder1 = workPart->Features()->CreateJoinCurvesBuilder(nullNXOpen_Features_Feature); joinCurvesBuilder1->SetDistanceTolerance(0.001);//設定距離公差 joinCurvesBuilder1->SetAngleTolerance(0.050000000000000003); //設定角度公差 //返回收集要連線的輸入曲線的部分 joinCurvesBuilder1->Section()->SetDistanceTolerance(0.001); joinCurvesBuilder1->Section()->SetChainingTolerance(0.00095); joinCurvesBuilder1->Section()->SetAngleTolerance(0.050000000000000003); joinCurvesBuilder1->Section()->SetAllowedEntityTypes(NXOpen::Section::AllowTypesOnlyCurves); //傳入選擇的邊tag NXOpen::Edge *edge1(dynamic_cast<NXOpen::Edge *>(NXOpen::NXObjectManager::Get(tObject)));//此處修改邊的tag NXOpen::Edge *nullNXOpen_Edge(NULL); NXOpen::EdgeTangentRule *edgeTangentRule1; edgeTangentRule1 = workPart->ScRuleFactory()->CreateRuleEdgeTangent(edge1, nullNXOpen_Edge, true, 0.050000000000000003, false, false); joinCurvesBuilder1->Section()->AllowSelfIntersection(true); std::vector<NXOpen::SelectionIntentRule *> rules1(1); rules1[0] = edgeTangentRule1; NXOpen::NXObject *nullNXOpen_NXObject(NULL); NXOpen::Point3d helpPoint1(0, 0, 0); joinCurvesBuilder1->Section()->AddToSection(rules1, edge1, nullNXOpen_NXObject, nullNXOpen_NXObject, helpPoint1, NXOpen::Section::ModeCreate, false); NXOpen::NXObject *nXObject1; nXObject1 = joinCurvesBuilder1->Commit();//生成連線曲線特徵 //將joinCurvesBuilder1生成的NXObject物件轉換成Features::JoinCurves連線曲線物件(它是特徵型別,並不是曲線型別),怎麼轉換的,錄製得出來的(方式1) NXOpen::Features::JoinCurves *joinCurves1(dynamic_cast<NXOpen::Features::JoinCurves *>(nXObject1)); ////另外一種錄製出來的轉換方式(方式2) //NXOpen::Features::JoinCurves *joinCurves1(dynamic_cast<NXOpen::Features::JoinCurves *>(workPart->Features()->FindObject(nXObject1->JournalIdentifier()))); //返回連線曲線特徵建立的曲線物件(NXOPEN方式) std::vector< NXOpen::NXObject *>spline = joinCurves1->GetEntities(); //提取連線曲線特徵裡的曲線物件(UFUN方式) int num_curves = 0; tag_t *feature_curves = NULL_TAG; UF_CURVE_ask_feature_curves(joinCurves1->Tag(), &num_curves, &feature_curves); //輸出型別 int type, subtype = 0; UF_OBJ_ask_type_and_subtype(spline[0]->Tag(), &type, &subtype); //獲得首選項-物件-樣條的顏色(這一步有點多此一舉了,首選項是什麼顏色,創建出來的樣條就應該是什麼顏色,不需要第二次在設定曲線顏色的,這裡只是例子需要) int color_num = workPart->Preferences()->ObjectPreferences()->GetColor(Preferences::PartObject::ObjectTypeSpline); ////設定曲線顏色(UFUN) //UF_OBJ_set_color(spline[0]->Tag(), color_num); //設定曲線顏色(NXOPEN) NXOpen::DisplayModification *displayModification1; displayModification1 = theSession->DisplayManager()->NewDisplayModification(); displayModification1->SetApplyToAllFaces(true); displayModification1->SetApplyToOwningParts(false); displayModification1->SetNewColor(186);//顏色號碼 std::vector<NXOpen::DisplayableObject *> objects1(1); //轉換 NXOpen::Spline *spline1(dynamic_cast<NXOpen::Spline *>(joinCurves1->FindObject(spline[0]->JournalIdentifier()))); objects1[0] = spline1; displayModification1->Apply(objects1); delete displayModification1; //釋放 UF_free(feature_curves); goto L10;//跳轉回去重新選 } UF_terminate(); } //------------------------------------------------------------------------------ // Entry point(s) for unmanaged internal NXOpen C/C++ programs //------------------------------------------------------------------------------ // Explicit Execution extern "C" DllExport void ufusr( char *parm, int *returnCode, int rlen ) { try { // Create NXOpen C++ class instance MyClass *theMyClass; theMyClass = new MyClass(); theMyClass->do_it(); delete theMyClass; } catch (const NXException& e1) { UI::GetUI()->NXMessageBox()->Show("NXException", NXOpen::NXMessageBox::DialogTypeError, e1.Message()); } catch (const exception& e2) { UI::GetUI()->NXMessageBox()->Show("Exception", NXOpen::NXMessageBox::DialogTypeError, e2.what()); } catch (...) { UI::GetUI()->NXMessageBox()->Show("Exception", NXOpen::NXMessageBox::DialogTypeError, "Unknown Exception."); } } //------------------------------------------------------------------------------ // Unload Handler //------------------------------------------------------------------------------ extern "C" DllExport int ufusr_ask_unload() { return (int)NXOpen::Session::LibraryUnloadOptionImmediately; } 阿飛 2021年8月29日
  • 步驟剖析

挑重點的寫,怎麼搭建環境,怎麼加標頭檔案,怎麼用UFUN函式,怎麼錄NXOPEN程式碼,不在文章寫的範圍。

1.錄製連線曲線命令

        //建立連線曲線
        NXOpen::Features::Feature *nullNXOpen_Features_Feature(NULL);
        NXOpen::Features::JoinCurvesBuilder *joinCurvesBuilder1;
        joinCurvesBuilder1 = workPart->Features()->CreateJoinCurvesBuilder(nullNXOpen_Features_Feature);
        joinCurvesBuilder1->SetDistanceTolerance(0.001);//設定距離公差
        joinCurvesBuilder1->SetAngleTolerance(0.050000000000000003); //設定角度公差
        //返回收集要連線的輸入曲線的部分
        joinCurvesBuilder1->Section()->SetDistanceTolerance(0.001);
        joinCurvesBuilder1->Section()->SetChainingTolerance(0.00095);
        joinCurvesBuilder1->Section()->SetAngleTolerance(0.050000000000000003);
        joinCurvesBuilder1->Section()->SetAllowedEntityTypes(NXOpen::Section::AllowTypesOnlyCurves);
        //傳入選擇的邊tag
        NXOpen::Edge *edge1(dynamic_cast<NXOpen::Edge *>(NXOpen::NXObjectManager::Get(tObject)));//此處修改邊的tag
        NXOpen::Edge *nullNXOpen_Edge(NULL);
        NXOpen::EdgeTangentRule *edgeTangentRule1;
        edgeTangentRule1 = workPart->ScRuleFactory()->CreateRuleEdgeTangent(edge1, nullNXOpen_Edge, true, 0.050000000000000003, false, false);
        joinCurvesBuilder1->Section()->AllowSelfIntersection(true);
        std::vector<NXOpen::SelectionIntentRule *> rules1(1);
        rules1[0] = edgeTangentRule1;
        NXOpen::NXObject *nullNXOpen_NXObject(NULL);
        NXOpen::Point3d helpPoint1(0, 0, 0);
        joinCurvesBuilder1->Section()->AddToSection(rules1, edge1, nullNXOpen_NXObject, nullNXOpen_NXObject, helpPoint1, NXOpen::Section::ModeCreate, false);
        NXOpen::NXObject *nXObject1;
        nXObject1 = joinCurvesBuilder1->Commit();//生成連線曲線特徵

說說上面這段程式碼是怎麼來的

1.找到連線曲線命令,錄製一下它

錄出來的程式碼如下,有一大堆,看著頭疼,所以很多人不願意用NXOPEN,沒有UFUN簡潔

// NX 11.0.2.7
// Journal created by Administrator on Sun Aug 29 13:23:58 2021 中國標準時間

//
#include <uf_defs.h>
#include <NXOpen/NXException.hxx>
#include <NXOpen/Session.hxx>
#include <NXOpen/Builder.hxx>
#include <NXOpen/Edge.hxx>
#include <NXOpen/EdgeTangentRule.hxx>
#include <NXOpen/Features_Block.hxx>
#include <NXOpen/Features_FeatureCollection.hxx>
#include <NXOpen/Features_JoinCurvesBuilder.hxx>
#include <NXOpen/GeometricUtilities_CurveOptions.hxx>
#include <NXOpen/NXObject.hxx>
#include <NXOpen/Part.hxx>
#include <NXOpen/PartCollection.hxx>
#include <NXOpen/ScRuleFactory.hxx>
#include <NXOpen/Section.hxx>
#include <NXOpen/SelectionIntentRule.hxx>
#include <NXOpen/Session.hxx>
using namespace NXOpen;

extern "C" DllExport int ufusr_ask_unload()
{
    return (int)NXOpen::Session::LibraryUnloadOptionImmediately;
}

extern "C" DllExport void ufusr(char *param, int *retCode, int paramLen)
{
    NXOpen::Session *theSession = NXOpen::Session::GetSession();
    NXOpen::Part *workPart(theSession->Parts()->Work());
    NXOpen::Part *displayPart(theSession->Parts()->Display());
    // ----------------------------------------------
    //   Menu: 插入(S)->派生曲線(U)->連結(J)...
    // ----------------------------------------------
    NXOpen::Session::UndoMarkId markId1;
    markId1 = theSession->SetUndoMark(NXOpen::Session::MarkVisibilityVisible, NXString("\345\274\200\345\247\213", NXString::UTF8));
    
    NXOpen::Features::Feature *nullNXOpen_Features_Feature(NULL);
    NXOpen::Features::JoinCurvesBuilder *joinCurvesBuilder1;
    joinCurvesBuilder1 = workPart->Features()->CreateJoinCurvesBuilder(nullNXOpen_Features_Feature);
    
    joinCurvesBuilder1->SetDistanceTolerance(0.001);
    
    joinCurvesBuilder1->SetAngleTolerance(0.050000000000000003);
    
    theSession->SetUndoMarkName(markId1, NXString("\350\277\236\347\273\223\346\233\262\347\272\277 \345\257\271\350\257\235\346\241\206", NXString::UTF8));
    
    joinCurvesBuilder1->Section()->SetDistanceTolerance(0.001);
    
    joinCurvesBuilder1->Section()->SetChainingTolerance(0.00095);
    
    joinCurvesBuilder1->Section()->SetAngleTolerance(0.050000000000000003);
    
    joinCurvesBuilder1->Section()->SetAllowedEntityTypes(NXOpen::Section::AllowTypesOnlyCurves);
    
    NXOpen::Session::UndoMarkId markId2;
    markId2 = theSession->SetUndoMark(NXOpen::Session::MarkVisibilityInvisible, "section mark");
    
    NXOpen::Session::UndoMarkId markId3;
    markId3 = theSession->SetUndoMark(NXOpen::Session::MarkVisibilityInvisible, NULL);
    
    NXOpen::Features::Block *block1(dynamic_cast<NXOpen::Features::Block *>(workPart->Features()->FindObject("BLOCK(1)")));
    NXOpen::Edge *edge1(dynamic_cast<NXOpen::Edge *>(block1->FindObject("EDGE * 1 * 3 {(0,0,100)(0,50,100)(0,100,100) BLOCK(1)}")));
    NXOpen::Edge *nullNXOpen_Edge(NULL);
    NXOpen::EdgeTangentRule *edgeTangentRule1;
    edgeTangentRule1 = workPart->ScRuleFactory()->CreateRuleEdgeTangent(edge1, nullNXOpen_Edge, true, 0.050000000000000003, false, false);
    
    joinCurvesBuilder1->Section()->AllowSelfIntersection(true);
    
    std::vector<NXOpen::SelectionIntentRule *> rules1(1);
    rules1[0] = edgeTangentRule1;
    NXOpen::NXObject *nullNXOpen_NXObject(NULL);
    NXOpen::Point3d helpPoint1(0.0, 47.283993560949256, 100.0);
    joinCurvesBuilder1->Section()->AddToSection(rules1, edge1, nullNXOpen_NXObject, nullNXOpen_NXObject, helpPoint1, NXOpen::Section::ModeCreate, false);
    
    theSession->DeleteUndoMark(markId3, NULL);
    
    theSession->DeleteUndoMark(markId2, NULL);
    
    NXOpen::Session::UndoMarkId markId4;
    markId4 = theSession->SetUndoMark(NXOpen::Session::MarkVisibilityInvisible, NXString("\350\277\236\347\273\223\346\233\262\347\272\277", NXString::UTF8));
    
    theSession->DeleteUndoMark(markId4, NULL);
    
    NXOpen::Session::UndoMarkId markId5;
    markId5 = theSession->SetUndoMark(NXOpen::Session::MarkVisibilityInvisible, NXString("\350\277\236\347\273\223\346\233\262\347\272\277", NXString::UTF8));
    
    NXOpen::NXObject *nXObject1;
    nXObject1 = joinCurvesBuilder1->Commit();
    
    theSession->DeleteUndoMark(markId5, NULL);
    
    theSession->SetUndoMarkName(markId1, NXString("\350\277\236\347\273\223\346\233\262\347\272\277", NXString::UTF8));
    
    joinCurvesBuilder1->Destroy();
    
    // ----------------------------------------------
    //   Menu: 工具(T)->操作記錄(J)->停止錄製(S)
    // ----------------------------------------------
}

下面說哪些程式碼是要的,哪些是不要的

先看官方文件的介紹(C井的,對C++一樣適用,看懂原理就行了)

文件資料出處https://www.cnblogs.com/nxopen2018/articles/11664518.html

一大堆,看不懂也沒關係,能看懂多少就看懂多少。

回到我們的例子當中來

凡是帶UndoMarkId的全部是不要的

刪完也就剩下這些了,還是有不少

格式都是固定的了,直接抄過去到專案裡。

我們要改的就一個地方,就是傳參的地方。就這兩句

我們錄製命令的時候,是直接選擇的邊,但是它把塊都給錄上了。變成了先找塊,在找塊的某一邊。

下面我們開始修改程式碼,塊對我們是不需要的,我們只要對話方塊選邊,傳參邊的tag就行了。

NXOpen::Edge *edge1(dynamic_cast<NXOpen::Edge *>(NXOpen::NXObjectManager::Get(tObject)));//此處修改邊的tag

就這一句,就可以轉換。tObject為邊的tag,意思是將UFUN的邊tag轉換成NXOPEN的Edge型別(邊),在NX二次開發中,不同的物件,都有自己不同的型別。這就涉及到了型別轉換的問題。

轉換傳什麼引數。它要什麼,你傳什麼就行了,上面錄製的時候,不是都已經看到了,FindObject裡面要的是EDGE物件型別,那你就把你的UFUN邊的tag給進去。

中間轉換用NXOPEN的這個方法,注意要加標頭檔案 #include <NXOpen/NXObjectManager.hxx>

下面關於各種型別的一些簡單介紹,在我們的例子當中,錄製出來的是生成連線曲線特徵,想要設定顏色只能對曲線設定顏色,不能對特徵設定顏色,所以我們還要提取出特徵裡的曲線。

2.型別轉換,將連線曲線特徵物件轉換成曲線物件

        //將joinCurvesBuilder1生成的NXObject物件轉換成Features::JoinCurves連線曲線物件(它是特徵型別,並不是曲線型別),怎麼轉換的,錄製得出來的(方式1)
        NXOpen::Features::JoinCurves *joinCurves1(dynamic_cast<NXOpen::Features::JoinCurves *>(nXObject1));

        ////另外一種錄製出來的轉換方式(方式2)
        //NXOpen::Features::JoinCurves *joinCurves1(dynamic_cast<NXOpen::Features::JoinCurves *>(workPart->Features()->FindObject(nXObject1->JournalIdentifier())));
        
        //返回連線曲線特徵建立的曲線物件(NXOPEN方式)
        std::vector< NXOpen::NXObject *>spline = joinCurves1->GetEntities();

        //提取連線曲線特徵裡的曲線物件(UFUN方式)
        int num_curves = 0;
        tag_t *feature_curves = NULL_TAG;
        UF_CURVE_ask_feature_curves(joinCurves1->Tag(), &num_curves, &feature_curves);

        //輸出型別
        int type, subtype = 0;
        UF_OBJ_ask_type_and_subtype(spline[0]->Tag(), &type, &subtype);

上面這段NXOPEN轉換程式碼是怎麼來的,將做詳細介紹,UFUN的那段就不介紹了,現成的API翻幫助就行了。

怎麼轉換的,我也不知道,反正不知道,那就繼續錄製唄。

方法1連續錄製

錄製出來的程式碼如下,你會發現又是一大堆,實質我們需要的就兩段

// NX 11.0.2.7
// Journal created by Administrator on Sun Aug 29 13:54:41 2021 中國標準時間

//
#include <uf_defs.h>
#include <NXOpen/NXException.hxx>
#include <NXOpen/Session.hxx>
#include <NXOpen/Builder.hxx>
#include <NXOpen/DisplayManager.hxx>
#include <NXOpen/DisplayModification.hxx>
#include <NXOpen/DisplayableObject.hxx>
#include <NXOpen/Edge.hxx>
#include <NXOpen/EdgeTangentRule.hxx>
#include <NXOpen/Features_Block.hxx>
#include <NXOpen/Features_FeatureCollection.hxx>
#include <NXOpen/Features_JoinCurves.hxx>
#include <NXOpen/Features_JoinCurvesBuilder.hxx>
#include <NXOpen/GeometricUtilities_CurveOptions.hxx>
#include <NXOpen/NXObject.hxx>
#include <NXOpen/Part.hxx>
#include <NXOpen/PartCollection.hxx>
#include <NXOpen/ScRuleFactory.hxx>
#include <NXOpen/Section.hxx>
#include <NXOpen/SelectionIntentRule.hxx>
#include <NXOpen/Session.hxx>
#include <NXOpen/Spline.hxx>
#include <NXOpen/Update.hxx>
using namespace NXOpen;

extern "C" DllExport int ufusr_ask_unload()
{
    return (int)NXOpen::Session::LibraryUnloadOptionImmediately;
}

extern "C" DllExport void ufusr(char *param, int *retCode, int paramLen)
{
    NXOpen::Session *theSession = NXOpen::Session::GetSession();
    NXOpen::Part *workPart(theSession->Parts()->Work());
    NXOpen::Part *displayPart(theSession->Parts()->Display());
    // ----------------------------------------------
    //   Menu: 插入(S)->派生曲線(U)->連結(J)...
    // ----------------------------------------------
    NXOpen::Session::UndoMarkId markId1;
    markId1 = theSession->SetUndoMark(NXOpen::Session::MarkVisibilityVisible, NXString("\345\274\200\345\247\213", NXString::UTF8));
    
    NXOpen::Features::Feature *nullNXOpen_Features_Feature(NULL);
    NXOpen::Features::JoinCurvesBuilder *joinCurvesBuilder1;
    joinCurvesBuilder1 = workPart->Features()->CreateJoinCurvesBuilder(nullNXOpen_Features_Feature);
    
    joinCurvesBuilder1->SetDistanceTolerance(0.001);
    
    joinCurvesBuilder1->SetAngleTolerance(0.050000000000000003);
    
    theSession->SetUndoMarkName(markId1, NXString("\350\277\236\347\273\223\346\233\262\347\272\277 \345\257\271\350\257\235\346\241\206", NXString::UTF8));
    
    joinCurvesBuilder1->Section()->SetDistanceTolerance(0.001);
    
    joinCurvesBuilder1->Section()->SetChainingTolerance(0.00095);
    
    joinCurvesBuilder1->Section()->SetAngleTolerance(0.050000000000000003);
    
    joinCurvesBuilder1->Section()->SetAllowedEntityTypes(NXOpen::Section::AllowTypesOnlyCurves);
    
    NXOpen::Session::UndoMarkId markId2;
    markId2 = theSession->SetUndoMark(NXOpen::Session::MarkVisibilityInvisible, "section mark");
    
    NXOpen::Session::UndoMarkId markId3;
    markId3 = theSession->SetUndoMark(NXOpen::Session::MarkVisibilityInvisible, NULL);
    
    NXOpen::Features::Block *block1(dynamic_cast<NXOpen::Features::Block *>(workPart->Features()->FindObject("BLOCK(1)")));
    NXOpen::Edge *edge1(dynamic_cast<NXOpen::Edge *>(block1->FindObject("EDGE * 1 * 2 {(100,0,100)(50,0,100)(0,0,100) BLOCK(1)}")));
    NXOpen::Edge *nullNXOpen_Edge(NULL);
    NXOpen::EdgeTangentRule *edgeTangentRule1;
    edgeTangentRule1 = workPart->ScRuleFactory()->CreateRuleEdgeTangent(edge1, nullNXOpen_Edge, true, 0.050000000000000003, false, false);
    
    joinCurvesBuilder1->Section()->AllowSelfIntersection(true);
    
    std::vector<NXOpen::SelectionIntentRule *> rules1(1);
    rules1[0] = edgeTangentRule1;
    NXOpen::NXObject *nullNXOpen_NXObject(NULL);
    NXOpen::Point3d helpPoint1(57.771598781542366, 0.0, 100.0);
    joinCurvesBuilder1->Section()->AddToSection(rules1, edge1, nullNXOpen_NXObject, nullNXOpen_NXObject, helpPoint1, NXOpen::Section::ModeCreate, false);
    
    theSession->DeleteUndoMark(markId3, NULL);
    
    theSession->DeleteUndoMark(markId2, NULL);
    
    NXOpen::Session::UndoMarkId markId4;
    markId4 = theSession->SetUndoMark(NXOpen::Session::MarkVisibilityInvisible, NXString("\350\277\236\347\273\223\346\233\262\347\272\277", NXString::UTF8));
    
    theSession->DeleteUndoMark(markId4, NULL);
    
    NXOpen::Session::UndoMarkId markId5;
    markId5 = theSession->SetUndoMark(NXOpen::Session::MarkVisibilityInvisible, NXString("\350\277\236\347\273\223\346\233\262\347\272\277", NXString::UTF8));
    
    NXOpen::NXObject *nXObject1;
    nXObject1 = joinCurvesBuilder1->Commit();
    
    theSession->DeleteUndoMark(markId5, NULL);
    
    theSession->SetUndoMarkName(markId1, NXString("\350\277\236\347\273\223\346\233\262\347\272\277", NXString::UTF8));
    
    joinCurvesBuilder1->Destroy();
    
    // ----------------------------------------------
    //   Menu: 編輯(E)->物件顯示(J)...
    // ----------------------------------------------
    // ----------------------------------------------
    //   Dialog Begin 顏色
    // ----------------------------------------------
    NXOpen::Session::UndoMarkId markId6;
    markId6 = theSession->SetUndoMark(NXOpen::Session::MarkVisibilityVisible, "Edit Object Display");
    
    NXOpen::DisplayModification *displayModification1;
    displayModification1 = theSession->DisplayManager()->NewDisplayModification();
    
    displayModification1->SetApplyToAllFaces(true);
    
    displayModification1->SetApplyToOwningParts(false);
    
    displayModification1->SetNewColor(186);
    
    std::vector<NXOpen::DisplayableObject *> objects1(1);
    NXOpen::Features::JoinCurves *joinCurves1(dynamic_cast<NXOpen::Features::JoinCurves *>(nXObject1));
    NXOpen::Spline *spline1(dynamic_cast<NXOpen::Spline *>(joinCurves1->FindObject("CURVE 1")));
    objects1[0] = spline1;
    displayModification1->Apply(objects1);
    
    int nErrs1;
    nErrs1 = theSession->UpdateManager()->DoUpdate(markId6);
    
    delete displayModification1;
    // ----------------------------------------------
    //   Menu: 工具(T)->操作記錄(J)->停止錄製(S)
    // ----------------------------------------------
}

就這兩段,轉換方法,錄製給帶出來了,我們只要改裡面傳的引數就行了

    NXOpen::Features::JoinCurves *joinCurves1(dynamic_cast<NXOpen::Features::JoinCurves *>(nXObject1));
    NXOpen::Spline *spline1(dynamic_cast<NXOpen::Spline *>(joinCurves1->FindObject("CURVE 1")));

我們發現nXObject1實際就是上面我們一開始錄製連線曲線最後

NXOpen::NXObject *nXObject1;
nXObject1 = joinCurvesBuilder1->Commit();//生成連線曲線特徵

生成的那個物件。這裡它是個曲線特徵物件,你可以拿UF_OBJ_ask_type_and_subtype去列印下它的型別

        int type, subtype = 0;
        UF_OBJ_ask_type_and_subtype(nXObject1->Tag(), &type, &subtype);

#defineUF_feature_type 205型別

這段就是說把nXObject1轉換成NXOpen::Features::JoinCurves *joinCurves1物件型別。因為上面JoinCurvesBuilder->Commit返回的是NXObject物件

NXOpen::Features::JoinCurves *joinCurves1是連線曲線特徵型別

在Features類裡

得到了Features::JoinCurves *joinCurves1型別後,我們還要去幫助裡面翻這個類裡的函式方法,

看有沒有獲得這個曲線特徵(Feature)裡樣條曲線物件(Spline)的,這裡可能會有人問為啥是Spline型別,

而不是line或者circle型別。

答案就是上面我們錄製出來的程式碼就是Spline物件型別,說明它就是Spline。

不相信的話,還可以自己拿移刀去檢視下。

下面去找獲得連線曲線特徵裡的樣條曲線物件方法

就是這個

其實我也不知道是這個,反正是挨個get去測試的,列印輸出,剛好到它這裡,輸出的就是spline型別

下面直接拿它返回的NXObject去用UFUN設定顏色就行了

        //將joinCurvesBuilder1生成的NXObject物件轉換成Features::JoinCurves連線曲線物件(它是特徵型別,並不是曲線型別),怎麼轉換的,錄製得出來的(方式1)
        NXOpen::Features::JoinCurves *joinCurves1(dynamic_cast<NXOpen::Features::JoinCurves *>(nXObject1));

        //返回連線曲線特徵建立的曲線物件(NXOPEN方式)
        std::vector< NXOpen::NXObject *>spline = joinCurves1->GetEntities();

        //輸出型別
        int type, subtype = 0;
        UF_OBJ_ask_type_and_subtype(spline[0]->Tag(), &type, &subtype);

        ////設定曲線顏色(UFUN)
        //UF_OBJ_set_color(spline[0]->Tag(), color_num);

如果不想用UFUN去設定顏色,想用NXOPEN設定顏色也可以的。

        //設定曲線顏色(NXOPEN)
        NXOpen::DisplayModification *displayModification1;
        displayModification1 = theSession->DisplayManager()->NewDisplayModification();
        displayModification1->SetApplyToAllFaces(true);
        displayModification1->SetApplyToOwningParts(false);
        displayModification1->SetNewColor(186);//顏色號碼
        std::vector<NXOpen::DisplayableObject *> objects1(1);
        //轉換
        NXOpen::Spline *spline1(dynamic_cast<NXOpen::Spline *>(joinCurves1->FindObject(spline[0]->JournalIdentifier())));
        objects1[0] = spline1;
        displayModification1->Apply(objects1);
        delete displayModification1;

這段程式碼也是錄製出來的,只要把轉換的那一句傳引數改掉就行了,

重點是NXOpen::Spline *spline1(dynamic_cast<NXOpen::Spline *>(joinCurves1->FindObject("CURVE 1")));這句

裡面傳入的是CURVE物件型別

我們上面std::vector< NXOpen::NXObject *>spline = joinCurves1->GetEntities();返回的就是curve物件型別

spline是歸屬於curve的,line,arc等都是屬於curve型別的。

我們拿這個引數值去傳入進去

NXOpen::Spline *spline1(dynamic_cast<NXOpen::Spline *>(joinCurves1->FindObject(spline[0]->JournalIdentifier())));

至於為什麼->JournalIdentifier()這樣寫,也是出自幫助的。

我們看上面joinCurves1->FindObject("")括號裡寫的是曲線物件的名字,直接find就是找到了,拿過來用。

而->JournalIdentifier()返回的也是個字串物件的名字

沒辦法,英語不會,軟肋,全程靠翻譯。

方法2單段錄製,跟上一種差不多。

就是先錄連線曲線的程式碼,然後停掉,

在開始錄製修改顏色的程式碼,錄它型別轉換,find物件的程式碼。

要的就是資料型別,和輸入輸出引數。

    NXOpen::Features::JoinCurves *joinCurves1(dynamic_cast<NXOpen::Features::JoinCurves *>(workPart->Features()->FindObject("JOIN_CURVE(54)")));

這句和上面那句是等價的,用哪個都可以的。

更改傳參方式,也是直接nXObject1->JournalIdentifier得到字串的名字傳入進去

        ////另外一種錄製出來的轉換方式(方式2)
        //NXOpen::Features::JoinCurves *joinCurves1(dynamic_cast<NXOpen::Features::JoinCurves *>(workPart->Features()->FindObject(nXObject1->JournalIdentifier())));

講到這裡這個例子也就結束了,

用NXOPEN的要點就是

1.會錄程式碼

2.會刪除沒用不需要的程式碼

3.資料型別轉換,更改傳參的值,就跟你自己封裝的函式,輸入的引數是int還是double資料型別一回事,錄出來的程式碼要啥物件型別,你就傳啥

不知道怎麼強制轉換,沒關係,那就去錄程式碼。

幾種轉換方式

1.遇到FindObject的就傳入用->JournalIdentifier()

2.遇到NXOPEN轉UFUN的就直接->tag

3.遇到UFUN轉NXOPEN的就直接NXOpen::NXObjectManager::Get(tag)

相關參考資料

https://www.cnblogs.com/nxopen2018/p/10957445.html

https://www.cnblogs.com/nxopen2018/category/2021548.html

阿飛

2021年8月29日