/*
Copyright (c) 2019 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved.
*/
#include "ProToolkit.h"
#include "ProFeature.h"
#include "ProAnalysis.h"
#include "ProArray.h"
#include "ProDtmPnt.h"
#include "ProElement.h"
#include "ProExtdata.h"
#include "ProMessage.h"
#include "ProPoint.h"
#include "ProSection.h"
#include "Pro2dEntdef.h"
#include "ProSelection.h"
#include "ProSurface.h"
#include "ProGraphic.h"
#include "ProModelitem.h"
#include "ProUtil.h"
#include <PTApplsUnicodeUtils.h>
#include <UtilString.h>
#include "UtilMath.h"
static ProFileName msgfil;
/*--------------------------------------------------------------------*\
Data structure to describe the information needed by an analysis
feature that creates a surface sys. The csys is centered at a
datum point on a surface, with its X and Y axes aligned with the
U and V mesh lines. The Z axis can be inwards or outwards, by
user choice, and the origin can be offset from the datum point
by an offset value that is stored as a feature dimension.
\*--------------------------------------------------------------------*/
typedef struct surf_csys_data
{
/* References */
ProSelection point; /* The datum point referenced by the csys */
/* Dimensions */
double offset;
/* Application-specific data */
ProBoolean outwards;
/* Results storage */
ProCsysdata csysdata; /* The geometry of the csys */
} Surfcsysdata_t;
int UsrClassRegister(ProMdl model, ProExtdataClass *class);
/*====================================================================*\
FUNCTION : UsrSurfcsysUiAction()
PURPOSE : Callback for UI action for surface csys
\*====================================================================*/
ProError UsrSurfcsysUiAction(
ProAnalysis analysis)
{
Surfcsysdata_t *data;
ProError status;
ProSelection *sel;
int n_sel;
ProModelitem modelitem;
ProPoint p;
ProDtmpntType ptype;
ProError UsrYesnoGet();
/*--------------------------------------------------------------------*\
Ask the user to select a datum point on a surface. Check that it
is on a surface, and reject it if it is not.
\*--------------------------------------------------------------------*/
ProMessageDisplay(msgfil,"USER Select a point on a surface");
while(1)
{
if(ProSelect("point",1,NULL,NULL,NULL,NULL,&sel,&n_sel)
!= PRO_TK_NO_ERROR || n_sel < 0)
return(PRO_TK_MSG_USER_QUIT);
ProSelectionModelitemGet(sel[0], &modelitem);
ProPointInit(modelitem.owner, modelitem.id, &p);
if(!UsrPointPtypeGet(modelitem.owner, p, &ptype) ||
ptype != PRO_DTMPNT_TYPE_ON_SURF)
{
ProMessageDisplay(msgfil,"USER That is not a point on surf. Select again");
continue;
}
break;
}
/*--------------------------------------------------------------------*\
Get the pointer to the application data stored for this analysis
feature, and set the datum point in it.
\*--------------------------------------------------------------------*/
if(ProAnalysisInfoGet(analysis, (ProAppData*)&data) !=
PRO_TK_NO_ERROR)
return(PRO_TK_GENERAL_ERROR);
ProSelectionCopy(sel[0], &data->point);
/*--------------------------------------------------------------------*\
Ask the user whether the Z axis is inwards or outwards, and
set the answer in the application data.
\*--------------------------------------------------------------------*/
ProMessageDisplay(msgfil,"USER Is the Z axis to be outwards? ||| Yes");
if(UsrYesnoGet(msgfil,"YES",&data->outwards) != PRO_TK_NO_ERROR)
return(PRO_TK_GENERAL_ERROR);
/*--------------------------------------------------------------------*\
Ask the user for the Z offset, and store that, too.
\*--------------------------------------------------------------------*/
ProMessageDisplay(msgfil,"USER Enter the Z offset distance|||0.0");
status = ProMessageDoubleRead(NULL, &data->offset);
if(status == PRO_TK_MSG_USER_QUIT)
return(PRO_TK_GENERAL_ERROR);
if(status != PRO_TK_NO_ERROR)
data->offset = 0.0;
return(PRO_TK_NO_ERROR);
}
/*====================================================================*\
FUNCTION : UsrSurfcsysDimsAction()
PURPOSE : Callback for Dims action for surface csys
\*====================================================================*/
ProError UsrSurfcsysDimsAction(
ProAnalysis analysis,
double **dims)
{
Surfcsysdata_t *data;
/*--------------------------------------------------------------------*\
Get the application data for this analysis
\*--------------------------------------------------------------------*/
if(ProAnalysisInfoGet(analysis, (ProAppData*)&data) !=
PRO_TK_NO_ERROR)
return(PRO_TK_GENERAL_ERROR);
/*--------------------------------------------------------------------*\
Add the csys offset value as a feature dimension
\*--------------------------------------------------------------------*/
ProArrayObjectAdd((ProArray*)dims, -1, 1, &data->offset);
return(PRO_TK_NO_ERROR);
}
/*====================================================================*\
FUNCTION : UsrSurfcsysInfoallocAction()
PURPOSE : Callback to allocate application data needed to describe
the surface csys
\*====================================================================*/
ProError UsrSurfcsysInfoallocAction(
ProAnalysis analysis)
{
Surfcsysdata_t *data;
/*--------------------------------------------------------------------*\
Allocate a data structure
\*--------------------------------------------------------------------*/
data = (Surfcsysdata_t*)calloc(1, sizeof(Surfcsysdata_t));
/*--------------------------------------------------------------------*\
Put the data pointer into the analysis
\*--------------------------------------------------------------------*/
ProAnalysisInfoSet(analysis, data);
return(PRO_TK_NO_ERROR);
}
/*====================================================================*\
FUNCTION : UsrSurfcsysInfofreeAction()
PURPOSE : Callback to free the application data for surface csys
\*====================================================================*/
ProError UsrSurfcsysInfofreeAction(
ProAnalysis analysis)
{
Surfcsysdata_t *data;
/*--------------------------------------------------------------------*\
Get the data pointer from the analysis
\*--------------------------------------------------------------------*/
if(ProAnalysisInfoGet(analysis, (ProAppData*)&data) !=
PRO_TK_NO_ERROR)
return(PRO_TK_GENERAL_ERROR);
/*--------------------------------------------------------------------*\
Free the data
\*--------------------------------------------------------------------*/
free(data);
/*--------------------------------------------------------------------*\
Set the data pointer in the analysis to NULL
\*--------------------------------------------------------------------*/
ProAnalysisInfoSet(analysis, NULL);
return(PRO_TK_NO_ERROR);
}
/*====================================================================*\
FUNCTION : UsrSurfcsysCompcheckAction()
PURPOSE : Callback to tell Pro/E whether computation can be performed
for surface csys analysis feature
\*====================================================================*/
ProError UsrSurfcsysCompcheckAction(
ProAnalysis analysis)
{
Surfcsysdata_t *data;
/*--------------------------------------------------------------------*\
Get the analysis data
\*--------------------------------------------------------------------*/
if(ProAnalysisInfoGet(analysis, (ProAppData*)&data) !=
PRO_TK_NO_ERROR)
return(PRO_TK_GENERAL_ERROR);
/*--------------------------------------------------------------------*\
Return NO_ERROR if the datum point selection is set OK
\*--------------------------------------------------------------------*/
return(data->point!=NULL?PRO_TK_NO_ERROR:PRO_TK_GENERAL_ERROR);
}
/*====================================================================*\
FUNCTION : UsrSurfcsysComputeAction()
PURPOSE : Callback to perform the surface csys computation
\*====================================================================*/
ProError UsrSurfcsysComputeAction(
ProAnalysis analysis)
{
Surfcsysdata_t *data;
ProModelitem modelitem;
ProPoint p;
ProVector pos;
ProSurface surface;
ProUvParam uv;
ProVector normal, der1[2];
ProFeature feature;
/*--------------------------------------------------------------------*\
Get the application data from the analysis
\*--------------------------------------------------------------------*/
if(ProAnalysisInfoGet(analysis, (ProAppData*)&data) !=
PRO_TK_NO_ERROR)
return(PRO_TK_GENERAL_ERROR);
/*--------------------------------------------------------------------*\
Get the location of the datum point
\*--------------------------------------------------------------------*/
ProSelectionModelitemGet(data->point, &modelitem);
ProPointInit(modelitem.owner, modelitem.id, &p);
ProPointCoordGet(p, data->csysdata.origin);
/*--------------------------------------------------------------------*\
Find the surface the datum point sits on, and find its first
derivative vectors and the normal
\*--------------------------------------------------------------------*/
UsrPointSrfGet(data->point, &surface);
ProSurfaceParamEval(modelitem.owner, surface, data->csysdata.origin,
uv);
ProSurfaceXyzdataEval(surface, uv, NULL, der1, NULL, normal);
/*--------------------------------------------------------------------*\
Flip and offset if necessary
\*--------------------------------------------------------------------*/
if(!data->outwards)
ProUtilVectorScale(-1.0, normal, normal);
ProUtilVectorsLincom(1.0, data->csysdata.origin, data->offset, normal,
data->csysdata.origin);
/*--------------------------------------------------------------------*\
Copy this information to the application data as a csys geometry
\*--------------------------------------------------------------------*/
memcpy(data->csysdata.x_vector, der1[0], sizeof(ProVector));
ProUtilVectorNormalize(data->csysdata.x_vector,
data->csysdata.x_vector);
memcpy(data->csysdata.z_vector, normal, sizeof(ProVector));
ProUtilVectorNormalize(data->csysdata.z_vector,
data->csysdata.z_vector);
ProUtilVectorCross(data->csysdata.z_vector,
data->csysdata.x_vector, data->csysdata.y_vector);
return(PRO_TK_NO_ERROR);
}
/*====================================================================*\
FUNCTION : UsrSurfcsysDisplayAction()
PURPOSE : Callback to display the results of the analysis computation
\*====================================================================*/
ProError UsrSurfcsysDisplayAction(
ProAnalysis analysis)
{
Surfcsysdata_t *data;
ProVector pos;
/*--------------------------------------------------------------------*\
Get the application data from the analysis
\*--------------------------------------------------------------------*/
if(ProAnalysisInfoGet(analysis, (ProAppData*)&data) !=
PRO_TK_NO_ERROR)
return(PRO_TK_GENERAL_ERROR);
/*--------------------------------------------------------------------*\
Draw a line for the X vector
\*--------------------------------------------------------------------*/
ProGraphicsPenPosition(data->csysdata.origin);
pos[0]=data->csysdata.origin[0]+data->csysdata.x_vector[0];
pos[1]=data->csysdata.origin[1]+data->csysdata.x_vector[1];
pos[2]=data->csysdata.origin[2]+data->csysdata.x_vector[2];
ProGraphicsLineDraw(pos);
/*--------------------------------------------------------------------*\
Draw a line for the Y vector
\*--------------------------------------------------------------------*/
ProGraphicsPenPosition(data->csysdata.origin);
pos[0]=data->csysdata.origin[0]+data->csysdata.y_vector[0];
pos[1]=data->csysdata.origin[1]+data->csysdata.y_vector[1];
pos[2]=data->csysdata.origin[2]+data->csysdata.y_vector[2];
ProGraphicsLineDraw(pos);
/*--------------------------------------------------------------------*\
Draw a line for the Z vector
\*--------------------------------------------------------------------*/
ProGraphicsPenPosition(data->csysdata.origin);
pos[0]=data->csysdata.origin[0]+data->csysdata.z_vector[0];
pos[1]=data->csysdata.origin[1]+data->csysdata.z_vector[1];
pos[2]=data->csysdata.origin[2]+data->csysdata.z_vector[2];
ProGraphicsLineDraw(pos);
return(PRO_TK_NO_ERROR);
}
/*====================================================================*\
FUNCTION : UsrSurfcsysOutputAction()
PURPOSE : Callback to write textual information about the result of
the computation
\*====================================================================*/
ProError UsrSurfcsysOutputAction(
ProAnalysis analysis,
ProLine **lines)
{
Surfcsysdata_t *data;
ProCharLine buff;
ProLine ll[4];
/*--------------------------------------------------------------------*\
Get the application dara from the analysis
\*--------------------------------------------------------------------*/
if(ProAnalysisInfoGet(analysis, (ProAppData*)&data) !=
PRO_TK_NO_ERROR)
return(PRO_TK_GENERAL_ERROR);
/*--------------------------------------------------------------------*\
Write the origin of the csys
\*--------------------------------------------------------------------*/
ProTKSprintf(buff,"Csys is at location (%0.2f, %0.2f, %0.2f)",
data->csysdata.origin[0],
data->csysdata.origin[1],
data->csysdata.origin[2]);
ProStringToWstring(ll[0], buff);
/*--------------------------------------------------------------------*\
X vector
\*--------------------------------------------------------------------*/
ProTKSprintf(buff," X vector (%0.2f, %0.2f, %0.2f)",
data->csysdata.x_vector[0],
data->csysdata.x_vector[1],
data->csysdata.x_vector[2]);
ProStringToWstring(ll[1], buff);
/*--------------------------------------------------------------------*\
Y vector
\*--------------------------------------------------------------------*/
ProTKSprintf(buff," Y vector (%0.2f, %0.2f, %0.2f)",
data->csysdata.y_vector[0],
data->csysdata.y_vector[1],
data->csysdata.y_vector[2]);
ProStringToWstring(ll[2], buff);
/*--------------------------------------------------------------------*\
Z vector
\*--------------------------------------------------------------------*/
ProTKSprintf(buff," Z vector (%0.2f, %0.2f, %0.2f)",
data->csysdata.z_vector[0],
data->csysdata.z_vector[1],
data->csysdata.z_vector[2]);
ProStringToWstring(ll[3], buff);
/*--------------------------------------------------------------------*\
Add the four lines to the output array
\*--------------------------------------------------------------------*/
ProArrayObjectAdd((ProArray*)lines, -1, 4, ll);
return(PRO_TK_NO_ERROR);
}
/*====================================================================*\
FUNCTION : UsrSurfcsysSavecheckAction()
PURPOSE : Callback to tell Pro/E whether the analysis application
data can be saved
\*====================================================================*/
ProError UsrSurfcsysSavecheckAction(
ProAnalysis analysis)
{
return(PRO_TK_NO_ERROR);
}
/*====================================================================*\
FUNCTION : UsrSurfcsysInfosaveAction()
PURPOSE : Callback to tell Pro/E what element references are required
by the analysis feature, and save the rest of the info
to Ext Data
\*====================================================================*/
ProError UsrSurfcsysInfosaveAction(
ProAnalysis analysis,
ProFeature *feature,
ProSelection **references)
{
Surfcsysdata_t *data;
ProSelection reference;
/*--------------------------------------------------------------------*\
Get the application data from the analysis
\*--------------------------------------------------------------------*/
if(ProAnalysisInfoGet(analysis, (ProAppData*)&data) !=
PRO_TK_NO_ERROR)
return(PRO_TK_GENERAL_ERROR);
/*--------------------------------------------------------------------*\
Output the reference to the datum point
\*--------------------------------------------------------------------*/
ProSelectionCopy(data->point, &reference);
ProArrayObjectAdd((ProArray*)references, -1, 1, &reference);
/*--------------------------------------------------------------------*\
Save the "outwards" option
\*--------------------------------------------------------------------*/
if(!UsrOutwardsSave(feature, data->outwards))
return(PRO_TK_GENERAL_ERROR);
return(PRO_TK_NO_ERROR);
}
ProError UsrSurfcsysDimFilter(
ProDimension *dimension,
ProAppData data)
{
static ProBoolean first_time = PRO_B_TRUE;
if (first_time)
{
first_time = PRO_B_FALSE;
return PRO_TK_NO_ERROR;
}
else
return PRO_TK_CONTINUE;
}
ProError UsrSurfcsysDimAction (
ProDimension *dimension,
ProError status,
ProAppData data)
{
data = (ProAppData)dimension;
return PRO_TK_NO_ERROR;
}
/*====================================================================*\
FUNCTION : UsrSurfcsysInforetrieveAction()
PURPOSE : Callback to get the references Pro/E has stored with the
analysis feature, and retrieve the rest from Ext Data
\*====================================================================*/
ProError UsrSurfcsysInforetrieveAction(
ProAnalysis analysis,
ProFeature *feature,
ProSelection *references)
{
Surfcsysdata_t *data;
ProError status;
ProDimension first_dim;
double dim_value;
/*--------------------------------------------------------------------*\
Get the application data from the analysis
\*--------------------------------------------------------------------*/
if(ProAnalysisInfoGet(analysis, (ProAppData*)&data) !=
PRO_TK_NO_ERROR)
return(PRO_TK_GENERAL_ERROR);
/*--------------------------------------------------------------------*\
Copy the first reference to the application as the datum point
\*--------------------------------------------------------------------*/
ProSelectionCopy(references[0], &data->point);
/*--------------------------------------------------------------------*\
Retrieve the "outwards" option from Ext Data
\*--------------------------------------------------------------------*/
UsrOutwardsRetrieve(feature, &data->outwards);
/*--------------------------------------------------------------------*\
If the feature has a dimension, take its value as the offset
\*--------------------------------------------------------------------*/
status = ProFeatureDimensionVisit(feature,
(ProDimensionVisitAction)UsrSurfcsysDimAction,
(ProDimensionFilterAction)UsrSurfcsysDimFilter,
(ProAppData)&first_dim);
status = ProDimensionValueGet(&first_dim, &dim_value);
data->offset = dim_value;
return(PRO_TK_NO_ERROR);
}
/*====================================================================*\
FUNCTION : UsrSurfcsysInfocopyAction()
PURPOSE : Callback to copy application information from one analysis
to another.
\*====================================================================*/
ProError UsrSurfcsysInfocopyAction(
ProAnalysis from,
ProAnalysis to)
{
Surfcsysdata_t *fdata, *tdata;
/*--------------------------------------------------------------------*\
Get the application data from the analyses
\*--------------------------------------------------------------------*/
if(ProAnalysisInfoGet(from, (ProAppData*)&fdata) != PRO_TK_NO_ERROR)
return(PRO_TK_GENERAL_ERROR);
if(ProAnalysisInfoGet(to, (ProAppData*)&tdata) != PRO_TK_NO_ERROR)
return(PRO_TK_GENERAL_ERROR);
/*--------------------------------------------------------------------*\
Copy the application-specific data (everything except references)
\*--------------------------------------------------------------------*/
tdata->outwards = fdata->outwards;
tdata->offset = fdata->offset;
return(PRO_TK_NO_ERROR);
}
/*====================================================================*\
FUNCTION : UsrSurfcsysResultAction()
PURPOSE : Callback to give Pro/E the feature parameters and geometry
that the analysis feature must contain
\*====================================================================*/
ProError UsrSurfcsysResultAction(
ProAnalysis analysis,
ProBoolean names_only,
ProAnalysisParameter **parameters,
ProAnalysisGeomitem **geometry)
{
Surfcsysdata_t *data;
ProAnalysisGeomitem geomitem;
ProAnalysisParameter param;
/*--------------------------------------------------------------------*\
Get the application data from the analysis
\*--------------------------------------------------------------------*/
if(ProAnalysisInfoGet(analysis, (ProAppData*)&data) !=
PRO_TK_NO_ERROR)
return(PRO_TK_GENERAL_ERROR);
/*--------------------------------------------------------------------*\
Specify a CSYS DATUM with the geometry stored in the application data
\*--------------------------------------------------------------------*/
ProStringToWstring(geomitem.name,"SURF_CSYS");
geomitem.create = PRO_B_TRUE;
geomitem.type = PRO_ANALYSIS_CSYS;
if(!names_only)
{
ProArrayAlloc(1, sizeof(ProAnalysisEntity), 1,
(ProArray*)&geomitem.shapes);
memcpy(geomitem.shapes[0].csys.origin, data->csysdata.origin,
sizeof(ProVector));
memcpy(geomitem.shapes[0].csys.x_vector, data->csysdata.x_vector,
sizeof(ProVector));
memcpy(geomitem.shapes[0].csys.y_vector, data->csysdata.y_vector,
sizeof(ProVector));
memcpy(geomitem.shapes[0].csys.z_vector, data->csysdata.z_vector,
sizeof(ProVector));
}
/*--------------------------------------------------------------------*\
Output the csys geometry description
\*--------------------------------------------------------------------*/
ProArrayAlloc(0, sizeof(ProAnalysisGeomitem), 1, (ProArray*)geometry);
ProArrayObjectAdd((ProArray*)geometry, -1, 1, &geomitem);
return(PRO_TK_NO_ERROR);
}
int UsrExtAnalysisRegister ()
{
ProAnalysisFuncsData data;
ProStringToWstring(msgfil,"umsg.txt");
/*--------------------------------------------------------------------*\
Build the description of the surface csys analysis feature
data, and register it with Pro/E
\*--------------------------------------------------------------------*/
memset(&data, '\0', sizeof(ProAnalysisFuncsData));
ProStringToWstring(data.type, "Surface Csys");
data.ui_action = UsrSurfcsysUiAction;
data.dims_action = UsrSurfcsysDimsAction;
data.infoalloc_action = UsrSurfcsysInfoallocAction;
data.infofree_action = UsrSurfcsysInfofreeAction;
data.compcheck_action = UsrSurfcsysCompcheckAction;
data.compute_action = UsrSurfcsysComputeAction;
data.display_action = UsrSurfcsysDisplayAction;
data.output_action = UsrSurfcsysOutputAction;
data.savecheck_action = UsrSurfcsysSavecheckAction;
data.infosave_action = UsrSurfcsysInfosaveAction;
data.inforetrieve_action = UsrSurfcsysInforetrieveAction;
data.infocopy_action = UsrSurfcsysInfocopyAction;
data.result_action = UsrSurfcsysResultAction;
ProAnalysisTypeRegister(&data);
return(0);
}
/*====================================================================*\
FUNCTION : UsrPointPtypeGet()
PURPOSE : Utility to get the placement type of a datum point
\*====================================================================*/
int UsrPointPtypeGet(
ProSolid owner,
ProPoint p,
ProDtmpntType *ptype)
{
ProElempathItem items[5];
ProElempath epath;
ProValue value;
ProValueData vdata;
int id;
ProGeomitem geomitem;
ProFeature feature;
/*--------------------------------------------------------------------*\
Get the feature that owns the point
\*--------------------------------------------------------------------*/
ProPointIdGet(p, &id);
ProModelitemInit(owner, id, PRO_POINT, &geomitem);
ProGeomitemFeatureGet(&geomitem, &feature);
/*--------------------------------------------------------------------*\
Get the placement type from the element tree
\*--------------------------------------------------------------------*/
items[0].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
items[0].path_item.elem_id = PRO_E_DPOINT_POINTS_ARRAY;
items[1].type = PRO_ELEM_PATH_ITEM_TYPE_INDEX;
items[1].path_item.elem_index = 0;
items[2].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
items[2].path_item.elem_id = PRO_E_DPOINT_PLA_CONSTRAINTS;
items[3].type = PRO_ELEM_PATH_ITEM_TYPE_INDEX;
items[3].path_item.elem_index = 0;
items[4].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
items[4].path_item.elem_id = PRO_E_DPOINT_PLA_CONSTR_TYPE;
ProElempathAlloc(&epath);
ProElempathDataSet(epath, items, 5);
if(ProFeatureElemValueGet(&feature, epath, &value) != PRO_TK_NO_ERROR)
return(0);
if(ProValueDataGet(value, &vdata) != PRO_TK_NO_ERROR)
return(0);
*ptype = (ProDtmpntType)vdata.v.i;
return(1);
}
/*====================================================================*\
FUNCTION : UsrPointSrfGet()
PURPOSE : Utility to get the surface a datum point is placed on.
\*====================================================================*/
int UsrPointSrfGet(
ProSelection point,
ProSurface *surface)
{
ProElempathItem items[5];
ProElempath epath;
ProValue value;
ProValueData vdata;
int id;
ProGeomitem geomitem;
ProFeature feature;
ProSelection sel;
/*--------------------------------------------------------------------*\
Get the feature that owns the datum point
\*--------------------------------------------------------------------*/
ProSelectionModelitemGet(point, &geomitem);
ProGeomitemFeatureGet(&geomitem, &feature);
/*--------------------------------------------------------------------*\
Get the surface from the element tree
\*--------------------------------------------------------------------*/
items[0].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
items[0].path_item.elem_id = PRO_E_DPOINT_POINTS_ARRAY;
items[1].type = PRO_ELEM_PATH_ITEM_TYPE_INDEX;
items[1].path_item.elem_index = 0;
items[2].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
items[2].path_item.elem_id = PRO_E_DPOINT_PLA_CONSTRAINTS;
items[3].type = PRO_ELEM_PATH_ITEM_TYPE_INDEX;
items[3].path_item.elem_index = 0;
items[4].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
items[4].path_item.elem_id = PRO_E_DPOINT_PLA_CONSTR_REF;
ProElempathAlloc(&epath);
ProElempathDataSet(epath, items, 5);
if(ProFeatureElemValueGet(&feature, epath, &value) != PRO_TK_NO_ERROR)
return(0);
if(ProValueDataGet(value, &vdata) != PRO_TK_NO_ERROR)
return(0);
sel = (ProSelection)vdata.v.r;
ProSelectionModelitemGet(sel, &geomitem);
ProSurfaceInit(geomitem.owner, geomitem.id, surface);
return(1);
}
/*====================================================================*\
FUNCTION : UsrYesnoGet()
PURPOSE : Prompt for a yes/no answer
\*====================================================================*/
ProError UsrYesnoGet(
wchar_t *msgfil,
char *def, /* INPUT : default answer */
ProBoolean *yes)/* Output: TRUE = yes, FALSE no */
{
wchar_t wreply[4];
char reply[4];
ProError status;
while(1)
{
/*--------------------------------------------------------------------*\
Read string from keyboard
\*--------------------------------------------------------------------*/
status = ProMessageStringRead(4, wreply);
if(status == PRO_TK_MSG_USER_QUIT)
return(PRO_TK_MSG_USER_QUIT);
/*--------------------------------------------------------------------*\
Convert reply (or default) to uppercase C string
\*--------------------------------------------------------------------*/
if(status == PRO_TK_NO_ERROR)
ProWstringToString(reply,wreply);
else
strcpy(reply, def);
ProUtilStringUpper(reply,reply);
/*--------------------------------------------------------------------*\
Output response
\*--------------------------------------------------------------------*/
if(reply[0] == 'Y')
{
*yes = PRO_B_TRUE;
return(PRO_TK_NO_ERROR);
}
if(reply[0] == 'N')
{
*yes = PRO_B_FALSE;
return(PRO_TK_NO_ERROR);
}
/*--------------------------------------------------------------------*\
If reply was neither yes or no, ask again.
\*--------------------------------------------------------------------*/
ProMessageDisplay(msgfil,"USER Please answer Y or N : ");
}
}
#define CLASS_NAME "SURFCSYS"
/*====================================================================*\
FUNCTION : UsrOutwardsSave()
PURPOSE : Save the "outwards" flag to external data
\*====================================================================*/
int UsrOutwardsSave(
ProFeature *feature,
ProBoolean outwards)
{
ProExtdataClass class;
ProCharName slotname;
if(!UsrClassRegister(feature->owner, &class))
return(0);
ProTKSprintf(slotname,"OUTWARDS_%d",feature->id);
UsrIntegerSave(&class, slotname, (int)outwards);
return(1);
}
/*====================================================================*\
FUNCTION : UsrOutwardsRetrieve()
PURPOSE : Retrieve the outwards flag from external data
\*====================================================================*/
int UsrOutwardsRetrieve(
ProFeature *feature,
ProBoolean *outwards)
{
ProExtdataClass class;
ProCharName slotname;
int i;
if(!UsrClassExists(feature->owner, CLASS_NAME, &class))
return(0);
ProTKSprintf(slotname,"OUTWARDS_%d",feature->id);
if(!UsrIntegerRetrieve(&class, slotname, &i))
return(0);
*outwards = i==0 ? PRO_B_FALSE : PRO_B_TRUE;
return(1);
}
/*====================================================================*\
FUNCTION : UsrClassRegister()
PURPOSE : Register a data class, if it does not already exist
\*====================================================================*/
int UsrClassRegister(
ProMdl model,
ProExtdataClass *class)
{
ProName cname;
if(!UsrClassExists(model, CLASS_NAME, class))
{
ProStringToWstring(cname, CLASS_NAME);
if(ProExtdataClassRegister(model, cname, class) !=
PROEXTDATA_TK_NO_ERROR)
return(0);
}
return(1);
}
/*====================================================================*\
FUNCTION : UsrIntegerSave()
PURPOSE : Utility to save an integer slot
\*====================================================================*/
int UsrIntegerSave(
ProExtdataClass *class,
char *slotname,
int i)
{
ProExtdataSlot slot;
ProName sname;
/*--------------------------------------------------------------------*\
If the specified slot does not exist, create it
\*--------------------------------------------------------------------*/
ProStringToWstring(sname, slotname);
if(ProExtdataSlotCreate(class, sname, &slot) !=
PROEXTDATA_TK_NO_ERROR)
{
slot.p_class = class;
ProStringToWstring(slot.slot_name, slotname);
}
/*--------------------------------------------------------------------*\
Write the integer to the data slot
\*--------------------------------------------------------------------*/
ProExtdataSlotWrite(&slot, KEY_BY_NAME, PRO_INTEGER_TYPE, 0, &i);
return(1);
}
/*====================================================================*\
FUNCTION : UsrIntegerRetrieve()
PURPOSE : Retrieve an integer
\*====================================================================*/
int UsrIntegerRetrieve(
ProExtdataClass *class,
char *slotname,
int *i)
{
ProExtdataSlot slot;
int *data;
int size, type;
/*--------------------------------------------------------------------*\
Read the integer from the data slot
\*--------------------------------------------------------------------*/
slot.p_class = class;
ProStringToWstring(slot.slot_name, slotname);
if(ProExtdataSlotRead(&slot, KEY_BY_NAME, &type, &size, (void**)&data)
!= PROEXTDATA_TK_NO_ERROR)
return(0);
*i = *data;
return(1);
}
/*====================================================================*\
FUNCTION : UsrClassExists
PURPOSE : Check if the specified class exists
\*====================================================================*/
int UsrClassExists(
ProMdl model,
char *name,
ProExtdataClass *class)
{
ProExtdataErr status;
int n_classes, c;
ProName *classes;
status = ProExtdataClassNamesList(model, &n_classes, &classes);
if(status != PROEXTDATA_TK_NO_ERROR)
return(0);
for(c=0;c<n_classes;c++)
{
if(!ProUtilStrwscmp(name, classes[c]))
{
class->p_model = model;
ProStringToWstring(class->class_name, name);
ProArrayFree((ProArray *)&classes);
return(1);
}
}
ProArrayFree((ProArray *)&classes);
return(0);
}