/*
Copyright (c) 2024 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved.
*/
#include <GearDesign.h>
#include <ProToolkit.h>
#include <Pro2dEntdef.h>
#include <ProFeature.h>
#include <ProModelitem.h>
#include <UtilCollect.h>
#include <UtilMath.h>
#include <ProSection.h>
#include "UtilMenu.h"
#include "UtilMessage.h"
#include "TestSect.h"
#include "UtilMessage.h"
#include "TestError.h"
#include "UtilMath.h"
#include "UtilMatrix.h"
#include "UtilCollect.h"
#include "UtilString.h"
#include <ProToolkit.h>
#include <ProObjects.h>
#include <ProSecdim.h>
#include <ProSection.h>
#include <ProMdl.h>
#include <ProMenu.h>
#include <ProEdge.h>
#include <ProGeomitem.h>
#include <ProFeature.h>
#include <ProSelection.h>
#include <ProSurface.h>
#include <ProArray.h>
#include <ProUtil.h>
#include <ProCurve.h>
#include <ProTKRunTime.h>
#include <ProAxis.h>
#define sqr(a) ((a)*(a))
typedef struct feat_by_name_find
{
FeatByName *feats;
int num_feats;
} FeatByNameFind;
static ProError err;
/*=============================================================*\
Function: ProUtilCreateCircleSection
Purpose: Full creating of section with one circle
Return :
\*=============================================================*/
ProError ProUtilCreateCircleSection(
ProSection section, /*In : the section */
Parameter *params) /*In : params [0] - diameter */
/* params [1] - vertical surface */
/* params [2] - vertical surface */
{
Pro2dCircledef circle;
Pro2dEntdef* ent;
Pro2dLinedef* line;
Pro2dPnt point;
int brk=0;
int circle_id, circle_diam, side_id, bot_id;
ProSectionPointType pnt_types[2];
ProError err;
ProWSecerror errors;
do /* Used for exit from the middle of block */
{
/*----------------------------------------------------------*\
Create entities
\*----------------------------------------------------------*/
circle.type = PRO_2D_CIRCLE;
/* Align the X coordinate of the circle with the side datum plane */
err = ProSectionEntityFromProjection(section, params[1].r, &side_id);
err = ProSectionEntityGet (section, side_id, &ent);
line = (Pro2dLinedef*) ent;
circle.center[0] = line->end1 [0];
/* Align the Y coordinate of the circle with the bottom datum plane */
err = ProSectionEntityFromProjection(section, params[2].r, &bot_id);
err = ProSectionEntityGet (section, bot_id, &ent);
line = (Pro2dLinedef*) ent;
circle.center[1] = line->end1 [1];
circle.radius = params[0].d/2;
err = ProSectionEntityAdd(section, (Pro2dEntdef*)&circle, &circle_id);
/*----------------------------------------------------------*\
Add dimensions
\*----------------------------------------------------------*/
/*point[0] = 0.0;
point[1] = params[0].d/2+1;
pnt_types[0] = PRO_ENT_WHOLE;
err =ProSecdimCreate(section, &circle_id, pnt_types, 1,
PRO_TK_DIM_DIA, point, &circle_diam);*/
/*----------------------------------------------------------*\
Solve section
\*----------------------------------------------------------*/
err = ProSecerrorAlloc(&errors);
err = ProSectionAutodim (section, &errors);
err = ProSecerrorFree(&errors);
} while (brk);
return (err);
}
/*=============================================================*\
Function: ProUtilCreateToothSection
Purpose: Full creating of tooth space section
Return :
\*=============================================================*/
ProError ProUtilCreateToothSection(
ProSection section, /*In : the section */
Parameter *params) /*In : params [0] - the module m */
/* params [1] - the number of teeth */
/* params [2] - standart pressure angle */
/* params [3] - gear side surface */
/* params [4] - side datum plane*/
{
Pro2dLinedef line;
Pro2dPnt point, p1, p2, p3;
Pro2dCircledef *p_circle, add_circle, ded_circle, t_circle;
Pro2dArcdef arc;
int dims[2], brk=0, ring_gear, z, arc1_id, arc2_id, d_id;
int circle_id, ded_id;
ProSectionPointType pnt_types[2];
ProError err;
ProWSecerror errors;
double d, r, angle, r_base, r_t, m, an ;
do /* Used for exit from the middle of block */
{
err = ProSectionEntityFromProjection(section, params[3].r, &circle_id);
if(err != PRO_TK_NO_ERROR)
break;
err = ProSectionEntityGet(section, circle_id, (Pro2dEntdef**)&p_circle);
if(err != PRO_TK_NO_ERROR)
break;
m = params[0].d; /* module */
r = p_circle->radius; /* addendum circle radius */
z = params[1].i; /* no. of teeth */
d = params[0].d * z;; /* The Pitch circle radius */
ring_gear = r < d/2;
angle = params[2].d*PI/180;
r_t = d/2 * sin(angle);
r_base = d/2 * cos(angle); /* The base-circle diam */
if (ring_gear)
{
add_circle.radius = r;
ded_circle.radius = d/2 + 1.2*m;
angle = PI/2 + angle - PI/(z*2);
}
else
{
add_circle.radius = r;
ded_circle.radius = d/2 - 1.25*m;
angle = PI/2 - angle - PI/(z*2);
}
add_circle.center[0] = ded_circle.center[0] = p_circle -> center [0];
add_circle.center[1] = ded_circle.center[1] = p_circle -> center [1];
t_circle.center[0] = p_circle -> center [0] + r_base * cos(angle);
t_circle.center[1] = p_circle -> center [1] + r_base * sin(angle);
t_circle.radius = r_t;
ProUtilTwoCircleIntersection(&add_circle, &t_circle, p1, p2);
if (ring_gear)
{
if (p1[0]<p2[0])
memcpy(p1, p2, sizeof(p1));
} else
{
if (p1[0]>p2[0])
memcpy(p1, p2, sizeof(p1));
}
ProUtilTwoCircleIntersection(&ded_circle, &t_circle, p2, p3);
if (ring_gear)
{
if (p2[0]<p3[0])
memcpy(p2, p3, sizeof(p1));
} else
{
if (p2[0]>p3[0])
memcpy(p2, p3, sizeof(p1));
}
/*----------------------------------------------------------*\
Create entities
\*----------------------------------------------------------*/
line.type = PRO_2D_CENTER_LINE;
line.end1[0] = p_circle -> center [0];
line.end1[1] = p_circle -> center [1];
line.end2[0] = p_circle -> center [0];
line.end2[1] = p_circle -> center [1] + r;
err = ProSectionEntityAdd(section, (Pro2dEntdef*)&line, &d_id);
if(err != PRO_TK_NO_ERROR)
break;
arc.type = PRO_2D_ARC;
memcpy(arc.center, t_circle.center, sizeof(arc.center));
arc.start_angle = atan2(p1[1]-arc.center[1], p1[0]-arc.center[0]);
arc.end_angle = atan2(p2[1]-arc.center[1], p2[0]-arc.center[0]);
arc.radius = r_t;
err = ProSectionEntityAdd(section, (Pro2dEntdef*)&arc, &arc1_id);
if(err != PRO_TK_NO_ERROR)
break;
an = PI - arc.start_angle;
arc.start_angle = PI - arc.end_angle;
arc.end_angle = an;
arc.center[0] = (2 * p_circle -> center [0] ) - arc.center[0];
err = ProSectionEntityAdd(section, (Pro2dEntdef*)&arc, &arc2_id);
if(err != PRO_TK_NO_ERROR)
break;
memcpy(arc.center, ded_circle.center, sizeof(arc.center));
arc.start_angle = atan2( p2[1] - arc.center [1], p2[0] - arc.center [0]);
arc.end_angle = PI - arc.start_angle;
arc.radius = ded_circle.radius;
err = ProSectionEntityAdd(section, (Pro2dEntdef*)&arc, &ded_id);
if(err != PRO_TK_NO_ERROR)
break;
/*----------------------------------------------------------*\
Add dimensions
\*----------------------------------------------------------*/
point[0] = p_circle -> center [0];
point[1] = t_circle.center[1] + 1;
pnt_types[0] = PRO_ENT_CENTER;
pnt_types[1] = PRO_ENT_CENTER;
dims[0] = arc1_id;
dims[1] = arc2_id;
err = ProSecdimCreate(section, dims, pnt_types, 2,
PRO_TK_DIM_PNT_PNT_HORIZ, point, &d_id);
if(err != PRO_TK_NO_ERROR)
break;
point[0] = 1.2 * t_circle.center[0];
point[1] = t_circle.center[1]/2;
dims[1] = circle_id;
err = ProSecdimCreate(section, dims, pnt_types, 2,
PRO_TK_DIM_PNT_PNT_VERT, point, &d_id);
if(err != PRO_TK_NO_ERROR)
break;
point[0] = 0;
if (ring_gear)
point[1] = 1.2 * ded_circle.radius;
else
point[1] = 0.8 * ded_circle.radius;
pnt_types[0] = PRO_ENT_WHOLE;
err = ProSecdimCreate(section, &ded_id, pnt_types, 1,
PRO_TK_DIM_RAD, point, &d_id);
if(err != PRO_TK_NO_ERROR)
break;
point[0] = p1[0] * 1.2;
point[1] = p1[1] * 1.2;
err = ProSecdimCreate(section, &arc1_id, pnt_types, 1,
PRO_TK_DIM_RAD, point, &d_id);
if(err != PRO_TK_NO_ERROR)
break;
/*----------------------------------------------------------*\
Solve section
\*----------------------------------------------------------*/
err = ProSecerrorAlloc(&errors);
err = ProSectionSolve(section, &errors);
if (err != PRO_TK_NO_ERROR)
break;
err = ProSecerrorFree(&errors);
} while (brk);
return (err);
}
/*=============================================================*\
Function: ProUtilCreateKeySection
Purpose: Full creating of open section with tree lines
Return :
\*=============================================================*/
ProError ProUtilCreateKeySection(
ProSection section, /*In : the section */
Parameter *params) /*In : params [0] - section width */
/* params [1] - section height */
/* params [2] - cyl surface */
{
Pro2dLinedef line;
Pro2dPnt point;
Pro2dCircledef *p_circle;
int dims[2], brk=0;
int left_id, right_id, top_id, width_id, height_id, circle_id;
ProSectionPointType pnt_types[2];
ProError err;
ProWSecerror errors;
double y, r;
do /* Used for exit from the middle of block */
{
err = ProSectionEntityFromProjection(section, params[2].r, &circle_id);
err = ProSectionEntityGet(section, circle_id, (Pro2dEntdef**)&p_circle);
r = p_circle->radius;
y = sqrt(r*r - params[0].d*params[0].d/4);
/*----------------------------------------------------------*\
Create entities
\*----------------------------------------------------------*/
line.type = PRO_2D_LINE;
line.end1[0] = line.end2[0] = -params[0].d/2;
line.end1[1] = y;
line.end2[1] = r + params[1].d;
err = ProSectionEntityAdd(section, (Pro2dEntdef*)&line, &left_id);
line.end1[0] = line.end2[0] = -line.end1[0];
err = ProSectionEntityAdd(section, (Pro2dEntdef*)&line, &right_id);
line.end1[0] = -line.end1[0];
line.end1[1] = line.end2[1];
err = ProSectionEntityAdd(section, (Pro2dEntdef*)&line, &top_id);
/*----------------------------------------------------------*\
Add dimensions
\*----------------------------------------------------------*/
point[0] = 0.0;
point[1] = r + params[1].d+1;
pnt_types[0] = PRO_ENT_WHOLE;
err =ProSecdimCreate(section, &top_id, pnt_types, 1,
PRO_TK_DIM_LINE, point, &width_id);
point[0] = params[0].d/2+1;
point[1] = (y + point[1])/2;
pnt_types[0] = pnt_types[1] = PRO_ENT_WHOLE;
dims[0] = top_id;
dims[1] = circle_id;
err = ProSecdimCreate(section, dims, pnt_types, 2,
PRO_TK_DIM_LINE_AOC, point, &height_id);
/*----------------------------------------------------------*\
Solve section
\*----------------------------------------------------------*/
err = ProSecerrorAlloc(&errors);
err = ProSectionSolve(section, &errors);
err = ProSecerrorFree(&errors);
} while (brk);
return (err);
}
/*=============================================================*\
Function: ProUtilCreateNotchSection
Purpose: Full creating of open section with tree lines
Return :
\*=============================================================*/
ProError ProUtilCreateNotchSection(
ProSection section, /*In : the section */
Parameter *params) /*In : params [0] - circle diameter */
/* params [1] - notch radius */
/* params [2] - backplate surface */
{
Pro2dArcdef arc;
Pro2dCircledef* p_circle;
Pro2dPnt point;
int dims[2], brk=0;
int circle_id, arc_id, hor_id, vert_id, rad_id;
ProSectionPointType pnt_types[2];
ProError err;
ProWSecerror errors;
double y, x;
do /* Used for exit from the middle of block */
{
y = ((params[0].d*params[0].d)/2-params[1].d*params[1].d)/params[0].d;
x = sqrt((params[0].d*params[0].d)/4-y*y);
/*----------------------------------------------------------*\
Create entities
\*----------------------------------------------------------*/
err = ProSectionEntityFromProjection(section, params[2].r, &circle_id);
err = ProSectionEntityGet (section, circle_id, (Pro2dEntdef**)&p_circle);
arc.type = PRO_2D_ARC;
arc.center[0] = p_circle -> center [0];
arc.center[1] = p_circle -> center [1] + params[0].d/2;
arc.radius = params[1].d;
arc.start_angle = atan2(y-params[0].d/2, -x)+PI*2;
arc.end_angle = 3*PI - arc.start_angle;
err = ProSectionEntityAdd(section, (Pro2dEntdef*)&arc, &arc_id);
/*----------------------------------------------------------*\
Add dimensions
\*----------------------------------------------------------*/
point[0] = p_circle -> center [0];
point[1] = p_circle -> center [1] + params[0].d/2 ;
pnt_types[0] = PRO_ENT_WHOLE;
err =ProSecdimCreate(section, &arc_id, pnt_types, 1,
PRO_TK_DIM_RAD, point, &rad_id);
point[0] = p_circle -> center [0];
point[1] = p_circle -> center [1] + params[0].d/4;
pnt_types[0] = PRO_ENT_CENTER;
pnt_types[1] = PRO_ENT_CENTER;
dims[0] = circle_id;
dims[1] = arc_id;
err = ProSecdimCreate(section, dims, pnt_types, 2,
PRO_TK_DIM_PNT_PNT_HORIZ, point, &hor_id);
point[0] = p_circle -> center [0] + 1.0;
point[1] = p_circle -> center [1] + params[0].d/4;
pnt_types[0] = PRO_ENT_CENTER;
pnt_types[1] = PRO_ENT_CENTER;
dims[0] = circle_id;
dims[1] = arc_id;
vert_id = -1;
ProTKPrintf( "point=(%f %f)\n", point[0], point[1] );
err = ProSecdimCreate(section, dims, pnt_types, 2,
PRO_TK_DIM_AOC_AOC_TAN_VERT, point, &vert_id);
/*----------------------------------------------------------*\
Solve section
\*----------------------------------------------------------*/
err = ProSecerrorAlloc(&errors);
err = ProSectionSolve(section, &errors);
if (err != PRO_TK_NO_ERROR)
break;
err = ProSecerrorFree(&errors);
} while (brk);
return (err);
}
/*=============================================================*\
Function: ProUtilCreateSketchedFeature
Purpose: create a new feature
Return : PRO_TK_NO_ERROR if succsessfull, an error otherwise
\*=============================================================*/
ProError ProUtilCreateSketchedFeature(
GearParam *g_ptr, /* In : */
FeatureDef *feat_def, /* In : Feature definition */
ProFeature *feature) /* Out: created feature */
{
static ElemTreeData sketch[]={
{1, PRO_E_SKETCHER, {PRO_VALUE_TYPE_POINTER}}
};
static ProElempathItem path_items[] = {
{PRO_ELEM_PATH_ITEM_TYPE_ID, PRO_E_STD_SECTION},
{PRO_ELEM_PATH_ITEM_TYPE_ID, PRO_E_SKETCHER}
};
ProElement elem_tree, elem_sec;
ProElement created_elemtree, sketch_element;
ProError err;
ProModelitem model_item;
ProSelection model_sel;
ProFeatureCreateOptions opts[1];
ProErrorlist errs;
ProElempath path;
ProValue value;
ProValueData value_data;
ProSection section;
int brk = 0;
do /* Used for exit from middle of block */
{
/*----------------------------------------------------------*\
Create Element Tree
\*----------------------------------------------------------*/
err = ProUtilElemtreeCreate(feat_def->tree, feat_def->sizeof_tree, NULL,
&elem_tree);
if (err != PRO_TK_NO_ERROR)
break;
/*----------------------------------------------------------*\
Create the incomplete protrusion in the current model
\*----------------------------------------------------------*/
err = ProMdlToModelitem(g_ptr->model, &model_item);
err = ProSelectionAlloc(NULL, &model_item, &model_sel);
opts[0] = PRO_FEAT_CR_INCOMPLETE_FEAT;
err = ProFeatureCreate(model_sel, elem_tree, opts, 1, feature, &errs);
if (err != PRO_TK_NO_ERROR)
{
ProUtilFeatErrsWrite("ProFeatureCreate", err, elem_tree, &errs);
break;
}
err = ProSelectionFree(&model_sel);
/*----------------------------------------------------------*\
Get the initialized section element from the database
\*----------------------------------------------------------*/
err = ProElempathAlloc(&path);
err = ProElempathDataSet(path, path_items, 2);
err = ProFeatureElemtreeCreate (feature, &created_elemtree);
err = ProElemtreeElementGet (created_elemtree, path, &sketch_element);
err = ProElementValueGet (sketch_element, &value);
err = ProValueDataGet(value, &value_data);
section = (ProSection)value_data.v.p;
err = ProElempathFree(&path);
/*----------------------------------------------------------*\
Create a section
\*----------------------------------------------------------*/
err = feat_def->section_create_func(section, feat_def->params);
if (err != PRO_TK_NO_ERROR)
break;
/*------------------------------------------------------------*\
Set section-dependent element values
\*------------------------------------------------------------*/
ProUtilFeatureSetSectionDependentValues (created_elemtree,
feat_def->tree,
feat_def->sizeof_tree);
opts[0] = PRO_FEAT_CR_INCOMPLETE_FEAT;
err = ProFeatureRedefine(NULL, feature, created_elemtree, opts, 1, &errs);
if (err != PRO_TK_NO_ERROR)
{
ProUtilFeatErrsWrite("ProFeatureRedefine", err, elem_tree, &errs);
break;
}
err = ProElementFree(&elem_tree);
/*----------------------------------------------------------*\
Set feature name
\*----------------------------------------------------------*/
ProUtilModelitemNameSet(feature, feat_def->feat_name);
} while (brk);
return (err);
}
/*=============================================================*\
Function: ProUtilFeatureSetSectionDependentValues
Purpose: Assign necessary elements (direction, material side) from
original value table (special for Extrude, Revolve element
tree, these elements must be set along with or after
PRO_E_SEKTCHER)
\*=============================================================*/
ProError ProUtilFeatureSetSectionDependentValues (ProElement elemtree,
ElemTreeData* elemarr,
int n_elem)
{
ElemTreeData* needed_elems = NULL;
int i_elem, i_value;
int size;
ProElempath elem_path;
ProElempathItem path_item;
ProElement element;
ProValue value;
for (i_elem = 0; i_elem < n_elem; i_elem ++)
{
switch (elemarr [i_elem].elem_id)
{
case PRO_E_EXT_SURF_CUT_SOLID_TYPE:
{
ProArrayAlloc (0, sizeof (ElemTreeData), 1, (ProArray*)&needed_elems);
break;
}
case PRO_E_STD_DIRECTION:
case PRO_E_STD_MATRLSIDE:
{
if (needed_elems != NULL)
{
ProArrayObjectAdd ((ProArray*)&needed_elems, -1, 1, &elemarr[i_elem]);
}
break;
}
default:
break;
}
}
if (needed_elems == NULL)
return PRO_TK_NO_ERROR;
err = ProArraySizeGet (needed_elems, &size);
if (err != PRO_TK_NO_ERROR)
return PRO_TK_NO_ERROR;
if (size == 0)
{
ProArrayFree ((ProArray*)&needed_elems);
return PRO_TK_NO_ERROR;
}
for (i_value = 0; i_value < size; i_value ++)
{
switch (needed_elems [i_value].elem_id)
{
case PRO_E_STD_DIRECTION:
case PRO_E_STD_MATRLSIDE:
{
ProElempathAlloc (&elem_path);
path_item.type = PRO_ELEM_PATH_ITEM_TYPE_ID;
path_item.path_item.elem_id = needed_elems [i_value].elem_id;
ProElempathDataSet (elem_path, &path_item, 1);
ProElemtreeElementGet (elemtree, elem_path, &element);
/*----------------------------------------------------------*\
Add Element value
\*----------------------------------------------------------*/
ProValueAlloc(&value);
ProValueDataSet(value, &needed_elems[i_value].data);
ProElementValueSet(element, value);
ProElempathFree (&elem_path);
break;
}
}
}
ProArrayFree ((ProArray*) &needed_elems);
return PRO_TK_NO_ERROR;
}
/*=============================================================*\
Function: ProUtilModelitemNameSet
Purpose: Set new name for the model item
Return : as ProModelitemNameSet
\*=============================================================*/
ProError ProUtilModelitemNameSet(ProModelitem *modelitem, char *name)
{
ProName w_name;
ProError err;
ProStringToWstring(w_name, name);
err = ProModelitemNameSet(modelitem, w_name);
return (err);
}
/*=============================================================*\
Function: ProUtilFeatByNameVisit
Purpose: visiting fucntion for ProSolidFeatVisit
Return : 1 if feature with required name found, 0 otherwise
\*=============================================================*/
static ProError ProUtilModelitemByNameVisit(
ProModelitem *modelitem,
ProError err,
ProAppData app_data)
{
FeatByNameFind *feat_by_name = (FeatByNameFind *)app_data;
ProName name;
int i;
ProBoolean vis;
if (modelitem->type == PRO_FEATURE)
{
err = ProFeatureVisibilityGet((ProFeature*)modelitem, &vis);
if (err!=PRO_TK_NO_ERROR || vis == PRO_B_FALSE)
return (PRO_TK_NO_ERROR);
}
err = ProModelitemNameGet(modelitem, name);
if (err != PRO_TK_NO_ERROR)
return (PRO_TK_NO_ERROR);
for (i=0; i<feat_by_name->num_feats; i++)
{
if (ProUtilStrwscmp(feat_by_name->feats[i].name, name)==0)
feat_by_name->feats[i].id = modelitem->id;
}
return (PRO_TK_NO_ERROR);
}
/*=============================================================*\
Function: ProUtilFeatsByName
Purpose: to find solid features by name
Return : PRO_TK_NO_ERROR if successfull,
\*=============================================================*/
ProError ProUtilFeatsByName(
ProSolid model,
FeatByName *feats,
int num_feats)
{
FeatByNameFind feat_by_name;
ProError err;
int i;
feat_by_name.feats = feats;
feat_by_name.num_feats = num_feats;
for (i=0; i<num_feats; i++)
feats[i].id = -1;
err = ProSolidFeatVisit((ProSolid)model,
(ProFeatureVisitAction)ProUtilModelitemByNameVisit, NULL,
(ProAppData)&feat_by_name);
return (err);
}
/*=============================================================*\
Function: ProUtilSelectionFromSurfaceId
Purpose: transformation from surface id to ProSelection
Return : PRO_TK_NO_ERROR if successfull,
\*=============================================================*/
ProError ProUtilSelectionFromSurfaceId(
ProMdl model, /* In : model */
int surf_id, /* In : surface id */
ProSelection *sel) /* Out: selection, to free use ProSelectionFree() */
{
ProError err;
ProSurface surf;
ProModelitem modelitem;
err=ProSurfaceInit(model, surf_id, &surf);
if (err!=PRO_TK_NO_ERROR)
return (err);
err = ProSurfaceToGeomitem((ProSolid)model, surf, (ProGeomitem*)&modelitem);
if (err != PRO_TK_NO_ERROR)
return (err);
err = ProSelectionAlloc(NULL, &modelitem, sel);
if (err != PRO_TK_NO_ERROR)
return (err);
return (PRO_TK_NO_ERROR);
}
/*=============================================================*\
Function: ProUtilAxisGeomitemVisit
Purpose: Visit function for the ProFeatureGeomitemVisit
Return : only one axis as feature it self is axis
\*=============================================================*/
ProError ProUtilAxisGeomitemVisit(
ProGeomitem *geomitem,
ProError err,
ProAppData appdata)
{
ProGeomitem *axis = (ProGeomitem*)appdata;
axis[0] = geomitem[0];
err = PRO_TK_E_FOUND;
return (PRO_TK_E_FOUND);
}
/*=============================================================*\
Function: ProUtilAxisGeomitem
Purpose: Found Axis GeomItem for the axis feature (PRO_FEAT_DATUM_AXIS)
Return : PRO_TK_NO_ERROR if successful
\*=============================================================*/
ProError ProUtilAxisGeomitem(
ProFeature *feature_axis, /* In: the feature */
ProType type, /* In: Geomitem type */
int *featid) /*Out: Geomitem id */
{
ProModelitem modelitem;
ProError err;
err = ProFeatureGeomitemVisit(feature_axis, type,
ProUtilAxisGeomitemVisit, NULL,
(ProAppData)&modelitem);
if (err==PRO_TK_E_FOUND)
{
featid[0] = modelitem.id;
return (PRO_TK_NO_ERROR);
}
return (PRO_TK_E_NOT_FOUND);
}
/*===================================================================*\
Function: ProUtilSelectionFromAxisId
Purpose: transformation from axis id to ProSelection
Return : PRO_TK_NO_ERROR if successfull,
\*=============================================================*/
ProError ProUtilSelectionFromAxisId(
ProMdl model, /* In : model */
int axis_id, /* In : axis id */
ProSelection *sel) /* Out: selection, to free use ProSelectionFree() */
{
ProError err;
ProAxis axis;
ProModelitem modelitem;
err = ProAxisInit(model, axis_id, &axis);
if (err!=PRO_TK_NO_ERROR)
return (err);
err = ProAxisToGeomitem((ProSolid)model, axis, (ProGeomitem*)&modelitem);
if (err != PRO_TK_NO_ERROR)
return (err);
err = ProSelectionAlloc(NULL, &modelitem, sel);
if (err!=PRO_TK_NO_ERROR)
return (err);
return (PRO_TK_NO_ERROR);
}
/*=============================================================*\
Function: ProUtilGeometryAtPointFind
Purpose: to find surface at point
Return : PRO_TK_NO_ERROR if successfull,
PRO_TK_E_NOT_FOUND otherwise
\*=============================================================*/
ProError ProUtilGeometryAtPointFind(
ProPart part,
Pro3dPnt point,
ProModelitem *modelitem)
{
int n_sel, i;
ProSelection *p_sel;
ProType type;
ProError err;
err = ProGeometryAtPointFind(part, point, &p_sel, &n_sel);
if (err != PRO_TK_NO_ERROR)
return (PRO_TK_E_NOT_FOUND);
err = ProSelectionModelitemGet(p_sel[0], modelitem);
/* Free memory allocated by ProGeometryAtPointFind */
for (i = 0; i < n_sel; i++)
ProSelectionFree( &p_sel[i]);
ProArrayFree((ProArray *) &p_sel);
return (PRO_TK_NO_ERROR);
}
/*=============================================================*\
Function: ProUtilFeatFirstGeomitemVisit
Purpose: Visit function for the ProFeatureGeomitemVisit
Return : 1 (only first geom item visited)
\*=============================================================*/
ProError ProUtilFeatFirstGeomitemVisit(
ProGeomitem *geom_item,
ProError err,
ProAppData app_data)
{
ProGeomitem *surf = (ProGeomitem*)app_data;
surf[0] = geom_item[0];
return ((ProError)1);
}
/*=============================================================*\
Function: ProUtilFeatFirstGeomitem
Purpose: Found first GeomItem for the feature
Return : PRO_TK_NO_ERROR if successful
\*=============================================================*/
ProError ProUtilFeatFirstGeomitem(
ProFeature *feature, /* In: the feature */
ProType type, /* In: Geomitem type */
int *item_id) /*Out: Geomitem id, user's memory */
{
ProModelitem model_item;
ProError err;
err = ProFeatureGeomitemVisit(feature, type,
ProUtilFeatFirstGeomitemVisit, NULL, (ProAppData)&model_item);
if (err==1)
{
item_id[0] = model_item.id;
return (PRO_TK_NO_ERROR);
}
return (PRO_TK_E_NOT_FOUND);
}
/*=============================================================*\
Function: ProUtilFeatFirstDimensionVisit
Purpose: Visit function for the ProFeatureDimensionVisit
Return : 1 (only first dim visited)
\*=============================================================*/
ProError ProUtilFeatFirstDimensionVisit(
ProDimension *dim,
ProError err,
ProAppData app_data)
{
ProDimension *found = (ProDimension*)app_data;
found[0] = dim[0];
return ((ProError)1);
}
/*=============================================================*\
Function: ProUtilFeatFirstDimension
Purpose: Found first GeomItem for the feature
Return : PRO_TK_NO_ERROR if successful
\*=============================================================*/
ProError ProUtilFeatFirstDimension(
ProFeature *feature, /* In: the feature */
int *item_id) /*Out: Dimension id, user's memory */
{
ProModelitem model_item;
ProError err;
err = ProFeatureDimensionVisit(feature,
ProUtilFeatFirstDimensionVisit, NULL, (ProAppData)&model_item);
if (err==1)
{
item_id[0] = model_item.id;
return (PRO_TK_NO_ERROR);
}
return (PRO_TK_E_NOT_FOUND);
}
/*=============================================================*\
Function: ProUtilFindTwoCircleIntersection
Purpose: Calculate intersection of two circles
Return : PRO_TK_NO_ERROR if successfull
PRO_TK_GENERAL_ERROR - no intersection
\*=============================================================*/
ProError ProUtilTwoCircleIntersection(
Pro2dCircledef *c1,
Pro2dCircledef *c2,
Pro2dPnt p1,
Pro2dPnt p2)
{
double d, x1, y1, sa, ca;
d = sqrt(sqr(c1->center[0]-c2->center[0]) +
sqr(c1->center[1]-c2->center[1]));
if ((d<EPSM6) || (d>c1->radius + c2->radius) ||
(d + c1->radius < c2->radius) || (d + c2->radius < c1->radius))
return (PRO_TK_GENERAL_ERROR);
y1 = (sqr(c1->radius) + sqr(d) - sqr(c2->radius)) / 2 /d;
x1 = sqrt(sqr(c1->radius) - sqr(y1));
sa = (c2->center[0]-c1->center[0]) / d;
ca = (c2->center[1]-c1->center[1]) / d;
p1[0] = y1 * sa + x1 * ca + c1->center[0];
p1[1] = y1 * ca - x1 * sa + c1->center[1];
p2[0] = y1 * sa - x1 * ca + c1->center[0];
p2[1] = y1 * ca + x1 * sa + c1->center[1];
return (PRO_TK_NO_ERROR);
}
/*=============================================================*\
Function: ProUtilFeatErrsWrite
Purpose: Debug function. Print elem tree and errors af feature
creation or redefenition failed
*=============================================================*/
void ProUtilFeatErrsWrite(
char *function,
ProError err,
ProElement tree,
ProErrorlist *err_list)
{
ProTKFprintf(stderr, "Function %s returned %d\n", function, err);
ProUtilElementtreePrint(tree, (UtilTreeprintWindow)2, 0);
ProUtilFeatErrsPrint(err_list);
}
ProError ProUtilSecEntityUseCurveLoop (ProSection section, Parameter *params)
{
ProSelection *ref_geom_sketch;
ProModelitem ref_item;
ProSelection curve_ref;
ProIntlist ids;
ProWSecerror sec_errors;
int num_ids;
ProErrorlist errors;
ProMdl model;
ProError status;
int curve_id;
ProFeature feature;
ProModelitem app_data;
FeatByName feat_sketch[] = {
{"SKETCH_1"}};
ProCurve curve;
CurveComponent *curvecomps;
status = ProMdlCurrentGet (&model);
status = ProUtilFeatsByName(model, feat_sketch, 1);
status = ProFeatureInit(model, feat_sketch[0].id, &feature);
status = ProFeatureGeomitemVisit(&feature, PRO_CURVE, ProUtilGeomItemVisitCurve, NULL, (ProAppData)&app_data);
curve_id = app_data.id;
// Extract curve from composite curve
status = ProCurveInit ((ProSolid)model, curve_id, &curve);
ProUtilCollectCurveComponents(curve, &curvecomps);
status = ProCurveIdGet(curvecomps[0].p_curve, &curve_id);
status = ProModelitemInit (model, (curve_id), PRO_CURVE, &ref_item);
status = ProSelectionAlloc (NULL, &ref_item, &curve_ref);
status = ProSectionEntityUseCurveLoop (section, curve_ref, &ids, &num_ids);
status = ProSelectionFree (&curve_ref);
status = ProSecerrorAlloc (&sec_errors);
status = ProSectionAutodim (section, &sec_errors);
status = ProSecerrorFree (&sec_errors);
return (status);
}
ProError ProUtilGeomItemVisitCurve (ProGeomitem *geom_item, ProError err_status, ProAppData data)
{
ProGeomitem *curve = (ProGeomitem*)data;
curve[0] = geom_item[0];
err_status = PRO_TK_E_FOUND;
return (PRO_TK_E_FOUND);
}