/*
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);
}