//==============================================================================
// 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\Application\gaiyansetool.cpp
//
// This file was generated by the NX Block UI Styler
// Created by: MICH-ROG
// Version: NX 12
// Date: 07-31-2025 (Format: mm-dd-yyyy)
// Time: 16:55 (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 "gaiyansetool.hpp"
using namespace NXOpen;
using namespace NXOpen::BlockStyler;
// 辅助结构体存储面信息
struct FaceInfo {
TaggedObject* faceObj;
double centerZ;
int faceType;
double radius;
};
//------------------------------------------------------------------------------
// Initialize static variables
//------------------------------------------------------------------------------
Session *(gaiyansetool::theSession) = NULL;
UI *(gaiyansetool::theUI) = NULL;
//------------------------------------------------------------------------------
// Constructor for NX Styler class
//------------------------------------------------------------------------------
gaiyansetool::gaiyansetool()
{
try
{
// Initialize the NX Open C++ API environment
gaiyansetool::theSession = NXOpen::Session::GetSession();
gaiyansetool::theUI = UI::GetUI();
theDlxFileName = "gaiyansetool.dlx";
theDialog = gaiyansetool::theUI->CreateDialog(theDlxFileName);
// Registration of callback functions
theDialog->AddApplyHandler(make_callback(this, &gaiyansetool::apply_cb));
theDialog->AddOkHandler(make_callback(this, &gaiyansetool::ok_cb));
theDialog->AddUpdateHandler(make_callback(this, &gaiyansetool::update_cb));
theDialog->AddInitializeHandler(make_callback(this, &gaiyansetool::initialize_cb));
theDialog->AddDialogShownHandler(make_callback(this, &gaiyansetool::dialogShown_cb));
}
catch(exception& ex)
{
//---- Enter your exception handling code here -----
throw;
}
}
//------------------------------------------------------------------------------
// Destructor for NX Styler class
//------------------------------------------------------------------------------
gaiyansetool::~gaiyansetool()
{
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)
{
gaiyansetool *thegaiyansetool = NULL;
try
{
UF_initialize(); //开发的许可函数,初始化
thegaiyansetool = new gaiyansetool();
// The following method shows the dialog immediately
thegaiyansetool->Show();
}
catch(exception& ex)
{
//---- Enter your exception handling code here -----
gaiyansetool::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what());
}
if(thegaiyansetool != NULL)
{
delete thegaiyansetool;
thegaiyansetool = 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 -----
gaiyansetool::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what());
}
}
int gaiyansetool::Show()
{
try
{
theDialog->Show();
}
catch(exception& ex)
{
//---- Enter your exception handling code here -----
gaiyansetool::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what());
}
return 0;
}
//------------------------------------------------------------------------------
//---------------------Block UI Styler Callback Functions--------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//Callback Name: initialize_cb
//------------------------------------------------------------------------------
void gaiyansetool::initialize_cb()
{
try
{
group1 = dynamic_cast<NXOpen::BlockStyler::Group*>(theDialog->TopBlock()->FindBlock("group1"));
enum0 = dynamic_cast<NXOpen::BlockStyler::Enumeration*>(theDialog->TopBlock()->FindBlock("enum0"));
group0 = dynamic_cast<NXOpen::BlockStyler::Group*>(theDialog->TopBlock()->FindBlock("group0"));
face1 = dynamic_cast<NXOpen::BlockStyler::FaceCollector*>(theDialog->TopBlock()->FindBlock("face1"));
group = dynamic_cast<NXOpen::BlockStyler::Group*>(theDialog->TopBlock()->FindBlock("group"));
color1 = dynamic_cast<NXOpen::BlockStyler::ObjectColorPicker*>(theDialog->TopBlock()->FindBlock("color1"));
color2 = dynamic_cast<NXOpen::BlockStyler::ObjectColorPicker*>(theDialog->TopBlock()->FindBlock("color2"));
color3 = dynamic_cast<NXOpen::BlockStyler::ObjectColorPicker*>(theDialog->TopBlock()->FindBlock("color3"));
color4 = dynamic_cast<NXOpen::BlockStyler::ObjectColorPicker*>(theDialog->TopBlock()->FindBlock("color4"));
bu1 = dynamic_cast<NXOpen::BlockStyler::Button*>(theDialog->TopBlock()->FindBlock("bu1"));
bu2 = dynamic_cast<NXOpen::BlockStyler::Button*>(theDialog->TopBlock()->FindBlock("bu2"));
bu3 = dynamic_cast<NXOpen::BlockStyler::Button*>(theDialog->TopBlock()->FindBlock("bu3"));
bu4 = dynamic_cast<NXOpen::BlockStyler::Button*>(theDialog->TopBlock()->FindBlock("bu4"));
color5 = dynamic_cast<NXOpen::BlockStyler::ObjectColorPicker*>(theDialog->TopBlock()->FindBlock("color5"));
color6 = dynamic_cast<NXOpen::BlockStyler::ObjectColorPicker*>(theDialog->TopBlock()->FindBlock("color6"));
color7 = dynamic_cast<NXOpen::BlockStyler::ObjectColorPicker*>(theDialog->TopBlock()->FindBlock("color7"));
color8 = dynamic_cast<NXOpen::BlockStyler::ObjectColorPicker*>(theDialog->TopBlock()->FindBlock("color8"));
bu5 = dynamic_cast<NXOpen::BlockStyler::Button*>(theDialog->TopBlock()->FindBlock("bu5"));
bu6 = dynamic_cast<NXOpen::BlockStyler::Button*>(theDialog->TopBlock()->FindBlock("bu6"));
bu7 = dynamic_cast<NXOpen::BlockStyler::Button*>(theDialog->TopBlock()->FindBlock("bu7"));
bu8 = dynamic_cast<NXOpen::BlockStyler::Button*>(theDialog->TopBlock()->FindBlock("bu8"));
color9 = dynamic_cast<NXOpen::BlockStyler::ObjectColorPicker*>(theDialog->TopBlock()->FindBlock("color9"));
color10 = dynamic_cast<NXOpen::BlockStyler::ObjectColorPicker*>(theDialog->TopBlock()->FindBlock("color10"));
color11 = dynamic_cast<NXOpen::BlockStyler::ObjectColorPicker*>(theDialog->TopBlock()->FindBlock("color11"));
color12 = dynamic_cast<NXOpen::BlockStyler::ObjectColorPicker*>(theDialog->TopBlock()->FindBlock("color12"));
bu9 = dynamic_cast<NXOpen::BlockStyler::Button*>(theDialog->TopBlock()->FindBlock("bu9"));
bu10 = dynamic_cast<NXOpen::BlockStyler::Button*>(theDialog->TopBlock()->FindBlock("bu10"));
bu11 = dynamic_cast<NXOpen::BlockStyler::Button*>(theDialog->TopBlock()->FindBlock("bu11"));
bu12 = dynamic_cast<NXOpen::BlockStyler::Button*>(theDialog->TopBlock()->FindBlock("bu12"));
group2 = dynamic_cast<NXOpen::BlockStyler::Group*>(theDialog->TopBlock()->FindBlock("group2"));
dbpface = dynamic_cast<NXOpen::BlockStyler::Button*>(theDialog->TopBlock()->FindBlock("dbpface"));
gtbody = dynamic_cast<NXOpen::BlockStyler::Button*>(theDialog->TopBlock()->FindBlock("gtbody"));
arcface = dynamic_cast<NXOpen::BlockStyler::Button*>(theDialog->TopBlock()->FindBlock("arcface"));
gaodipoints = dynamic_cast<NXOpen::BlockStyler::Button*>(theDialog->TopBlock()->FindBlock("gaodipoints"));
Keyway1 = dynamic_cast<NXOpen::BlockStyler::Button*>(theDialog->TopBlock()->FindBlock("Keyway1"));
}
catch(exception& ex)
{
//---- Enter your exception handling code here -----
gaiyansetool::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what());
}
}
//------------------------------------------------------------------------------
//Callback Name: dialogShown_cb
//This callback is executed just before the dialog launch. Thus any value set
//here will take precedence and dialog will be launched showing that value.
//------------------------------------------------------------------------------
void gaiyansetool::dialogShown_cb()
{
try
{
//---- Enter your callback code here -----
}
catch(exception& ex)
{
//---- Enter your exception handling code here -----
gaiyansetool::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what());
}
}
//------------------------------------------------------------------------------
//Callback Name: apply_cb
//------------------------------------------------------------------------------
int gaiyansetool::apply_cb()
{
int errorCode = 0;
try
{
//---- Enter your callback code here -----
}
catch(exception& ex)
{
//---- Enter your exception handling code here -----
errorCode = 1;
gaiyansetool::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what());
}
return errorCode;
}
//------------------------------------------------------------------------------
//Callback Name: update_cb
//------------------------------------------------------------------------------
int gaiyansetool::update_cb(NXOpen::BlockStyler::UIBlock* block)
{
try
{
if (block == enum0)
{
//---------Enter your code here-----------
}
else if (block == face1)
{
//---------Enter your code here-----------
}
else if (block == color1)
{
//---------Enter your code here-----------
}
else if (block == color2)
{
//---------Enter your code here-----------
}
else if (block == color3)
{
//---------Enter your code here-----------
}
else if (block == color4)
{
//---------Enter your code here-----------
}
else if (block == bu1)
{
try
{
if (color1 != nullptr)
{
//获取ui枚举索引值
int iType = 0;
iType = this->enum0->GetProperties()->GetEnum("Value");
// ⚙️ 1. 获取属性列表
PropertyList* colorProps = color1->GetProperties();
// 🎨 2. 获取颜色值:关键属性名为 "Value",返回整数向量
std::vector<int> colors = colorProps->GetIntegerVector("Value");
int colorID = colors[0]; // 取第一个值为颜色索引
delete colorProps;// 🧹 3. 释放属性列表内存(必须!)
//char msg[256];//调试//
//sprintf(msg, "%d", iType);
//uc1601(msg, 1);//
// ====== 以下是应用颜色到面的逻辑 ======
if (face1 != nullptr)
{
// 获取选中的面
std::vector<NXOpen::TaggedObject*> vFaces = face1->GetSelectedObjects();
if (vFaces.empty())
{
theUI->NXMessageBox()->Show("MICH-明:提示", NXMessageBox::DialogTypeError, "未选择面!");
return 0;
}
if (iType == 0)
{
// 🖌️ 遍历所有面并设置颜色
for (auto face : vFaces)
{
tag_t faceTag = face->Tag();
UF_OBJ_set_color(faceTag, colorID); // 应用颜色
UF_DISP_set_highlight(faceTag, 0); //高亮,0=不高亮,1=高亮
}
}
else
{
// 模式1:给选中面所在的实体设置颜色
std::set<tag_t> processedBodies;// 用于记录已处理的实体
for (auto face : vFaces)
{
tag_t faceTag = face->Tag();
tag_t bodyTag = NULL_TAG;
// 获取面所属的实体
UF_MODL_ask_face_body(faceTag, &bodyTag);
if (bodyTag != NULL_TAG && processedBodies.find(bodyTag) == processedBodies.end())
{
// 清除实体上所有面的单独颜色设置(关键修复)
uf_list_p_t faceList = NULL;
UF_MODL_ask_body_faces(bodyTag, &faceList);
int faceCount = 0;
UF_MODL_ask_list_count(faceList, &faceCount);
for (int i = 0; i < faceCount; i++)
{
tag_t bodyFaceTag = NULL_TAG;
UF_MODL_ask_list_item(faceList, i, &bodyFaceTag);
// 重置面颜色继承
UF_OBJ_set_color(bodyFaceTag, colorID);
}
UF_MODL_delete_list(&faceList);
// 设置实体颜色
UF_OBJ_set_color(bodyTag, colorID);
UF_DISP_set_highlight(bodyTag, 0);
processedBodies.insert(bodyTag); // 添加到已处理集合
}
}
}
// 清空选择并刷新显示
vFaces.clear();
face1->SetSelectedObjects(vFaces);
UF_DISP_refresh();
}
}
else
{
theUI->NXMessageBox()->Show("MICH-明:错误提示", NXMessageBox::DialogTypeError, "color1未初始化!");
}
}
catch (exception& ex)
{
theUI->NXMessageBox()->Show("MICH-明:错误提示", NXMessageBox::DialogTypeError, ex.what());
}
} // 这行结束
else if (block == bu2)
{
//---------Enter your code here-----------
}
else if (block == bu3)
{
//---------Enter your code here-----------
}
else if (block == bu4)
{
//---------Enter your code here-----------
}
else if (block == color5)
{
//---------Enter your code here-----------
}
else if (block == color6)
{
//---------Enter your code here-----------
}
else if (block == color7)
{
//---------Enter your code here-----------
}
else if (block == color8)
{
//---------Enter your code here-----------
}
else if (block == bu5)
{
//---------Enter your code here-----------
}
else if (block == bu6)
{
//---------Enter your code here-----------
}
else if (block == bu7)
{
//---------Enter your code here-----------
}
else if (block == bu8)
{
//---------Enter your code here-----------
}
else if (block == color9)
{
//---------Enter your code here-----------
}
else if (block == color10)
{
//---------Enter your code here-----------
}
else if (block == color11)
{
//---------Enter your code here-----------
}
else if (block == color12)
{
//---------Enter your code here-----------
}
else if (block == bu9)
{
//---------Enter your code here-----------
}
else if (block == bu10)
{
//---------Enter your code here-----------
}
else if (block == bu11)
{
//---------Enter your code here-----------
}
else if (block == bu12)
{
//---------Enter your code here-----------
}
else if (block == dbpface)
{
try
{
// 确保face1控件已初始化
if (face1 != nullptr)
{
// 1. 获取当前显示部件
tag_t displayPart = UF_PART_ask_display_part(); // 获取当前显示部件的标签
if (displayPart == NULL_TAG) // 检查是否成功获取显示部件
{
theUI->NXMessageBox()->Show("MICH-明:错误提示", NXMessageBox::DialogTypeError, "未找到显示部件!"); // 显示错误消息
return 0; // 退出函数
}
// 2. 收集所有可见实体
std::vector<tag_t> allObjects; // 存储可见实体的容器
tag_t currentObject = NULL_TAG; // 当前处理的对象标签
// 遍历部件中的所有实体对象
UF_OBJ_cycle_objs_in_part(displayPart, UF_solid_type, ¤tObject); // 获取第一个实体对象
while (currentObject != NULL_TAG) // 循环直到没有更多实体
{
// 获取对象的显示属性
UF_OBJ_disp_props_t disp_props; // 声明显示属性结构体
if (UF_OBJ_ask_display_properties(currentObject, &disp_props) == 0) // 获取对象的显示属性
{
// 检查对象是否显示(未隐藏)
if (UF_OBJ_NOT_BLANKED == disp_props.blank_status) // 检查对象是否显示
{
// 检查对象所在图层状态
int layer_status = 0; // 存储图层状态
if (UF_LAYER_ask_status(disp_props.layer, &layer_status) == 0) // 获取图层状态
{
// 检查图层是否可见(活动图层或参考图层)
if (
layer_status == UF_LAYER_WORK_LAYER || // 工作图层(可见可编辑)
layer_status == UF_LAYER_ACTIVE_LAYER || // 活动图层(可见可选)
layer_status == UF_LAYER_REFERENCE_LAYER) // 参考图层(仅可见)
{
allObjects.push_back(currentObject); // 将可见实体添加到容器
}
}
}
}
// 获取下一个对象
UF_OBJ_cycle_objs_in_part(displayPart, UF_solid_type, ¤tObject); // 继续遍历下一个实体
}
if (allObjects.empty()) // 检查是否有可见实体
{
theUI->NXMessageBox()->Show("MICH-明:提示", NXMessageBox::DialogTypeInformation, "部件中没有可见实体!"); // 显示提示消息
return 0; // 退出函数
}
// 3. 收集所有面
std::vector<TaggedObject*> allFaces;
for (tag_t objectTag : allObjects)
{
// 获取对象上的所有面
uf_list_p_t faceList = NULL;
if (UF_MODL_ask_body_faces(objectTag, &faceList) != 0) continue;
int faceCount = 0;
UF_MODL_ask_list_count(faceList, &faceCount);
for (int i = 0; i < faceCount; i++)
{
tag_t faceTag = NULL_TAG;
UF_MODL_ask_list_item(faceList, i, &faceTag);
// 创建NXOpen::Face对象并添加到列表
NXOpen::Face* face = dynamic_cast<NXOpen::Face*>(NXOpen::NXObjectManager::Get(faceTag));
if (face) allFaces.push_back(face);
}
// 释放面列表内存
if (faceList) UF_MODL_delete_list(&faceList);
}
// ================ 使用UF函数过滤水平面 ================
std::vector<TaggedObject*> horizontalFaces;
const double tolerance = 0.0175; // 约1度(弧度)
const double z_axis[3] = { 0.0, 0.0, 1.0 }; // 绝对Z轴方向
for (auto faceObj : allFaces)
{
tag_t faceTag = faceObj->Tag();
int faceType = 0;
// 获取面类型
if (UF_MODL_ask_face_type(faceTag, &faceType) == 0 && faceType == UF_MODL_PLANAR_FACE)
{
double direction[3] = { 0.0, 0.0, 0.0 };
double point[3] = { 0.0, 0.0, 0.0 };
double box[6] = { 0.0 };
double rad = 0.0;
double rad_data[2] = { 0.0 };
int status = 0;
// 获取面数据
if (UF_MODL_ask_face_data(faceTag, &faceType, point, direction, box, &rad, rad_data, &status) == 0)
{
// 计算法向与Z轴的点积
double dot = z_axis[0] * direction[0] + z_axis[1] * direction[1] + z_axis[2] * direction[2];
// 法向平行于Z轴(点积接近1或-1)
if (fabs(fabs(dot) - 1.0) < tolerance)
{
horizontalFaces.push_back(faceObj);
}
}
}
}
// ================ 结束过滤代码 ================
// ================ 找出Z方向最高的水平面 ================
std::vector<TaggedObject*> highestFaces;
double maxZ = -DBL_MAX; // 初始化为最小可能值
// 1. 找出最高Z值
for (auto faceObj : horizontalFaces)
{
tag_t faceTag = faceObj->Tag();
double box[6]; // [xmin, ymin, zmin, xmax, ymax, zmax]
// 获取面的包围盒
if (UF_MODL_ask_bounding_box(faceTag, box) == 0)
{
// 使用包围盒的zmax作为面的高度
double zMax = box[5];
// 更新最大Z值
if (zMax > maxZ)
{
maxZ = zMax;
}
}
}
// 2. 收集所有位于最高Z值位置的面
const double zTolerance = 0.001; // Z值容差(1毫米)
for (auto faceObj : horizontalFaces)
{
tag_t faceTag = faceObj->Tag();
double box[6];
if (UF_MODL_ask_bounding_box(faceTag, box) == 0)
{
double zMax = box[5];
// 检查是否在最高Z值位置(考虑容差)
if (fabs(zMax - maxZ) < zTolerance)
{
highestFaces.push_back(faceObj);
}
}
}
// ================ 结束最高面选择 ================
// 4. 设置到FaceCollector控件 - 使用最高水平面
face1->SetSelectedObjects(highestFaces);
// 5. 刷新界面
UF_DISP_refresh();
//// 显示成功消息
//char msg[256];
//sprintf(msg, "已选择 %d 个最高水平面 (Z = %.2f)", (int)highestFaces.size(), maxZ);
//theUI->NXMessageBox()->Show("操作成功", NXMessageBox::DialogTypeInformation, msg);
}
else
{
theUI->NXMessageBox()->Show("MICH-明:提示错误", NXMessageBox::DialogTypeError, "面选择控件未初始化!");
}
}
catch (exception& ex)
{
theUI->NXMessageBox()->Show("MICH-明:提示异常错误", NXMessageBox::DialogTypeError, ex.what());
}
//---------Enter your code here-----------
}
else if (block == gtbody)
{
try
{
// 1. 获取当前显示部件
tag_t displayPart = UF_PART_ask_display_part(); // 获取当前工作部件
if (displayPart == NULL_TAG) // 检查部件是否有效
{
theUI->NXMessageBox()->Show("MICH-明错误提示", NXMessageBox::DialogTypeError, "未找到显示部件!");
return 0;
}
// 2. 收集所有可见实体
std::vector<tag_t> allBodies; // 存储所有可见实体
tag_t currentBody = NULL_TAG;
UF_OBJ_cycle_objs_in_part(displayPart, UF_solid_type, ¤tBody); // 开始遍历实体
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)
{
allBodies.push_back(currentBody); // 添加到可见实体列表
}
}
}
UF_OBJ_cycle_objs_in_part(displayPart, UF_solid_type, ¤tBody); // 获取下一个实体
}
if (allBodies.empty()) // 检查是否有可见实体
{
theUI->NXMessageBox()->Show("MICH-明提示", NXMessageBox::DialogTypeInformation, "部件中没有可见实体!");
return 0;
}
// 3. 收集需要着色的实体
std::set<tag_t> targetBodies; // 使用set避免重复
const double tolerance = 0.0175; // 约1度(弧度)的法向容差
const double z_axis[3] = { 0.0, 0.0, 1.0 }; // Z轴方向向量
const double z_tolerance = 0.001; // Z坐标容差(1毫米)
// 遍历所有实体
for (tag_t bodyTag : allBodies)
{
uf_list_p_t faceList = NULL;
if (UF_MODL_ask_body_faces(bodyTag, &faceList) != 0) continue; // 获取实体所有面
int faceCount = 0;
UF_MODL_ask_list_count(faceList, &faceCount); // 获取面数量
double minZ = DBL_MAX; // 初始化最小Z值为最大值
tag_t lowestFace = NULL_TAG; // 存储最低水平面
// 遍历实体的每个面
for (int i = 0; i < faceCount; i++)
{
tag_t faceTag = NULL_TAG;
UF_MODL_ask_list_item(faceList, i, &faceTag); // 获取面标签
int faceType = 0;
if (UF_MODL_ask_face_type(faceTag, &faceType) != 0) continue; // 获取面类型
// 只处理平面
if (faceType == UF_MODL_PLANAR_FACE)
{
double direction[3] = { 0 }; // 面法向
double point[3] = { 0 }; // 面上一点
double box[6] = { 0 }; // 面边界框
double rad = 0, rad_data[2] = { 0 };
int status = 0;
// 获取面几何数据
if (UF_MODL_ask_face_data(faceTag, &faceType, point, direction, box, &rad, rad_data, &status) == 0)
{
// 计算法向与Z轴的点积
double dot = z_axis[0] * direction[0] +
z_axis[1] * direction[1] +
z_axis[2] * direction[2];
// 检查是否为水平面(法向平行Z轴)
if (fabs(fabs(dot) - 1.0) < tolerance)
{
// 获取面的最低点Z坐标(边界框Zmin)
double faceMinZ = box[2];
// 更新最低水平面
if (faceMinZ < minZ)
{
minZ = faceMinZ;
lowestFace = faceTag;
}
}
}
}
}
// 检查是否找到最低水平面且高于XY平面
if (lowestFace != NULL_TAG && minZ > z_tolerance)
{
targetBodies.insert(bodyTag); // 添加到目标实体集合
}
UF_MODL_delete_list(&faceList); // 释放面列表内存
}
// 4. 检查是否有符合条件的实体
if (targetBodies.empty())
{
theUI->NXMessageBox()->Show("MICH-明提示", NXMessageBox::DialogTypeInformation, "未找到符合要求实体!");
return 0;
}
// 5. 着色处理
if (color5 != nullptr) // 确保颜色控件有效
{
try
{
// 获取选择的颜色
PropertyList* colorProps = color5->GetProperties();
std::vector<int> colors = colorProps->GetIntegerVector("Value");
int colorID = colors[0]; // 提取颜色ID
delete colorProps; // 释放属性对象
// 6. 为实体着色(保留面颜色重置)
for (tag_t bodyTag : targetBodies) // 遍历目标实体
{
// 重置实体所有面的颜色为继承
uf_list_p_t faceList = NULL;
if (UF_MODL_ask_body_faces(bodyTag, &faceList) == 0)
{
int faceCount = 0;
UF_MODL_ask_list_count(faceList, &faceCount);
for (int i = 0; i < faceCount; i++)
{
tag_t faceTag = NULL_TAG;
UF_MODL_ask_list_item(faceList, i, &faceTag);
UF_OBJ_set_color(faceTag, colorID); // 0=继承实体颜色
}
UF_MODL_delete_list(&faceList); // 释放面列表
}
// 设置实体颜色
UF_OBJ_set_color(bodyTag, colorID);
UF_DISP_set_highlight(bodyTag, 0); // 取消高亮
}
UF_DISP_refresh(); // 刷新显示
//// 显示结果信息
//char msg[256];
//snprintf(msg, sizeof(msg), "已为 %zu 个实体设置颜色", targetBodies.size());
//theUI->NXMessageBox()->Show("着色完成", NXMessageBox::DialogTypeInformation, msg);
}
catch (std::exception& ex)
{
theUI->NXMessageBox()->Show("MICH-明提示:着色错误", NXMessageBox::DialogTypeError, ex.what());
}
}
else
{
theUI->NXMessageBox()->Show("MICH-明错误提示", NXMessageBox::DialogTypeError, "颜色选择控件未初始化!");
}
}
catch (std::exception& ex)
{
theUI->NXMessageBox()->Show("MICH-明:系统错误", NXMessageBox::DialogTypeError, ex.what());
}
//---------Enter your code here-----------
}
else if(block == arcface)
{
try
{
if (face1 != nullptr) // 确保面选择控件有效
{
// 1. 获取当前显示部件
tag_t displayPart = UF_PART_ask_display_part(); // 获取当前显示的部件标签
if (displayPart == NULL_TAG) // 检查是否获取成功
{
theUI->NXMessageBox()->Show("MICH-明:错误提示", NXMessageBox::DialogTypeError, "未找到显示部件!"); // 显示错误信息
return 0; // 提前返回
}
// 2. 收集可见实体并筛选最低点高于Z0的实体
std::vector<tag_t> filteredObjects; // 存储符合条件的实体标签
tag_t currentObject = NULL_TAG; // 当前遍历的实体
UF_OBJ_cycle_objs_in_part(displayPart, UF_solid_type, ¤tObject); // 开始遍历部件中的实体
while (currentObject != NULL_TAG) // 遍历所有实体
{
// 检查实体的显示属性
UF_OBJ_disp_props_t disp_props; // 存储显示属性
if (UF_OBJ_ask_display_properties(currentObject, &disp_props) == 0) // 获取显示属性
{
// 检查实体是否未被隐藏
if (UF_OBJ_NOT_BLANKED == disp_props.blank_status) // 实体可见
{
int layer_status = 0; // 图层状态
if (UF_LAYER_ask_status(disp_props.layer, &layer_status) == 0) // 获取图层状态
{
// 检查是否在可见图层上
if (layer_status == UF_LAYER_WORK_LAYER ||
layer_status == UF_LAYER_ACTIVE_LAYER ||
layer_status == UF_LAYER_REFERENCE_LAYER)
{
// 计算实体的边界框
double bbox[6] = { 0 }; // [xmin, ymin, zmin, xmax, ymax, zmax]
if (UF_MODL_ask_bounding_box(currentObject, bbox) == 0) // 获取边界框
{
// 检查实体最低点是否高于Z0
if (bbox[2] > 0.0) // bbox[2] 是 Zmin
{
filteredObjects.push_back(currentObject); // 添加到筛选列表
//// 调试信息:显示实体的最低点高度
//char debugMsg[256]; // 调试信息缓冲区
//snprintf(debugMsg, sizeof(debugMsg),
// "实体 %d 最低点: %.2f", currentObject, bbox[2]); // 格式化信息
// 使用NXMessageBox替代theUFUI
//theUI->NXMessageBox()->Show("调试信息", NXMessageBox::DialogTypeInformation, debugMsg); // 显示调试信息
}
}
}
}
}
}
UF_OBJ_cycle_objs_in_part(displayPart, UF_solid_type, ¤tObject); // 获取下一个实体
}
//// 显示筛选后的实体数量
//char objCountMsg[256]; // 消息缓冲区
//snprintf(objCountMsg, sizeof(objCountMsg),
// "找到最低点高于Z0的实体数量: %zu", filteredObjects.size()); // 格式化消息
//theUI->NXMessageBox()->Show("实体筛选", NXMessageBox::DialogTypeInformation, objCountMsg); // 显示消息
if (filteredObjects.empty()) // 检查是否有符合条件的实体
{
theUI->NXMessageBox()->Show("MICH-明:提示", NXMessageBox::DialogTypeInformation,
"没有符合条件的实体!"); // 显示提示
return 0; // 提前返回
}
// 3. 从筛选后的实体中收集所有圆弧面
std::vector<NXOpen::TaggedObject*> allFaces; // 存储所有面对象
for (tag_t objectTag : filteredObjects) // 遍历筛选后的实体
{
uf_list_p_t faceList = nullptr; // 面列表指针
if (UF_MODL_ask_body_faces(objectTag, &faceList) != 0) continue; // 获取实体所有面
// 自动释放列表内存的RAII封装
auto listDeleter = [](uf_list_p_t* list) { if (*list) UF_MODL_delete_list(list); }; // 自定义删除器
std::unique_ptr<uf_list_p_t, decltype(listDeleter)> listGuard(&faceList, listDeleter); // 智能指针管理
int faceCount = 0; // 面数量
UF_MODL_ask_list_count(faceList, &faceCount); // 获取面数量
for (int i = 0; i < faceCount; i++) // 遍历所有面
{
tag_t faceTag = NULL_TAG; // 面标签
UF_MODL_ask_list_item(faceList, i, &faceTag); // 获取面标签
if (auto face = dynamic_cast<NXOpen::Face*>(NXOpen::NXObjectManager::Get(faceTag))) // 转换为面对象
{
allFaces.push_back(face); // 添加到面列表
}
}
}
// 4. 收集所有圆弧面(包括圆柱、圆锥和圆角面)
std::vector<NXOpen::TaggedObject*> allArcFaces; // 存储圆弧面对象
int cylinderCount = 0, coneCount = 0, blendCount = 0; // 各类面计数器
for (auto faceObj : allFaces) // 遍历所有面
{
tag_t faceTag = faceObj->Tag(); // 获取面标签
int faceType = 0; // 面类型
double point[3] = { 0 }; // 点坐标
double dir[3] = { 0 }; // 方向向量
double box[6] = { 0 }; // 边界框
double radius = 0; // 半径
double rad_data[2] = { 0 }; // 半径数据
int norm_dir = 0; // 法线方向
// 获取面数据
if (UF_MODL_ask_face_data(faceTag, &faceType, point, dir, box, &radius, rad_data, &norm_dir) != 0)
continue; // 跳过获取失败的面
// 只收集圆弧相关面类型
if (faceType == 16) // 圆柱面
{
cylinderCount++; // 增加计数器
allArcFaces.push_back(faceObj); // 添加到圆弧面列表
}
else if (faceType == 7) // 圆锥面
{
coneCount++; // 增加计数器
allArcFaces.push_back(faceObj); // 添加到圆弧面列表
}
else if (faceType == 19) // 圆环曲面
{
coneCount++; // 增加计数器
allArcFaces.push_back(faceObj); // 添加到圆弧面列表
}
else if (faceType == 18) // 球面
{
coneCount++; // 增加计数器
allArcFaces.push_back(faceObj); // 添加到圆弧面列表
}
else if (faceType == 23) // 圆角面
{
blendCount++; // 增加计数器
allArcFaces.push_back(faceObj); // 添加到圆弧面列表
}
}
//// 显示圆弧面统计信息
//char debugMsg[256]; // 消息缓冲区
//snprintf(debugMsg, sizeof(debugMsg),
// "从筛选实体中找到圆弧面总数: %zu\n圆柱面: %d\n圆锥面: %d\n圆角面: %d",
// allArcFaces.size(), cylinderCount, coneCount, blendCount); // 格式化消息
//theUI->NXMessageBox()->Show("圆弧面统计", NXMessageBox::DialogTypeInformation, debugMsg); // 显示消息
if (allArcFaces.empty()) // 检查是否有圆弧面
{
theUI->NXMessageBox()->Show("MICH-明:提示", NXMessageBox::DialogTypeInformation,
"筛选实体中没有圆弧面!"); // 显示提示
return 0; // 提前返回
}
// 5. 直接选择所有圆弧面
face1->SetSelectedObjects(allArcFaces); // 设置选中的面
UF_DISP_refresh(); // 刷新显示
//// 显示最终结果
//char msg[256]; // 结果消息缓冲区
//snprintf(msg, sizeof(msg), "已选择 %zu 个圆弧面", allArcFaces.size()); // 格式化消息
//theUI->NXMessageBox()->Show("操作成功", NXMessageBox::DialogTypeInformation, msg); // 显示结果
}
}
catch (std::exception& ex) // 捕获异常
{
theUI->NXMessageBox()->Show("MICH-明:系统错误", NXMessageBox::DialogTypeError, ex.what()); // 显示错误信息
}
//---------Enter your code here-----------
}
else if(block == gaodipoints)
{
try
{
// 1. 获取当前显示部件
tag_t displayPart = UF_PART_ask_display_part();
if (displayPart == NULL_TAG)
{
theUI->NXMessageBox()->Show("MICH-明错误提示", NXMessageBox::DialogTypeError, "未找到显示部件!");
return 0;
}
// 2. 收集所有可见实体
std::vector<tag_t> allBodies;
tag_t currentBody = NULL_TAG;
UF_OBJ_cycle_objs_in_part(displayPart, UF_solid_type, ¤tBody);
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)
{
allBodies.push_back(currentBody);
}
}
}
UF_OBJ_cycle_objs_in_part(displayPart, UF_solid_type, ¤tBody);
}
if (allBodies.empty())
{
theUI->NXMessageBox()->Show("MICH-明提示", NXMessageBox::DialogTypeInformation, "部件中没有可见实体!");
return 0;
}
// 3. 收集目标实体和它们的最大边界面
std::set<tag_t> targetBodies;
std::vector<tag_t> targetFaces; // 存储最大边界上的面
const double normal_tolerance = 0.0175; // 法向容差≈1°(弧度)
const double coord_tolerance = 0.001; // 坐标容差(1毫米)
const double z_axis[3] = { 0.0, 0.0, 1.0 }; // Z轴方向向量
// 遍历所有实体
for (tag_t bodyTag : allBodies)
{
// 3.1 获取实体的边界框
double bodyMinPoint[3], bodyMaxPoint[3];
if (UF_MODL_ask_bounding_box(bodyTag, bodyMinPoint, bodyMaxPoint) != 0)
continue;
// 3.2 获取实体的所有面
uf_list_p_t faceList = NULL;
if (UF_MODL_ask_body_faces(bodyTag, &faceList) != 0) continue;
int faceCount = 0;
UF_MODL_ask_list_count(faceList, &faceCount);
// 3.3 遍历实体的每个面
for (int i = 0; i < faceCount; i++)
{
tag_t faceTag = NULL_TAG;
UF_MODL_ask_list_item(faceList, i, &faceTag);
int faceType = 0;
if (UF_MODL_ask_face_type(faceTag, &faceType) != 0) continue;
// 只处理平面
if (faceType == UF_MODL_PLANAR_FACE)
{
double direction[3] = { 0 }; // 面法向
double point[3] = { 0 }; // 面上一点
double box[6] = { 0 }; // 面边界框
double rad = 0, rad_data[2] = { 0 };
int status = 0;
// 获取面几何数据
if (UF_MODL_ask_face_data(faceTag, &faceType, point, direction, box, &rad, rad_data, &status) == 0)
{
// 3.4 检查是否为垂直平面(平行于Z轴)
// 法向与Z轴的点积应接近0(垂直)
double dot = z_axis[0] * direction[0] +
z_axis[1] * direction[1] +
z_axis[2] * direction[2];
if (fabs(dot) < normal_tolerance)
{
// 3.5 检查面是否位于实体的最大边界上
bool isMaxBoundaryFace = false;
// 检查X方向最大边界
if (fabs(box[3] - bodyMaxPoint[0]) < coord_tolerance)
{
// 法向应与X轴正方向一致(朝外)
if (direction[0] > 0.5)
{
isMaxBoundaryFace = true;
}
}
// 检查Y方向最大边界
else if (fabs(box[4] - bodyMaxPoint[1]) < coord_tolerance)
{
// 法向应与Y轴正方向一致(朝外)
if (direction[1] > 0.5)
{
isMaxBoundaryFace = true;
}
}
// 检查X方向最小边界(法向朝外)
if (!isMaxBoundaryFace && fabs(box[0] - bodyMinPoint[0]) < coord_tolerance)
{
if (direction[0] < -0.5)
{
isMaxBoundaryFace = true;
}
}
// 检查Y方向最小边界(法向朝外)
else if (!isMaxBoundaryFace && fabs(box[1] - bodyMinPoint[1]) < coord_tolerance)
{
if (direction[1] < -0.5)
{
isMaxBoundaryFace = true;
}
}
// 3.6 如果是最大边界上的面,添加到结果
if (isMaxBoundaryFace)
{
targetBodies.insert(bodyTag);
targetFaces.push_back(faceTag);
}
}
}
}
}
UF_MODL_delete_list(&faceList); // 释放面列表内存
}
// 4. 检查是否有符合条件的实体
if (targetBodies.empty())
{
theUI->NXMessageBox()->Show("MICH-明提示", NXMessageBox::DialogTypeInformation, "未找到符合要求的实体!");
return 0;
}
// 5. 着色处理
if (color5 != nullptr)
{
try
{
// 获取选择的颜色
PropertyList* colorProps = color5->GetProperties();
std::vector<int> colors = colorProps->GetIntegerVector("Value");
int colorID = colors[0];
delete colorProps;
// 6. 为实体和边界面着色
for (tag_t faceTag : targetFaces)
{
UF_OBJ_set_color(faceTag, colorID); // 为边界面着色
}
// 刷新显示
UF_DISP_refresh();
// 显示结果信息
char msg[256];
snprintf(msg, sizeof(msg), "已为 %zu 个实体的 %zu 个边界面设置颜色",
targetBodies.size(), targetFaces.size());
theUI->NXMessageBox()->Show("着色完成", NXMessageBox::DialogTypeInformation, msg);
}
catch (std::exception& ex)
{
theUI->NXMessageBox()->Show("MICH-明提示:着色错误", NXMessageBox::DialogTypeError, ex.what());
}
}
else
{
theUI->NXMessageBox()->Show("MICH-明错误提示", NXMessageBox::DialogTypeError, "颜色选择控件未初始化!");
}
}
catch (std::exception& ex)
{
theUI->NXMessageBox()->Show("MICH-明:系统错误", NXMessageBox::DialogTypeError, ex.what());
}
//---------Enter your code here-----------
}
}
catch(exception& ex)
{
//---- Enter your exception handling code here -----
gaiyansetool::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what());
}
return 0;
}
//------------------------------------------------------------------------------
//Callback Name: ok_cb
//------------------------------------------------------------------------------
int gaiyansetool::ok_cb()
{
int errorCode = 0;
try
{
errorCode = apply_cb();
}
catch(exception& ex)
{
//---- Enter your exception handling code here -----
errorCode = 1;
gaiyansetool::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what());
}
return errorCode;
}
//------------------------------------------------------------------------------
//Function Name: GetBlockProperties
//Description: Returns the propertylist of the specified BlockID
//------------------------------------------------------------------------------
PropertyList* gaiyansetool::GetBlockProperties(const char *blockID)
{
return theDialog->GetBlockProperties(blockID);
}
提示严重性 代码 说明 项目 文件 行 禁止显示状态
错误(活动) E0140 函数调用中的参数太多 gaiyansetool D:\NXopen\BaiduSyncdisk\studio\gaiyansetool\gaiyansetool.cpp 1083