(以上图片为文章例图) 

一,问题的引出

     之前在求曲面的面积时,也接触过一部分的NXOPEN C++接口,但是了解的不够全面,这次是需要完成一个空间三维曲面拉伸的功能。

    问题:在利用UG自带的命令并选择sheet edges是可以完成空间sheet body的实体拉伸的,但是利用ugopen 中的create_extrude函数,则只能拉伸二维片体,对于三维空间sheet则无法完成。

二,问题的着手

     在排出了函数使用问题后,首先想到的是能不能利用C++的接口辅助完成这样的功能,众所周知,C++的接口更加丰富并且在UG中可以直接录制生成C++代码,这样无疑大大简化了C++接口函数的使用。

在仔细查看空间片体拉伸的C++代码后,发现其是通过向UF_MODL_create_extrude函数提供需要拉伸的对象的tag值实现,在UG特征树里面是以profile表现出来的;而C++函数和ug自带命令都是以section作为

拉伸轮廓,在其基础上拉伸出来的。见下图:


        上图是利用ug命令做出来的效果,而利用ugopen函数生成时,图中的红色框中不是section而是profile。可能这是导致不能利用ugopen拉伸空间sheet的原因所在。从这里我们也可以得到一个启示:在利用某个函数生成一个特征时,我们可以先在ug中手动操作一遍,在特征树中查看该特征的所有细节,这样有助于我们更好的使用其对应的ugopen API。

        当我把录制生成的C++代码完整的复制到当前工程(利用vs2005在NX4.0上开发的)的相应函数中时,发现总是执行错误,提示:memory access error,由于之前了解到每个NX的版本对应的开发环境是不一样的,于是将该工程转到vs2010中并在NX8.0上进行测试,但是发现始终不能成功。这时蛋疼的找错误旅程开始了,经过各种艰辛和挫折终于找到了问题所在:由于当前的工程是在NX4.0中创建的,现在又将其拿到了NX8.0上来测试,结果发现这两个平台上的默认工程设置有些选项是不一样的,如果不进行修改就会导致在NX8.0上运行不成功。先将其问题所在截图如下:

在NX4.0中其默认设置是/MDd而在NX8.0中必须是/MD,否则会出现错误。

具体解释见下面链接:/static/upload/wimg/2017/11/20/1018674381906612.jpg

三,问题的解决

      在将上述设置修改之后,功能成功实现,最后利用与ugopen C的交互完成上述功能,具体代码如下:比较粗略,不是完全的最终实际代码,但是有C和C++交互的地方。
Session *theSession = Session::GetSession();
   Part *workPart(theSession->Parts()->Work());
   Part *displayPart(theSession->Parts()->Display());
   // ----------------------------------------------
   //   Menu: Insert->Design Feature->Extrude...
   // ----------------------------------------------
   Session::UndoMarkId markId1;
   markId1 = theSession->SetUndoMark(Session::MarkVisibilityVisible, "Start");

   Unit *unit1(dynamic_cast<Unit *>(workPart->UnitCollection()->FindObject("MilliMeter")));
   Expression *expression1;
   expression1 = workPart->Expressions()->CreateSystemExpressionWithUnits("0", unit1);

   Expression *expression2;
   expression2 = workPart->Expressions()->CreateSystemExpressionWithUnits("0", unit1);

   Features::Feature *nullFeatures_Feature(NULL);

   if ( !workPart->Preferences()->Modeling()->GetHistoryMode() )
   {
    throw NXException::Create("Create or edit of a Feature was recorded in History Mode but playback is in History-Free Mode.");
   }

   Features::ExtrudeBuilder *extrudeBuilder1;
   extrudeBuilder1 = workPart->Features()->CreateExtrudeBuilder(nullFeatures_Feature);

   Section *section1;
   section1 = workPart->Sections()->CreateSection(0.02413, 0.0254, 0.5);

   extrudeBuilder1->SetSection(section1);

   extrudeBuilder1->AllowSelfIntersectingSection(true);

   Unit *unit2;
   unit2 = extrudeBuilder1->Draft()->FrontDraftAngle()->Units();

   Expression *expression3;
   expression3 = workPart->Expressions()->CreateSystemExpressionWithUnits("2.00", unit2);

   extrudeBuilder1->SetDistanceTolerance(0.0254);

   extrudeBuilder1->BooleanOperation()->SetType(GeometricUtilities::BooleanOperation::BooleanTypeCreate);

   std::vector<Body *> targetBodies1(1);
   Body *nullBody(NULL);
   targetBodies1[0] = nullBody;
   extrudeBuilder1->BooleanOperation()->SetTargetBodies(targetBodies1);

   extrudeBuilder1->Limits()->StartExtend()->Value()->SetRightHandSide("0");

   extrudeBuilder1->Limits()->EndExtend()->Value()->SetRightHandSide("206");

   extrudeBuilder1->BooleanOperation()->SetType(GeometricUtilities::BooleanOperation::BooleanTypeCreate);

   std::vector<Body *> targetBodies2(1);
   targetBodies2[0] = nullBody;
   extrudeBuilder1->BooleanOperation()->SetTargetBodies(targetBodies2);

   extrudeBuilder1->Offset()->StartOffset()->SetRightHandSide("0");

   extrudeBuilder1->Offset()->EndOffset()->SetRightHandSide("-5");

   theSession->SetUndoMarkName(markId1, "Extrude Dialog");

   section1->SetDistanceTolerance(0.0254);

   section1->SetChainingTolerance(0.02413);

   section1->SetAllowedEntityTypes(Section::AllowTypesOnlyCurves);

   Session::UndoMarkId markId2;
   markId2 = theSession->SetUndoMark(Session::MarkVisibilityInvisible, "section mark");

   Session::UndoMarkId markId3;
   markId3 = theSession->SetUndoMark(Session::MarkVisibilityInvisible, NULL);

   //Body *body1(dynamic_cast<Body *>(workPart->Bodies()->FindObject("UNPARAMETERIZED_FEATURE(13)")));
   Body *body1 = (NXOpen::Body*)NXOpen::NXObjectManager::Get(selected_objects[0]);
   EdgeSheetBoundaryRule *edgeSheetBoundaryRule1;
   edgeSheetBoundaryRule1 = workPart->ScRuleFactory()->CreateRuleEdgeSheetBoundary(body1);

   section1->AllowSelfIntersection(true);

   std::vector<SelectionIntentRule *> rules1(1);
   rules1[0] = edgeSheetBoundaryRule1;
   //Features::Brep *brep1(dynamic_cast<Features::Brep *>(workPart->Features()->FindObject("UNPARAMETERIZED_FEATURE(13)")));
   //Edge *edge1(dynamic_cast<Edge *>(brep1->FindObject("EDGE * -7 * 1 {(-407.1621251224786,-1172.7439800662899,520.4009237838723)(-216.591454390298,-1172.7439800624404,510.916864808886)(-33.6870813398001,-1172.7439800616039,456.5742642366055) UNPARAMETERIZED_FEATURE(13)}")));
   uf_list_p_t  edge_list  = NULL;
   tag_t           edge;
   //edge = edge2->GetTag();
   UF_MODL_ask_body_edges(selected_objects[0],&edge_list);
   UF_MODL_ask_list_item(edge_list,0,&edge);
   Edge *edge1 = (NXOpen::Edge*)NXOpen::NXObjectManager::Get(edge);
   UF_MODL_delete_list(&edge_list);
   NXObject *nullNXObject(NULL);
   Point3d helpPoint1(-127.272222356459, -1172.74398006166, 490.324907507769);
   section1->AddToSection(rules1, edge1, nullNXObject, nullNXObject, helpPoint1, Section::ModeCreate, false);

   theSession->DeleteUndoMark(markId3, NULL);

   Point3d origin1(-216.591454403986, -586.37199003064, 510.916864771841);
   Vector3d vector1(0.168457071581346, 6.62067622040613e-011, 0.985708991048696);
   Direction *direction1;
   direction1 = workPart->Directions()->CreateDirection(origin1, vector1, SmartObject::UpdateOptionWithinModeling);

   extrudeBuilder1->SetDirection(direction1);

   theSession->DeleteUndoMark(markId2, NULL);

   Session::UndoMarkId markId4;
   markId4 = theSession->SetUndoMark(Session::MarkVisibilityInvisible, "Extrude");

   extrudeBuilder1->SetParentFeatureInternal(false);

   Features::Feature *feature1;
   feature1 = extrudeBuilder1->CommitFeature();

   theSession->DeleteUndoMark(markId4, NULL);

   theSession->SetUndoMarkName(markId1, "Extrude");

   Expression *expression4(extrudeBuilder1->Limits()->StartExtend()->Value());
   Expression *expression5(extrudeBuilder1->Limits()->EndExtend()->Value());
   extrudeBuilder1->Destroy();

   workPart->Expressions()->Delete(expression3);

   workPart->Expressions()->Delete(expression1);

   workPart->Expressions()->Delete(expression2);


四,总结

1.以后找问题症结时,一定要先找出现错误可能性较大的地方,再次之,按照这样的条理可能会帮你节约很多的时间;

2.原来利用vs2005在NX4.0中使用C++接口错误,是不是工程设置的问题呢?

 

      经过今天的测试证明:在修改了上述工程设置之后,利用VS2005编译的工程也是可以再NX4.0上面运行的(这里是指利用C++接口时),说明NX版本和编译器版本并不是对应的特别严格。这是一个好的消息。
      还有一个不好的消息:由于NXopen C++接口在不断的更新,也就是每个版本的NX对应的C++接口都不一样,这样会导致在NX4.0上运行成功的code在NX8.0上不能运行。这就要求利用到C++接口时需要针对于特定的版本进行开发。可能这也是NXOPEN C++还不是应用特别广泛的原因之一。