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. 计算两条边界曲线端点间的最短距离并创建两条连接直线 =====
try {
// 获取前两条边界曲线
NXOpen::Curve* curve1 = boundaryCurves[0];
NXOpen::Curve* curve2 = boundaryCurves[1];
// 声明存储曲线端点的数组
double curve1Start[3] = { 0.0, 0.0, 0.0 }; // 曲线1起点坐标
double curve1End[3] = { 0.0, 0.0, 0.0 }; // 曲线1终点坐标
double curve2Start[3] = { 0.0, 0.0, 0.0 }; // 曲线2起点坐标
double curve2End[3] = { 0.0, 0.0, 0.0 }; // 曲线2终点坐标
// 获取第一条曲线的端点
tag_t curve1Tag = curve1->Tag();
UF_EVAL_p_t evaluator1 = NULL;
if (UF_EVAL_initialize(curve1Tag, &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]);
}
// 评估曲线1的起点
if (UF_EVAL_evaluate(evaluator1, 0, limits1[0], curve1Start, NULL) != 0) {
UF_EVAL_free(evaluator1);
throw std::runtime_error("无法评估曲线1的起点");
}
// 评估曲线1的终点
if (UF_EVAL_evaluate(evaluator1, 0, limits1[1], curve1End, NULL) != 0) {
UF_EVAL_free(evaluator1);
throw std::runtime_error("无法评估曲线1的终点");
}
UF_EVAL_free(evaluator1);
// 获取第二条曲线的端点
tag_t curve2Tag = curve2->Tag();
UF_EVAL_p_t evaluator2 = NULL;
if (UF_EVAL_initialize(curve2Tag, &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]);
}
// 评估曲线2的起点
if (UF_EVAL_evaluate(evaluator2, 0, limits2[0], curve2Start, NULL) != 0) {
UF_EVAL_free(evaluator2);
throw std::runtime_error("无法评估曲线2的起点");
}
// 评估曲线2的终点
if (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);
// 找出最小距离对应的点对
double minDist = std::min({ dist1, dist2, dist3, dist4 });
NXOpen::Point3d minPoint1, minPoint2;
int minIndex = 0;
if (minDist == dist1) {
minPoint1 = p1_start;
minPoint2 = p2_start;
minIndex = 1;
}
else if (minDist == dist2) {
minPoint1 = p1_start;
minPoint2 = p2_end;
minIndex = 2;
}
else if (minDist == dist3) {
minPoint1 = p1_end;
minPoint2 = p2_start;
minIndex = 3;
}
else {
minPoint1 = p1_end;
minPoint2 = p2_end;
minIndex = 4;
}
// 确定剩余的两个端点
NXOpen::Point3d remainingPoint1, remainingPoint2;
auto isPointEqual = [](const NXOpen::Point3d& a, const NXOpen::Point3d& b, double tolerance = 1e-6) -> bool {
return (fabs(a.X - b.X) < tolerance) &&
(fabs(a.Y - b.Y) < tolerance) &&
(fabs(a.Z - b.Z) < tolerance);
};
// 对于曲线1,找出未使用的端点
if (isPointEqual(minPoint1, p1_start)) {
remainingPoint1 = p1_end;
}
else {
remainingPoint1 = p1_start;
}
// 对于曲线2,找出未使用的端点
if (isPointEqual(minPoint2, p2_start)) {
remainingPoint2 = p2_end;
}
else {
remainingPoint2 = p2_start;
}
// ===== 14. 创建两条连接直线 =====
try {
// 创建第一条直线(最短距离连接)
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;
tag_t line1Tag = NULL_TAG;
int status1 = UF_CURVE_create_line(&line1Coords, &line1Tag);
if (status1 != 0 || line1Tag == NULL_TAG) {
throw std::runtime_error("创建最短距离直线失败");
}
// 设置第一条直线属性)
int workLayer = workPart->Layers()->WorkLayer();
UF_OBJ_set_layer(line1Tag, workLayer);
UF_OBJ_set_color(line1Tag, 31); // 改色
// 创建第二条直线(剩余端点连接)
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;
tag_t line2Tag = NULL_TAG;
int status2 = UF_CURVE_create_line(&line2Coords, &line2Tag);
if (status2 != 0 || line2Tag == NULL_TAG) {
// 即使第二条直线失败,第一条直线已创建
throw std::runtime_error("创建剩余端点直线失败");
}
// 设置第二条直线属性
UF_OBJ_set_layer(line2Tag, workLayer);
UF_OBJ_set_color(line2Tag, 31); // 改色
// 计算第二条直线的距离
double remainingDist = distance(remainingPoint1, remainingPoint2);
// 更新显示
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;
}
}
catch (std::exception& ex) {
char errMsg[256];
snprintf(errMsg, sizeof(errMsg), "端点距离计算失败: %s", ex.what());
theUI->NXMessageBox()->Show("错误", NXOpen::NXMessageBox::DialogTypeError, errMsg);
errorCode = 2;
}
}
catch (exception& ex)
{
// 捕获并显示通用错误
char errMsg[256];
snprintf(errMsg, sizeof(errMsg), "错误: %s", ex.what());
theUI->NXMessageBox()->Show("MiCH-明提示", NXOpen::NXMessageBox::DialogTypeError, errMsg);
errorCode = 1;
}
return errorCode; // 确保返回错误代码
}请在创建直线后把下方拉伸代码加上,: // ===== 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("MICH-明警告",
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("MICH-明警告",
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();
}
不需要收集面跟改色的部分,只需要拉伸。拉伸截面是“bianjie_edge跟创建出来的直线”。设置拉伸范围:“起始距离设为expression_clcq。结束距离设为expression_smh减去expression_jlcq”。拔模角度不需要
最新发布