/*
	Copyright (c) 2024 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved.
*/



/*---------------------- Pro/Toolkit Includes ------------------------*/
#include "ProToolkit.h"
#include "ProMdl.h"
#include "ProCollect.h"
#include "ProElement.h"
#include "ProElempath.h"
#include "ProSelection.h"
#include "ProFeature.h"
#include "ProArray.h"
#include "ProD3Elem.h"
#include "ProModelitem.h"
#include "ProFlexMove.h"
#include "ProSolid.h"
#include "ProCrvcollection.h"
#include "ProMessage.h"
#include "ProFeatType.h"
#include "ProSrfcollection.h"


static ProFileName message_file; 
 

#define C_LOG(a) ProTKPrintf ("Status for %s is = %d\n", a, status ); \
	ERROR_CHECK( a, "UgFlexModelCreate.c", status );

#define C_PRINT(a) ProTKPrintf ( "%s\n", a);

/*---------------------- Function Prototypes -------------------------*/
int MakeFeature(ProMdl,ProElement);
ProError UserFlexModelCreateonSurface();
ProError UserFlexModelCreateonEdge();
ProError UserFlexModelCreateFree();

/*------------------------- Global Data -----------------------------*/

/*===============================================================*\
FUNCTION : ProDemoSketchedCurveCreate
PURPOSE  : Demonstrates the creation of the extruded protrusion
           base feature.
\*===============================================================*/


ProError UserFlexModelCreateonSurface ()
{
	ProMdl mdl;
	ProSelection* sel_surface;
	ProElement elem_tree; 
	ProElement elem_d3,elem_d3_sets,elem_place,elem_moves,elem_move,elem_move_type,elem_move_value;
	ProElempath path;
	ProElempathItem items2[4];
	
	ProReference ref_surface;
	
	ProUvParam uv_params_set={0.0,0.0};
	
	ProFeature feature;
	
	ProFeatureCreateOptions* arr;
	ProFeatureCreateOptions opt = PRO_FEAT_CR_DEFINE_MISS_ELEMS ;
	
	ProErrorlist errors;
	ProModelitem mdl_item;
	ProSelection feat_sel;
	
	double x,y;
	int no;
	
	ProStringToWstring ( message_file, "utilities.txt" );
	
	status = ProMdlCurrentGet(&mdl);
	C_LOG( " ProMdlCurrentGet " );
	
	status = ProElementAlloc(PRO_E_FEATURE_TREE,&elem_tree);
	C_LOG( " ProElementAlloc " );
	
	status = MakeFeature(mdl,elem_tree);
	
	status = ProMessageDisplay (message_file, "USER Select a surface as placement reference for handle");
    C_LOG( " ProMessageDisplay " );
	
	status = ProSelect("surface",1,NULL,NULL,NULL,NULL,&sel_surface,&no);
	C_LOG( " ProSelect " );
	
	if (status != PRO_TK_NO_ERROR)
	{
		status = ProMessageDisplay (message_file, "USER Wrong Selection");
		return status;
	}
	
	status = ProElementAlloc(PRO_E_D3ELEM_SETS,&elem_d3);
	C_LOG( " ProElementAlloc " );
	
	status = ProElementAlloc(PRO_E_D3ELEM_SET,&elem_d3_sets);
	C_LOG( " ProElementAlloc " );
	
	status = ProElemtreeElementAdd(elem_d3,NULL,elem_d3_sets);
	C_LOG( " ProElemtreeElementAdd " );
		
	status = ProElementAlloc(PRO_E_D3ELEM_PLACEMENT_REFERENCE,&elem_place);
	C_LOG( " ProElementAlloc " );
	status = ProSelectionToReference(sel_surface[0],&ref_surface);
	C_LOG( " ProSelectionToReference " );
	status = ProElementReferenceSet(elem_place,ref_surface);
	C_LOG( " ProElementReferenceSet " );
	
	status = ProElempathAlloc(&path);
	C_LOG( " ProElempathAlloc " );
	
	items2[0].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[0].path_item.elem_id = PRO_E_D3ELEM_SET;
	items2[1].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[1].path_item.elem_id = PRO_E_D3ELEM_PLACEMENT_REFERENCE;
	
	status = ProElempathDataSet(path,items2,2);
	C_LOG( " ProElempathDataSet " );
	
	status = ProElemtreeElementAdd(elem_d3,path,elem_place);
	C_LOG( " ProElemtreeElementAdd " );
	
	status = ProElempathFree(&path);
	C_LOG( " ProElempathFree " );
	
	status = ProElementAlloc(PRO_E_D3ELEM_MOVES,&elem_moves);
	C_LOG( " ProElementAlloc " );
	
	status = ProElempathAlloc(&path);
	C_LOG( " ProElempathAlloc " );
	
	items2[0].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[0].path_item.elem_id = PRO_E_D3ELEM_SET;
	items2[1].type = PRO_ELEM_PATH_ITEM_TYPE_INDEX;
	items2[1].path_item.elem_index = 0;
	
	status = ProElempathDataSet(path,items2,2);
	C_LOG( " ProElempathDataSet " );
	status = ProElemtreeElementAdd(elem_d3,path,elem_moves);
	C_LOG( " ProElemtreeElementAdd " );
	
	status = ProElempathFree(&path);
	C_LOG( " ProElempathFree " );
	
	status = ProElementAlloc(PRO_E_D3ELEM_MOVE,&elem_move);
	C_LOG( " ProElementAlloc " );
	
	status = ProElempathAlloc(&path);
	C_LOG( " ProElempathAlloc " );
	
	items2[0].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[0].path_item.elem_id = PRO_E_D3ELEM_SET;
	items2[1].type = PRO_ELEM_PATH_ITEM_TYPE_INDEX;
	items2[1].path_item.elem_index = 0;
	items2[2].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[2].path_item.elem_id = PRO_E_D3ELEM_MOVE;
	
	status = ProElempathDataSet(path,items2,3);
	C_LOG( " ProElempathDataSet " );
	status = ProElemtreeElementAdd(elem_d3,path,elem_move);
	C_LOG( " ProElempathDataSet " );
	
	status = ProElempathFree(&path);
	C_LOG("ProElempathFree");
	
	status = ProElementAlloc(PRO_E_D3ELEM_MOVE_TYPE,&elem_move_type);
	C_LOG("ProElementAlloc");
	
	status = ProElementIntegerSet(elem_move_type,PRO_D3_MOVE_TYPE_SURF);
	C_LOG("ProElementIntegerSet");
	
	status = ProElempathAlloc(&path);
	C_LOG("ProElempathAlloc");
	
	items2[0].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[0].path_item.elem_id = PRO_E_D3ELEM_SET;
	items2[1].type = PRO_ELEM_PATH_ITEM_TYPE_INDEX;
	items2[1].path_item.elem_index = 0;
	items2[2].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[2].path_item.elem_id = PRO_E_D3ELEM_MOVE;
	items2[3].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[3].path_item.elem_id = PRO_E_D3ELEM_MOVE_TYPE;
	
	status = ProElempathDataSet(path,items2,4);
	C_LOG("ProElempathDataSet");
	
	status = ProElemtreeElementAdd(elem_d3,path,elem_move_type);
	C_LOG("ProElemtreeElementAdd");
	
	status = ProElempathFree(&path);
	C_LOG("ProElempathFree");
	
	status = ProElementAlloc(PRO_E_D3ELEM_MOVE_VALUE,&elem_move_value);
	C_LOG("ProElementAlloc");
	
	status = ProMessageDisplay (message_file, "USER Enter the x co-ordinate of the point where the handle is to be placed");
	C_LOG("ProMessageDisplay");
	status = ProMessageDoubleRead(NULL, &x);
	C_LOG("ProMessageDoubleRead");
	
	status = ProMessageDisplay (message_file, "USER Enter the y co-ordinate of the point where the handle is to be placed");
	C_LOG("ProMessageDisplay");
	status = ProMessageDoubleRead(NULL, &y);
	C_LOG("ProMessageDoubleRead")
	
	uv_params_set[0]=x;
    uv_params_set[1]=y;
	
	status = ProFeatureD3elemUvSet(elem_move_value,uv_params_set);
	C_LOG("ProFeatureD3elemUvSet");
	
	status = ProElempathAlloc(&path);
	C_LOG("ProElempathAlloc");
	
    items2[0].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[0].path_item.elem_id = PRO_E_D3ELEM_SET;
	items2[1].type = PRO_ELEM_PATH_ITEM_TYPE_INDEX;
	items2[1].path_item.elem_index = 0;
	items2[2].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[2].path_item.elem_id = PRO_E_D3ELEM_MOVE;
	items2[3].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[3].path_item.elem_id = PRO_E_D3ELEM_MOVE_VALUE;
	
	status = ProElempathDataSet(path,items2,4);
	C_LOG("ProElempathDataSet");
	
	status = ProElemtreeElementAdd(elem_d3,path,elem_move_value);
	C_LOG("ProElemtreeElementAdd");
	
	status = ProElempathFree(&path);
	C_LOG("ProElempathFree");
	
	status = ProElemtreeElementAdd(elem_tree,NULL,elem_d3);
	C_LOG("ProElemtreeElementAdd");
	
	/* Creating the feature */
	
	status = ProArrayAlloc(0,sizeof(ProFeatureCreateOptions),1,(ProArray *)&arr);
	C_LOG("ProArrayAlloc");
	status = ProArrayObjectAdd((ProArray *)&arr,PRO_VALUE_UNUSED,1,&opt);
	C_LOG("ProArrayObjectAdd");
	
	status = ProMdlToModelitem(mdl,&mdl_item);
	C_LOG("ProMdlToModelitem");
	
	status = ProSelectionAlloc(NULL,&mdl_item,&feat_sel);
	C_LOG("ProSelectionAlloc");
	
	status = ProFeatureWithoptionsCreate(feat_sel,elem_tree,arr,PRO_REGEN_NO_FLAGS,&feature,&errors);
    C_LOG("ProFeatureWithoptionsCreate");
	
	
	if (status != PRO_TK_NO_ERROR)
		{
			status = ProMessageDisplay (message_file, "USER Failed");
		}
		
	/* Free APIs */
	
	
	ProElementFree(&elem_tree);
	ProSelectionFree(&feat_sel);
	ProArrayFree((ProArray *)&arr);
	
	return PRO_TK_NO_ERROR;

}

ProError UserFlexModelCreateonEdge ()
{
	ProMdl mdl;
	ProSelection* sel_edge;
	ProElement elem_tree,elem_d3,elem_d3_sets,elem_place,elem_moves,elem_move,elem_move_type,elem_move_value;
	ProElempath path;
	ProElempathItem items2[4];
	
	ProReference ref_edge;
	
	double ratio;
	
	ProFeatureCreateOptions* arr;
	ProFeatureCreateOptions opt = PRO_FEAT_CR_DEFINE_MISS_ELEMS ;
	
	ProModelitem mdl_item;
	ProSelection feat_sel;
	ProFeature feature;
	ProErrorlist errors;
	
    int no;
	
	ProStringToWstring ( message_file, "utilities.txt" );
	
	status = ProMdlCurrentGet(&mdl);
	C_LOG("ProMdlCurrentGet");

	status = ProElementAlloc(PRO_E_FEATURE_TREE,&elem_tree);
	C_LOG("ProElementAlloc");
	
	status = MakeFeature(mdl,elem_tree);
	
	status = ProMessageDisplay (message_file, "USER Select an edge as placement reference for handle");
    C_LOG("ProMessageDisplay");
	
	status = ProSelect("edge",1,NULL,NULL,NULL,NULL,&sel_edge,&no);
	C_LOG("ProElementAlloc");
	
	if (status != PRO_TK_NO_ERROR)
	{
		status = ProMessageDisplay (message_file, "USER Invalid Selection");
		return status;
	}
	
	
	/* Assigning elements to PRO_E_D3ELEM_SETS*/
	
	status = ProElementAlloc(PRO_E_D3ELEM_SETS,&elem_d3);
	C_LOG("ProElementAlloc");
	
	status = ProElementAlloc(PRO_E_D3ELEM_SET,&elem_d3_sets);
	C_LOG("ProElementAlloc");
	
    status = ProElemtreeElementAdd(elem_d3,NULL,elem_d3_sets);
	C_LOG("ProElemtreeElementAdd");
	
	status = ProElementAlloc(PRO_E_D3ELEM_PLACEMENT_REFERENCE,&elem_place);
	C_LOG("ProElementAlloc");
	status = ProSelectionToReference(sel_edge[0],&ref_edge);
	C_LOG("ProSelectionToReference");
	status = ProElementReferenceSet(elem_place,ref_edge);
	C_LOG("ProElementReferenceSet");
	
	status = ProElempathAlloc(&path);
	C_LOG("ProElempathAlloc");
	
	items2[0].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[0].path_item.elem_id = PRO_E_D3ELEM_SET;
	items2[1].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[1].path_item.elem_id = PRO_E_D3ELEM_PLACEMENT_REFERENCE;
	
	status = ProElempathDataSet(path,items2,2);
	C_LOG("ProElempathDataSet");
	
	status = ProElemtreeElementAdd(elem_d3,path,elem_place);
	C_LOG("ProElemtreeElementAdd");
	
	status = ProElempathFree(&path);
	C_LOG("ProElempathFree");
	
	status = ProElementAlloc(PRO_E_D3ELEM_MOVES,&elem_moves);
	C_LOG("ProElementAlloc");
	
	status = ProElempathAlloc(&path);
	C_LOG("ProElempathAlloc");
	
	items2[0].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[0].path_item.elem_id = PRO_E_D3ELEM_SET;
	items2[1].type = PRO_ELEM_PATH_ITEM_TYPE_INDEX;
	items2[1].path_item.elem_index = 0;
	
	status = ProElempathDataSet(path,items2,2);
	C_LOG("ProElempathDataSet");
	status = ProElemtreeElementAdd(elem_d3,path,elem_moves);
	C_LOG("ProElemtreeElementAdd");
	
	status = ProElempathFree(&path);
	C_LOG("ProElempathFree");
	
	status = ProElementAlloc(PRO_E_D3ELEM_MOVE,&elem_move);
	C_LOG("ProElementAlloc");
	
	status = ProElempathAlloc(&path);
	C_LOG("ProElempathAlloc");
	
	items2[0].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[0].path_item.elem_id = PRO_E_D3ELEM_SET;
	items2[1].type = PRO_ELEM_PATH_ITEM_TYPE_INDEX;
	items2[1].path_item.elem_index = 0;
	items2[2].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[2].path_item.elem_id = PRO_E_D3ELEM_MOVE;
	
	status = ProElempathDataSet(path,items2,3);
	C_LOG("ProElempathDataSet");
	status = ProElemtreeElementAdd(elem_d3,path,elem_move);
	C_LOG("ProElemtreeElementAdd");
	
	status = ProElempathFree(&path);
	C_LOG("ProElempathFree");
	
	status = ProElementAlloc(PRO_E_D3ELEM_MOVE_TYPE,&elem_move_type);
	C_LOG("ProElementAlloc");
	
	status = ProElementIntegerSet(elem_move_type,PRO_D3_MOVE_TYPE_EDGE );
	C_LOG("ProElementIntegerSet");
	
	status = ProElempathAlloc(&path);
	C_LOG("ProElempathAlloc");
	
	items2[0].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[0].path_item.elem_id = PRO_E_D3ELEM_SET;
	items2[1].type = PRO_ELEM_PATH_ITEM_TYPE_INDEX;
	items2[1].path_item.elem_index = 0;
	items2[2].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[2].path_item.elem_id = PRO_E_D3ELEM_MOVE;
	items2[3].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[3].path_item.elem_id = PRO_E_D3ELEM_MOVE_TYPE;
	
	status = ProElempathDataSet(path,items2,4);
	C_LOG("ProElempathDataSet");
	
	status = ProElemtreeElementAdd(elem_d3,path,elem_move_type);
	C_LOG("ProElemtreeElementAdd");
	
	status = ProElempathFree(&path);
	C_LOG("ProElempathFree");
	
	status = ProElementAlloc(PRO_E_D3ELEM_MOVE_VALUE,&elem_move_value);
	C_LOG("ProElementAlloc");
	
	status = ProMessageDisplay (message_file, "USER Enter the edge ratio for placing the handle (between 0 and 1)");
	C_LOG("ProMessageDisplay");
	status = ProMessageDoubleRead(NULL, &ratio);
	C_LOG("ProMessageDoubleRead")
	
	status = ProFeatureD3elemRatioSet(elem_move_value,ratio);
	C_LOG("ProFeatureD3elemRatioSet");
	
	status = ProElempathAlloc(&path);
	C_LOG("ProElempathAlloc");
	
    items2[0].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[0].path_item.elem_id = PRO_E_D3ELEM_SET;
	items2[1].type = PRO_ELEM_PATH_ITEM_TYPE_INDEX;
	items2[1].path_item.elem_index = 0;
	items2[2].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[2].path_item.elem_id = PRO_E_D3ELEM_MOVE;
	items2[3].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[3].path_item.elem_id = PRO_E_D3ELEM_MOVE_VALUE;
	
	status = ProElempathDataSet(path,items2,4);
	C_LOG("ProElempathDataSet");
	
	status = ProElemtreeElementAdd(elem_d3,path,elem_move_value);
	C_LOG("ProElemtreeElementAdd");
	
	status = ProElempathFree(&path);
	C_LOG("ProElempathFree");
	
	status = ProElemtreeElementAdd(elem_tree,NULL,elem_d3);
	C_LOG("ProElemtreeElementAdd");
	
	/* Creating the feature */
	
	status = ProArrayAlloc(0,sizeof(ProFeatureCreateOptions),1,(ProArray *)&arr);
	C_LOG("ProArrayAlloc");
	status = ProArrayObjectAdd((ProArray *)&arr,PRO_VALUE_UNUSED,1,&opt);
	C_LOG("ProArrayObjectAdd");
	
	status = ProMdlToModelitem(mdl,&mdl_item);
	C_LOG("ProMdlToModelitem");
	
	status = ProSelectionAlloc(NULL,&mdl_item,&feat_sel);
	C_LOG("ProSelectionAlloc");
	
	status = ProFeatureWithoptionsCreate(feat_sel,elem_tree,arr,PRO_REGEN_NO_FLAGS,&feature,&errors);
	C_LOG("ProFeatureWithoptionsCreate");
	
	if (status != PRO_TK_NO_ERROR)
		{
			status = ProMessageDisplay (message_file, "USER Failed");
		}
		
	/* Free APIs */
	
	ProElementFree(&elem_tree);
	ProSelectionFree(&feat_sel);
	ProArrayFree((ProArray *)&arr);
	
	return PRO_TK_NO_ERROR;

}

ProError UserFlexModelCreateFree ()
{
	ProMdl mdl;
	ProElement elem_tree,elem_d3,elem_d3_sets,elem_place,elem_moves,elem_move,elem_move_type,elem_move_value;
	ProElempath path;
	ProElempathItem items2[4];
	
    ProMatrix transf_mat_set;
	
	ProFeatureCreateOptions* arr;
	ProFeatureCreateOptions opt = PRO_FEAT_CR_DEFINE_MISS_ELEMS ;
	
	ProModelitem mdl_item;
	ProSelection feat_sel;
	ProFeature feature;
	ProErrorlist errors;
	
	int no;
	
	ProStringToWstring ( message_file, "utilities.txt" );

	status = ProMdlCurrentGet(&mdl);
	C_LOG("ProMdlCurrentGet");
	
	status = ProElementAlloc(PRO_E_FEATURE_TREE,&elem_tree);
	C_LOG("ProElementAlloc");
	
	status = MakeFeature(mdl,elem_tree);
	
	/* Assigning elements to PRO_E_D3ELEM_SETS*/
	
	status = ProElementAlloc(PRO_E_D3ELEM_SETS,&elem_d3);
	C_LOG("ProElementAlloc");
	
	status = ProElementAlloc(PRO_E_D3ELEM_SET,&elem_d3_sets);
	C_LOG("ProElementAlloc");
	
    status = ProElemtreeElementAdd(elem_d3,NULL,elem_d3_sets);
	C_LOG("ProElemtreeElementAdd");
	
	status = ProElementAlloc(PRO_E_D3ELEM_PLACEMENT_REFERENCE,&elem_place);
	C_LOG("ProElementAlloc");
	
	status = ProElempathAlloc(&path);
	C_LOG("ProElempathAlloc");
	
	items2[0].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[0].path_item.elem_id = PRO_E_D3ELEM_SET;
	items2[1].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[1].path_item.elem_id = PRO_E_D3ELEM_PLACEMENT_REFERENCE;
	
	status = ProElempathDataSet(path,items2,2);
	C_LOG("ProElempathDataSet");
	
	status = ProElemtreeElementAdd(elem_d3,path,elem_place);
	C_LOG("ProElemtreeElementAdd");
	
	status = ProElempathFree(&path);
	C_LOG("ProElempathFree");
	
	status = ProElementAlloc(PRO_E_D3ELEM_MOVES,&elem_moves);
	C_LOG("ProElementAlloc");
	
	status = ProElempathAlloc(&path);
	C_LOG("ProElempathAlloc");
	
	items2[0].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[0].path_item.elem_id = PRO_E_D3ELEM_SET;
	items2[1].type = PRO_ELEM_PATH_ITEM_TYPE_INDEX;
	items2[1].path_item.elem_index = 0;
	
	status = ProElempathDataSet(path,items2,2);
	C_LOG("ProElempathDataSet");
	status = ProElemtreeElementAdd(elem_d3,path,elem_moves);
	C_LOG("ProElemtreeElementAdd");
	
	status = ProElempathFree(&path);
	C_LOG("ProElempathFree");
	
	status = ProElementAlloc(PRO_E_D3ELEM_MOVE,&elem_move);
	C_LOG("ProElementAlloc");
	
	status = ProElempathAlloc(&path);
	C_LOG("ProElempathAlloc");
	
	items2[0].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[0].path_item.elem_id = PRO_E_D3ELEM_SET;
	items2[1].type = PRO_ELEM_PATH_ITEM_TYPE_INDEX;
	items2[1].path_item.elem_index = 0;
	items2[2].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[2].path_item.elem_id = PRO_E_D3ELEM_MOVE;
	
	status = ProElempathDataSet(path,items2,3);
	C_LOG("ProElempathDataSet");
	status = ProElemtreeElementAdd(elem_d3,path,elem_move);
	C_LOG("ProElemtreeElementAdd");
	
	status = ProElempathFree(&path);
	C_LOG("ProElempathFree");
	
	status = ProElementAlloc(PRO_E_D3ELEM_MOVE_TYPE,&elem_move_type);
	C_LOG("ProElementAlloc");
	
	status = ProElementIntegerSet(elem_move_type,PRO_D3_MOVE_TYPE_FREE );
	C_LOG("ProElementIntegerSet");
	
	status = ProElempathAlloc(&path);
	C_LOG("ProElempathAlloc");
	
	items2[0].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[0].path_item.elem_id = PRO_E_D3ELEM_SET;
	items2[1].type = PRO_ELEM_PATH_ITEM_TYPE_INDEX;
	items2[1].path_item.elem_index = 0;
	items2[2].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[2].path_item.elem_id = PRO_E_D3ELEM_MOVE;
	items2[3].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[3].path_item.elem_id = PRO_E_D3ELEM_MOVE_TYPE;
	
	status = ProElempathDataSet(path,items2,4);
	C_LOG("ProElempathDataSet");
	
	status = ProElemtreeElementAdd(elem_d3,path,elem_move_type);
	C_LOG("ProElemtreeElementAdd");
	
	status = ProElempathFree(&path);
	C_LOG("ProElempathFree");
	
	status = ProElementAlloc(PRO_E_D3ELEM_MOVE_VALUE,&elem_move_value);
	C_LOG("ProElementAlloc");
	
	transf_mat_set[0][0] = 0.068194;
    transf_mat_set[0][1] = 0.255567;
    transf_mat_set[0][2] = 0.964383;
    transf_mat_set[0][3] = 0.0;
     
    transf_mat_set[1][0] = 0.633677;
    transf_mat_set[1][1] = 0.735517;
    transf_mat_set[1][2] = -0.239725;
    transf_mat_set[1][3] = 0.0;
     
    transf_mat_set[2][0] = -0.770586;
    transf_mat_set[2][1] = 0.627456;
    transf_mat_set[2][2] = -0.111789;
    transf_mat_set[2][3] = 0.0;
     
    transf_mat_set[3][0] = 113.834758;
    transf_mat_set[3][1] = 206.272839;
    transf_mat_set[3][2] = -62.707134;
    transf_mat_set[3][3] = 1.0;
	
	status = ProFeatureD3elemMatrixSet(elem_move_value,transf_mat_set);
	C_LOG("ProFeatureD3elemMatrixSet");
	
	status = ProElempathAlloc(&path);
	C_LOG("ProElempathAlloc");
	
    items2[0].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[0].path_item.elem_id = PRO_E_D3ELEM_SET;
	items2[1].type = PRO_ELEM_PATH_ITEM_TYPE_INDEX;
	items2[1].path_item.elem_index = 0;
	items2[2].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[2].path_item.elem_id = PRO_E_D3ELEM_MOVE;
	items2[3].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	items2[3].path_item.elem_id = PRO_E_D3ELEM_MOVE_VALUE;
	
	status = ProElempathDataSet(path,items2,4);
	C_LOG("ProElempathDataSet");
	
	status = ProElemtreeElementAdd(elem_d3,path,elem_move_value);
	C_LOG("ProElemtreeElementAdd");
	
	status = ProElempathFree(&path);
	C_LOG("ProElempathFree");
	
	status = ProElemtreeElementAdd(elem_tree,NULL,elem_d3);
	C_LOG("ProElemtreeElementAdd");
	
	/* Creating the feature */
	
	status = ProArrayAlloc(0,sizeof(ProFeatureCreateOptions),1,(ProArray *)&arr);
	C_LOG("ProArrayAlloc");
	status = ProArrayObjectAdd((ProArray *)&arr,PRO_VALUE_UNUSED,1,&opt);
	C_LOG("ProArrayObjectAdd");
	
	status = ProMdlToModelitem(mdl,&mdl_item);
	C_LOG("ProMdlToModelitem");
	
	status = ProSelectionAlloc(NULL,&mdl_item,&feat_sel);
	C_LOG("ProSelectionAlloc");
	
	status = ProFeatureWithoptionsCreate(feat_sel,elem_tree,arr,PRO_REGEN_NO_FLAGS,&feature,&errors);
	C_LOG("ProFeatureWithoptionsCreate");
	
	if (status != PRO_TK_NO_ERROR)
		{
			status = ProMessageDisplay (message_file, "USER Failed");
		}
		
	/* Free APIs */
	
	ProElementFree(&elem_tree);
	ProSelectionFree(&feat_sel);
	ProArrayFree((ProArray *)&arr);
	
	return PRO_TK_NO_ERROR;

}

int MakeFeature (ProMdl model,ProElement elem)
{
  
  ProSelection* sels;
  ProElement elem_type,elem_feat_name,elem_mov_geom,elem_sel,elem_method;
  ProElempath path;
  ProElempathItem items1[2];
  
  ProName w_string;
	
  ProCollection coll;
  int n_sels,no;
  
  ProCollectioninstrType types[] = {PRO_SURFCOLL_SINGLE_SURF,PRO_SURFCOLL_GEOM_RULE,PRO_SURFCOLL_SHAPE_BASED};
  
  ProStringToWstring ( message_file, "utilities.txt" );
  
  status = ProSrfcollectionAlloc(&coll);
  C_LOG("ProSrfcollectionAlloc");
	
  status = ProMessageDisplay (message_file, "USER Select surfaces for flexible modelling");
  C_LOG("ProMessageDisplay");
	
  status = ProSurfacesCollect(types,3,NULL,NULL,coll,&sels,&n_sels);
  C_LOG("ProSurfacesCollect");
  
 if (status != PRO_TK_NO_ERROR)
	{
		status = ProMessageDisplay (message_file, "USER Invalid Selection");
		return status;
	}
  
  status = ProElementAlloc(PRO_E_FEATURE_TYPE,&elem_type);
  C_LOG("ProElementAlloc");
  status = ProElementIntegerSet(elem_type,PRO_FEAT_FLEXMOVE);
  C_LOG("ProElementIntegerSet");
  status = ProElemtreeElementAdd(elem,NULL,elem_type);
  C_LOG("ProElemtreeElementAdd");
	
  status = ProElementAlloc(PRO_E_STD_FEATURE_NAME,&elem_feat_name);
  C_LOG("ProElementAlloc");
  ProStringToWstring(w_string,"Flex_move");
  status = ProElementWstringSet(elem_feat_name,w_string);
  C_LOG("ProElementWstringSet");
  status = ProElemtreeElementAdd(elem,NULL,elem_feat_name);
  C_LOG("ProElemtreeElementAdd");
	
  status = ProElementAlloc(PRO_E_FLEXMOVE_MOVED_GEOMETRY,&elem_mov_geom);
  C_LOG("ProElementAlloc");
  status = ProElemtreeElementAdd(elem,NULL,elem_mov_geom);
  C_LOG("ProElemtreeElementAdd");
	
  status = ProElementAlloc(PRO_E_STD_SURF_COLLECTION_APPL,&elem_sel);
  C_LOG("ProElementAlloc");
  status = ProElementCollectionSet(elem_sel,coll);
  C_LOG("ProElementReferenceSet");
	
  status = ProCollectionFree(&coll);
  C_LOG("ProCrvcollectionFree");
	
  status = ProSelectionarrayFree(sels);
  C_LOG("ProSelectionarrayFree");
	
  status = ProElempathAlloc(&path);
  C_LOG("ProElempathAlloc");
	
  items1[0].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
  items1[0].path_item.elem_id = PRO_E_FLEXMOVE_MOVED_GEOMETRY;
  items1[1].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
  items1[1].path_item.elem_id = PRO_E_STD_SURF_COLLECTION_APPL;
	
  status = ProElempathDataSet(path,items1,2);
  C_LOG("ProElempathDataSet");
  status = ProElemtreeElementAdd(elem,path,elem_sel);
  C_LOG("ProElemtreeElementAdd");
	
  status = ProElempathFree(&path);
  C_LOG("ProElempathFree");
	
  status = ProElementAlloc(PRO_E_FLEXMOVE_DEFINE_METHOD,&elem_method);
  C_LOG("ProElementAlloc");
  status = ProElementIntegerSet(elem_method,PRO_FLEXMOVE_DEF_METHOD_3D_DRAG);
  C_LOG("ProElementIntegerSet");
  status = ProElemtreeElementAdd(elem,NULL,elem_method);
  C_LOG("ProElemtreeElementAdd");
  
  return PRO_TK_NO_ERROR;
}