/*
Copyright (c) 2024 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved.
*/
/*--------------------------------------------------------------------*\
Pro/Toolkit includes
\*--------------------------------------------------------------------*/
#include <ProToolkit.h>
#include <ProSelection.h>
#include <ProObjects.h>
#include <ProSolid.h>
#include <ProGeomitem.h>
#include <ProModelitem.h>
#include <ProMdl.h>
#include <ProExtobj.h>
#include <ProExtobjDisp.h>
#include <ProMessage.h>
#include <ProSurface.h>
/*--------------------------------------------------------------------*\
Application includes
\*--------------------------------------------------------------------*/
#include "ProUtil.h"
#include "TestError.h"
#include "UtilMath.h"
#include "math.h"
/*--------------------------------------------------------------------*\
Application data
\*--------------------------------------------------------------------*/
static ProExtobjClass User_arrow_class ;
/*====================================================================*\
FUNCTION : UserExtobjCreate()
PURPOSE : Example of external object creation.
\*====================================================================*/
int UserExtobjCreate()
{
static int calls = 0 ; /* number of calls to this func. */
static int extobjid = 1 ; /* ids for external objects */
int UserMakeSelections(ProSurface *, ProModelitem *, Pro3dPnt ) ;
/* function to get user selections */
ProMdl model ; /* current model */
ProName msg_file ; /* message file */
ProSurface surf ; /* target surface to get arrow */
ProModelitem surf_mdlitem ; /* target surface ProModelitem */
ProModelitem surf_owner_mdlitem ; /* ProModelitem for surface owner */
int status ; /* return value */
ProUvParam surf_uv ; /* surface point in uv*/
ProVector surf_xyz ; /* surface point in xyz */
ProVector deriv1[2], deriv2[3] ; /* derivatives at point on surf */
ProVector surf_norm; /* surface normal */
ProExtobj arrow_obj ; /* ext. object to be created */
ProWExtobjdata arrow_disp_data = NULL ;
/* display data for the ext. object */
double scale ; /* scale factor for ext. object */
Pro3dPnt outline_points[2] ; /* points delimiting solid */
ProCurvedata curvedata[10] ; /* array of curves to be drawn */
int i, j ; /* counters */
ProMatrix transform ; /* arrow transformation */
int num_box; /* number of selection boxes */
ProWExtobjdata sel_data = NULL; /* selection data */
ProSelbox sel_box[16], *sel_box_ptr; /* list of selection boxes */
/*--------------------------------------------------------------------*\
Unit arrow to be transformed and scaled.
\*--------------------------------------------------------------------*/
#define ARROW_COLOR PRO_COLOR_SHEETMETAL /* Green. */
#define ARROW_LINESTYLE PRO_LINESTYLE_SOLID /* Solid lines. */
#define ARROW_SCALE 0.1 /* Scale factor (fraction of model size). */
#define ARROW_NUM_SEG 9 /* Number of segments in arrow. */
#define HW 0.2 /* Head width. */
#define HL 0.2 /* Head length. */
ProLinedata unit_arrow[ARROW_NUM_SEG] = {
{ PRO_ENT_LINE, {HL,0.0,0.0}, {1.0,0.0,0.0} }, /* arrow "shaft" */
{ PRO_ENT_LINE, {0.0,0.0,0.0}, {HL,HW,0.0} },
{ PRO_ENT_LINE, {0.0,0.0,0.0}, {HL,0.0,HW} },
{ PRO_ENT_LINE, {0.0,0.0,0.0}, {HL,-HW,0.0} },
{ PRO_ENT_LINE, {0.0,0.0,0.0}, {HL,0.0,-HW} },
{ PRO_ENT_LINE, {HL,HW,0.0}, {HL,0.0,HW} },
{ PRO_ENT_LINE, {HL,0.0,HW}, {HL,-HW,0.0} },
{ PRO_ENT_LINE, {HL,-HW,0.0}, {HL,0.0,-HW} },
{ PRO_ENT_LINE, {HL,0.0,-HW}, {HL,HW,0.0} }
} ;
/*--------------------------------------------------------------------*\
Get current model.
\*--------------------------------------------------------------------*/
status = ProMdlCurrentGet(&model);
ERROR_CHECK("UserExtobjCreate()", "ProMdlCurrentGet()", status);
if (status != PRO_TK_NO_ERROR)
{
ProStringToWstring(msg_file, "msg_ugfund.txt") ;
ProMessageDisplay(msg_file, "USER %0s F", "Error getting current model.");
return(status) ;
}
/*--------------------------------------------------------------------*\
Create the external object class.
\*--------------------------------------------------------------------*/
if (calls == 0)
{
ProStringToWstring(User_arrow_class.name, "Arrows");
User_arrow_class.type = 0;
status = ProExtobjClassCreate(&User_arrow_class) ;
ERROR_CHECK("UserExtobjCreate()", "ProExtobjClassCreate()", status);
}
++calls ;
/*--------------------------------------------------------------------*\
Use model size to get the scale.
\*--------------------------------------------------------------------*/
status = ProSolidOutlineGet( (ProSolid) model, outline_points) ;
ERROR_CHECK("UserExtobjCreate()", "ProSolidOutlineGet()", status);
scale = ARROW_SCALE * ProUtilPointsDist (outline_points[1],
outline_points[0]);
/*--------------------------------------------------------------------*\
Get ProSurface and ProModelitem from user selection. Also get the
xyz point that is selected.
\*--------------------------------------------------------------------*/
status = UserMakeSelections(&surf, &surf_mdlitem, surf_xyz) ;
ERROR_CHECK("UserExtobjCreate()", "UserMakeSelections()", status);
/*--------------------------------------------------------------------*\
Get the ProModelitem for the surface owner.
\*--------------------------------------------------------------------*/
status = ProMdlToModelitem(surf_mdlitem.owner, &surf_owner_mdlitem) ;
/*--------------------------------------------------------------------*\
Determine the uv parameters from the xyz point.
\*--------------------------------------------------------------------*/
status = ProSurfaceParamEval( (ProSolid) surf_mdlitem.owner, surf,
surf_xyz, surf_uv) ;
ERROR_CHECK("UserExtobjCreate()", "ProSurfaceParamEval()", status);
/*--------------------------------------------------------------------*\
Evaluate surface data (normal, gradient, ...) at the uv point.
\*--------------------------------------------------------------------*/
status = ProSurfaceXyzdataEval(surf, surf_uv, surf_xyz,
deriv1, deriv2, surf_norm);
ERROR_CHECK("UserExtobjCreate()", "ProSurfaceXyzdataEval()", status);
/*--------------------------------------------------------------------*\
Get transformation for the arrow.
\*--------------------------------------------------------------------*/
ProUtilVectorNormalize(surf_norm, surf_norm) ;
ProUtilVectorNormalize(deriv1[0], deriv1[0]) ;
ProUtilVectorNormalize(deriv1[1], deriv1[1]) ;
status = ProUtilVectorsToTransf(surf_norm, deriv1[0], deriv1[1],
surf_xyz, transform) ;
/*--------------------------------------------------------------------*\
Create the arrow object.
\*--------------------------------------------------------------------*/
status = ProExtobjCreate(&User_arrow_class, &surf_owner_mdlitem,
&arrow_obj) ;
ERROR_CHECK("UserExtobjCreate()", "ProExtobjCreate()", status);
/*--------------------------------------------------------------------*\
Set object identifiers to be reusable.
\*--------------------------------------------------------------------*/
status = ProExtobjReusableSet(&arrow_obj) ;
ERROR_CHECK("UserExtobjCreate()", "ProExtobjReusableSet()", status);
/*--------------------------------------------------------------------*\
Initialize the display data structure.
\*--------------------------------------------------------------------*/
status = ProDispdatAlloc(&arrow_disp_data) ;
ERROR_CHECK("UserExtobjCreate()", "ProDispdatAlloc()", status);
/*--------------------------------------------------------------------*\
Set the display scale, color, linetype, and display properties.
\*--------------------------------------------------------------------*/
status = ProDispdatScaleSet(arrow_disp_data, scale) ;
ERROR_CHECK("UserExtobjCreate()", "ProDispdatScaleSet()", status);
status = ProDispdatColorSet(arrow_disp_data, ARROW_COLOR) ;
ERROR_CHECK("UserExtobjCreate()", "ProDispdatColorSet()", status);
status = ProDispdatLinestyleSet(arrow_disp_data, ARROW_LINESTYLE) ;
ERROR_CHECK("UserExtobjCreate()", "ProDispdatLinestyleSet()", status);
/*--------------------------------------------------------------------*\
Set the line segments (the "entities") in the display data.
\*--------------------------------------------------------------------*/
for (i = 0; i < ARROW_NUM_SEG; ++i)
{
curvedata[i].line.type = unit_arrow[i].type ;
for (j = 0; j<3 ; ++j)
{
curvedata[i].line.end1[j] = unit_arrow[i].end1[j] ;
curvedata[i].line.end2[j] = unit_arrow[i].end2[j] ;
}
}
status = ProDispdatEntsSet(arrow_disp_data, &curvedata[0], ARROW_NUM_SEG) ;
ERROR_CHECK("UserExtobjCreate()", "ProDispdatEntsSet()", status);
/*--------------------------------------------------------------------*\
Set arrow transformation.
\*--------------------------------------------------------------------*/
status = ProDispdatTrfSet(arrow_disp_data, transform) ;
ERROR_CHECK("UserExtobjCreate()", "ProDispdatTrfSet()", status);
/*--------------------------------------------------------------------*\
Add the display data to the object.
\*--------------------------------------------------------------------*/
status = ProExtobjdataAdd(&arrow_obj, &User_arrow_class,
arrow_disp_data) ;
ERROR_CHECK("UserExtobjCreate()", "ProExtobjdataAdd()", status);
status = ProSeldatAlloc (&sel_data);
ERROR_CHECK("UserExtobjCreate()", "ProSeldatAlloc()", status);
sel_box_ptr = &sel_box[0];
(*sel_box_ptr)[0][0] = 0.0;
(*sel_box_ptr)[0][1] = 0.0;
(*sel_box_ptr)[0][2] = 0.0;
(*sel_box_ptr)[1][0] = 0.5;
(*sel_box_ptr)[1][1] = 0.5;
(*sel_box_ptr)[1][2] = 0.5;
num_box = 1;
status = ProSeldatSelboxesSet (sel_data, sel_box, num_box);
ERROR_CHECK("UserExtobjCreate()", "ProSeldatSelboxesSet()", status);
status = ProExtobjdataAdd (&arrow_obj, &User_arrow_class, sel_data);
ERROR_CHECK("UserExtobjCreate()", "ProExtobjdataAdd()", status);
status = ProExtobjdataFree (&sel_data);
ERROR_CHECK("UserExtobjCreate()", "ProExtobjdataFree()", status);
/*--------------------------------------------------------------------*\
Repaint the window so the object is displayed.
\*--------------------------------------------------------------------*/
ProWindowRepaint(PRO_VALUE_UNUSED) ;
return(PRO_TK_NO_ERROR) ;
}