/* Copyright (c) 2024 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved. */ #include <ProToolkit.h> #include <ProDwgtable.h> #include <ProPoint.h> /*--------------------------------------------------------------------*\ Data structure for information needed about datum points \*--------------------------------------------------------------------*/ typedef struct point_t { ProFeature feature; ProVector position; ProName name; } Point_t; int UsrPointsCollect(); int UsrTableTextAdd(); /*====================================================================*\ FUNCTION : UsrPointTable() PURPOSE : Command to create a table of datum points \*====================================================================*/ int UsrPointTable () { ProError status; ProSelection *sel; int n_sel, n_points, p; ProSolid solid; ProCharName csys_name; char name[PRO_MDLNAME_SIZE], type[PRO_MDLEXTENSION_SIZE]; ProName wname; ProGeomitem csys_geom; ProAsmcomppath csys_comppath; ProMatrix from_csys, to_csys, trf; ProGeomitemdata *gdata; ProMouseButton button; ProVector pos; Point_t *points; ProDwgtabledata tdata; double widths[] = {8.0, 8.0, 10.0, 10.0, 10.0}; ProHorzJust justs[] = { PROHORZJUST_LEFT, PROHORZJUST_LEFT, PROHORZJUST_LEFT, PROHORZJUST_LEFT, PROHORZJUST_LEFT}; double *heights; int last_feat_row; ProDrawing drawing; ProDwgtable table; ProCharLine line; ProFileName msgfil; ProMdlName modelName; ProMdlExtension modelExtension; ProStringToWstring (msgfil, "msg_ugdrawing.txt"); /*--------------------------------------------------------------------*\ Select a coordinate system. This defines the model (the top one in that view), and the reference for the datum point positions. \*--------------------------------------------------------------------*/ 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); /*--------------------------------------------------------------------*\ Extract the csys handle, and assembly path. \*--------------------------------------------------------------------*/ ProSelectionModelitemGet(sel[0], &csys_geom); ProSelectionAsmcomppathGet(sel[0], &csys_comppath); /*--------------------------------------------------------------------*\ Extract the csys location \*--------------------------------------------------------------------*/ ProGeomitemdataGet(&csys_geom, &gdata); ProMatrixInit(gdata->data.p_csys_data->x_vector, gdata->data.p_csys_data->y_vector, gdata->data.p_csys_data->z_vector, gdata->data.p_csys_data->origin, from_csys); ProUtilMatrixInvert(from_csys, to_csys); ProGeomitemdataFree(&gdata); /*--------------------------------------------------------------------*\ Extract the csys name \*--------------------------------------------------------------------*/ ProModelitemNameGet(&csys_geom, wname); ProWstringToString(csys_name, wname); /*--------------------------------------------------------------------*\ Get the root solid, and the transform from the root to the component owning the csys \*--------------------------------------------------------------------*/ if(csys_comppath.table_num > 0) { solid = csys_comppath.owner; ProAsmcomppathTrfGet(&csys_comppath, PRO_B_FALSE, trf); } else { solid = csys_geom.owner; ProUtilMatrixCopy(NULL, trf); } /*--------------------------------------------------------------------*\ Get a list of datum points in the model \*--------------------------------------------------------------------*/ UsrPointsCollect(solid, &points); ProArraySizeGet(points, &n_points); if(n_points < 1) return(0); /*--------------------------------------------------------------------*\ Get the user to select the table position \*--------------------------------------------------------------------*/ ProMessageDisplay(msgfil,"USER Pick table position"); if(ProMousePickGet(PRO_ANY_BUTTON, &button, pos) != PRO_TK_NO_ERROR) return(0); /*--------------------------------------------------------------------*\ Setup the table data \*--------------------------------------------------------------------*/ ProDwgtabledataAlloc(&tdata); ProDwgtabledataOriginSet(tdata, pos); ProDwgtabledataSizetypeSet(tdata, PRODWGTABLESIZE_CHARACTERS); ProDwgtabledataColumnsSet(tdata, 5, widths, justs); heights = (double*)calloc(n_points+2, sizeof(double)); for(p=0;p<n_points+2;p++) heights[p] = 1.0; ProDwgtabledataRowsSet(tdata, n_points+2, heights); free(heights); /*--------------------------------------------------------------------*\ Create the table \*--------------------------------------------------------------------*/ ProMdlCurrentGet((ProMdl*)&drawing); ProDrawingTableCreate(drawing, tdata, PRO_B_FALSE, &table); /*--------------------------------------------------------------------*\ Merge the top row cells to form the header \*--------------------------------------------------------------------*/ ProDwgtableCellsMerge(&table, 1, 1, 5, 1, PRO_B_FALSE); /*--------------------------------------------------------------------*\ Write header text specifying model and csys \*--------------------------------------------------------------------*/ ProMdlMdlnameGet(solid, modelName); ProMdlExtensionGet(solid, modelExtension); ProWstringToString(name, modelName); ProWstringToString(type, modelExtension); ProTKSprintf(line, "Datum points for %s.%s, w.r.t csys %s\n", name, type, csys_name); UsrTableTextAdd(&table, 1, 1, line); /*--------------------------------------------------------------------*\ Add subheadings to columns \*--------------------------------------------------------------------*/ UsrTableTextAdd(&table, 1, 2, "Feat id"); UsrTableTextAdd(&table, 2, 2, "Point"); UsrTableTextAdd(&table, 3, 2, "X"); UsrTableTextAdd(&table, 4, 2, "Y"); UsrTableTextAdd(&table, 5, 2, "Z"); /*--------------------------------------------------------------------*\ For each datum point... \*--------------------------------------------------------------------*/ for(p=0;p<n_points;p++) { /*--------------------------------------------------------------------*\ If the owning feature is the same as the last one, just merge column 1 with the cell above, else enter the feature id \*--------------------------------------------------------------------*/ if(p == 0 || points[p].feature.id != points[p-1].feature.id) { ProTKSprintf(name, "%d", points[p].feature.id); UsrTableTextAdd(&table, 1, p+3, name); last_feat_row = p+3; } else ProDwgtableCellsMerge(&table, 1, last_feat_row, 1, p+3, PRO_B_FALSE); /*--------------------------------------------------------------------*\ Add the point name to column 2 \*--------------------------------------------------------------------*/ ProWstringToString(name, points[p].name); UsrTableTextAdd(&table, 2, p+3, name); /*--------------------------------------------------------------------*\ Transform the location w.r.t to the csys \*--------------------------------------------------------------------*/ ProPntTrfEval(points[p].position, trf, points[p].position); ProPntTrfEval(points[p].position, to_csys, points[p].position); /*--------------------------------------------------------------------*\ Add the XYZ to column 3,4,5 \*--------------------------------------------------------------------*/ ProTKSprintf(name,"%8.3f", points[p].position[0]); UsrTableTextAdd(&table, 3, p+3, name); ProTKSprintf(name,"%8.3f", points[p].position[1]); UsrTableTextAdd(&table, 4, p+3, name); ProTKSprintf(name,"%8.3f", points[p].position[2]); UsrTableTextAdd(&table, 5, p+3, name); } /*--------------------------------------------------------------------*\ Display the table \*--------------------------------------------------------------------*/ ProDwgtableDisplay(&table); return(1); } /*====================================================================*\ FUNCTION : UsrTableTextAdd() PURPOSE : Utility to add one text line to a table cell \*====================================================================*/ int UsrTableTextAdd( ProDwgtable *table, int col, int row, char *text) { ProWstring *lines; ProArrayAlloc(1, sizeof(ProWstring), 1, (ProArray*)&lines); lines[0] = (wchar_t*)calloc(strlen(text) + 1, sizeof(wchar_t)); ProStringToWstring(lines[0], text); ProDwgtableTextEnter(table, col, row, lines); ProArrayFree((ProArray*)&lines); } /*====================================================================*\ FUNCTION : UsrPointAction() PURPOSE : Visit action function called for each datum point \*====================================================================*/ ProError UsrPointAction( ProGeomitem *geomitem, ProError filt_status, ProAppData data) { Point_t point; ProPoint p; /*--------------------------------------------------------------------*\ Find out which feature the datum point belongs to \*--------------------------------------------------------------------*/ ProGeomitemFeatureGet(geomitem, &point.feature); /*--------------------------------------------------------------------*\ Get the point position \*--------------------------------------------------------------------*/ ProPointInit(geomitem->owner, geomitem->id, &p); ProPointCoordGet(p, point.position); /*--------------------------------------------------------------------*\ Get the point name \*--------------------------------------------------------------------*/ ProModelitemNameGet(geomitem, point.name); /*--------------------------------------------------------------------*\ Add the point to the array \*--------------------------------------------------------------------*/ ProArrayObjectAdd((ProArray*)data, -1, 1, &point); return(PRO_TK_NO_ERROR); } /*====================================================================*\ FUNCTION : UsrFeatureAction() PURPOSE : Visit action function called for each feature \*====================================================================*/ ProError UsrFeatureAction( 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, UsrPointAction, NULL, data); return(PRO_TK_NO_ERROR); } /*====================================================================*\ FUNCTION : UsrPointsCollect() PURPOSE : Collect an array of datum points in the solid \*====================================================================*/ int UsrPointsCollect( ProSolid solid, Point_t **points) { /*--------------------------------------------------------------------*\ Allocate the array \*--------------------------------------------------------------------*/ ProArrayAlloc(0, sizeof(Point_t), 1, (ProArray*)points); /*--------------------------------------------------------------------*\ Visit the features \*--------------------------------------------------------------------*/ ProSolidFeatVisit(solid, UsrFeatureAction, NULL, points); }