/* Copyright (c) 2024 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved. */ #include <ProToolkit.h> #include <ProObjects.h> #include <ProChamfer.h> #include <ProFeature.h> #include <ProCrvcollection.h> #include <ProMdl.h> #include <ProGeomitem.h> #include <ProSelbuffer.h> #include <ProVariantFeat.h> #include <ProAnnotationFeat.h> #include <ProAnnotationElem.h> #include <PTAFExamples.h> /*====================================================================*\ FUNCTION : TestPTAFExCreateChamferFeatureAccess() PURPOSE : Enable/Disable access to the Chamfer Feature from AE button \*====================================================================*/ uiCmdAccessState TestPTAFExCreateChamferFeatureAccess(uiCmdAccessMode access_mode) { ProMdl mdl; ProMdlType mdltype; ProAnnotationElem annotelem; int featType = -1; ProSelection *sel=NULL; /*---------------------------------------------------------------------*\ Test to See if the current model is a Part / Assembly where annotation features exist \*---------------------------------------------------------------------*/ status = ProMdlCurrentGet(&mdl); if (status != PRO_TK_NO_ERROR) return (ACCESS_UNAVAILABLE); ProMdlTypeGet(mdl, &mdltype); if ((mdltype != PRO_MDL_PART) && (mdltype != PRO_MDL_ASSEMBLY)) return (ACCESS_UNAVAILABLE); /*---------------------------------------------------------------------*\ Test to see if the Selection buffer if empty Get the Annotation Element from the Selection buffer \*---------------------------------------------------------------------*/ status = PTAFExTestforSelectionsInBuffer(); PT_TEST_LOG_SUCC("PTAFExTestforSelectionsInBuffer "); if (status != PRO_TK_NO_ERROR) return (ACCESS_UNAVAILABLE); /*---------------------------------------------------------------------*\ User gets the ProSelection from the selection buffer \*---------------------------------------------------------------------*/ status = ProSelbufferSelectionsGet(&sel); PT_TEST_LOG_SUCC("PTAFExCreateRoundfromAE::ProSelbufferSelectionsGet "); /*---------------------------------------------------------------------*\ Get ModelItem from the ProSelection \*---------------------------------------------------------------------*/ status = ProSelectionModelitemGet(sel[0], &annotelem); PT_TEST_LOG_SUCC("PTAFExCreateRoundfromAE::ProSelectionModelitemGet "); ProSelectionarrayFree (sel); /*---------------------------------------------------------------------*\ Make sure Modelitem is an AE \*---------------------------------------------------------------------*/ if (annotelem.type != PRO_ANNOTATION_ELEM) return ACCESS_UNAVAILABLE; /*---------------------------------------------------------------------*\ Get the feature type to be created \*---------------------------------------------------------------------*/ status = PTAFExGetFeatureType(&annotelem, &featType); if (featType == PTAFEX_PRO_FEAT_CHAMFER) return (ACCESS_AVAILABLE); else return (ACCESS_UNAVAILABLE); } /*====================================================================*\ FUNCTION : PTAFExCreateChamferfromAE() PURPOSE : Callback to create Chamfer feature from AE \*====================================================================*/ ProError PTAFExCreateChamferfromAE() { ProSelection *sel=NULL, ref_sel; ProAnnotationElem annotelem; int feature_type = -1; double chamfer_dim = -1; ProAnnotationReference *references=NULL; int num_refs = 0, i; ProGeomitem edge; ProFeature feat; ProFeattype feat_type; ProCrvcollinstr curv_coll_instr; ProCollection curv_coll; ProAsmcomppath path; ProMdlType type; ProFeature inh_feat; ProReference edge_ref; inh_feat.owner = NULL; /*---------------------------------------------------------------------*\ User gets the ProSelection from the selection buffer \*---------------------------------------------------------------------*/ status = ProSelbufferSelectionsGet(&sel); PT_TEST_LOG_SUCC("PTAFExCreateRoundfromAE::ProSelbufferSelectionsGet "); /*---------------------------------------------------------------------*\ Get ModelItem from the ProSelection \*---------------------------------------------------------------------*/ status = ProSelectionModelitemGet(sel[0], &annotelem); PT_TEST_LOG_SUCC("PTAFExCreateRoundfromAE::ProSelectionModelitemGet "); /*---------------------------------------------------------------------*\ If the selected modelitem owner is not the same as the component path owner, and the component path owner is a part, the selection was from an inheritance feature. \*---------------------------------------------------------------------*/ status = ProSelectionAsmcomppathGet (sel[0], &path); if (status == PRO_TK_NO_ERROR) { status = ProMdlTypeGet (path.owner, &type); if (type == PRO_MDL_PART) { /*---------------------------------------------------------------------*\ Save the inheritance feature information. \*---------------------------------------------------------------------*/ inh_feat.owner = path.owner; inh_feat.id = path.comp_id_table [0]; inh_feat.type = PRO_FEATURE; } } /*---------------------------------------------------------------------*\ Make sure Modelitem is an AE \*---------------------------------------------------------------------*/ if (annotelem.type != PRO_ANNOTATION_ELEM) return PRO_TK_NO_ERROR; /*---------------------------------------------------------------------*\ If an AE, check for feature type parameter \*---------------------------------------------------------------------*/ status = PTAFExGetFeatureType(&annotelem, &feature_type); if (status == PRO_TK_NO_ERROR) { /*---------------------------------------------------------------------*\ If the AE does not contain a parameter indicating the type, display error message and quit function \*---------------------------------------------------------------------*/ if (feature_type != PTAFEX_PRO_FEAT_CHAMFER) return PRO_TK_NO_ERROR; /*---------------------------------------------------------------------*\ If the AE contains parameter for the chamfer dimension, get the value. \*---------------------------------------------------------------------*/ status = PTAFExGetFeatureValue(&annotelem, &chamfer_dim); /*---------------------------------------------------------------------*\ Allocate a new Curve Collection for use as the chamfer reference \*---------------------------------------------------------------------*/ status = ProCrvcollectionAlloc( &curv_coll ); /*---------------------------------------------------------------------*\ Convert the references for the annotation to feature references \*---------------------------------------------------------------------*/ status = ProAnnotationelemReferencesCollect(&annotelem, PRO_ANNOTATION_REF_ALL, PRO_ANNOT_REF_FROM_ANNOTATION, &references); PT_TEST_LOG_SUCC ("ProAnnotationelemReferencesCollect()"); status = ProArraySizeGet((ProArray)references, &num_refs); PT_TEST_LOG_SUCC ("ProArraySizeGet()"); for (i=0; i<num_refs; i++) { ProAnnotationRefType my_ref_type = references[i].type; if ( my_ref_type != PRO_ANNOT_REF_SINGLE ) continue; /*---------------------------------------------------------------------*\ Create the Geomitem from the ProReference \*---------------------------------------------------------------------*/ status = ProReferenceToSelection(references[i].object.reference, &ref_sel); status = ProSelectionModelitemGet(ref_sel, (ProModelitem*)&edge); /*---------------------------------------------------------------------*\ If not an Edge, ignore the reference for chamfer creation \*---------------------------------------------------------------------*/ if (edge.type == PRO_EDGE) { status = ProGeomitemFeatureGet(&edge, &feat); status = ProFeatureTypeGet(&feat, &feat_type); /*---------------------------------------------------------------------*\ If the annotation element was from an inheritance feature, we need to convert the references to references in the top-level model. \*---------------------------------------------------------------------*/ if (inh_feat.owner != NULL) { ProGeomitem new_edge; status = ProDatasharingfeatCopiedgeomitemFind (&inh_feat, NULL, &edge, &new_edge); PT_TEST_LOG_SUCC ("ProDatasharingfeatCopiedgeomitemFind()"); ProReferenceAlloc (&edge_ref); ProReferenceSet (edge_ref, NULL, &new_edge); } else ProSelectionToReference (ref_sel, &edge_ref); ProSelectionFree (&ref_sel); /*---------------------------------------------------------------------*\ If the edge belongs to a Hole, it may be 1/2 of a tangent edge circling the top of the hole. Make this assumption, and create the reference chain for the chamfer as a tangent chain. Otherwise, use just this one edge as the reference chain. \*---------------------------------------------------------------------*/ if(feat_type == PRO_FEAT_HOLE) status = ProCrvcollinstrAlloc(PRO_CURVCOLL_TAN_INSTR, &curv_coll_instr); else status = ProCrvcollinstrAlloc(PRO_CURVCOLL_ADD_ONE_INSTR, &curv_coll_instr); /*---------------------------------------------------------------------*\ Add the reference to the Instruction \*---------------------------------------------------------------------*/ status = ProCrvcollinstrReferenceAdd(curv_coll_instr, edge_ref); ProReferenceFree (edge_ref); /*---------------------------------------------------------------------*\ Add the instruction to the curve collection \*---------------------------------------------------------------------*/ status = ProCrvcollectionInstructionAdd( curv_coll, curv_coll_instr ); } } /*---------------------------------------------------------------------*\ Create the Chamfer feature based on the attributes \*---------------------------------------------------------------------*/ if (inh_feat.owner == NULL) status = ProMdlCurrentGet( &curr_mdl); else curr_mdl = inh_feat.owner; status = PTAFExChamferCreate(curr_mdl, chamfer_dim, curv_coll); ProAnnotationreferencearrayFree (references); ProCollectionFree (&curv_coll); } ProSelectionarrayFree (sel); return PRO_TK_NO_ERROR; } /*====================================================================*\ FUNCTION : PTAFExChamferCreate() PURPOSE : Create a chamfer using element tree. Based on UserEdgeChamferCreate() in UgEdgeChamferCreate.c (pt_userguide) \*====================================================================*/ int PTAFExChamferCreate( ProMdl model, double chamfer_dim, ProCollection curv_coll ) { ProElement pro_e_feature_tree; ProElement pro_e_feature_type; ProElement pro_e_rndch_sets; ProElement pro_e_rndch_set; ProElement pro_e_rndch_dimensional_schema; ProElement pro_e_rndch_chamfer_shape; ProElement pro_e_rndch_shape_options; ProElement pro_e_rndch_variable_radius; ProElement pro_e_rndch_compound_conic; ProElement pro_e_rndch_conic_type; ProElement pro_e_rndch_conic_value; ProElement pro_e_rndch_conic_dep_opt; ProElement pro_e_rndch_references; ProElement pro_e_rndch_reference_type; ProElement pro_e_std_curve_collection_appl; ProElement pro_e_rndch_compound_spine; ProElement pro_e_rndch_ball_spine; ProElement pro_e_rndch_compound_ext_options; ProElement pro_e_rndch_auto_blend; ProElement pro_e_rndch_radii; ProElement pro_e_rndch_radius; ProElement pro_e_rndch_leg1; ProElement pro_e_rndch_leg_type; ProElement pro_e_rndch_leg_value; ProElement pro_e_rndch_leg2; ProElement pro_e_rndch_attach_type; ProElement pro_e_rndch_transitions; status = ProElementAlloc ( PRO_E_FEATURE_TREE, &pro_e_feature_tree ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElementAlloc ( PRO_E_FEATURE_TYPE, &pro_e_feature_type ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElementIntegerSet ( pro_e_feature_type, 914 ); status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_feature_type ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_RNDCH_SETS, &pro_e_rndch_sets ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_rndch_sets ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_RNDCH_SET, &pro_e_rndch_set ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElemtreeElementAdd ( pro_e_rndch_sets, NULL, pro_e_rndch_set ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_RNDCH_DIMENSIONAL_SCHEMA, &pro_e_rndch_dimensional_schema ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElementIntegerSet ( pro_e_rndch_dimensional_schema, 602 ); status = ProElemtreeElementAdd ( pro_e_rndch_set, NULL, pro_e_rndch_dimensional_schema ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_RNDCH_CHAMFER_SHAPE, &pro_e_rndch_chamfer_shape ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElementIntegerSet ( pro_e_rndch_chamfer_shape, 1 ); status = ProElemtreeElementAdd ( pro_e_rndch_set, NULL, pro_e_rndch_chamfer_shape ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_RNDCH_SHAPE_OPTIONS, &pro_e_rndch_shape_options ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElementIntegerSet ( pro_e_rndch_shape_options, 0 ); status = ProElemtreeElementAdd ( pro_e_rndch_set, NULL, pro_e_rndch_shape_options ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_RNDCH_VARIABLE_RADIUS, &pro_e_rndch_variable_radius ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElementIntegerSet ( pro_e_rndch_variable_radius, 0 ); status = ProElemtreeElementAdd ( pro_e_rndch_set, NULL, pro_e_rndch_variable_radius ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_RNDCH_COMPOUND_CONIC, &pro_e_rndch_compound_conic ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElemtreeElementAdd ( pro_e_rndch_set, NULL, pro_e_rndch_compound_conic ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_RNDCH_CONIC_TYPE, &pro_e_rndch_conic_type ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElementIntegerSet ( pro_e_rndch_conic_type, 2 ); status = ProElemtreeElementAdd ( pro_e_rndch_compound_conic, NULL, pro_e_rndch_conic_type ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_RNDCH_CONIC_VALUE, &pro_e_rndch_conic_value ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElementDoubleSet ( pro_e_rndch_conic_value, 0.000000 ); status = ProElemtreeElementAdd ( pro_e_rndch_compound_conic, NULL, pro_e_rndch_conic_value ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_RNDCH_CONIC_DEP_OPT, &pro_e_rndch_conic_dep_opt ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElementIntegerSet ( pro_e_rndch_conic_dep_opt, 0 ); status = ProElemtreeElementAdd ( pro_e_rndch_compound_conic, NULL, pro_e_rndch_conic_dep_opt ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_RNDCH_REFERENCES, &pro_e_rndch_references ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElemtreeElementAdd ( pro_e_rndch_set, NULL, pro_e_rndch_references ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_RNDCH_REFERENCE_TYPE, &pro_e_rndch_reference_type ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElementIntegerSet ( pro_e_rndch_reference_type, 1 ); status = ProElemtreeElementAdd ( pro_e_rndch_references, NULL, pro_e_rndch_reference_type ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_STD_CURVE_COLLECTION_APPL, &pro_e_std_curve_collection_appl ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElementCollectionSet( pro_e_std_curve_collection_appl, curv_coll ); PT_TEST_LOG_SUCC( " ProElementCollectionSet " ); status = ProElemtreeElementAdd ( pro_e_rndch_references, NULL, pro_e_std_curve_collection_appl ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_RNDCH_COMPOUND_SPINE, &pro_e_rndch_compound_spine ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElemtreeElementAdd ( pro_e_rndch_set, NULL, pro_e_rndch_compound_spine ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_RNDCH_BALL_SPINE, &pro_e_rndch_ball_spine ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElementIntegerSet ( pro_e_rndch_ball_spine, 0 ); status = ProElemtreeElementAdd ( pro_e_rndch_compound_spine, NULL, pro_e_rndch_ball_spine ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_STD_CURVE_COLLECTION_APPL, &pro_e_std_curve_collection_appl ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElementAlloc ( PRO_E_RNDCH_COMPOUND_EXT_OPTIONS, &pro_e_rndch_compound_ext_options ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElemtreeElementAdd ( pro_e_rndch_set, NULL, pro_e_rndch_compound_ext_options ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_RNDCH_AUTO_BLEND, &pro_e_rndch_auto_blend ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElementIntegerSet ( pro_e_rndch_auto_blend, 0 ); status = ProElemtreeElementAdd ( pro_e_rndch_compound_ext_options, NULL, pro_e_rndch_auto_blend ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_RNDCH_RADII, &pro_e_rndch_radii ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElemtreeElementAdd ( pro_e_rndch_set, NULL, pro_e_rndch_radii ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_RNDCH_RADIUS, &pro_e_rndch_radius ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElemtreeElementAdd ( pro_e_rndch_radii, NULL, pro_e_rndch_radius ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_RNDCH_LEG1, &pro_e_rndch_leg1 ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElemtreeElementAdd ( pro_e_rndch_radius, NULL, pro_e_rndch_leg1 ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_RNDCH_LEG_TYPE, &pro_e_rndch_leg_type ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElementIntegerSet ( pro_e_rndch_leg_type, 1 ); status = ProElemtreeElementAdd ( pro_e_rndch_leg1, NULL, pro_e_rndch_leg_type ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_RNDCH_LEG_VALUE, &pro_e_rndch_leg_value ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElementDoubleSet ( pro_e_rndch_leg_value, chamfer_dim); status = ProElemtreeElementAdd ( pro_e_rndch_leg1, NULL, pro_e_rndch_leg_value ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_RNDCH_LEG2, &pro_e_rndch_leg2 ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElemtreeElementAdd ( pro_e_rndch_radius, NULL, pro_e_rndch_leg2 ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_RNDCH_LEG_TYPE, &pro_e_rndch_leg_type ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElementIntegerSet ( pro_e_rndch_leg_type, 0 ); status = ProElemtreeElementAdd ( pro_e_rndch_leg2, NULL, pro_e_rndch_leg_type ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_RNDCH_LEG_VALUE, &pro_e_rndch_leg_value ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElementDoubleSet ( pro_e_rndch_leg_value, 0.000000 ); status = ProElemtreeElementAdd ( pro_e_rndch_leg2, NULL, pro_e_rndch_leg_value ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_STD_CURVE_COLLECTION_APPL, &pro_e_std_curve_collection_appl ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElementAlloc ( PRO_E_RNDCH_ATTACH_TYPE, &pro_e_rndch_attach_type ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElementIntegerSet ( pro_e_rndch_attach_type, 0 ); status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_rndch_attach_type ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = ProElementAlloc ( PRO_E_RNDCH_TRANSITIONS, &pro_e_rndch_transitions ); PT_TEST_LOG_SUCC( " ProElementAlloc " ); status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_rndch_transitions ); PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" ); status = PTTestFeatureCreate_low ( model, pro_e_feature_tree ); PT_TEST_LOG_SUCC (" PTTestFeatureCreate_low"); return status; }