PROE二次开发(protoolkit):Relations 关系式

Proe的一个特征或者PART可以由一组关系式驱动。关系编辑界面如图:

Proe中可以拥有关系式的modelItem类型主要如下:

 

1.ProModelitemToRelset

    函数ProModelitemToRelset获得一个ProModelitem的关系式句柄。但是不是每种ProModelitem都有关系式的,只有上面表格中的类型才有关系式句柄。

2.ProRelsetToModelitem

    如果知道一个关系式句柄ProRelset,那么函数ProRelsetToModelitem可以根据关系式句柄获得关系式所在的ProModelitem。这个函数在ProSolidRelsetVisit

中有用,可以从ProSolidRelsetVisitAction中获取ProRelset所在的ProModelitem。

3.ProSolidRelsetVisit

遍历PRO_PART 或者PRO_ASSEMBLY中每个ProModelitem的关系式。和其他访问函数一样,需要传入一个遍历动作函数:

ProError     (*ProSolidRelsetVisitAction)     (
    ProRelset *p_relset     
    /* (In)
    The relation set
    */
    ProAppData caller_data     
    /* (In)
    The user-supplied data
    */
)

遍历动作函数要是返回非PRO_TK_NO_ERROR的其它状态值,那么遍历自动停止。和其它访问函数不同的是,不需要传入过滤函数。

4.ProRelsetRegenerate

该函数重新执行关系运算,同时还检查关系式时候正确,如果返回PRO_TK_NO_ERROR,则表示正确,否则关系式错误。

5.ProRelsetCreate

为ProModelitem创建一个关系式,如果已经存在关系式则函数返回PRO_TK_E_FOUND

#include <ProRelSet.h>
ProError     ProRelsetCreate     (
    ProModelitem *p_item     
    /* (In)
    The model item for which to create the relation set
    */
    ProRelset *p_relset     
    /* (Out)
    The relation set
    */
)

 6.ProRelsetDelete

删除一个ProModelitem的关系式

7.获取关系表达式

一个关系式由若干行的关系表达式组成,函数ProRelsetRelationsGet可获取若干行关系表达式:

ProError     ProRelsetRelationsGet     (
    ProRelset *p_relset     
    /* (In)
    The relation set.
    */
    ProWstring **p_line_array     
    /* (Out)
    The address to a user-allocated array of ProWstring. Use the functions ProArrayAlloc() and ProWstringproarrayFree() to allocate and free this array. Do not reuse the array.
    */

 注意一定要先ProArrayAlloc一个wstring,否则会出错,例子如下:

ProWstring *w_rel=0;
    //should alloc the memory for reaotions
    ProArrayAlloc(0, sizeof(ProWstring), 1, (ProArray*)&w_rel);
    if(PRO_TK_NO_ERROR!=ProRelsetRelationsGet(&p_selret,&w_rel))
    {
        //fail to get relations
        AfxMessageBox("fail to get relations");
        return rv;
    }

 

获取modelitem的关系表达式的函数如下:

std::vector<std::string> RelGetRealtionFromMdl(ProModelitem& it)
{
    //visualsan@yahoo.cn
    //J-SUN-SO 2013.3
    std::vector<std::string> rv;

    ProRelset p_selret;
    //fail to create ProRelset
    if(PRO_TK_NO_ERROR!=ProModelitemToRelset(&it,&p_selret))
    {
        AfxMessageBox("fail to create ProRelset");
        return rv;
    }
    ProWstring *w_rel=0;
    //should alloc the memory for reaotions
    ProArrayAlloc(0, sizeof(ProWstring), 1, (ProArray*)&w_rel);
    if(PRO_TK_NO_ERROR!=ProRelsetRelationsGet(&p_selret,&w_rel))
    {
        //fail to get relations
        AfxMessageBox("fail to get relations");
        return rv;
    }
    
    int n=0,i=0;
    char buffer[200];
    ProArraySizeGet(w_rel,&n);
    for (;i<n;++i)
    {
        ProWstringToString(buffer,w_rel[i]);
        rv.push_back(buffer);
    } 

    ProArrayFree((ProArray*)w_rel);
    return rv;
}

//测试函数
void test() { ProMdl mdl; if(PRO_TK_NO_ERROR!=ProMdlCurrentGet(&mdl)) { AfxMessageBox("没有模型!"); return; } ProModelitem it; if(PRO_TK_NO_ERROR!=ProMdlToModelitem(mdl,&it)) { AfxMessageBox("无法转换为Modelitem"); return; } std::vector<std::string> rsl= RelGetRealtionFromMdl(it); CString str; for (int i=0;i<rsl.size();i++) { str=str+rsl[i].c_str()+"\n\r"; } AfxMessageBox(str); }

 

 

8.设置关系表达式

函数ProRelsetRelationsSet用于设置关系表达式,通过传递一组描述关系表达式的文本定义新的关系。

设置好后务必ProRelsetRegenerate检查一下有没有问题。

ProError     ProRelsetRelationsSet     (
    ProRelset *p_relset     
    /* (In)
    The relation set
    */
    ProWstring *line_array     
    /* (In)
    The relations assigned to this relation set
    */
    int n_lines     
    /* (In)
    The number of lines in the relations
    */
)

 9.ProRelationEval

计算表达式右边的值

......待续(累了,要睡觉了...2013.3.11-5:00~9:30)

-----------------------------------------------------------------------------------------------

设置表达式的值: 

   bool RelSetRealtionFromMdl(ProModelitem& it,std::vector<std::string>& rel)

ProModelitem& it:拥有表达式的modelitem

std::vector<std::string>& rel:表达式描述数组
   std::vector<std::string> vl;
//visualsan@yahoo.cn //J-SUN-SO 2013.3
//插入你需要的表达式
    vl.push_back("x=10");
    vl.push_back("y=20");
    ProMdl mdl;
    if(PRO_TK_NO_ERROR!=ProMdlCurrentGet(&mdl))
    {
        return;
    }
    ProModelitem it;
    if(PRO_TK_NO_ERROR!=ProMdlToModelitem(mdl,&it))
    {
        return;
    }
    RelSetRealtionFromMdl(it,vl);
    return;

bool
RelSetRealtionFromMdl(ProModelitem& it,std::vector<std::string>& rel) { //visualsan@yahoo.cn //J-SUN-SO 2013.3 ProRelset p_selret; //fail to create ProRelset if(PRO_TK_NO_ERROR!=ProModelitemToRelset(&it,&p_selret)) { if(PRO_TK_NO_ERROR!=ProRelsetCreate(&it,&p_selret)) { AfxMessageBox("fail to create relset!"); return false; } } ProWstring* w_rel=0; wchar_t **w_ptr=new wchar_t*[rel.size()]; ProLine *lv=new ProLine[rel.size()]; ProArrayAlloc(0, sizeof(ProWstring), 1, (ProArray*)&w_rel); int i=0; for (i=0;i<rel.size();++i) { ProStringToWstring(lv[i],(char*)rel[i].c_str()); w_ptr[i]=lv[i]; ProArrayObjectAdd((ProArray*)&w_rel, PRO_VALUE_UNUSED, 1, &w_ptr[i]); } if(PRO_TK_NO_ERROR!=ProRelsetRelationsSet(&p_selret, w_rel,rel.size())) { delete []lv; delete []w_ptr; ProArrayFree((ProArray*)w_rel); AfxMessageBox("fail to ProRelsetRelationsSet"); return false; } delete []lv; delete []w_ptr; ProArrayFree((ProArray*)w_rel); return true; }

 

添加表达式:在原有关系表达式基础上添加新的表达式

void RelAddRealtionFromMdl(ProModelitem& it,std::vector<std::string>&to_add  )

    std::vector<std::string> vl;
    vl.push_back("x=10");
    vl.push_back("y=20*sin(x)");
    ProMdl mdl;
    if(PRO_TK_NO_ERROR!=ProMdlCurrentGet(&mdl))
        return;
    ProModelitem it;
    if(PRO_TK_NO_ERROR!=ProMdlToModelitem(mdl,&it))
        return;
   RelAddRealtionFromMdl(it,vl);

void
RelAddRealtionFromMdl(ProModelitem& it,std::vector<std::string>&to_add ) { //visualsan@yahoo.cn //J-SUN-SO 2013.3.13 ProRelset p_selret; //fail to create ProRelset ProWstring* w_rel=0; wchar_t **w_ptr=new wchar_t*[to_add.size()]; ProLine *lv=new ProLine[to_add.size()]; ProArrayAlloc(0, sizeof(ProWstring), 1, (ProArray*)&w_rel); int n_init_size=0; if(PRO_TK_NO_ERROR!=ProModelitemToRelset(&it,&p_selret)) { if(PRO_TK_NO_ERROR!=ProRelsetCreate(&it,&p_selret)) { delete []lv; delete []w_ptr; ProArrayFree((ProArray*)w_rel); AfxMessageBox("fail to create relset!"); return ; } }else { ProRelsetRelationsGet(&p_selret, &w_rel);; ProArraySizeGet((ProArray)w_rel,&n_init_size); } int i=0; for (i=0;i<to_add.size();++i) { ProStringToWstring(lv[i],(char*)to_add[i].c_str()); w_ptr[i]=lv[i]; ProArrayObjectAdd((ProArray*)&w_rel, PRO_VALUE_UNUSED, 1, &w_ptr[i]); } if(PRO_TK_NO_ERROR!=ProRelsetRelationsSet(&p_selret, w_rel,to_add.size()+n_init_size)) { delete []lv; delete []w_ptr; ProArrayFree((ProArray*)w_rel); AfxMessageBox("fail to ProRelsetRelationsSet"); return ; } delete []lv; delete []w_ptr; ProArrayFree((ProArray*)w_rel); }

 (----------------------------------------------------sleep    2013.3.13 22:56  浦江镇-------------------------------------------------------------)待续

 

 为关系表达式添加自定义函数

函数ProRelationFunctionRegister为关系表达式添加自定义函数。注册自定义函数步骤如下:

1.定义一组输入参数,每个参数包含数据类型(int,double...)和定义是否可以忽略参的属性参数。

2.定义是否需要在调用函数时检查参数类型。如果定义不检查参数输入,那么PROE将不会检查参数类型是否和规定的类型一致,用户需要自己处理错误情况。

3.一个检查输入参数的函数。

4.读函数,一个用来计算函数值并赋值给等号的左边变量,比如 d=f(1,2),那么读函数需要计算f(x,y)的值并赋值给d。

5.一个写函数,定义当函数表达式在左边时的表达式行为,比如f(1,2)=12。

6.上述所有函数都可以为NULL。

7.自定义函数只有在PROE中注册后才生效,如果导入一个模型包含有自定义函数,那么如果自定义函数没有注册那么评估表达式值时会发生错误。

ProRelationFunctionRegister定义如下:

#include <ProRelSet.h>
ProError     ProRelationFunctionRegister     (
    char *extfunc_name     
    /* (In)
    name of new relation function used in the relations.
函数的名称
*/ ProRelfuncArg *arg_descr_arr /* (In) argument description ProArray. Can be NULL if: no arguments should be supplied to the new function. you don't want Pro/ENGINEER to check the validity of arguments (in conjunction with 'dis_type_ctrl' = PRO_B_TRUE).
参数列表,可以没有参数为NULL
*/ ProRelationReadFunction read_func /* (In) function that implements read-access of external function; can be NULL; */ ProRelationWriteFunction write_func /* (In) function that implements write-access of external function; can be NULL; */ ProRelationArgscheckFunction check_func /* (In) function to check arguments of external function; can be NULL; */ ProBoolean dis_type_ctrl /* (In) PRO_B_TRUE to disable type checking for arguments. PRO_B_FALSE indicates that the arguments will be checked. */ ProAppData app_data /* (In) application data passed to the relation callbacks. Can be NULL. */ ) Returns PRO_TK_NO_ERROR The function succeeded. PRO_TK_BAD_INPUTS One or more inputs was invalid. PRO_TK_E_FOUND Function with the given name was already found.

关系表达式中的函数参数个数和*arg_descr_arr的数组长度一致,表达式参数个数不够或者过多都不合法

其中ProRelfuncArg是输入参数结构体,其定义如下:

typedef struct rel_func_arg { ProParamvalueType type; ProRelfuncAttr attributes; } ProRelfuncArg;

有两个属性,一个为类型:

typedef enum  param_value_types  {
   PRO_PARAM_DOUBLE  = 50,
   PRO_PARAM_STRING  = 51,
   PRO_PARAM_INTEGER = 52,
   PRO_PARAM_BOOLEAN = 53,
   PRO_PARAM_NOTE_ID = 54,
   PRO_PARAM_VOID    = 57
}  ProParamvalueType;

一个为检测在执行函数事参数是否可以忽略:

typedef enum rel_func_arg_attr
{
   PRO_RELF_ATTR_NONE     = 0,
   PRO_RELF_ATTR_OPTIONAL = 1<<0   /* Argument is optional */
}  ProRelfuncAttr;


当函数在等号右边时,会调用ProRelationReadFunction来计算参数值

ProRelationReadFunction定义如下:

ProError     (*ProRelationReadFunction)     (
    ProRelset *pro_relset     
    /* (In)
    The relation set.    表达式句柄
    */
    ProMdl pro_model     
    /* (In)
    The model that owns the relation set.   拥有表达式的modelitem
    */
    char *extfunc_name     
    /* (In)
    The name of the external function.  函数名称
    */
    ProParamvalue *pro_args     
    /* (In)
    ProArray of argument values.    输入参数数组
    */
    ProAppData app_data     
    /* (In)
    The application data passed to registration function.   注册函数传递的数据
    */
    ProParamvalue *pro_result     
    /* (Out)
    The result of the relation function calculation.   等号左边值,需要写入
这个参数的数据类型和数值必须都写入,否则在关系表达式中调用时会出错
*/ )

当函数出现在表达式的左边时需要调用ProRelationWriteFunction进行计算。

ProRelationWriteFunction定义如下:

#include <ProRelSet.h>
ProError     (*ProRelationWriteFunction)     (
    ProRelset *pro_relset     
    /* (In)
    The relation set.  表达式句柄
    */
    ProMdl pro_model     
    /* (In)
    The model that owns the relation set.   拥有表达式的modelitem
    */
    char *extfunc_name     
    /* (In)
    The name of the external function.   函数名称
    */
    ProParamvalue *pro_args      
    /* (In)
    ProArray of argument values.    输入参数值
    */
    ProParamvalue *pro_input     
    /* (In)
    The value of the right hand side of the relation expression.   表达式右边的值
    */
    ProAppData app_data       
    /* (In)
    The application data passed to registration function.  注册函数传入参数
    */ 
)
Returns
    
PRO_TK_NO_ERROR         The calculation succeeded.
Any other error - The calculation failed; the relation has an error.

 

函数ProRelationArgscheckFunction用来检测输入值。

#include <ProRelSet.h>
ProError     (*ProRelationArgscheckFunction)     (
    ProRelset *pro_relset     
    /* (In)
    The relation set.
    */
    ProMdl pro_model     
    /* (In)
    The model that owns the relation set.
    */
    char *extfunc_name     
    /* (In)
    The name of the external function.
    */
    ProParamvalue *pro_args     
    /* (In)
    ProArray of argument values.
    */
    ProAppData app_data     
    /* (In)
    The application data passed to registration function.
    */
)
Returns
    
PRO_TK_NO_ERROR         The arguments are valid.
        Any other error - The arguments are invalid;the relation has an error.

 

自定义函数例子

1. 自定义一个函数计算两个数的平方差 z=sqrt(x*x+y*y)

函数名称  sqrt_xy。首先为了层次清楚,我们定义一个类(为了不和其他函数混淆,建议类名称和函数名称一致),然后定义“读”函数Func_read和注册函数UserCustomRelFuncDefine

需要注册时调用注册函数sqrt_xy::UserCustomRelFuncDefine即可。

//自定义函数示例: z=sqrt(x*x+y*y)
//函数名称  sqrt_xy
//
//读函数
//visualsan@yahoo.cn
//J-SUN-SO 2013.3
 struct sqrt_xy{ 
//1.定义“读”函数,即z=sqrt_xy(x,y)时计算结果并赋值给z的表达式计算,其中ProParamvalue* result代表要写入的z
static ProError Func_read (ProRelset* relset, ProMdl mdl, char* ext_func_name, ProParamvalue* args, ProAppData data, ProParamvalue* result); //写函数:无,因为sqrt_xy(x,y)=z没有意义 static int UserCustomRelFuncDefine(); };
ProError sqrt_xy::Func_read(ProRelset* relset, ProMdl mdl,
                            char* ext_func_name, ProParamvalue* args,
                            ProAppData data, ProParamvalue* result)
{
    double x = args [0].value.d_val;
    double y = args [1].value.d_val;

    result->type = PRO_PARAM_DOUBLE;
    result->value.d_val = sqrt(x * x + y*y);

    return PRO_TK_NO_ERROR;
}
int sqrt_xy::UserCustomRelFuncDefine()
{

    ProRelfuncArg* args_array;

    /*---------------------------------------------------------------------*\
    两个变量,类型均为double,输入不能忽略
    \*---------------------------------------------------------------------*/
    ProArrayAlloc (2, sizeof (ProRelfuncArg), 1, (ProArray*)&args_array);
    args_array [0].type = PRO_PARAM_DOUBLE;
    args_array [0].attributes = PRO_RELF_ATTR_NONE;
    args_array [1].type = PRO_PARAM_DOUBLE;
    args_array [1].attributes = PRO_RELF_ATTR_NONE;

    /*---------------------------------------------------------------------*\
    注册函数,只注册读函数,写函数忽略
    \*---------------------------------------------------------------------*/
    ProRelationFunctionRegister ("sqrt_xy", args_array,
        Func_read, NULL, NULL,
        PRO_B_FALSE, NULL);

    return (PRO_TK_NO_ERROR);
}

运行效果:

2.自定义函数  z=J_SUN_SO(x,y),函数内部有一个数值m,当 J_SUN_SO(x,y)=z调用时,给m赋值;

当z=J_SUN_SO(x,y)时,计算z=f*x+y;实现代码如下:

/自定义函数示例: z=f*x+y
//函数名称  J_SUN_SO(:ps J_SUN_SO其实是楼主的名字)
//
//读函数
//visualsan@yahoo.cn
//J-SUN-SO 2013.3
struct J_SUN_SO{

    static double m_factor;//系数
    static ProError Func_read (ProRelset* relset, ProMdl mdl,
        char* ext_func_name,  ProParamvalue* args,
        ProAppData data, ProParamvalue* result);
    //写函数,用于给m_factor赋值
    static ProError Func_write(ProRelset      *pro_relset, 
        ProMdl          pro_model, 
        char           *extfunc_name, 
        ProParamvalue  *pro_args, 
        ProParamvalue  *pro_input,
        ProAppData     app_data);
    static int UserCustomRelFuncDefine();
};
ProError J_SUN_SO::Func_read(ProRelset* relset, ProMdl mdl,
                            char* ext_func_name, ProParamvalue* args,
                            ProAppData data, ProParamvalue* result)
{
    double x = args [0].value.d_val;
    double y = args [1].value.d_val;

    result->type = PRO_PARAM_DOUBLE;
    result->value.d_val = m_factor*x+y;

    return PRO_TK_NO_ERROR;
}
double J_SUN_SO::m_factor=0;
ProError J_SUN_SO::Func_write(ProRelset      *pro_relset, 
                    ProMdl          pro_model, 
                    char           *extfunc_name, 
                    ProParamvalue  *pro_args, 
                    ProParamvalue  *pro_input,
                    ProAppData     app_data)
{
    double inp=0;
    if (pro_input->type==PRO_PARAM_INTEGER)
    {
        inp = pro_input->value.i_val;
    }else if (pro_input->type==PRO_PARAM_DOUBLE)
    {
        inp=pro_input->value.d_val;
    }else
        return PRO_TK_GENERAL_ERROR;
    m_factor = inp;
    return PRO_TK_NO_ERROR;
}
int J_SUN_SO::UserCustomRelFuncDefine()
{

    ProRelfuncArg* args_array;

    /*---------------------------------------------------------------------*\
    两个变量,类型均为double,输入不能忽略
    \*---------------------------------------------------------------------*/
    ProArrayAlloc (2, sizeof (ProRelfuncArg), 1, (ProArray*)&args_array);
    args_array [0].type = PRO_PARAM_DOUBLE;
    args_array [0].attributes = PRO_RELF_ATTR_NONE;
    args_array [1].type = PRO_PARAM_DOUBLE;
    args_array [1].attributes = PRO_RELF_ATTR_NONE;

    /*---------------------------------------------------------------------*\
    注册函数,注册读函数和写函数
    \*---------------------------------------------------------------------*/
    ProRelationFunctionRegister ("J_SUN_SO", args_array,
        Func_read, Func_write, NULL,
        PRO_B_FALSE, NULL);

    return (PRO_TK_NO_ERROR);
}

效果图:

3.当然每个关系表达式都属于某个ProMdl,你也可以利用ProMdl作为计算参数来源。

举个例子:mass_density(density_input)   根据输入密度计算一个模型的质量

//visualsan@yahoo.cn 
//J-SUN-SO 2013.3
struct
mass_density{ static ProError Func_read (ProRelset* relset, ProMdl mdl, char* ext_func_name, ProParamvalue* args, ProAppData data, ProParamvalue* result); static int UserCustomRelFuncDefine(); }; ProError mass_density::Func_read(ProRelset* relset, ProMdl mdl, char* ext_func_name, ProParamvalue* args, ProAppData data, ProParamvalue* result) { double x = args [0].value.d_val; ProMdlType tp; ProMdlTypeGet(mdl,&tp); if (tp!=PRO_MDL_ASSEMBLY&&tp!=PRO_MDL_PART) { return PRO_TK_GENERAL_ERROR; } ProMassProperty p; ProSolidMassPropertyGet((ProSolid)mdl,NULL,&p); result->type = PRO_PARAM_DOUBLE; result->value.d_val = p.volume*x;//密度*体积 return PRO_TK_NO_ERROR; } int mass_density::UserCustomRelFuncDefine() {
ProRelfuncArg
* args_array; /*---------------------------------------------------------------------*\ 1个变量,类型均为double,输入不能忽略 \*---------------------------------------------------------------------*/ ProArrayAlloc (1, sizeof (ProRelfuncArg), 1, (ProArray*)&args_array); args_array [0].type = PRO_PARAM_DOUBLE; args_array [0].attributes = PRO_RELF_ATTR_NONE; /*---------------------------------------------------------------------*\ 注册函数,只注册读函数,写函数忽略 \*---------------------------------------------------------------------*/ ProRelationFunctionRegister ("mass_density", args_array, Func_read, NULL, NULL, PRO_B_FALSE, NULL); return (PRO_TK_NO_ERROR); }

 (----------------------------------------------------sleep    2013.3.15 23:52  浦江镇-------------------------------------------------------------)relation END

posted on 2013-03-11 21:27  DoJustForFun  阅读(1649)  评论(0编辑  收藏  举报

导航