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) 编辑 收藏 举报