/*
Copyright (c) 2019 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved.
*/
/*--------------------------------------------------------------------*\
Pro/Toolkit includes
\*--------------------------------------------------------------------*/
#include <ProToolkit.h>
#include <ProMdl.h>
#include <ProMenuBar.h>
#include <ProArray.h>
#include <ProObjects.h>
#include <ProSurfacedata.h>
#include <ProSurface.h>
#include <ProAxis.h>
#include <ProDtmAxis.h>
#include <ProElemId.h>
#include <ProValue.h>
#include <ProElement.h>
#include <ProFeature.h>
#include <ProFeatType.h>
#include <ProFeatType.h>
#include <ProSelection.h>
#include <ProElempath.h>
#include <ProAsmcomp.h>
#include <ProGroup.h>
#include <math.h>
#include <ProTKRunTime.h>
typedef struct auto_srf_data
{
ProSurface rev_srf;
int axis_id;
double diameter;
} Auto_srf_data;
typedef struct auto_axis_pnts
{
Pro3dPnt p1;
Pro3dPnt p2;
} Axis_p12;
typedef struct auto_srfs_data
{
int total_srfs;
int num_rev_srfs;
Auto_srf_data *srfs_array;
int num_axes;
Axis_p12 *axes_pnts;
int axes_created;
ProMdl owner;
} Auto_srfs_data;
/* Signals that a representative axis was already found for this "hole" */
#define AXIS_ALT_FOUND -5
/*--------------------------------------------------------------------*\
PROTOTYPES OF LOCAL FUNCTIONS
\*--------------------------------------------------------------------*/
ProError AutoaxisMain( ProMdl imported_model );
ProError AutoaxisCollectAxes ( ProAxis axis,
ProError status,
ProAppData app_data );
ProError AutoaxisCollectRevSurfaces ( ProSurface p_surface,
ProError status,
ProAppData app_data );
ProError AutoaxisSurfaceFilter( ProSurface p_surface,
ProAppData app_data );
ProError AutoaxisElementAdd( ProElemId id, ProElement *parent,
ProValueData *elem_data, ProElement *elem );
ProError AutoaxisSurfaceAxisCreate( Auto_srfs_data *srfs,
ProSurface surface, int* axis_id);
ProError AutoaxisSurfaceCheckAxis( ProSurface p_surface,
Axis_p12 *p12 );
ProError AutoaxisGeomVisitAction ( ProGeomitem *p_geomitem,
ProError err,
ProAppData app_data) ;
ProError AutoaxisCheckAxis( ProSurface surface ,
Auto_srfs_data *srfs );
/*--------------------------------------------------------------------*\
USER INTRFACE
\*--------------------------------------------------------------------*/
static uiCmdAccessState TestAccessDefault(uiCmdAccessMode access_mode)
{
return (ACCESS_AVAILABLE);
}
/*====================================================================*\
FUNCTION : user_initialize()
PURPOSE :
\*====================================================================*/
int user_initialize(
int argc,
char *argv[],
char *version,
char *build,
wchar_t errbuf[80])
{
uiCmdCmdId cmd_id;
ProError status;
int RunAutoAxis( );
status = ProCmdActionAdd("AutoAxis", (uiCmdCmdActFn)RunAutoAxis,
uiProe2ndImmediate, TestAccessDefault,
PRO_B_TRUE, PRO_B_TRUE, &cmd_id);
status = ProMenubarmenuPushbuttonAdd(
"Applications", "AutoAxis", "AutoAxis", "Creates axes in the model",
NULL, PRO_B_FALSE, cmd_id, L"usrmsg.txt");
return (0);
}
/*====================================================================*\
FUNCTION : user_terminate()
PURPOSE : To handle any termination actions
\*====================================================================*/
void user_terminate()
{
}
int RunAutoAxis( )
{
ProMdl cur_mdl;
ProError status;
status = ProMdlCurrentGet( &cur_mdl);
if ( status == PRO_TK_NO_ERROR )
{
status = AutoaxisMain(cur_mdl);
}
return 0;
}
/*--------------------------------------------------------------------*\
--------------------------------------------------------------------
FUNCTION DEFINITIONS
--------------------------------------------------------------------
\*--------------------------------------------------------------------*/
/*====================================================*\
Function : AutoaxisSurfaceCheckAxis()
Purpose : To check if any axis exists which can be
related to given surface.
\*====================================================*/
ProError AutoaxisSurfaceCheckAxis( ProSurface p_surface, Axis_p12 *p12)
{
ProError status;
ProGeomitemdata *gitem_data;
ProSrftype srftype;
ProUvParam uv_min, uv_max;
ProSurfaceOrient s_orient;
ProSurfaceshapedata s_shapedata;
ProVector e1, e2, e3;
Pro3dPnt origin;
ProCurvedata cur1;
double rad1, alpha;
int s_id;
double epsilan;
double a,b,c;
double x01,y01,z01;
double det1,det2,det3;
double cp,dist,abc;
ProVector a_v;
ProError axis_stat;
if ( p_surface == NULL || p12 == NULL )
return PRO_TK_BAD_INPUTS;
gitem_data = NULL;
epsilan = 0.00000001; /* Value is enough ? */
axis_stat = PRO_TK_E_NOT_FOUND;
status = ProSurfaceDataGet(p_surface, &gitem_data);
if ( status == PRO_TK_NO_ERROR )
{
status = ProSurfacedataGet( gitem_data->data.p_surface_data,
&srftype, uv_min, uv_max, &s_orient,
&s_shapedata, &s_id);
if ( status == PRO_TK_NO_ERROR )
{
switch(srftype)
{
case PRO_SRF_CYL:
status = ProCylinderdataGet( &s_shapedata, e1, e2, e3,
origin, &rad1);
break;
case PRO_SRF_CONE:
status = ProConedataGet( &s_shapedata, e1, e2, e3, origin,
&alpha);
break;
case PRO_SRF_REV:
status = ProSrfrevdataGet( &s_shapedata, e1, e2, e3, origin,
&cur1);
break;
default :
ProTKPrintf("Not a Rev. Type surface..\n");
}
}
}
if ( status == PRO_TK_NO_ERROR )
{
/* To find collinearity between exsting axis with
axis to be created using the given surface.
1. Data available from axis ( p1,p2 )
2. Data available from surface Origin(x0,y0,z0) and Vectors(X,Y,Z)
Assumption is made that the axis will be always
coincident/parallel with Z vector of the surface.
In this scenario, the condition for being parallel
and coincident vectors,
a) Cross product must be zero, ( Axis x Z = 0 )
b) The distance between the Axis and O(origin) of the surface
must be zero
If above two conditions are true, no axis will be created because
one already exists.
*/
/* Axis from p1,p2 */
/* In vector form (a,b,c) */
a = p12->p1[0] - p12->p2[0] ;
b = p12->p1[1] - p12->p2[1] ;
c = p12->p1[2] - p12->p2[2] ;
abc = sqrt ( a*a + b*b + c*c );
/* Unit vector along axis */
a_v[0] = a/abc ;
a_v[1] = b/abc ;
a_v[2] = c/abc ;
/* Cross Product ( Axis x Z_vec ) */
cp = a_v[1]*e3[2] - a_v[2]*e3[1] ;
cp += a_v[2]*e3[0] - a_v[0]*e3[2] ;
cp += a_v[0]*e3[1] - a_v[1]*e3[0] ;
if ( cp <= epsilan )
{
/* Distance between origin an Axis */
x01 = origin[0] - p12->p1[0] ;
y01 = origin[1] - p12->p1[1] ;
z01 = origin[2] - p12->p1[2] ;
det1 = c*y01 - b*z01 ;
det2 = a*z01 - c*x01 ;
det3 = b*x01 - a*y01 ;
/*
Actual formula for Shortest Distace to a line( Localized vector)
from a point.
dist = sqrt (( det1*det1 + det2*det2 + det3*det3 )
/ ( a*a + b*b + c*c ) ) ;
But denominator can be ignored .
*/
dist = det1*det1 + det2*det2 + det3*det3 ;
if ( dist <= epsilan )
{
axis_stat = PRO_TK_E_FOUND;
}
else
{
axis_stat = PRO_TK_E_NOT_FOUND;
}
}
}
if( gitem_data != NULL )
{
ProGeomitemdataFree( &gitem_data );
}
return axis_stat;
}
/*====================================================*\
Function : AutoaxisSurfaceIsHole()
Purpose : Determine if the surface is likely a part of a "hole" that needs
an axis.
\*====================================================*/
ProBoolean AutoaxisSurfaceIsHole (ProSolid solid, ProSurface surface)
{
ProError status;
ProSurface* same_surfs;
int n_same_surfs;
/*-----------------------------------------------------*\
Determine if the surface has a matching surface
(typically the other half of a split cylinder or cone).
\*-----------------------------------------------------*/
ProArrayAlloc (0, sizeof (ProSurface), 1, (ProArray*)&same_surfs);
status = ProSurfaceSameSrfsFind (solid,
surface,
&same_surfs,
&n_same_surfs);
ProArrayFree ((ProArray*)&same_surfs);
if (status == PRO_TK_NO_ERROR && n_same_surfs > 1)
return PRO_B_TRUE;
else
return PRO_B_FALSE;
}
/*====================================================*\
Function : AutoaxisSurfaceFilter()
Purpose : Filter function for ProSolidSurfaceVisit
\*====================================================*/
ProError AutoaxisSurfaceFilter( ProSurface p_surface, ProAppData app_data )
{
ProSrftype surface_type;
ProError status;
Auto_srfs_data *data;
ProFeattype ftype;
ProFeature feature;
ProGeomitem geom;
int s_id;
status = PRO_TK_NO_ERROR;
data = (Auto_srfs_data *)app_data;
data->total_srfs++;
status = ProSurfaceIdGet ( p_surface, &s_id );
if(status == PRO_TK_NO_ERROR)
{
geom.id = s_id;
geom.owner = data->owner;
geom.type = PRO_SURFACE;
}
if(status == PRO_TK_NO_ERROR)
status = ProSurfaceTypeGet ( p_surface, &surface_type);
if ( status == PRO_TK_NO_ERROR &&
( surface_type == PRO_SRF_CYL ||
surface_type == PRO_SRF_CONE ||
surface_type == PRO_SRF_REV ) &&
AutoaxisSurfaceIsHole (data->owner, p_surface) )
{
return PRO_TK_NO_ERROR ;
}
return PRO_TK_CONTINUE;
}
/*====================================================*\
Function : AutoaxisAddSortedSurface()
Purpose : Add the given surface to the surface array,
in a position sorted
by diameter (largest to smallest). Non-cylindrical
surfaces are added to the end of the array.
\*====================================================*/
ProError AutoaxisAddSortedSurface (Auto_srfs_data* data,
Auto_srf_data* srf)
{
int num_srfs = data->num_rev_srfs;
int i;
ProSurface current_srf;
ProSrftype surface_type;
double current_diam = 0.0;
ProError status;
ProUvParam param = {0.0, 0.0};
status = ProSurfaceTypeGet ( srf->rev_srf, &surface_type);
if (surface_type == PRO_SRF_CYL)
{
ProSurfaceDiameterEval (srf->rev_srf, param, &srf->diameter);
}
else
srf->diameter = -1.0;
if (num_srfs == 0)
{
ProArrayObjectAdd ((ProArray*)&data->srfs_array,
PRO_VALUE_UNUSED, 1, srf);
data->num_rev_srfs++;
}
else
{
for (i = 0; i < num_srfs; i++)
{
current_srf = data->srfs_array[i].rev_srf;
current_diam = data->srfs_array[i].diameter;
/* If its bigger than this surface, add it to the array just
before */
if (srf->diameter > current_diam)
{
ProArrayObjectAdd ((ProArray*)&data->srfs_array,
i, 1, srf);
data->num_rev_srfs++;
break;
}
/* If its smaller than all other surfaces, add it to the end
of the array */
if (i == num_srfs - 1)
{
ProArrayObjectAdd ((ProArray*)&data->srfs_array,
PRO_VALUE_UNUSED, 1, srf);
data->num_rev_srfs++;
}
}
}
return PRO_TK_NO_ERROR;
}
/*====================================================*\
Function : AutoaxisCollectRevSurfaces()
Purpose : Action function for ProSolidSurfaceVisit
Collects revolved surfaces
\*====================================================*/
ProError AutoaxisCollectRevSurfaces ( ProSurface p_surface,
ProError status,
ProAppData app_data )
{
ProError err;
int srf_id;
Auto_srf_data srf;
Auto_srfs_data *data;
data = (Auto_srfs_data *)app_data;
if ( status == PRO_TK_NO_ERROR )
{
err = PRO_TK_NO_ERROR ;
srf_id = 0;
err = ProSurfaceIdGet ( p_surface, &srf_id);
if ( err == PRO_TK_NO_ERROR )
{
srf.axis_id = PRO_VALUE_UNUSED ;
err = ProSurfaceInit ( data->owner, srf_id, &srf.rev_srf);
if ( err == PRO_TK_NO_ERROR )
{
err = AutoaxisAddSortedSurface (data, &srf);
}
}
}
return status;
}
/*====================================================*\
Function : AutoaxisCollectQuiltSurfaces()
Purpose : Action function for ProSolidQuiltVisit
Collects the rev surfaces in the model.
\*====================================================*/
ProError AutoaxisCollectQuiltSurfaces ( ProQuilt p_quilt,
ProError status,
ProAppData app_data )
{
ProError err;
if ( status == PRO_TK_NO_ERROR )
{
err = ProQuiltSurfaceVisit( p_quilt,AutoaxisCollectRevSurfaces,
AutoaxisSurfaceFilter,app_data );
}
return err;
}
/*====================================================*\
Function : AutoaxisCollectAxes()
Purpose : Action function for ProSolidAxisVisit
Collects the axes in the model.
\*====================================================*/
ProError AutoaxisCollectAxes ( ProAxis axis,
ProError status,
ProAppData app_data )
{
ProError err;
Auto_srfs_data *data;
Axis_p12 pnts;
ProGeomitemdata *a_gitem_data;
a_gitem_data = NULL;
data = ( Auto_srfs_data * ) app_data;
err = ProAxisDataGet(axis, &a_gitem_data);
if ( err == PRO_TK_NO_ERROR && a_gitem_data != NULL )
{
err = ProLinedataGet( a_gitem_data->data.p_curve_data,
pnts.p1, pnts.p2);
}
if ( err == PRO_TK_NO_ERROR )
{
err = ProArrayObjectAdd ((ProArray*)&data->axes_pnts,
PRO_VALUE_UNUSED, 1, &pnts);
if ( err == PRO_TK_NO_ERROR )
{
data->num_axes++;
}
}
if( a_gitem_data != NULL )
{
ProGeomitemdataFree( &a_gitem_data );
}
return status;
}
/*====================================================*\
Function : AutoaxisElementAdd()
Purpose : Adds elem to parent
\*====================================================*/
ProError AutoaxisElementAdd( ProElemId id, ProElement *parent,
ProValueData *elem_data, ProElement *elem )
{
ProValue value ;
ProError status = PRO_TK_NOT_VALID ;
if ( elem_data == NULL || elem == NULL || parent == NULL )
return PRO_TK_BAD_INPUTS ;
status = ProElementAlloc(id, elem) ;
if ( status != PRO_TK_NO_ERROR )
return status;
status = ProValueAlloc (&value) ;
if ( status == PRO_TK_NO_ERROR )
status = ProValueDataSet (value, elem_data) ;
if ( status == PRO_TK_NO_ERROR )
status = ProElementValueSet (*elem, value) ;
if ( elem_data != NULL && status != PRO_TK_NO_ERROR )
return status;
status = ProElemtreeElementAdd( *parent, NULL, *elem ) ;
return status;
}
/*====================================================*\
Function : AutoaxisGeomVisitAction()
Purpose : Collects end points of an axis
\*====================================================*/
ProError AutoaxisGeomVisitAction ( ProGeomitem *p_geomitem,
ProError err,
ProAppData app_data)
{
ProError status;
Auto_srfs_data *data;
Axis_p12 pnts;
ProGeomitemdata *a_gitem_data;
ProAxis axis;
if ( app_data == NULL )
return PRO_TK_BAD_INPUTS;
status = PRO_TK_NO_ERROR;
a_gitem_data = NULL;
data = (Auto_srfs_data*) app_data;
if ( status == PRO_TK_NO_ERROR )
status = ProGeomitemToAxis(p_geomitem, &axis);
if ( status == PRO_TK_NO_ERROR )
status = ProAxisDataGet(axis, &a_gitem_data);
if ( status == PRO_TK_NO_ERROR && a_gitem_data != NULL )
{
status = ProLinedataGet( a_gitem_data->data.p_curve_data,
pnts.p1, pnts.p2);
}
if ( status == PRO_TK_NO_ERROR )
{
status = ProArrayObjectAdd ((ProArray*)&data->axes_pnts,
PRO_VALUE_UNUSED, 1, &pnts);
if ( status == PRO_TK_NO_ERROR )
{
data->axes_created++ ;
}
}
if( a_gitem_data != NULL )
{
ProGeomitemdataFree( &a_gitem_data );
}
return err;
}
/*====================================================*\
Function : AutoaxisSurfaceAxisCreate()
Purpose : Creates axis for given revolve surface
\*====================================================*/
ProError AutoaxisSurfaceAxisCreate( Auto_srfs_data *srfs,
ProSurface surface, int* axis_id)
{
ProValueData value_data;
ProElement root_tree, feat_type;
ProElement cnstrnts, cnstrnt;
ProElement cnstrnt_type, cnstrnt_ref;
ProElemId elemid;
ProError status;
ProFeature feature;
ProFeatureCreateOptions opts[1];
ProModelitem modelitem;
ProSelection mdl_sel;
ProErrorlist errors;
ProGeomitem rev_srf;
ProSelection rev_srf_sel;
int srf_id;
ProMdl model;
if ( srfs == NULL || surface == NULL )
return PRO_TK_BAD_INPUTS;
status = PRO_TK_NO_ERROR;
srf_id = -1;
mdl_sel = NULL;
rev_srf_sel = NULL;
root_tree = NULL;
model = srfs->owner ;
status = ProSurfaceIdGet (surface, &srf_id);
if ( status == PRO_TK_NO_ERROR && srf_id )
{
rev_srf.owner = model ;
rev_srf.id = srf_id ;
rev_srf.type = PRO_SURFACE ;
status = ProSelectionAlloc(NULL, &rev_srf, &rev_srf_sel);
if ( status != PRO_TK_NO_ERROR )
return status;
}
/*---------------------------------------------------------------------------*\
Prepare element tree for Axis Feature
\*---------------------------------------------------------------------------*/
status = ProElementAlloc(PRO_E_FEATURE_TREE, &root_tree);
elemid = PRO_E_FEATURE_TYPE ;
value_data.type = PRO_VALUE_TYPE_INT;
value_data.v.i = PRO_FEAT_DATUM_AXIS ;
status = AutoaxisElementAdd(elemid, &root_tree,&value_data,
&feat_type);
elemid = PRO_E_DTMAXIS_CONSTRAINTS ;
status = ProElementAlloc(elemid, &cnstrnts );
status = ProElemtreeElementAdd(root_tree, NULL, cnstrnts );
elemid = PRO_E_DTMAXIS_CONSTRAINT ;
status = ProElementAlloc(elemid, &cnstrnt );
status = ProElemtreeElementAdd(cnstrnts, NULL, cnstrnt );
elemid = PRO_E_DTMAXIS_CONSTR_TYPE ;
value_data.type = PRO_VALUE_TYPE_INT;
value_data.v.i = PRO_DTMAXIS_CONSTR_TYPE_THRU ;
status = AutoaxisElementAdd(elemid, &cnstrnt,&value_data,
&cnstrnt_type);
if ( rev_srf_sel != NULL )
{
elemid = PRO_E_DTMAXIS_CONSTR_REF ;
value_data.type = PRO_VALUE_TYPE_SELECTION;
value_data.v.r = rev_srf_sel ;
status = AutoaxisElementAdd(elemid, &cnstrnt,&value_data,
&cnstrnt_ref);
}
status = ProMdlToModelitem(model, &modelitem);
if ( status == PRO_TK_NO_ERROR )
status = ProSelectionAlloc(NULL, &modelitem, &mdl_sel);
opts[0] = PRO_FEAT_CR_NO_OPTS;
if ( status == PRO_TK_NO_ERROR )
{
status = ProFeatureCreate(mdl_sel, root_tree, opts, 1, &feature,
&errors);
}
if ( status == PRO_TK_NO_ERROR )
{
*axis_id = feature.id;
/* Collect the axis end points.
This is to avoid visiting it
again while creating another axis.
*/
ProFeatureGeomitemVisit( &feature, PRO_AXIS,
AutoaxisGeomVisitAction,
NULL,(ProAppData)srfs);
}
if( rev_srf_sel != NULL )
ProSelectionFree(&rev_srf_sel);
if( rev_srf_sel != NULL )
ProSelectionFree(&mdl_sel);
if( root_tree != NULL )
ProElementFree( &root_tree);
return status;
}
/*====================================================*\
Function : AutoaxisCheckAxis()
Purpose : Checks existance of any axis related to
given surface
\*====================================================*/
ProError AutoaxisCheckAxis( ProSurface surface, Auto_srfs_data *srfs )
{
ProError status;
int i,total_axes;
if ( surface == NULL || srfs == NULL )
return PRO_TK_BAD_INPUTS;
status = PRO_TK_E_NOT_FOUND ;
total_axes = srfs->num_axes + srfs->axes_created ;
for ( i = 0 ; i < total_axes ; i++ )
{
status = AutoaxisSurfaceCheckAxis ( surface, &srfs->axes_pnts[i] );
if ( status == PRO_TK_E_FOUND )
return status;
}
return PRO_TK_E_NOT_FOUND;
}
/*====================================================*\
Function : AutoaxisAxesCreate()
Purpose : Creates axes for revolve surfaces
\*====================================================*/
ProError AutoaxisAxesCreate( Auto_srfs_data *surfaces)
{
ProError status;
int j, axis_id = PRO_VALUE_UNUSED;
for ( j = 0; j < surfaces->num_rev_srfs ; j++ )
{
if( surfaces->srfs_array[j].axis_id != PRO_VALUE_UNUSED &&
surfaces->srfs_array[j].axis_id != AXIS_ALT_FOUND)
continue;
/* Any axis exists ? */
status = AutoaxisCheckAxis ( surfaces->srfs_array[j].rev_srf,
surfaces );
if ( status == PRO_TK_E_FOUND )
{
surfaces->srfs_array[j].axis_id = AXIS_ALT_FOUND;
continue;
}
status = AutoaxisSurfaceAxisCreate( surfaces,
surfaces->srfs_array[j].rev_srf, &axis_id);
if ( status == PRO_TK_NO_ERROR )
{
surfaces->srfs_array[j].axis_id = axis_id;
}
}
return status;
}
/*====================================================*\
Function : AutoaxisAsmComponent()
Purpose : Action function for components
This is to run AutoAxis on Asm Comps.
\*====================================================*/
ProError AutoaxisAsmComponent ( ProFeature *p_feature, ProError status,
ProAppData app_data )
{
ProMdl p_mdl;
status = ProAsmcompMdlGet ((ProAsmcomp *)p_feature, &p_mdl);
if ( status == PRO_TK_NO_ERROR )
status = AutoaxisMain(p_mdl);
return status;
}
/*====================================================*\
Function : AutoaxisAsmcompFilter()
Purpose : Filter function for components
\*====================================================*/
ProError AutoaxisAsmcompFilter ( ProFeature* p_feature,
ProAppData app_data )
{
ProError status;
ProFeattype ftype;
ProMdl p_mdl;
ProMdlType p_type;
status = ProFeatureTypeGet(p_feature, &ftype);
if ( status == PRO_TK_NO_ERROR && ftype == PRO_FEAT_COMPONENT)
{
status = ProAsmcompMdlGet ((ProAsmcomp *)p_feature, &p_mdl);
if ( status == PRO_TK_NO_ERROR )
{
status = ProMdlTypeGet (p_mdl, &p_type);
if ( status == PRO_TK_NO_ERROR )
{
if (p_type == PRO_MDL_ASSEMBLY || p_type == PRO_MDL_PART)
{
return(PRO_TK_NO_ERROR);
}
}
}
}
return PRO_TK_CONTINUE;
}
/*====================================================*\
Function : AutoaxisGroupCreate
Purpose : Create group of axes that go to matching diameter holes.
\*====================================================*/
ProError AutoaxisGroupCreate (ProSolid owner, double target_diameter,
int* feat_ids)
{
int num_feats;
ProCharName name_buff;
ProName name;
ProGroup group;
ProArraySizeGet (feat_ids, &num_feats);
if (target_diameter > 0.0)
{
ProTKSprintf (name_buff, "AXES_DIAM_%.1lf", target_diameter);
ProStringToWstring (name, name_buff);
}
else
{
ProTKSprintf (name_buff, "AXES_NOT_CYLINDRICAL");
ProStringToWstring (name, name_buff);
}
ProLocalGroupCreate (owner, feat_ids, num_feats, name, &group);
return (PRO_TK_NO_ERROR);
}
#define D_EPS 0.1
/*====================================================*\
Function : AutoaxisAxesGroup
Purpose : Group axes by diameter.
\*====================================================*/
ProError AutoaxisAxesGroup ( Auto_srfs_data* data )
{
int i, num_feats, current_id;
int num_srfs = data->num_rev_srfs;
int* feat_ids = NULL;
double target_diameter = -1.0;
double current_diameter;
for (i = 0; i < num_srfs; i++)
{
current_diameter = data->srfs_array [i].diameter;
current_id = data->srfs_array[i].axis_id;
/* For the first surface found */
if (feat_ids == NULL)
{
target_diameter = current_diameter;
/* if (target_diameter > 0.0) */
if (current_id > 0)
{
ProArrayAlloc (1, sizeof (int), 1, (ProArray*)&feat_ids);
feat_ids [0] = current_id;
}
}
else
{
/* If there's a true axis assigned to this surface */
if (current_id > 0)
{
/* If the diameter matches the target, add it and
continue */
if (fabs (current_diameter - target_diameter) < D_EPS)
{
ProArrayObjectAdd ((ProArray*)&feat_ids,
PRO_VALUE_UNUSED, 1, ¤t_id);
}
/* Otherwise, process the set of axes in the current group,
and start collecting a new one */
else if (i != num_srfs -1)
{
AutoaxisGroupCreate (data->owner, target_diameter,
feat_ids);
ProArrayFree ((ProArray*)&feat_ids);
target_diameter = current_diameter;
ProArrayAlloc (1, sizeof (int), 1, (ProArray*)&feat_ids);
feat_ids [0] = current_id;
}
}
/* Finish the last group for the last surface */
if (i == num_srfs - 1)
{
AutoaxisGroupCreate (data->owner, target_diameter, feat_ids);
ProArrayFree ((ProArray*)&feat_ids);
}
}
}
return PRO_TK_NO_ERROR;
}
#undef D_EPS
/*====================================================*\
Function : AutoaxisMain()
Purpose : Top level function to
create Axes for Revolved surfaces
\*====================================================*/
ProError AutoaxisMain( ProMdl imported_model )
{
ProError status;
Auto_srfs_data surfaces;
ProMdlType mdl_type;
status = PRO_TK_NO_ERROR;
status = ProMdlTypeGet ( imported_model, &mdl_type);
if ( status != PRO_TK_NO_ERROR ||
(mdl_type != PRO_MDL_PART &&
mdl_type != PRO_MDL_ASSEMBLY &&
mdl_type != PRO_MDL_MFG) )
return PRO_TK_BAD_INPUTS;
if ( status == PRO_TK_NO_ERROR )
{
if ( mdl_type != PRO_MDL_PART )
{
/* In case of assemblies visit all components recursively */
status = ProSolidFeatVisit (( ProSolid )imported_model,
AutoaxisAsmComponent,
AutoaxisAsmcompFilter, NULL ) ;
}
}
surfaces.total_srfs = 0 ;
surfaces.num_rev_srfs = 0 ;
surfaces.srfs_array = NULL ;
surfaces.num_axes = 0 ;
surfaces.axes_pnts = NULL ;
surfaces.axes_created = 0 ;
surfaces.owner = imported_model ;
/* Collect all Axes(End points) in the Model */
status = ProArrayAlloc (0, sizeof (Axis_p12), 1,
(ProArray*)&surfaces.axes_pnts);
if ( status == PRO_TK_NO_ERROR )
{
status = ProSolidAxisVisit( (ProSolid) imported_model,
AutoaxisCollectAxes,
NULL, ( ProAppData ) &surfaces );
}
/* Collect all revolve type surfaces in the Model */
status = ProArrayAlloc (0, sizeof (Auto_srf_data), 1,
(ProArray*)&surfaces.srfs_array);
if ( status == PRO_TK_NO_ERROR )
{
status = ProSolidSurfaceVisit( (ProSolid) imported_model,
AutoaxisCollectRevSurfaces,
AutoaxisSurfaceFilter,
( ProAppData ) &surfaces );
}
status = ProSolidQuiltVisit( (ProSolid) imported_model,
AutoaxisCollectQuiltSurfaces,
NULL, ( ProAppData ) &surfaces );
if ( surfaces.num_rev_srfs > 0 )
{
/* Create and group the axes */
status = AutoaxisAxesCreate( &surfaces );
status = AutoaxisAxesGroup ( &surfaces );
}
ProTKPrintf("\n");
ProTKPrintf("\n**********************************************************");
ProTKPrintf("\n******************* AutoAxis Summary *********************");
ProTKPrintf("\n**********************************************************");
ProTKPrintf("\nTotal Surfaces found = %d",surfaces.total_srfs);
ProTKPrintf("\nRev Surfaces found = %d",surfaces.num_rev_srfs);
ProTKPrintf("\nAxes found = %d",surfaces.num_axes);
ProTKPrintf("\nAxes Created = %d",surfaces.axes_created);
ProTKPrintf("\n**********************************************************");
ProTKPrintf("\n**********************************************************");
ProTKPrintf("\n");
if ( surfaces.axes_pnts != NULL )
{
status = ProArrayFree( ( ProArray *)&surfaces.axes_pnts);
}
if ( surfaces.srfs_array != NULL )
{
status = ProArrayFree( ( ProArray *) &surfaces.srfs_array);
}
return PRO_TK_NO_ERROR;
}