【ProToolkit范例之四】创建udf

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、切记勿忘释放资源。

   

posted on 2013-01-03 15:53  wangyao1052  阅读(1667)  评论(0编辑  收藏  举报

导航