/*
Copyright (c) 2024 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved.
*/
/*--------------------------------------------------------------------*\
Pro/Toolkit includes
\*--------------------------------------------------------------------*/
#include <ProToolkit.h>
#include <ProMenuBar.h>
#include <ProMdl.h>
#include <ProPart.h>
#include <ProMdlUnits.h>
#include <ProSolid.h>
#include <ProMessage.h>
#include <ProUtil.h>
#include <ProWstring.h>
#include <ProSelbuffer.h>
#include <TestError.h>
/*--------------------------------------------------------------------*\
Application global/external data
\*--------------------------------------------------------------------*/
static wchar_t MSGFIL[] = {'u','t','i','l','i','t','i','e','s','.','t','x','t','\0'};
/*=====================================================================*\
FUNCTION: UserPartInfoMass
PURPOSE: Write a part's mass value & units to the message window.
\*=====================================================================*/
int UserPartInfoMass (ProPart part)
{
ProError status;
double density;
ProMassProperty massProps;
ProUnitsystem unitSystem;
ProUnitsystemType type;
ProUnititem unit, forceUnit, timeUnit, lengthUnit;
ProLine massUnitsLabel;
/*--------------------------------------------------------------------*\
Check for the density. If it hasn't been set, inform the user
\*--------------------------------------------------------------------*/
status = ProPartDensityGet (part, &density);
if (status != PRO_TK_NO_ERROR)
{
ProMessageDisplay ( MSGFIL, "USER Part has not been assigned density.");
return PRO_TK_E_NOT_FOUND;
}
/*--------------------------------------------------------------------*\
Extract the mass properties using the default part coordinate system
\*--------------------------------------------------------------------*/
status = ProSolidMassPropertyGet (part, NULL, &massProps);
/*--------------------------------------------------------------------*\
Extract system of units
\*--------------------------------------------------------------------*/
status = ProMdlPrincipalunitsystemGet (part, &unitSystem);
ProUnitsystemTypeGet (&unitSystem, &type);
if (type == PRO_UNITSYSTEM_MLT)
{
ProUnitsystemUnitGet (&unitSystem, PRO_UNITTYPE_MASS, &unit);
ProWstringCopy (unit.name, massUnitsLabel, PRO_VALUE_UNUSED);
}
else
{
/*--------------------------------------------------------------------*\
If the units are Force/Length/Time, format the units into the correct
equivalent for mass.
\*--------------------------------------------------------------------*/
ProUnitsystemUnitGet (&unitSystem, PRO_UNITTYPE_FORCE, &forceUnit);
ProUnitsystemUnitGet (&unitSystem, PRO_UNITTYPE_TIME, &timeUnit);
ProUnitsystemUnitGet (&unitSystem, PRO_UNITTYPE_LENGTH, &lengthUnit);
ProMessageToBuffer (massUnitsLabel,
MSGFIL, "USER Force unit -> mass", &forceUnit.name,
&timeUnit.name, &lengthUnit.name);
}
/*--------------------------------------------------------------------*\
Show the mass to the user
\*--------------------------------------------------------------------*/
ProMessageDisplay ( MSGFIL, "USER Part mass", &massProps.mass, &massUnitsLabel);
return PRO_TK_NO_ERROR;
}
/*=====================================================================*\
FUNCTION: UserPartInfoMass_AO
PURPOSE: Action/Object callback for extracting mass from a part.
\*=====================================================================*/
int UserPartInfoMass_AO()
{
ProMdl currMdl;
ProError status;
status = ProMdlCurrentGet (&currMdl);
ERROR_CHECK ("UserPartInfoMass_AO()",
"ProMdlCurrentGet()", status);
UserPartInfoMass ((ProPart)currMdl);
return (1);
}
/*=====================================================================*\
FUNCTION: UserPartInfoMass_TestAO
PURPOSE: Access function for extracting mass from the current part.
\*=====================================================================*/
uiCmdAccessState UserPartInfoMass_TestAO (uiCmdAccessMode mode)
{
ProMdl currMdl;
ProError status;
ProMdlType type;
status = ProMdlCurrentGet (&currMdl);
ERROR_CHECK ("UserPartInfoMass_TestAO()",
"ProMdlCurrentGet()", status);
if (status == PRO_TK_NO_ERROR)
{
status = ProMdlTypeGet (currMdl, &type);
if (status == PRO_TK_NO_ERROR && type == PRO_MDL_PART)
return ACCESS_AVAILABLE;
}
return ACCESS_UNAVAILABLE;
}
/*=====================================================================*\
FUNCTION: UserPartInfoMass_OA
PURPOSE: Object/Action callback for extracting mass from the selected part.
\*=====================================================================*/
int UserPartInfoMass_OA()
{
ProError status;
ProSelection* sel_array;
ProModelitem item;
/*--------------------------------------------------------------------*\
Extract the current selected part
\*--------------------------------------------------------------------*/
status = ProSelbufferSelectionsGet (&sel_array);
status = ProSelectionModelitemGet (sel_array [0], &item);
UserPartInfoMass (item.owner);
ProSelectionarrayFree (sel_array);
return (1);
}
#define OA 1 /* Standard OA in the menu system, typically gray out
the button when not usable*/
#define PM 2 /* OA in a popup menu, typically remove the button when
not usable */
/*=====================================================================*\
FUNCTION: UserPartInfoMass_TestLow
PURPOSE: Access function for the button for printing mass info for a part.
\*=====================================================================*/
static uiCmdAccessState UserPartInfoMass_TestLow (ProSelection* sels, int mode)
{
uiCmdAccessState access_result;
ProBoolean should_free = PRO_B_FALSE;
ProError status;
int size;
/*-----------------------------------------------------------------*\
Set the default return if the button is unusable.
\*-----------------------------------------------------------------*/
if (mode == OA)
access_result = ACCESS_UNAVAILABLE;
else
access_result = ACCESS_REMOVE;
/*-----------------------------------------------------------------*\
If called without selections, extract the current selections from
the buffer.
\*-----------------------------------------------------------------*/
if (sels == NULL)
{
status = ProSelbufferSelectionsGet (&sels);
if (status != PRO_TK_NO_ERROR)
return access_result;
if (sels == NULL)
return access_result;
should_free = PRO_B_TRUE;
}
/*-----------------------------------------------------------------*\
This command allows only one selection.
\*-----------------------------------------------------------------*/
status = ProArraySizeGet (sels, &size);
if (status != PRO_TK_NO_ERROR)
return access_result;
if (size == 1)
{
ProModelitem item;
status = ProSelectionModelitemGet (sels [0], &item);
/*-----------------------------------------------------------------*\
The selected type must be part.
\*-----------------------------------------------------------------*/
if (item.type == PRO_PART)
{
access_result = ACCESS_AVAILABLE;
}
}
if (should_free)
ProSelectionarrayFree (sels);
return access_result;
}
/*=====================================================================*\
FUNCTION: UserPartInfoMass_TestMdlTree
PURPOSE: Access function for the model tree popup menu button.
\*=====================================================================*/
uiCmdAccessState UserPartInfoMass_TestMdlTree (uiCmdAccessMode mode)
{
return UserPartInfoMass_TestLow (NULL, PM);
}
/*=====================================================================*\
FUNCTION: UserPartInfoMass_TestPM
PURPOSE: Access function for the graphics window popup menu button.
\*=====================================================================*/
uiCmdAccessState UserPartInfoMass_TestPM (uiCmdCmdId id,
ProAppData data,
ProSelection* sels)
{
return UserPartInfoMass_TestLow (sels, PM);
}
#undef OA
#undef PM