VS2005+ProE3.0 示例程序下载:http://download.csdn.net/detail/wangyao1052/4954443
使用方法:1、解压缩,在Bin目录下有创建好的udf:hole.gph以及零件档:prt001.prt,还有已经编译好的dll文件。
2、修改GoProE.bat中启动ProE3.0的路径为你本机Proe3.0的安装路径,双击GoProE.bat启动ProE3.0,会加载Test菜单。
3、在ProE中打开prt001.prt,点击Test就会调用程序让用户选择点,选择其中的某个点后,就会调用hole.gph创建孔。
我们知道,ProE在插入UDF时,会从两个路径下寻找udf:ProE当前的工作目录以及在配置文件config.pro或config.sup中pro_group_dir定义的路径。
所以,为保证此程序顺利找到udf,hole.gph必须放在ProE的当前工作目录下。
而之所以,用GoProE.bat启动ProE,就在于用这种方式启动ProE会设置ProE的工作目录为GoProE.bat所在的目录下,这样就能找到hole.gph了,而且,protk.dat文件里面的路径为相对路径,而不是绝对路径,这样,就能通过protk.dat正确加载路径了。
创建对应udf的视频:http://download.csdn.net/detail/wangyao1052/4954580
代码如下:
//----------------------------------------------------------------------------- //***************************************************************************** //----------------------------------------------------------------------------- #pragma region #include <ProToolkit.h> #include <ProUtil.h> #include <ProMenuBar.h> #include <ProMenu.h> #include <ProMode.h> #include <ProMdl.h> #include <ProSolid.h> #include <ProAsmcomp.h> #include <ProArray.h> #include <ProModelitem.h> #include <ProLayer.h> #include <ProUdf.h> #include <ProWindows.h> // 函数声明 uiCmdAccessState TestAccess(uiCmdAccessMode access_mode); int Test(uiCmdCmdId command, uiCmdValue *p_value, void *p_push_command_data); extern "C" int user_initialize() { ProError err; ProFamilyName MsgFile; ProStringToWstring(MsgFile, "Test_Msg.txt"); // 添加菜单TestMenu err = ProMenubarMenuAdd("TestMenu", "TestMenu", "Help", PRO_B_TRUE, MsgFile); // 添加命令和Menu Item uiCmdCmdId cmd_id1; err = ProCmdActionAdd("Test", Test, uiProeImmediate, TestAccess, PRO_B_FALSE, PRO_B_FALSE, &cmd_id1); err = ProMenubarmenuPushbuttonAdd("TestMenu", "Test", "Test", "Test_Help", NULL, PRO_B_TRUE, cmd_id1, MsgFile); return 0; } extern "C" void user_terminate() { } int Test(uiCmdCmdId command, uiCmdValue *p_value, void *p_push_command_data) { ProError err; ProMdl mdl_curr; ProSelection *p_sel; ProSelection pnt_sel; int n_sel; // 获取当前模型 err = ProMdlCurrentGet(&mdl_curr); // 选择点 err = ProSelect("point", 1, NULL, NULL, NULL, NULL, &p_sel, &n_sel); if (PRO_TK_NO_ERROR != err || n_sel != 1) return -1; ProSelectionCopy(p_sel[0], &pnt_sel); // udf相关变量定义 ProUdfdata udf_data; ProUdfreference udf_pnt_ref; ProUdfvardim udf_diameter_dim, udf_depth_dim; ProGroup udf; // udf基本属性 ProUdfdataAlloc(&udf_data); ProUdfdataNameSet(udf_data, L"hole", NULL); ProUdfdataDependencySet(udf_data, PROUDFDEPENDENCY_INDEPENDENT); // 设置udf的参考 ProUdfreferenceAlloc(L"place_point", pnt_sel, PRO_B_FALSE, &udf_pnt_ref); ProUdfdataReferenceAdd(udf_data, udf_pnt_ref); // 设置udf的尺寸数据:diameter=50.0, depth=50.0 err = ProUdfvardimAlloc(L"diameter", 50, PROUDFVARTYPE_DIM, &udf_diameter_dim); err = ProUdfdataUdfvardimAdd(udf_data, udf_diameter_dim); err = ProUdfvardimAlloc(L"depth", 50, PROUDFVARTYPE_DIM, &udf_depth_dim); err = ProUdfdataUdfvardimAdd(udf_data, udf_depth_dim); // 创建udf err = ProUdfCreate((ProSolid)mdl_curr, udf_data, NULL, NULL, 0, &udf); if (PRO_TK_NO_ERROR != err) { AfxMessageBox(TEXT("Create udf failed.")); } // 释放资源 ProUdfdataFree(udf_data); ProUdfvardimFree(udf_diameter_dim); ProUdfvardimFree(udf_depth_dim); ProUdfreferenceFree(udf_pnt_ref); ProSelectionFree(&pnt_sel); // 刷新窗口显示 ProWindowRepaint (PRO_VALUE_UNUSED); return 0; } uiCmdAccessState TestAccess(uiCmdAccessMode access_mode) { ProError err; ProMode mode; err = ProModeCurrentGet(&mode); if (err != PRO_TK_NO_ERROR) { return ACCESS_UNAVAILABLE; } if (mode == PRO_MODE_PART || mode == PRO_MODE_ASSEMBLY) { return ACCESS_AVAILABLE; } else { return ACCESS_UNAVAILABLE; } } #pragma endregion //----------------------------------------------------------------------------- //***************************************************************************** //-----------------------------------------------------------------------------
程序说明:
1、首先获取ProE下的当前模型,用ProMdlCurrentGet。
2、调用ProSelect选择点point,获取所选点的ProSelection。
为何在程序中要用到ProSelectionCopy,因为你调用ProSelect之后,获取的ProSelection只是在ProE当前的Selection Buffer中,这个是个临时的内容。如果你后面的程序有用到你获取的ProSelection,而在这之前这个ProSelection被释放掉了,这样就会出错,就相当于,你在C++中new了一块Buffer,获取了其指针,但是用delete释放掉了之后,你后面再用到这个获取的指针肯定就会出错,因为它指向了已经被释放掉的Buffer。
这么解释吧,你在ProE中手动选择一个元素,那么就会创建一ProSelection加入到Selection Buffer中,你会看到你选中的元素在模型窗口中呈高亮显示,如果这时你按Esc键,那么就会清空Selection Buffer,你再看界面中就没有高亮显示的元素了,这就是Selection Buffer被清空了。
3、ProUdfdataNameSet设置要插入的udf的名字。
4、ProUdfreferenceAlloc(L"place_point", pnt_sel, PRO_B_FALSE, &udf_pnt_ref);
ProUdfdataReferenceAdd(udf_data, udf_pnt_ref);
加入参考,注意"place point"为参考的名字,就是你在用ProE创建udf时,ProE会弹出窗口让你为每个参考命名,具体可以看上面创建udf视频里面的操作。
5、// 设置udf的尺寸数据:diameter=50.0, depth=50.0
err = ProUdfvardimAlloc(L"diameter", 50, PROUDFVARTYPE_DIM, &udf_diameter_dim);
err = ProUdfdataUdfvardimAdd(udf_data, udf_diameter_dim);
err = ProUdfvardimAlloc(L"depth", 50, PROUDFVARTYPE_DIM, &udf_depth_dim);
err = ProUdfdataUdfvardimAdd(udf_data, udf_depth_dim);
设置udf的尺寸数据,如果在这里不设置,就会按照创建udf时默认的尺寸驱动。
"diameter"以及"depth"为尺寸的名字,这个在创建udf时,ProE也会弹出窗口,让你为每个你设置的驱动尺寸命名,具体可参看上面创建udf视频里面的操作。
虽然你在创建udf时,为驱动尺寸命名的名字可以和其本身的名字不相符,但有时会出现你用程序插入udf时无法驱动尺寸的情况出现,这一问题我也没有搞清楚,大概是proE的Bug吧,所以,为了安全起见,请按照上面创建udf视频里面的操作一样,先为尺寸命名,再创建udf,并命名驱动尺寸的名字,使其保持一致。
6、ProUdfCreate 插入udf
7、切记勿忘释放资源。