/*
Copyright (c) 2019 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved.
*/
/*------------------------------------------------------------------*\
Pro/Toolkit includes
\*------------------------------------------------------------------*/
#include <ProToolkit.h>
#include <ProObjects.h>
#include <ProFeature.h>
#include <ProDimension.h>
#include <ProAxis.h>
#include <ProUtil.h>
#include <ProSolid.h>
#include <ProMessage.h>
#include <ProAnnotation.h>
/*------------------------------------------------------------------*\
Application includes
\*------------------------------------------------------------------*/
#include <TestError.h>
#include <UtilMath.h>
typedef struct
{
ProVector vector; /* The direction that the dimension should
be parallel to */
ProBoolean found; /* Flag signalling if any matching
dimensions were found. */
ProDimension dim_found; /* May be used if visiting in an attempt
to locate a certain dimension */
} DimByVector;
/*==================================================================*\
FUNCTION : UserDimensionFilterByVector()
PURPOSE : Find linear dimensions oriented parallel to vector (a filter
action)
\*==================================================================*/
ProError UserDimensionFilterByVector (ProDimension* dim,
ProAppData appdata)
{
ProDimlocation dimloc;
ProDimensiontype type;
ProPoint3d arrow_1, arrow_2;
int i;
ProError status;
ProVector dimvector;
double dotproduct;
DimByVector* data = (DimByVector*) appdata;
/*------------------------------------------------------------------*\
Continue only for linear dimensions
\*------------------------------------------------------------------*/
ProDimensionTypeGet (dim, &type);
if (type != PRODIMTYPE_LINEAR)
return (PRO_TK_CONTINUE);
/*------------------------------------------------------------------*\
Extract the location of the arrows of the dimension
\*------------------------------------------------------------------*/
status = ProDimensionLocationGet (dim, NULL, NULL, &dimloc);
if (status != PRO_TK_NO_ERROR)
return (PRO_TK_CONTINUE);
ProDimlocationArrowsGet (dimloc, arrow_1, arrow_2);
ProDimlocationFree (dimloc);
/*------------------------------------------------------------------*\
Construct, validate, and normalize the dimension direction vector
\*------------------------------------------------------------------*/
for (i = 0; i < 3; i++)
dimvector [i] = arrow_2 [i] - arrow_1 [i];
if (ProUtilVectorLength (dimvector) < EPSM6 )
return (PRO_TK_CONTINUE);
ProUtilVectorNormalize (dimvector, dimvector);
/*------------------------------------------------------------------*\
Check if the angle between the vectors is 0 or 180 degrees
\*------------------------------------------------------------------*/
dotproduct = ProUtilVectorDot (data->vector, dimvector);
if (fabs (fabs (dotproduct) - 1.0) < EPSM6 )
{
data->found = PRO_B_TRUE;
return (PRO_TK_NO_ERROR);
}
else
return (PRO_TK_CONTINUE);
}
/*==================================================================*\
FUNCTION : UserDimensionShow()
PURPOSE : Show the given dimension (a visit action)
\*==================================================================*/
ProError UserDimensionShow (ProDimension* dim,
ProError error_status,
ProAppData appdata)
{
ProAnnotationShow ( (ProAnnotation*)dim, NULL, NULL);
return (PRO_TK_NO_ERROR);
}
/*==================================================================*\
FUNCTION : UserDimensionsByDirectionShow()
PURPOSE : Highlight linear dimensions in the feature that are
oriented parallel to a given vector.
\*==================================================================*/
ProError UserDimensionsByDirectionShow(ProSolid solid,
ProFeature* feature,
ProVector vector)
{
DimByVector data;
ProError status;
ProFileName msg_file;
ProStringToWstring(msg_file, "msg_ugfund.txt");
memcpy (data.vector, vector, sizeof (ProVector));
data.found = PRO_B_FALSE;
if (feature != NULL)
{
/*------------------------------------------------------------------*\
Visit all feature dimensions.
\*------------------------------------------------------------------*/
status = ProFeatureDimensionVisit (feature,
UserDimensionShow,
UserDimensionFilterByVector,
(ProAppData)&data);
}
else
{
/*------------------------------------------------------------------*\
Visit all model dimensions.
\*------------------------------------------------------------------*/
status = ProSolidDimensionVisit (solid,
PRO_B_FALSE,
UserDimensionShow,
UserDimensionFilterByVector,
&data);
}
/*------------------------------------------------------------------*\
Return based on the success of the visit.
\*------------------------------------------------------------------*/
if (status != PRO_TK_NO_ERROR || data.found == PRO_B_FALSE)
{
ProMessageDisplay(msg_file, "USER %0s F",
"No dimensions found parallel to the supplied direction.");
return (PRO_TK_E_NOT_FOUND);
}
else
{
ProMessageDisplay(msg_file, "USER %0s F",
"Showing dimensions parallel to the supplied direction.");
return(PRO_TK_NO_ERROR);
}
}
/*==================================================================*\
FUNCTION : UserDimensionsByAxisDirectionShow()
PURPOSE : Highlight model or feature dimensions parallel to a
selected axis.
\*==================================================================*/
ProError UserDimensionsByAxisDirectionShow ()
{
ProError status;
ProSelection* sels;
int n_sels = -1;
ProFileName msg_file;
ProSolid input_solid_ptr;
ProFeature* input_feat_ptr;
ProFeature feature;
ProModelitem axis_item;
ProAxis axis;
ProGeomitemdata* axis_data;
ProVector dirvector;
int i;
ProStringToWstring(msg_file, "msg_ugfund.txt") ;
/*------------------------------------------------------------------*\
Prompt to select the context
\*------------------------------------------------------------------*/
ProMessageDisplay(msg_file, "USER %0s F",
"Select the feature for locating dimensions. <CANCEL> to locate dimensions in the current model.");
status = ProSelect ("feature", 1, NULL, NULL, NULL, NULL,
&sels, &n_sels);
if (status == PRO_TK_USER_ABORT)
{
ProMdlCurrentGet ((ProMdl)&input_solid_ptr);
input_feat_ptr = NULL;
}
else if (status != PRO_TK_NO_ERROR || n_sels < 1)
{
return (PRO_TK_USER_ABORT);
}
else
{
ProSelectionModelitemGet (sels [0], &feature);
input_solid_ptr = NULL;
input_feat_ptr = &feature;
}
/*------------------------------------------------------------------*\
Prompt to select the axis
\*------------------------------------------------------------------*/
ProMessageDisplay(msg_file, "USER %0s F",
"Select the axis for orientation of the dimensions.");
status = ProSelect ("axis", 1, NULL, NULL, NULL, NULL, &sels, &n_sels);
if (status != PRO_TK_NO_ERROR || n_sels < 1)
{
return (PRO_TK_USER_ABORT);
}
/*------------------------------------------------------------------*\
Extract the direction vector of the axis
\*------------------------------------------------------------------*/
ProSelectionModelitemGet (sels [0], &axis_item);
ProGeomitemToAxis (&axis_item, &axis);
ProAxisDataGet (axis, &axis_data);
for (i = 0; i < 3; i ++)
dirvector [i] = axis_data->data.p_curve_data->line.end2 [i] -
axis_data->data.p_curve_data->line.end1 [i];
ProUtilVectorNormalize (dirvector, dirvector);
ProGeomitemdataFree (&axis_data);
/*------------------------------------------------------------------*\
Show the dimensions
\*------------------------------------------------------------------*/
UserDimensionsByDirectionShow (input_solid_ptr, input_feat_ptr, dirvector);
return PRO_TK_NO_ERROR;
}