/*
Copyright (c) 2024 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved.
*/
#include <ProToolkit.h>
#include <ProMfg.h>
#include <ProSolid.h>
#include <ProSelection.h>
#include <ProAsmcomppath.h>
#include <ProElement.h>
#include <ProElemId.h>
#include <ProValue.h>
#include <ProFeature.h>
#include <ProUtil.h>
#include <ProWcell.h>
#include <ProUtil.h>
#include <ProModelitem.h>
#include <ProMfgOptions.h>
#include <ProFeatType.h>
#include <ProToolinput.h>
#include <ProMdlUnits.h>
#include <ProTool.h>
#include <ProTKRunTime.h>
#include <TestError.h>
#include <UtilString.h>
#include <UtilTree.h>
#include <TestConsts.h>
#include <UgMfg.h>
/*====================================================================*\
FUNCTION : UserMfgWcellInitTools
PURPOSE : Create tools and add to tool table
\*====================================================================*/
static ProError UserMfgWcellInitTools( ProMfg mfg_model,
ProElement tool_arr_elem )
{
ProTool tool;
ProError err = PRO_TK_NO_ERROR;
static MfgPrmDblValue drill_params[] =
{
{ "CUTTER_DIAM", 12.0 },
{ "LENGTH", 80.0 },
{ "POINT_ANGLE", 118.0 }
};
static MfgPrmDblValue center_drill_params[] =
{
{ "CUTTER_DIAM", 13.0 },
{ "POINT_ANGLE", 118.0 },
{ "LENGTH", 50.0 },
{ "CSINK_ANGLE", 90.0 },
{ "DRILL_DIAMETER", 5.0 },
{ "DRILL_LENGTH", 5.0 },
};
static MfgPrmDblValue end_mill_params[] =
{
{ "CUTTER_DIAM", 20.0 },
{ "LENGTH", 60.0 }
};
int n_params= 0;
int pocket_num;
ProPath tool_file;
/*-----------------------------------------------*/
/* Add drill */
/*-----------------------------------------------*/
pocket_num = 1;
n_params = sizeof( drill_params )/sizeof( MfgPrmDblValue );
err = UserParamToolCreate( mfg_model, PRO_TOOL_DRILL, L"DRILL_D12",
drill_params, n_params, PRO_UNITLENGTH_MM,
&tool );
ERROR_CHECK( "UserMfgWcellInitTools", "UserParamToolCreate", err );
err = UserMfgWcellAddToolSetup( &tool, pocket_num, tool_arr_elem );
ERROR_CHECK( "UserMfgWcellInitTools", "UserMfgWcellAddToolSetup", err );
/*-----------------------------------------------*/
/* Add center-drill */
/*-----------------------------------------------*/
pocket_num = 2;
n_params = sizeof( center_drill_params )/sizeof( MfgPrmDblValue );
err = UserParamToolCreate( mfg_model, PRO_TOOL_CENTER_DRL, L"C-DRILL_D12",
center_drill_params, n_params, PRO_UNITLENGTH_MM,
&tool );
ERROR_CHECK( "UserMfgWcellInitTools", "UserParamToolCreate", err );
err = UserMfgWcellAddToolSetup( &tool, pocket_num, tool_arr_elem );
ERROR_CHECK( "UserMfgWcellInitTools", "UserMfgWcellAddToolSetup", err );
/*-----------------------------------------------*/
/* Add end mill */
/*-----------------------------------------------*/
pocket_num = 3;
n_params = sizeof( end_mill_params )/sizeof( MfgPrmDblValue );
err = UserParamToolCreate( mfg_model, PRO_TOOL_END_MILL, L"END_MILL_D20",
end_mill_params, n_params, PRO_UNITLENGTH_MM,
&tool );
ERROR_CHECK( "UserMfgWcellInitTools", "UserParamToolCreate", err );
err = UserMfgWcellAddToolSetup( &tool, pocket_num, tool_arr_elem );
ERROR_CHECK( "UserMfgWcellInitTools", "UserMfgWcellAddToolSetup", err );
/*-----------------------------------------------*/
/* Add drill by reading a file */
/*-----------------------------------------------*/
pocket_num = 4;
ProStringToWstring ( tool_file, "mill_d20.xml");
err = UserToolFileRead( mfg_model, L"MILL_D20", tool_file, PRO_B_TRUE,
&tool );
ERROR_CHECK( "UserMfgWcellInitTools", "UserToolFileRead", err );
err = UserMfgWcellAddToolSetup( &tool, pocket_num, tool_arr_elem );
ERROR_CHECK( "UserMfgWcellInitTools", "UserMfgWcellAddToolSetup", err );
return ( err );
}
/*====================================================================*\
Function : UserToolHeadSet()
Purpose : Setup a tool table
\*====================================================================*/
static ProError UserToolHeadSet( ProElement head_elem )
{
ProError err = PRO_TK_NO_ERROR;
ProMfg mfg_model;
ProElement tool_arr_elem;
err = ProMdlCurrentGet( (ProMdl*)&mfg_model );
ERROR_CHECK( "UserToolHeadSet","ProMdlCurrentGet", err );
err = ProElementAlloc( PRO_E_MFG_WCELL_TOOL_SETUP_ARR, &tool_arr_elem );
ERROR_CHECK( "UserToolHeadSet", "ProElementAlloc", err );
err = UserMfgWcellInitTools( mfg_model, tool_arr_elem );
ERROR_CHECK( "UserToolHeadSet","UserMfgWcellInitTools",err );
err = ProElemtreeElementAdd( head_elem, NULL, tool_arr_elem );
ERROR_CHECK( "UserToolHeadSet","ProElemtreeElementAdd",err );
return ( err );
}
/*====================================================================*\
FUNCTION : UserWorkcellCreate
PURPOSE : Create a workcell
\*====================================================================*/
int UserWorkcellCreate ()
{
ProMdl mfg_model;
ProElement element = NULL; /* Individual element */
ProElement elem_tree = NULL; /* Entire tree */
ProValueData value_data;
ProValue value;
ProFeature wc_feature;
ProError err = PRO_TK_NO_ERROR;
int n_dbl_params = 0;
int n_str_params = 0;
int ii = 0, num_elems = 0;
static ElemTable elem_table[] =
{
{ PRO_E_FEATURE_TYPE, PRO_VALUE_TYPE_INT },
{ PRO_E_WCELL_TYPE, PRO_VALUE_TYPE_INT },
{ PRO_E_STD_FEATURE_NAME, PRO_VALUE_TYPE_WSTRING },
{ PRO_E_MFG_WCELL_NUM_AXES, PRO_VALUE_TYPE_INT },
{ PRO_E_MFG_PARAM_ARR, ARRAY },
{ PRO_E_MFG_WCELL_HEAD_1, COMPOUND },
{ PRO_E_MFG_COMMENTS, PRO_VALUE_TYPE_WSTRING }
};
static MfgPrmDblValue dbl_params[] = /* example (not required) */
{
{ "RAPID_FEED_RATE", 500.0 }
};
static MfgPrmStrValue str_params[] = /* examples (not required) */
{
{ "MACH_NAME", L"GPOST348" },
{ "MACH_ID", L"5" },
{ "CONTROLLER", L"FANUC 6M" },
{ "LOADTL_OUTPUT", L"MODAL_OUTPUT" },
{ "SPINDL_OFF_OUTPUT", L"NO" },
{ "COOLNT_OFF_OUTPUT", L"NO" },
{ "CUTCOM_GEOMETRY_TYPE", L"OUTPUT_ON_CENTER" }
};
n_dbl_params = sizeof( dbl_params ) / sizeof( MfgPrmDblValue );
n_str_params = sizeof( str_params ) / sizeof( MfgPrmStrValue );
/*
*/
num_elems = sizeof( elem_table ) / sizeof( ElemTable );
err = ProElementAlloc( PRO_E_FEATURE_TREE, &elem_tree );
ERROR_CHECK( "UserWorkcellCreate","ProElementAlloc()", err );
for ( ii = 0 ; ii < num_elems; ii++ )
{
err = ProElementAlloc( elem_table[ii].elem_type, &element );
ERROR_CHECK( "UserWorkcellCreate","ProElementAlloc()", err );
switch ( elem_table[ii].elem_type )
{
case PRO_E_FEATURE_TYPE:
value_data.v.i = PRO_FEAT_WORKCELL;
break;
case PRO_E_WCELL_TYPE:
value_data.v.i = PRO_WCELL_MILL;
break;
case PRO_E_MFG_WCELL_NUM_AXES:
value_data.v.i = PRO_WCELL_3_AXIS;
break;
case PRO_E_MFG_PARAM_ARR:
if ( n_dbl_params != 0 || n_str_params != 0 )
{
err = UserMfgParamArrSet( dbl_params, n_dbl_params,
str_params, n_str_params,
element );
ERROR_CHECK( "UserWorkcellCreate", "UserMfgParamArrSet()", err );
}
else
{
err = ProElementFree( &element );
continue;
}
break;
case PRO_E_STD_FEATURE_NAME:
value_data.v.w = (wchar_t*) malloc( sizeof( ProName ) );
if ( value_data.v.w != NULL )
ProStringToWstring( value_data.v.w, "Mill_3_Axis" );
break;
case PRO_E_MFG_COMMENTS:
value_data.v.w = (wchar_t*) malloc( sizeof(ProComment) );
if ( value_data.v.w != NULL )
ProStringToWstring( value_data.v.w, "Just example" );
break;
case PRO_E_MFG_WCELL_HEAD_1:
err = UserToolHeadSet( element );
break;
default:
ProTKFprintf( stderr, "Error setting element type\n" );
err = PRO_TK_GENERAL_ERROR;
ERROR_CHECK( "UserWorkcellCreate", "UserWorkcellCreate()", err );
break;
}
if ( elem_table[ii].val_type == PRO_VALUE_TYPE_INT)
{
err = ProElementIntegerSet (element, value_data.v.i);
ERROR_CHECK( "UserWorkcellCreate","ProElementIntegerSet()", err );
}
else if (elem_table[ii].val_type == PRO_VALUE_TYPE_WSTRING )
{
err = ProElementWstringSet(element, value_data.v.w);
ERROR_CHECK( "UserWorkcellCreate", "ProElementWstringSet()", err );
}
err = ProElemtreeElementAdd( elem_tree, NULL, element );
ERROR_CHECK( "UserWorkcellCreate", "ProElemtreeElementAdd()", err );
}
ProUtilElementtreePrint( elem_tree, PRO_TEST_INFO_WINDOW, NULL );
err = ProMdlCurrentGet( &mfg_model );
ERROR_CHECK( "UserWorkcellCreate","ProMdlCurrentGet", err );
/*********************************************/
/* Create feature */
/*********************************************/
err = UserMfgModelFeatureCreate( mfg_model, elem_tree, &wc_feature );
ERROR_CHECK( "UserWorkcellCreate", "UserMfgModelFeatureCreate()", err );
err = ProElementFree( &elem_tree );
ERROR_CHECK( "UserWorkcellCreate", "ProElementFree()", err );
return( (int)err );
}
/*====================================================================*\
Function : UserWpieceSelCreate()
Purpose : Create a selection handle for the mfg assembly or items in it
\*====================================================================*/
ProError UserWpieceSelCreate (
/*--------------------------------------------------------------------*/
ProMfg mfg_model,
int item_id,
ProType item_type,
ProSelection *selection
)
/*--------------------------------------------------------------------*/
{
ProSolid mfg_solid;
ProAsmcomppath comp_path;
ProModelitem wkpiece_item;
ProError err = PRO_TK_NO_ERROR;
err = ProMfgSolidGet( mfg_model, &mfg_solid );
ERROR_CHECK( "UserWpieceSelCreate", "ProMfgSolidGet()", err );
if ( err == PRO_TK_NO_ERROR )
{
err= ProMfgFeatureOwnerGet( mfg_model, &comp_path );
ERROR_CHECK( "UserWpieceSelCreate", "ProMfgSolidGet()", err );
}
if ( err == PRO_TK_NO_ERROR )
{
err = ProModelitemInit( mfg_solid, item_id, item_type, &wkpiece_item );
ERROR_CHECK( "UserWpieceSelCreate", "ProModelitemInit()", err );
}
if ( err == PRO_TK_NO_ERROR )
{
err = ProSelectionAlloc( &comp_path, &wkpiece_item, selection );
ERROR_CHECK( "UserWpieceSelCreate", "ProSelectionAlloc()", err );
}
return ( err );
}
/*====================================================================*\
FUNCTION : UserToolSetupSet
PURPOSE : Create tools and add to tool table
\*====================================================================*/
ProError UserToolSetupSet(
/*--------------------------------------------------------------------*/
ProTool *tool,
int pocket_num,
ProElement tool_setup_elem
)
/*--------------------------------------------------------------------*/
{
ProError err = PRO_TK_NO_ERROR;
ProElement element = NULL;
ProValueData value_data;
ProValue value;
int ii = 0, table_size = 0;
static ElemTable tsetup_elem_table[] =
{
{ PRO_E_MFG_WCELL_TOOL_POCKET_NUM, PRO_VALUE_TYPE_INT },
{ PRO_E_MFG_WCELL_TOOL_ID, PRO_VALUE_TYPE_WSTRING }
};
table_size = sizeof( tsetup_elem_table ) / sizeof( ElemTable );
for ( ii = 0; ii < table_size; ii++ )
{
err = ProElementAlloc( tsetup_elem_table[ii].elem_type, &element );
ERROR_CHECK( "UserToolSetupSet","ProElementAlloc()", err );
switch ( tsetup_elem_table[ii].elem_type )
{
case PRO_E_MFG_WCELL_TOOL_POCKET_NUM:
value_data.v.i = pocket_num;
err = ProElementIntegerSet (element, value_data.v.i);
break;
case PRO_E_MFG_WCELL_TOOL_ID:
value_data.v.w = (wchar_t*) malloc( sizeof( ProName ) );
if ( value_data.v.w != NULL )
{
err = ProWstringCopy( tool->tool_id, value_data.v.w,
PRO_VALUE_UNUSED );
ERROR_CHECK( "UserToolSetupSet","ProWstringCopy()", err );
}
err = ProElementWstringSet(element, value_data.v.w);
ERROR_CHECK( "UserToolSetupSet","ProElementWstringSet()", err );
break;
default:
ProTKFprintf( stderr, "Error setting element type\n" );
err = PRO_TK_GENERAL_ERROR;
ERROR_CHECK( "UserToolSetupSet","UserToolSetupSet()", err );
break;
}
err = ProElemtreeElementAdd( tool_setup_elem, NULL, element );
ERROR_CHECK( "UserToolSetupSet","ProElemtreeElementAdd", err );
}
return ( err );
}
/*====================================================================*\
FUNCTION : UserMfgWcellAddToolSetup
PURPOSE : Adds tool setup element
\*====================================================================*/
ProError UserMfgWcellAddToolSetup( ProTool *tool,
int pocket_num,
ProElement tool_arr_elem )
{
ProError err = PRO_TK_NO_ERROR;
ProElement tool_setup_elem = NULL;
err = ProElementAlloc( PRO_E_MFG_WCELL_TOOL_SETUP, &tool_setup_elem );
ERROR_CHECK( "UserMfgWcellAddToolSetup", "ProElementAlloc", err );
err = UserToolSetupSet( tool, pocket_num, tool_setup_elem );
ERROR_CHECK( "UserMfgWcellAddToolSetup", "UserToolSetupSet", err );
err = ProElemtreeElementAdd( tool_arr_elem, NULL, tool_setup_elem );
ERROR_CHECK( "UserMfgWcellAddToolSetup","ProElemtreeElementAdd", err );
return ( err );
}
/*====================================================================*\
FUNCTION : UserWorkcellTreeToolPocketGet
PURPOSE : Finds pocket by tool id (first found)
\*====================================================================*/
ProBool UserWorkcellTreeToolPocketGet(
/*--------------------------------------------------------------------*/
ProElement wc_elem_tree,
ProMfgToolHeadType head_num,
ProLine tool_name,
int *p_pocket_num
)
/*--------------------------------------------------------------------*/
{
ProError err = PRO_TK_NO_ERROR;
ProElement elem_tree;
ProElempath path;
ProElempath id_path;
ProElempath pocket_path;
ProElement tool_arr_elem;
ProElement *tool_setups;
ProElement tool_id_elem;
ProElement pocket_elem;
ProLine tool_name_upper;
ProValue value;
wchar_t *tool_id = NULL;
int tool_arr_path_size;
int pocket_num = 1;
int result;
int ii, num;
ProBool found = PRO_B_FALSE;
ProElempathItem p_items[3];
ProElempathItem tooling_path_items[2] =
{
{ PRO_ELEM_PATH_ITEM_TYPE_ID, PRO_E_MFG_WCELL_HEAD_1 },
{ PRO_ELEM_PATH_ITEM_TYPE_ID, PRO_E_MFG_WCELL_TOOL_SETUP_ARR }
};
tool_arr_path_size = sizeof( tooling_path_items )/sizeof( ProElempathItem );
/*-------------------------------------------------------*\
Get element PRO_E_MFG_WCELL_TOOL_SETUP_ARR
\*-------------------------------------------------------*/
if ( head_num == PRO_MFG_TOOL_HEAD_2 )
tooling_path_items[0].path_item.elem_id = PRO_E_MFG_WCELL_HEAD_2;
ProElempathAlloc( &path );
ProElempathDataSet( path, tooling_path_items, tool_arr_path_size );
ProArrayAlloc( 0, sizeof(ProElement), 4, (ProArray *)&tool_setups );
err = ProElementChildrenGet( wc_elem_tree, path, &tool_setups );
ERROR_CHECK( "UserWorkcellTreeToolPocketGet", "ProElementChildrenGet", err );
ProElempathFree( &path );
ProArraySizeGet( (ProArray)tool_setups, &num );
ProElempathAlloc( &pocket_path );
p_items[0].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
p_items[0].path_item.elem_id = PRO_E_MFG_WCELL_TOOL_POCKET_NUM ;
ProElempathDataSet( pocket_path, p_items, 1 );
ProElempathAlloc( &id_path );
p_items[0].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
p_items[0].path_item.elem_id = PRO_E_MFG_WCELL_TOOL_ID ;
ProElempathDataSet( id_path, p_items, 1 );
for ( ii = 0; ii < num; ii++ )
{
/*-------------------------------------------------------*\
Get element PRO_E_MFG_WCELL_TOOL_ID
\*-------------------------------------------------------*/
err = ProElemtreeElementGet( tool_setups[ii], id_path, &tool_id_elem );
ERROR_CHECK( "UserWorkcellTreeToolPocketGet", "ProElemtreeElementGet",
err );
err = ProElementWstringGet( tool_id_elem, NULL, &tool_id );
ERROR_CHECK( "UserWorkcellTreeToolPocketGet", "ProElementWstringGet", err );
err = ProWstringCompare( tool_name, tool_id, PRO_VALUE_UNUSED, &result );
ERROR_CHECK( "UserWorkcellTreeToolPocketGet", "ProWstringCompare", err );
ProWstringFree( tool_id );
if ( result == 0 )
{
err = ProElemtreeElementGet( tool_setups[ii], pocket_path,
&pocket_elem );
ERROR_CHECK( "UserWorkcellTreeToolPocketGet", "ProElemtreeElementGet",
err );
err = ProElementIntegerGet( pocket_elem, NULL, &pocket_num );
ERROR_CHECK( "UserWorkcellTreeToolPocketGet", "ProElementIntegerGet",
err );
found = PRO_B_TRUE;
break;
}
}
if ( p_pocket_num != NULL )
*p_pocket_num = pocket_num;
ProElempathFree( &id_path );
ProElempathFree( &pocket_path );
ProArrayFree( (ProArray *)&tool_setups );
return ( found );
}
/*====================================================================*\
FUNCTION : UserWorkcellToolAdd
PURPOSE : Add flat mill cutter to workcell tooling
\*====================================================================*/
ProError UserWorkcellToolAdd(
/*--------------------------------------------------------------------*/
ProMfg mfg_model,
ProSelection workcell,
ProMfgToolHeadType head_num,
ProToolType tool_type,
ProLine tool_name,
MfgPrmDblValue params[],
int n_params,
ProUnitLength units,
ProBool allow_reuse_existing,
int *p_pocket_num
)
/*--------------------------------------------------------------------*/
{
ProError err = PRO_TK_NO_ERROR;
ProErrorlist errors;
ProElement elem_tree;
ProFeature wcell_feat;
ProTool tool;
ProElempath path;
ProElement tool_arr_elem;
ProElement tool_setup_elem;
ProBool found = PRO_B_FALSE;
int path_size;
int pocket_num = 1;
ProElempathItem tooling_path_items[2] =
{
{ PRO_ELEM_PATH_ITEM_TYPE_ID, PRO_E_MFG_WCELL_HEAD_1 },
{ PRO_ELEM_PATH_ITEM_TYPE_ID, PRO_E_MFG_WCELL_TOOL_SETUP_ARR }
};
ProFeatureCreateOptions opts[] = {PRO_FEAT_CR_NO_OPTS};
path_size = sizeof( tooling_path_items ) / sizeof( ProElempathItem );
err = ProToolInit( tool_name, mfg_model, &tool );
ERROR_CHECK( "UserWorkcellToolAdd", "ProToolInit", err );
/*-------------------------------------------------------*\
Verify that tool doesn't exist in mfg model
\*-------------------------------------------------------*/
err = ProToolVerify( &tool );
if ( err == PRO_TK_E_NOT_FOUND )
{
/*-------------------------------------------------------*\
Add tool to mfg model if it doesn't exist
\*-------------------------------------------------------*/
err = UserParamToolCreate( mfg_model, tool_type, tool_name,
params, n_params, units, &tool );
ERROR_CHECK( "UserWorkcellToolAdd", "UserParamToolCreate", err );
}
/*-------------------------------------------------------*\
Extract workcell elem tree to modify (to add new tool)
\*-------------------------------------------------------*/
err = ProSelectionModelitemGet( workcell, &wcell_feat );
ERROR_CHECK( "UserWorkcellToolAdd", "ProSelectionModelitemGet", err );
err = ProFeatureElemtreeExtract( &wcell_feat, NULL,
PRO_FEAT_EXTRACT_NO_OPTS,
&elem_tree );
ERROR_CHECK( "UserWorkcellToolAdd", "ProFeatureElemtreeExtract", err );
/*-------------------------------------------------------*\
Pocket number
\*-------------------------------------------------------*/
if ( allow_reuse_existing )
{
found = UserWorkcellTreeToolPocketGet( elem_tree, head_num, tool_name,
&pocket_num );
if ( found )
{
if ( p_pocket_num != NULL )
*p_pocket_num = pocket_num;
return ( PRO_TK_NO_ERROR );
}
}
err = ProWcellMaxToolPosGet( &wcell_feat, head_num, &pocket_num );
ERROR_CHECK( "UserWorkcellToolAdd", "ProWcellMaxToolPosGet", err );
pocket_num++;
/*-------------------------------------------------------*\
Get element PRO_E_MFG_WCELL_TOOL_SETUP_ARR
\*-------------------------------------------------------*/
if ( head_num == PRO_MFG_TOOL_HEAD_2 )
tooling_path_items[0].path_item.elem_id = PRO_E_MFG_WCELL_HEAD_2;
ProElempathAlloc( &path );
ProElempathDataSet( path, tooling_path_items, path_size );
err = ProElemtreeElementGet( elem_tree, path, &tool_arr_elem );
ERROR_CHECK( "UserWorkcellToolAdd", "ProElemtreeElementGet", err );
ProElempathFree( &path );
/*-------------------------------------------------------*\
Add tool setup
\*-------------------------------------------------------*/
err = UserMfgWcellAddToolSetup( &tool, pocket_num, tool_arr_elem );
ERROR_CHECK( "UserWorkcellToolAdd", "UserMfgWcellAddToolSetup", err );
/*-------------------------------------------------------*\
Redefined workcell feature
\*-------------------------------------------------------*/
err = ProFeatureRedefine( NULL, &wcell_feat, elem_tree, opts, 1, &errors );
if ( err != PRO_TK_NO_ERROR )
ProTKFprintf( stderr, "Error in element %d\n",
errors.error_list[0].err_item_id );
ERROR_CHECK( "UserWorkcellToolAdd","ProFeatureRedefine", err );
if ( tool_name != NULL )
ProWstringCopy( tool.tool_id, tool_name, PRO_VALUE_UNUSED );
if ( p_pocket_num != NULL )
*p_pocket_num = pocket_num;
return ( err );
}