/* Copyright (c) 2024 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved. */ #include <ProToolkit.h> #include <ProDtmPln.h> #include <ProDtmCsys.h> #include <ProElemId.h> #include <ProFeatType.h> #include <ProMenu.h> #include <ProMessage.h> #include <ProMdl.h> #include <ProUtil.h> #include <TestError.h> #include <UtilCollect.h> #include <UtilMath.h> #include <UtilMenu.h> #include <UtilMessage.h> #include <UtilTree.h> #include "UtilString.h" #define msgfil "feat" #define SIZEOFARR(a) (sizeof(a)/(sizeof(a[0]))) #define MAX_CONSTR_TYPES 7 #define MAX_REF_TYPE 5 typedef enum dtm_constr_type { DCTR_THROUGH = 0, DCTR_NORMAL, DCTR_PARALLEL, DCTR_OFFSET, DCTR_ANGLE, DCTR_TANGENT, DCTR_BLEND_SECTION, DCTR_DEFAULT } DtmConstrType; typedef enum dtm_constr_ref { USER_LINE = 0, USER_POINT, USER_PLANE, USER_CYL, USER_CSYS } DtmConsrRef; typedef struct test_ref_type { char *button_name; char *select_option; int freedom[MAX_CONSTR_TYPES]; int state_en; int state_hi; } RefType; typedef struct test_constr_type { char *button_name; int state_en; } ContrType; typedef struct dtmpln_constr { int cur_constr; int constr_enabled; int ref_highlighted; int ref_enabled; ProBoolean ref_pressed; Pro3dPnt points[3]; int n_points; ProBoolean through; int n_constr; ProDtmplnConstrType type[3]; ProSelection ref[3]; double offset[3]; int index[3]; int freedom; ProMdl model; } DtmPlnConstr; static ContrType constr_type[MAX_CONSTR_TYPES] = { {(char *)"Through"}, {(char *)"Normal"}, {(char *)"Parallel"}, {(char *)"Offset"}, {(char *)"Angle"}, {(char *)"Tangent"}, {(char *)"BlendSection"} }; static RefType ref_type[MAX_REF_TYPE] = { {(char *)"AxisEdgeCurv", (char *)"axis,edge,curve", { 2, 1, -1, -1, -1, -1, -1}}, {(char *)"Point/Vertex", (char *)"point,edge_end,curve_end", { 1, -1, -1, -1, -1, -1, -1}}, {(char *)"Plane", (char *)"surface,datum", { 3, 1, 1, 3, 1, -1, -1}}, {(char *)"Cylinder", (char *)"surface", { 2, -1, -1, -1, -1, 1, -1}}, {(char *)"Coord Sys", (char *)"csys", {-1, -1, -1, 3, -1, -1, -1}} }; static DtmPlnConstr constraint; /*=============================================================*\ FUNCTION: ProUtilDefMenuAction PURPOSE: Menu button function \*=============================================================*/ static int ProUtilDefMenuAction( ProAppData data, int action) { ProError err; err = ProMenuDeleteWithStatus(action); TEST_CALL_REPORT("ProFeatureTypeGet()", "ProUtilDefMenuaAction()", err, err != PRO_TK_NO_ERROR); return (0); } /*=============================================================*\ FUNCTION: ProTestDtmplnDefCreate PURPOSE: Create default datum plane \*=============================================================*/ ProError ProTestDtmplnDefCreate( ProMdl model, int n_csys) { ProError err; int action, n_sel, i; ProElement tree, constr_elem; ProSelection *p_sel_arr, csys_sel = NULL, featsel; ProModelitem modelitem; ProGeomitem *p_geomitems; ProFeature feat; ProErrorlist errs; ProFeatureCreateOptions *opts = 0; char *c= (char *)"x"; double offset[3]; static ElemTreeData def_csys[]= { {0, PRO_E_FEATURE_TREE, {(ProValueDataType)-1}}, {1, PRO_E_FEATURE_TYPE, {PRO_VALUE_TYPE_INT, {PRO_FEAT_CSYS}}}, {1, PRO_E_CSYS_METHOD, {PRO_VALUE_TYPE_INT, {PRO_CSYS_DEFAULT}}} }; static ElemTreeData dtmpln[] = { {0, PRO_E_FEATURE_TREE, {(ProValueDataType)-1}}, {1, PRO_E_FEATURE_TYPE, {PRO_VALUE_TYPE_INT, {PRO_FEAT_DATUM}}}, {1, PRO_E_DTMPLN_CONSTRAINTS, {(ProValueDataType)-1}}, {2, PRO_E_DTMPLN_CONSTRAINT, {(ProValueDataType)-1}} }; static ElemTreeData def_dtmpln[] = { {1, PRO_E_DTMPLN_CONSTR_TYPE, {PRO_VALUE_TYPE_INT, {PRO_DTMPLN_DEF_X}}} }; static ElemTreeData offs_dtmpln[] = { {1, PRO_E_DTMPLN_CONSTR_TYPE, {PRO_VALUE_TYPE_INT, {PRO_DTMPLN_OFFS}}}, {1, PRO_E_DTMPLN_CONSTR_REF, {PRO_VALUE_TYPE_SELECTION}}, {1, PRO_E_DTMPLN_OFF_CSYS, {PRO_VALUE_TYPE_INT}}, {1, PRO_E_DTMPLN_OFF_CSYS_OFFSET, {PRO_VALUE_TYPE_DOUBLE}} }; static ProElempathItem constr_path[] = { {PRO_ELEM_PATH_ITEM_TYPE_ID, PRO_E_DTMPLN_CONSTRAINTS}, {PRO_ELEM_PATH_ITEM_TYPE_INDEX, 0} }; static int offs_type[3] = {PRO_DTMPLN_OFF_CSYS_X, PRO_DTMPLN_OFF_CSYS_Y, PRO_DTMPLN_OFF_CSYS_Z }; static int def_constr_type[3] = {PRO_DTMPLN_DEF_X, PRO_DTMPLN_DEF_Y, PRO_DTMPLN_DEF_Z }; err = ProMenuFileRegister((char *)"tkmenudtm opt",(char *)"tkmdtmopt.mnu", NULL); err = ProMenubuttonActionSet((char *)"tkmenudtm opt", (char *)"Default", (ProMenubuttonAction)ProUtilDefMenuAction, NULL, DCTR_DEFAULT); err = ProMenubuttonActionSet((char *)"tkmenudtm opt", (char *)"Offset", (ProMenubuttonAction)ProUtilDefMenuAction, NULL, DCTR_OFFSET); err = ProMenubuttonActionSet((char *)"tkmenudtm opt", (char *)"tkmenudtm opt", (ProMenubuttonAction)ProMenuDelete, NULL, 0); err = ProMenuCreate(PROMENUTYPE_MAIN, (char *)"tkmenudtm opt", NULL); err = ProMenuProcess((char *)"", &action); if (err != PRO_TK_NO_ERROR) return (err); if (action != DCTR_DEFAULT) { if (n_csys > 0) { /*------------------------------------------------------------------*\ Csys alredy exists, select one \*------------------------------------------------------------------*/ ProUtilMsgPrint(msgfil, (char *)"TEST Select a coordinate system."); err = ProSelect((char *)"csys", 1, NULL, NULL, NULL, NULL, &p_sel_arr, &n_sel); TEST_CALL_REPORT("ProSelect()", "ProTestDtmplnDefCreate()", err, err != PRO_TK_NO_ERROR); if (err != PRO_TK_NO_ERROR) return (err); err = ProSelectionCopy(p_sel_arr[0], &csys_sel); TEST_CALL_REPORT("ProSelectionCopy()", "ProTestDtmplnDefCreate()", err, err != PRO_TK_NO_ERROR); } for (i=0, c[0]='x'; i<3; i++, c[0]++) { /*------------------------------------------------------------------*\ Read offset values \*------------------------------------------------------------------*/ offset[i] = 0; ProUtilMsgPrint(msgfil, (char *)"TEST Enter offset value in the %0s-direction [%1f]:", c, offset+i); err = ProMessageDoubleRead(NULL, offset+i); TEST_CALL_REPORT("ProMessageDoubleRead()", "ProTestDtmplnDefCreate()", err, err != PRO_TK_NO_ERROR); if (err == PRO_TK_MSG_USER_QUIT) break; } if (i<3) return (PRO_TK_NO_ERROR); if (n_csys == 0) { /*------------------------------------------------------------------*\ Create default datum csys first if no one already created \*------------------------------------------------------------------*/ err = ProUtilElemtreeCreate(def_csys, SIZEOFARR(def_csys), NULL, &tree); err = ProMdlToModelitem(model, &modelitem); TEST_CALL_REPORT("ProMdlToModelitem()", "ProTestDtmplnDefCreate()", err, err != PRO_TK_NO_ERROR); err = ProSelectionAlloc(NULL, &modelitem, &featsel); TEST_CALL_REPORT("ProSelectionAlloc()", "ProTestDtmplnDefCreate()", err, err != PRO_TK_NO_ERROR); err = ProArrayAlloc(1,sizeof(ProFeatureCreateOptions), 1, (ProArray*)&opts); opts[0]= PRO_FEAT_CR_NO_OPTS; err = ProFeatureWithoptionsCreate(featsel, tree, opts, PRO_REGEN_NO_FLAGS, &feat, &errs); TEST_CALL_REPORT("ProFeatureWithoptionsCreate()", "ProTestDtmplnDefCreate()", err, err != PRO_TK_NO_ERROR); err = ProArrayFree((ProArray*)&opts); err = ProSelectionFree(&featsel); TEST_CALL_REPORT("ProSelectionFree()", "ProTestDtmplnDefCreate()", err, err != PRO_TK_NO_ERROR); err = ProUtilCollectFeatureGeomitems(&feat, PRO_CSYS, &p_geomitems); if (err != PRO_TK_NO_ERROR) return(err); err = ProSelectionAlloc(NULL, p_geomitems, &csys_sel); TEST_CALL_REPORT("ProSelectionAlloc()", "ProTestDtmplnDefCreate()", err, err != PRO_TK_NO_ERROR); err = ProArrayFree((ProArray*)&p_geomitems); TEST_CALL_REPORT("ProArrayFree()", "ProTestDtmplnDefCreate()", err, err != PRO_TK_NO_ERROR); err = ProElementFree(&tree); TEST_CALL_REPORT("ProElementFree()", "ProTestDtmplnDefCreate()", err, err != PRO_TK_NO_ERROR); } } /*------------------------------------------------------------------*\ Alloc selection to the model \*------------------------------------------------------------------*/ err = ProMdlToModelitem(model, &modelitem); TEST_CALL_REPORT("ProMdlToModelitem()", "ProTestDtmplnDefCreate()", err, err != PRO_TK_NO_ERROR); err = ProSelectionAlloc(NULL, &modelitem, &featsel); TEST_CALL_REPORT("ProSelectionAlloc()", "ProTestDtmplnDefCreate()", err, err != PRO_TK_NO_ERROR); for (i=0; i<3; i++) { /*------------------------------------------------------------------*\ Create main part of feat tree \*------------------------------------------------------------------*/ err = ProUtilElemtreeCreate(dtmpln, SIZEOFARR(dtmpln), NULL, &tree); err = ProUtilElemtreeElementGet(tree, constr_path, SIZEOFARR(constr_path), &constr_elem); /*------------------------------------------------------------------*\ Create specific part of feat tree \*------------------------------------------------------------------*/ if (action == DCTR_DEFAULT) { def_dtmpln[0].data.v.i = def_constr_type[i]; err = ProUtilElemtreeCreate(def_dtmpln, SIZEOFARR(def_dtmpln), constr_elem, &constr_elem); } else { offs_dtmpln[1].data.v.r = csys_sel; offs_dtmpln[2].data.v.i = offs_type[i]; offs_dtmpln[3].data.v.d = offset[i]; err = ProUtilElemtreeCreate(offs_dtmpln, SIZEOFARR(offs_dtmpln), constr_elem, &constr_elem); } /*------------------------------------------------------------------*\ Create datum plane \*------------------------------------------------------------------*/ err = ProArrayAlloc(1,sizeof(ProFeatureCreateOptions), 1, (ProArray*)&opts); opts[0]= PRO_FEAT_CR_NO_OPTS; err = ProFeatureWithoptionsCreate(featsel, tree, opts, PRO_REGEN_NO_FLAGS, &feat, &errs); TEST_CALL_REPORT("ProFeatureWithoptionsCreate()", "ProTestDtmplnDefCreate()", err, err != PRO_TK_NO_ERROR); err = ProArrayFree((ProArray*)&opts); err = ProElementFree(&tree); TEST_CALL_REPORT("ProElementFree()", "ProTestDtmplnDefCreate()", err, err != PRO_TK_NO_ERROR); } err = ProSelectionFree(&featsel); TEST_CALL_REPORT("ProSelectionFree()", "ProTestDtmplnDefCreate()", err, err != PRO_TK_NO_ERROR); if (csys_sel != NULL) { err = ProSelectionFree(&csys_sel); TEST_CALL_REPORT("ProSelectionFree()", "ProTestDtmplnDefCreate()", err, err != PRO_TK_NO_ERROR); } ProUtilMsgPrint(msgfil, (char *)"TEST %0s has been created successfully.", "DATUM PLANE"); return(PRO_TK_NO_ERROR); } /*=============================================================*\ FUNCTION: ProUtilCheckFeatures PURPOSE: Visit func. Check if another than csys feature is created \*=============================================================*/ ProError ProUtilNonCsysFeatCheck( ProFeature *feature, ProError status, ProAppData num_csys) { ProError err; ProFeattype type; err = ProFeatureTypeGet(feature, &type); TEST_CALL_REPORT("ProFeatureTypeGet()", "ProUtilNonCsysFeatCheck()", err, err != PRO_TK_NO_ERROR); if (type == PRO_FEAT_CSYS) { ((int*)num_csys)[0]++; return (PRO_TK_NO_ERROR); } else { return (PRO_TK_E_FOUND); } } /*=============================================================*\ FUNCTION: ProTestDtmplnMenuSet PURPOSE: Allow/Disable menu buttons \*=============================================================*/ ProError ProTestDtmplnMenuSet( DtmPlnConstr *constr) { int i; for (i=0; i<MAX_CONSTR_TYPES; i++) { if (constr_type[i].state_en != (constr->constr_enabled & (1 << i))) { constr_type[i].state_en = constr->constr_enabled & (1 << i); ProUtilMenubuttonActivate((char *)"tkdtm plane", constr_type[i].button_name, constr_type[i].state_en); } } for (i=0; i<SIZEOFARR(ref_type); i++) { if ((ref_type[i].state_en != (constr->ref_enabled & (1 << i))) || (ref_type[i].state_hi != (constr->ref_highlighted & (1 << i)))) { ref_type[i].state_en = constr->ref_enabled & (1 << i); ref_type[i].state_hi = constr->ref_highlighted & (1 << i); ProUtilMenubuttonActivate((char *)"tkdtmplnc", ref_type[i].button_name, 1); ProUtilMenubuttonHighlight((char *)"tkdtmplnc", ref_type[i].button_name, ref_type[i].state_hi); ProUtilMenubuttonActivate((char *)"tkdtmplnc", ref_type[i].button_name, ref_type[i].state_en); } } return (PRO_TK_NO_ERROR); } /*=============================================================*\ FUNCTION: ProUtilMenucompDelete PURPOSE: ProMenuDelete function for the compound menu \*=============================================================*/ static ProError ProUtilMenucompDelete() { ProError err; err = ProMenuDelete(); err = ProMenuDelete(); err = ProMenuDelete(); TEST_CALL_REPORT("ProMenuDelete()", "ProTestDtmpln()", err, err != PRO_TK_NO_ERROR); return (PRO_TK_NO_ERROR); } /*=============================================================*\ FUNCTION: ProTestDtmplnDone PURPOSE: Done creation \*=============================================================*/ int ProTestDtmplnDone( DtmPlnConstr *constr) { ProElement tree, constr_elem, constrs_elem; ProFeature feat; ProError err; ProErrorlist errs; ProModelitem modelitem; ProSelection featsel; ProFeatureCreateOptions *opts = 0; int i; static ElemTreeData dtmpln[] = { {0, PRO_E_FEATURE_TREE, {(ProValueDataType)-1}}, {1, PRO_E_FEATURE_TYPE, {PRO_VALUE_TYPE_INT, {PRO_FEAT_DATUM}}}, {1, PRO_E_DTMPLN_CONSTRAINTS, {(ProValueDataType)-1}} }; static ElemTreeData constr_dtmpln[] = { {0, PRO_E_DTMPLN_CONSTRAINT, {(ProValueDataType)-1}}, {1, PRO_E_DTMPLN_CONSTR_TYPE, {PRO_VALUE_TYPE_INT, {PRO_DTMPLN_OFFS}}}, {1, PRO_E_DTMPLN_CONSTR_REF, {PRO_VALUE_TYPE_SELECTION}} }; static ElemTreeData offcsys_dtmpln[] = { {1, PRO_E_DTMPLN_OFF_CSYS, {PRO_VALUE_TYPE_INT}}, {1, PRO_E_DTMPLN_OFF_CSYS_OFFSET, {PRO_VALUE_TYPE_DOUBLE}} }; static ElemTreeData offs_dtmpln[] = { {1, PRO_E_DTMPLN_CONSTR_REF_OFFSET, {PRO_VALUE_TYPE_DOUBLE}} }; static ElemTreeData angle_dtmpln[] = { {1, PRO_E_DTMPLN_CONSTR_REF_ANGLE, {PRO_VALUE_TYPE_DOUBLE}} }; static ElemTreeData blend_dtmpln[] = { {1, PRO_E_DTMPLN_SEC_IND, {PRO_VALUE_TYPE_INT}} }; static ProElempathItem constr_path[] = { {PRO_ELEM_PATH_ITEM_TYPE_ID, PRO_E_DTMPLN_CONSTRAINTS} }; err = ProUtilElemtreeCreate(dtmpln, SIZEOFARR(dtmpln), NULL, &tree); err = ProUtilElemtreeElementGet(tree, constr_path, SIZEOFARR(constr_path), &constrs_elem); for (i=0; i<constr->n_constr; i++) { constr_dtmpln[1].data.v.i = constr->type[i]; constr_dtmpln[2].data.v.r = constr->ref[i]; err = ProUtilElemtreeCreate(constr_dtmpln, SIZEOFARR(constr_dtmpln), NULL, &constr_elem); switch(constr->type[i]) { case DCTR_OFFSET: if (constr->index[i] == -1) { /* Offset plane */ offs_dtmpln[0].data.v.d = constr->offset[i]; err = ProUtilElemtreeCreate(offs_dtmpln, SIZEOFARR(offs_dtmpln), constr_elem, &constr_elem); } else { /* Offset csys */ offcsys_dtmpln[0].data.v.i = constr->index[i]; offcsys_dtmpln[1].data.v.d = constr->offset[i]; err = ProUtilElemtreeCreate(offcsys_dtmpln, SIZEOFARR(offcsys_dtmpln), constr_elem, &constr_elem); } break; case DCTR_ANGLE: offs_dtmpln[0].data.v.d = constr->offset[i]; err = ProUtilElemtreeCreate(angle_dtmpln, SIZEOFARR(angle_dtmpln), constr_elem, &constr_elem); break; case DCTR_BLEND_SECTION: offs_dtmpln[0].data.v.i = constr->index[i]; err = ProUtilElemtreeCreate(blend_dtmpln, SIZEOFARR(blend_dtmpln), constr_elem, &constr_elem); break; } /* For testing purposes used ProElementArraySet/Get, the better way use ProElemtreeElementAdd */ #if 0 err = ProArrayAlloc(0, sizeof(ProElement), 1, (ProArray*)&p_elems); TEST_CALL_REPORT("ProArrayAlloc()", "ProTestDtmplnDone()", err, err != PRO_TK_NO_ERROR); err = ProElementArrayGet(constrs_elem, NULL, &p_elems); TEST_CALL_REPORT("ProElementArrayGet()", "ProTestDtmplnDone()", err, err != PRO_TK_NO_ERROR); if (err != PRO_TK_NO_ERROR) { /* Added since bug in func ProElementArrayGet in the pipe mode */ err = ProArrayAlloc(0, sizeof(ProElement), 1, (ProArray*)&p_elems); TEST_CALL_REPORT("ProArrayAlloc()", "ProTestDtmplnDone()", err, err != PRO_TK_NO_ERROR); } err = ProArrayObjectAdd((ProArray*)&p_elems, PRO_VALUE_UNUSED, 1, &constr_elem); TEST_CALL_REPORT("ProArrayObjectAdd()", "ProTestDtmplnDone()", err, err != PRO_TK_NO_ERROR); err = ProElementArraySet(constrs_elem, NULL, p_elems); TEST_CALL_REPORT("ProElementArraySet()", "ProTestDtmplnDone()", err, err != PRO_TK_NO_ERROR); err = ProArrayFree((ProArray*)&p_elems); TEST_CALL_REPORT("ProArrayFree()", "ProTestDtmplnDone()", err, err != PRO_TK_NO_ERROR); #else err = ProElemtreeElementAdd(constrs_elem, NULL, constr_elem); TEST_CALL_REPORT("ProElemtreeElementAdd()", "ProTestDtmplnDone()", err, err != PRO_TK_NO_ERROR); #endif } /*------------------------------------------------------------------*\ Alloc selection to the model \*------------------------------------------------------------------*/ err = ProMdlToModelitem(constr->model, &modelitem); TEST_CALL_REPORT("ProMdlToModelitem()", "ProTestDtmplnDone()", err, err != PRO_TK_NO_ERROR); err = ProSelectionAlloc(NULL, &modelitem, &featsel); TEST_CALL_REPORT("ProSelectionAlloc()", "ProTestDtmplnDone()", err, err != PRO_TK_NO_ERROR); /*------------------------------------------------------------------*\ Create datum plane \*------------------------------------------------------------------*/ err = ProUtilElementtreePrint(tree, PRO_TEST_INFO_WINDOW, NULL); err = ProArrayAlloc(1,sizeof(ProFeatureCreateOptions), 1, (ProArray*)&opts); opts[0]= PRO_FEAT_CR_NO_OPTS; err = ProFeatureWithoptionsCreate(featsel, tree, opts, PRO_REGEN_NO_FLAGS, &feat, &errs); TEST_CALL_REPORT("ProFeatureWithoptionsCreate()", "ProTestDtmplnDone()", err, err != PRO_TK_NO_ERROR); err = ProArrayFree((ProArray*)&opts); if (err != PRO_TK_NO_ERROR) { ProUtilFeatErrsPrint(&errs); } else { ProUtilMsgPrint(msgfil, (char *)"TEST %0s has been created successfully.", (char *)"DATUM PLANE"); err = ProTreetoolRefresh(constr->model); TEST_CALL_REPORT("ProTreetoolRefresh()", "ProTestDtmplnDone()", err, err != PRO_TK_NO_ERROR); } err = ProElementFree(&tree); TEST_CALL_REPORT("ProElementFree()", "ProTestDtmplnDone()", err, err != PRO_TK_NO_ERROR); err = ProSelectionFree(&featsel); TEST_CALL_REPORT("ProSelectionFree()", "ProTestDtmplnDone()", err, err != PRO_TK_NO_ERROR); ProUtilMenucompDelete(); return (0); } /*=============================================================*\ FUNCTION: ProTestDtmplnRestart PURPOSE: Restart datum plane creation \*=============================================================*/ int ProTestDtmplnRestart( DtmPlnConstr *constr) { int i; ProMdl model; ProUtilMsgPrint(msgfil, (char *)"TEST Datum plane was restarted. Select options again."); if (constr->cur_constr != -1) ProUtilMenubuttonHighlight((char *)"tkdtm plane", constr_type[constr->cur_constr].button_name, 0); ProUtilMenubuttonHighlight((char *)"tkdtmplnd", (char *)"Restart", 0); model = constr->model; memset(constr, '\0', sizeof(DtmPlnConstr)); constr->cur_constr = -1; constr->constr_enabled = -1; constr->model = model; for (i=0; i<SIZEOFARR(constr_type); i++) constr_type[i].state_en = -1; for (i=0; i<SIZEOFARR(ref_type); i++) { ref_type[i].state_en = -1; ref_type[i].state_hi = -1; } ProTestDtmplnMenuSet(constr); return (0); } /*=============================================================*\ FUNCTION: ProUtilMenucompRestart PURPOSE: Restart datum plane creation \*=============================================================*/ int ProTestDtmplnQuit( DtmPlnConstr *constr) { ProUtilMsgPrint(msgfil, (char *)"TEST Datum plane was not created."); ProUtilMenucompDelete(); return (0); } /*=============================================================*\ FUNCTION: ProUtilOffsetPlaneThruPoint PURPOSE: Calculate offset to datum plane by pick point on the model \*=============================================================*/ int ProUtilOffsetPlaneThruPoint( ProGeomitemdata **p_data, double *offset) { ProError err; ProPoint3d point; ProSelection *p_sel_arr; ProGeomitemdata *data =*p_data; int n_sel; err = ProSelect((char *)"surface,datum", 1, NULL, NULL, NULL, NULL, &p_sel_arr, &n_sel); TEST_CALL_REPORT("ProSelect()", "ProUtilOffsetPlaneThruPoint()", err, err != PRO_TK_NO_ERROR); if (err != PRO_TK_NO_ERROR || n_sel != 1) return(-1); err = ProSelectionPoint3dGet(p_sel_arr[0], point); TEST_CALL_REPORT("ProSelectionPoint3dGet()", "ProUtilOffsetPlaneThruPoint()", err, err != PRO_TK_NO_ERROR); *offset = ProUtilPointPlaneDist(point, data->data.p_surface_data->srf_shape.plane.origin, data->data.p_surface_data->srf_shape.plane.e3); err = ProMenuDeleteWithStatus(0); TEST_CALL_REPORT("ProMenuDeleteWithStatus()", "ProUtilOffsetPlaneThruPoint()", err, err != PRO_TK_NO_ERROR); return (0); } /*=============================================================*\ FUNCTION: ProUtilOffsetPlaneThruPoint PURPOSE: Calculate offset to datum plane by pick point on the model \*=============================================================*/ int ProUtilOffsetPlaneEnterValue( ProGeomitemdata **p_data, double *p_offset) { ProGeomitemdata *data =*p_data; ProError err; double offset; *p_offset = 0.0; ProUtilMsgPrint(msgfil, (char *)"TEST Enter offset in the indicated direction, <ESC> to quit[%0f]:", &offset); err = ProMessageDoubleRead(NULL, &offset); TEST_CALL_REPORT("ProMessageDoubleRead()", "ProUtilOffsetPlaneEnterValue()", err, err != PRO_TK_NO_ERROR); if (err != PRO_TK_NO_ERROR && err != PRO_TK_GENERAL_ERROR) return (-1); *p_offset = offset; err = ProMenuDeleteWithStatus(0); TEST_CALL_REPORT("ProMenuDeleteWithStatus()", "ProUtilOffsetPlaneEnterValue()", err, err != PRO_TK_NO_ERROR); return(0); } /*=============================================================*\ FUNCTION: ProUtilDtmplnSelPostFilter PURPOSE: Post filter for selection \*=============================================================*/ ProError ProUtilDtmplnSelPostFilter( ProSelection sel, DtmPlnConstr *constr) { ProError err; ProBoolean ok = PRO_B_TRUE; ProModelitem modelitem; ProGeomitemdata *p_data; int num_sec; /* TEST_CALL_REPORT("ProSelectionPostFilter()", "ProUtilDtmplnSelPostFilter()", 0, 0);*/ err = ProSelectionModelitemGet(sel, &modelitem); TEST_CALL_REPORT("ProSelectionModelitemGet()", "ProUtilDtmplnSelPostFilter()", err, err != PRO_TK_NO_ERROR); if (modelitem.type == PRO_EDGE || modelitem.type == PRO_SURFACE) { err = ProGeomitemdataGet((ProGeomitem*)&modelitem, &p_data); TEST_CALL_REPORT("ProGeomitemdataGet()", "ProUtilDtmplnSelPostFilter()", err, err != PRO_TK_NO_ERROR); if (modelitem.type == PRO_EDGE && p_data->data.p_curve_data->line.type != PRO_ENT_LINE && p_data->data.p_curve_data->line.type != PRO_ENT_ARC && p_data->data.p_curve_data->line.type != PRO_ENT_ELLIPSE) ok = PRO_B_FALSE; if (modelitem.type == PRO_SURFACE) { if (constr->cur_constr == DCTR_TANGENT && p_data->data.p_surface_data->type != PRO_SRF_CYL && p_data->data.p_surface_data->type != PRO_SRF_CONE) ok = PRO_B_FALSE; if ((constr->cur_constr == DCTR_PARALLEL || constr->cur_constr == DCTR_NORMAL || constr->cur_constr == DCTR_OFFSET || constr->cur_constr == DCTR_ANGLE) && p_data->data.p_surface_data->type != PRO_SRF_PLANE) ok = PRO_B_FALSE; if (constr->cur_constr == DCTR_THROUGH && p_data->data.p_surface_data->type != PRO_SRF_PLANE && p_data->data.p_surface_data->type != PRO_SRF_CYL && p_data->data.p_surface_data->type != PRO_SRF_CONE) ok = PRO_B_FALSE; } err = ProGeomitemdataFree(&p_data); TEST_CALL_REPORT("ProGeomitemdataFree()", "ProUtilDtmplnSelPostFilter()", err, err != PRO_TK_NO_ERROR); } if (modelitem.type == PRO_FEATURE) { err = ProFeatureNumSectionsGet((ProFeature*)&modelitem, &num_sec); TEST_CALL_REPORT("ProFeatureNumSectionsGet()", "ProUtilDtmplnSelPostFilter()", err, err != PRO_TK_NO_ERROR); if (err != PRO_TK_NO_ERROR || num_sec<1) ok = PRO_B_FALSE; } return (ok ? PRO_TK_NO_ERROR : PRO_TK_GENERAL_ERROR); } /*=============================================================*\ FUNCTION: ProUtilDtmplnSelPostSelact PURPOSE: Post action function for selection \*=============================================================*/ ProError ProUtilDtmplnSelPostSelact( Pro3dPnt pnt, ProSelection sel, DtmPlnConstr *constr) { ProError err; ProModelitem modelitem; double offset; int action; char *c= (char *)"x"; /* TEST_CALL_REPORT("ProSelectionPostSelact()", "ProUtilDtmplnSelPostSelact()", 0, 0);*/ if (constr->cur_constr == DCTR_OFFSET ) { err = ProSelectionModelitemGet(sel, &modelitem); TEST_CALL_REPORT("ProSelectionModelitemGet()", "ProUtilDtmplnSelPostSelact()", err, err != PRO_TK_NO_ERROR); if (modelitem.type == PRO_CSYS) { err = ProMenuFileRegister((char *)"tkoff csys", (char *)"tkoffcsys.mnu", NULL); err = ProMenubuttonActionSet((char *)"tkoff csys", (char *)"X Axis", (ProMenubuttonAction)ProUtilMenubuttonDeleteWithStatus, NULL, PRO_DTMPLN_OFF_CSYS_X); err = ProMenubuttonActionSet((char *)"tkoff csys", (char *)"Y Axis", (ProMenubuttonAction)ProUtilMenubuttonDeleteWithStatus, NULL, PRO_DTMPLN_OFF_CSYS_Y); err = ProMenubuttonActionSet((char *)"tkoff csys", (char *)"Z Axis", (ProMenubuttonAction)ProUtilMenubuttonDeleteWithStatus, NULL, PRO_DTMPLN_OFF_CSYS_Z); err = ProMenubuttonActionSet((char *)"tkoff csys", (char *)"tkoff csys", (ProMenubuttonAction)ProMenubuttonDelete, NULL, 0); err = ProMenuCreate(PROMENUTYPE_MAIN, (char *)"tkoff csys", NULL); err = ProMenuProcess((char *)"tkoff csys", &action); if (err == PRO_TK_NO_ERROR) { constr->index[constr->n_constr] = action; offset = 0.0; c[0] = action - PRO_DTMPLN_OFF_CSYS_X + 'x'; ProUtilMsgPrint(msgfil, (char *)"TEST Enter offset value in the %0s-direction [%1f]:", c, &offset); err = ProMessageDoubleRead(NULL, &offset); TEST_CALL_REPORT("ProMessageDoubleRead()", "ProUtilDtmplnSelPostSelact()", err, err !=PRO_TK_NO_ERROR); constr->offset[constr->n_constr] = offset; } } } return (PRO_TK_NO_ERROR); } /*=============================================================*\ FUNCTION: ProTestDtmplnConstrAdd PURPOSE: Add new constraint \*=============================================================*/ int ProTestDtmplnConstrAdd( DtmPlnConstr *constr, /* In: Setup struct */ int index) /* In : Const index in the table */ { ProCharLine line; int i, n_sel, action, reftype; ProSelection *p_sel_arr; ProModelitem modelitem; ProGeomitemdata *p_data; ProSelFunctions func; ProError err; double offset = 0.0; if (constr->ref_pressed) constr->ref_pressed = PRO_B_FALSE; else { constr->cur_constr = index; for (i=0, constr->ref_enabled = 0; i<SIZEOFARR(ref_type); i++) if (ref_type[i].freedom[index] > 0) constr->ref_enabled |= (1 << i); constr->ref_highlighted = constr->ref_enabled; } ProTestDtmplnMenuSet(constr); if (constr->cur_constr == DCTR_BLEND_SECTION) { ProUtilstrcpy(line, "feature"); ProUtilMsgPrint(msgfil, (char *)"TEST Not implemented."); return (0); } else for (i=0, line[0] = '\0'; i<SIZEOFARR(ref_type); i++) { if (constr->ref_highlighted & (1 << i)) { if (line[0] != '\0') ProUtilstrcat(line, ","); ProUtilstrcat(line, (const char*)ref_type[i].select_option); } } memset(&func, '\0', sizeof(func)); func.post_filter = (ProSelectionPostFilter)ProUtilDtmplnSelPostFilter; func.post_selact = (ProSelectionPostSelact)ProUtilDtmplnSelPostSelact; func.app_data = (ProAppData)constr; /* do {*/ err = ProSelect(line, 1, NULL, &func, NULL, NULL, &p_sel_arr, &n_sel); TEST_CALL_REPORT("ProSelect()", "ProTestDtmplnConstrAdd()", err, err != PRO_TK_NO_ERROR && err != PRO_TK_PICK_ABOVE); /* } while(err != PRO_TK_PICK_ABOVE && !(err ==PRO_TK_NO_ERROR && n_sel == 1)); */ if (err != PRO_TK_NO_ERROR) return (0); err = ProSelectionModelitemGet(p_sel_arr[0], &modelitem); TEST_CALL_REPORT("ProSelectionModelitemGet()", "ProTestDtmplnConstrAdd()", err, err != PRO_TK_NO_ERROR); constr->ref_enabled = 0; constr->ref_highlighted = 0; ProUtilMenubuttonHighlight((char *)"tkdtm plane", constr_type[index].button_name, 0); ProTestDtmplnMenuSet(constr); err = ProGeomitemdataGet((ProGeomitem*)&modelitem, &p_data); TEST_CALL_REPORT("ProGeomitemdataGet()", "ProTestDtmplnConstrAdd()", err, err != PRO_TK_NO_ERROR); err = ProSelectionCopy(p_sel_arr[0], &constr->ref[constr->n_constr]); TEST_CALL_REPORT("ProSelectionCopy()", "ProTestDtmplnConstrAdd()", err, err != PRO_TK_NO_ERROR); /*------------------------------------------------------------*\ Add constarint \*------------------------------------------------------------*/ if (index == DCTR_OFFSET) { if (modelitem.type == PRO_SURFACE) { err = ProMenuFileRegister((char *)"tkoffset", (char *)"tkoffset.mnu", NULL); err = ProMenubuttonGenactionSet((char *)"tkoffset", (char *)"Thru point", (ProMenubuttonGenaction)ProUtilOffsetPlaneThruPoint, &p_data, &offset, NULL, NULL, NULL, NULL); err = ProMenubuttonGenactionSet((char *)"tkoffset", (char *)"Enter Value", (ProMenubuttonGenaction)ProUtilOffsetPlaneEnterValue, &p_data, &offset, NULL, NULL, NULL, NULL); err = ProMenubuttonActionSet((char *)"tkoffset", (char *)"tkoffset", (ProMenubuttonAction)ProMenuDelete, NULL, 0); err = ProMenuCreate(PROMENUTYPE_MAIN, (char *)"tkoffset", NULL); err = ProMenuCommandPush((char *)"Thru point"); TEST_CALL_REPORT("ProMenuCommandPush()", (char *)"ProTestDtmplnConstrAdd()", err, err != PRO_TK_NO_ERROR); err = ProMenuProcess((char *)"tkoffset", &action); if (err != PRO_TK_NO_ERROR) return (0); constr->offset[constr->n_constr] = offset; constr->index[constr->n_constr] = -1; } } if (index == DCTR_ANGLE) { ProUtilMsgPrint(msgfil, (char *)"TEST Angle in indicated direction, [%0f]:", &offset); err = ProMessageDoubleRead(NULL, &offset); TEST_CALL_REPORT("ProMessageDoubleRead()", "ProTestDtmplnConstrAdd()", err, err != PRO_TK_NO_ERROR); constr->offset[constr->n_constr] = offset; } /* Here constraint should be checked */ switch (modelitem.type) { case PRO_AXIS: case PRO_EDGE: case PRO_CURVE: if (p_data->data.p_curve_data->line.type == PRO_ENT_LINE) reftype = USER_LINE; else reftype = USER_PLANE; break; case PRO_POINT: case PRO_EDGE_START: case PRO_EDGE_END: case PRO_CRV_START: case PRO_CRV_END: reftype = USER_POINT; break; case PRO_SURFACE: if (p_data->data.p_surface_data->type == PRO_SRF_PLANE) reftype = USER_PLANE; else reftype = USER_CYL; break; case PRO_CSYS: reftype = USER_CSYS; break; case PRO_FEATURE: reftype = USER_PLANE; index = DCTR_THROUGH; /* Here we must find the feature section */ break; } err = ProGeomitemdataFree(&p_data); TEST_CALL_REPORT("ProGeomitemdataFree()", "ProTestDtmplnConstrAdd()", err, err != PRO_TK_NO_ERROR); constr->type[constr->n_constr] = (ProDtmplnConstrType)constr->cur_constr; constr->n_constr++; constr->freedom += ref_type[reftype].freedom[index]; if (index == DCTR_THROUGH || index == DCTR_OFFSET) constr->through = PRO_B_TRUE; /* Allow offset and Blend be only first constraint */ constr->constr_enabled = constr->constr_enabled & (~((1 << DCTR_OFFSET)|(1 << DCTR_BLEND_SECTION))); if (constr->cur_constr == DCTR_PARALLEL) constr->constr_enabled = constr->constr_enabled & (~(1 << DCTR_PARALLEL)); if ((constr->freedom >= 3) && constr->through) { ProUtilMsgPrint(msgfil, (char *)"TEST Datum Plane is fully constrained."); constr->constr_enabled = 0; } ProTestDtmplnMenuSet(constr); return (0); } /*=============================================================*\ FUNCTION: ProTestDtmplnConstrRef PURPOSE: Enable/Disable constraint ref \*=============================================================*/ int ProTestDtmplnConstrRef( DtmPlnConstr *constr, int index) { ProError err; constr->ref_pressed = PRO_B_TRUE; constr->ref_highlighted ^= (1 << index); err = ProMenuCommandPush(constr_type[constr->cur_constr].button_name); TEST_CALL_REPORT("ProMenuCommandPush()", "ProTestDtmplnConstrRef()", err, err != PRO_TK_NO_ERROR); return (0); } /*=============================================================*\ FUNCTION: ProTestDtmplnCreate PURPOSE: Create datum plane feature \*=============================================================*/ int ProTestDtmplnCreate( ProMdl model) { ProError err; int action, i, n_menus; char *compound[] = {(char *)"tkdtm plane", (char *)"tkdtmplnc", (char *)"tkdtmplnd", (char *)""}; memset(&constraint, '\0', sizeof(constraint)); constraint.cur_constr = -1; constraint.constr_enabled = -1; constraint.model = model; err = ProMenuFileRegister((char *)"tkdtm plane", (char *)"tkdtmpln.mnu", NULL); for (i=0; i<SIZEOFARR(constr_type); i++) { err = ProMenubuttonActionSet((char *)"tkdtm plane", constr_type[i].button_name, (ProMenubuttonAction)ProTestDtmplnConstrAdd, &constraint, i); constr_type[i].state_en = -1; } err = ProMenubuttonActionSet((char *)"tkdtm plane", (char *)"tkdtm plane", (ProMenubuttonAction)ProTestDtmplnQuit, NULL, 0); err = ProMenuFileRegister((char *)"tkdtmplnc", (char *)"tkdtmplnc.mnu", NULL); for (i=0; i<SIZEOFARR(ref_type); i++) { err = ProMenubuttonActionSet((char *)"tkdtmplnc", ref_type[i].button_name, (ProMenubuttonAction)ProTestDtmplnConstrRef, &constraint, i); ref_type[i].state_en = -1; ref_type[i].state_hi = -1; } err = ProMenuFileRegister((char *)"tkdtmplnd",(char *)"tkdtmplnd.mnu", NULL); err = ProMenubuttonActionSet((char *)"tkdtmplnd", (char *)"Done", (ProMenubuttonAction)ProTestDtmplnDone, &constraint, 0); err = ProMenubuttonActionSet((char *)"tkdtmplnd", (char *)"Restart", (ProMenubuttonAction)ProTestDtmplnRestart, &constraint, 0); err = ProMenubuttonActionSet((char *)"tkdtmplnd", (char *)"Quit", (ProMenubuttonAction)ProTestDtmplnQuit, &constraint, 0); err = ProMenuPush(); TEST_CALL_REPORT("ProMenuPush()", "ProTestDtmpln()", err, err != PRO_TK_NO_ERROR); err = ProMenuDatamodeSet((char *)"tkdtmplnc", PRO_B_TRUE); TEST_CALL_REPORT("ProMenuDatamodeSet()", "ProTestDtmpln()", err, err != PRO_TK_NO_ERROR); err = ProCompoundmenuCreate(compound, &n_menus); TEST_CALL_REPORT("ProCompoundmenuCreate()", "ProTestDtmpln()", err, err != PRO_TK_NO_ERROR); ProTestDtmplnMenuSet(&constraint); err = ProMenuProcess((char *)"tkdtm plane", &action); err = ProMenuPop(); TEST_CALL_REPORT("ProMenuPop()", "ProTestDtmpln()", err, err != PRO_TK_NO_ERROR); return (PRO_TK_NO_ERROR); } /*=============================================================*\ FUNCTION: ProTestDtmpln PURPOSE: Create datum plane feature main funct \*=============================================================*/ ProError ProTestDtmpln() { ProMdl model; ProError err; int n_csys = 0; err = ProMdlCurrentGet(&model); TEST_CALL_REPORT("ProMdlCurrentGet()", "ProTestDtmpln()", err, err != PRO_TK_NO_ERROR); err = ProSolidFeatVisit((ProSolid)model, (ProFeatureVisitAction)ProUtilNonCsysFeatCheck, (ProFeatureFilterAction)NULL, (ProAppData)&n_csys); TEST_CALL_REPORT("ProSolidFeatVisit()", "ProTestDtmpln()", err, err != PRO_TK_NO_ERROR && err != PRO_TK_E_FOUND); if (err == PRO_TK_E_FOUND) { ProTestDtmplnCreate(model); } else { ProTestDtmplnDefCreate(model, n_csys); } return (PRO_TK_NO_ERROR); }