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