/* Copyright (c) 2024 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved. */ #include <ProToolkit.h> #include <ProFeature.h> #include <ProSelbuffer.h> #include <ProReference.h> #include <ProUtil.h> #include <ProSmtFlatWall.h> #include <ProSheetmetal.h> #include <ProMenuBar.h> #include <ProPopupmenu.h> #include <ProMdl.h> #include <PTApplsUnicodeUtils.h> #include <ProEdge.h> #include <ProFeatType.h> /*=====================================================================*\ FUNCTION: UserSmtFlatWallCreate PURPOSE: Create sheetmetal flat wall features. \*=====================================================================*/ int UserSmtFlatWallCreate (ProReference edge_ref, double bend_radius, ProSection section) { ProError status; ProElement pro_e_feature_tree; ProElement pro_e_feature_type; ProElement pro_e_smt_wall_type; ProElement pro_e_std_feature_name; ProElement pro_e_smt_flat_wall_att_edge; ProElement pro_e_smt_flat_wall_angle; ProElement pro_e_smt_flat_wall_angle_type; ProElement pro_e_smt_flat_wall_angle_val; ProElement pro_e_smt_flat_wall_angle_flip; ProElement pro_e_std_section; ProElement pro_e_sketcher; ProElement pro_e_smt_fillets; ProElement pro_e_smt_fillets_use_rad; ProElement pro_e_smt_fillets_side; ProElement pro_e_smt_fillets_value; ProElement pro_e_smt_wall_height; ProElement pro_e_smt_wall_height_type; ProElement pro_e_smt_wall_height_value; ProElement pro_e_smt_bend_relief; ProElement pro_e_smt_bend_relief_side1; ProElement pro_e_bend_relief_type; ProElement pro_e_bend_relief_width; ProElement pro_e_bend_relief_depth; ProElement pro_e_bend_relief_angle; ProElement pro_e_smt_bend_relief_side2; ProElement pro_e_smt_wall_thickness_flip; ProElement pro_e_smt_dev_len_calculation; ProElement pro_e_smt_dev_len_source; ProElement pro_e_smt_dev_len_y_factor; ProElement pro_e_smt_dev_len_y_factor_value; ProElement pro_e_smt_dev_len_y_factor_type; ProElement pro_e_smt_dev_len_bend_table; ProMdl model; ProModelitem model_item; ProFeatureCreateOptions *opts = 0; ProSelection model_sel; ProFeature feature; ProErrorlist errors; ProSelection feat_sel; /*-----------------------------------------------------------------*\ Processing Element PRO_E_FEATURE_TREE \*-----------------------------------------------------------------*/ status = ProElementAlloc ( PRO_E_FEATURE_TREE, &pro_e_feature_tree ); /*-----------------------------------------------------------------*\ Processing Element PRO_E_FEATURE_TYPE \*-----------------------------------------------------------------*/ status = ProElementAlloc ( PRO_E_FEATURE_TYPE, &pro_e_feature_type ); status = ProElementIntegerSet ( pro_e_feature_type, PRO_FEAT_WALL ); status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_feature_type ); /*-----------------------------------------------------------------*\ Processing Element PRO_E_SMT_WALL_TYPE \*-----------------------------------------------------------------*/ status = ProElementAlloc ( PRO_E_SMT_WALL_TYPE, &pro_e_smt_wall_type ); status = ProElementIntegerSet ( pro_e_smt_wall_type, PRO_SMT_WALL_TYPE_FLAT ); status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_smt_wall_type ); /*-----------------------------------------------------------------*\ Processing Element PRO_E_SMT_FLAT_WALL_ATT_EDGE \*-----------------------------------------------------------------*/ status = ProElementAlloc ( PRO_E_SMT_FLAT_WALL_ATT_EDGE, &pro_e_smt_flat_wall_att_edge ); status = ProElementReferenceSet( pro_e_smt_flat_wall_att_edge, edge_ref ); status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_smt_flat_wall_att_edge ); /*-----------------------------------------------------------------*\ Processing Element PRO_E_SMT_FLAT_WALL_ANGLE \*-----------------------------------------------------------------*/ status = ProElementAlloc ( PRO_E_SMT_FLAT_WALL_ANGLE, &pro_e_smt_flat_wall_angle ); status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_smt_flat_wall_angle ); /*-----------------------------------------------------------------*\ Processing Element PRO_E_SMT_FLAT_WALL_ANGLE_TYPE \*-----------------------------------------------------------------*/ status = ProElementAlloc ( PRO_E_SMT_FLAT_WALL_ANGLE_TYPE, &pro_e_smt_flat_wall_angle_type ); status = ProElementIntegerSet ( pro_e_smt_flat_wall_angle_type, PRO_BND_ANGLE_VALUE); status = ProElemtreeElementAdd ( pro_e_smt_flat_wall_angle, NULL, pro_e_smt_flat_wall_angle_type ); /*-----------------------------------------------------------------*\ Processing Element PRO_E_SMT_FLAT_WALL_ANGLE_VAL \*-----------------------------------------------------------------*/ status = ProElementAlloc ( PRO_E_SMT_FLAT_WALL_ANGLE_VAL, &pro_e_smt_flat_wall_angle_val ); status = ProElementDoubleSet ( pro_e_smt_flat_wall_angle_val, 90.000000 ); status = ProElemtreeElementAdd ( pro_e_smt_flat_wall_angle, NULL, pro_e_smt_flat_wall_angle_val ); /*-----------------------------------------------------------------*\ Processing Element PRO_E_SMT_FLAT_WALL_ANGLE_FLIP \*-----------------------------------------------------------------*/ status = ProElementAlloc ( PRO_E_SMT_FLAT_WALL_ANGLE_FLIP, &pro_e_smt_flat_wall_angle_flip ); status = ProElementIntegerSet ( pro_e_smt_flat_wall_angle_flip, PRO_B_FALSE); status = ProElemtreeElementAdd ( pro_e_smt_flat_wall_angle, NULL, pro_e_smt_flat_wall_angle_flip ); /*-----------------------------------------------------------------*\ Processing Element PRO_E_STD_SECTION \*-----------------------------------------------------------------*/ status = ProElementAlloc ( PRO_E_STD_SECTION, &pro_e_std_section ); status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_std_section ); /*-----------------------------------------------------------------*\ Processing Element PRO_E_SKETCHER \*-----------------------------------------------------------------*/ status = ProElementAlloc ( PRO_E_SKETCHER, &pro_e_sketcher ); status = ProElementSpecialvalueSet ( pro_e_sketcher, section ); status = ProElemtreeElementAdd ( pro_e_std_section, NULL, pro_e_sketcher ); /*-----------------------------------------------------------------*\ Processing Element PRO_E_SMT_FILLETS \*-----------------------------------------------------------------*/ status = ProElementAlloc ( PRO_E_SMT_FILLETS, &pro_e_smt_fillets ); status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_smt_fillets ); /*-----------------------------------------------------------------*\ Processing Element PRO_E_SMT_FILLETS_USE_RAD \*-----------------------------------------------------------------*/ status = ProElementAlloc ( PRO_E_SMT_FILLETS_USE_RAD, &pro_e_smt_fillets_use_rad ); status = ProElementIntegerSet ( pro_e_smt_fillets_use_rad, PRO_B_TRUE); status = ProElemtreeElementAdd ( pro_e_smt_fillets, NULL, pro_e_smt_fillets_use_rad ); /*-----------------------------------------------------------------*\ Processing Element PRO_E_SMT_FILLETS_SIDE \*-----------------------------------------------------------------*/ status = ProElementAlloc ( PRO_E_SMT_FILLETS_SIDE, &pro_e_smt_fillets_side ); status = ProElementIntegerSet ( pro_e_smt_fillets_side, PRO_BEND_RAD_INSIDE ); status = ProElemtreeElementAdd ( pro_e_smt_fillets, NULL, pro_e_smt_fillets_side ); /*-----------------------------------------------------------------*\ Processing Element PRO_E_SMT_FILLETS_VALUE \*-----------------------------------------------------------------*/ status = ProElementAlloc ( PRO_E_SMT_FILLETS_VALUE, &pro_e_smt_fillets_value ); status = ProElementDoubleSet ( pro_e_smt_fillets_value, bend_radius ); status = ProElemtreeElementAdd ( pro_e_smt_fillets, NULL, pro_e_smt_fillets_value ); /*-----------------------------------------------------------------*\ Processing Element PRO_E_SMT_WALL_HEIGHT \*-----------------------------------------------------------------*/ status = ProElementAlloc ( PRO_E_SMT_WALL_HEIGHT, &pro_e_smt_wall_height ); status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_smt_wall_height ); /*-----------------------------------------------------------------*\ Processing Element PRO_E_SMT_WALL_HEIGHT_TYPE \*-----------------------------------------------------------------*/ status = ProElementAlloc ( PRO_E_SMT_WALL_HEIGHT_TYPE, &pro_e_smt_wall_height_type ); status = ProElementIntegerSet ( pro_e_smt_wall_height_type, PRO_SMT_WALL_HEIGHT_NONE ); status = ProElemtreeElementAdd ( pro_e_smt_wall_height, NULL, pro_e_smt_wall_height_type ); /*-----------------------------------------------------------------*\ Processing Element PRO_E_SMT_BEND_RELIEF \*-----------------------------------------------------------------*/ status = ProElementAlloc ( PRO_E_SMT_BEND_RELIEF, &pro_e_smt_bend_relief ); status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_smt_bend_relief ); /*-----------------------------------------------------------------*\ Processing Element PRO_E_SMT_BEND_RELIEF_SIDE1 \*-----------------------------------------------------------------*/ status = ProElementAlloc ( PRO_E_SMT_BEND_RELIEF_SIDE1, &pro_e_smt_bend_relief_side1 ); status = ProElemtreeElementAdd ( pro_e_smt_bend_relief, NULL, pro_e_smt_bend_relief_side1 ); /*-----------------------------------------------------------------*\ Processing Element PRO_E_BEND_RELIEF_TYPE \*-----------------------------------------------------------------*/ status = ProElementAlloc ( PRO_E_BEND_RELIEF_TYPE, &pro_e_bend_relief_type ); status = ProElementIntegerSet ( pro_e_bend_relief_type, PRO_BEND_RLF_RIP ); status = ProElemtreeElementAdd ( pro_e_smt_bend_relief_side1, NULL, pro_e_bend_relief_type ); /*-----------------------------------------------------------------*\ Processing Element PRO_E_SMT_BEND_RELIEF_SIDE2 \*-----------------------------------------------------------------*/ status = ProElementAlloc ( PRO_E_SMT_BEND_RELIEF_SIDE2, &pro_e_smt_bend_relief_side2 ); status = ProElemtreeElementAdd ( pro_e_smt_bend_relief, NULL, pro_e_smt_bend_relief_side2 ); /*-----------------------------------------------------------------*\ Processing Element PRO_E_BEND_RELIEF_TYPE \*-----------------------------------------------------------------*/ status = ProElementAlloc ( PRO_E_BEND_RELIEF_TYPE, &pro_e_bend_relief_type ); status = ProElementIntegerSet ( pro_e_bend_relief_type, PRO_BEND_RLF_RIP ); status = ProElemtreeElementAdd ( pro_e_smt_bend_relief_side2, NULL, pro_e_bend_relief_type ); /*-----------------------------------------------------------------*\ Processing Element PRO_E_SMT_WALL_THICKNESS_FLIP \*-----------------------------------------------------------------*/ status = ProElementAlloc ( PRO_E_SMT_WALL_THICKNESS_FLIP, &pro_e_smt_wall_thickness_flip ); status = ProElementIntegerSet ( pro_e_smt_wall_thickness_flip, PRO_B_FALSE ); status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_smt_wall_thickness_flip ); /*-----------------------------------------------------------------*\ Processing Element PRO_E_SMT_DEV_LEN_CALCULATION \*-----------------------------------------------------------------*/ status = ProElementAlloc ( PRO_E_SMT_DEV_LEN_CALCULATION, &pro_e_smt_dev_len_calculation ); status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_smt_dev_len_calculation ); /*-----------------------------------------------------------------*\ Processing Element PRO_E_SMT_DEV_LEN_SOURCE \*-----------------------------------------------------------------*/ status = ProElementAlloc ( PRO_E_SMT_DEV_LEN_SOURCE, &pro_e_smt_dev_len_source ); status = ProElementIntegerSet ( pro_e_smt_dev_len_source, PRO_DVL_SRC_FEAT_YF_ONLY ); status = ProElemtreeElementAdd ( pro_e_smt_dev_len_calculation, NULL, pro_e_smt_dev_len_source ); /*-----------------------------------------------------------------*\ Processing Element PRO_E_SMT_DEV_LEN_Y_FACTOR \*-----------------------------------------------------------------*/ status = ProElementAlloc ( PRO_E_SMT_DEV_LEN_Y_FACTOR, &pro_e_smt_dev_len_y_factor ); status = ProElemtreeElementAdd ( pro_e_smt_dev_len_calculation, NULL, pro_e_smt_dev_len_y_factor ); /*-----------------------------------------------------------------*\ Processing Element PRO_E_SMT_DEV_LEN_Y_FACTOR_VALUE \*-----------------------------------------------------------------*/ status = ProElementAlloc ( PRO_E_SMT_DEV_LEN_Y_FACTOR_VALUE, &pro_e_smt_dev_len_y_factor_value ); status = ProElementDoubleSet ( pro_e_smt_dev_len_y_factor_value, 0.320000 ); status = ProElemtreeElementAdd ( pro_e_smt_dev_len_y_factor, NULL, pro_e_smt_dev_len_y_factor_value ); /*-----------------------------------------------------------------*\ Create the feature using the element tree \*-----------------------------------------------------------------*/ status = ProMdlCurrentGet (&model); status = ProMdlToModelitem( model, &model_item ); status = ProSelectionAlloc (NULL, &model_item, &model_sel); status = ProArrayAlloc(1,sizeof(ProFeatureCreateOptions), 1, (ProArray*)&opts); opts[0]= PRO_FEAT_CR_NO_OPTS; status = ProFeatureWithoptionsCreate (model_sel, pro_e_feature_tree, opts, PRO_REGEN_NO_FLAGS, &feature, &errors); status = ProArrayFree((ProArray*)&opts); if (status == PRO_TK_NO_ERROR) { ProSelectionAlloc (NULL, &feature, &feat_sel); ProSelbufferClear (); ProSelbufferSelectionAdd (feat_sel); ProSelectionFree (&feat_sel); } return (PRO_TK_NO_ERROR); } /*=====================================================================*\ FUNCTION: UserSmtFlatWallCreate_OA_CreateISec PURPOSE: Create sheetmetal flat wall features using Object/Action selection and Pro/E's predefined rectangular section. \*=====================================================================*/ int UserSmtFlatWallCreate_OA_CreateRectSec () { ProError status; ProSelection* sel; ProReference reference; ProPart part; ProDimension thickness_dim; double thickness; ProSection rect_wall_sec; ProPath w_mdlpath; ProCharPath mdlpath, secpath; char* prodir; /*-----------------------------------------------------------------*\ Extract the current selected edge or edge chain as the wall attachment \*-----------------------------------------------------------------*/ status = ProSelbufferSelectionsGet (&sel); status = ProSelectionToReference ( sel[0], &reference ); /*-----------------------------------------------------------------*\ Extract the wall thickness to use for the bend radius \*-----------------------------------------------------------------*/ status = ProMdlCurrentGet ((ProMdl*)&part); status = ProSmtPartThicknessGet(part, &thickness_dim); status = ProDimensionValueGet (&thickness_dim, &thickness); /*-----------------------------------------------------------------*\ Retrieve the Pro/ENGINEER default section for rectangular flat walls \*-----------------------------------------------------------------*/ prodir = getenv ("PRO_DIRECTORY"); if (prodir == NULL) return PRO_TK_INVALID_DIR; ProTKSprintf (secpath, "%s/text/smt/", prodir); ProTKSprintf (mdlpath, "%srect_flat_wall.sec", secpath); ProStringToWstring (w_mdlpath, mdlpath); status = ProMdlFiletypeLoad (w_mdlpath, PRO_MDLFILE_UNUSED, PRO_B_FALSE, (ProMdl*)&rect_wall_sec); /*-----------------------------------------------------------------*\ Create the feature with the extracted information \*-----------------------------------------------------------------*/ UserSmtFlatWallCreate (reference, thickness, rect_wall_sec); ProReferenceFree (reference); return (PRO_TK_NO_ERROR); } /*=====================================================================*\ FUNCTION: UserSectionOpen PURPOSE: Retrieve a section using a File Open dialog. \*=====================================================================*/ ProError UserSectionOpen (ProSection* sec) { ProError status; ProName label; ProLine filter; ProPath* shortcut_path_arr; ProName* shortcut_name; ProPath path; /*-----------------------------------------------------------------*\ Prompt to select a section using the Open dialog box \*-----------------------------------------------------------------*/ ProStringToWstring (label, "Select section"); ProStringToWstring (filter, "*.sec"); ProArrayAlloc (0, sizeof (ProPath), 1, (ProArray*) &shortcut_path_arr); ProArrayAlloc (0, sizeof (ProName), 1, (ProArray*) &shortcut_name); status = ProFileMdlnameOpen (label, filter, shortcut_path_arr, shortcut_name, NULL, NULL, path); if (status == PRO_TK_NO_ERROR) { /*-----------------------------------------------------------------*\ Retrieve the selected section \*-----------------------------------------------------------------*/ status = ProMdlFiletypeLoad (path, PRO_MDLFILE_UNUSED, PRO_B_FALSE, (ProMdl*)sec); } ProArrayFree ((ProArray*)&shortcut_path_arr); ProArrayFree ((ProArray*)&shortcut_name); return (status); } /*=====================================================================*\ FUNCTION: UserSmtFlatWallCreate_OA_CreateUserDefSec PURPOSE: Create sheetmetal flat wall features using Object/Action selection and a user-selected 2D section. \*=====================================================================*/ int UserSmtFlatWallCreate_OA_CreateUserDefSec () { ProError status; ProSelection* sel; ProReference reference; ProPart part; ProDimension thickness_dim; double thickness; ProSection userdef_sec; ProPath w_mdlpath; ProCharPath mdlpath, secpath; char* prodir; /*-----------------------------------------------------------------*\ Prompt the user to select a section for the flange wall \*-----------------------------------------------------------------*/ status = UserSectionOpen (&userdef_sec); if (status != PRO_TK_NO_ERROR) return (status); /*-----------------------------------------------------------------*\ Extract the current selected edge or edge chain as the wall attachment \*-----------------------------------------------------------------*/ status = ProSelbufferSelectionsGet (&sel); status = ProSelectionToReference ( sel[0], &reference ); /*-----------------------------------------------------------------*\ Extract the wall thickness to use for the bend radius \*-----------------------------------------------------------------*/ status = ProMdlCurrentGet ((ProMdl*)&part); status = ProSmtPartThicknessGet(part, &thickness_dim); status = ProDimensionValueGet (&thickness_dim, &thickness); /*-----------------------------------------------------------------*\ Create the feature with the extracted information \*-----------------------------------------------------------------*/ UserSmtFlatWallCreate (reference, thickness, userdef_sec); ProReferenceFree (reference); ProMdlErase (userdef_sec); return (PRO_TK_NO_ERROR); } /*=====================================================================*\ FUNCTION: UserEdgeIsSmtFaceEdge PURPOSE: Returns TRUE if the edge borders a sheetmetal face. \*=====================================================================*/ ProBoolean UserEdgeIsSmtFaceEdge (ProGeomitem* edge) { ProEdge edge_ptr; ProEdge edges [2]; ProSurface surfs [2]; ProSmtSurfType srf_type, srf_type2; /*-----------------------------------------------------------------*\ Obtain the neighboring surfaces for the given edge \*-----------------------------------------------------------------*/ ProGeomitemToEdge (edge, &edge_ptr); ProEdgeNeighborsGet (edge_ptr, &edges[0], &edges[1], &surfs [0], &surfs[1]); /*-----------------------------------------------------------------*\ Test the surfaces \*-----------------------------------------------------------------*/ ProSmtSurfaceTypeGet (edge->owner, surfs [0], &srf_type); ProSmtSurfaceTypeGet (edge->owner, surfs [1], &srf_type2); if (srf_type == PRO_SMT_SURF_FACE || srf_type2 == PRO_SMT_SURF_FACE || srf_type == PRO_SMT_SURF_OFFSET || srf_type2 == PRO_SMT_SURF_OFFSET) return PRO_B_TRUE; else return PRO_B_FALSE; } #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: UserSmtFlatWallCreate_TestLow PURPOSE: Access function for the button for smt flat wall feature creation \*=====================================================================*/ static uiCmdAccessState UserSmtFlatWallCreate_TestLow (ProSelection* sels, int mode) { uiCmdAccessState access_result; ProBoolean should_free = PRO_B_FALSE; ProError status; ProMdl mdl; ProMdlType type; ProMdlsubtype subtype; ProReference reference; ProModelitem item; ProEdge edge; ProEnttype ent_type; int size; /*-----------------------------------------------------------------*\ Set the default return if the button is unusable. \*-----------------------------------------------------------------*/ if (mode == OA) access_result = ACCESS_UNAVAILABLE; else access_result = ACCESS_REMOVE; status = ProMdlCurrentGet (&mdl); if (status != PRO_TK_NO_ERROR) return (access_result); status = ProMdlTypeGet (mdl, &type); status = ProMdlSubtypeGet (mdl, &subtype); if (type != PRO_MDL_PART || subtype != PROMDLSTYPE_PART_SHEETMETAL) return (access_result); /*-----------------------------------------------------------------*\ 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) { /*-----------------------------------------------------------------*\ Extract the reference edge selected by the user \*-----------------------------------------------------------------*/ status = ProSelectionToReference (sels [0], &reference); ProTKPrintf ("Status of ProSelectionCollectionGet: %d\n\n", status); if (status == PRO_TK_NO_ERROR) { /*-----------------------------------------------------------------*\ Check the reference to ensure that the reference is an edge which borders a sheetmetal face. \*-----------------------------------------------------------------*/ ProReferenceTypeGet (reference, &item.type); if (item.type == PRO_EDGE) { ProReferenceOwnerGet (reference, &item.owner); ProReferenceIdGet (reference, &item.id); ProReferenceFree (reference); if (UserEdgeIsSmtFaceEdge (&item)) { /*-----------------------------------------------------------------*\ Flat wall attachment edge must be straight \*-----------------------------------------------------------------*/ ProGeomitemToEdge (&item, &edge); ProEdgeTypeGet (edge, &ent_type); if (ent_type == PRO_ENT_LINE) { /*-----------------------------------------------------------------*\ If reference is OK, the button should be active. \*-----------------------------------------------------------------*/ access_result = ACCESS_AVAILABLE; } } } } } if (should_free) ProSelectionarrayFree (sels); return access_result; } /*=====================================================================*\ FUNCTION: UserSmtFlatWallCreate_TestMdlTree PURPOSE: Access function for the model tree popup menu button. \*=====================================================================*/ uiCmdAccessState UserSmtFlatWallCreate_TestMdlTree (uiCmdAccessMode mode) { return UserSmtFlatWallCreate_TestLow (NULL, PM); } /*=====================================================================*\ FUNCTION: UserSmtFlatWallCreate_TestPM PURPOSE: Access function for the graphics window popup menu button. \*=====================================================================*/ uiCmdAccessState UserSmtFlatWallCreate_TestPM (uiCmdCmdId id, ProAppData data, ProSelection* sels) { return UserSmtFlatWallCreate_TestLow (sels, PM); }