一,问题的引出
之前在求曲面的面积时,也接触过一部分的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,否则会出现错误。
具体解释见下面链接:http://www.davidlenihan.com/2008/01/choosing_the_correct_cc_runtim.html
三,问题的解决
在将上述设置修改之后,功能成功实现,最后利用与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++接口错误,是不是工程设置的问题呢?太晚了,要回去了,明天给答案!
五,最后
现在关于UG二次开发的技术讨论已经转到了http://www.kongmishu.com/.