/* Copyright (c) 2024 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved. */ #include <ProToolkit.h> #include <ProDrawing.h> #include <ProDimension.h> #include <ProArray.h> #include <ProSolid.h> #include <ProFeature.h> #include <ProPoint.h> #include <ProMessage.h> #include <ProAnnotation.h> int UsrPointGeomitemsCollect(ProSolid solid, ProGeomitem **points); /*====================================================================*\ FUNCTION: UsrDimPoints() PURPOSE : Command to create a table of datum points \*====================================================================*/ int UsrDimPoints() { ProError status; ProSelection *sel, csys_sel; int n_sel, n_points, p; ProSolid solid; ProGeomitem csys_geom; ProAsmcomppath csys_comppath; ProMatrix trf; ProVector csys_pos, csys_3dpos, pnt_pos, dim_pos, outline[2]; ProGeomitem *points; ProDrawing drawing; ProSelection *attachments; ProDimSense *senses; ProDimension dimension, vbase_dim, hbase_dim; ProPoint point; ProView view; ProFileName msgfil; ProStringToWstring (msgfil, "msg_ugdrawing.txt"); ProMdlCurrentGet((ProMdl*)&drawing); /*--------------------------------------------------------------------*\ Select a coordinate system. This defines the model (the top one in that view), and the common attachments for the dimensions \*--------------------------------------------------------------------*/ ProMessageDisplay(msgfil,"USER Select csys"); status = ProSelect("csys",1,NULL,NULL,NULL,NULL,&sel,&n_sel); if(status != PRO_TK_NO_ERROR || n_sel < 1) return(0); ProSelectionCopy(sel[0], &csys_sel); ProSelectionModelitemGet(csys_sel, &csys_geom); ProSelectionAsmcomppathGet(csys_sel, &csys_comppath); /*--------------------------------------------------------------------*\ Get the root solid \*--------------------------------------------------------------------*/ if(csys_comppath.table_num > 0) solid = csys_comppath.owner; else solid = csys_geom.owner; /*--------------------------------------------------------------------*\ Get a list of datum points in the model \*--------------------------------------------------------------------*/ UsrPointGeomitemsCollect(solid, &points); ProArraySizeGet(points, &n_points); if(n_points < 1) return(0); /*--------------------------------------------------------------------*\ Calculate where the csys is located on the drawing \*--------------------------------------------------------------------*/ ProSelectionPoint3dGet(csys_sel, csys_pos); if(csys_comppath.table_num > 0) { ProAsmcomppathTrfGet(&csys_comppath, PRO_B_TRUE, trf); ProPntTrfEval(csys_pos, trf, csys_pos); } memcpy(csys_3dpos, csys_pos, sizeof(ProVector)); ProSelectionViewGet(csys_sel, &view); ProDrawingViewTransformGet(drawing, view, PRO_B_TRUE, trf); ProPntTrfEval(csys_pos, trf, csys_pos); /*--------------------------------------------------------------------*\ Get the view outline \*--------------------------------------------------------------------*/ ProDrawingViewOutlineGet(drawing, view, outline); /*--------------------------------------------------------------------*\ Allocate the attachment arrays \*--------------------------------------------------------------------*/ ProArrayAlloc(2, sizeof(ProSelection), 1, (ProArray*)&attachments); ProArrayAlloc(2, sizeof(ProDimSense), 1, (ProArray*)&senses); /*--------------------------------------------------------------------*\ For each datum point... \*--------------------------------------------------------------------*/ for(p=0;p<n_points;p++) { ProDimAttachment* attachmentsArr = NULL; /*--------------------------------------------------------------------*\ Calculate the position of the point on the drawing \*--------------------------------------------------------------------*/ ProPointInit(points[p].owner, points[p].id, &point); ProPointCoordGet(point, pnt_pos); ProPntTrfEval(pnt_pos, trf, pnt_pos); /*--------------------------------------------------------------------*\ Set up the "sense" information for the point attachment (Specify a vertical dimension) \*--------------------------------------------------------------------*/ senses[0].type = PRO_DIM_SNS_TYP_PNT; senses[0].sense = PRO_POINT_TYP_CENTER; senses[0].orient_hint = PRO_DIM_ORNT_VERT; /*--------------------------------------------------------------------*\ Set up the "sense" information for the csys attachment \*--------------------------------------------------------------------*/ senses[1].type = PRO_DIM_SNS_TYP_PNT; senses[1].sense = PRO_POINT_TYP_CENTER; senses[1].orient_hint = PRO_DIM_ORNT_NONE; /*--------------------------------------------------------------------*\ Set the attachment information \*--------------------------------------------------------------------*/ ProSelectionAlloc(NULL, &points[p], &attachments[0]); ProSelectionViewSet(view, &attachments[0]); ProSelectionCopy(csys_sel, &attachments[1]); ProArrayAlloc(2, sizeof(ProDimAttachment), 1, (ProArray*)&attachmentsArr); ProSelectionCopy(attachments[0], &attachmentsArr[0][0]); ProSelectionCopy(attachments[1], &attachmentsArr[1][0]); attachmentsArr[0][1] = NULL; attachmentsArr[1][1] = NULL; /*--------------------------------------------------------------------*\ Calculate the dim position to be just to the left of the drawing view, midway between the point and csys \*--------------------------------------------------------------------*/ dim_pos[0] = outline[0][0] - 20.0; dim_pos[1] = (csys_pos[1] + pnt_pos[1]) / 2.0; dim_pos[2] = 0.0; /*--------------------------------------------------------------------*\ Create and display the dimension \*--------------------------------------------------------------------*/ ProDrawingDimensionCreate(drawing, attachmentsArr, senses, PRO_DIM_ORNT_NONE, dim_pos, PRO_B_FALSE, &dimension); ProAnnotationShow ((ProAnnotation*)&dimension, NULL, view); /*--------------------------------------------------------------------*\ If this is the first vertical dim, create an ordinate base line from it, else just convert it to ordinate \*--------------------------------------------------------------------*/ if(p==0) ProDrawingOrdbaselineCreate(drawing, &dimension, csys_3dpos, &vbase_dim); else ProDrawingDimToOrdinate(drawing, &dimension, &vbase_dim); /*--------------------------------------------------------------------*\ Set this dimension to be horizontal \*--------------------------------------------------------------------*/ senses[0].orient_hint = PRO_DIM_ORNT_HORIZ; /*--------------------------------------------------------------------*\ Calculate the dim position to be just to the bottom of the drawing view, midway between the point and csys \*--------------------------------------------------------------------*/ dim_pos[0] = (csys_pos[0] + pnt_pos[0]) / 2.0; dim_pos[1] = outline[0][1] - 20.0; /*--------------------------------------------------------------------*\ Create and display the dimension \*--------------------------------------------------------------------*/ ProDrawingDimensionCreate(drawing, attachmentsArr, senses, PRO_DIM_ORNT_NONE, dim_pos, PRO_B_FALSE, &dimension); ProAnnotationShow ((ProAnnotation*)&dimension, NULL, view); /*--------------------------------------------------------------------*\ If this is the first horizontal dim, create an ordinate base line from it, else just convert it to ordinate \*--------------------------------------------------------------------*/ if(p==0) ProDrawingOrdbaselineCreate(drawing, &dimension, csys_3dpos, &hbase_dim); else ProDrawingDimToOrdinate(drawing, &dimension, &hbase_dim); /*--------------------------------------------------------------------*\ Free the attachment selection objects \*--------------------------------------------------------------------*/ ProSelectionFree(&attachments[0]); ProSelectionFree(&attachments[1]); } return(1); } /*====================================================================*\ FUNCTION : UsrPointAddAction() PURPOSE : Visit action function called for each datum point \*====================================================================*/ ProError UsrPointAddAction( ProGeomitem *geomitem, ProError filt_status, ProAppData data) { /*--------------------------------------------------------------------*\ Add the point to the array \*--------------------------------------------------------------------*/ ProArrayObjectAdd((ProArray*)data, -1, 1, geomitem); return(PRO_TK_NO_ERROR); } /*====================================================================*\ FUNCTION : UsrFeatureGetPointsAction() PURPOSE: Visit action function called for each feature \*====================================================================*/ ProError UsrFeatureGetPointsAction( ProFeature *feature, ProError filt_status, ProAppData data) { ProFeatStatus fstatus; /*--------------------------------------------------------------------*\ If the feature is not active, skip it \*--------------------------------------------------------------------*/ ProFeatureStatusGet(feature, &fstatus); if(fstatus != PRO_FEAT_ACTIVE) return(PRO_TK_NO_ERROR); /*--------------------------------------------------------------------*\ Visit the datum points in the feature \*--------------------------------------------------------------------*/ ProFeatureGeomitemVisit(feature, PRO_POINT, UsrPointAddAction, NULL, data); return(PRO_TK_NO_ERROR); } /*====================================================================*\ FUNCTION : UsrPointGeomitemsCollect() PURPOSE: Collect an array of datum points in the solid \*====================================================================*/ int UsrPointGeomitemsCollect( ProSolid solid, ProGeomitem **points) { /*--------------------------------------------------------------------*\ Allocate the array \*--------------------------------------------------------------------*/ ProArrayAlloc(0, sizeof(ProGeomitem), 1, (ProArray*)points); /*--------------------------------------------------------------------*\ Visit the features \*--------------------------------------------------------------------*/ ProSolidFeatVisit(solid, UsrFeatureGetPointsAction, NULL, points); }