/*
Copyright (c) 2024 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved.
*/
#include <ProToolkit.h>
#include <ProObjects.h>
#include <ProDraft.h>
#include <ProDirection.h>
#include <ProElement.h>
#include <ProSrfcollection.h>
#include <ProCrvcollection.h>
#include <ProMdl.h>
#include <ProGeomitem.h>
#include <ProSelbuffer.h>
#include <ProMessage.h>
#include <ProFeature.h>
#include <ProFeatType.h>
#include <ProSurface.h>
#include <ProVariantFeat.h>
#include <ProAnnotationFeat.h>
#include <ProAnnotationElem.h>
#include <PTAFExamples.h>
/*====================================================================*\
FUNCTION : TestPTAFExCreateDraftFeatureAccess()
PURPOSE : Enable access to the Draft Feature from AE button
\*====================================================================*/
uiCmdAccessState TestPTAFExCreateDraftFeatureAccess(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();
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_DRAFT) return (ACCESS_AVAILABLE);
else return (ACCESS_UNAVAILABLE);
}
/*====================================================================*\
FUNCTION : PTAFExCreateDraftfromAE()
PURPOSE : Callback to create Draft feature from AE
\*====================================================================*/
ProError PTAFExCreateDraftfromAE()
{
ProSelection *sel=NULL, ref_sel;
ProAnnotationElem annotelem;
int feature_type = -1;
double draft_angle = -1;
ProAnnotationReference *references=NULL;
int num_refs = 0, i;
ProGeomitem draft_reference;
ProFeature feat;
ProFeattype feat_type;
ProCollection surf_coll;
ProSrfcollinstr surf_coll_instr;
ProSrfcollref surf_coll_ref;
ProReference hinge_ref, direction_ref;
ProBoolean is_surf_defined = PRO_B_FALSE, is_hinge_defined=PRO_B_FALSE, is_direction_defined=PRO_B_FALSE;
ProAsmcomppath path;
ProMdlType type;
ProFeature inh_feat;
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 "round" parameter
\*---------------------------------------------------------------------*/
status = PTAFExGetFeatureType(&annotelem, &feature_type);
if (status == PRO_TK_NO_ERROR) {
/*---------------------------------------------------------------------*\
If the AE does not contain a parameter for feature type, quit function
\*---------------------------------------------------------------------*/
if (feature_type != PTAFEX_PRO_FEAT_DRAFT) return PRO_TK_NO_ERROR;
/*---------------------------------------------------------------------*\
If the AE contains parameter for the draft angle, get the value.
\*---------------------------------------------------------------------*/
status = PTAFExGetFeatureValue(&annotelem, &draft_angle);
/*---------------------------------------------------------------------*\
Also, get the references for the AE
\*---------------------------------------------------------------------*/
status = ProAnnotationelemReferencesCollect(&annotelem,
PRO_ANNOTATION_REF_ALL,
PRO_ANNOT_REF_FROM_ALL,
&references);
status = ProArraySizeGet((ProArray*)references, &num_refs);
for (i=0; i<num_refs; i++) {
ProAnnotationRefType my_ref_type = references[i].type;
if ( my_ref_type != PRO_ANNOT_REF_SINGLE )
continue;
/*---------------------------------------------------------------------*\
Get the Geomitem from the ProReference
\*---------------------------------------------------------------------*/
status = ProReferenceToSelection(references[i].object.reference, &ref_sel);
status = ProSelectionModelitemGet(ref_sel, (ProModelitem*)&draft_reference);
/*---------------------------------------------------------------------*\
Get the feature type that is the parent of the geomitem
\*---------------------------------------------------------------------*/
status = ProGeomitemFeatureGet(&draft_reference, &feat);
status = ProFeatureTypeGet(&feat, &feat_type);
/*---------------------------------------------------------------------*\
If the Geomitem Type is an edge this reference is the
direction reference for the draft
\*---------------------------------------------------------------------*/
if (draft_reference.type == PRO_EDGE) {
/*---------------------------------------------------------------------*\
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,
&draft_reference,
&new_edge);
PT_TEST_LOG_SUCC ("ProDatasharingfeatCopiedgeomitemFind()");
ProReferenceAlloc (&direction_ref);
ProReferenceSet (direction_ref, NULL, &new_edge);
}
else
{
status = ProSelectionToReference(ref_sel, &direction_ref);
}
ProSelectionFree (&ref_sel);
is_direction_defined=PRO_B_TRUE;
}
/*---------------------------------------------------------------------*\
If the Geomitem Type is a datum surface,
this reference is the hinge reference for the draft
\*---------------------------------------------------------------------*/
if (draft_reference.type == PRO_SURFACE) {
if (PTAFSurfaceIsDatum (&draft_reference)) {
/*---------------------------------------------------------------------*\
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_surf;
status = ProDatasharingfeatCopiedgeomitemFind (&inh_feat,
NULL,
&draft_reference,
&new_surf);
PT_TEST_LOG_SUCC ("ProDatasharingfeatCopiedgeomitemFind()");
ProReferenceAlloc (&hinge_ref);
ProReferenceSet (hinge_ref, NULL, &new_surf);
}
else
{
status = ProSelectionToReference(ref_sel, &hinge_ref);
}
ProSelectionFree (&ref_sel);
is_hinge_defined = PRO_B_TRUE;
}
else {
ProReference surf_ref;
/*---------------------------------------------------------------------*\
If surface type is not a Datum Plane, the the reference is the surface to be
drafted.
Create a surface collection instruction for SINGLE surface containing
this reference
\*---------------------------------------------------------------------*/
status = ProSrfcollinstrAlloc(PRO_SURFCOLL_SINGLE_SURF, PRO_B_FALSE, &surf_coll_instr);
status = ProSrfcollinstrIncludeSet ( surf_coll_instr, PRO_B_TRUE);
/*---------------------------------------------------------------------*\
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_surf;
status = ProDatasharingfeatCopiedgeomitemFind (&inh_feat,
NULL,
&draft_reference,
&new_surf);
PT_TEST_LOG_SUCC ("ProDatasharingfeatCopiedgeomitemFind()");
ProReferenceAlloc (&surf_ref);
ProReferenceSet (surf_ref, NULL, &new_surf);
}
else
{
status = ProSelectionToReference(ref_sel, &surf_ref);
}
ProSelectionFree (&ref_sel);
status = ProSrfcollrefAlloc(PRO_SURFCOLL_REF_SINGLE,
surf_ref,
&surf_coll_ref);
ProReferenceFree (surf_ref);
status = ProSrfcollinstrReferenceAdd(surf_coll_instr, surf_coll_ref);
status = ProSrfcollectionAlloc( &surf_coll );
status = ProSrfcollectionInstructionAdd( surf_coll, surf_coll_instr );
is_surf_defined = PRO_B_TRUE;
}
}
}
/*---------------------------------------------------------------------*\
If all the references are present, then create the draft feature
\*---------------------------------------------------------------------*/
if (is_surf_defined && is_hinge_defined && is_direction_defined)
{
/*---------------------------------------------------------------------*\
Create the Draft feature based on the attributes
\*---------------------------------------------------------------------*/
if (inh_feat.owner == NULL)
status = ProMdlCurrentGet( &curr_mdl);
else
curr_mdl = inh_feat.owner;
status = PTAFExDraftCreate(curr_mdl, draft_angle, surf_coll, hinge_ref, direction_ref);
ProAnnotationreferencearrayFree (references);
ProReferenceFree (hinge_ref);
ProReferenceFree (direction_ref);
ProCollectionFree (&surf_coll);
}
/*---------------------------------------------------------------------*\
If all the references were not present, display an error message to the user.
\*---------------------------------------------------------------------*/
else
{
ProMessageDisplay(message_file_init,
"PTAFEX ERROR %0s",
"All the required references not contained in the Annotation Element.");
}
}
ProSelectionarrayFree (sel);
return PRO_TK_NO_ERROR;
}
/*====================================================================*\
FUNCTION : PTAFExDraftCreate()
PURPOSE : Create a draft using element tree. Based on
UserSimpleDraftCreate() in UgSimpleDraftCreate.c (pt_userguide)
\*====================================================================*/
int PTAFExDraftCreate( ProMdl model,
double draft_angle,
ProCollection surf_coll,
ProReference hinge_ref,
ProReference direction_ref )
{
ProElement pro_e_feature_tree;
ProElement pro_e_feature_type;
ProElement pro_e_draft_tweak_or_intersec;
ProElement pro_e_draft_split;
ProElement pro_e_std_surf_collection_appl;
ProElement pro_e_direction_compound;
ProElement pro_e_direction_reference;
ProElement pro_e_direction_flip;
ProElement pro_e_std_curve_collection_appl;
ProElement pro_e_draft_constant_or_variable;
ProElement pro_e_draft_include_tangent;
ProElement pro_e_draft_side_1;
ProElement pro_e_draft_neutral_object_type_1;
ProElement pro_e_draft_dependent_1;
ProElement pro_e_draft_angle_1;
ProElement pro_e_draft_angles;
ProElement pro_e_draft_side_2;
ProElement pro_e_draft_neutral_object_type_2;
ProElement pro_e_draft_dependent_2;
ProElement pro_e_draft_angle_2;
ProElement pro_e_draft_neutral_plane_1;
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, 927 );
status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_feature_type );
PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" );
status = ProElementAlloc ( PRO_E_DRAFT_TWEAK_OR_INTERSEC, &pro_e_draft_tweak_or_intersec );
PT_TEST_LOG_SUCC( " ProElementAlloc " );
status = ProElementIntegerSet ( pro_e_draft_tweak_or_intersec, 0 );
status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_draft_tweak_or_intersec );
PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" );
status = ProElementAlloc ( PRO_E_DRAFT_SPLIT, &pro_e_draft_split );
PT_TEST_LOG_SUCC( " ProElementAlloc " );
status = ProElementIntegerSet ( pro_e_draft_split, 0 );
status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_draft_split );
PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" );
status = ProElementAlloc ( PRO_E_STD_SURF_COLLECTION_APPL, &pro_e_std_surf_collection_appl );
PT_TEST_LOG_SUCC( " ProElementAlloc " );
status = ProElementCollectionSet( pro_e_std_surf_collection_appl, surf_coll );
PT_TEST_LOG_SUCC( " ProElementCollectionSet " );
status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_std_surf_collection_appl );
PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" );
status = ProElementAlloc ( PRO_E_DIRECTION_COMPOUND, &pro_e_direction_compound );
PT_TEST_LOG_SUCC( " ProElementAlloc " );
status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_direction_compound );
PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" );
status = ProElementAlloc ( PRO_E_DIRECTION_REFERENCE, &pro_e_direction_reference );
PT_TEST_LOG_SUCC( " ProElementAlloc " );
status = ProElementReferenceSet( pro_e_direction_reference, direction_ref );
PT_TEST_LOG_SUCC( " ProElementReferenceSet " );
status = ProElemtreeElementAdd ( pro_e_direction_compound, NULL, pro_e_direction_reference );
PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" );
status = ProElementAlloc ( PRO_E_DIRECTION_FLIP, &pro_e_direction_flip );
PT_TEST_LOG_SUCC( " ProElementAlloc " );
status = ProElementIntegerSet ( pro_e_direction_flip, 1 );
status = ProElemtreeElementAdd ( pro_e_direction_compound, NULL, pro_e_direction_flip );
PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" );
status = ProElementAlloc ( PRO_E_DRAFT_CONSTANT_OR_VARIABLE, &pro_e_draft_constant_or_variable );
PT_TEST_LOG_SUCC( " ProElementAlloc " );
status = ProElementIntegerSet ( pro_e_draft_constant_or_variable, 1 );
status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_draft_constant_or_variable );
PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" );
status = ProElementAlloc ( PRO_E_DRAFT_INCLUDE_TANGENT, &pro_e_draft_include_tangent );
PT_TEST_LOG_SUCC( " ProElementAlloc " );
status = ProElementIntegerSet ( pro_e_draft_include_tangent, 1 );
status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_draft_include_tangent );
PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" );
status = ProElementAlloc ( PRO_E_DRAFT_SIDE_1, &pro_e_draft_side_1 );
PT_TEST_LOG_SUCC( " ProElementAlloc " );
status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_draft_side_1 );
PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" );
status = ProElementAlloc ( PRO_E_DRAFT_NEUTRAL_OBJECT_TYPE_1, &pro_e_draft_neutral_object_type_1 );
PT_TEST_LOG_SUCC( " ProElementAlloc " );
/*---------------------------------------------------------------------*\
Using the Datum Plane as the draft hinge object type
\*---------------------------------------------------------------------*/
status = ProElementIntegerSet ( pro_e_draft_neutral_object_type_1, 1 );
status = ProElemtreeElementAdd ( pro_e_draft_side_1, NULL, pro_e_draft_neutral_object_type_1 );
PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" );
status = ProElementAlloc ( PRO_E_DRAFT_NEUTRAL_PLANE_1, &pro_e_draft_neutral_plane_1 );
PT_TEST_LOG_SUCC( " ProElementAlloc " );
status = ProElementReferenceSet ( pro_e_draft_neutral_plane_1, hinge_ref );
status = ProElemtreeElementAdd ( pro_e_draft_side_1, NULL, pro_e_draft_neutral_plane_1 );
PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" );
status = ProElementAlloc ( PRO_E_DRAFT_DEPENDENT_1, &pro_e_draft_dependent_1 );
PT_TEST_LOG_SUCC( " ProElementAlloc " );
status = ProElementIntegerSet ( pro_e_draft_dependent_1, 0 );
status = ProElemtreeElementAdd ( pro_e_draft_side_1, NULL, pro_e_draft_dependent_1 );
PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" );
status = ProElementAlloc ( PRO_E_DRAFT_ANGLE_1, &pro_e_draft_angle_1 );
PT_TEST_LOG_SUCC( " ProElementAlloc " );
status = ProElementDoubleSet ( pro_e_draft_angle_1, draft_angle );
status = ProElemtreeElementAdd ( pro_e_draft_side_1, NULL, pro_e_draft_angle_1 );
PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" );
status = ProElementAlloc ( PRO_E_DRAFT_ANGLES, &pro_e_draft_angles );
PT_TEST_LOG_SUCC( " ProElementAlloc " );
status = ProElemtreeElementAdd ( pro_e_draft_side_1, NULL, pro_e_draft_angles );
PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" );
status = ProElementAlloc ( PRO_E_DRAFT_SIDE_2, &pro_e_draft_side_2 );
PT_TEST_LOG_SUCC( " ProElementAlloc " );
status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_draft_side_2 );
PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" );
status = ProElementAlloc ( PRO_E_DRAFT_NEUTRAL_OBJECT_TYPE_2, &pro_e_draft_neutral_object_type_2 );
PT_TEST_LOG_SUCC( " ProElementAlloc " );
status = ProElementIntegerSet ( pro_e_draft_neutral_object_type_2, 0 );
status = ProElemtreeElementAdd ( pro_e_draft_side_2, NULL, pro_e_draft_neutral_object_type_2 );
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_DRAFT_DEPENDENT_2, &pro_e_draft_dependent_2 );
PT_TEST_LOG_SUCC( " ProElementAlloc " );
status = ProElementIntegerSet ( pro_e_draft_dependent_2, 0 );
status = ProElemtreeElementAdd ( pro_e_draft_side_2, NULL, pro_e_draft_dependent_2 );
PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" );
status = ProElementAlloc ( PRO_E_DRAFT_ANGLE_2, &pro_e_draft_angle_2 );
PT_TEST_LOG_SUCC( " ProElementAlloc " );
status = ProElementDoubleSet ( pro_e_draft_angle_2, 0.000000 );
status = ProElemtreeElementAdd ( pro_e_draft_side_2, NULL, pro_e_draft_angle_2 );
PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" );
status = ProElementAlloc ( PRO_E_DRAFT_ANGLES, &pro_e_draft_angles );
PT_TEST_LOG_SUCC( " ProElementAlloc " );
status = ProElemtreeElementAdd ( pro_e_draft_side_2, NULL, pro_e_draft_angles );
PT_TEST_LOG_SUCC( " ProElemtreeElementAdd" );
status = PTTestFeatureCreate_low ( model, pro_e_feature_tree );
PT_TEST_LOG_SUCC (" PTTestFeatureCreate_low");
return status;
}