【错误分析】NX error status: 32

在使用NX制图软件时,若遇到表格注释合并单元格时报错NXerrorstatus:32的情况,可能并非由直接操作引起。通过检查前面的代码逻辑,清理标注操作等步骤,可以有效定位并解决问题。本文提供了解决此类问题的方法和思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在进行NX 制图里面的表格注释合并单元格时,总是报错NX error status: 32,找了很久都不知道问题所在。

报错提示如下:

NXOpen.NXException: NX error status: 32

NXOpen.UF.UFTabnot.MergeCells(Tag start_cell, Tag end_cell)

 

后来发现我们代码有问题的地方根本不在这一块,而是在别的地方。比如之前进行标注的报错,没有清理等等。

当遇到这种情况时,不妨看看前面的代码是否有问题。

转载于:https://www.cnblogs.com/bizca/p/5359203.html

我正在学习NX二次开发,用的是Visual Studio 2019,ug版本是12.0,开发平台是c++,uf函数为主nxopen函数为辅。需要你辅助我开发,重点注意开发模版是c++,优先使用uf函数,要求你先搞清楚你提供给我的代码真实有效性,语句与标点符号的正确位置,避免出现ug12.0没有提供的接口成员出现!确保所有方法调用都符合 NX12 的 API 签名,深度思考下再回答,每次回答前先回顾下前面的所有对话避免问题重复出现,每行代码都用中文注解具体意思与作用。int qiaowei_tool::apply_cb() { int errorCode = 0; // 错误代码,0表示成功 try { // 获取NX会话和工作部件 NXOpen::Session* theSession = NXOpen::Session::GetSession(); NXOpen::Part* workPart = theSession->Parts()->Work(); NXOpen::UI* theUI = NXOpen::UI::GetUI(); // ===== 1. 获取边界边曲线 ===== std::vector<NXOpen::Curve*> boundaryCurves; if (bianjie_edge) { // 获取曲线选择器属性列表 std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(bianjie_edge->GetProperties()); // 获取选中的对象集合 std::vector<NXOpen::TaggedObject*> selObjs = props->GetTaggedObjectVector("SelectedObjects"); // 遍历选中对象并转换为曲线 for (NXOpen::TaggedObject* obj : selObjs) { if (NXOpen::Curve* curve = dynamic_cast<NXOpen::Curve*>(obj)) { boundaryCurves.push_back(curve); } } } // ===== 2. 获取出料边曲线 ===== std::vector<NXOpen::Curve*> dischargeCurves; if (chuliao_edge) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(chuliao_edge->GetProperties()); std::vector<NXOpen::TaggedObject*> selObjs = props->GetTaggedObjectVector("SelectedObjects"); for (NXOpen::TaggedObject* obj : selObjs) { if (NXOpen::Curve* curve = dynamic_cast<NXOpen::Curve*>(obj)) { dischargeCurves.push_back(curve); } } } // ===== 3. 获取出料沉桥值 ===== double materialThickness = 0.0; if (expression_clcq) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(expression_clcq->GetProperties()); // 获取表达式数值 materialThickness = props->GetDouble("Value"); } // ===== 4. 获取上模厚度值 ===== double scanHeight = 0.0; if (expression_smh) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(expression_smh->GetProperties()); scanHeight = props->GetDouble("Value"); } // ===== 5. 获取进料沉桥值 ===== double clearanceValue = 0.0; if (expression_jlcq) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(expression_jlcq->GetProperties()); clearanceValue = props->GetDouble("Value"); } // ===== 6. 获取倒桥角度值 ===== double currentAngle = 0.0; if (expression_dqjiaodu) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(expression_dqjiaodu->GetProperties()); currentAngle = props->GetDouble("Value"); } // ===== 7. 获取倒角开关状态 ===== bool chamferToggle = false; if (toggle_daojiao) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(toggle_daojiao->GetProperties()); // 获取开关状态(选中/未选中) chamferToggle = props->GetLogical("Value"); } // ===== 8. 获取倒角半径值 ===== double chamferRadius = 0.0; if (expression_rjiao && chamferToggle) // 仅在倒角开启时获取 { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(expression_rjiao->GetProperties()); chamferRadius = props->GetDouble("Value"); } // ===== 9. 获取偏移开关状态 ===== bool offsetToggle = false; if (toggle_pianzhi) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(toggle_pianzhi->GetProperties()); offsetToggle = props->GetLogical("Value"); } // ===== 10. 获取偏移距离值 ===== double offsetDistance = 0.0; if (expression_pianzhi && offsetToggle) // 仅在偏移开启时获取 { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(expression_pianzhi->GetProperties()); offsetDistance = props->GetDouble("Value"); } // ===== 11. 获取矢量方向 ===== NXOpen::Vector3d directionVector(0.0, 0.0, 1.0); // 默认Z轴方向 if (vector0) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(vector0->GetProperties()); // 获取用户指定的矢量方向 directionVector = props->GetVector("Vector"); } // ===== 12. 验证必要输入 ===== if (boundaryCurves.size() < 2) { throw std::runtime_error("需要选择两条桥位边界曲线!"); } if (dischargeCurves.empty()) { throw std::runtime_error("出料边曲线未选择!"); } if (scanHeight <= 0) { throw std::runtime_error("上模厚度必须大于0!"); } // ===== 13. 计算两条边界曲线端点间的最短距离并创建两条连接直线 ===== tag_t line1Tag = NULL_TAG; tag_t line2Tag = NULL_TAG; double minDist = 0.0; double remainingDist = 0.0; try { // 获取前两条边界曲线 NXOpen::Curve* curve1 = boundaryCurves[0]; NXOpen::Curve* curve2 = boundaryCurves[1]; // 获取曲线端点 double curve1Start[3] = { 0.0 }, curve1End[3] = { 0.0 }; double curve2Start[3] = { 0.0 }, curve2End[3] = { 0.0 }; // 获取曲线1端点 UF_EVAL_p_t evaluator1 = NULL; if (UF_EVAL_initialize(curve1->Tag(), &evaluator1) != 0) { throw std::runtime_error("无法初始化曲线1的评估器"); } double limits1[2]; if (UF_EVAL_ask_limits(evaluator1, limits1) != 0) { UF_EVAL_free(evaluator1); throw std::runtime_error("无法获取曲线1的参数范围"); } if (limits1[0] > limits1[1]) std::swap(limits1[0], limits1[1]); if (UF_EVAL_evaluate(evaluator1, 0, limits1[0], curve1Start, NULL) != 0 || UF_EVAL_evaluate(evaluator1, 0, limits1[1], curve1End, NULL) != 0) { UF_EVAL_free(evaluator1); throw std::runtime_error("无法评估曲线1的端点"); } UF_EVAL_free(evaluator1); // 获取曲线2端点 UF_EVAL_p_t evaluator2 = NULL; if (UF_EVAL_initialize(curve2->Tag(), &evaluator2) != 0) { throw std::runtime_error("无法初始化曲线2的评估器"); } double limits2[2]; if (UF_EVAL_ask_limits(evaluator2, limits2) != 0) { UF_EVAL_free(evaluator2); throw std::runtime_error("无法获取曲线2的参数范围"); } if (limits2[0] > limits2[1]) std::swap(limits2[0], limits2[1]); if (UF_EVAL_evaluate(evaluator2, 0, limits2[0], curve2Start, NULL) != 0 || UF_EVAL_evaluate(evaluator2, 0, limits2[1], curve2End, NULL) != 0) { UF_EVAL_free(evaluator2); throw std::runtime_error("无法评估曲线2的端点"); } UF_EVAL_free(evaluator2); // 转换为NXOpen点对象 NXOpen::Point3d p1_start(curve1Start[0], curve1Start[1], curve1Start[2]); NXOpen::Point3d p1_end(curve1End[0], curve1End[1], curve1End[2]); NXOpen::Point3d p2_start(curve2Start[0], curve2Start[1], curve2Start[2]); NXOpen::Point3d p2_end(curve2End[0], curve2End[1], curve2End[2]); // 计算两点间距离的函数 auto distance = [](const NXOpen::Point3d& a, const NXOpen::Point3d& b) -> double { return sqrt(pow(a.X - b.X, 2) + pow(a.Y - b.Y, 2) + pow(a.Z - b.Z, 2)); }; // 计算四种可能的端点组合距离 double dist1 = distance(p1_start, p2_start); double dist2 = distance(p1_start, p2_end); double dist3 = distance(p1_end, p2_start); double dist4 = distance(p1_end, p2_end); // 找出最小距离对应的点对 minDist = std::min({ dist1, dist2, dist3, dist4 }); NXOpen::Point3d minPoint1, minPoint2; int minIndex = 0; if (minDist == dist1) { minPoint1 = p1_start; minPoint2 = p2_start; } else if (minDist == dist2) { minPoint1 = p1_start; minPoint2 = p2_end; } else if (minDist == dist3) { minPoint1 = p1_end; minPoint2 = p2_start; } else { minPoint1 = p1_end; minPoint2 = p2_end; } // 确定剩余的两个端点 auto isPointEqual = [](const NXOpen::Point3d& a, const NXOpen::Point3d& b, double tol = 1e-6) -> bool { return (fabs(a.X - b.X) < tol) && (fabs(a.Y - b.Y) < tol) && (fabs(a.Z - b.Z) < tol); }; NXOpen::Point3d remainingPoint1 = isPointEqual(minPoint1, p1_start) ? p1_end : p1_start; NXOpen::Point3d remainingPoint2 = isPointEqual(minPoint2, p2_start) ? p2_end : p2_start; remainingDist = distance(remainingPoint1, remainingPoint2); // ===== 创建两条连接直线 ===== // 创建第一条直线(最短距离连接) UF_CURVE_line_t line1Coords; line1Coords.start_point[0] = minPoint1.X; line1Coords.start_point[1] = minPoint1.Y; line1Coords.start_point[2] = minPoint1.Z; line1Coords.end_point[0] = minPoint2.X; line1Coords.end_point[1] = minPoint2.Y; line1Coords.end_point[2] = minPoint2.Z; if (UF_CURVE_create_line(&line1Coords, &line1Tag) != 0 || line1Tag == NULL_TAG) { throw std::runtime_error("创建最短距离直线失败"); } // 设置第一条直线属性 int workLayer = workPart->Layers()->WorkLayer(); UF_OBJ_set_layer(line1Tag, 254); // 创建第二条直线(剩余端点连接) UF_CURVE_line_t line2Coords; line2Coords.start_point[0] = remainingPoint1.X; line2Coords.start_point[1] = remainingPoint1.Y; line2Coords.start_point[2] = remainingPoint1.Z; line2Coords.end_point[0] = remainingPoint2.X; line2Coords.end_point[1] = remainingPoint2.Y; line2Coords.end_point[2] = remainingPoint2.Z; if (UF_CURVE_create_line(&line2Coords, &line2Tag) != 0 || line2Tag == NULL_TAG) { throw std::runtime_error("创建剩余端点直线失败"); } // 设置第二条直线属性 UF_OBJ_set_layer(line2Tag, 254); UF_LAYER_set_status(254, UF_LAYER_INACTIVE_LAYER); // 更新显示 UF_DISP_refresh(); // 显示成功信息 char msg[256]; snprintf(msg, sizeof(msg), "已创建两条连接直线:\n" "1. 最短距离直线: %.2f mm\n" "2. 剩余端点直线: %.2f mm", minDist, remainingDist); theUI->NXMessageBox()->Show("操作成功", NXOpen::NXMessageBox::DialogTypeInformation, msg); } catch (std::exception& ex) { char errMsg[256]; snprintf(errMsg, sizeof(errMsg), "端点距离计算或直线创建失败: %s", ex.what()); theUI->NXMessageBox()->Show("错误", NXOpen::NXMessageBox::DialogTypeError, errMsg); errorCode = 2; return errorCode; // 提前返回,不再继续后续操作 } // ===== 14. 创建拉伸特征(新建体) ===== try { // 设置撤销标记 NXOpen::Session::UndoMarkId markId = theSession->SetUndoMark( NXOpen::Session::MarkVisibilityVisible, "桥位拉伸"); // 创建拉伸构建器 NXOpen::Features::ExtrudeBuilder* extrudeBuilder = workPart->Features()->CreateExtrudeBuilder(nullptr); // 创建截面 NXOpen::Section* section = workPart->Sections()->CreateSection( 0.001, 0.001, 0.05); extrudeBuilder->SetSection(section); // 准备截面曲线:边界曲线 + 连接直线 std::vector<NXOpen::Curve*> sectionCurves; sectionCurves.push_back(boundaryCurves[0]); sectionCurves.push_back(boundaryCurves[1]); // 将直线标签转换为曲线对象 NXOpen::Curve* line1Curve = dynamic_cast<NXOpen::Curve*>( NXOpen::NXObjectManager::Get(line1Tag)); NXOpen::Curve* line2Curve = dynamic_cast<NXOpen::Curve*>( NXOpen::NXObjectManager::Get(line2Tag)); if (line1Curve) sectionCurves.push_back(line1Curve); if (line2Curve) sectionCurves.push_back(line2Curve); // 创建曲线规则 std::vector<NXOpen::SelectionIntentRule*> rules; if (!sectionCurves.empty()) { NXOpen::SelectionIntentRule* curveRule = workPart->ScRuleFactory()->CreateRuleCurveDumb(sectionCurves); rules.push_back(curveRule); } // 获取帮助点(中点) NXOpen::Point3d helpPoint(0.0, 0.0, 0.0); if (!sectionCurves.empty()) { tag_t curveTag = sectionCurves[0]->Tag(); UF_EVAL_p_t evaluator = NULL; double limits[2]; if (UF_EVAL_initialize(curveTag, &evaluator) == 0) { if (UF_EVAL_ask_limits(evaluator, limits) == 0) { if (limits[0] > limits[1]) std::swap(limits[0], limits[1]); double midParam = (limits[0] + limits[1]) / 2.0; double midPoint[3]; if (UF_EVAL_evaluate(evaluator, 0, midParam, midPoint, NULL) == 0) { helpPoint = NXOpen::Point3d(midPoint[0], midPoint[1], midPoint[2]); } } UF_EVAL_free(evaluator); } } // 添加到截面 section->AddToSection( rules, sectionCurves[0], NULL, NULL, helpPoint, NXOpen::Section::ModeCreate ); // 设置拉伸方向 NXOpen::Point3d origin(0.0, 0.0, 0.0); NXOpen::Direction* extrudeDirection = workPart->Directions()->CreateDirection( origin, directionVector, NXOpen::SmartObject::UpdateOptionWithinModeling ); extrudeBuilder->SetDirection(extrudeDirection); // 设置拉伸范围 NXOpen::GeometricUtilities::Limits* limitsObj = extrudeBuilder->Limits(); limitsObj->StartExtend()->Value()->SetRightHandSide( std::to_string(materialThickness).c_str()); double endDistance = scanHeight - clearanceValue; limitsObj->EndExtend()->Value()->SetRightHandSide( std::to_string(endDistance).c_str()); // ===== 设置布尔操作为新建体 ===== extrudeBuilder->BooleanOperation()->SetType( NXOpen::GeometricUtilities::BooleanOperation::BooleanTypeCreate); // ===== 执行拉伸操作 ===== try { // 提交拉伸操作 NXOpen::NXObject* featureNXObject = extrudeBuilder->Commit(); // 将特征对象转换为Extrude类型 NXOpen::Features::Extrude* extrudeFeature = dynamic_cast<NXOpen::Features::Extrude*>(featureNXObject); if (extrudeFeature) { // 正确获取拉伸创建的实体 std::vector<NXOpen::Body*> resultBodies = extrudeFeature->GetBodies(); // 显示结果信息 char successMsg[256]; if (!resultBodies.empty()) { snprintf(successMsg, sizeof(successMsg), "创建新实体成功!\n实体数量: %d\n起始距离: %.2f mm\n结束距离: %.2f mm", resultBodies.size(), materialThickness, endDistance); } else { snprintf(successMsg, sizeof(successMsg), "拉伸操作完成但未创建实体!\n起始距离: %.2f mm\n结束距离: %.2f mm", materialThickness, endDistance); } theUI->NXMessageBox()->Show("操作结果", NXOpen::NXMessageBox::DialogTypeInformation, successMsg); } else { throw std::runtime_error("创建的特征不是拉伸类型"); } // 清理资源 extrudeBuilder->Destroy(); section->Destroy(); } catch (std::exception& ex) { // 拉伸操作错误处理 char errMsg[256]; snprintf(errMsg, sizeof(errMsg), "拉伸操作失败: %s", ex.what()); theUI->NXMessageBox()->Show("错误", NXOpen::NXMessageBox::DialogTypeError, errMsg); errorCode = 3; // 特殊错误处理:布尔操作冲突 if (std::string(ex.what()).find("boolean") != std::string::npos) { theUI->NXMessageBox()->Show("布尔操作错误", NXOpen::NXMessageBox::DialogTypeError, "请检查布尔操作设置是否与现有几何冲突"); errorCode = 4; } // 确保资源被清理 if (extrudeBuilder) extrudeBuilder->Destroy(); if (section) section->Destroy(); } } catch (std::exception& ex) { // 外层异常处理 char errMsg[256]; snprintf(errMsg, sizeof(errMsg), "拉伸特征创建过程出错: %s", ex.what()); theUI->NXMessageBox()->Show("错误", NXOpen::NXMessageBox::DialogTypeError, errMsg); errorCode = 5; } // 刷新显示 UF_DISP_refresh(); } catch (std::exception& ex) { // 异常处理 char errMsg[256]; snprintf(errMsg, sizeof(errMsg), "操作失败: %s", ex.what()); qiaowei_tool::theUI->NXMessageBox()->Show("错误", NXOpen::NXMessageBox::DialogTypeError, errMsg); errorCode = 1; } return errorCode; } 。我需要在拉伸后处理“chuliao_edge”里面的两条曲线,先拿出一条曲线做曲线长度,参考以下操作记录文件:// NX 12.0.2.9 // Journal created by MiCH-CEO on Fri Aug 8 22:41:18 2025 中国标准时间 // #include <uf_defs.h> #include <NXOpen/NXException.hxx> #include <NXOpen/Session.hxx> #include <NXOpen/BasePart.hxx> #include <NXOpen/Builder.hxx> #include <NXOpen/CurveDumbRule.hxx> #include <NXOpen/Expression.hxx> #include <NXOpen/Features_AssociativeLine.hxx> #include <NXOpen/Features_CurveLengthBuilder.hxx> #include <NXOpen/Features_FeatureCollection.hxx> #include <NXOpen/GeometricUtilities_CurveLengthData.hxx> #include <NXOpen/GeometricUtilities_CurveOptions.hxx> #include <NXOpen/IBaseCurve.hxx> #include <NXOpen/Line.hxx> #include <NXOpen/NXObject.hxx> #include <NXOpen/Part.hxx> #include <NXOpen/PartCollection.hxx> #include <NXOpen/ScRuleFactory.hxx> #include <NXOpen/Section.hxx> #include <NXOpen/SectionCollection.hxx> #include <NXOpen/SelectionIntentRule.hxx> #include <NXOpen/Session.hxx> #include <NXOpen/Unit.hxx> #include <NXOpen/Update.hxx> // We are currently testing removal of using namespace NXOpen. // Uncomment the below line if your journal does not compile. // 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: 编辑(E)->曲线(V)->长度(L)... // ---------------------------------------------- NXOpen::Session::UndoMarkId markId1; markId1 = theSession->SetUndoMark(NXOpen::Session::MarkVisibilityVisible, NXOpen::NXString("\345\274\200\345\247\213", NXOpen::NXString::UTF8)); NXOpen::Section *section1; section1 = workPart->Sections()->CreateSection(0.00095, 0.001, 0.5); NXOpen::Features::Feature *nullNXOpen_Features_Feature(NULL); NXOpen::Features::CurveLengthBuilder *curveLengthBuilder1; curveLengthBuilder1 = workPart->Features()->CreateCurvelengthBuilder(nullNXOpen_Features_Feature); curveLengthBuilder1->SetSection(section1); curveLengthBuilder1->SetDistanceTolerance(0.001); theSession->SetUndoMarkName(markId1, NXOpen::NXString("\346\233\262\347\272\277\351\225\277\345\272\246 \345\257\271\350\257\235\346\241\206", NXOpen::NXString::UTF8)); curveLengthBuilder1->CurvelengthData()->SetExtensionMethod(NXOpen::GeometricUtilities::ExtensionMethodIncremental); curveLengthBuilder1->CurvelengthData()->SetExtensionSide(NXOpen::GeometricUtilities::ExtensionSideSymmetric); curveLengthBuilder1->CurvelengthData()->SetExtensionDirection(NXOpen::GeometricUtilities::ExtensionDirectionNatural); section1->SetDistanceTolerance(0.001); section1->SetChainingTolerance(0.00095); curveLengthBuilder1->CurvelengthData()->SetStartDistance("0"); curveLengthBuilder1->CurvelengthData()->SetEndDistance("0"); section1->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); theSession->UndoToMark(markId3, NULL); std::vector<NXOpen::IBaseCurve *> curves1(1); NXOpen::Features::AssociativeLine *associativeLine1(dynamic_cast<NXOpen::Features::AssociativeLine *>(workPart->Features()->FindObject("LINE(6)"))); NXOpen::Line *line1(dynamic_cast<NXOpen::Line *>(associativeLine1->FindObject("CURVE 1"))); curves1[0] = line1; NXOpen::CurveDumbRule *curveDumbRule1; curveDumbRule1 = workPart->ScRuleFactory()->CreateRuleBaseCurveDumb(curves1); section1->AllowSelfIntersection(true); std::vector<NXOpen::SelectionIntentRule *> rules1(1); rules1[0] = curveDumbRule1; NXOpen::NXObject *nullNXOpen_NXObject(NULL); NXOpen::Point3d helpPoint1(38.801255969220286, -24.161642792657258, 1.7763568394002505e-15); section1->AddToSection(rules1, line1, nullNXOpen_NXObject, nullNXOpen_NXObject, helpPoint1, NXOpen::Section::ModeCreate, false); theSession->DeleteUndoMark(markId3, NULL); curveLengthBuilder1->CurvelengthData()->SetStartDistance("0"); curveLengthBuilder1->CurvelengthData()->SetEndDistance("0"); curveLengthBuilder1->CurvelengthData()->SetStartDistance("0"); curveLengthBuilder1->CurvelengthData()->SetEndDistance("0"); curveLengthBuilder1->CurvelengthData()->SetStartDistance("0"); curveLengthBuilder1->CurvelengthData()->SetEndDistance("0"); curveLengthBuilder1->CurvelengthData()->SetStartDistance("0"); curveLengthBuilder1->CurvelengthData()->SetEndDistance("0"); theSession->DeleteUndoMark(markId2, NULL); curveLengthBuilder1->CurvelengthData()->SetStartDistance("100"); curveLengthBuilder1->CurvelengthData()->SetEndDistance("100"); curveLengthBuilder1->CurvelengthData()->SetStartDistance("100"); curveLengthBuilder1->CurvelengthData()->SetEndDistance("100"); NXOpen::Session::UndoMarkId markId4; markId4 = theSession->SetUndoMark(NXOpen::Session::MarkVisibilityInvisible, NXOpen::NXString("\346\233\262\347\272\277\351\225\277\345\272\246", NXOpen::NXString::UTF8)); theSession->DeleteUndoMark(markId4, NULL); NXOpen::Session::UndoMarkId markId5; markId5 = theSession->SetUndoMark(NXOpen::Session::MarkVisibilityInvisible, NXOpen::NXString("\346\233\262\347\272\277\351\225\277\345\272\246", NXOpen::NXString::UTF8)); NXOpen::NXObject *nXObject1; nXObject1 = curveLengthBuilder1->Commit(); theSession->DeleteUndoMark(markId5, NULL); theSession->SetUndoMarkName(markId1, NXOpen::NXString("\346\233\262\347\272\277\351\225\277\345\272\246", NXOpen::NXString::UTF8)); section1->CleanMappingData(); section1->CleanMappingData(); NXOpen::Expression *expression1(curveLengthBuilder1->CurvelengthData()->StartDistance()); curveLengthBuilder1->Destroy(); NXOpen::Session::UndoMarkId id1; id1 = theSession->GetNewestUndoMark(NXOpen::Session::MarkVisibilityVisible); int nErrs1; nErrs1 = theSession->UpdateManager()->DoUpdate(id1); // ---------------------------------------------- // Menu: 工具(T)->操作记录(J)->停止录制(S) // ---------------------------------------------- }
08-09
int qiaowei_tool::apply_cb() { int errorCode = 0; // 错误代码,0表示成功 try { // 获取NX会话和工作部件 NXOpen::Session* theSession = NXOpen::Session::GetSession(); NXOpen::Part* workPart = theSession->Parts()->Work(); NXOpen::UI* theUI = NXOpen::UI::GetUI(); // ===== 1. 获取边界边曲线 ===== std::vector<NXOpen::Curve*> boundaryCurves; if (bianjie_edge) { // 获取曲线选择器属性列表 std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(bianjie_edge->GetProperties()); // 获取选中的对象集合 std::vector<NXOpen::TaggedObject*> selObjs = props->GetTaggedObjectVector("SelectedObjects"); // 遍历选中对象并转换为曲线 for (NXOpen::TaggedObject* obj : selObjs) { if (NXOpen::Curve* curve = dynamic_cast<NXOpen::Curve*>(obj)) { boundaryCurves.push_back(curve); } } } // ===== 2. 获取出料边曲线 ===== std::vector<NXOpen::Curve*> dischargeCurves; if (chuliao_edge) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(chuliao_edge->GetProperties()); std::vector<NXOpen::TaggedObject*> selObjs = props->GetTaggedObjectVector("SelectedObjects"); for (NXOpen::TaggedObject* obj : selObjs) { if (NXOpen::Curve* curve = dynamic_cast<NXOpen::Curve*>(obj)) { dischargeCurves.push_back(curve); } } } // ===== 3. 获取出料沉桥值 ===== double materialThickness = 0.0; if (expression_clcq) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(expression_clcq->GetProperties()); // 获取表达式数值 materialThickness = props->GetDouble("Value"); } // ===== 4. 获取上模厚度值 ===== double scanHeight = 0.0; if (expression_smh) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(expression_smh->GetProperties()); scanHeight = props->GetDouble("Value"); } // ===== 5. 获取进料沉桥值 ===== double clearanceValue = 0.0; if (expression_jlcq) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(expression_jlcq->GetProperties()); clearanceValue = props->GetDouble("Value"); } // ===== 6. 获取倒桥角度值 ===== double currentAngle = 0.0; if (expression_dqjiaodu) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(expression_dqjiaodu->GetProperties()); currentAngle = props->GetDouble("Value"); } // ===== 7. 获取倒角开关状态 ===== bool chamferToggle = false; if (toggle_daojiao) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(toggle_daojiao->GetProperties()); // 获取开关状态(选中/未选中) chamferToggle = props->GetLogical("Value"); } // ===== 8. 获取倒角半径值 ===== double chamferRadius = 0.0; if (expression_rjiao && chamferToggle) // 仅在倒角开启时获取 { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(expression_rjiao->GetProperties()); chamferRadius = props->GetDouble("Value"); } // ===== 9. 获取偏移开关状态 ===== bool offsetToggle = false; if (toggle_pianzhi) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(toggle_pianzhi->GetProperties()); offsetToggle = props->GetLogical("Value"); } // ===== 10. 获取偏移距离值 ===== double offsetDistance = 0.0; if (expression_pianzhi && offsetToggle) // 仅在偏移开启时获取 { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(expression_pianzhi->GetProperties()); offsetDistance = props->GetDouble("Value"); } // ===== 11. 获取矢量方向 ===== NXOpen::Vector3d directionVector(0.0, 0.0, 1.0); // 默认Z轴方向 if (vector0) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(vector0->GetProperties()); // 获取用户指定的矢量方向 directionVector = props->GetVector("Vector"); } // ===== 12. 验证必要输入 ===== if (boundaryCurves.size() < 2) { throw std::runtime_error("需要选择两条桥位边界曲线!"); } if (dischargeCurves.empty()) { throw std::runtime_error("出料边曲线未选择!"); } if (scanHeight <= 0) { throw std::runtime_error("上模厚度必须大于0!"); } // ===== 13. 计算两条边界曲线端点间的最短距离并创建两条连接直线 ===== tag_t line1Tag = NULL_TAG; tag_t line2Tag = NULL_TAG; double minDist = 0.0; double remainingDist = 0.0; try { // 获取前两条边界曲线 NXOpen::Curve* curve1 = boundaryCurves[0]; NXOpen::Curve* curve2 = boundaryCurves[1]; // 获取曲线端点 double curve1Start[3] = { 0.0 }, curve1End[3] = { 0.0 }; double curve2Start[3] = { 0.0 }, curve2End[3] = { 0.0 }; // 获取曲线1端点 UF_EVAL_p_t evaluator1 = NULL; if (UF_EVAL_initialize(curve1->Tag(), &evaluator1) != 0) { throw std::runtime_error("无法初始化曲线1的评估器"); } double limits1[2]; if (UF_EVAL_ask_limits(evaluator1, limits1) != 0) { UF_EVAL_free(evaluator1); throw std::runtime_error("无法获取曲线1的参数范围"); } if (limits1[0] > limits1[1]) std::swap(limits1[0], limits1[1]); if (UF_EVAL_evaluate(evaluator1, 0, limits1[0], curve1Start, NULL) != 0 || UF_EVAL_evaluate(evaluator1, 0, limits1[1], curve1End, NULL) != 0) { UF_EVAL_free(evaluator1); throw std::runtime_error("无法评估曲线1的端点"); } UF_EVAL_free(evaluator1); // 获取曲线2端点 UF_EVAL_p_t evaluator2 = NULL; if (UF_EVAL_initialize(curve2->Tag(), &evaluator2) != 0) { throw std::runtime_error("无法初始化曲线2的评估器"); } double limits2[2]; if (UF_EVAL_ask_limits(evaluator2, limits2) != 0) { UF_EVAL_free(evaluator2); throw std::runtime_error("无法获取曲线2的参数范围"); } if (limits2[0] > limits2[1]) std::swap(limits2[0], limits2[1]); if (UF_EVAL_evaluate(evaluator2, 0, limits2[0], curve2Start, NULL) != 0 || UF_EVAL_evaluate(evaluator2, 0, limits2[1], curve2End, NULL) != 0) { UF_EVAL_free(evaluator2); throw std::runtime_error("无法评估曲线2的端点"); } UF_EVAL_free(evaluator2); // 转换为NXOpen点对象 NXOpen::Point3d p1_start(curve1Start[0], curve1Start[1], curve1Start[2]); NXOpen::Point3d p1_end(curve1End[0], curve1End[1], curve1End[2]); NXOpen::Point3d p2_start(curve2Start[0], curve2Start[1], curve2Start[2]); NXOpen::Point3d p2_end(curve2End[0], curve2End[1], curve2End[2]); // 计算两点间距离的函数 auto distance = [](const NXOpen::Point3d& a, const NXOpen::Point3d& b) -> double { return sqrt(pow(a.X - b.X, 2) + pow(a.Y - b.Y, 2) + pow(a.Z - b.Z, 2)); }; // 计算四种可能的端点组合距离 double dist1 = distance(p1_start, p2_start); double dist2 = distance(p1_start, p2_end); double dist3 = distance(p1_end, p2_start); double dist4 = distance(p1_end, p2_end); // 找出最小距离对应的点对 minDist = std::min({ dist1, dist2, dist3, dist4 }); NXOpen::Point3d minPoint1, minPoint2; int minIndex = 0; if (minDist == dist1) { minPoint1 = p1_start; minPoint2 = p2_start; } else if (minDist == dist2) { minPoint1 = p1_start; minPoint2 = p2_end; } else if (minDist == dist3) { minPoint1 = p1_end; minPoint2 = p2_start; } else { minPoint1 = p1_end; minPoint2 = p2_end; } // 确定剩余的两个端点 auto isPointEqual = [](const NXOpen::Point3d& a, const NXOpen::Point3d& b, double tol = 1e-6) -> bool { return (fabs(a.X - b.X) < tol) && (fabs(a.Y - b.Y) < tol) && (fabs(a.Z - b.Z) < tol); }; NXOpen::Point3d remainingPoint1 = isPointEqual(minPoint1, p1_start) ? p1_end : p1_start; NXOpen::Point3d remainingPoint2 = isPointEqual(minPoint2, p2_start) ? p2_end : p2_start; remainingDist = distance(remainingPoint1, remainingPoint2); // ===== 创建两条连接直线 ===== // 创建第一条直线(最短距离连接) UF_CURVE_line_t line1Coords; line1Coords.start_point[0] = minPoint1.X; line1Coords.start_point[1] = minPoint1.Y; line1Coords.start_point[2] = minPoint1.Z; line1Coords.end_point[0] = minPoint2.X; line1Coords.end_point[1] = minPoint2.Y; line1Coords.end_point[2] = minPoint2.Z; if (UF_CURVE_create_line(&line1Coords, &line1Tag) != 0 || line1Tag == NULL_TAG) { throw std::runtime_error("创建最短距离直线失败"); } // 设置第一条直线属性 int workLayer = workPart->Layers()->WorkLayer(); UF_OBJ_set_layer(line1Tag, 254); // 创建第二条直线(剩余端点连接) UF_CURVE_line_t line2Coords; line2Coords.start_point[0] = remainingPoint1.X; line2Coords.start_point[1] = remainingPoint1.Y; line2Coords.start_point[2] = remainingPoint1.Z; line2Coords.end_point[0] = remainingPoint2.X; line2Coords.end_point[1] = remainingPoint2.Y; line2Coords.end_point[2] = remainingPoint2.Z; if (UF_CURVE_create_line(&line2Coords, &line2Tag) != 0 || line2Tag == NULL_TAG) { throw std::runtime_error("创建剩余端点直线失败"); } // 设置第二条直线属性 UF_OBJ_set_layer(line2Tag, 254); UF_LAYER_set_status(254, UF_LAYER_INACTIVE_LAYER); // 更新显示 UF_DISP_refresh(); // 显示成功信息 char msg[256]; snprintf(msg, sizeof(msg), "已创建两条连接直线:\n" "1. 最短距离直线: %.2f mm\n" "2. 剩余端点直线: %.2f mm", minDist, remainingDist); theUI->NXMessageBox()->Show("操作成功", NXOpen::NXMessageBox::DialogTypeInformation, msg); } catch (std::exception& ex) { char errMsg[256]; snprintf(errMsg, sizeof(errMsg), "端点距离计算或直线创建失败: %s", ex.what()); theUI->NXMessageBox()->Show("错误", NXOpen::NXMessageBox::DialogTypeError, errMsg); errorCode = 2; return errorCode; // 提前返回,不再继续后续操作 } // ===== 14. 创建拉伸特征(新建体) ===== try { // 设置撤销标记 NXOpen::Session::UndoMarkId markId = theSession->SetUndoMark( NXOpen::Session::MarkVisibilityVisible, "桥位拉伸"); // 创建拉伸构建器 NXOpen::Features::ExtrudeBuilder* extrudeBuilder = workPart->Features()->CreateExtrudeBuilder(nullptr); // 创建截面 NXOpen::Section* section = workPart->Sections()->CreateSection( 0.001, 0.001, 0.05); extrudeBuilder->SetSection(section); // 准备截面曲线:边界曲线 + 连接直线 std::vector<NXOpen::Curve*> sectionCurves; sectionCurves.push_back(boundaryCurves[0]); sectionCurves.push_back(boundaryCurves[1]); // 将直线标签转换为曲线对象 NXOpen::Curve* line1Curve = dynamic_cast<NXOpen::Curve*>( NXOpen::NXObjectManager::Get(line1Tag)); NXOpen::Curve* line2Curve = dynamic_cast<NXOpen::Curve*>( NXOpen::NXObjectManager::Get(line2Tag)); if (line1Curve) sectionCurves.push_back(line1Curve); if (line2Curve) sectionCurves.push_back(line2Curve); // 创建曲线规则 std::vector<NXOpen::SelectionIntentRule*> rules; if (!sectionCurves.empty()) { NXOpen::SelectionIntentRule* curveRule = workPart->ScRuleFactory()->CreateRuleCurveDumb(sectionCurves); rules.push_back(curveRule); } // 获取帮助点(中点) NXOpen::Point3d helpPoint(0.0, 0.0, 0.0); if (!sectionCurves.empty()) { tag_t curveTag = sectionCurves[0]->Tag(); UF_EVAL_p_t evaluator = NULL; double limits[2]; if (UF_EVAL_initialize(curveTag, &evaluator) == 0) { if (UF_EVAL_ask_limits(evaluator, limits) == 0) { if (limits[0] > limits[1]) std::swap(limits[0], limits[1]); double midParam = (limits[0] + limits[1]) / 2.0; double midPoint[3]; if (UF_EVAL_evaluate(evaluator, 0, midParam, midPoint, NULL) == 0) { helpPoint = NXOpen::Point3d(midPoint[0], midPoint[1], midPoint[2]); } } UF_EVAL_free(evaluator); } } // 添加到截面 section->AddToSection( rules, sectionCurves[0], NULL, NULL, helpPoint, NXOpen::Section::ModeCreate ); // 设置拉伸方向 NXOpen::Point3d origin(0.0, 0.0, 0.0); NXOpen::Direction* extrudeDirection = workPart->Directions()->CreateDirection( origin, directionVector, NXOpen::SmartObject::UpdateOptionWithinModeling ); extrudeBuilder->SetDirection(extrudeDirection); // 设置拉伸范围 NXOpen::GeometricUtilities::Limits* limitsObj = extrudeBuilder->Limits(); limitsObj->StartExtend()->Value()->SetRightHandSide( std::to_string(materialThickness).c_str()); double endDistance = scanHeight - clearanceValue; limitsObj->EndExtend()->Value()->SetRightHandSide( std::to_string(endDistance).c_str()); // ===== 设置布尔操作为新建体 ===== extrudeBuilder->BooleanOperation()->SetType( NXOpen::GeometricUtilities::BooleanOperation::BooleanTypeCreate); // ===== 执行拉伸操作 ===== try { // 提交拉伸操作 NXOpen::NXObject* featureNXObject = extrudeBuilder->Commit(); // 将特征对象转换为Extrude类型 NXOpen::Features::Extrude* extrudeFeature = dynamic_cast<NXOpen::Features::Extrude*>(featureNXObject); if (extrudeFeature) { // 正确获取拉伸创建的实体 std::vector<NXOpen::Body*> resultBodies = extrudeFeature->GetBodies(); // 显示结果信息 char successMsg[256]; if (!resultBodies.empty()) { snprintf(successMsg, sizeof(successMsg), "创建新实体成功!\n实体数量: %d\n起始距离: %.2f mm\n结束距离: %.2f mm", resultBodies.size(), materialThickness, endDistance); } else { snprintf(successMsg, sizeof(successMsg), "拉伸操作完成但未创建实体!\n起始距离: %.2f mm\n结束距离: %.2f mm", materialThickness, endDistance); } theUI->NXMessageBox()->Show("操作结果", NXOpen::NXMessageBox::DialogTypeInformation, successMsg); } else { throw std::runtime_error("创建的特征不是拉伸类型"); } // 清理资源 extrudeBuilder->Destroy(); section->Destroy(); } catch (std::exception& ex) { // 拉伸操作错误处理 char errMsg[256]; snprintf(errMsg, sizeof(errMsg), "拉伸操作失败: %s", ex.what()); theUI->NXMessageBox()->Show("错误", NXOpen::NXMessageBox::DialogTypeError, errMsg); errorCode = 3; // 特殊错误处理:布尔操作冲突 if (std::string(ex.what()).find("boolean") != std::string::npos) { theUI->NXMessageBox()->Show("布尔操作错误", NXOpen::NXMessageBox::DialogTypeError, "请检查布尔操作设置是否与现有几何冲突"); errorCode = 4; } // 确保资源被清理 if (extrudeBuilder) extrudeBuilder->Destroy(); if (section) section->Destroy(); } } catch (std::exception& ex) { // 外层异常处理 char errMsg[256]; snprintf(errMsg, sizeof(errMsg), "拉伸特征创建过程出错: %s", ex.what()); theUI->NXMessageBox()->Show("错误", NXOpen::NXMessageBox::DialogTypeError, errMsg); errorCode = 5; } // ===== 在拉伸操作成功后添加出料边曲线处理 ===== try { // 设置撤销标记 NXOpen::Session::UndoMarkId curveMarkId = theSession->SetUndoMark( NXOpen::Session::MarkVisibilityVisible, "出料边曲线长度编辑"); // 遍历所有出料边曲线 for (NXOpen::Curve* dischargeCurve : dischargeCurves) { // 创建截面对象 NXOpen::Section* section = workPart->Sections()->CreateSection( 0.00095, 0.001, 0.05); // 创建曲线长度构建器 NXOpen::Features::CurveLengthBuilder* curveLengthBuilder = workPart->Features()->CreateCurvelengthBuilder(nullptr); curveLengthBuilder->SetSection(section); curveLengthBuilder->SetDistanceTolerance(0.001); // 设置曲线延伸参数 curveLengthBuilder->CurvelengthData()->SetExtensionMethod( NXOpen::GeometricUtilities::ExtensionMethodIncremental); // 直接使用枚举值 curveLengthBuilder->CurvelengthData()->SetExtensionSide( NXOpen::GeometricUtilities::ExtensionSideSymmetric); curveLengthBuilder->CurvelengthData()->SetExtensionDirection( NXOpen::GeometricUtilities::ExtensionDirectionNatural); // 设置延伸距离(这里使用固定值100,实际应使用参数) curveLengthBuilder->CurvelengthData()->SetStartDistance("100"); curveLengthBuilder->CurvelengthData()->SetEndDistance("100"); // 创建选择规则 std::vector<NXOpen::IBaseCurve*> baseCurves(1); baseCurves[0] = dynamic_cast<NXOpen::IBaseCurve*>(dischargeCurve); if (!baseCurves[0]) continue; // 类型转换失败则跳过 NXOpen::CurveDumbRule* curveRule = workPart->ScRuleFactory()->CreateRuleBaseCurveDumb(baseCurves); // 计算曲线中点作为帮助点 double midParam = 0.0; double midPoint[3] = { 0 }; UF_EVAL_p_t evaluator = NULL; if (UF_EVAL_initialize(dischargeCurve->Tag(), &evaluator) == 0) { double limits[2]; if (UF_EVAL_ask_limits(evaluator, limits) == 0) { midParam = (limits[0] + limits[1]) / 2.0; UF_EVAL_evaluate(evaluator, 0, midParam, midPoint, NULL); } UF_EVAL_free(evaluator); } NXOpen::Point3d helpPoint(midPoint[0], midPoint[1], midPoint[2]); // 添加曲线到截面 std::vector<NXOpen::SelectionIntentRule*> rules(1); rules[0] = curveRule; section->AddToSection(rules, dischargeCurve, nullptr, nullptr, helpPoint, NXOpen::Section::ModeCreate, false); // 提交曲线长度特征 curveLengthBuilder->Commit(); // 清理资源 curveLengthBuilder->Destroy(); section->Destroy(); } // 更新模型 theSession->UpdateManager()->DoUpdate(curveMarkId); // 显示成功信息 char msg[256]; snprintf(msg, sizeof(msg), "已处理%d条出料边曲线", dischargeCurves.size()); theUI->NXMessageBox()->Show("曲线处理完成", NXOpen::NXMessageBox::DialogTypeInformation, msg); } catch (std::exception& ex) { char errMsg[256]; snprintf(errMsg, sizeof(errMsg), "曲线处理失败: %s", ex.what()); theUI->NXMessageBox()->Show("错误", NXOpen::NXMessageBox::DialogTypeError, errMsg); errorCode = 6; // 设置新的错误代码 } // 刷新显示 UF_DISP_refresh(); } catch (std::exception& ex) { // 异常处理 char errMsg[256]; snprintf(errMsg, sizeof(errMsg), "操作失败: %s", ex.what()); qiaowei_tool::theUI->NXMessageBox()->Show("错误", NXOpen::NXMessageBox::DialogTypeError, errMsg); errorCode = 1; } return errorCode; } 我需要在创建曲线长度后再创建一个拉伸,拉伸截面就是曲线长度的其中一条曲线,设置拉伸范围起始同上一个拉伸一样,结束是“scanHeight加10.”布尔跟第一个拉伸的实体求差,设置前拔模角度(从截面开始处拔模)角度为“expression_dqjiaodu”,拉伸偏置模式为两侧(偏置起始0,结束100),每行代码中文注解
最新发布
08-10
int qiaowei_tool::apply_cb() { int errorCode = 0; // 错误代码,0表示成功 NXOpen::Body* firstExtrudeBody = nullptr;// 将声明移到函数作用域 try { // 获取NX会话和工作部件 NXOpen::Session* theSession = NXOpen::Session::GetSession(); NXOpen::Part* workPart = theSession->Parts()->Work(); NXOpen::UI* theUI = NXOpen::UI::GetUI(); // ===== 1. 获取边界边曲线 ===== std::vector<NXOpen::Curve*> boundaryCurves; if (bianjie_edge) { // 获取曲线选择器属性列表 std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(bianjie_edge->GetProperties()); // 获取选中的对象集合 std::vector<NXOpen::TaggedObject*> selObjs = props->GetTaggedObjectVector("SelectedObjects"); // 遍历选中对象并转换为曲线 for (NXOpen::TaggedObject* obj : selObjs) { if (NXOpen::Curve* curve = dynamic_cast<NXOpen::Curve*>(obj)) { boundaryCurves.push_back(curve); } } } // ===== 2. 获取出料边曲线 ===== std::vector<NXOpen::Curve*> dischargeCurves; if (chuliao_edge) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(chuliao_edge->GetProperties()); std::vector<NXOpen::TaggedObject*> selObjs = props->GetTaggedObjectVector("SelectedObjects"); for (NXOpen::TaggedObject* obj : selObjs) { if (NXOpen::Curve* curve = dynamic_cast<NXOpen::Curve*>(obj)) { dischargeCurves.push_back(curve); } } } // ===== 3. 获取出料沉桥值 ===== double materialThickness = 0.0; if (expression_clcq) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(expression_clcq->GetProperties()); // 获取表达式数值 materialThickness = props->GetDouble("Value"); } // ===== 4. 获取上模厚度值 ===== double scanHeight = 0.0; if (expression_smh) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(expression_smh->GetProperties()); scanHeight = props->GetDouble("Value"); } // ===== 5. 获取进料沉桥值 ===== double clearanceValue = 0.0; if (expression_jlcq) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(expression_jlcq->GetProperties()); clearanceValue = props->GetDouble("Value"); } // ===== 6. 获取倒桥角度值 ===== double currentAngle = 0.0; if (expression_dqjiaodu) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(expression_dqjiaodu->GetProperties()); currentAngle = props->GetDouble("Value"); } // ===== 7. 获取倒角开关状态 ===== bool chamferToggle = false; if (toggle_daojiao) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(toggle_daojiao->GetProperties()); // 获取开关状态(选中/未选中) chamferToggle = props->GetLogical("Value"); } // ===== 8. 获取倒角半径值 ===== double chamferRadius = 0.0; if (expression_rjiao && chamferToggle) // 仅在倒角开启时获取 { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(expression_rjiao->GetProperties()); chamferRadius = props->GetDouble("Value"); } // ===== 9. 获取偏移开关状态 ===== bool offsetToggle = false; if (toggle_pianzhi) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(toggle_pianzhi->GetProperties()); offsetToggle = props->GetLogical("Value"); } // ===== 10. 获取偏移距离值 ===== double offsetDistance = 0.0; if (expression_pianzhi && offsetToggle) // 仅在偏移开启时获取 { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(expression_pianzhi->GetProperties()); offsetDistance = props->GetDouble("Value"); } // ===== 11. 获取矢量方向 ===== NXOpen::Vector3d directionVector(0.0, 0.0, 1.0); // 默认Z轴方向 if (vector0) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(vector0->GetProperties()); // 获取用户指定的矢量方向 directionVector = props->GetVector("Vector"); } // ===== 12. 验证必要输入 ===== if (boundaryCurves.size() < 2) { throw std::runtime_error("需要选择两条桥位边界曲线!"); } if (dischargeCurves.empty()) { throw std::runtime_error("出料边曲线未选择!"); } if (scanHeight <= 0) { throw std::runtime_error("上模厚度必须大于0!"); } // ===== 13. 计算两条边界曲线端点间的最短距离并创建两条连接直线 ===== tag_t line1Tag = NULL_TAG; tag_t line2Tag = NULL_TAG; double minDist = 0.0; double remainingDist = 0.0; try { // 获取前两条边界曲线 NXOpen::Curve* curve1 = boundaryCurves[0]; NXOpen::Curve* curve2 = boundaryCurves[1]; // 获取曲线端点 double curve1Start[3] = { 0.0 }, curve1End[3] = { 0.0 }; double curve2Start[3] = { 0.0 }, curve2End[3] = { 0.0 }; // 获取曲线1端点 UF_EVAL_p_t evaluator1 = NULL; if (UF_EVAL_initialize(curve1->Tag(), &evaluator1) != 0) { throw std::runtime_error("无法初始化曲线1的评估器"); } double limits1[2]; if (UF_EVAL_ask_limits(evaluator1, limits1) != 0) { UF_EVAL_free(evaluator1); throw std::runtime_error("无法获取曲线1的参数范围"); } if (limits1[0] > limits1[1]) std::swap(limits1[0], limits1[1]); if (UF_EVAL_evaluate(evaluator1, 0, limits1[0], curve1Start, NULL) != 0 || UF_EVAL_evaluate(evaluator1, 0, limits1[1], curve1End, NULL) != 0) { UF_EVAL_free(evaluator1); throw std::runtime_error("无法评估曲线1的端点"); } UF_EVAL_free(evaluator1); // 获取曲线2端点 UF_EVAL_p_t evaluator2 = NULL; if (UF_EVAL_initialize(curve2->Tag(), &evaluator2) != 0) { throw std::runtime_error("无法初始化曲线2的评估器"); } double limits2[2]; if (UF_EVAL_ask_limits(evaluator2, limits2) != 0) { UF_EVAL_free(evaluator2); throw std::runtime_error("无法获取曲线2的参数范围"); } if (limits2[0] > limits2[1]) std::swap(limits2[0], limits2[1]); if (UF_EVAL_evaluate(evaluator2, 0, limits2[0], curve2Start, NULL) != 0 || UF_EVAL_evaluate(evaluator2, 0, limits2[1], curve2End, NULL) != 0) { UF_EVAL_free(evaluator2); throw std::runtime_error("无法评估曲线2的端点"); } UF_EVAL_free(evaluator2); // 转换为NXOpen点对象 NXOpen::Point3d p1_start(curve1Start[0], curve1Start[1], curve1Start[2]); NXOpen::Point3d p1_end(curve1End[0], curve1End[1], curve1End[2]); NXOpen::Point3d p2_start(curve2Start[0], curve2Start[1], curve2Start[2]); NXOpen::Point3d p2_end(curve2End[0], curve2End[1], curve2End[2]); // 计算两点间距离的函数 auto distance = [](const NXOpen::Point3d& a, const NXOpen::Point3d& b) -> double { return sqrt(pow(a.X - b.X, 2) + pow(a.Y - b.Y, 2) + pow(a.Z - b.Z, 2)); }; // 计算四种可能的端点组合距离 double dist1 = distance(p1_start, p2_start); double dist2 = distance(p1_start, p2_end); double dist3 = distance(p1_end, p2_start); double dist4 = distance(p1_end, p2_end); // 找出最小距离对应的点对 minDist = std::min({ dist1, dist2, dist3, dist4 }); NXOpen::Point3d minPoint1, minPoint2; int minIndex = 0; if (minDist == dist1) { minPoint1 = p1_start; minPoint2 = p2_start; } else if (minDist == dist2) { minPoint1 = p1_start; minPoint2 = p2_end; } else if (minDist == dist3) { minPoint1 = p1_end; minPoint2 = p2_start; } else { minPoint1 = p1_end; minPoint2 = p2_end; } // 确定剩余的两个端点 auto isPointEqual = [](const NXOpen::Point3d& a, const NXOpen::Point3d& b, double tol = 1e-6) -> bool { return (fabs(a.X - b.X) < tol) && (fabs(a.Y - b.Y) < tol) && (fabs(a.Z - b.Z) < tol); }; NXOpen::Point3d remainingPoint1 = isPointEqual(minPoint1, p1_start) ? p1_end : p1_start; NXOpen::Point3d remainingPoint2 = isPointEqual(minPoint2, p2_start) ? p2_end : p2_start; remainingDist = distance(remainingPoint1, remainingPoint2); // ===== 创建两条连接直线 ===== // 创建第一条直线(最短距离连接) UF_CURVE_line_t line1Coords; line1Coords.start_point[0] = minPoint1.X; line1Coords.start_point[1] = minPoint1.Y; line1Coords.start_point[2] = minPoint1.Z; line1Coords.end_point[0] = minPoint2.X; line1Coords.end_point[1] = minPoint2.Y; line1Coords.end_point[2] = minPoint2.Z; if (UF_CURVE_create_line(&line1Coords, &line1Tag) != 0 || line1Tag == NULL_TAG) { throw std::runtime_error("创建最短距离直线失败"); } // 设置第一条直线属性 int workLayer = workPart->Layers()->WorkLayer(); UF_OBJ_set_layer(line1Tag, 254); // 创建第二条直线(剩余端点连接) UF_CURVE_line_t line2Coords; line2Coords.start_point[0] = remainingPoint1.X; line2Coords.start_point[1] = remainingPoint1.Y; line2Coords.start_point[2] = remainingPoint1.Z; line2Coords.end_point[0] = remainingPoint2.X; line2Coords.end_point[1] = remainingPoint2.Y; line2Coords.end_point[2] = remainingPoint2.Z; if (UF_CURVE_create_line(&line2Coords, &line2Tag) != 0 || line2Tag == NULL_TAG) { throw std::runtime_error("创建剩余端点直线失败"); } // 设置第二条直线属性 UF_OBJ_set_layer(line2Tag, 254); UF_LAYER_set_status(254, UF_LAYER_INACTIVE_LAYER); // 更新显示 UF_DISP_refresh(); // 显示成功信息 char msg[256]; snprintf(msg, sizeof(msg), "已创建两条连接直线:\n" "1. 最短距离直线: %.2f mm\n" "2. 剩余端点直线: %.2f mm", minDist, remainingDist); theUI->NXMessageBox()->Show("操作成功", NXOpen::NXMessageBox::DialogTypeInformation, msg); } catch (std::exception& ex) { char errMsg[256]; snprintf(errMsg, sizeof(errMsg), "端点距离计算或直线创建失败: %s", ex.what()); theUI->NXMessageBox()->Show("错误", NXOpen::NXMessageBox::DialogTypeError, errMsg); errorCode = 2; return errorCode; // 提前返回,不再继续后续操作 } // ===== 14. 创建拉伸特征(新建体) ===== try { // 设置撤销标记 NXOpen::Session::UndoMarkId markId = theSession->SetUndoMark( NXOpen::Session::MarkVisibilityVisible, "桥位拉伸"); // 创建拉伸构建器 NXOpen::Features::ExtrudeBuilder* extrudeBuilder = workPart->Features()->CreateExtrudeBuilder(nullptr); // 创建截面 NXOpen::Section* section = workPart->Sections()->CreateSection( 0.001, 0.001, 0.05); extrudeBuilder->SetSection(section); // 准备截面曲线:边界曲线 + 连接直线 std::vector<NXOpen::Curve*> sectionCurves; sectionCurves.push_back(boundaryCurves[0]); sectionCurves.push_back(boundaryCurves[1]); // 将直线标签转换为曲线对象 NXOpen::Curve* line1Curve = dynamic_cast<NXOpen::Curve*>( NXOpen::NXObjectManager::Get(line1Tag)); NXOpen::Curve* line2Curve = dynamic_cast<NXOpen::Curve*>( NXOpen::NXObjectManager::Get(line2Tag)); if (line1Curve) sectionCurves.push_back(line1Curve); if (line2Curve) sectionCurves.push_back(line2Curve); // 创建曲线规则 std::vector<NXOpen::SelectionIntentRule*> rules; if (!sectionCurves.empty()) { NXOpen::SelectionIntentRule* curveRule = workPart->ScRuleFactory()->CreateRuleCurveDumb(sectionCurves); rules.push_back(curveRule); } // 获取帮助点(中点) NXOpen::Point3d helpPoint(0.0, 0.0, 0.0); if (!sectionCurves.empty()) { tag_t curveTag = sectionCurves[0]->Tag(); UF_EVAL_p_t evaluator = NULL; double limits[2]; if (UF_EVAL_initialize(curveTag, &evaluator) == 0) { if (UF_EVAL_ask_limits(evaluator, limits) == 0) { if (limits[0] > limits[1]) std::swap(limits[0], limits[1]); double midParam = (limits[0] + limits[1]) / 2.0; double midPoint[3]; if (UF_EVAL_evaluate(evaluator, 0, midParam, midPoint, NULL) == 0) { helpPoint = NXOpen::Point3d(midPoint[0], midPoint[1], midPoint[2]); } } UF_EVAL_free(evaluator); } } // 添加到截面 section->AddToSection( rules, sectionCurves[0], NULL, NULL, helpPoint, NXOpen::Section::ModeCreate ); // 设置拉伸方向 NXOpen::Point3d origin(0.0, 0.0, 0.0); NXOpen::Direction* extrudeDirection = workPart->Directions()->CreateDirection( origin, directionVector, NXOpen::SmartObject::UpdateOptionWithinModeling ); extrudeBuilder->SetDirection(extrudeDirection); // 设置拉伸范围 NXOpen::GeometricUtilities::Limits* limitsObj = extrudeBuilder->Limits(); limitsObj->StartExtend()->Value()->SetRightHandSide( std::to_string(materialThickness).c_str()); double endDistance = scanHeight - clearanceValue; limitsObj->EndExtend()->Value()->SetRightHandSide( std::to_string(endDistance).c_str()); // ===== 设置布尔操作为新建体 ===== extrudeBuilder->BooleanOperation()->SetType( NXOpen::GeometricUtilities::BooleanOperation::BooleanTypeCreate); // ===== 执行拉伸操作 ===== try { // 提交拉伸操作 NXOpen::NXObject* featureNXObject = extrudeBuilder->Commit(); // 将特征对象转换为Extrude类型 NXOpen::Features::Extrude* extrudeFeature = dynamic_cast<NXOpen::Features::Extrude*>(featureNXObject); if (extrudeFeature) { // 正确获取拉伸创建的实体 std::vector<NXOpen::Body*> resultBodies = extrudeFeature->GetBodies(); // 保存第一个实体(用于后续求差) if (!resultBodies.empty()) { firstExtrudeBody = resultBodies[0]; // 赋值给函数作用域的变量 } // 显示结果信息 char successMsg[256]; if (!resultBodies.empty()) { snprintf(successMsg, sizeof(successMsg), "创建新实体成功!\n实体数量: %d\n起始距离: %.2f mm\n结束距离: %.2f mm", resultBodies.size(), materialThickness, endDistance); } else { snprintf(successMsg, sizeof(successMsg), "拉伸操作完成但未创建实体!\n起始距离: %.2f mm\n结束距离: %.2f mm", materialThickness, endDistance); } theUI->NXMessageBox()->Show("操作结果", NXOpen::NXMessageBox::DialogTypeInformation, successMsg); } else { throw std::runtime_error("创建的特征不是拉伸类型"); } // 清理资源 extrudeBuilder->Destroy(); section->Destroy(); } catch (std::exception& ex) { // 拉伸操作错误处理 char errMsg[256]; snprintf(errMsg, sizeof(errMsg), "拉伸操作失败: %s", ex.what()); theUI->NXMessageBox()->Show("错误", NXOpen::NXMessageBox::DialogTypeError, errMsg); errorCode = 3; // 特殊错误处理:布尔操作冲突 if (std::string(ex.what()).find("boolean") != std::string::npos) { theUI->NXMessageBox()->Show("布尔操作错误", NXOpen::NXMessageBox::DialogTypeError, "请检查布尔操作设置是否与现有几何冲突"); errorCode = 4; } // 确保资源被清理 if (extrudeBuilder) extrudeBuilder->Destroy(); if (section) section->Destroy(); } } catch (std::exception& ex) { // 外层异常处理 char errMsg[256]; snprintf(errMsg, sizeof(errMsg), "拉伸特征创建过程出错: %s", ex.what()); theUI->NXMessageBox()->Show("错误", NXOpen::NXMessageBox::DialogTypeError, errMsg); errorCode = 5; } // ===== 在拉伸操作成功后添加出料边曲线处理 ===== try { // 设置撤销标记 NXOpen::Session::UndoMarkId curveMarkId = theSession->SetUndoMark( NXOpen::Session::MarkVisibilityVisible, "出料边曲线长度编辑"); // 定义存储所有延伸曲线的向量(用于后续拉伸操作) std::vector<NXOpen::Curve*> extendedCurves; // 遍历所有出料边曲线 for (NXOpen::Curve* dischargeCurve : dischargeCurves) { // 创建截面对象(用于曲线长度特征) NXOpen::Section* section = workPart->Sections()->CreateSection(0.00095, 0.001, 0.05); // 创建曲线长度构建器(用于延伸曲线) NXOpen::Features::CurveLengthBuilder* curveLengthBuilder = workPart->Features()->CreateCurvelengthBuilder(nullptr); curveLengthBuilder->SetSection(section); curveLengthBuilder->SetDistanceTolerance(0.001); // 设置距离容差 // 设置曲线延伸参数:对称延伸,增量方式 curveLengthBuilder->CurvelengthData()->SetExtensionMethod( NXOpen::GeometricUtilities::ExtensionMethodIncremental); curveLengthBuilder->CurvelengthData()->SetExtensionSide( NXOpen::GeometricUtilities::ExtensionSideSymmetric); curveLengthBuilder->CurvelengthData()->SetExtensionDirection( NXOpen::GeometricUtilities::ExtensionDirectionNatural); // 设置延伸距离(两端各延伸100mm) curveLengthBuilder->CurvelengthData()->SetStartDistance("100"); curveLengthBuilder->CurvelengthData()->SetEndDistance("100"); // 创建选择规则:基于单条曲线 std::vector<NXOpen::IBaseCurve*> baseCurves(1); baseCurves[0] = dynamic_cast<NXOpen::IBaseCurve*>(dischargeCurve); if (!baseCurves[0]) continue; // 类型转换失败则跳过 NXOpen::CurveDumbRule* curveRule = workPart->ScRuleFactory()->CreateRuleBaseCurveDumb(baseCurves); // 计算曲线中点作为帮助点(用于选择定位) double midParam = 0.0; double midPoint[3] = { 0 }; UF_EVAL_p_t evaluator = NULL; if (UF_EVAL_initialize(dischargeCurve->Tag(), &evaluator) == 0) { double limits[2]; if (UF_EVAL_ask_limits(evaluator, limits) == 0) { midParam = (limits[0] + limits[1]) / 2.0; UF_EVAL_evaluate(evaluator, 0, midParam, midPoint, NULL); } UF_EVAL_free(evaluator); } NXOpen::Point3d helpPoint(midPoint[0], midPoint[1], midPoint[2]); // 创建规则集合 std::vector<NXOpen::SelectionIntentRule*> rules; rules.push_back(curveRule); // 添加曲线到截面 section->AddToSection(rules, dischargeCurve, nullptr, nullptr, helpPoint, NXOpen::Section::ModeCreate, false); // 提交曲线长度特征 NXOpen::Features::Feature* curveLengthFeature = dynamic_cast<NXOpen::Features::Feature*>(curveLengthBuilder->Commit()); // 获取新创建的延伸曲线(关键修改:直接添加到外部集合) if (curveLengthFeature) { std::vector<NXOpen::NXObject*> createdEntities = curveLengthFeature->GetEntities(); for (NXOpen::NXObject* obj : createdEntities) { if (NXOpen::Curve* curve = dynamic_cast<NXOpen::Curve*>(obj)) { extendedCurves.push_back(curve); // 添加到外部集合 } } } // 清理资源 curveLengthBuilder->Destroy(); section->Destroy(); // 显示曲线处理信息 char curveMsg[256]; snprintf(curveMsg, sizeof(curveMsg), "曲线处理成功:\n原始曲线: %s\n延伸距离: 100 mm\n创建新曲线: %d条", dischargeCurve->JournalIdentifier().GetText(), extendedCurves.size()); theUI->NXMessageBox()->Show("曲线处理", NXOpen::NXMessageBox::DialogTypeInformation, curveMsg); } // 结束出料边曲线遍历循环 // 更新模型 theSession->UpdateManager()->DoUpdate(curveMarkId); // 显示成功信息 char msg[256]; snprintf(msg, sizeof(msg), "已处理%d条出料边曲线", dischargeCurves.size()); theUI->NXMessageBox()->Show("曲线处理完成", NXOpen::NXMessageBox::DialogTypeInformation, msg); // ===== 创建第二个拉伸特征(在曲线长度处理后)===== try { // 设置撤销标记 NXOpen::Session::UndoMarkId markId2 = theSession->SetUndoMark( NXOpen::Session::MarkVisibilityVisible, "出料边拉伸求差"); // 验证延伸曲线是否可用 if (extendedCurves.empty()) { throw std::runtime_error("没有可用的延伸曲线作为拉伸截面"); } // 选择第一条延伸曲线作为拉伸截面 NXOpen::Curve* curveForExtrude = extendedCurves[0]; // 创建拉伸构建器 NXOpen::Features::ExtrudeBuilder* extrudeBuilder2 = workPart->Features()->CreateExtrudeBuilder(nullptr); // 创建截面对象 NXOpen::Section* section2 = workPart->Sections()->CreateSection( 0.001, 0.001, 0.05); // 距离公差0.001mm,角度公差0.05度 extrudeBuilder2->SetSection(section2); // 创建曲线选择规则 std::vector<NXOpen::Curve*> sectionCurves2; sectionCurves2.push_back(curveForExtrude); NXOpen::SelectionIntentRule* curveRule2 = workPart->ScRuleFactory()->CreateRuleCurveDumb(sectionCurves2); // 获取曲线中点作为帮助点 NXOpen::Point3d helpPoint2(0.0, 0.0, 0.0); { tag_t curveTag = curveForExtrude->Tag(); UF_EVAL_p_t evaluator = NULL; double limits[2]; if (UF_EVAL_initialize(curveTag, &evaluator) == 0) { if (UF_EVAL_ask_limits(evaluator, limits) == 0) { if (limits[0] > limits[1]) std::swap(limits[0], limits[1]); double midParam = (limits[0] + limits[1]) / 2.0; double midPoint[3]; if (UF_EVAL_evaluate(evaluator, 0, midParam, midPoint, NULL) == 0) { helpPoint2 = NXOpen::Point3d(midPoint[0], midPoint[1], midPoint[2]); } } UF_EVAL_free(evaluator); } } // 添加曲线到截面 std::vector<NXOpen::SelectionIntentRule*> rules2; rules2.push_back(curveRule2); section2->AddToSection( rules2, // 曲线规则集合 curveForExtrude, // 主要曲线对象 nullptr, // 不指定曲线起点 nullptr, // 不指定曲线终点 helpPoint2, // 帮助点(中点) NXOpen::Section::ModeCreate // 创建模式 ); // 设置拉伸方向(与第一个拉伸相同) NXOpen::Point3d origin(0.0, 0.0, 0.0); NXOpen::Direction* extrudeDirection2 = workPart->Directions()->CreateDirection( origin, directionVector, // 使用相同的方向矢量 NXOpen::SmartObject::UpdateOptionWithinModeling ); extrudeBuilder2->SetDirection(extrudeDirection2); // 设置拉伸范围 NXOpen::GeometricUtilities::Limits* limitsObj2 = extrudeBuilder2->Limits(); // 起始距离 = 材料厚度(与第一个拉伸相同) limitsObj2->StartExtend()->Value()->SetRightHandSide( std::to_string(materialThickness).c_str()); // 结束距离 = 扫描高度 + 10mm limitsObj2->EndExtend()->Value()->SetRightHandSide( std::to_string(scanHeight + 10.0).c_str()); // ===== 设置偏置模式 ===== // 获取拉伸特征的偏置构建器 NXOpen::GeometricUtilities::FeatureOffset* featureOffset = extrudeBuilder2->Offset(); // 设置非对称偏置(两侧不同距离) featureOffset->SetOption(NXOpen::GeometricUtilities::TypeNonsymmetricOffset); // 设置具体偏置值 featureOffset->StartOffset()->SetRightHandSide("0"); // 起始端偏置0 featureOffset->EndOffset()->SetRightHandSide("100"); // 设置拔模类型:从起始位置简单拔模 extrudeBuilder2->Draft()->SetDraftOption( NXOpen::GeometricUtilities::SimpleDraft::SimpleDraftTypeSimpleFromStart); // 设置前拔模角度(从截面开始处拔模) extrudeBuilder2->Draft()->FrontDraftAngle()->SetRightHandSide( std::to_string(currentAngle).c_str()); // 设置后拔模角度(这里我们设为0,因为只需要单边拔模) extrudeBuilder2->Draft()->BackDraftAngle()->SetRightHandSide("0"); // ===== 设置布尔操作 ===== // 设置操作类型:求差(从第一个拉伸实体中减去此拉伸) extrudeBuilder2->BooleanOperation()->SetType( NXOpen::GeometricUtilities::BooleanOperation::BooleanTypeSubtract); // 设置布尔操作类型(创建新实体) extrudeBuilder2->BooleanOperation()->SetType( NXOpen::GeometricUtilities::BooleanOperation::BooleanTypeCreate); //// 设置布尔操作类型(求差) //// 设置目标体(第一个拉伸创建的实体) // std::vector<NXOpen::Body*> targetBodies; // if (firstExtrudeBody) { // targetBodies.push_back(firstExtrudeBody); // extrudeBuilder2->BooleanOperation()->SetTargetBodies(targetBodies); // } // else { // throw std::runtime_error("第一个拉伸实体未找到"); // }//求差 // ===== 执行拉伸操作 ===== NXOpen::NXObject* featureNXObject2 = extrudeBuilder2->Commit(); // 检查是否成功创建特征 if (!featureNXObject2) { throw std::runtime_error("第二个拉伸特征创建失败"); } // ===== 新增:找出拉伸截面中点并与边界曲线比较 ===== // ===== 修正后的曲线中点距离判断规则 ===== try { // 1. 确保有两条延伸曲线和两条边界曲线 if (extendedCurves.size() < 2 || boundaryCurves.size() < 2) { throw std::runtime_error("需要两条延伸曲线和两条边界曲线"); } // 2. 获取两条延伸曲线和两条边界曲线 NXOpen::Curve* extCurve1 = extendedCurves[0]; NXOpen::Curve* extCurve2 = extendedCurves[1]; NXOpen::Curve* bndCurve1 = boundaryCurves[0]; NXOpen::Curve* bndCurve2 = boundaryCurves[1]; // 3. 计算所有曲线的中点 struct CurveMidPoint { NXOpen::Curve* curve; double midPoint[3]; }; // 计算中点函数 auto calculateMidPoint = [](NXOpen::Curve* curve) -> double* { static double midPoint[3] = { 0 }; UF_EVAL_p_t evaluator = NULL; if (UF_EVAL_initialize(curve->Tag(), &evaluator) == 0) { double limits[2]; if (UF_EVAL_ask_limits(evaluator, limits) == 0) { double midParam = (limits[0] + limits[1]) / 2.0; UF_EVAL_evaluate(evaluator, 0, midParam, midPoint, NULL); } UF_EVAL_free(evaluator); } return midPoint; }; // 存储所有曲线的中点 CurveMidPoint extMid1 = { extCurve1, {0} }; memcpy(extMid1.midPoint, calculateMidPoint(extCurve1), 3 * sizeof(double)); CurveMidPoint extMid2 = { extCurve2, {0} }; memcpy(extMid2.midPoint, calculateMidPoint(extCurve2), 3 * sizeof(double)); CurveMidPoint bndMid1 = { bndCurve1, {0} }; memcpy(bndMid1.midPoint, calculateMidPoint(bndCurve1), 3 * sizeof(double)); CurveMidPoint bndMid2 = { bndCurve2, {0} }; memcpy(bndMid2.midPoint, calculateMidPoint(bndCurve2), 3 * sizeof(double)); // 4. 计算距离函数 auto distance = [](double p1[3], double p2[3]) -> double { double dx = p1[0] - p2[0]; double dy = p1[1] - p2[1]; double dz = p1[2] - p2[2]; return sqrt(dx * dx + dy * dy + dz * dz); }; // 5. 计算所有可能的距离组合 double d11 = distance(extMid1.midPoint, bndMid1.midPoint); // 延伸1-边界1 double d12 = distance(extMid1.midPoint, bndMid2.midPoint); // 延伸1-边界2 double d21 = distance(extMid2.midPoint, bndMid1.midPoint); // 延伸2-边界1 double d22 = distance(extMid2.midPoint, bndMid2.midPoint); // 延伸2-边界2 // 6. 找出最近的两个中点组合(无冲突配对) std::vector<std::pair<NXOpen::Curve*, NXOpen::Curve*>> closestPairs; // 确定延伸曲线1的最佳配对 if (d11 < d12) { closestPairs.push_back({ extCurve1, bndCurve1 }); } else { closestPairs.push_back({ extCurve1, bndCurve2 }); } // 确定延伸曲线2的最佳配对(排除已使用的边界曲线) if (closestPairs[0].second == bndCurve1) { // 如果边界1已被使用,延伸2只能配边界2 closestPairs.push_back({ extCurve2, bndCurve2 }); } else { // 如果边界2已被使用,延伸2只能配边界1 closestPairs.push_back({ extCurve2, bndCurve1 }); } // 7. 找出与拉伸二截面线相关的边界曲线 // 假设拉伸二使用的是延伸曲线2 NXOpen::Curve* stretchTwoCurve = extCurve2; NXOpen::Curve* relatedBoundaryCurve = nullptr; for (auto& pair : closestPairs) { if (pair.first == stretchTwoCurve) { relatedBoundaryCurve = pair.second; break; } } // 8. 高亮显示相关的边界曲线 if (relatedBoundaryCurve) { // 高亮相关边界曲线 UF_DISP_set_highlight(relatedBoundaryCurve->Tag(), 1); // 高亮显示 // 刷新显示 UF_DISP_refresh(); // 显示结果信息 char resultMsg[512]; snprintf(resultMsg, sizeof(resultMsg), "曲线中点配对结果:\n\n" "延伸曲线1中点与边界曲线1中点距离: %.4f mm\n" "延伸曲线1中点与边界曲线2中点距离: %.4f mm\n" "延伸曲线2中点与边界曲线1中点距离: %.4f mm\n" "延伸曲线2中点与边界曲线2中点距离: %.4f mm\n\n" "拉伸二使用曲线: %s\n" "已高亮显示相关边界曲线: %s", d11, d12, d21, d22, stretchTwoCurve->JournalIdentifier().GetText(), relatedBoundaryCurve->JournalIdentifier().GetText()); theUI->NXMessageBox()->Show("曲线中点配对结果", NXOpen::NXMessageBox::DialogTypeInformation, resultMsg); } else { throw std::runtime_error("未找到与拉伸二截面线相关的边界曲线"); } } catch (std::exception& ex) { char warnMsg[256]; snprintf(warnMsg, sizeof(warnMsg), "曲线中点配对失败: %s", ex.what()); theUI->NXMessageBox()->Show("警告", NXOpen::NXMessageBox::DialogTypeWarning, warnMsg); } // 获取创建的实体 NXOpen::Features::Extrude* extrudeFeature2 = dynamic_cast<NXOpen::Features::Extrude*>(featureNXObject2); std::vector<NXOpen::Body*> resultBodies2; if (extrudeFeature2) { resultBodies2 = extrudeFeature2->GetBodies(); } // 清理资源 extrudeBuilder2->Destroy(); section2->Destroy(); // 显示成功信息 char successMsg[256]; snprintf(successMsg, sizeof(successMsg), "第二个拉伸创建成功!\n" "拔模角度: %.2f°\n" "偏置范围: 0-100 mm\n" "创建实体: %d个", currentAngle, resultBodies2.size()); theUI->NXMessageBox()->Show("操作结果", NXOpen::NXMessageBox::DialogTypeInformation, successMsg); } catch (std::exception& ex) { // 错误处理 char errMsg[256]; snprintf(errMsg, sizeof(errMsg), "第二个拉伸创建失败: %s", ex.what()); theUI->NXMessageBox()->Show("错误", NXOpen::NXMessageBox::DialogTypeError, errMsg); errorCode = 7; // 设置新的错误代码 } // 刷新显示 UF_DISP_refresh(); } // 结束出料边曲线处理try块 catch (std::exception& ex) { char errMsg[256]; snprintf(errMsg, sizeof(errMsg), "曲线处理失败: %s", ex.what()); theUI->NXMessageBox()->Show("错误", NXOpen::NXMessageBox::DialogTypeError, errMsg); errorCode = 6; // 设置新的错误代码 } // 刷新显示 UF_DISP_refresh(); } // 结束主try块 catch (std::exception& ex) { // 异常处理 char errMsg[256]; snprintf(errMsg, sizeof(errMsg), "操作失败: %s", ex.what()); qiaowei_tool::theUI->NXMessageBox()->Show("错误", NXOpen::NXMessageBox::DialogTypeError, errMsg); errorCode = 1; } return errorCode; }里面“// 7. 找出与拉伸二截面线相关的边界曲线 // 假设拉伸二使用的是延伸曲线2 NXOpen::Curve* stretchTwoCurve = extCurve2; NXOpen::Curve* relatedBoundaryCurve = nullptr;”这部分没有正确的找到我拉伸2里面使用的是哪条截面线
08-10
//============================================================================== // WARNING!! This file is overwritten by the Block UI Styler while generating // the automation code. Any modifications to this file will be lost after // generating the code again. // // Filename: D:\NXopen\BaiduSyncdisk\studio\hkjm\ui\hkjm.cpp // // This file was generated by the NX Block UI Styler // Created by: MiCH-CEO // Version: NX 12 // Date: 08-06-2025 (Format: mm-dd-yyyy) // Time: 19:18 (Format: hh-mm) // //============================================================================== //============================================================================== // Purpose: This TEMPLATE file contains C++ source to guide you in the // construction of your Block application dialog. The generation of your // dialog file (.dlx extension) is the first step towards dialog construction // within NX. You must now create a NX Open application that // utilizes this file (.dlx). // // The information in this file provides you with the following: // // 1. Help on how to load and display your Block UI Styler dialog in NX // using APIs provided in NXOpen.BlockStyler namespace // 2. The empty callback methods (stubs) associated with your dialog items // have also been placed in this file. These empty methods have been // created simply to start you along with your coding requirements. // The method name, argument list and possible return values have already // been provided for you. //============================================================================== //------------------------------------------------------------------------------ //These includes are needed for the following template code //------------------------------------------------------------------------------ #include "hkjm.hpp" using namespace NXOpen; using namespace NXOpen::BlockStyler; //------------------------------------------------------------------------------ // Initialize static variables //------------------------------------------------------------------------------ Session *(hkjm::theSession) = NULL; UI *(hkjm::theUI) = NULL; //------------------------------------------------------------------------------ // Constructor for NX Styler class //------------------------------------------------------------------------------ hkjm::hkjm() { try { // Initialize the NX Open C++ API environment hkjm::theSession = NXOpen::Session::GetSession(); hkjm::theUI = UI::GetUI(); theDlxFileName = "hkjm.dlx"; theDialog = hkjm::theUI->CreateDialog(theDlxFileName); // Registration of callback functions theDialog->AddApplyHandler(make_callback(this, &hkjm::apply_cb)); theDialog->AddOkHandler(make_callback(this, &hkjm::ok_cb)); theDialog->AddUpdateHandler(make_callback(this, &hkjm::update_cb)); theDialog->AddInitializeHandler(make_callback(this, &hkjm::initialize_cb)); theDialog->AddDialogShownHandler(make_callback(this, &hkjm::dialogShown_cb)); } catch(exception& ex) { //---- Enter your exception handling code here ----- throw; } } //------------------------------------------------------------------------------ // Destructor for NX Styler class //------------------------------------------------------------------------------ hkjm::~hkjm() { 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_BASE_DIR\ugii\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) { hkjm *thehkjm = NULL; try { UF_initialize(); //开发的许可函数,初始化 thehkjm = new hkjm(); // The following method shows the dialog immediately thehkjm->Show(); } catch(exception& ex) { //---- Enter your exception handling code here ----- hkjm::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what()); } if(thehkjm != NULL) { delete thehkjm; thehkjm = NULL; }UF_terminate(); //释放许可函数,结束化 } //------------------------------------------------------------------------------ // 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 ----- hkjm::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what()); } } int hkjm::Show() { try { theDialog->Show(); } catch(exception& ex) { //---- Enter your exception handling code here ----- hkjm::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what()); } return 0; } //------------------------------------------------------------------------------ //---------------------Block UI Styler Callback Functions-------------------------- //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ //Callback Name: initialize_cb //------------------------------------------------------------------------------ void hkjm::initialize_cb() { try { group0 = dynamic_cast<NXOpen::BlockStyler::Group*>(theDialog->TopBlock()->FindBlock("group0")); hk2edge = dynamic_cast<NXOpen::BlockStyler::CurveCollector*>(theDialog->TopBlock()->FindBlock("hk2edge")); hk1edge = dynamic_cast<NXOpen::BlockStyler::CurveCollector*>(theDialog->TopBlock()->FindBlock("hk1edge")); hk1sd = dynamic_cast<NXOpen::BlockStyler::ExpressionBlock*>(theDialog->TopBlock()->FindBlock("hk1sd")); hk2sd = dynamic_cast<NXOpen::BlockStyler::ExpressionBlock*>(theDialog->TopBlock()->FindBlock("hk2sd")); group = dynamic_cast<NXOpen::BlockStyler::Group*>(theDialog->TopBlock()->FindBlock("group")); hkdj = dynamic_cast<NXOpen::BlockStyler::ExpressionBlock*>(theDialog->TopBlock()->FindBlock("hkdj")); hk2jd = dynamic_cast<NXOpen::BlockStyler::ExpressionBlock*>(theDialog->TopBlock()->FindBlock("hk2jd")); hk1jd = dynamic_cast<NXOpen::BlockStyler::ExpressionBlock*>(theDialog->TopBlock()->FindBlock("hk1jd")); vector0 = dynamic_cast<NXOpen::BlockStyler::SpecifyVector*>(theDialog->TopBlock()->FindBlock("vector0")); bodySelect0 = dynamic_cast<NXOpen::BlockStyler::BodyCollector*>(theDialog->TopBlock()->FindBlock("bodySelect0")); color1 = dynamic_cast<NXOpen::BlockStyler::ObjectColorPicker*>(theDialog->TopBlock()->FindBlock("color1")); color2 = dynamic_cast<NXOpen::BlockStyler::ObjectColorPicker*>(theDialog->TopBlock()->FindBlock("color2")); } catch(exception& ex) { //---- Enter your exception handling code here ----- hkjm::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what()); } } //获取实体、、 // 过滤函数:获取工作部件的所有可见实体 std::vector<tag_t> FilterVisibleBodies() { std::vector<tag_t> visibleBodies; NXOpen::Session* theSession = NXOpen::Session::GetSession(); NXOpen::UI* theUI = NXOpen::UI::GetUI(); try { // 获取工作部件 NXOpen::Part* workPart = theSession->Parts()->Work(); if (!workPart) { theUI->NXMessageBox()->Show("错误提示", NXOpen::NXMessageBox::DialogTypeError, "未找到工作部件!"); return visibleBodies; } // 获取工作部件的tag tag_t workPartTag = workPart->Tag(); // 遍历工作部件中的所有实体 tag_t currentBody = NULL_TAG; UF_OBJ_cycle_objs_in_part(workPartTag, UF_solid_type, &currentBody); while (currentBody != NULL_TAG) { // 获取实体的显示属性 UF_OBJ_disp_props_t disp_props; if (UF_OBJ_ask_display_properties(currentBody, &disp_props) == 0) { // 检查实体是否可见(未隐藏) if (disp_props.blank_status == UF_OBJ_NOT_BLANKED) { // 检查实体所在层是否可见 int layer_status = 0; UF_LAYER_ask_status(disp_props.layer, &layer_status); // 只添加可见层(工作层、活动层、参考层)的实体 if (layer_status == UF_LAYER_WORK_LAYER || layer_status == UF_LAYER_ACTIVE_LAYER || layer_status == UF_LAYER_REFERENCE_LAYER) { visibleBodies.push_back(currentBody); } } } // 获取下一个实体 UF_OBJ_cycle_objs_in_part(workPartTag, UF_solid_type, &currentBody); } // 如果没有可见实体,显示提示信息 if (visibleBodies.empty()) { theUI->NXMessageBox()->Show("提示", NXOpen::NXMessageBox::DialogTypeInformation, "工作部件中没有可见实体!"); } } catch (const std::exception& ex) { theUI->NXMessageBox()->Show("过滤错误", NXOpen::NXMessageBox::DialogTypeError, ex.what()); } return visibleBodies; } //------------------------------------------------------------------------------ //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. //------------------------------------------------------------------------------ // 修改dialogShown_cb函数 void hkjm::dialogShown_cb() { try { // 获取所有可见实体的tag std::vector<tag_t> visibleBodyTags = FilterVisibleBodies(); // 转换为NXOpen::Body对象 - 使用正确的方法 std::vector<NXOpen::Body*> visibleBodies; for (tag_t tag : visibleBodyTags) { // 正确方法:使用NXObjectManager::Get获取对象后动态转换 NXOpen::NXObject* obj = NXOpen::NXObjectManager::Get(tag); if (obj) { // 使用安全的dynamic_cast进行类型转换 NXOpen::Body* body = dynamic_cast<NXOpen::Body*>(obj); if (body) { visibleBodies.push_back(body); } } } // 设置到bodySelect0控件 if (bodySelect0 && !visibleBodies.empty()) { // 获取控件的属性列表 NXOpen::BlockStyler::PropertyList* props = bodySelect0->GetProperties(); // 创建正确的TaggedObject数组 std::vector<NXOpen::TaggedObject*> selectedObjects; for (NXOpen::Body* body : visibleBodies) { // Body继承自TaggedObject,直接转换 selectedObjects.push_back(static_cast<NXOpen::TaggedObject*>(body)); } // 设置选中对象 - 使用正确的属性名 props->SetTaggedObjectVector("SelectedObjects", selectedObjects); // 不需要调用SetProperties,设置后自动生效 // 刷新控件 - 使用正确的方法 bodySelect0->Update(); } } catch (std::exception& ex) { hkjm::theUI->NXMessageBox()->Show("对话框错误", NXOpen::NXMessageBox::DialogTypeError, ex.what()); } } //------------------------------------------------------------------------------ //Callback Name: apply_cb //------------------------------------------------------------------------------ // 应用按钮回调函数 - 读取所有控件数据 //------------------------------------------------------------------------------ int hkjm::apply_cb() { int errorCode = 0; // 错误代码,0表示成功 try { // 获取NX会话和工作部件 NXOpen::Session* theSession = NXOpen::Session::GetSession(); NXOpen::Part* workPart = theSession->Parts()->Work(); NXOpen::UI* theUI = NXOpen::UI::GetUI(); // ===== 1. 处理曲线选择器1的值 ===== std::vector<NXOpen::Curve*> sectionCurves1; if (hk1edge) { // 使用智能指针管理属性列表内存 std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(hk1edge->GetProperties()); std::vector<NXOpen::TaggedObject*> selObjs = props->GetTaggedObjectVector("SelectedObjects"); for (NXOpen::TaggedObject* obj : selObjs) { if (NXOpen::Curve* curve = dynamic_cast<NXOpen::Curve*>(obj)) { sectionCurves1.push_back(curve); } } } // ===== 2. 处理曲线选择器2的值 ===== std::vector<NXOpen::Curve*> sectionCurves2; if (hk2edge) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(hk2edge->GetProperties()); std::vector<NXOpen::TaggedObject*> selObjs = props->GetTaggedObjectVector("SelectedObjects"); for (NXOpen::TaggedObject* obj : selObjs) { if (NXOpen::Curve* curve = dynamic_cast<NXOpen::Curve*>(obj)) { sectionCurves2.push_back(curve); } } } // ===== 3. 获取hk1sd表达式值 ===== double hk1sdValue = 0.0; if (hk1sd) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(hk1sd->GetProperties()); hk1sdValue = props->GetDouble("Value"); } // ===== 4. 获取hk2sd表达式值 ===== double hk2sdValue = 0.0; if (hk2sd) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(hk2sd->GetProperties()); hk2sdValue = props->GetDouble("Value"); } // ===== 5. 获取hkdj表达式值 ===== double hkdjValue = 0.0; if (hkdj) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(hkdj->GetProperties()); hkdjValue = props->GetDouble("Value"); } // ===== 6. 获取hk1jd表达式值 ===== double hk1jdValue = 0.0; if (hk1jd) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(hk1jd->GetProperties()); hk1jdValue = props->GetDouble("Value"); } // ===== 7. 获取hk2jd表达式值 ===== double hk2jdValue = 0.0; if (hk2jd) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(hk2jd->GetProperties()); hk2jdValue = props->GetDouble("Value"); } // ===== 8. 获取矢量方向 ===== NXOpen::Vector3d directionVec(0.0, 0.0, 1.0); // 默认Z轴 if (vector0) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(vector0->GetProperties()); directionVec = props->GetVector("Vector"); } // ===== 9. 处理选中的实体 ===== std::vector<NXOpen::Body*> selectedBodies; if (bodySelect0) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(bodySelect0->GetProperties()); std::vector<NXOpen::TaggedObject*> selObjs = props->GetTaggedObjectVector("SelectedObjects"); for (NXOpen::TaggedObject* obj : selObjs) { if (NXOpen::Body* body = dynamic_cast<NXOpen::Body*>(obj)) { selectedBodies.push_back(body); } } } // ===== 10. 获取颜色选择器1的颜色 ===== int colorIndex1 = 0; if (color1) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> colorProps(color1->GetProperties()); std::vector<int> colors = colorProps->GetIntegerVector("Value"); if (!colors.empty()) colorIndex1 = colors[0]; } // ===== 11. 获取颜色选择器2的颜色 ===== int colorIndex2 = 0; if (color2) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> colorProps(color2->GetProperties()); std::vector<int> colors = colorProps->GetIntegerVector("Value"); if (!colors.empty()) colorIndex2 = colors[0]; } // ===== 3. 创建拉伸特征 ===== if (!sectionCurves1.empty() && hk1sdValue != 0.0) { // 设置撤销标记 NXOpen::Session::UndoMarkId markId = theSession->SetUndoMark( NXOpen::Session::MarkVisibilityVisible, "拉伸操作"); // 创建拉伸构建器 NXOpen::Features::ExtrudeBuilder* extrudeBuilder = workPart->Features()->CreateExtrudeBuilder(nullptr); // 创建截面 NXOpen::Section* section = workPart->Sections()->CreateSection( 0.001, 0.001, 0.05); extrudeBuilder->SetSection(section); // 创建曲线规则 - 使用dumb规则 std::vector<NXOpen::SelectionIntentRule*> rules; if (!sectionCurves1.empty()) { // 创建dumb曲线规则 - 直接传递曲线向量 NXOpen::SelectionIntentRule* curveRule = workPart->ScRuleFactory()->CreateRuleCurveDumb(sectionCurves1); rules.push_back(curveRule); } // 获取帮助点(曲线中点)- 使用UF_CURVE_ask_centroid获取曲线中心点 NXOpen::Point3d helpPoint(0.0, 0.0, 0.0); if (!sectionCurves1.empty()) { double centroid[3] = { 0.0, 0.0, 0.0 }; // 使用UF函数获取曲线中心点 if (UF_CURVE_ask_centroid(sectionCurves1[0]->Tag(), centroid) == 0) { helpPoint = NXOpen::Point3d(centroid[0], centroid[1], centroid[2]); } else { // 如果获取中心点失败,使用曲线端点作为备选 tag_t curveTag = sectionCurves1[0]->Tag(); double twoEnd[2][3] = { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0} }; // 使用UF_EVAL系列函数获取曲线端点 UF_EVAL_p_t evaluator = NULL; double limits[2]; // 初始化评估器 if (UF_EVAL_initialize(curveTag, &evaluator) == 0) { // 获取参数范围 if (UF_EVAL_ask_limits(evaluator, limits) == 0) { // 确保参数范围有序 if (limits[0] > limits[1]) { double temp = limits[0]; limits[0] = limits[1]; limits[1] = temp; } // 评估起点 if (UF_EVAL_evaluate(evaluator, 0, limits[0], twoEnd[0], NULL) == 0) { helpPoint = NXOpen::Point3d(twoEnd[0][0], twoEnd[0][1], twoEnd[0][2]); } // 如果起点评估失败,尝试评估终点 else if (UF_EVAL_evaluate(evaluator, 0, limits[1], twoEnd[1], NULL) == 0) { helpPoint = NXOpen::Point3d(twoEnd[1][0], twoEnd[1][1], twoEnd[1][2]); } } // 释放评估器资源 UF_EVAL_free(evaluator); } // 如果所有方法都失败,使用原点 if (helpPoint.X == 0.0 && helpPoint.Y == 0.0 && helpPoint.Z == 0.0) { // 记录错误信息 char msg[256]; sprintf_s(msg, "无法获取曲线 %d 上的点", curveTag); hkjm::theUI->NXMessageBox()->Show("警告", NXOpen::NXMessageBox::DialogTypeWarning, msg); } } } // 添加到截面 - 使用正确的API签名 section->AddToSection( rules, // 规则向量 sectionCurves1[0], // 种子曲线 NULL, // 起始连接对象(无) NULL, // 结束连接对象(无) helpPoint, // 帮助点 NXOpen::Section::ModeCreate // 创建模式 ); // 设置拉伸方向 - 使用正确的CreateDirection重载 NXOpen::Point3d origin(0.0, 0.0, 0.0); NXOpen::Direction* extrudeDirection = workPart->Directions()->CreateDirection( origin, directionVec, NXOpen::SmartObject::UpdateOptionWithinModeling ); extrudeBuilder->SetDirection(extrudeDirection); // 设置拉伸范围 NXOpen::GeometricUtilities::Limits* limits = extrudeBuilder->Limits(); limits->StartExtend()->Value()->SetRightHandSide(std::to_string(hk1sdValue).c_str()); // 起始距离设为hk1sdValue limits->EndExtend()->Value()->SetRightHandSide("0"); // 结束距离设为0 // ===== 添加拔模角度设置 ===== if (hk1jdValue != 0.0) // 只有拔模角度不为0时才设置 { // 设置拔模类型:从起始位置简单拔模 extrudeBuilder->Draft()->SetDraftOption( NXOpen::GeometricUtilities::SimpleDraft::SimpleDraftTypeSimpleFromStart); // 设置前拔模角度(从截面开始处拔模) extrudeBuilder->Draft()->FrontDraftAngle()->SetRightHandSide( std::to_string(hk1jdValue).c_str()); // 设置后拔模角度(这里我们设为0,因为只需要单边拔模) extrudeBuilder->Draft()->BackDraftAngle()->SetRightHandSide("0"); } //// 设置布尔操作类型(创建新实体) //extrudeBuilder->BooleanOperation()->SetType( // NXOpen::GeometricUtilities::BooleanOperation::BooleanTypeCreate); // 设置布尔操作类型(求差) extrudeBuilder->BooleanOperation()->SetType( NXOpen::GeometricUtilities::BooleanOperation::BooleanTypeSubtract); // 设置求差目标体 if (!selectedBodies.empty()) { extrudeBuilder->BooleanOperation()->SetTargetBodies(selectedBodies); } else { // 如果没有选择目标体,显示警告信息 theUI->NXMessageBox()->Show("警告", NXOpen::NXMessageBox::DialogTypeWarning, "未选择求差目标体,将创建独立特征"); } // 在执行拉伸操作前记录目标体的面 std::map<tag_t, std::set<tag_t>> bodyFacesBeforeMap; for (NXOpen::Body* body : selectedBodies) { std::set<tag_t> faceTags; std::vector<NXOpen::Face*> faces = body->GetFaces(); for (NXOpen::Face* face : faces) { faceTags.insert(face->Tag()); } bodyFacesBeforeMap[body->Tag()] = faceTags; } // 执行拉伸操作 NXOpen::NXObject* featureNXObject = extrudeBuilder->Commit(); NXOpen::Features::Feature* feature = dynamic_cast<NXOpen::Features::Feature*>(featureNXObject); // 收集新创建的面 std::vector<NXOpen::Face*> newFaces; // 方法1:比较特征创建前后的面差异 for (NXOpen::Body* body : selectedBodies) { std::vector<NXOpen::Face*> facesAfter = body->GetFaces(); std::set<tag_t> faceTagsBefore = bodyFacesBeforeMap[body->Tag()]; for (NXOpen::Face* face : facesAfter) { tag_t faceTag = face->Tag(); // 如果这个面在创建前不存在,则是新面 if (faceTagsBefore.find(faceTag) == faceTagsBefore.end()) { newFaces.push_back(face); } } } // 仅给新面设置颜色 if (colorIndex1 > 0 && !newFaces.empty()) { for (NXOpen::Face* face : newFaces) { tag_t faceTag = face->Tag(); UF_OBJ_set_color(faceTag, colorIndex1); UF_DISP_set_highlight(faceTag, 0); } // 刷新显示 theSession->Parts()->Work()->Views()->WorkView()->UpdateDisplay(); } // 清理资源 extrudeBuilder->Destroy(); section->Destroy(); } } catch (std::exception& ex) { errorCode = 1; hkjm::theUI->NXMessageBox()->Show("错误", NXOpen::NXMessageBox::DialogTypeError, ex.what()); } catch (...) { errorCode = 1; hkjm::theUI->NXMessageBox()->Show("错误", NXOpen::NXMessageBox::DialogTypeError, "未知错误"); } return errorCode; } //------------------------------------------------------------------------------ //Callback Name: update_cb //------------------------------------------------------------------------------ int hkjm::update_cb(NXOpen::BlockStyler::UIBlock* block) { try { if(block == hk2edge) { //---------Enter your code here----------- } else if(block == hk1edge) { //---------Enter your code here----------- } else if(block == hk1sd) { //---------Enter your code here----------- } else if(block == hk2sd) { //---------Enter your code here----------- } else if(block == hkdj) { //---------Enter your code here----------- } else if(block == hk2jd) { //---------Enter your code here----------- } else if(block == hk1jd) { //---------Enter your code here----------- } else if(block == vector0) { //---------Enter your code here----------- } else if(block == bodySelect0) { //---------Enter your code here----------- } else if(block == color1) { //---------Enter your code here----------- } else if(block == color2) { //---------Enter your code here----------- } } catch(exception& ex) { //---- Enter your exception handling code here ----- hkjm::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what()); } return 0; } //------------------------------------------------------------------------------ //Callback Name: ok_cb //------------------------------------------------------------------------------ int hkjm::ok_cb() { int errorCode = 0; try { errorCode = apply_cb(); } catch(exception& ex) { //---- Enter your exception handling code here ----- errorCode = 1; hkjm::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what()); } return errorCode; } //------------------------------------------------------------------------------ //Function Name: GetBlockProperties //Description: Returns the propertylist of the specified BlockID //------------------------------------------------------------------------------ PropertyList* hkjm::GetBlockProperties(const char *blockID) { return theDialog->GetBlockProperties(blockID); } 报错:严重性 代码 说明 项目 文件 行 禁止显示状态 错误(活动) E0135 class "NXOpen::BlockStyler::BodyCollector" 没有成员 "Update" hkjm D:\NXopen\BaiduSyncdisk\studio\hkjm\hkjm.cpp 320 错误(活动) E0144 "NXOpen::TaggedObject *" 类型的值不能用于初始化 "NXOpen::NXObject *" 类型的实体 hkjm D:\NXopen\BaiduSyncdisk\studio\hkjm\hkjm.cpp 292 错误 C2440 “初始化”: 无法从“NXOpen::TaggedObject *”转换为“NXOpen::NXObject *” hkjm D:\NXopen\BaiduSyncdisk\studio\hkjm\hkjm.cpp 292 错误 C2039 "Update": 不是 "NXOpen::BlockStyler::BodyCollector" 的成员 hkjm D:\NXopen\BaiduSyncdisk\studio\hkjm\hkjm.cpp 320
08-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值