本来做的是案例六NX二次开发减重块。但是当时在处理导入指定面时发现坐标转化存在很大问题,开了我很长时间,太难受了,决定放一放,昨天做了第六个案例采取了一种补救方法(实在不会的一种解决思路),个人认为NX这么优秀的软件应该有更好的方法,坐标转化真让人头大。刚开始学习NX二次开发时,有人让我做一个“标识特征”的功能,就是在指定的位置打上标识。那时候觉得特别难,几乎什么都不会。现在正好有时间重新回头做一下,发现其实并不复杂。这个功能就是在指定的位置导入标识,然后通过布尔运算进行相减,整体实现也比较简单。(案例六过几天再补齐)
目录
一、Block UI分析
主要用到了的控件为:枚举控件(菱形框和R标识)、选择面和边的控件和三个个双精度的控件。
二、存在的问题
说一下存在的问题吧,看似简单的功能实则存在很大的BUG,出错总是出人意料,一个是写代码的习惯,一个是TAG之间的联系,说一下该案例中主要用到的功能中发现的问题。
(1)在指定面导入部件后,如何点击不同面实现快速切换——本来想的是重新编辑,但是后来发现好像导入函数里边没有重新编辑,因此决定删除,在重新导入。那么如何找到导入后的部件TAG,是重要的问题之一;
(2)坐标系之间的转化:导入部件一个原点,一个是设置正确的导入坐标,原点简单的很,找到你放置位置的点就行,但是坐标真是让人头大。个人认为是最难,如果坐标可以搞明白,该功做出来很轻松,目前个人水平有限,只能实现代码堆叠,要是有人授课,不是特别贵,我愿意报名。这个真的好多功能都会用到。
解决思路:
导入部件后的名称在哪里
UF_PART_import(BasePanth1.c_str(), &modes, dest_csys, dest_point, 1.0, &group);这个group就行直接删除(UF_OBJ_delete_object(TAGgroup);),后续的布尔求差所用到的实体的tag也是在group中过滤信息得到的实体。
坐标问题
(1)只选择放置面时,放置到指定面的中点,主要用到获取面的法向量,然后获得面上随机的X_Y方向向量;
(2)选择放置面和边时,放置在边的中点,根据法向量和边上两点构成的X向量,可以求出Y向量,然后就是调整Y向量的方向了,使最后标识特征在面上正确显示。
//设置导入部件的X和Y方向
vector<double> NXOpen_IdentificationFeature::SetPartXYAxis()
{
vector<double> XYAxis;
try
{
//获得选中面标识
PropertyList* faceSelectProps = face_select0->GetProperties();
std::vector<NXOpen::TaggedObject *> face = faceSelectProps->GetTaggedObjectVector("SelectedObjects");
delete faceSelectProps;
faceSelectProps = NULL;
//获取指定面的法向量ZAxis
int type = 0;
double pointf[3];
double AxisZ[3];
double box[6];
double radius;
double rad_data[2];
int norm_dir = 0;
UF_MODL_ask_face_data(face[0]->Tag(), &type, pointf, AxisZ, box, &radius, rad_data, &norm_dir);
//获得选中边标识
PropertyList* edgeSelectProps = edge_select0->GetProperties();
std::vector<NXOpen::TaggedObject *> edges = edgeSelectProps->GetTaggedObjectVector("SelectedObjects");
delete edgeSelectProps;
edgeSelectProps = NULL;
if (edges.empty())
{
//由面的法向量随机生成 XYAxis
//获得XY方向
double mtx[9];
UF_MTX3_initialize_z(AxisZ, mtx);
double AxisX[3] = { mtx[0],mtx[1],mtx[2] };
double AxisY[3] = { mtx[3],mtx[4],mtx[5] };
for (int i = 0; i < 6; i++)
{
XYAxis.push_back(mtx[i]);
}
XYAxis.push_back(AxisZ[0]);
XYAxis.push_back(AxisZ[1]);
XYAxis.push_back(AxisZ[2]);
}
else
{
double edgepoint1[3];
double edgepoint2[3];
int vertex_count = 0;
//获取边的端点
UF_MODL_ask_edge_verts(edges[0]->Tag(), edgepoint1, edgepoint2, &vertex_count);
//两点求向量AxisX
double AxisX1[3] = { 0.0 };
UF_VEC3_sub(edgepoint1, edgepoint2, AxisX1);
//向量长度
double dist = 0;
UF_VEC3_distance(edgepoint1, edgepoint2, &dist);
//单元化一个向量。单位向量。
double AxisX[3] = { 0.0 };
UF_VEC3_unitize(AxisX1, 0.001, &dist, AxisX);
//两个向量叉乘求AxisY
double AxisY[3] = { 0.0 };
UF_VEC3_cross(AxisZ, AxisX, AxisY);
//处理1法向量为Y负
double tol = 0.001;
int retY1 = 0;
double vecY1[3] = { 0.0,-1.0,0.0 };
UF_VEC3_is_equal(vecY1, AxisZ, tol, &retY1);
//处理2法向量为Y正
int retY2 = 0;
double vecY2[3] = { 0.0,1.0,0.0 };
UF_VEC3_is_equal(vecY2, AxisZ, tol, &retY2);
//处理3法向量为X负
int retX1 = 0;
double vecX1[3] = { -1.0,0.0,0.0 };
UF_VEC3_is_equal(vecX1, AxisZ, tol, &retX1);
//处理4法向量为X正
int retX2 = 0;
double vecX2[3] = {1.0,0.0,0.0 };
UF_VEC3_is_equal(vecX2, AxisZ, tol, &retX2);
if (retY1)
{
int retY_X1 = 0;
double vecY_X1[3] = { 1.0,0.0,0.0 };
UF_VEC3_is_equal(vecY_X1, AxisY, tol, &retY_X1);
if (!retY_X1)
{
AxisY[0] = -AxisY[0];
AxisY[1] = -AxisY[1];
AxisY[2] = -AxisY[2];
}
else
{
//获得所选平面中点facepoint
double uv_min_max[4];
UF_MODL_ask_face_uv_minmax(face[0]->Tag(), uv_min_max);
double param[2];
param[0] = (uv_min_max[0] + uv_min_max[1]) / 2;
param[1] = (uv_min_max[2] + uv_min_max[3]) / 2;
double facepoint