您的位置:首页 > 其它

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

2013-03-11 21:27 381 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: