/*
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);
}