/*****************************************************************************\
FILE    : Ug3DSketchFeat.c
PURPOSE : Pro/TOOLKIT User Guide Examples related to 3D Sketched Features
HISTORY..
DATE      BUILD   AUTHOR    MODIFICATIONS
04-Dec-97 H-02-02 KS        $$1    Created
10-Dec-97 H-03-31 Philippe  $$2    add includes
\*****************************************************************************/
#include <ProToolkit.h>
#include <ProMdl.h>
#include <ProModelitem.h>

ProError User3dSketchedFeatureCreate();
ProError UserSectionBuild(ProSection section, ProSelection *sketch_refs);

/* =============================================================== *\
   Function: User3dSketchedFeatureCreate()
   Purpose: Creates feature from 3D section 
\* =============================================================== */
ProError User3dSketchedFeatureCreate()
{
	int status;
	ProElement elem_tree, elem_ftype, elem_form, elem_sec, elem_sket;
	ProElement elem_attributes, elem_attr_std_sides, elem_direction, elem_ext_depth;
	ProElement elem_ext_depth_to, elem_ext_depth_to_type;
	ProElement elem_ext_depth_to_value, elem_sec_plane, elem_sec_pln_ref;
	ProElement elem_sec_pln_view_dir, elem_sec_plane_sk_orient;
	ProElement elem_sec_pln_orient_dir, elem_sec_pln_orient_ref;
	ProMdl model;
	ProModelitem model_item;
	ProSelection model_sel, *sketch_refs;
	ProFeatureCreateOptions options[1];
	ProValue  value;
	ProValueData  value_data;
	ProFeature  feature;
	ProSection  section;
	ProErrorlist  errors;
	ProElempath  elem_path;
	ProElempathItem  path_items[2];

/* =============================================================== *\
        Obtain handles for sketch plane and orientation reference
\* =============================================================== */

	sketch_refs = (ProSelection *)calloc(2, sizeof(ProSelection));
	if (sketch_refs != NULL)
	{
		status = UserSelectSketchPlaneRefs(&sketch_refs);
			ERROR_CHECK("UserSelectSketchPlaneRefs", "User3dSketchedFeatureCreate", status);
	}

/* =============================================================== *\
        Create root of element tree
\* =============================================================== */

	status = ProElementAlloc(PRO_E_FEATURE_TREE, &elem_tree);
			ERROR_CHECK("ProElementAlloc", "User3dSketchedFeatureCreate", status);

/* =============================================================== *\
        Create feature type element
\* =============================================================== */

	status = ProElementAlloc(PRO_E_FEATURE_TYPE, &elem_ftype);

/* =============================================================== *\
        Set value of feature type element and add to element tree
\* =============================================================== */
  
    value_data.type = PRO_VALUE_TYPE_INT;
    value_data.v.i = PRO_FEAT_PROTRUSION;
    status = ProValueAlloc(&value);
    status = ProValueDataSet(value, &value_data);
    status = ProElementValueSet(elem_ftype, value);
	status = ProElemtreeElementAdd(elem_tree, NULL, elem_ftype);

/* =============================================================== *\
        Create feature form element
\* =============================================================== */

	status = ProElementAlloc(PRO_E_FEATURE_FORM, &elem_form);

/* =============================================================== *\
        Set value of feature form element and add to element tree
\* =============================================================== */
  
    value_data.type = PRO_VALUE_TYPE_INT;
    value_data.v.i = PRO_EXTRUDE;
    status = ProValueAlloc(&value);
    status = ProValueDataSet(value, &value_data);
    status = ProElementValueSet(elem_form, value);
	status = ProElemtreeElementAdd(elem_tree, NULL, elem_form);

/* =============================================================== *\
        Allocate and add section element to tree
\* =============================================================== */

	status = ProElementAlloc (PRO_E_STD_SECTION, &elem_sec);	
	status = ProElemtreeElementAdd(elem_tree, NULL, elem_sec);

/* =============================================================== *\
        Allocate and add standard section plane element to tree
\* =============================================================== */

	status = ProElementAlloc (PRO_E_STD_SECTION_PLANE, &elem_sec_plane);	
	status = ProElemtreeElementAdd(elem_sec, NULL, elem_sec_plane);


/* =============================================================== *\
        Allocate and add sketch plane reference element to tree
\* =============================================================== */

	status = ProElementAlloc (PRO_E_STD_SEC_PLANE, &elem_sec_pln_ref);	
    value_data.type = PRO_VALUE_TYPE_SELECTION;
    value_data.v.r = sketch_refs[0];
    status = ProValueAlloc(&value);
    status = ProValueDataSet(value, &value_data);
    status = ProElementValueSet(elem_sec_pln_ref, value);
	status = ProElemtreeElementAdd(elem_sec_plane, NULL, elem_sec_pln_ref);

/* =============================================================== *\
        Allocate and add sketch plane view direction element to tree
\* =============================================================== */

	status = ProElementAlloc (PRO_E_STD_SEC_PLANE_VIEW_DIR, &elem_sec_pln_view_dir);	
    value_data.type = PRO_VALUE_TYPE_INT;
    value_data.v.i = PRO_SEC_VIEW_DIR_SIDE_ONE;
    status = ProValueAlloc(&value);
    status = ProValueDataSet(value, &value_data);
    status = ProElementValueSet(elem_sec_pln_view_dir, value);
	status = ProElemtreeElementAdd(elem_sec_plane, NULL, elem_sec_pln_view_dir);

/* =============================================================== *\
        Allocate and add sketch plane orientation element to tree
\* =============================================================== */

	status = ProElementAlloc (PRO_E_STD_SEC_PLANE_SKET_ORIENT, &elem_sec_plane_sk_orient);	
	status = ProElemtreeElementAdd(elem_sec_plane, NULL, elem_sec_plane_sk_orient);

/* =============================================================== *\
        Allocate and add sketch plane orientation direction element to tree
\* =============================================================== */

	status = ProElementAlloc (PRO_E_STD_SEC_PLANE_ORIENT_DIR, &elem_sec_pln_orient_dir);	
    value_data.type = PRO_VALUE_TYPE_INT;
    value_data.v.i = PRO_SEC_ORIENT_DIR_UP;
    status = ProValueAlloc(&value);
    status = ProValueDataSet(value, &value_data);
    status = ProElementValueSet(elem_sec_pln_orient_dir, value);
	status = ProElemtreeElementAdd(elem_sec_plane_sk_orient, NULL, elem_sec_pln_orient_dir);

/* =============================================================== *\
        Allocate and add sketch plane orientation reference element to tree
\* =============================================================== */

	status = ProElementAlloc (PRO_E_STD_SEC_PLANE_ORIENT_REF, &elem_sec_pln_orient_ref);	
    value_data.type = PRO_VALUE_TYPE_SELECTION;
    value_data.v.r = sketch_refs[1];
    status = ProValueAlloc(&value);
    status = ProValueDataSet(value, &value_data);
    status = ProElementValueSet(elem_sec_pln_orient_ref, value);
	status = ProElemtreeElementAdd(elem_sec_plane_sk_orient, NULL, elem_sec_pln_orient_ref);

/* =============================================================== *\
        Create incomplete feature
\* =============================================================== */

	status = ProMdlCurrentGet(&model);
		ERROR_CHECK("ProMdlCurrentGet", "User3dSketchedFeatureCreate", status);

	status = ProMdlToModelitem(model, &model_item);
		ERROR_CHECK("ProMdlToModelitem", "User3dSketchedFeatureCreate", status);

	status = ProSelectionAlloc(NULL, &model_item, &model_sel);
		ERROR_CHECK("ProSelectionAlloc", "User3dSketchedFeatureCreate", status);

	options[0] = PRO_FEAT_CR_INCOMPLETE_FEAT;

	status = ProFeatureCreate(model_sel, elem_tree, options, 1, &feature, &errors);
		ERROR_CHECK("ProFeatureCreate", "User3dSketchedFeatureCreate", status);


/* =============================================================== *\
       Obtain handle for section
\* =============================================================== */

	status = ProElempathAlloc(&elem_path);
		ERROR_CHECK("ProElempathAlloc", "User3dSketchedFeatureCreate", status);

	path_items[0].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	path_items[0].path_item.elem_id = PRO_E_STD_SECTION;
	path_items[1].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
	path_items[1].path_item.elem_id = PRO_E_SKETCHER;

	status = ProElempathDataSet(elem_path, path_items, 2);
		ERROR_CHECK("ProElempathDataSet", "User3dSketchedFeatureCreate", status);

	status = ProFeatureElemValueGet(&feature, elem_path, &value);
		ERROR_CHECK("ProFeatureElemValueGet", "User3dSketchedFeatureCreate", status);

	status = ProValueDataGet(value, &value_data);
		ERROR_CHECK("ProValueDataGet", "User3dSketchedFeatureCreate", status);

	section = (ProSection)value_data.v.p;

/* =============================================================== *\
       Create section
\* =============================================================== */

	status = UserSectionBuild(section, sketch_refs);
		ERROR_CHECK("UserSectionBuild", "User3dSketchedFeatureCreate", status);

/* =============================================================== *\
      Create sketcher element  
\* =============================================================== */

	status = ProElementAlloc(PRO_E_SKETCHER, &elem_sket);

/* =============================================================== *\
      Set value of sketcher element and add to tree as a 
	  branch of the elem_sec element 
\* =============================================================== */

	value_data.type = PRO_VALUE_TYPE_POINTER;
	value_data.v.p = (void *) section;
	status = ProValueAlloc(&value);
	status = ProValueDataSet(value, &value_data);
	status = ProElementValueSet(elem_sket, value);
	status = ProElemtreeElementAdd(elem_sec, NULL, elem_sket);
 
/* =============================================================== *\
      Create attributes element and add to element tree
\* =============================================================== */

	status = ProElementAlloc(PRO_E_ATTRIBUTES, &elem_attributes);
	status = ProElemtreeElementAdd(elem_tree, NULL, elem_attributes);

/* =============================================================== *\
      Create standard sides element and add to tree 
\* =============================================================== */

	status = ProElementAlloc(PRO_E_STD_SIDES, &elem_attr_std_sides);
	value_data.type = PRO_VALUE_TYPE_INT;
	value_data.v.i = PRO_SIDES_ONE_SIDE;
	status = ProValueAlloc(&value);
	status = ProValueDataSet(value, &value_data);
	status = ProElementValueSet(elem_attr_std_sides, value);
	status = ProElemtreeElementAdd(elem_attributes, NULL, elem_attr_std_sides);
 
/* =============================================================== *\
      Create extrusion direction element 
\* =============================================================== */

	status = ProElementAlloc(PRO_E_STD_DIRECTION, &elem_direction);
 
/* =============================================================== *\
      Set value of extrusion direction element and add to element tree
\* =============================================================== */
  
    status = value_data.type = PRO_VALUE_TYPE_INT;
    status = value_data.v.i = PRO_STD_DIR_SIDE_ONE;
    status = ProValueAlloc(&value);
    status = ProValueDataSet(value, &value_data);
    status = ProElementValueSet(elem_direction, value);
	status = ProElemtreeElementAdd(elem_tree, NULL, elem_direction);

/* =============================================================== *\
      Create section depth compound element and add to tree
\* =============================================================== */

	status = ProElementAlloc(PRO_E_STD_EXT_DEPTH, &elem_ext_depth);
	status = ProElemtreeElementAdd(elem_tree, NULL, elem_ext_depth);

/* =============================================================== *\
      Create extrusion-depth-to compound element and add to tree
\* =============================================================== */
 
	status = ProElementAlloc(PRO_E_EXT_DEPTH_TO, &elem_ext_depth_to);
	status = ProElemtreeElementAdd(elem_ext_depth, NULL, elem_ext_depth_to);

/* =============================================================== *\
      Create extrusion depth type element and add to tree as 
	  branch of elem_ext_depth_to element
\* =============================================================== */

	status = ProElementAlloc(PRO_E_EXT_DEPTH_TO_TYPE, &elem_ext_depth_to_type);
    value_data.type = PRO_VALUE_TYPE_INT;
   	value_data.v.i = PRO_EXT_DEPTH_TO_BLIND;
    status = ProValueAlloc(&value);
    status = ProValueDataSet(value, &value_data);
    status = ProElementValueSet(elem_ext_depth_to_type, value);
	status = ProElemtreeElementAdd(elem_ext_depth_to, NULL, elem_ext_depth_to_type);
 
/* =============================================================== *\
      Create extrusion depth value element and add to tree as 
	  branch of elem_ext_depth_to element
\* =============================================================== */

    status = ProElementAlloc(PRO_E_EXT_DEPTH_TO_VALUE, &elem_ext_depth_to_value);
    value_data.type = PRO_VALUE_TYPE_DOUBLE;
    value_data.v.d = 30.0;
    status = ProValueAlloc(&value);
    status = ProValueDataSet(value, &value_data);
    status = ProElementValueSet(elem_ext_depth_to_value, value);
	status = ProElemtreeElementAdd(elem_ext_depth_to, NULL, elem_ext_depth_to_value);
 
/* =============================================================== *\
	  Redefine the feature with updated elements in the tree
\* =============================================================== */

	options[0] = PRO_FEAT_CR_NO_OPTS;
	
	status = ProFeatureRedefine(NULL, &feature, elem_tree, options, 1,&errors);
		ERROR_CHECK("ProFeatureRedefine", "User3dSketchedFeatureCreate", status);

	status = ProElementFree(&elem_tree);
		ERROR_CHECK("ProElementFree", "User3dSketchedFeatureCreate", status);

	free(sketch_refs);

	return(status);
		
}
