/* Copyright (c) 2024 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved. */ /*--------------------------------------------------------------------*\ Pro/Toolkit includes -- include this first \*--------------------------------------------------------------------*/ #include <ProToolkit.h> #include <ProModFeat.h> #include <ProFeatType.h> #include <ProGraphic.h> #include <ProDisplist.h> #include <ProExtrude.h> #include <ProFeatForm.h> #include <ProStdSection.h> #include <ProTKRunTime.h> /*--------------------------------------------------------------------*\ Application includes \*--------------------------------------------------------------------*/ #include "UtilMath.h" #include "UtilMatrix.h" #include "UtilTree.h" #include "TestSect.h" #include <ProSolid.h> #include <ProMenu.h> #include <ProMdl.h> #include <TestError.h> #include <ProSolid.h> #include <UtilMessage.h> #include <ProWindows.h> #include <ProSurface.h> #include <ProUtil.h> #include <ProMessage.h> #include <UtilVisit.h> /*--------------------------------------------------------------------*\ Application data types \*--------------------------------------------------------------------*/ /* Section data structure */ typedef struct tag_SketchingData { ProSection section; /* The section to add sketched entities to */ ProMatrix trf_matrix; /* The matrix to transform screen coords to section coords */ ProMatrix mdl_matrix; /* The matrix to transform screen coords to model coords */ } SketchingData; typedef struct tag_DepthData { ProExtDepthFromType from_type; ProValueData from_value; ProExtDepthToType to_type; ProValueData to_value; } DepthData; typedef struct tag_DirectionArrow { ProPoint3d origin; ProVector dir_vector; ProSecViewDirType direction; int disp_id; } DirectionArrow; /* Message file name */ #define msgfil "feat" /* Array direction actions */ #define OKAY_DIRECTION 0 #define FLIP_DIRECTION 1 /* Sketching reference plane types */ #define SK_REF_NONE 0 #define SK_REF_TOP 1 #define SK_REF_BOTTOM 2 #define SK_REF_RIGHT 3 #define SK_REF_LEFT 4 #define SK_REF_DEFAULT 5 /* Sektcher actions */ #define SKETCHER_QUIT 0 #define SKETCHER_DONE 1 #define SKETCHER_SKETCH 2 /* Planes disposition constants */ #define UNKNOWN_PLANES -1 #define PARALLEL_PLANES 0 #define PERPENDICULAR_PLANES 1 /* Feature depth type */ #define DEPTH_TYPE_QUIT 0 #define DEPTH_TYPE_DONE 1 #define DEPTH_TYPE_BLIND 2 #define DEPTH_TYPE_2SIDEBLIND 3 #define DEPTH_TYPE_THRU_NEXT 4 #define DEPTH_TYPE_THRU_ALL 5 #define DEPTH_TYPE_THRU_UNTIL 6 #define DEPTH_TYPE_UPTO_PNT 7 #define DEPTH_TYPE_UPTO_CURVE 8 #define DEPTH_TYPE_UPTO_SURFACE 9 #define DEPTH_TYPE_NONE 10 #define SIZEOFARR(a) (sizeof(a)/(sizeof(a[0]))) /*--------------------------------------------------------------------*\ Application global variables \*--------------------------------------------------------------------*/ static int Disp_ID = 745; /*--------------------------------------------------------------------*\ Functions declaration \*--------------------------------------------------------------------*/ ProError ProTestFeatureExtrudeCreate(); ProError ProTestFirstFeatureCreate(ProMdl model); ProError ProTestFeatureAttrsRetrieve(ProSides *p_sides); int ProTestFeatSidesSet( ProSides *p_sides, ProSides sides ); ProError ProTestPlaneSelect(ProSurface *p_plane, ProSelection *p_plane_sel); ProError ProTestFeatureDirectionRetrieve ( ProSurface plane, ProSecViewDirType *p_direction); ProError ProTestDirectionArrowCreate( ProSurface plane, /* In: Sketching plane */ ProSecViewDirType init_dir, /* In: Init arrow direction: 1 - along normal vect; -1- reversed normal */ DirectionArrow *p_dir_arrow ); /* Out: Created direction arrow */ int ProTestDirectionArrowFlip( DirectionArrow *p_dir_arrow, /* In: [0] is origin point, [1] is direction vector */ int action ); /* In: OKAY_DIRECTION or FLIP_DIRECTION */ ProError ProTestDirectionArrowDraw( ProPoint3d point1, ProPoint3d point2, ProColor *p_color); ProError ProTestDirectionArrowDelete( DirectionArrow *p_dir_arrow ); ProError ProTestSketchingViewSet( ProSurface sk_plane, /* In: Sketching plane */ ProSecViewDirType direction, /* In: Feature direction */ int *p_ref_type, /* Out: Reference type */ ProSelection *p_ref_plane_sel, /* Out: Reference plane selection structure */ ProMatrix sk_view_matrix ); int ProTestRefPlaneTypeSet( int *p_ref_type, int ref_type ); ProError ProTestModelOrient( ProSurface sk_plane, /* In: Sketching plane */ ProSecViewDirType direction, /* In: Feature direction */ int ref_type, /* In: Orientation of reference plane */ ProSelection *p_ref_plane_sel, /* Out: Reference plane selection structure. Use ProSelectionFree to free the memory */ ProMatrix view_matrix ); /* Out: Matrix to to transform model coords to section coords */ ProBoolean ProTestPlanesPerpendicular( ProSurface plane1, ProSurface plane2 ); ProError ProTestSectionSketcher( ProMatrix sk_view_matrix, /* In: Matrix to convert model coords to section coords, (NULL- for 1st feature) */ ProSection *p_out_section, /* Out: The undimesioned section */ ProSelection **p_refs ); /* Out: Allocated array with selected references. Array must be released with ProTestSectionRefsFree. Pass NULL when creating the 1st feature */ int ProTestSpecifyRefsMenuPostaction(); ProError ProTestSketchingDataInit( ProSection section, /* In: The section */ ProMatrix sk_view_matrix, /* In: Matrix to convert model coords to section coords (NULL - for first feature */ SketchingData *p_sk_data ); /* Out: Initialized sketching data */ int ProTestSectionSketch( SketchingData *p_sk_data, int sketcher_action ); int ProTestSectionRefsSet( ProSelection **p_ref_sel); ProError ProTestSectionRefsFree( ProSelection **p_ref_sel ); ProError ProTestSectionDraw(); int ProTestSectionLineEntityCreate( SketchingData *p_sk_data); ProError ProTestSectionLineEntityAdd( SketchingData *p_sk_data, /* In: Sketching data */ ProPoint3d point1, /* In: Line end 1 in screen coords */ ProPoint3d point2 ); /* In: Line end 2 in screen coords */ ProError ProTestLineDraw( ProPoint3d point1, /* In: Screen coords of line end point*/ ProPoint3d point2, /* In: Screen coords of line end point*/ ProMatrix trf_matrix ); /* In: Matrx to convert screen coords into model coords (NULL)*/ int ProTestSectionRectangleEntityCreate( SketchingData *p_sk_data); ProError ProTestSectionRectangleEntityAdd( SketchingData *p_sk_data, /* In: Sketching data */ ProPoint3d point1, /* In: Screen coords of top point*/ ProPoint3d point3 ); /* In: Screen coords of bottom point */ ProError ProTestRectangleDraw( ProPoint3d point1, /* In: Screen coords of top point*/ ProPoint3d point3, /* In: Screen coords of bottom point */ ProMatrix trf_matrix ); /* In: Matrx to convert screen coords into model coords (NULL)*/ int ProTestSectionCircleEntityCreate( SketchingData *p_sk_data); ProError ProTestSectionCircleEntityAdd( SketchingData *p_sk_data, /* In: Sketching data */ ProPoint3d center, /* In: The center point */ ProPoint3d circle ); /* In: Circle point */ int ProTestSectionArcEntityCreate( SketchingData *p_sk_data); ProError ProTestCircleDraw( ProPoint3d center, /* In: Screen coords of center point */ ProPoint3d circle, /* In: Screen coords of circle point */ ProMatrix trf_matrix ); /* In: Matrx to convert screen coords into model coords (NULL) */ ProError ProTestPointDraw( ProPoint3d point, /* In: Point screen coords */ ProMatrix trf_matrix ); /* In: Matrx to convert screen coords into model coords (NULL) */ wchar_t *ProTestNewSectionNameGet( ProName w_name ); ProError ProTestProtrusionFeatureCreate( ProSecViewDirType view_direction, /* In: Feature direction */ ProSelection sk_plane_sel, /* In: The sketching plane selection */ int ref_type, /* In: The reference plane type (TOP, ...) */ ProSelection ref_plane_sel, /* In: The reference plane selection */ ProSection section, /* In: The sketched section */ ProSelection *p_references, /* In: The sketching references */ DepthData *p_depth, /* In: Initialized depth data */ ProFeature *p_feature ); /* Out: Created feature */ ProError ProTestFeatureSectionInit( ProFeature *p_feature, /* In: Incomplete feature */ ProSection section, /* In: Sketched section */ ProSelection *p_references, /* In: Sketching refs (NULL) */ ProBoolean is_first); /* In: If first feature or not */ ProError ProTestFeatureSectionRefsAdd( ProSection section, /* In: The section */ ProSelection *p_references ); /* In: The selected refs */ ProError ProTestSectionRegenerate( ProSection section ); ProError ProTestFeatureDepthRetrieve( ProSides sides, /* In: ONE_SIDE or BOTH_SIDES */ ProSecViewDirType direction, /* In: Feature direction */ ProSurface sk_plane, /* In: Sketching plane */ DepthData *p_depth ); /* Out: Initialized depth data. If ONE_SIDE, init only p_depth->to_*, setting from_type to DEPTH_TYPE_NONE */ ProError ProTestFeatureDepthTypeGet( ProSides sides, ProBoolean is_second_side, /* In: TRUE for 2nd side depth initialization. In this case "Blind" and "2 Side Blind" buttons are disabled */ int *p_depth_type ); /* Out: Depth type */ int ProTestFeatureDepthTypeSet( int *p_depth_type, int depth_type ); ProError ProTestFeatureDepthValueInit( ProSides sides, ProBoolean is_second_side, /* In: TRUE if for 2nd side depth initialization. In this case "Blind" and "2 Side Blind" buttons are disabled */ int *p_depth_type, ProValueData *p_depth_value ); double ProTestDoubleValueGet( double def ); /*-------------------------------------------- Declaration of variable SKETCHER_DONE_LOCAL and it is initialized to SKETCHER_QUIT to mean that sketch has not been done in the sketcher mode. --------------------------------------------*/ int SKETCHER_DONE_LOCAL = SKETCHER_QUIT; /*====================================================================*\ FUNCTION : ProTestFeatureExtrudeCreate PURPOSE : Retrieve all the necessary data and create extruded protrusion feature \*====================================================================*/ ProError ProTestFeatureExtrudeCreate() { ProError status; ProMdl model; int n_csys; ProSides sides; ProSecViewDirType direction; ProSurface sk_plane; ProSelection sk_plane_selection = NULL; int ref_plane_type; ProSelection ref_plane_selection = NULL; ProSection section; ProSelection *p_references = NULL; DepthData depth_data; ProMatrix sk_view_matrix; ProFeature feature; status = ProMdlCurrentGet( &model ); TEST_CALL_REPORT( "ProMdlCurrentGet()", "ProTestFeatureExtrudeCreate()", status, status != PRO_TK_NO_ERROR); /*--------------------------------------------------------------*\ Try to find the feature which is not csys. If there are no such kind of feature create one of type FIRST_FEATURE. \*--------------------------------------------------------------*/ status = ProSolidFeatVisit((ProSolid)model, (ProFeatureVisitAction)ProUtilNonCsysFeatCheck, (ProFeatureFilterAction)NULL, (ProAppData)&n_csys); TEST_CALL_REPORT("ProSolidFeatVisit()", "ProTestFeatureExtrudeCreate()", status, status != PRO_TK_NO_ERROR && status != PRO_TK_E_FOUND && status != PRO_TK_E_NOT_FOUND); if( status != PRO_TK_E_FOUND ) { return ProTestFirstFeatureCreate( model ); } status = ProTestFeatureAttrsRetrieve( &sides ); if( status == PRO_TK_NO_ERROR ) { ProUtilMsgPrint( msgfil, (char *)"USER Select or create a SKETCHING PLANE." ); status = ProTestPlaneSelect( &sk_plane, &sk_plane_selection ); } if( status == PRO_TK_NO_ERROR ) status = ProTestFeatureDirectionRetrieve( sk_plane, &direction ); if( status == PRO_TK_NO_ERROR ) status = ProTestSketchingViewSet( sk_plane, direction, &ref_plane_type, &ref_plane_selection, sk_view_matrix ); if( status == PRO_TK_NO_ERROR ) status = ProTestSectionSketcher( sk_view_matrix, §ion, &p_references ); if( status == PRO_TK_NO_ERROR ) status = ProTestFeatureDepthRetrieve( sides, direction, sk_plane, &depth_data ); if( status == PRO_TK_NO_ERROR ) ProTestProtrusionFeatureCreate( direction, sk_plane_selection, ref_plane_type, ref_plane_selection, section, p_references, &depth_data, &feature ); ProWindowRepaint( PRO_VALUE_UNUSED ); /* Free allocated memory */ if( sk_plane_selection != NULL ) ProSelectionFree( &sk_plane_selection ); if( ref_plane_selection != NULL ) ProSelectionFree( &ref_plane_selection ); if( p_references != NULL ) ProTestSectionRefsFree( &p_references ); return PRO_TK_NO_ERROR; } /*====================================================================*\ FUNCTION : ProTestFeatureAttrsRetrieve PURPOSE : Retrieve direction of feature creation \*====================================================================*/ ProError ProTestFeatureAttrsRetrieve( ProSides *p_sides ) /* Out: Direction of feature creation */ { ProError status; ProSides sides = (ProSides)(-1); int menu_id; int action; /*------------------------------------*\ Choose direction of feature creation \*------------------------------------*/ ProMenuFileRegister( (char *)"TK SIDES", (char *)"tksides.mnu", &menu_id ); ProMenubuttonActionSet( (char *)"TK SIDES", (char *)"One Side", (ProMenubuttonAction)ProTestFeatSidesSet, &sides, PRO_SIDES_ONE_SIDE ); ProMenubuttonActionSet( (char *)"TK SIDES", (char *)"Both Sides", (ProMenubuttonAction)ProTestFeatSidesSet, &sides,PRO_SIDES_BOTH_SIDES ); ProMenubuttonActionSet( (char *)"TK SIDES", (char *)"TK SIDES", (ProMenubuttonAction)ProMenuDelete, NULL, 0 ); status = ProMenuCreate( PROMENUTYPE_MAIN, (char *)"TK SIDES", &menu_id ); if( status == PRO_TK_NO_ERROR ) { status = ProMenuProcess( (char *)"TK SIDES", &action ); } if( sides != -1 ) { *p_sides = sides; status = PRO_TK_NO_ERROR; } else status = PRO_TK_GENERAL_ERROR; return status; } /*====================================================================*\ FUNCTION : ProTestFeatSidesSet PURPOSE : ProMenubuttonAction for TK SIDES \*====================================================================*/ int ProTestFeatSidesSet( ProSides *p_sides, ProSides sides ) { *p_sides = sides; ProMenuDelete(); return 0; } /*====================================================================*\ FUNCTION : ProTestPlaneSelect PURPOSE : Select plane feature in current model \*====================================================================*/ ProError ProTestPlaneSelect( ProSurface *p_plane, /* Out: Selected plane */ ProSelection *p_plane_sel ) /* Out: Selection structure (NULL). Use ProSelectionFree to free the memory */ { ProError status; ProSelection *p_sel; int n_sel; ProModelitem model_item; ProSurface surface; ProSrftype srf_type = PRO_SRF_NONE; do { n_sel = 0; srf_type = PRO_SRF_NONE; /* Select surface */ status = ProSelect( (char *)"surface,sldface,qltface,datum", 1, NULL, NULL, NULL, NULL, &p_sel, &n_sel ); TEST_CALL_REPORT( "ProSelect()", "ProTestPlaneSelect()", status, status != PRO_TK_NO_ERROR); if( status != PRO_TK_NO_ERROR || n_sel < 1 ) return PRO_TK_GENERAL_ERROR; /* Check out model item */ status = ProSelectionModelitemGet( p_sel[0], &model_item ); TEST_CALL_REPORT( "ProSelectionModelitemGet", "ProTestPlaneSelect()", status, status != PRO_TK_NO_ERROR); if( model_item.type != PRO_SURFACE && model_item.type != PRO_DATUM_PLANE ) { ProUtilMsgPrint( msgfil, (char *)"USER Only planes are allowed" ); continue; } /* Get the selected surface */ status = ProSurfaceInit( model_item.owner, model_item.id, &surface ); TEST_CALL_REPORT( "ProSurfaceInit", "ProTestPlaneSelect()", status, status != PRO_TK_NO_ERROR); if( status != PRO_TK_NO_ERROR ) continue; /* Check out the surface type. A plane is only acceptable */ status = ProSurfaceTypeGet( surface, &srf_type ); TEST_CALL_REPORT( "ProSurfaceTypeGet", "ProTestPlaneSelect()", status, status != PRO_TK_NO_ERROR); if( srf_type != PRO_SRF_PLANE ) { ProUtilMsgPrint( msgfil, (char *)"USER Only planes are allowed" ); continue; } } while( srf_type != PRO_SRF_PLANE ); memcpy( p_plane, &surface, sizeof(ProSurface) ); if( p_plane_sel ) { status = ProSelectionCopy( *p_sel, p_plane_sel ); TEST_CALL_REPORT( "ProSelectionCopy", "ProTestPlaneSelect()", status, status != PRO_TK_NO_ERROR ); } return PRO_TK_NO_ERROR; } /*====================================================================*\ FUNCTION : ProTestFeatureDirectionRetrieve PURPOSE : Retrieve feature creation direction basing on sketching plane \*====================================================================*/ ProError ProTestFeatureDirectionRetrieve( ProSurface plane, /* In: Sketching plane */ ProSecViewDirType *p_direction ) /* Out: Direction */ { ProError status; int menu_id; int action = OKAY_DIRECTION; DirectionArrow dir_arrow; ProUtilMsgPrint( msgfil, (char *)"USER Arrow shows direction of feature creation" ); /* Create and display initial direction arrow */ ProTestDirectionArrowCreate( plane, (ProSecViewDirType)1, &dir_arrow ); /* Choose feature direction */ ProMenuFileRegister( (char *)"TK DIRECTION", (char *)"tkdirection.mnu", &menu_id ); ProMenubuttonActionSet( (char *)"TK DIRECTION", (char *)"Flip", (ProMenubuttonAction)ProTestDirectionArrowFlip, &dir_arrow, FLIP_DIRECTION ); ProMenubuttonActionSet( (char *)"TK DIRECTION", (char *)"Okay", (ProMenubuttonAction)ProTestDirectionArrowFlip, &dir_arrow, OKAY_DIRECTION ); status = ProMenuCreate( PROMENUTYPE_MAIN, (char *)"TK DIRECTION", &menu_id ); if( status == PRO_TK_NO_ERROR ) { status = ProMenuProcess( (char *)"TK DIRECTION", &action ); } /* Init output value */ if( dir_arrow.direction > 0 ) *p_direction = PRO_SEC_VIEW_DIR_SIDE_ONE; else *p_direction = PRO_SEC_VIEW_DIR_SIDE_TWO; /* Delete direction arrow */ ProTestDirectionArrowDelete( &dir_arrow ); return PRO_TK_NO_ERROR; } /*====================================================================*\ FUNCTION : ProTestDirectionArrowCreate PURPOSE : Create arrow image \*====================================================================*/ ProError ProTestDirectionArrowCreate( ProSurface plane, /* In: Sketching plane */ ProSecViewDirType init_dir, /* In: Init arrow direction: 1 - along normal vect; -1- reversed normal */ DirectionArrow *p_dir_arrow ) /* Out: Created direction arrow */ { ProError status; ProPoint3d point2; ProGeomitemdata *p_geom_data; ProColor color; ProMatrix transform; /* Get the plane geom data */ status = ProSurfaceDataGet( plane, &p_geom_data ); TEST_CALL_REPORT( "ProSurfaceDataGet", "ProTestDirectionArrowCreate()", status, status != PRO_TK_NO_ERROR ); /* Retrieve the point on the plane to place direction arrow */ status = ProSurfaceXyzdataEval( plane, p_geom_data->data.p_surface_data->uv_max, p_dir_arrow->origin, NULL, NULL, p_dir_arrow->dir_vector ); TEST_CALL_REPORT( "ProSurfaceXyzdataEval", "ProTestDirectionArrowCreate()", status, status != PRO_TK_NO_ERROR ); p_dir_arrow->direction = init_dir; p_dir_arrow->disp_id = Disp_ID++; /* Get the end point of direction vector */ point2[0] = p_dir_arrow->origin[0] + p_dir_arrow->dir_vector[0]*0.6*init_dir; point2[1] = p_dir_arrow->origin[1] + p_dir_arrow->dir_vector[1]*0.6*init_dir; point2[2] = p_dir_arrow->origin[2] + p_dir_arrow->dir_vector[2]*0.6*init_dir; /* Draw the arrow */ color.method = PRO_COLOR_METHOD_TYPE; color.value.type = PRO_COLOR_HIGHLITE; status = ProWindowCurrentMatrixGet( transform ); TEST_CALL_REPORT( "ProWindowCurrentMatrixGet", "ProTestDirectionArrowCreate()", status, status != PRO_TK_NO_ERROR ); status = ProDisplist3dCreate( p_dir_arrow->disp_id, (ProDisplistCallback)ProTestDirectionArrowDraw, p_dir_arrow->origin, point2, &color ); TEST_CALL_REPORT( "ProDisplist3dCreate", "ProTestDirectionArrowCreate()", status, status != PRO_TK_NO_ERROR ); status = ProDisplist3dDisplay( p_dir_arrow->disp_id, transform ); TEST_CALL_REPORT( "ProDisplist3dDisplay", "ProTestDirectionArrowCreate()", status, status != PRO_TK_NO_ERROR ); status = ProWindowRepaint( PRO_VALUE_UNUSED ); TEST_CALL_REPORT( "ProWindowRepaint", "ProTestDirectionArrowCreate()", status, status != PRO_TK_NO_ERROR ); /* Release the memory allocated by ProSurfaceDataGet */ status = ProGeomitemdataFree( &p_geom_data ); TEST_CALL_REPORT( "ProGeomitemdataFree", "ProTestDirectionArrowCreate()", status, status != PRO_TK_NO_ERROR ); return PRO_TK_NO_ERROR; } /*====================================================================*\ FUNCTION : ProTestDirectionArrowFlip PURPOSE : Flip arrow image \*====================================================================*/ int ProTestDirectionArrowFlip( DirectionArrow *p_dir_arrow, /* In: [0] is origin point, [1] is direction vector */ int action ) /* In: OKAY_DIRECTION or FLIP_DIRECTION */ { ProError status; ProPoint3d point2; ProColor color; ProMatrix transform; if( action == OKAY_DIRECTION ) { ProMenuDelete(); return 0; } /* Inverse direction */ p_dir_arrow->direction = (ProSecViewDirType)-p_dir_arrow->direction; /* Set the arrow color */ if( p_dir_arrow->direction > 0 ) { color.method = PRO_COLOR_METHOD_TYPE; color.value.type = PRO_COLOR_HIGHLITE; } else { color.method = PRO_COLOR_METHOD_TYPE; color.value.type = PRO_COLOR_LETTER; } /* Get the end point og direction vector */ point2[0] = p_dir_arrow->origin[0] + p_dir_arrow->dir_vector[0] * p_dir_arrow->direction * 0.6; point2[1] = p_dir_arrow->origin[1] + p_dir_arrow->dir_vector[1] * p_dir_arrow->direction * 0.6; point2[2] = p_dir_arrow->origin[2] + p_dir_arrow->dir_vector[2] * p_dir_arrow->direction * 0.6; /* Delete previous arrow */ ProDisplist3dDelete( p_dir_arrow->disp_id ); /* Draw the arrow */ status = ProWindowCurrentMatrixGet( transform ); TEST_CALL_REPORT( "ProWindowCurrentMatrixGet","ProTestDirectionArrowFlip()", status, status != PRO_TK_NO_ERROR ); status = ProDisplist3dCreate( p_dir_arrow->disp_id, (ProDisplistCallback)ProTestDirectionArrowDraw, p_dir_arrow->origin, point2, &color ); TEST_CALL_REPORT( "ProDisplist3dCreate","ProTestDirectionArrowFlip()", status, status != PRO_TK_NO_ERROR ); status = ProDisplist3dDisplay( p_dir_arrow->disp_id, transform ); TEST_CALL_REPORT( "ProDisplist3dDisplay","ProTestDirectionArrowFlip()", status, status != PRO_TK_NO_ERROR ); status = ProWindowRepaint( PRO_VALUE_UNUSED ); TEST_CALL_REPORT( "ProWindowRepaint","ProTestDirectionArrowFlip()", status, status != PRO_TK_NO_ERROR ); return 0; } /*====================================================================*\ FUNCTION : ProTestDirectionArrowDraw PURPOSE : Draw the arrow. This is the display list creation callback function \*====================================================================*/ ProError ProTestDirectionArrowDraw( ProPoint3d point1, ProPoint3d point2, ProColor *p_color) { ProError status; ProLinestyle old_line_style; ProColor old_color; ProPoint3d center; double radius; double dx, dy, dz; int i; /* Set new style and color */ status = ProLinestyleSet( PRO_LINESTYLE_SOLID, &old_line_style ); TEST_CALL_REPORT( "ProLinestyleSet","ProTestDirectionArrowDraw()", status, status != PRO_TK_NO_ERROR && status != PRO_TK_NO_CHANGE); status = ProGraphicsColorModify( p_color, &old_color ); TEST_CALL_REPORT( "ProGraphicsColorModify","ProTestDirectionArrowDraw()", status, status != PRO_TK_NO_ERROR ); ProGraphicsPenPosition( point1 ); ProGraphicsLineDraw( point2 ); dx = (point2[0] - point1[0]) / 6; dy = (point2[1] - point1[1]) / 6; dz = (point2[2] - point1[2]) / 6; center[0] = point1[0]; center[1] = point1[1]; center[2] = point1[2]; radius = 0.08; for( i=0; i<8; i++ ) { ProGraphicsCircleDraw( center, radius ); center[0] += dx; center[1] += dy; center[2] += dz; radius -= 0.01; } /* Restore style and color */ status = ProLinestyleSet( old_line_style, &old_line_style ); TEST_CALL_REPORT( "ProLinestyleSet","ProTestDirectionArrowDraw()", status, status != PRO_TK_NO_ERROR && status != PRO_TK_NO_CHANGE); status = ProGraphicsColorModify( &old_color, NULL ); TEST_CALL_REPORT( "ProGraphicsColorModify","ProTestDirectionArrowDraw()", status, status != PRO_TK_NO_ERROR ); return PRO_TK_NO_ERROR; } /*====================================================================*\ FUNCTION : ProTestDirectionArrowDelete PURPOSE : Delete the arrow. \*====================================================================*/ ProError ProTestDirectionArrowDelete( DirectionArrow *p_dir_arrow ) /* In: Dir arrow structure */ { ProError status; status = ProDisplist3dDelete( p_dir_arrow->disp_id ); TEST_CALL_REPORT( "ProDisplist3dDelete","ProTestDirectionArrowDelete()", status, status != PRO_TK_NO_ERROR ); status = ProWindowRepaint( PRO_VALUE_UNUSED ); TEST_CALL_REPORT( "ProWindowRepaint","ProTestDirectionArrowDelete()", status, status != PRO_TK_NO_ERROR ); return PRO_TK_NO_ERROR; } /*====================================================================*\ FUNCTION : ProTestSketchingViewSet PURPOSE : Select reference type and set the view for sketching \*====================================================================*/ ProError ProTestSketchingViewSet( ProSurface sk_plane, /* In: Sketching plane */ ProSecViewDirType direction, /* In: Feature direction */ int *p_ref_type, /* Out: Reference type */ ProSelection *p_ref_plane_sel, /* Out: Reference plane selection structure */ ProMatrix sk_view_matrix ) /* Out: Matrix to to transform model coords to section coords */ { ProError status; int menu_id; int action = 0; int ref_type = SK_REF_NONE; ProUtilMsgPrint( msgfil, (char *)"USER Select reference for sketching" ); /*--------------------------------------------*\ Choose reference plane type \*--------------------------------------------*/ ProMenuFileRegister( (char *)"TK SKET VIEW", (char *)"tk_orient.mnu", &menu_id ); ProMenubuttonActionSet( (char *)"TK SKET VIEW", (char *)"Top", (ProMenubuttonAction)ProTestRefPlaneTypeSet, (ProAppData)&ref_type, SK_REF_TOP ); ProMenubuttonActionSet( (char *)"TK SKET VIEW", (char *)"Bottom", (ProMenubuttonAction)ProTestRefPlaneTypeSet, (ProAppData)&ref_type, SK_REF_BOTTOM ); ProMenubuttonActionSet( (char *)"TK SKET VIEW", (char *)"Right", (ProMenubuttonAction)ProTestRefPlaneTypeSet, (ProAppData)&ref_type, SK_REF_RIGHT ); ProMenubuttonActionSet( (char *)"TK SKET VIEW", (char *)"Left", (ProMenubuttonAction)ProTestRefPlaneTypeSet, (ProAppData)&ref_type, SK_REF_LEFT ); ProMenubuttonActionSet( (char *)"TK SKET VIEW", (char *)"Quit", (ProMenubuttonAction)ProTestRefPlaneTypeSet, (ProAppData)&ref_type, SK_REF_NONE ); ProMenubuttonActionSet( (char *)"TK SKET VIEW", (char *)"TK SKET VIEW", (ProMenubuttonAction)ProTestRefPlaneTypeSet, (ProAppData)&ref_type, SK_REF_NONE ); status = ProMenuCreate( PROMENUTYPE_MAIN, (char *)"TK SKET VIEW", &menu_id ); if( status == PRO_TK_NO_ERROR ) { status = ProMenuProcess( (char *)"TK SKET VIEW", &action ); if( action != 0 ) return PRO_TK_GENERAL_ERROR; } /*--------------------------------------------*\ Set the new view for sketching \*--------------------------------------------*/ status = ProTestModelOrient( sk_plane, direction, ref_type, p_ref_plane_sel, sk_view_matrix ); *p_ref_type = ref_type; return status; } /*====================================================================*\ FUNCTION : ProTestRefPlaneTypeSet PURPOSE : \*====================================================================*/ int ProTestRefPlaneTypeSet( int *p_ref_type, int ref_type ) { *p_ref_type = ref_type; if( ref_type == SK_REF_NONE ) ProMenuDeleteWithStatus( -1 ); else ProMenuDeleteWithStatus( 0 ); return 0; } #if 0 int print_matrix( ProMatrix m ) { int i,j; for( i=0; i<4; i++ ) { for( j=0; j<4; j++ ) printf( "%f ", m[i][j] ); putchar( '\n' ); } putchar( '\n' ); return 0; } int print_vector( ProVector m ) { int i,j; for( i=0; i<3; i++ ) printf( "%f ", m[i] ); putchar( '\n' ); return 0; } #endif /*====================================================================*\ FUNCTION : ProTestModelOrient PURPOSE : Select reference plane, generate sketching view matrix and set the view for sketching \*====================================================================*/ ProError ProTestModelOrient( ProSurface sk_plane, /* In: Sketching plane */ ProSecViewDirType direction, /* In: Feature direction */ int ref_type, /* In: Orientation of reference plane */ ProSelection *p_ref_plane_sel, /* Out: Reference plane selection structure. Use ProSelectionFree to free the memory */ ProMatrix view_matrix ) /* Out: Matrix to to transform model coords to section coords */ { ProError status; ProSurface ref_plane; ProVector orig_vector = { 0.0, 0.0, 0.0 }; ProVector tmp_orig; ProGeomitemdata *p_geom_data; ProVector x_vector; ProVector y_vector; ProVector z_vector; ProVector sk_plane_normal; ProVector ref_plane_normal; ProMatrix new_matrix; /* Select the reference plane which is perpendicular to the sketching plane */ do { status = ProTestPlaneSelect( &ref_plane, p_ref_plane_sel ); if( status != PRO_TK_NO_ERROR ) return status; } while( ProTestPlanesPerpendicular( sk_plane, ref_plane ) != PRO_B_TRUE ); /* Get the reference plane normal vector */ status = ProSurfaceDataGet( ref_plane, &p_geom_data ); TEST_CALL_REPORT( "ProSurfaceDataGet","ProTestModelOrient()", status, status != PRO_TK_NO_ERROR ); status = ProSurfaceXyzdataEval( ref_plane, p_geom_data->data.p_surface_data->uv_max, tmp_orig, NULL, NULL, ref_plane_normal ); TEST_CALL_REPORT( "ProSurfaceXyzdataEval","ProTestModelOrient()", status, status != PRO_TK_NO_ERROR ); status = ProGeomitemdataFree( &p_geom_data ); TEST_CALL_REPORT( "ProGeomitemdataFree","ProTestModelOrient()", status, status != PRO_TK_NO_ERROR ); /* Get the sketching plane normal vector */ status = ProSurfaceDataGet( sk_plane, &p_geom_data ); TEST_CALL_REPORT( "ProSurfaceDataGet","ProTestModelOrient()", status, status != PRO_TK_NO_ERROR ); status = ProSurfaceXyzdataEval( sk_plane, p_geom_data->data.p_surface_data->uv_max, tmp_orig, NULL, NULL, sk_plane_normal ); TEST_CALL_REPORT( "ProSurfaceXyzdataEval","ProTestModelOrient()", status, status != PRO_TK_NO_ERROR ); status = ProGeomitemdataFree( &p_geom_data ); TEST_CALL_REPORT( "ProGeomitemdataFree","ProTestModelOrient()", status, status != PRO_TK_NO_ERROR ); /* Use sketching plane normal vector as Z vector of new view */ ProUtilVectorCopy( sk_plane_normal, z_vector ); /* Reverse Z vector if we use "flipped" direction for protrusion creation */ if( direction == PRO_SEC_VIEW_DIR_SIDE_TWO ) ProUtilVectorScale( -1.0, z_vector, z_vector ); /* Generate the vectors for new view */ switch( ref_type ) { case SK_REF_TOP: ProUtilVectorCopy( ref_plane_normal, y_vector ); ProUtilVectorCross( y_vector, z_vector, x_vector ); break; case SK_REF_BOTTOM: ProUtilVectorScale( -1.0, ref_plane_normal, y_vector ); ProUtilVectorCross( y_vector, z_vector, x_vector ); break; case SK_REF_RIGHT: ProUtilVectorCopy( ref_plane_normal, x_vector ); ProUtilVectorCross( z_vector, x_vector, y_vector ); break; case SK_REF_LEFT: ProUtilVectorScale( -1.0, ref_plane_normal, x_vector ); ProUtilVectorCross( z_vector, x_vector, y_vector ); break; } /* Set new view matrix */ status = ProMatrixInit( x_vector, y_vector, z_vector, orig_vector, new_matrix ); TEST_CALL_REPORT( "ProMatrixInit","ProTestModelOrient()", status, status != PRO_TK_NO_ERROR ); ProUtilMatrixInvert( new_matrix, view_matrix ); status = ProViewMatrixSet( NULL, NULL, view_matrix ); TEST_CALL_REPORT( "ProViewMatrixSet","ProTestModelOrient()", status, status != PRO_TK_NO_ERROR ); ProWindowRefresh( PRO_VALUE_UNUSED ); status = ProWindowRepaint( PRO_VALUE_UNUSED ); TEST_CALL_REPORT( "ProWindowRepaint","ProTestModelOrient()", status, status != PRO_TK_NO_ERROR ); return PRO_TK_NO_ERROR; } /*====================================================================*\ FUNCTION : ProTestPlanesPerpendicular PURPOSE : Check out if two planes are perpendicular. \*====================================================================*/ ProBoolean ProTestPlanesPerpendicular( ProSurface plane1, ProSurface plane2 ) { ProError status; ProGeomitemdata *p_geom_data1 = NULL; ProGeomitemdata *p_geom_data2 = NULL; double dot; /* Get the planes geom data */ status = ProSurfaceDataGet( plane1, &p_geom_data1 ); TEST_CALL_REPORT( "ProSurfaceDataGet","ProTestPlanesPerpendicular()", status, status != PRO_TK_NO_ERROR ); if( status != PRO_TK_NO_ERROR ) return PRO_B_FALSE; status = ProSurfaceDataGet( plane2, &p_geom_data2 ); TEST_CALL_REPORT( "ProSurfaceDataGet","ProTestPlanesPerpendicular()", status, status != PRO_TK_NO_ERROR ); if( status != PRO_TK_NO_ERROR ) return PRO_B_FALSE; /* If dot product of planes normals is 0.0 the planes are perpendicular */ dot = ProUtilVectorDot( p_geom_data1->data.p_surface_data->srf_shape.plane.e3, p_geom_data2->data.p_surface_data->srf_shape.plane.e3 ); /* Release the mem allocated with ProSurfaceDataGet */ status = ProGeomitemdataFree( &p_geom_data1 ); TEST_CALL_REPORT( "ProGeomitemdataFree","ProTestPlanesPerpendicular()", status, status != PRO_TK_NO_ERROR ); status = ProGeomitemdataFree( &p_geom_data2 ); TEST_CALL_REPORT( "ProGeomitemdataFree","ProTestPlanesPerpendicular()", status, status != PRO_TK_NO_ERROR ); if( fabs( dot ) < EPSM6 ) return PRO_B_TRUE; else return PRO_B_FALSE; } /*====================================================================*\ FUNCTION : ProTestSectionSketcher PURPOSE : Create the section \*====================================================================*/ ProError ProTestSectionSketcher( ProMatrix sk_view_matrix, /* In: Matrix to convert model coords to section coords, (NULL- for 1st feature) */ ProSection *p_out_section, /* Out: The undimesioned section */ ProSelection **p_refs ) /* Out: Allocated array with selected references. Array must be released with ProTestSectionRefsFree. Pass NULL when creating the 1st feature */ { ProError status = PRO_TK_NO_ERROR; int menu_id; int action = SKETCHER_QUIT; static char *p_menus[] = { (char *)"TK SKETCHER", (char *)"DONE QUIT", (char *)"" }; ProSection section; ProName w_section_name; ProSelection *p_ref_sel = NULL; SketchingData sk_data; /*-------------------------------------------*\ Allocate the new section and set its name \*-------------------------------------------*/ status = ProSection2DAlloc( §ion ); TEST_CALL_REPORT( "ProSection2DAlloc","ProTestSectionSketcher()", status, status != PRO_TK_NO_ERROR ); if( status == PRO_TK_NO_ERROR ) { status = ProSectionNameSet( section, ProTestNewSectionNameGet( w_section_name ) ); TEST_CALL_REPORT( "ProSectionNameSet","ProTestSectionSketcher()", status, status != PRO_TK_NO_ERROR ); } if( status != PRO_TK_NO_ERROR ) return status; /*-------------------------------------------*\ Init sketching data structure \*-------------------------------------------*/ ProTestSketchingDataInit( section, sk_view_matrix, &sk_data ); /*-------------------------------------------*\ Specify references and draw the section. \*-------------------------------------------*/ ProMenuFileRegister( (char *)"TK SKETCHER", (char *)"tksketcher.mnu", &menu_id ); ProMenubuttonActionSet( (char *)"TK SKETCHER", (char *)"Sketch", (ProMenubuttonAction)ProTestSectionSketch, (ProAppData)&sk_data, SKETCHER_SKETCH ); ProMenubuttonActionSet( (char *)"TK SKETCHER", (char *)"Specify Refs", (ProMenubuttonAction)ProTestSectionRefsSet, (ProAppData)&p_ref_sel, 0 ); ProMenubuttonActionSet( (char *)"TK SKETCHER", (char *)"TK SKETCHER", (ProMenubuttonAction)ProTestSectionSketch, (ProAppData)&sk_data, SKETCHER_QUIT ); ProMenuFileRegister( (char *)"DONE QUIT", (char *)"tkdonequit.mnu", &menu_id ); ProMenubuttonActionSet( (char *)"DONE QUIT", (char *)"-Done", (ProMenubuttonAction)ProTestSectionSketch, (ProAppData)&sk_data, SKETCHER_DONE ); ProMenubuttonActionSet( (char *)"DONE QUIT", (char *)"-Quit", (ProMenubuttonAction)ProTestSectionSketch, (ProAppData)&sk_data, SKETCHER_QUIT ); ProMenubuttonActionSet( (char *)"DONE QUIT", (char *)"DONE QUIT", (ProMenubuttonAction)ProTestSectionSketch, (ProAppData)&sk_data, SKETCHER_QUIT ); action = SKETCHER_QUIT; status = ProCompoundmenuCreate( p_menus, &menu_id ); if( status == PRO_TK_NO_ERROR ) { /*--------------------------------------------------*\ Do not specify references for the 1st feature \*--------------------------------------------------*/ if( p_refs == NULL ) { ProMenubuttonDeactivate( (char *)"TK SKETCHER", (char *)"Specify Refs" ); ProMenuCommandPush( (char *)"Sketch" ); } else { ProMenubuttonActivate( (char *)"TK SKETCHER", (char *)"Specify Refs" ); ProMenuCommandPush( (char *)"Specify Refs" ); } ProMenuProcess( (char *)"TK SKETCHER", &action ); } /*------------------------------------------------------------------ This if block is executed only if the user sketch entities in the Sketcher mode and pick -Done in the menu.Otherwise this fn will return PRO_TK_USER_ABORT. ------------------------------------------------------------------*/ if( action == SKETCHER_DONE && SKETCHER_DONE_LOCAL == SKETCHER_DONE) { /* Init output data */ memcpy( p_out_section, &(sk_data.section), sizeof(ProSection) ); if( p_refs != NULL ) *p_refs = p_ref_sel; status = PRO_TK_NO_ERROR; } else { /* Section creation process was canceled. Delete incomplete section. */ status = ProSectionFree( §ion ); TEST_CALL_REPORT( "ProSectionFree","ProTestSectionSketcher()", status, status != PRO_TK_NO_ERROR ); if( p_ref_sel != NULL ) ProTestSectionRefsFree( &p_ref_sel ); status = PRO_TK_USER_ABORT; } return status; } /*====================================================================*\ FUNCTION : ProTestSketchingDataInit PURPOSE : Initialize sketching data structure to use it in sketching menu actions \*====================================================================*/ ProError ProTestSketchingDataInit( ProSection section, /* In: The section */ ProMatrix sk_view_matrix, /* In: Matrix to convert model coords to section coords (NULL - for first feature */ SketchingData *p_sk_data ) /* Out: Initialized sketching data */ { ProMatrix mdl_matrix; ProMatrix identity_matrix = { {1.0, 0.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 0.0, 1.0} }; p_sk_data->section = section; /*------------------------------------------------------------------*\ Create matrix to transform screen coords to model coords \*------------------------------------------------------------------*/ ProViewMatrixGet( NULL, NULL, mdl_matrix ); ProUtilMatrixInvert( mdl_matrix, p_sk_data->mdl_matrix ); if( sk_view_matrix == NULL ) { /*------------------------------------------------------------------*\ For the first feature use identity matrix to transform screen coords to section coords \*------------------------------------------------------------------*/ ProUtilMatrixCopy( identity_matrix, p_sk_data->trf_matrix ); return PRO_TK_NO_ERROR; } /*------------------------------------------------------------------*\ Create matrix to transform screen coords to section coords \*------------------------------------------------------------------*/ ProUtilMatrixProduct( p_sk_data->mdl_matrix, sk_view_matrix, p_sk_data->trf_matrix ); return PRO_TK_NO_ERROR; } /*====================================================================*\ FUNCTION : ProTestSectionSketch PURPOSE : Select from menu to draw the entities of section \*====================================================================*/ int ProTestSectionSketch( SketchingData *p_sk_data, int sketcher_action ) { ProError status; int menu_id; int action; /*-------------------------------------------*\ Check for sketcher exiting \*-------------------------------------------*/ if( sketcher_action == SKETCHER_DONE || sketcher_action == SKETCHER_QUIT ) { ProMenuDeleteWithStatus( sketcher_action ); ProMenuDeleteWithStatus( sketcher_action ); return 0; } /*-------------------------------------------*\ Choose entity type and draw it \*-------------------------------------------*/ ProMenuFileRegister( (char *)"TK GEOMETRY", (char *)"tksketgeom.mnu", &menu_id ); ProMenubuttonActionSet( (char *)"TK GEOMETRY", (char *)"Point", (ProMenubuttonAction)NULL, (ProAppData)p_sk_data, 0 ); ProMenubuttonActionSet( (char *)"TK GEOMETRY", (char *)"Line", (ProMenubuttonAction)ProTestSectionLineEntityCreate, (ProAppData)p_sk_data, 0 ); ProMenubuttonActionSet( (char *)"TK GEOMETRY", (char *)"Rectangle", (ProMenubuttonAction)ProTestSectionRectangleEntityCreate, (ProAppData)p_sk_data, 0 ); ProMenubuttonActionSet( (char *)"TK GEOMETRY", (char *)"Circle", (ProMenubuttonAction)ProTestSectionCircleEntityCreate, (ProAppData)p_sk_data, 0 ); ProMenubuttonActionSet( (char *)"TK GEOMETRY", (char *)"Arc", (ProMenubuttonAction)ProTestSectionArcEntityCreate, (ProAppData)p_sk_data, 0 ); ProMenubuttonActionSet( (char *)"TK GEOMETRY", (char *)"TK GEOMETRY", (ProMenubuttonAction)ProMenuDelete, (ProAppData)p_sk_data, 0 ); status = ProMenuCreate( PROMENUTYPE_MAIN, (char *)"TK GEOMETRY", &menu_id ); if( status == PRO_TK_NO_ERROR ) { ProMenubuttonDeactivate( (char *)"TK GEOMETRY", (char *)"Point"); ProMenubuttonDeactivate( (char *)"TK GEOMETRY", (char *)"Arc" ); status = ProMenuProcess( (char *)"TK GEOMETRY", &action ); } return 0; } /*====================================================================*\ FUNCTION : ProTestSectionRefsSet PURPOSE : "Set Refs" on-button function. Select sketching references \*====================================================================*/ int ProTestSectionRefsSet( ProSelection **p_ref_sel) /* Out: If NULL - Allocated array with selected references. Array must be released with ProTestSectionRefsFree. If !NULL - contains previously selected references. */ { ProError status; ProSelection *p_sel; int n_sel = 0; int i; /*------------------------------------------------- Note: The variable SKETCHER_DONE_LOCAL is set to SKETCHER_QUIT and this can be changed to SKETCHER_DONE only by a fn call to create entities in the sketcher.Those calls are ProTestSectionRectangleEntityCreate() ProTestSectionCircleEntityCreate() ProTestSectionLineEntityCreate() ---------------------------------------------------*/ SKETCHER_DONE_LOCAL = SKETCHER_QUIT; /*------------------------------------------------- Note:The Sketch menu is hiden untill the sketcher reference is not given. ---------------------------------------------------*/ ProMenubuttonDeactivate( (char *)"TK SKETCHER", (char *)"Sketch" ); ProUtilMsgPrint( msgfil, (char *)"USER Select a perpendicular surface" ); /* Select an edge to use as dimension/constrain reference */ status = ProSelect( (char *)"datum,sldedge,edge,curve,point,edge_end,surface,sldface", 2, *p_ref_sel, NULL, NULL, NULL, &p_sel, &n_sel ); TEST_CALL_REPORT( "ProSelect","ProTestSectionRefsSet()", status, status != PRO_TK_NO_ERROR ); if( status != PRO_TK_NO_ERROR || n_sel < 1 ) { return -1; } else { ProMenubuttonActivate( (char *)"TK SKETCHER", (char *)"Sketch" ); } /* Delete initial references if necessary */ if( *p_ref_sel != NULL ) ProTestSectionRefsFree( p_ref_sel ); /* Copy selected referencies to output array */ status = ProArrayAlloc( n_sel, sizeof(ProSelection), 1, (ProArray*)p_ref_sel ); TEST_CALL_REPORT( "ProArrayAlloc","ProTestSectionRefsSet()", status, status != PRO_TK_NO_ERROR ); if( status != PRO_TK_NO_ERROR) return -1; for( i=0; i<n_sel; i++ ) { status = ProSelectionCopy( p_sel[i], *p_ref_sel + i ); TEST_CALL_REPORT( "ProSelectionCopy","ProTestSectionRefsSet()", status, status != PRO_TK_NO_ERROR ); } /* Call the sketcher next */ status = ProMenuCommandPush( (char *)"Sketch" ); TEST_CALL_REPORT( "ProMenuCommandPush","ProTestSectionRefsSet()", status, status != PRO_TK_NO_ERROR ); return 0; } /*====================================================================*\ FUNCTION : ProTestSectionRefsFree PURPOSE : Free array of selected section references. \*====================================================================*/ ProError ProTestSectionRefsFree( ProSelection **p_ref_sel ) /* In: ProArray of selected refs */ { ProError status; int n_refs = 0; int i; status = ProArraySizeGet( (ProArray)(*p_ref_sel), &n_refs ); TEST_CALL_REPORT( "ProArraySizeGet","ProTestSectionRefsFree()", status, status != PRO_TK_NO_ERROR ); if( status != PRO_TK_NO_ERROR || n_refs < 1 ) return PRO_TK_NO_ERROR; for( i=0; i<n_refs; i++ ) { status = ProSelectionFree( *p_ref_sel + i ); TEST_CALL_REPORT( "ProSelectionFree","ProTestSectionRefsFree()", status, status != PRO_TK_NO_ERROR ); } status = ProArrayFree( (ProArray*)p_ref_sel ); TEST_CALL_REPORT( "ProArrayFree","ProTestSectionRefsFree()", status, status != PRO_TK_NO_ERROR ); return PRO_TK_NO_ERROR; } /*---------------------------------------------------------------------------*\ Sketching entities \*---------------------------------------------------------------------------*/ /*====================================================================*\ FUNCTION : ProTestSectionLineEntityCreate PURPOSE : Draw the line entity and add it to the section \*====================================================================*/ int ProTestSectionLineEntityCreate( SketchingData *p_sk_data) { ProError status; ProMouseButton mouse_button; ProPoint3d point1, point2; ProColor old_color; ProColor warning_color; /*------------------------------------------------------ Note: Value of the SKETCHER_DONE_LOCAL is changed from SKETCHER_QUIT to SKETCHER_DONE.This implies, the sketch has been done in the Sketcher mode. ------------------------------------------------------*/ SKETCHER_DONE_LOCAL = SKETCHER_DONE; /* Pick the first point */ mouse_button = PRO_NO_BUTTON; status = ProMousePickGet( PRO_ANY_BUTTON, &mouse_button, point1 ); TEST_CALL_REPORT( "ProMousePickGet","ProTestSectionLineEntityCreate()", status, status != PRO_TK_NO_ERROR ); if( status != PRO_TK_NO_ERROR || mouse_button != PRO_LEFT_BUTTON ) return -1; /* Draw the first point */ warning_color.method = PRO_COLOR_METHOD_TYPE; warning_color.value.type = PRO_COLOR_WARNING; ProGraphicsColorModify( &warning_color, &old_color ); ProTestPointDraw( point1, p_sk_data->mdl_matrix ); while( mouse_button != PRO_MIDDLE_BUTTON ) { /* Pick the line end point */ status = ProMousePickGet( PRO_ANY_BUTTON, &mouse_button, point2 ); TEST_CALL_REPORT( "ProMousePickGet","ProTestSectionLineEntityCreate()", status, status != PRO_TK_NO_ERROR ); if( status != PRO_TK_NO_ERROR ) break; if( mouse_button == PRO_LEFT_BUTTON ) { /* Draw the line and line end point */ ProTestLineDraw( point1, point2, p_sk_data->mdl_matrix ); /* Add drawn line as entity */ ProTestSectionLineEntityAdd( p_sk_data, point1, point2 ); point1[0] = point2[0]; point1[1] = point2[1]; point1[2] = point2[2]; } } ProGraphicsColorModify( &old_color, NULL ); return 0; } /*====================================================================*\ FUNCTION : ProTestSectionRectangleEntityCreate PURPOSE : Draw the rectangle entity and add it to the section \*====================================================================*/ int ProTestSectionRectangleEntityCreate( SketchingData *p_sk_data) { ProError status; ProMouseButton mouse_button; ProPoint3d point1, point2; ProColor old_color; ProColor warning_color; /*------------------------------------------------------ Note: Value of the SKETCHER_DONE_LOCAL is changed from SKETCHER_QUIT to SKETCHER_DONE.This implies, the sketch has been done in the Sketcher mode. ------------------------------------------------------*/ SKETCHER_DONE_LOCAL = SKETCHER_DONE; /* Pick the first point */ mouse_button = PRO_NO_BUTTON; status = ProMousePickGet( PRO_ANY_BUTTON, &mouse_button, point1 ); TEST_CALL_REPORT( "ProMousePickGet","ProTestSectionRectangleEntityCreate()", status, status != PRO_TK_NO_ERROR ); if( status != PRO_TK_NO_ERROR || mouse_button != PRO_LEFT_BUTTON ) return -1; /* Draw the first point */ warning_color.method = PRO_COLOR_METHOD_TYPE; warning_color.value.type = PRO_COLOR_WARNING; ProGraphicsColorModify( &warning_color, &old_color ); ProTestPointDraw( point1, p_sk_data->mdl_matrix ); /* Pick the circle point */ while( mouse_button != PRO_MIDDLE_BUTTON ) { /* Pick the line end point */ status = ProMousePickGet( PRO_ANY_BUTTON, &mouse_button, point2 ); TEST_CALL_REPORT( "ProMousePickGet", "ProTestSectionRectangleEntityCreate()", status, status != PRO_TK_NO_ERROR ); if( status != PRO_TK_NO_ERROR ) break; if( mouse_button == PRO_LEFT_BUTTON ) { /* Draw the rectangle */ ProTestRectangleDraw( point1, point2, p_sk_data->mdl_matrix ); /* Add drawn rectangle as entity */ ProTestSectionRectangleEntityAdd( p_sk_data, point1, point2 ); break; } } ProGraphicsColorModify( &old_color, NULL ); return 0; } /*====================================================================*\ FUNCTION : ProTestSectionCircleEntityCreate PURPOSE : Draw the circle entity and add it to the section \*====================================================================*/ int ProTestSectionCircleEntityCreate( SketchingData *p_sk_data) { ProError status; ProMouseButton mouse_button; ProPoint3d point1, point2; ProColor old_color; ProColor warning_color; /*------------------------------------------------------ Note: Value of the SKETCHER_DONE_LOCAL is changed from SKETCHER_QUIT to SKETCHER_DONE.This implies, the sketch has been done in the Sketcher mode. ------------------------------------------------------*/ SKETCHER_DONE_LOCAL = SKETCHER_DONE; /* Pick the center point */ mouse_button = PRO_NO_BUTTON; status = ProMousePickGet( PRO_ANY_BUTTON, &mouse_button, point1 ); TEST_CALL_REPORT( "ProMousePickGet","ProTestSectionCircleEntityCreate()", status, status != PRO_TK_NO_ERROR ); if( status != PRO_TK_NO_ERROR || mouse_button != PRO_LEFT_BUTTON ) return -1; /* Draw the center point */ warning_color.method = PRO_COLOR_METHOD_TYPE; warning_color.value.type = PRO_COLOR_WARNING; ProGraphicsColorModify( &warning_color, &old_color ); ProTestPointDraw( point1, p_sk_data->mdl_matrix ); /* Pick the circle point */ while( mouse_button != PRO_MIDDLE_BUTTON ) { /* Pick the line end point */ status = ProMousePickGet( PRO_ANY_BUTTON, &mouse_button, point2 ); TEST_CALL_REPORT( "ProMousePickGet", "ProTestSectionCircleEntityCreate()", status, status != PRO_TK_NO_ERROR ); if( status != PRO_TK_NO_ERROR ) break; if( mouse_button == PRO_LEFT_BUTTON ) { /* Draw the circle */ ProTestCircleDraw( point1, point2, p_sk_data->mdl_matrix ); /* Add drawn circle as entity */ ProTestSectionCircleEntityAdd( p_sk_data, point1, point2 ); break; } } ProGraphicsColorModify( &old_color, NULL ); return 0; } int ProTestSectionArcEntityCreate( SketchingData *p_sk_data) { #if 0 ProError status; ProMouseButton mouse_button; ProPoint3d point1; ProPoint3d point2; ProPoint3d point3; ProColor old_color; ProColor warning_color; /* Pick the first end point */ mouse_button = PRO_NO_BUTTON; status = ProMousePickGet( PRO_ANY_BUTTON, &mouse_button, point1 ); if( status != PRO_TK_NO_ERROR || mouse_button != PRO_LEFT_BUTTON ) return -1; /* Draw the first arc end point */ warning_color.method = PRO_COLOR_METHOD_TYPE; warning_color.value.type = PRO_COLOR_WARNING; ProGraphicsColorModify( &warning_color, &old_color ); ProTestPointDraw( point1, p_sk_data->mdl_matrix ); /* Get the second arc end point */ while( mouse_button != PRO_MIDDLE_BUTTON ) { /* Pick the second arc end point */ status = ProMousePickGet( PRO_ANY_BUTTON, &mouse_button, point2 ); if( status != PRO_TK_NO_ERROR ) break; if( mouse_button == PRO_LEFT_BUTTON ) { /* Draw the second end point */ ProTestPointDraw( point2, p_sk_data->mdl_matrix ); break; } } /* Get the center point */ while( mouse_button != PRO_MIDDLE_BUTTON ) { /* Pick the center point */ status = ProMousePickGet( PRO_ANY_BUTTON, &mouse_button, center ); if( status != PRO_TK_NO_ERROR ) break; if( mouse_button == PRO_LEFT_BUTTON ) { /* Draw the center point */ ProTestPointDraw( center, p_sk_data->mdl_matrix ); break; } } ProGraphicsColorModify( &old_color, NULL ); #endif return 0; } /*---------------------------------------------------------------------------*\ Adding entities \*---------------------------------------------------------------------------*/ /*====================================================================*\ FUNCTION : ProTestSectionLineEntityAdd PURPOSE : Add the specified line to the section \*====================================================================*/ ProError ProTestSectionLineEntityAdd( SketchingData *p_sk_data, /* In: Sketching data */ ProPoint3d point1, /* In: Line end 1 in screen coords */ ProPoint3d point2 ) /* In: Line end 2 in screen coords */ { ProError status; Pro2dLinedef line_def; int entity_id; ProPoint3d sec_point1, sec_point2; /* Transform from screen coords to section coords */ status = ProPntTrfEval( point1, p_sk_data->trf_matrix, sec_point1 ); TEST_CALL_REPORT( "ProPntTrfEval","ProTestSectionLineEntityAdd()", status, status != PRO_TK_NO_ERROR ); status = ProPntTrfEval( point2, p_sk_data->trf_matrix, sec_point2 ); TEST_CALL_REPORT( "ProPntTrfEval","ProTestSectionLineEntityAdd()", status, status != PRO_TK_NO_ERROR ); /* Init the entity structure */ line_def.type = PRO_2D_LINE; line_def.end1[0] = sec_point1[0]; line_def.end1[1] = sec_point1[1]; line_def.end2[0] = sec_point2[0]; line_def.end2[1] = sec_point2[1]; /* Add the entity */ status = ProSectionEntityAdd( p_sk_data->section, (Pro2dEntdef*)&line_def, &entity_id ); TEST_CALL_REPORT( "ProSectionEntityAdd","ProTestSectionLineEntityAdd()", status, status != PRO_TK_NO_ERROR ); return status; } /*====================================================================*\ FUNCTION : ProTestSectionRectangleEntityAdd PURPOSE : Add the specified rectangle to the section \*====================================================================*/ ProError ProTestSectionRectangleEntityAdd( SketchingData *p_sk_data, /* In: Sketching data */ ProPoint3d point1, /* In: Screen coords of top point*/ ProPoint3d point3 ) /* In: Screen coords of bottom point */ { ProError status; Pro2dLinedef line_def; int entity_id; ProPoint3d point2, point4; ProPoint3d sec_points[ 5 ]; int i; point2[0] = point3[0]; point2[1] = point1[1]; point2[2] = 0.0; point4[0] = point1[0]; point4[1] = point3[1]; point4[2] = 0.0; /* Transform from screen coords to section coords */ ProPntTrfEval( point1, p_sk_data->trf_matrix, sec_points[0] ); ProPntTrfEval( point2, p_sk_data->trf_matrix, sec_points[1] ); ProPntTrfEval( point3, p_sk_data->trf_matrix, sec_points[2] ); ProPntTrfEval( point4, p_sk_data->trf_matrix, sec_points[3] ); status = ProPntTrfEval( point1, p_sk_data->trf_matrix, sec_points[4] ); TEST_CALL_REPORT( "ProPntTrfEval","ProTestSectionRectangleEntityAdd()", status, status != PRO_TK_NO_ERROR ); for( i=1; i<5; i++ ) { line_def.type = PRO_2D_LINE; line_def.end1[0] = sec_points[i-1][0]; line_def.end1[1] = sec_points[i-1][1]; line_def.end2[0] = sec_points[i][0]; line_def.end2[1] = sec_points[i][1]; /* Add the entity */ status = ProSectionEntityAdd( p_sk_data->section, (Pro2dEntdef*)&line_def, &entity_id ); TEST_CALL_REPORT( "ProSectionEntityAdd", "ProTestSectionRectangleEntityAdd()", status, status != PRO_TK_NO_ERROR ); } return status; } /*====================================================================*\ FUNCTION : ProTestSectionCircleEntityAdd PURPOSE : Add the specified circle to the section \*====================================================================*/ ProError ProTestSectionCircleEntityAdd( SketchingData *p_sk_data, /* In: Sketching data */ ProPoint3d center, /* In: The center point */ ProPoint3d circle ) /* In: Circle point */ { ProError status; Pro2dCircledef circle_def; int entity_id; ProPoint3d sec_center; ProPoint3d sec_circle_point; /* Transform from screen coords to section coords */ status = ProPntTrfEval( center, p_sk_data->trf_matrix, sec_center ); TEST_CALL_REPORT( "ProPntTrfEval","ProTestSectionCircleEntityAdd()", status, status != PRO_TK_NO_ERROR ); status = ProPntTrfEval( circle, p_sk_data->trf_matrix, sec_circle_point ); TEST_CALL_REPORT( "ProPntTrfEval","ProTestSectionCircleEntityAdd()", status, status != PRO_TK_NO_ERROR ); /* Init the entity structure */ circle_def.type = PRO_2D_CIRCLE; circle_def.center[0] = sec_center[0]; circle_def.center[1] = sec_center[1]; circle_def.radius = ProUtilPointsDist( sec_center, sec_circle_point ); /* Add the entity */ status = ProSectionEntityAdd( p_sk_data->section, (Pro2dEntdef*)&circle_def, &entity_id ); TEST_CALL_REPORT( "ProSectionEntityAdd","ProTestSectionCircleEntityAdd()", status, status != PRO_TK_NO_ERROR ); return status; } /*---------------------------------------------------------------------------*\ Displaying graphics \*---------------------------------------------------------------------------*/ /*====================================================================*\ FUNCTION : ProTestPointDraw PURPOSE : Draw the point \*====================================================================*/ ProError ProTestPointDraw( ProPoint3d point, /* In: Point screen coords */ ProMatrix trf_matrix ) /* In: Matrx to convert screen coords into model coords (NULL) */ { ProColor old_color; ProColor letter_color; ProPoint3d mdl_point; /* Convert screen coords into model coords if necessary */ if( trf_matrix != NULL ) ProUtilPointTrans( trf_matrix, point, mdl_point ); else ProUtilVectorCopy( point, mdl_point ); /* Draw the point */ letter_color.method = PRO_COLOR_METHOD_TYPE; letter_color.value.type = PRO_COLOR_LETTER; ProGraphicsColorModify(&letter_color , &old_color ); ProGraphicsCircleDraw( mdl_point, 0.02 ); ProGraphicsColorModify( &old_color, NULL ); return PRO_TK_NO_ERROR; } /*====================================================================*\ FUNCTION : ProTestLineDraw PURPOSE : Draw the line \*====================================================================*/ ProError ProTestLineDraw( ProPoint3d point1, /* In: Screen coords of line end point*/ ProPoint3d point2, /* In: Screen coords of line end point*/ ProMatrix trf_matrix ) /* In: Matrx to convert screen coords into model coords (NULL)*/ { ProPoint3d mdl_point1, mdl_point2; /* Convert screen coords into model coords if necessary */ if( trf_matrix != NULL ) { ProUtilPointTrans( trf_matrix, point1, mdl_point1 ); ProUtilPointTrans( trf_matrix, point2, mdl_point2 ); } else { ProUtilVectorCopy( point1, mdl_point1 ); ProUtilVectorCopy( point2, mdl_point2 ); } /* Draw the line and line end points */ ProGraphicsPenPosition( mdl_point1 ); ProGraphicsLineDraw( mdl_point2 ); ProTestPointDraw( mdl_point1, NULL ); ProTestPointDraw( mdl_point2, NULL ); return PRO_TK_NO_ERROR; } /*====================================================================*\ FUNCTION : ProTestRectangleDraw PURPOSE : Draw the rectangle \*====================================================================*/ ProError ProTestRectangleDraw( ProPoint3d point1, /* In: Screen coords of top point*/ ProPoint3d point3, /* In: Screen coords of bottom point */ ProMatrix trf_matrix ) /* In: Matrx to convert screen coords into model coords (NULL)*/ { ProPoint3d point2 = {0,0,0}; ProPoint3d point4 = {0,0,0}; ProPoint3d mdl_point1, mdl_point2, mdl_point3, mdl_point4; point2[0] = point3[0]; point2[1] = point1[1]; point2[2] = 0.0; point4[0] = point1[0]; point4[1] = point3[1]; point4[2] = 0.0; /* Convert screen coords into model coords if necessary */ if( trf_matrix != NULL ) { ProUtilPointTrans( trf_matrix, point1, mdl_point1 ); ProUtilPointTrans( trf_matrix, point2, mdl_point2 ); ProUtilPointTrans( trf_matrix, point3, mdl_point3 ); ProUtilPointTrans( trf_matrix, point4, mdl_point4 ); } else { ProUtilVectorCopy( point1, mdl_point1 ); ProUtilVectorCopy( point2, mdl_point2 ); ProUtilVectorCopy( point3, mdl_point3 ); ProUtilVectorCopy( point4, mdl_point4 ); } /* Draw the rectangle and its end points */ ProGraphicsPenPosition( mdl_point1 ); ProGraphicsLineDraw( mdl_point2 ); ProGraphicsLineDraw( mdl_point3 ); ProGraphicsLineDraw( mdl_point4 ); ProGraphicsLineDraw( mdl_point1 ); ProTestPointDraw( mdl_point1, NULL ); ProTestPointDraw( mdl_point2, NULL ); ProTestPointDraw( mdl_point3, NULL ); ProTestPointDraw( mdl_point4, NULL ); return PRO_TK_NO_ERROR; } /*====================================================================*\ FUNCTION : ProTestCircleDraw PURPOSE : Draw the circle \*====================================================================*/ ProError ProTestCircleDraw( ProPoint3d center, /* In: Screen coords of center point */ ProPoint3d circle, /* In: Screen coords of circle point */ ProMatrix trf_matrix ) /* In: Matrx to convert screen coords into model coords (NULL) */ { ProPoint3d mdl_center; ProPoint3d mdl_circle; double radius; /* Convert screen coords into model coords if necessary */ if( trf_matrix != NULL ) { ProUtilPointTrans( trf_matrix, center, mdl_center ); ProUtilPointTrans( trf_matrix, circle, mdl_circle ); } else { ProUtilVectorCopy( center, mdl_center ); ProUtilVectorCopy( circle, mdl_circle ); } radius = ProUtilPointsDist( mdl_center, mdl_circle ); ProGraphicsCircleDraw( mdl_center, radius ); return PRO_TK_NO_ERROR; } /*====================================================================*\ FUNCTION : ProTestNewSectionNameGet PURPOSE : Generate the name of the next new section \*====================================================================*/ wchar_t *ProTestNewSectionNameGet( ProName w_name ) /* Out: Name of the new section. User must allocate w_name */ { static int counter = 0; ProCharName name; ProTKSprintf( name, (char *)"TKSECTION%04d", counter++ ); ProStringToWstring( w_name, name ); return w_name; } /*====================================================================*\ FUNCTION : ProTestProtrusionFeatureCreate PURPOSE : Initialize element tree and create extruded protrusion feature \*====================================================================*/ ProError ProTestProtrusionFeatureCreate( ProSecViewDirType view_direction, /* In: Feature direction */ ProSelection sk_plane_sel, /* In: The sketching plane selection */ int ref_type, /* In: The reference plane type (TOP, ...) */ ProSelection ref_plane_sel, /* In: The reference plane selection */ ProSection section, /* In: The sketched section */ ProSelection *p_references, /* In: The sketching references */ DepthData *p_depth, /* In: Initialized depth data */ ProFeature *p_feature ) /* Out: Created feature */ { ProMdl model; ProModelitem model_item; ProSelection model_sel; ProError status; ProElement elem_tree; ProFeatureCreateOptions *options = 0; ProErrorlist err_list; static ElemTreeData tree[]={ {0, PRO_E_FEATURE_TREE, {PRO_VALUE_TYPE_INT, PRO_VALUE_UNUSED}}, {1, PRO_E_FEATURE_TYPE, {PRO_VALUE_TYPE_INT, PRO_FEAT_PROTRUSION}}, {1, PRO_E_FEATURE_FORM, {PRO_VALUE_TYPE_INT, PRO_EXTRUDE}}, {1, PRO_E_EXT_SURF_CUT_SOLID_TYPE, {PRO_VALUE_TYPE_INT, PRO_EXT_FEAT_TYPE_SOLID}}, {1, PRO_E_REMOVE_MATERIAL, {PRO_VALUE_TYPE_INT, PRO_EXT_MATERIAL_ADD}}, /* Section */ {1, PRO_E_STD_SECTION, {PRO_VALUE_TYPE_INT, PRO_VALUE_UNUSED}}, {2, PRO_E_STD_SEC_SETUP_PLANE, {PRO_VALUE_TYPE_INT, PRO_VALUE_UNUSED}}, {3, PRO_E_STD_SEC_PLANE, {PRO_VALUE_TYPE_SELECTION}}, {3, PRO_E_STD_SEC_PLANE_VIEW_DIR, {PRO_VALUE_TYPE_INT}}, {3, PRO_E_STD_SEC_PLANE_ORIENT_DIR, {PRO_VALUE_TYPE_INT}}, {3, PRO_E_STD_SEC_PLANE_ORIENT_REF, {PRO_VALUE_TYPE_SELECTION}}, /* Extrusion depth */ {1, PRO_E_STD_EXT_DEPTH, {PRO_VALUE_TYPE_INT, PRO_VALUE_UNUSED}}, {2, PRO_E_EXT_DEPTH_FROM, {PRO_VALUE_TYPE_INT, PRO_VALUE_UNUSED}}, {3, PRO_E_EXT_DEPTH_FROM_TYPE, {PRO_VALUE_TYPE_INT}}, {3, PRO_E_EXT_DEPTH_FROM_VALUE, {PRO_VALUE_TYPE_DOUBLE}}, {3, PRO_E_EXT_DEPTH_FROM_REF, {PRO_VALUE_TYPE_SELECTION}}, {2, PRO_E_EXT_DEPTH_TO, {PRO_VALUE_TYPE_INT, PRO_VALUE_UNUSED}}, {3, PRO_E_EXT_DEPTH_TO_TYPE, {PRO_VALUE_TYPE_INT,PRO_EXT_DEPTH_TO_NONE} }, {3, PRO_E_EXT_DEPTH_TO_VALUE, {PRO_VALUE_TYPE_DOUBLE}}, {3, PRO_E_EXT_DEPTH_TO_REF, {PRO_VALUE_TYPE_SELECTION}} }; /*-------------------------------------------------*\ Complete section elements initialization \*-------------------------------------------------*/ tree[7].data.v.r = sk_plane_sel; tree[8].data.v.i = view_direction; tree[10].data.v.r = ref_plane_sel; /*-------------------------------------------------*\ Init orientation direction value \*-------------------------------------------------*/ switch( ref_type ) { case SK_REF_TOP: tree[9].data.v.i = PRO_SEC_ORIENT_DIR_UP; break; case SK_REF_BOTTOM: tree[9].data.v.i = PRO_SEC_ORIENT_DIR_DOWN; break; case SK_REF_RIGHT: tree[9].data.v.i = PRO_SEC_ORIENT_DIR_RIGHT; break; case SK_REF_LEFT: tree[9].data.v.i = PRO_SEC_ORIENT_DIR_LEFT; break; default: return PRO_TK_NO_ERROR; } /*-------------------------------------------------*\ Set PRO_E_EXT_DEPTH_FROM elements \*-------------------------------------------------*/ switch( p_depth->from_type ) { case DEPTH_TYPE_BLIND: /* symmetric blind */ case DEPTH_TYPE_2SIDEBLIND: tree[13].data.v.i = PRO_EXT_DEPTH_FROM_BLIND; tree[14].data.v.d = p_depth->from_value.v.d; break; case DEPTH_TYPE_THRU_NEXT: tree[13].data.v.i = PRO_EXT_DEPTH_FROM_NEXT; break; case DEPTH_TYPE_THRU_ALL: tree[13].data.v.i = PRO_EXT_DEPTH_FROM_ALL; break; case DEPTH_TYPE_THRU_UNTIL: tree[13].data.v.i = PRO_EXT_DEPTH_FROM_UNTIL; ProSelectionCopy( p_depth->from_value.v.r, &(tree[15].data.v.r) ); break; case DEPTH_TYPE_UPTO_PNT: case DEPTH_TYPE_UPTO_CURVE: case DEPTH_TYPE_UPTO_SURFACE: tree[13].data.v.i = PRO_EXT_DEPTH_FROM_REF; ProSelectionCopy( p_depth->from_value.v.r, &(tree[15].data.v.r) ); break; default: tree[13].data.v.i = PRO_EXT_DEPTH_FROM_NONE; } /*-------------------------------------------------*\ Set PRO_E_EXT_DEPTH_TO elements \*-------------------------------------------------*/ switch( p_depth->to_type ) { case DEPTH_TYPE_BLIND: if (p_depth->from_type == DEPTH_TYPE_BLIND) { tree[17].data.v.i = PRO_EXT_DEPTH_SYMMETRIC; } else { tree[17].data.v.i = PRO_EXT_DEPTH_TO_BLIND; tree[18].data.v.d = p_depth->to_value.v.d; } break; case DEPTH_TYPE_2SIDEBLIND: tree[17].data.v.i = PRO_EXT_DEPTH_TO_BLIND; tree[18].data.v.d = p_depth->to_value.v.d; break; case DEPTH_TYPE_THRU_NEXT: tree[17].data.v.i = PRO_EXT_DEPTH_TO_NEXT; break; case DEPTH_TYPE_THRU_ALL: tree[17].data.v.i = PRO_EXT_DEPTH_TO_ALL; break; case DEPTH_TYPE_THRU_UNTIL: tree[17].data.v.i = PRO_EXT_DEPTH_TO_UNTIL; ProSelectionCopy( p_depth->to_value.v.r, &(tree[19].data.v.r) ); break; case DEPTH_TYPE_UPTO_PNT: case DEPTH_TYPE_UPTO_CURVE: case DEPTH_TYPE_UPTO_SURFACE: tree[17].data.v.i = PRO_EXT_DEPTH_TO_REF; ProSelectionCopy( p_depth->to_value.v.r, &(tree[19].data.v.r) ); break; default: tree[17].data.v.i = PRO_EXT_DEPTH_TO_NONE; } /*-------------------------------------------------*\ Create element tree \*-------------------------------------------------*/ status = ProUtilElemtreeCreate( tree, SIZEOFARR(tree), NULL, &elem_tree ); if( status != PRO_TK_NO_ERROR ) return status; /*-------------------------------------------------*\ Create selection structure for current model \*-------------------------------------------------*/ status = ProMdlCurrentGet( &model ); TEST_CALL_REPORT( "ProMdlCurrentGet","ProTestProtrusionFeatureCreate()", status, status != PRO_TK_NO_ERROR ); status = ProMdlToModelitem( model, &model_item ); TEST_CALL_REPORT( "ProMdlToModelitem","ProTestProtrusionFeatureCreate()", status, status != PRO_TK_NO_ERROR ); status = ProSelectionAlloc( NULL, &model_item, &model_sel ); TEST_CALL_REPORT( "ProSelectionAlloc","ProTestProtrusionFeatureCreate()", status, status != PRO_TK_NO_ERROR ); /*-------------------------------------------------*\ Create the incomplete feature \*-------------------------------------------------*/ status = ProArrayAlloc(1,sizeof(ProFeatureCreateOptions), 1, (ProArray*)&options); options[0]= PRO_FEAT_CR_INCOMPLETE_FEAT; status = ProFeatureWithoptionsCreate( model_sel, elem_tree, options, PRO_REGEN_NO_FLAGS, p_feature, &err_list ); TEST_CALL_REPORT( "ProFeatureWithoptionsCreate","ProTestProtrusionFeatureCreate()", status, status != PRO_TK_NO_ERROR ); status = ProArrayFree((ProArray*)&options); /*-------------------------------------------------*\ Release element tree \*-------------------------------------------------*/ status = ProElementFree( &elem_tree ); TEST_CALL_REPORT( "ProElementFree","ProTestProtrusionFeatureCreate()", status, status != PRO_TK_NO_ERROR ); /*-------------------------------------------------*\ Complete the feature adding the sketched section \*-------------------------------------------------*/ status = ProTestFeatureSectionInit( p_feature, section, p_references, PRO_B_FALSE ); return status; } /* Complete PRO_E_SKETCHER element with section and references. */ ProError ProTestFeatureSectionInit( ProFeature *p_feature, /* In: Incomplete feature */ ProSection section, /* In: Sketched section */ ProSelection *p_references, /* In: Sketching refs (NULL) */ ProBoolean is_first) /* In: If first feature or not */ { ProError status; /* ProFeatureCreateOptions redefine_options[] = { PRO_FEAT_CR_NO_OPTS }; */ ProFeatureCreateOptions *redefine_options = 0; ProElement elem_tree; ProElement sketcher_elem; ProValue sketcher_elem_value, new_value; ProValueData value_data; ProMatrix location_matrix; ProMatrix inv_matrix; ProVector tran_vector = {0,0,0}; ProErrorlist err_list; int win_id; static ProElempathItem sketcher_elempath[] = { { PRO_ELEM_PATH_ITEM_TYPE_ID, {PRO_E_STD_SECTION} }, { PRO_ELEM_PATH_ITEM_TYPE_ID, {PRO_E_SKETCHER} } }; static ProElempathItem sketcher_elempath_first[] = { { PRO_ELEM_PATH_ITEM_TYPE_ID, {PRO_E_SKETCHER} } }; /* Get the element tree of newly created feature to init PRO_E_SKETCHER */ status = ProFeatureElemtreeExtract( p_feature, NULL, PRO_FEAT_EXTRACT_NO_OPTS, &elem_tree ); TEST_CALL_REPORT( "ProFeatureElemtreeExtract","ProTestFeatureSectionInit()", status, status != PRO_TK_NO_ERROR ); if( status != PRO_TK_NO_ERROR ) return status; if (is_first) { /* Find PRO_E_SKETCHER element in element tree */ ProUtilElemtreeElementGet( elem_tree, sketcher_elempath_first, 1, &sketcher_elem ); status = ProElementSpecialvalueGet( sketcher_elem, NULL, (ProAppData*)§ion ); TEST_CALL_REPORT( "ProElementSpecialvalueGet","ProTestFeatureSectionInit()", status, status != PRO_TK_NO_ERROR ); /* Following call will Autodim & Regenerate the section */ ProTestSectionRegenerate (section); status = ProElementSpecialvalueSet( sketcher_elem, (ProAppData)section ); TEST_CALL_REPORT( "ProElementSpecialvalueSet","ProTestFeatureSectionInit()", status, status != PRO_TK_NO_ERROR ); } else { ProSection cur_sec; /* Find PRO_E_SKETCHER element in element tree */ ProUtilElemtreeElementGet( elem_tree, sketcher_elempath, 2, &sketcher_elem ); status = ProElementSpecialvalueGet( sketcher_elem, NULL, (ProAppData*)&cur_sec ); TEST_CALL_REPORT( "ProElementSpecialvalueGet","ProTestFeatureSectionInit()", status, status != PRO_TK_NO_ERROR ); /* Calc translation vector */ status = ProSectionLocationGet( cur_sec, location_matrix ); TEST_CALL_REPORT( "ProSectionLocationGet","ProTestFeatureSectionInit()", status, status != PRO_TK_NO_ERROR ); ProUtilMatrixInvert( location_matrix, inv_matrix ); ProUtilVectorCopy( inv_matrix[3], tran_vector ); /* Copy sketched section into elem tree usin translation vector */ status = ProUtilSectionInfoCopy( section, cur_sec, tran_vector ); /* Add sketching referencies, dimension and regenerate the section */ if( p_references != NULL ) status = ProTestFeatureSectionRefsAdd(cur_sec, p_references ); status = ProTestSectionRegenerate( cur_sec ); } /* Redefine the feature with complete elem tree */ status = ProArrayAlloc(1,sizeof(ProFeatureCreateOptions), 1, (ProArray*)&redefine_options); redefine_options[0]= PRO_FEAT_CR_DEFINE_MISS_ELEMS; status = ProFeatureWithoptionsRedefine( NULL, p_feature, elem_tree, redefine_options, PRO_REGEN_NO_FLAGS, &err_list ); TEST_CALL_REPORT( "ProFeatureWithoptionsRedefine","ProTestFeatureSectionInit()", status, status != PRO_TK_NO_ERROR ); status = ProArrayFree((ProArray*)&redefine_options); /* Fit the nodel within the viewing window */ status = ProWindowCurrentGet(&win_id); TEST_CALL_REPORT( "ProWindowCurrentGet","ProTestFeatureSectionInit()", status, status != PRO_TK_NO_ERROR ); status = ProWindowRefit(win_id); TEST_CALL_REPORT( "ProWindowRefit","ProTestFeatureSectionInit()", status, status != PRO_TK_NO_ERROR ); /* Release element tree */ ProFeatureElemtreeFree( p_feature,elem_tree ); return status; } /* Add references to the feature section. */ ProError ProTestFeatureSectionRefsAdd( ProSection section, /* In: The section */ ProSelection *p_references ) /* In: The selected refs */ { ProError status; int n_refs = 0; int entity_id; int i; /* Get the number of references */ status = ProArraySizeGet( (ProArray)p_references, &n_refs ); TEST_CALL_REPORT( "ProArraySizeGet","ProTestFeatureSectionRefsAdd()", status, status != PRO_TK_NO_ERROR ); /* Add references to the section */ for( i=0; i<n_refs; i++ ) { status = ProSectionEntityFromProjection( section, p_references[i], &entity_id ); TEST_CALL_REPORT( "ProSectionEntityFromProjection", "ProTestFeatureSectionRefsAdd()", status, status != PRO_TK_NO_ERROR ); if( status != PRO_TK_NO_ERROR ) return status; } return PRO_TK_NO_ERROR; } /* Autodim and regenerate the section. */ ProError ProTestSectionRegenerate( ProSection section ) { ProError status; ProWSecerror sec_errors; status = ProSectionEpsilonSet( section, 0.1 ); TEST_CALL_REPORT( "ProSectionEpsilonSet","ProTestSectionRegenerate()", status, status != PRO_TK_NO_ERROR ); /* Allocate the error list */ status = ProSecerrorAlloc( &sec_errors ); TEST_CALL_REPORT( "ProSecerrorAlloc","ProTestSectionRegenerate()", status, status != PRO_TK_NO_ERROR ); /* Add all the missing dimensions */ status = ProSectionAutodim( section, &sec_errors ); TEST_CALL_REPORT( "ProSectionAutodim","ProTestSectionRegenerate()", status, status != PRO_TK_NO_ERROR ); if( status == PRO_TK_NO_ERROR ) { /* Regenerate the section */ status = ProSectionRegenerate( section, &sec_errors ); TEST_CALL_REPORT( "ProSectionRegenerate", "ProTestSectionRegenerate()", status, status != PRO_TK_NO_ERROR ); } /* Release the error list */ ProSecerrorFree( &sec_errors ); return status; } /* Initialize depth values for both feature sides */ ProError ProTestFeatureDepthRetrieve( ProSides sides, /* In: ONE_SIDE or BOTH_SIDES */ ProSecViewDirType direction, /* In: Feature direction */ ProSurface sk_plane, /* In: Sketching plane */ DepthData *p_depth ) /* Out: Initialized depth data. If ONE_SIDE, init only p_depth->to_*, setting from_type to DEPTH_TYPE_NONE */ { ProError status; DirectionArrow dir_arrow; /*-----------------------------------------*\ Init values for ONE_SIDE \*-----------------------------------------*/ if( sides == PRO_SIDES_ONE_SIDE ) { status = ProTestFeatureDepthValueInit( sides, PRO_B_FALSE, (int *)&(p_depth->to_type), &(p_depth->to_value) ); p_depth->from_type = (ProExtDepthFromType)DEPTH_TYPE_NONE; } /*-----------------------------------------*\ Init values for BOTH_SIDES \*-----------------------------------------*/ if( sides == PRO_SIDES_BOTH_SIDES ) { /* Create and display the direction arrow */ ProTestDirectionArrowCreate( sk_plane, direction, &dir_arrow ); /* Init TO type & value */ status = ProTestFeatureDepthValueInit( sides, PRO_B_FALSE, (int *)&(p_depth->to_type), &(p_depth->to_value) ); if( status != PRO_TK_NO_ERROR ) { ProTestDirectionArrowDelete( &dir_arrow ); return status; } if( p_depth->to_type == DEPTH_TYPE_BLIND ) { p_depth->from_type = (ProExtDepthFromType)DEPTH_TYPE_BLIND; /* Symmetric */ p_depth->from_value.type = PRO_VALUE_TYPE_DOUBLE; p_depth->from_value.v.d = p_depth->to_value.v.d; } else if( p_depth->to_type == DEPTH_TYPE_2SIDEBLIND ) { p_depth->from_type = (ProExtDepthFromType)DEPTH_TYPE_2SIDEBLIND; p_depth->from_value.type = PRO_VALUE_TYPE_DOUBLE; p_depth->from_value.v.d = ProTestDoubleValueGet( 3.0 ); } else { /* Flip direction arrow */ ProTestDirectionArrowFlip( &dir_arrow, -1 ); status = ProTestFeatureDepthValueInit(sides, PRO_B_TRUE, (int *)&(p_depth->from_type), &(p_depth->from_value) ); } ProTestDirectionArrowDelete( &dir_arrow ); } return status; } /* Use menu to select depth type. p_depth_value will contain: double value - for DEPTH_TYPE_BLIND, DEPTH_TYPE_2SIDEBLIND selection - for DEPTH_TYPE_THRU_UNTIL, DEPTH_TYPE_UPTO_PNT, DEPTH_TYPE_UPTO_CURVE, DEPTH_TYPE_UPTO_SURFACE nothing - for DEPTH_TYPE_THRU_NEXT, DEPTH_TYPE_THRU_ALL */ ProError ProTestFeatureDepthValueInit( ProSides sides, ProBoolean is_second_side, /* In: TRUE if for 2nd side depth initialization. In this case "Blind" and "2 Side Blind" buttons are disabled */ int *p_depth_type, ProValueData *p_depth_value ) { ProError status; int depth_type; char *p_option = NULL; ProSelection *p_sel; int n_sel = 0; ProUtilMsgPrint( msgfil, (char *)"USER Specify feature depth" ); /* Display the menu to select depth type */ status = ProTestFeatureDepthTypeGet( sides, is_second_side, &depth_type ); if( status != PRO_TK_NO_ERROR ) return status; /*---------------------------------------------------- Note: The default case is added to avoid the unexpected behaviour ,if the user enter DONE without giving the value of the DEPTH. ----------------------------------------------------*/ switch( depth_type ) { case DEPTH_TYPE_BLIND: p_depth_value->type = PRO_VALUE_TYPE_DOUBLE; p_depth_value->v.d = ProTestDoubleValueGet( 3.0 ); break; case DEPTH_TYPE_2SIDEBLIND: p_depth_value->type = PRO_VALUE_TYPE_DOUBLE; p_depth_value->v.d = ProTestDoubleValueGet( 3.0 ); break; case DEPTH_TYPE_THRU_NEXT: break; case DEPTH_TYPE_THRU_ALL: break; case DEPTH_TYPE_THRU_UNTIL: ProUtilMsgPrint( msgfil, (char *)"USER Select a surface to extrude until" ); p_option = (char *)"surface,sldface,qltface,datum"; break; case DEPTH_TYPE_UPTO_PNT: ProUtilMsgPrint( msgfil, (char *)"USER Select a datum point or a vertex to extrude up to" ); p_option = (char *)"point,edge_end,curve_end"; break; case DEPTH_TYPE_UPTO_CURVE: ProUtilMsgPrint( msgfil, (char *)"USER Select an axis to extrude up to" ); p_option = (char *)"axis,edge,curve,sldedge,qltedge"; break; case DEPTH_TYPE_UPTO_SURFACE: ProUtilMsgPrint( msgfil, (char *)"USER Select a surface to extrude up to" ); p_option = (char *)"surface,sldface,qltface,datum"; break; default: return (PRO_TK_GENERAL_ERROR); } if( p_option != NULL ) { n_sel = 0; status = ProSelect( p_option, 1, NULL, NULL, NULL, NULL, &p_sel, &n_sel ); TEST_CALL_REPORT( "ProSelect","ProTestFeatureDepthValueInit()", status, status != PRO_TK_NO_ERROR ); if( status != PRO_TK_NO_ERROR || n_sel < 1 ) return PRO_TK_GENERAL_ERROR; p_depth_value->type = PRO_VALUE_TYPE_SELECTION; status = ProSelectionCopy( *p_sel, &(p_depth_value->v.r) ); TEST_CALL_REPORT( "ProSelectionCopy","ProTestFeatureDepthValueInit()", status, status != PRO_TK_NO_ERROR ); } *p_depth_type = depth_type; return PRO_TK_NO_ERROR; } /* Display the menu to select depth type */ ProError ProTestFeatureDepthTypeGet( ProSides sides, ProBoolean is_second_side, /* In: TRUE for 2nd side depth initialization. In this case "Blind" and "2 Side Blind" buttons are disabled */ int *p_depth_type ) /* Out: Depth type */ { ProError status; int menu_id; int action; static char *p_enus[] = { (char *)"TK SPEC TO", (char *)"DONE QUIT", (char *)"" }; int depth_type; /*-------------------------------------------*\ Choose depth type \*-------------------------------------------*/ ProMenuFileRegister( (char *)"TK SPEC TO", (char *)"tkdepth.mnu", &menu_id ); ProMenubuttonActionSet( (char *)"TK SPEC TO", (char *)"Blind", (ProMenubuttonAction)ProTestFeatureDepthTypeSet, (ProAppData)&depth_type, DEPTH_TYPE_BLIND ); ProMenubuttonActionSet( (char *)"TK SPEC TO", (char *)"2 Side Blind", (ProMenubuttonAction)ProTestFeatureDepthTypeSet, (ProAppData)&depth_type, DEPTH_TYPE_2SIDEBLIND ); ProMenubuttonActionSet( (char *)"TK SPEC TO", (char *)"Thru Next", (ProMenubuttonAction)ProTestFeatureDepthTypeSet, (ProAppData)&depth_type, DEPTH_TYPE_THRU_NEXT ); ProMenubuttonActionSet( (char *)"TK SPEC TO", (char *)"Thru All", (ProMenubuttonAction)ProTestFeatureDepthTypeSet, (ProAppData)&depth_type, DEPTH_TYPE_THRU_ALL ); ProMenubuttonActionSet( (char *)"TK SPEC TO", (char *)"Thru Until", (ProMenubuttonAction)ProTestFeatureDepthTypeSet, (ProAppData)&depth_type, DEPTH_TYPE_THRU_UNTIL ); ProMenubuttonActionSet( (char *)"TK SPEC TO", (char *)"UpTo Pnt/Vtx", (ProMenubuttonAction)ProTestFeatureDepthTypeSet, (ProAppData)&depth_type, DEPTH_TYPE_UPTO_PNT ); ProMenubuttonActionSet( (char *)"TK SPEC TO", (char *)"UpTo Curve", (ProMenubuttonAction)ProTestFeatureDepthTypeSet, (ProAppData)&depth_type, DEPTH_TYPE_UPTO_CURVE ); ProMenubuttonActionSet( (char *)"TK SPEC TO", (char *)"UpTo Surface", (ProMenubuttonAction)ProTestFeatureDepthTypeSet, (ProAppData)&depth_type, DEPTH_TYPE_UPTO_SURFACE ); ProMenubuttonActionSet( (char *)"TK SPEC TO", (char *)"TK SPEC TO", (ProMenubuttonAction)ProTestFeatureDepthTypeSet, (ProAppData)&depth_type, DEPTH_TYPE_QUIT ); ProMenuFileRegister( (char *)"DONE QUIT", (char *)"tkdonequit.mnu", &menu_id ); ProMenubuttonActionSet( (char *)"DONE QUIT", (char *)"-Done", (ProMenubuttonAction)ProTestFeatureDepthTypeSet, (ProAppData)&depth_type, DEPTH_TYPE_DONE ); ProMenubuttonActionSet( (char *)"DONE QUIT", (char *)"-Quit", (ProMenubuttonAction)ProTestFeatureDepthTypeSet, (ProAppData)&depth_type, DEPTH_TYPE_QUIT ); ProMenubuttonActionSet( (char *)"DONE QUIT", (char *)"DONE QUIT", (ProMenubuttonAction)ProTestFeatureDepthTypeSet, (ProAppData)&depth_type, DEPTH_TYPE_QUIT ); action = DEPTH_TYPE_QUIT; status = ProCompoundmenuCreate( p_enus, &menu_id ); if( status == PRO_TK_NO_ERROR ) { if(sides == PRO_SIDES_ONE_SIDE || is_second_side == PRO_B_TRUE ) { ProMenubuttonDeactivate( (char *)"TK SPEC TO", (char *)"2 Side Blind" ); } else { ProMenubuttonActivate( (char *)"TK SPEC TO", (char *)"2 Side Blind" ); } ProMenuProcess( (char *)"TK SPEC TO", &action ); } if( action == DEPTH_TYPE_DONE ) { status = PRO_TK_NO_ERROR; *p_depth_type = depth_type; } else { status = PRO_TK_USER_ABORT; } return status; } int ProTestFeatureDepthTypeSet( int *p_depth_type, int depth_type ) { /*-------------------------------------------*\ Check for exiting \*-------------------------------------------*/ if( depth_type == DEPTH_TYPE_DONE || depth_type == DEPTH_TYPE_QUIT ) { ProMenuDeleteWithStatus( depth_type ); ProMenuDeleteWithStatus( depth_type ); return 0; } *p_depth_type = depth_type; return 0; } /* Get the double */ double ProTestDoubleValueGet( double def ) /* In: Default value */ { ProError status; double double_value; do { ProUtilMsgPrint( msgfil, (char *)"USER Enter depth %0f", &def ); status = ProMessageDoubleRead( NULL, &double_value ); TEST_CALL_REPORT( "ProMessageDoubleRead","ProTestDoubleValueGet()", status, status != PRO_TK_NO_ERROR ); } while( status == PRO_TK_MSG_USER_QUIT ); if( status != PRO_TK_NO_ERROR ) double_value = def; return double_value; } /* Create the first feature */ ProError ProTestFirstFeatureCreate( ProMdl model ) /* The model */ { ProError status; ProElement elem_tree; ProSection section; ProSelection model_sel; ProModelitem model_item; ProFeature feature; ProErrorlist err_list; ProFeatureCreateOptions *options = 0; static ElemTreeData tree[]={ {0, PRO_E_FEATURE_TREE, {PRO_VALUE_TYPE_INT, PRO_VALUE_UNUSED}}, {1, PRO_E_FEATURE_TYPE, {PRO_VALUE_TYPE_INT, PRO_FEAT_FIRST_FEAT}}, {1, PRO_E_FEATURE_FORM, {PRO_VALUE_TYPE_INT, PRO_EXTRUDE}}, /* Extrusion depth */ {1, PRO_E_STD_EXT_DEPTH, {PRO_VALUE_TYPE_INT, PRO_VALUE_UNUSED}}, {2, PRO_E_EXT_DEPTH_FROM, {PRO_VALUE_TYPE_INT, PRO_VALUE_UNUSED}}, {3, PRO_E_EXT_DEPTH_FROM_VALUE, {PRO_VALUE_TYPE_DOUBLE}} }; /*-------------------------------------------------*\ Sketch the section \*-------------------------------------------------*/ status = ProTestSectionSketcher( NULL, §ion, NULL ); if( status != PRO_TK_NO_ERROR ) return status; /*-------------------------------------------------*\ Set feature depth \*-------------------------------------------------*/ tree[5].data.v.d = ProTestDoubleValueGet( 3.0 ); /*-------------------------------------------------*\ Create element tree \*-------------------------------------------------*/ status = ProUtilElemtreeCreate( tree, SIZEOFARR(tree), NULL, &elem_tree ); if( status != PRO_TK_NO_ERROR ) return status; /*-------------------------------------------------*\ Create selection structure for current model \*-------------------------------------------------*/ status = ProMdlToModelitem( model, &model_item ); TEST_CALL_REPORT( "ProMdlToModelitem","ProTestFirstFeatureCreate()", status, status != PRO_TK_NO_ERROR ); status = ProSelectionAlloc( NULL, &model_item, &model_sel ); TEST_CALL_REPORT( "ProSelectionAlloc","ProTestFirstFeatureCreate()", status, status != PRO_TK_NO_ERROR ); /*-------------------------------------------------*\ Create the incomplete feature \*-------------------------------------------------*/ /* status = ProFeatureCreate( model_sel, elem_tree, options, 0, &feature, &err_list ); */ status = ProArrayAlloc(1,sizeof(ProFeatureCreateOptions), 1, (ProArray*)&options); options[0]= PRO_FEAT_CR_INCOMPLETE_FEAT; status = ProFeatureWithoptionsCreate( model_sel, elem_tree, options, PRO_REGEN_NO_FLAGS, &feature, &err_list ); TEST_CALL_REPORT( "ProFeatureWithoptionsCreate","ProTestFirstFeatureCreate()", status, status != PRO_TK_NO_ERROR ); status = ProArrayFree((ProArray*)&options); /*-------------------------------------------------*\ Release element tree \*-------------------------------------------------*/ status = ProElementFree( &elem_tree ); TEST_CALL_REPORT( "ProElementFree","ProTestFirstFeatureCreate()", status, status != PRO_TK_NO_ERROR ); /*-------------------------------------------------*\ Complete the feature adding the sketched section \*-------------------------------------------------*/ status = ProTestFeatureSectionInit( &feature, section, NULL, PRO_B_TRUE ); return status; }