我正在学习NX二次开发,用的是Visual Studio 2019,ug版本是12.0,开发平台是c++,uf函数为主nxopen函数为辅。需要你辅助我开发,重点注意开发模版是c++,优先使用uf函数,要求你先搞清楚你提供给我的代码真实有效性,语句与标点符号的正确位置,避免出现ug12.0没有提供的接口成员出现!确保所有方法调用都符合 NX12 的 API 签名,深度思考下再回答,每次回答前先回顾下前面的所有对话避免问题重复出现,每行代码都用中文注解具体意思与作用。
// ===== 创建第二个拉伸特征(在曲线长度处理后)=====
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());
// ===== 关键修改:动态偏置方向判断逻辑 =====
// 根据投影验证结果决定偏置方向
double endOffsetValue = 100.0; // 默认正偏置100mm
bool canProject = false; // 投影验证结果标志
// ===== 第一步:创建临时拉伸体进行投影验证 =====
try {
// 创建临时拉伸构建器(用于投影验证)
NXOpen::Features::ExtrudeBuilder* tempExtrudeBuilder =
workPart->Features()->CreateExtrudeBuilder(nullptr);
// 复制当前截面设置
tempExtrudeBuilder->SetSection(section2);
// 复制方向设置
tempExtrudeBuilder->SetDirection(extrudeDirection2);
// 复制拉伸范围
NXOpen::GeometricUtilities::Limits* tempLimits = tempExtrudeBuilder->Limits();
tempLimits->StartExtend()->Value()->SetRightHandSide(
std::to_string(materialThickness).c_str());
tempLimits->EndExtend()->Value()->SetRightHandSide(
std::to_string(scanHeight + 10.0).c_str());
// 设置临时偏置(默认正偏置100)
NXOpen::GeometricUtilities::FeatureOffset* tempOffset = tempExtrudeBuilder->Offset();
tempOffset->SetOption(NXOpen::GeometricUtilities::TypeNonsymmetricOffset);
tempOffset->StartOffset()->SetRightHandSide("0");
tempOffset->EndOffset()->SetRightHandSide("100");
// 设置布尔操作类型为创建(避免影响模型)
tempExtrudeBuilder->BooleanOperation()->SetType(
NXOpen::GeometricUtilities::BooleanOperation::BooleanTypeCreate);
// 提交临时拉伸特征
NXOpen::NXObject* tempFeature = tempExtrudeBuilder->Commit();
// 获取临时实体
std::vector<NXOpen::Body*> tempBodies;
if (NXOpen::Features::Extrude* extrudeFeature =
dynamic_cast<NXOpen::Features::Extrude*>(tempFeature)) {
tempBodies = extrudeFeature->GetBodies();
}
// 进行投影验证(使用临时实体)
if (!tempBodies.empty() && targetBoundaryCurve) {
// 创建曲线链表
uf_list_p_t curveList = NULL;
UF_MODL_create_list(&curveList);
UF_MODL_put_list_item(curveList, targetBoundaryCurve->Tag());
// 创建面链表
uf_list_p_t faceList = NULL;
UF_MODL_ask_body_faces(tempBodies[0]->Tag(), &faceList);
// 归一化投影方向
double dirMagnitude = sqrt(directionVector.X * directionVector.X +
directionVector.Y * directionVector.Y +
directionVector.Z * directionVector.Z);
double projDirection[3] = {
directionVector.X / dirMagnitude,
directionVector.Y / dirMagnitude,
directionVector.Z / dirMagnitude
};
// 执行投影
tag_t projCurveFeatTag = NULL_TAG;
int status = UF_MODL_create_proj_curves(
curveList, // 输入曲线列表
faceList, // 目标面列表
0, // 使用投影向量
projDirection, // 投影方向矢量
&projCurveFeatTag
);
// 处理投影结果
if (status == 0 && projCurveFeatTag != NULL_TAG) {
canProject = true;
// 删除投影特征(临时使用)
UF_OBJ_delete_object(projCurveFeatTag);
}
// 清理资源
if (curveList) UF_MODL_delete_list(&curveList);
if (faceList) UF_MODL_delete_list(&faceList);
}
// 清理临时特征
if (tempFeature) {
std::vector<NXOpen::TaggedObject*> toDelete(1);
toDelete[0] = tempFeature;
theSession->UpdateManager()->AddObjectsToDeleteList(toDelete);
}
tempExtrudeBuilder->Destroy();
}
catch (...) {
// 临时验证失败时使用默认偏置
canProject = false;
}
// ===== 第二步:根据验证结果设置最终偏置值 =====
if (!canProject) {
// 投影失败时使用负偏置
endOffsetValue = -100.0; // 负偏置-100mm
}
// ===== 设置偏置模式 =====
// 获取拉伸特征的偏置构建器
NXOpen::GeometricUtilities::FeatureOffset* featureOffset = extrudeBuilder2->Offset();
// 设置非对称偏置(两侧不同距离)
featureOffset->SetOption(NXOpen::GeometricUtilities::TypeNonsymmetricOffset);
// 设置具体偏置值
featureOffset->StartOffset()->SetRightHandSide("0"); // 起始端偏置0
// 动态设置偏置值
char offsetValueStr[32];
snprintf(offsetValueStr, sizeof(offsetValueStr), "%.2f", endOffsetValue);
featureOffset->EndOffset()->SetRightHandSide(offsetValueStr);
// 设置拔模类型:从起始位置简单拔模
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);
// 设置目标体(第一个拉伸实体)
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("第二个拉伸特征创建失败");
}
// 显示偏置方向信息
char offsetMsg[256];
snprintf(offsetMsg, sizeof(offsetMsg),
"使用偏置方向: %s\n投影验证结果: %s",
(endOffsetValue > 0) ? "正偏置(100mm)" : "负偏置(-100mm)",
canProject ? "成功" : "失败");
theUI->NXMessageBox()->Show("偏置设置",
NXOpen::NXMessageBox::DialogTypeInformation, offsetMsg);
// 获取创建的实体
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-%.2f mm\n"
"创建实体: %d个",
currentAngle, endOffsetValue, 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 {
// 设置撤销标记
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. 找出所有可能的配对组合
struct Pairing {
NXOpen::Curve* extCurve;
NXOpen::Curve* bndCurve;
double distance;
};
std::vector<Pairing> allPairs = {
{extCurve1, bndCurve1, d11},
{extCurve1, bndCurve2, d12},
{extCurve2, bndCurve1, d21},
{extCurve2, bndCurve2, d22}
};
// 7. 找出最短距离的组合
auto minPair = *std::min_element(allPairs.begin(), allPairs.end(),
[](const Pairing& a, const Pairing& b) {
return a.distance < b.distance;
});
// 8. 从原始集合中移除已配对的曲线
std::vector<NXOpen::Curve*> remainingExtCurves = { extCurve1, extCurve2 };
std::vector<NXOpen::Curve*> remainingBndCurves = { bndCurve1, bndCurve2 };
auto removeCurve = [](std::vector<NXOpen::Curve*>& vec, NXOpen::Curve* curve) {
vec.erase(std::remove(vec.begin(), vec.end(), curve), vec.end());
};
removeCurve(remainingExtCurves, minPair.extCurve);
removeCurve(remainingBndCurves, minPair.bndCurve);
// 9. 创建最终配对结果
std::vector<std::pair<NXOpen::Curve*, NXOpen::Curve*>> closestPairs;
// 第一对:最短距离组合
closestPairs.push_back({ minPair.extCurve, minPair.bndCurve });
// 第二对:剩余曲线组合
if (!remainingExtCurves.empty() && !remainingBndCurves.empty()) {
closestPairs.push_back({ remainingExtCurves[0], remainingBndCurves[0] });
}
// 10. 验证配对结果
if (closestPairs.size() != 2) {
throw std::runtime_error("无法创建完整的配对组合");
}
// ===== 新增:高亮显示与extendedCurves[0]配对的边界线 =====
NXOpen::Curve* targetExtCurve = extendedCurves[0];
// 在配对结果中查找与extendedCurves[0]配对的边界曲线
for (const auto& pair : closestPairs) {
if (pair.first == targetExtCurve) {
targetBoundaryCurve = pair.second;
break;
}
}
// 高亮相关边界曲线
UF_DISP_set_highlight(targetBoundaryCurve->Tag(), 1); // 高亮显示
//// 获取并存储高亮曲线的tag
//tag_t highlightCurveTag = targetBoundaryCurve->Tag();
// +++ 新增:打印高亮曲线的tag +++
char highlightMsg[256];
snprintf(highlightMsg, sizeof(highlightMsg),
"已高亮显示目标边界曲线\n曲线标识: %s\n曲线Tag: %d",
targetBoundaryCurve->JournalIdentifier().GetText(),
targetBoundaryCurve->Tag());
theUI->NXMessageBox()->Show("曲线信息",
NXOpen::NXMessageBox::DialogTypeInformation, highlightMsg);
// 刷新显示
UF_DISP_refresh();
// 显示配对结果
char pairInfo[512];
snprintf(pairInfo, sizeof(pairInfo),
"配对结果:\n"
"1. %s - %s (距离: %.4f mm)\n"
"2. %s - %s",
closestPairs[0].first->JournalIdentifier().GetText(),
closestPairs[0].second->JournalIdentifier().GetText(),
minPair.distance,
closestPairs[1].first->JournalIdentifier().GetText(),
closestPairs[1].second->JournalIdentifier().GetText());
theUI->NXMessageBox()->Show("曲线配对结果",
NXOpen::NXMessageBox::DialogTypeInformation, pairInfo);
}
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();
}
// ===== 新增:判断边界曲线能否投影到第二个拉伸实体上 =====
// ... 前面的代码保持不变 ...
// ===== 修复后的链表操作代码 =====
bool canProject = false;
std::string projectionResult = "投影失败: 未知错误";
// 确保目标曲线和实体有效
if (targetBoundaryCurve && !resultBodies2.empty())
{
try
{
// 获取目标边界曲线的标签
tag_t curveTag = targetBoundaryCurve->Tag();
if (curveTag == NULL_TAG) {
throw std::runtime_error("目标边界曲线标签无效");
}
// 创建曲线链表
uf_list_p_t curveList = NULL;
if (UF_MODL_create_list(&curveList) != 0 || curveList == NULL) {
throw std::runtime_error("无法创建曲线链表");
}
// 添加曲线到链表
if (UF_MODL_put_list_item(curveList, curveTag) != 0) {
UF_MODL_delete_list(&curveList);
throw std::runtime_error("无法添加曲线到链表");
}
// 验证曲线是否成功添加到链表
int curveCount = 0;
if (UF_MODL_ask_list_count(curveList, &curveCount) != 0 || curveCount != 1) {
UF_MODL_delete_list(&curveList);
throw std::runtime_error("曲线未正确添加到链表");
}
// 获取实体标签
tag_t bodyTag = resultBodies2[0]->Tag();
if (bodyTag == NULL_TAG) {
UF_MODL_delete_list(&curveList);
throw std::runtime_error("实体标签无效");
}
// 获取实体所有面
uf_list_p_t faceList = NULL;
if (UF_MODL_ask_body_faces(bodyTag, &faceList) != 0 || faceList == NULL) {
UF_MODL_delete_list(&curveList);
throw std::runtime_error("无法获取实体面");
}
// 创建面链表
uf_list_p_t faceRefs = NULL;
if (UF_MODL_create_list(&faceRefs) != 0 || faceRefs == NULL) {
UF_MODL_delete_list(&curveList);
UF_MODL_delete_list(&faceList);
throw std::runtime_error("无法创建面链表");
}
// 添加面到链表
int faceCount = 0;
UF_MODL_ask_list_count(faceList, &faceCount);
for (int i = 0; i < faceCount; i++)
{
tag_t faceTag = NULL_TAG;
if (UF_MODL_ask_list_item(faceList, i, &faceTag) == 0)
{
// 验证面标签有效性
if (faceTag == NULL_TAG) continue;
// 添加面到链表
if (UF_MODL_put_list_item(faceRefs, faceTag) != 0)
{
UF_MODL_delete_list(&curveList);
UF_MODL_delete_list(&faceList);
UF_MODL_delete_list(&faceRefs);
throw std::runtime_error("无法添加面到链表");
}
}
}
// 归一化投影方向
double dirMagnitude = sqrt(directionVector.X * directionVector.X +
directionVector.Y * directionVector.Y +
directionVector.Z * directionVector.Z);
if (dirMagnitude < 1e-6) {
UF_MODL_delete_list(&curveList);
UF_MODL_delete_list(&faceList);
UF_MODL_delete_list(&faceRefs);
throw std::runtime_error("投影方向为零向量");
}
double projDirection[3] = {
directionVector.X / dirMagnitude,
directionVector.Y / dirMagnitude,
directionVector.Z / dirMagnitude
};
// 执行投影
tag_t projCurveFeatTag = NULL_TAG;
int status = UF_MODL_create_proj_curves(
curveList, // 输入曲线列表
faceRefs, // 目标面列表
0, // 使用投影向量
projDirection, // 投影方向矢量
&projCurveFeatTag
);
// 处理投影结果
if (status == 0 && projCurveFeatTag != NULL_TAG)
{
canProject = true;
projectionResult = "投影成功!";
// 删除投影特征(临时使用)
UF_OBJ_delete_object(projCurveFeatTag);
}
else
{
char errMsg[133];
if (UF_get_fail_message(status, errMsg) == 0) {
projectionResult = "投影失败: " + std::string(errMsg);
}
else {
projectionResult = "投影失败: 未知错误 (" + std::to_string(status) + ")";
}
}
// 清理资源
if (curveList) UF_MODL_delete_list(&curveList);
if (faceList) UF_MODL_delete_list(&faceList);
if (faceRefs) UF_MODL_delete_list(&faceRefs);
}
catch (std::exception& ex)
{
projectionResult = ex.what();
}
}
else
{
// 详细说明失败原因
if (!targetBoundaryCurve) {
projectionResult = "目标曲线未找到或无效";
}
else if (resultBodies2.empty()) {
projectionResult = "拉伸实体未创建";
}
else {
projectionResult = "未知条件不足";
}
}
// ... 后续代码保持不变 ...
// 显示投影结果
char projMsg[1024];
snprintf(projMsg, sizeof(projMsg),
"投影验证结果:\n"
"状态: %s\n"
"目标曲线: %s (Tag: %d)\n"
"实体数量: %d",
projectionResult.c_str(),
(targetBoundaryCurve) ? targetBoundaryCurve->JournalIdentifier().GetText() : "N/A",
(targetBoundaryCurve) ? targetBoundaryCurve->Tag() : 0,
resultBodies2.size());
theUI->NXMessageBox()->Show("投影验证",
NXOpen::NXMessageBox::DialogTypeInformation, projMsg);
// 清理资源
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();。有问题的代码部分在创建面链表之前没有,获取实体标签,获取实体所有面,这两个操作