/* Copyright (c) 2024 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved. */ #include <ProToolkit.h> #include <ProParameter.h> #include <ProMaterial.h> #include <ProUtil.h> #include <ProSolid.h> #include <ProMdlUnits.h> #include <ProSelbuffer.h> #include <ProUICmd.h> #include <ProMessage.h> #include <ProModelitem.h> #include <TestError.h> extern int UserPartInfoMass (ProPart part); /*====================================================================*\ FUNCTION: UserApplyAndUpdateMaterial() PURPOSE: Read a material from file, read some of its properties, and add a user-defined parameter to it. Then assign it to the model and calculate the model mass properties. \*====================================================================*/ ProError UserApplyAndUpdateMaterial (ProPart part) { ProError status; ProFileName msg_file; ProName fopen_label; ProLine filter_string; ProPath* shortcut_paths; ProName* shortcut_names; ProPath mtl_file; ProPath mtl_file_path; ProPath current_dir; ProMdlName mtl_name; ProMaterialItem material_item; ProParamvalue mtl_type, mtl_density; ProUnititem units; int mtl_type_value; ProParamvalue mtl_prop_value; ProName mtl_prop_name; ProParameter param; ProMaterial material; ProPath unit_expression; ProMassProperty mass_prop; ProUnitsystem unit_system; ProUnititem mass_unit; /*--------------------------------------------------------------------*\ Set up the message file. \*--------------------------------------------------------------------*/ ProStringToWstring (msg_file, "msg_ugparam.txt"); /*--------------------------------------------------------------------*\ Get the material file name from the user. \*--------------------------------------------------------------------*/ ProStringToWstring (fopen_label, "Select material file"); ProStringToWstring (filter_string, "*.mtl"); ProArrayAlloc (0, sizeof (ProPath), 1, (ProArray*)&shortcut_paths); ProArrayAlloc (0, sizeof (ProName), 1, (ProArray*)&shortcut_names); status = ProFileMdlnameOpen (fopen_label, filter_string, shortcut_paths, shortcut_names, NULL, NULL, mtl_file); ProArrayFree ((ProArray*)&shortcut_paths); ProArrayFree ((ProArray*)&shortcut_names); if (status != PRO_TK_NO_ERROR) { return (status); } /*--------------------------------------------------------------------*\ Change Pro/ENGINEER to the material file directory \*--------------------------------------------------------------------*/ ProFileMdlnameParse (mtl_file, mtl_file_path, mtl_name, NULL, NULL); ProDirectoryCurrentGet (current_dir); ProDirectoryChange (mtl_file_path); /*--------------------------------------------------------------------*\ Read the material from the file. \*--------------------------------------------------------------------*/ status = ProMaterialfileRead (part, mtl_name); ProDirectoryChange (current_dir); if (status != PRO_TK_NO_ERROR) { ProMessageDisplay (msg_file, "UG MaterialFile Read Error", mtl_name); ProDirectoryChange (current_dir); return (status); } /*--------------------------------------------------------------------*\ Get the material type and density. \*--------------------------------------------------------------------*/ status = ProModelitemByNameInit (part, PRO_RP_MATERIAL, mtl_name, &material_item); status = ProMaterialPropertyGet (&material_item, PRO_MATPROP_TYPE, &mtl_type, &units); status = ProMaterialPropertyGet (&material_item, PRO_MATPROP_MASS_DENSITY, &mtl_density, &units); /*--------------------------------------------------------------------*\ Convert the density units to a user-readable format. \*--------------------------------------------------------------------*/ status = ProUnitExpressionGet (&units, unit_expression); /*--------------------------------------------------------------------*\ Create a user-defined material property based on the type. \*--------------------------------------------------------------------*/ ProStringToWstring (mtl_prop_name, "STRUCTURAL_TYPE"); mtl_type_value = mtl_type.value.i_val; mtl_prop_value.type = PRO_PARAM_STRING; if (mtl_type_value & PRO_MATERIAL_TYPE_STRUCTURAL_ISOTROPIC) { ProStringToWstring (mtl_prop_value.value.s_val, "Isotropic"); } else if (mtl_type_value & PRO_MATERIAL_TYPE_STRUCTURAL_ORTHOTROPIC) { ProStringToWstring (mtl_prop_value.value.s_val, "Orthotropic"); } else ProStringToWstring (mtl_prop_value.value.s_val, "Transversely orthotropic"); ProStringToWstring (mass_unit.name,"in"); status = ProParameterWithUnitsCreate (&material_item, mtl_prop_name, &mtl_prop_value,&mass_unit, ¶m); /*--------------------------------------------------------------------*\ Assign the material. \*--------------------------------------------------------------------*/ material.part = part; ProWstringCopy (mtl_name, material.matl_name, PRO_VALUE_UNUSED); status = ProMaterialCurrentSet (&material); ProMessageDisplay (msg_file, "UG MaterialFile Mass Info", mtl_name, &mtl_density.value.d_val, unit_expression); /*--------------------------------------------------------------------*\ Compute and display the mass properties. \*--------------------------------------------------------------------*/ UserPartInfoMass (part); return (0); } /*=====================================================================*\ FUNCTION: UserApplyMaterial_OA PURPOSE: Object/Action callback for applying material to the part. \*=====================================================================*/ int UserApplyMaterial_OA() { ProError status; ProSelection* sel_array; ProModelitem item; /*--------------------------------------------------------------------*\ Extract the current selected part \*--------------------------------------------------------------------*/ status = ProSelbufferSelectionsGet (&sel_array); status = ProSelectionModelitemGet (sel_array [0], &item); UserApplyAndUpdateMaterial (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: UserApplyMaterial_TestLow PURPOSE: Access function for the button for applying material to a part. \*=====================================================================*/ static uiCmdAccessState UserApplyMaterial_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: UserApplyMaterial_TestMdlTree PURPOSE: Access function for the model tree popup menu button. \*=====================================================================*/ uiCmdAccessState UserApplyMaterial_TestMdlTree (uiCmdAccessMode mode) { return UserApplyMaterial_TestLow (NULL, PM); } /*=====================================================================*\ FUNCTION: UserApplyMaterial_TestPM PURPOSE: Access function for the graphics window popup menu button. \*=====================================================================*/ uiCmdAccessState UserApplyMaterial_TestPM (uiCmdCmdId id, ProAppData data, ProSelection* sels) { return UserApplyMaterial_TestLow (sels, PM); } #undef OA #undef PM