//==============================================================================
//! 
//! \brief Mil3dmod CAPI header (M3dmod...)
//! 
//! AUTHOR:  Matrox Imaging
//!
//! COPYRIGHT NOTICE:
//! Copyright (c) Matrox Electronic Systems Ltd., 1992-2023.
//! All Rights Reserved 
//  Revision:  10.60.0776
//==============================================================================

#ifndef __MIL_3DMOD_H__
#define __MIL_3DMOD_H__

#if (!M_MIL_LITE) /* MIL FULL ONLY */

/* C++ directive if needed */
#ifdef __cplusplus
extern "C"
   {
#endif

//==============================================================================   
// Indexing, used in other M3dmod functions (M3dmodInquire(), M3dmodControl(), ...)
#define M_DEFAULT                               0x10000000L // already defined in mil.h
#define M_CONTEXT                               0x08000000L // already defined in mil.h
#define M_GENERAL                               0x20000000L // already defined in milmod.h, ..
#define M_ALL                                   0x40000000L // already defined in mil.h
#define M_MOD_INDEX_FLAG                        0x00200000L

#define M_MOD_LABEL_VALUE                              5115  // =internal
#define M_MOD_INDEX_VALUE                              5116

#define M_MODIFICATION_COUNT                          5010L // already defined in mil.h

//==============================================================================
// M3dmodAlloc/AllocResult
#define M_FIND_CYLINDER_CONTEXT                      5121
#define M_FIND_SPHERE_CONTEXT                        5262
#define M_FIND_RECTANGULAR_PLANE_CONTEXT             5299
#define M_FIND_BOX_CONTEXT                           5441
#define M_FIND_SURFACE_CONTEXT                       5548
#define M_FIND_CYLINDER_RESULT                       5122
#define M_FIND_SPHERE_RESULT                         5476
#define M_FIND_RECTANGULAR_PLANE_RESULT              5477
#define M_FIND_BOX_RESULT                            5478
#define M_FIND_SURFACE_RESULT                        5549
#define M_DRAW_3D_CONTEXT                            3815 // Already defined in milcal
#define M_DRAW_3D_GEOMETRIC_CONTEXT                  M_DRAW_3D_CONTEXT
#define M_DRAW_3D_SURFACE_CONTEXT                    5768
//==============================================================================
// M3dmodControl / M3dmodInquire
// Context 
#define M_ENABLE                                     -9997L // also in mil.h
#define M_DISABLE                                    -9999L // also in mil.h
#define M_TRUE                                           1L // Already defined in    mil.h, milmeas.h, miledge.h
#define M_FALSE                                          0L // Already defined in    mil.h, milmeas.h, miledge.h
#define M_AUTO                                         444L // also in mil.h
#define M_USER_DEFINED                                  21L // also in mil.h
#define M_TIMEOUT                                     2077L
#define M_ALLOCATION_FAILURE_REAL_TEST_FLAG            971L // also in milblob.h, milstr.h

// Geometric Context
#define M_RECTANGLE                              0x00000040L   // 64 // Already defined in milmod
#define M_SPHERE                                       2931L // Already defined in 3dgeo
#define M_CYLINDER                                     3656 // Already defined in 3dgeo
#define M_BOX                                         0x101L // Already defined in 3dgeo
#define M_RECTANGLE_RANGE                              4194                                    
#define M_SPHERE_RANGE                                 4195 
#define M_CYLINDER_RANGE                               4196   
#define M_BOX_RANGE                                    4197
#define M_RESERVED_POINTS_DISTANCE                     5209
#define M_NUMBER_OF_POINTS_RESERVED                    5377
#define M_RADIUS_MIN                                   5117
#define M_RADIUS_MAX                                   5118
#define M_RADIUS                                 0x00000040L
#define M_TOLERANCE_RADIUS                             4192
#define M_TOLERANCE_LENGTH                             4193
#define M_LENGTH_MIN                                   5179
#define M_LENGTH_MAX                                   5180
#define M_SIZE_X_MIN                                   5737
#define M_SIZE_Y_MIN                                   5738
#define M_SIZE_Z_MIN                                   5739
#define M_SIZE_X_MAX                                   5740
#define M_SIZE_Y_MAX                                   5741
#define M_SIZE_Z_MAX                                   5742
#define M_FIT_NORMALS_DISTANCE                         5107 
#define M_ACCEPTANCE                                   200L   // Also defined in milmod.h
#define M_CERTAINTY                                    202L   // Also defined in milmod.h
#define M_COVERAGE_MAX                                2457L   // Already defined in milmod.h
#define M_FIT_ERROR_WEIGHTING_FACTOR                   221L   // Already defined in milmod.h
#define M_MIN_SEPARATION_DISTANCE                      5332
#define M_ACCEPTANCE_TARGET                            201L   // Already defined in milmod.h
#define M_NUMBER_OF_POINTS_MIN                        5060L   // ALready defined in mil3dblob
#define M_FIT_DISTANCE_MODE                           5427
#define M_FIT_DISTANCE                                5428
#define M_PERSEVERANCE                                5222
#define M_LOW                                            1L // Also defined in Milocr.h
#define M_MEDIUM                                         2L // Also defined in Milocr.h
#define M_HIGH                                           3L // Also defined in Milocr.h
#define M_ABSOLUTE                                       1L   // Also defined in milpat.h 
#define M_RELATIVE                                      21L   // Also defined in milpat.h
#define M_FIT_ITERATIONS_MAX                           104L // Already defined in milmet.h
//Cylinder context
//Plane context
#define M_NORMAL_CONDITION                            4114
#define M_NORMAL_X                                    3537 // Already defined in mil3d
#define M_NORMAL_Y                                    3538
#define M_NORMAL_Z                                    3539
#define M_NORMAL_ANGLE_TOLERANCE                      5517 
#define M_UNCONDITIONAL                               0L         // Already defined in mil.h
#define M_PARALLEL                                    0x0027L   // Already defined in milmetrol.h
#define M_PERPENDICULAR                               0x0028L   // Already defined in milmetrol.h
#define M_PARALLEL_OR_PERPENDICULAR                  4117
#define M_VISIBLE_FACE_PARALLEL                       5853
#define M_TOLERANCE_X                                 5473
#define M_TOLERANCE_Y                                 5474
#define M_TOLERANCE_Z                                 5475
// Box context
#define M_DISTANCE_MODE                               2563L // Already defined in milmetrol
#define M_DISTANCE_THRESHOLD                          4008 
#define M_PLANE_CERTAINTY                             4148
#define M_PLANE_ACCEPTANCE                            4149
#define M_PLANE_MAX_COVERAGE                          4150
#define M_NUMBER_OF_VISIBLE_FACES                     5615
#define M_NUMBER_OF_VISIBLE_FACES_MIN                 5909
#define M_NUMBER_OF_VISIBLE_FACES_MAX                 5910
#define M_COMPLETION_SIZE_X                             5618
#define M_COMPLETION_SIZE_Y                             5619
#define M_COMPLETION_SIZE_Z                             5620
#define M_SAME_AS_NOMINAL                                0
#define M_DIRECTION_MODE                              3431  // already defined in mil3dim.h              
#define M_TOWARDS_POSITION                            3432  // already defined in mil3dim.h
#define M_AWAY_FROM_POSITION                          3433  // already defined in mil3dim.h
#define M_TOWARDS_DIRECTION                           3434  // already defined in mil3dim.h
#define M_DIRECTION_REFERENCE_X                       3435  // already defined in mil3dim.h
#define M_DIRECTION_REFERENCE_Y                       3436  // already defined in mil3dim.h
#define M_DIRECTION_REFERENCE_Z                       3437  // already defined in mil3dim.h
#define M_BOX_ORIENTATION_TWO_PLANES                  5650 
#define M_BOX_ORIENTATION_LARGEST_PLANE               5651
#define M_BOX_ORIENTATION_AVERAGE_NORMAL              5652
#define M_BOX_ORIENTATION_AVERAGE_ROTATION            5653
#define M_BOX_FACE_PERPENDICULARITY_THRESHOLD         5654
#define M_COMPLETION_ANGLE_TOLERANCE                  5682
#define M_BOX_FACE_PARALLELISM_THRESHOLD              5655
#define M_ELONGATION_MIN                              5704
#define M_ELONGATION_MAX                              5705
#define M_POLARITY                              0x00004000L // already defined in milmeas.h
#define M_OUTSIDE                                        0L // already defined in mil.h
#define M_INSIDE                                         1L // already defined in mil.h
#define M_SAME                                          -1L // already defined in milocr.h
#define M_ANY                                   0x11000000L // already defined in milocr.h
#define M_VSDBG_ACTIVE                                5607
#define M_SORT_DIRECTION                              5650
#define M_EXHAUSTIVE_SEARCH                           5647 
// Draw context
#define M_ROOT_NODE                                            0  // already defined in mil3dgra.h
#define M_GLOBAL_DRAW_SETTINGS                         M_CONTEXT  // already defined in mil3dblob.h
#define M_DRAW_MODEL                                  0x00001000L // already defined
#define M_DRAW_BOX                                    0x00000020L // already defined in milpat.h
#define M_DRAW_INLIER_POINTS                          5492
#define M_DRAW_RESERVED_POINTS                        5493
#define M_DRAW_MODEL_KEYPOINTS                        5679
#define M_DRAW_MODEL_PREPROCESSED                     5769
#define M_DRAW_CS_SHIFT                                 16L // already defined in milcal
#define M_DRAW_AXES                                (1 << M_DRAW_CS_SHIFT) // already defined in milcal
#define M_DRAW_BACKGROUND_POINTS                      5835
#define M_PSEUDO_COLOR                              0x4000L // already defined in mil3dblob.h
#define M_PSEUDO_COLOR_OFFSET                         5439L // already defined in mil3dblob.h
#define M_GRAPHIC_LIST_DEFAULT                  0x04005526L // already defined in mil3dblob.h
#define M_ACTIVE                                      1534L // already defined in milmetrol.h
#define M_THICKNESS                                      3L // already defined in mil3dgra.h
#define M_APPEARANCE                                  4679  // already defined in mil3dgra.h
#define M_OPACITY                                     4728  // already defined in mil3dgra.h
#define M_COLOR                                 0x00000100L // already defined in mil3dgra.h
#define M_DEFAULT_LENGTH                               -1
#define M_REFERENCE_X                                  100L  // already defined in    milmod.h, milpat.h
#define M_REFERENCE_Y                                  101L  // already defined in    milmod.h, milpat.h
#define M_REFERENCE_Z                                 5765
#define M_CENTER                                 0x00000080L          // already defined in milim.h
//surface context
#define M_USER_DEFINED_REGISTRATION_CONTEXT_ID        5677L
#define M_REFINE_REGISTRATION                         5678L
#define M_SCENE_PROJECTION                            5763L
#define M_USER_DEFINED_REGISTRATION                   5722L
#define M_FIND_SURFACE_REFINEMENT_PRECISE             5723L
#define M_FIND_SURFACE_REFINEMENT_FAST                5816L
#define M_SEARCH_POINT_RESOLUTION                     5747
#define M_SAME_AS_MODEL                                 -1
#define M_MODEL_RESOLUTION                            5748
#define M_REMOVE_BACKGROUND                           5760L
#define M_SAVE_FIT_INFO                               5756
#define M_REMOVE_OUTLIERS                             5768L 
#define M_SCENE_COMPLEXITY                            5784
#define M_RESTING_PLANE_ANGLE_TOLERANCE               5872L
#define M_FLOOR_DEFINED                               5883
#define M_NUMBER_RESTING_PLANE                        5884
#define M_FLOOR                                       4867L       // 0x1303 already defined
 // Result
#define M_STOP_FIND                                     115L // already define milmod

//==============================================================================
// M3dmodInquire 
// Context                        
//==============================================================================
// M3dmodAllocResult ResultTypes
#define M_RMS_ERROR                                  3502
#define M_SCORE                                0x00001400L                // Also defined in milpat.h, milmod.h, milcode.h, milmeas.h, milreg.h
#define M_NUMBER_OF_POINTS                        M_NUMBER // already defined in mil3dim.h
#define M_NUMBER                                     1009L         // defined in milmeas.h
#define M_SCORE_TARGET                         0x00001800L // defined in milmod.h
//==============================================================================
// M3dmodGetResult ResultTypes
// General
#define M_STATUS                                0x00008002L // already defined
#define M_NOT_INITIALIZED                                3L // already defined in milcal
#define M_CURRENTLY_CALCULATING                       2718L //already defined in milreg
#define M_TIMEOUT_REACHED                             2554L // also in milmod.h, mildmr.h
#define M_STOPPED_BY_REQUEST                          2555L // also in milmod.h, mildmr.h
#define M_NOT_ENOUGH_MEMORY                              4L // also in mil.h, mildmr.h
#define M_COMPLETE                              0x00000000L // also in mil.h, milmod.h, mildmr.h
#define M_INTERNAL_ERROR                                 5L // also in milcal.h, mildmr.h
#define M_NOT_ENOUGH_VALID_DATA                        1336L      // Already defined in mil3dmet
#define M_MISSING_COMPONENT_NORMALS_MIL                4183
#define M_NOT_ENOUGH_FEATURES                          5588
#define M_ALL_POINTS_REPLICATED                        5787              
#define M_FIT_DISTANCE_USED                            5518
// Geo result
#define M_LENGTH                                0x00002000L // Already defined in mil3dgeo
#define M_AXIS_X                                      3664  // Already defined in mil3dgeo
#define M_AXIS_Y                                      3665  // Already defined in mil3dgeo
#define M_AXIS_Z                                      3666  // Already defined in mil3dgeo
#define M_CENTER_X                                       4L // Already defined in mil3dgeo
#define M_CENTER_Y                                       5L // Already defined in mil3dgeo
#define M_CENTER_Z                                    3400  // Already defined in mil3dgeo
#define M_RADIUS                                0x00000040L // Already defined in MilMod.h
#define M_START_POINT_X                               3658  // Already defined in mil3dgeo
#define M_START_POINT_Y                               3659  // Already defined in mil3dgeo                             
#define M_START_POINT_Z                               3660  // Already defined in mil3dgeo   
#define M_END_POINT_X                                 3661  // Already defined in mil3dgeo   
#define M_END_POINT_Y                                 3662  // Already defined in mil3dgeo   
#define M_END_POINT_Z                                 3663  // Already defined in mil3dgeo
#define M_COEFFICIENT_A                               3401  // Already defined in mil3dgeo
#define M_COEFFICIENT_B                               3402  // Already defined in mil3dgeo
#define M_COEFFICIENT_C                               3403  // Already defined in mil3dgeo
#define M_COEFFICIENT_D                               3404  // Already defined in mil3dgeo
#define M_NORMAL_X                                    3537  // Already defined in mil3dgeo
#define M_NORMAL_Y                                    3538  // Already defined in mil3dgeo
#define M_NORMAL_Z                                    3539  // Already defined in mil3dgeo
#define M_SIZE_X                                      1536L // Already defined in mil3dgeo
#define M_SIZE_Y                                      1537L // Already defined in mil3dgeo
#define M_SIZE_Z                                      1538L // Already defined in mil3dgeo
#define M_CLOSEST_TO_ORIGIN_X                         3540  // Already defined in mil3dgeo
#define M_CLOSEST_TO_ORIGIN_Y                         3541  // Already defined in mil3dgeo
#define M_CLOSEST_TO_ORIGIN_Z                         3542  // Already defined in mil3dgeo
#define M_UNROTATED_MIN_X                             3850  // Already defined in mil3dgeo
#define M_UNROTATED_MIN_Y                             3851  // Already defined in mil3dgeo
#define M_UNROTATED_MIN_Z                             3852  // Already defined in mil3dgeo
#define M_UNROTATED_MAX_X                             3853  // Already defined in mil3dgeo
#define M_UNROTATED_MAX_Y                             3854  // Already defined in mil3dgeo
#define M_UNROTATED_MAX_Z                             3855  // Already defined in mil3dgeo
//Surface
#define M_STATUS_SCENE_RESOLUTION                     5845
#define M_STATUS_REFINE_REGISTRATION                  5848
#define M_APPLIED_AND_REJECTED                        5846
#define M_NOT_APPLIED                                 5818   
#define M_APPLIED                                     5817
#define M_INCOMPATIBLE                                5746
#define M_COMPATIBLE                                  5847
#define M_POSITION_X                            0x00003400L // Already defined in milpat.h
#define M_POSITION_Y                            0x00004400L // Already defined in milpat.h
#define M_POSITION_Z                                  3960L // Already defined in mil3dgra
#define M_SCORE_FIT                                   2461L // Already defined in milmod.h

//Pseudo Ids
#define M_3DMOD_FIND_SURFACE_PSEUDO_ID                (M_3DMOD_PSEUDO_ID +0x080000)
#define M_FIND_SURFACE_CONTEXT_REFINEMENT_FAST        (M_3DMOD_FIND_SURFACE_PSEUDO_ID + M_FAST)
#define M_FIND_SURFACE_CONTEXT_REFINEMENT_PRECISE     (M_3DMOD_FIND_SURFACE_PSEUDO_ID + M_PRECISE)

//==============================================================================
// CopyResult
#define M_BOUNDING_BOX                             0x00000003L      // Already defined in mil3dim 
#define M_GEOMETRY                                       1306L      // Already defined in mil3dgeo
#define M_RESULT_IMAGE_SIZE_X                            5226L // already defined in mil3dmet.h
#define M_RESULT_IMAGE_SIZE_Y                            5227L // already defined in mil3dmet.h
#define M_INDEX_IMAGE                                    5046L // already defined in mil3dblob.h
#define M_INLIER_MASK                                    3590L // Already defined in mil3dmet.h
#define M_INLIER_INDEX_IMAGE                             5489
#define M_RESERVED_MASK                                  5490
#define M_RESERVED_INDEX_IMAGE                           5491
#define M_OCCURRENCE_MATRIX                              5590
#define M_FIXTURING_MATRIX                               3878L // already defined in mil3dim.h
#define M_RESTING_PLANE                                  5871L
#define M_BACKGROUND_MASK                                5831L
#define M_PLANE                                          1353L // Already defined in mil3dgeo
//==============================================================================
// Define
#define M_DELETE                                            3L // already defined in milmod.h
#define M_ADD                                          0x0000L // already defined in milmod.h
#define M_ADD_FROM_GEOMETRY                              5471L
#define M_ADD_FROM_POINT_CLOUD                           5554
#define M_SURFACE                                        1021L // Already defined in mil.h (milbuf)
//==============================================================================
//M3dmodCopy
#define M_MODEL_KEYPOINTS                                5676
#define M_MODEL                                    0x00010000L   // already defined in milmod.h
#define M_MODEL_PREPROCESSED                             5770
//==============================================================================
// CAPI function prototypes
MIL_ID MFTYPE M3dmodAlloc(MIL_ID    SysId,
                          MIL_INT64 ContextType,
                          MIL_INT64 ControlFlag,
                          MIL_ID*   Context3dmodIdPtr);

MIL_ID MFTYPE M3dmodAllocResult(MIL_ID    SysId,
                                MIL_INT64 ResultType,
                                MIL_INT64 ControlFlag,
                                MIL_ID*   Result3dmodIdPtr);

void MFTYPE M3dmodFree(MIL_ID ContextOrResult3dmodId);


void MFTYPE M3dmodFind(MIL_ID     Context3dmodId,
                       MIL_ID     ContainerBufId,
                       MIL_ID     Result3dmodId,
                       MIL_INT64  ControlFlag);

void MFTYPE M3dmodCopyResult(MIL_ID     SrcResult3dmodId,
                             MIL_INT64  SrcIndex,
                             MIL_ID     DstMilObjectId,
                             MIL_INT64  DstIndex,
                             MIL_INT64  CopyType,
                             MIL_INT64  ControlFlag);


void MFTYPE M3dmodCopy(MIL_ID     SrcContext3dmodId,
                       MIL_INT64  SrcIndex,
                       MIL_ID     DstMilObjectId,
                       MIL_INT64  DstIndex,
                       MIL_INT64  CopyType,
                       MIL_INT64  ControlFlag);

MIL_INT64 MFTYPE M3dmodDefine(MIL_ID     Context3dmodId,
                              MIL_INT64  Operation,
                              MIL_INT64  ModelType,
                              MIL_DOUBLE Param1,
                              MIL_DOUBLE Param2,
                              MIL_DOUBLE Param3,
                              MIL_DOUBLE Param4,
                              MIL_DOUBLE Param5,
                              MIL_DOUBLE Param6,
                              MIL_INT64  ControlFlag);

MIL_INT64 MFTYPE M3dmodDraw3d(MIL_ID    OperationDraw3dContext3dmodId,
                              MIL_ID    SrcResult3dmodId,
                              MIL_INT64 SrcIndex,
                              MIL_ID    DstList3dgraId,
                              MIL_INT64 DstParentLabel,
                              MIL_INT64 ControlFlag);

void MFTYPE M3dmodPreprocess(MIL_ID     Context3dmodId,
                             MIL_INT64  ControlFlag);

void MFTYPE M3dmodControlInt64(MIL_ID     ContextOrResult3dmodId,
                               MIL_INT64  Index,
                               MIL_INT64  ControlType,
                               MIL_INT64  ControlValue);

void MFTYPE M3dmodControlDouble(MIL_ID     ContextOrResult3dmodId,
                                MIL_INT64  Index,
                                MIL_INT64  ControlType,
                                MIL_DOUBLE ControlValue);

MIL_INT64 MFTYPE M3dmodInquire(MIL_ID    Context3dmodId,
                               MIL_INT64 Index,
                               MIL_INT64 InquireType,
                               void*     UserVarPtr);

void MFTYPE M3dmodControlDrawInt64(MIL_ID     DrawContext3dmodId,
                                   MIL_INT64  Operation,
                                   MIL_INT64  ControlType,
                                   MIL_INT64  ControlValue);

void MFTYPE M3dmodControlDrawDouble(MIL_ID     DrawContext3dmodId,
                                    MIL_INT64  Operation,
                                    MIL_INT64  ControlType,
                                    MIL_DOUBLE ControlValue);

MIL_INT64 MFTYPE M3dmodInquireDraw(MIL_ID     DrawContext3dmodId,
                                   MIL_INT64  Operation,
                                   MIL_INT64  InquireType,
                                   void*      UserVarPtr);

MIL_DOUBLE MFTYPE M3dmodGetResult(MIL_ID    Result3dmodId,
                                  MIL_INT64 ResultIndex,
                                  MIL_INT64 ResultType,
                                  void*     ResultArrayPtr);

#if M_MIL_USE_UNICODE
void MFTYPE M3dmodSaveA(MIL_CONST_TEXTA_PTR FileName,
                        MIL_ID      Context3dmodId,
                        MIL_INT64   ControlFlag);

MIL_ID MFTYPE M3dmodRestoreA(MIL_CONST_TEXTA_PTR FileName,
                             MIL_ID      SysId,
                             MIL_INT64   ControlFlag,
                             MIL_ID*     Context3dmodIdPtr);

void MFTYPE M3dmodStreamA(MIL_TEXTA_PTR MemPtrOrFileName,
                          MIL_ID     SysId,
                          MIL_INT64  Operation,
                          MIL_INT64  StreamType,
                          MIL_DOUBLE Version,
                          MIL_INT64  ControlFlag,
                          MIL_ID*    Context3dmodIdPtr,
                          MIL_INT*   SizeByteVarPtr);



void MFTYPE M3dmodSaveW(MIL_CONST_TEXTW_PTR FileName,
                        MIL_ID              Context3dmodId,
                        MIL_INT64           ControlFlag);

MIL_ID MFTYPE M3dmodRestoreW(MIL_CONST_TEXTW_PTR FileName,
                             MIL_ID              SysId,
                             MIL_INT64           ControlFlag,
                             MIL_ID*             Context3dmodIdPtr);

void MFTYPE M3dmodStreamW(MIL_TEXTW_PTR MemPtrOrFileName,
                          MIL_ID        SysId,
                          MIL_INT64     Operation,
                          MIL_INT64     StreamType,
                          MIL_DOUBLE    Version,
                          MIL_INT64     ControlFlag,
                          MIL_ID*       Context3dmodIdPtr,
                          MIL_INT*      SizeByteVarPtr);



#if M_MIL_UNICODE_API
#define M3dmodSave               M3dmodSaveW
#define M3dmodRestore            M3dmodRestoreW
#define M3dmodStream             M3dmodStreamW
#else
#define M3dmodSave               M3dmodSaveA
#define M3dmodRestore            M3dmodRestoreA
#define M3dmodStream             M3dmodStreamA
#endif //M_MIL_UNICODE_API

#else

void MFTYPE   M3dmodSave(MIL_CONST_TEXT_PTR FileName,
                         MIL_ID             Context3dmodId,
                         MIL_INT64          ControlFlag);

MIL_ID MFTYPE M3dmodRestore(MIL_CONST_TEXT_PTR FileName,
                            MIL_ID             SysId,
                            MIL_INT64          ControlFlag,
                            MIL_ID*            Context3dmodIdPtr);

void MFTYPE   M3dmodStream(MIL_TEXT_PTR MemPtrOrFileName,
                           MIL_ID       SysId,
                           MIL_INT64    Operation,
                           MIL_INT64    StreamType,
                           MIL_DOUBLE   Version,
                           MIL_INT64    ControlFlag,
                           MIL_ID*      Context3dmodIdPtr,
                           MIL_INT*     SizeByteVarPtr);

#endif //M_MIL_USE_UNICODE

/* C++ directive if needed */
#ifdef __cplusplus
}
#endif

////////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
//C++ overloads

inline void MFTYPE M3dmodStreamCpp(MilStreamParam MemPtrOrFileName,
                                  MIL_ID         SysId,
                                  MIL_INT64      Operation,
                                  MIL_INT64      StreamType,
                                  MIL_DOUBLE     Version,
                                  MIL_INT64      ControlFlag,
                                  MIL_ID*        Context3dmodIdPtr,
                                  MIL_INT*       SizeByteVarPtr)
   {
   M3dmodStream(MemPtrOrFileName.m_Param, SysId, Operation, StreamType, Version, ControlFlag, Context3dmodIdPtr, SizeByteVarPtr);
   }

#undef  M3dmodStream
#define M3dmodStream M3dmodStreamCpp
#else

#endif // __cplusplus


//==============================================================================

#ifdef __cplusplus
#if M_MIL_USE_SAFE_TYPE

//=========================================================
// See milos.h for explanation about these functions.
//=========================================================

// ----------------------------------------------------------
// M3dmodInquire

inline MIL_INT64 MFTYPE M3dmodInquireSafeType(MIL_ID ContextOrResult3dmodId, MIL_INT64 Index, MIL_INT64 InquireType, MilVoidPtr UserVarPtr)
   {
   MIL_INT64 RequiredParamType = M_PARAM_TYPE_MIL_INT64;
   if(!(M_DEFAULT_DATA_TYPE_BIT_SET(InquireType) || M_RECOMMENDED_DATA_TYPE_BIT_SET(InquireType)))
      {
      M3dmodInquire(ContextOrResult3dmodId, Index, InquireType | M_DEFAULT_DATA_TYPE, &RequiredParamType);
      }
   if(!MfuncPointerIsCompatible(RequiredParamType, UserVarPtr.Type, InquireType))
      {
      SafeTypeError(MIL_TEXT("M3dmodInquire"));
      }
   return M3dmodInquire(ContextOrResult3dmodId, Index, InquireType, UserVarPtr.Ptr);
   }

inline MIL_INT64 MFTYPE M3dmodInquireUnsafe(MIL_ID ContextOrResult3dmodId, MIL_INT64 Index, MIL_INT64 InquireType, void* UserVarPtr)
   {
   return M3dmodInquire(ContextOrResult3dmodId,Index, InquireType, UserVarPtr);
   }

inline MIL_INT64 MFTYPE M3dmodInquireDrawSafeType(MIL_ID DrawContext3dmodId, MIL_INT64 Operation, MIL_INT64 InquireType, MilVoidPtr UserVarPtr)
   {
   MIL_INT64 RequiredParamType = M_PARAM_TYPE_MIL_INT64;
   if(!(M_DEFAULT_DATA_TYPE_BIT_SET(InquireType) || M_RECOMMENDED_DATA_TYPE_BIT_SET(InquireType)))
      {
      M3dmodInquireDraw(DrawContext3dmodId, Operation, InquireType | M_DEFAULT_DATA_TYPE, &RequiredParamType);
   }
   if(!MfuncPointerIsCompatible(RequiredParamType, UserVarPtr.Type, InquireType))
      {
      SafeTypeError(MIL_TEXT("M3dmodInquireDraw"));
      }
   return M3dmodInquireDraw(DrawContext3dmodId, Operation, InquireType, UserVarPtr.Ptr);
   }

inline MIL_INT64 MFTYPE M3dmodInquireDrawUnsafe(MIL_ID DrawContext3dmodId, MIL_INT64 Operation, MIL_INT64 InquireType, void* UserVarPtr)
   {
   return M3dmodInquireDraw(DrawContext3dmodId, Operation, InquireType, UserVarPtr);
   }

#define M3dmodInquire           M3dmodInquireSafeType
#define M3dmodInquireDraw       M3dmodInquireDrawSafeType

#else // #if M_MIL_USE_SAFE_TYPE
#define M3dmodInquireUnsafe     M3dmodInquire
#define M3dmodInquireDrawUnsafe M3dmodInquireDraw
#endif // #if M_MIL_USE_SAFE_TYPE

#if M_MIL_USE_SAFE_TYPE
// -------------------------------------------------------------------------
// M3dmodGetResult safe type definitions
// 
inline MIL_DOUBLE MFTYPE M3dmodGetResultSafeType(MIL_ID Result3dmodId, MIL_INT64 ResultIndex, MIL_INT64 ResultType, MilVoidPtr ResultArrayPtr)
   {
   MIL_INT64 RequiredParamType = M_PARAM_TYPE_MIL_INT64;
   if(!(M_DEFAULT_DATA_TYPE_BIT_SET(ResultType) || M_RECOMMENDED_DATA_TYPE_BIT_SET(ResultType)))
      {
      M3dmodGetResult(Result3dmodId, ResultIndex, ResultType | M_DEFAULT_DATA_TYPE, &RequiredParamType);
      }
   if(!MfuncPointerIsCompatible(RequiredParamType, ResultArrayPtr.Type, ResultType))
      {
      SafeTypeError(MIL_TEXT("M3dmodGetResult"));
      }
   return M3dmodGetResult(Result3dmodId, ResultIndex, ResultType, ResultArrayPtr.Ptr);
   }

inline MIL_DOUBLE MFTYPE M3dmodGetResultUnsafe(MIL_ID Result3dmodId, MIL_INT64 ResultIndex, MIL_INT64 ResultType, void* ResultArrayPtr)
   {
   return M3dmodGetResult(Result3dmodId, ResultIndex, ResultType, ResultArrayPtr);
   }

#define M3dmodGetResult            M3dmodGetResultSafeType

#else // #if M_MIL_USE_SAFE_TYPE
#define M3dmodGetResultUnsafe            M3dmodGetResult
#endif // #if M_MIL_USE_SAFE_TYPE

#endif // __cplusplus


#ifdef __cplusplus

//=========================================================
// M3dmodControl function overloads when compiling c++ files
//=========================================================
template <typename T>
inline void M3dmodControl(MIL_ID ContextOrResult3dmodId, MIL_INT64 Index, MIL_INT64 ControlType, T ControlValue)
   {
   M3dmodControlInt64(ContextOrResult3dmodId, Index, ControlType, ControlValue);
   }

inline void M3dmodControl(MIL_ID ContextOrResult3dmodId, MIL_INT64 Index, MIL_INT64 ControlType, float ControlValue)
   {
   M3dmodControlDouble(ContextOrResult3dmodId, Index, ControlType, ControlValue);
   }

inline void M3dmodControl(MIL_ID ContextOrResult3dmodId, MIL_INT64 Index, MIL_INT64 ControlType, MIL_DOUBLE ControlValue)
   {
   M3dmodControlDouble(ContextOrResult3dmodId, Index, ControlType, ControlValue);
   }

template <typename T>
inline void M3dmodControlDraw(MIL_ID DrawContext3dmodId, MIL_INT64 Operation, MIL_INT64 ControlType, T ControlValue)
   {
   M3dmodControlDrawInt64(DrawContext3dmodId, Operation, ControlType, ControlValue);
   }

inline void M3dmodControlDraw(MIL_ID DrawContext3dmodId, MIL_INT64 Operation, MIL_INT64 ControlType, float ControlValue)
   {
   M3dmodControlDrawDouble(DrawContext3dmodId, Operation, ControlType, ControlValue);
   }

inline void M3dmodControlDraw(MIL_ID DrawContext3dmodId, MIL_INT64 Operation, MIL_INT64 ControlType, MIL_DOUBLE ControlValue)
   {
   M3dmodControlDrawDouble(DrawContext3dmodId, Operation, ControlType, ControlValue);
   }
#else // __cplusplus
//=========================================================
// For C file, call the default function, i.e. Double one
//=========================================================
#define M3dmodControl            M3dmodControlDouble
#define M3dmodControlDraw        M3dmodControlDrawDouble
#endif // __cplusplus

// ----------------------------------------------------------
// Overload for std::vector.
#if defined(M_MIL_USE_VECTOR) && M_MIL_USE_VECTOR
template <typename UserType>
inline MIL_INT64 MFTYPE M3dmodInquire(MIL_ID ContextOrResult3dmodId, MIL_INT64 Index, MIL_INT64  InquireType, std::vector<UserType> &UserVarPtr)
   {
   // If the given MIL data type is not the same as the SrcType, change it to the correct one
   // and give a warning.
   MIL_INT64 InternalTrueDataTypeForStdVector = MilTraits<UserType>::TypeFlag;

#if M_MIL_USE_SAFE_TYPE
   if(M_GET_HLVLDATATYPE(InquireType) != 0)
      {
      SafeTypeError(MIL_TEXT("M3dmodInquire"), MIL_TEXT("Combination value for the required data type is not supported with std::vector overload."));
      }
#endif

   InquireType = M_STRIP_HLVLDATATYPE(InquireType) + InternalTrueDataTypeForStdVector;

   MIL_INT InternalNumberOfElementsForStdVector = 0;
   M3dmodInquire(ContextOrResult3dmodId, Index, M_STRIP_HLVLDATATYPE(InquireType) + M_NB_ELEMENTS + M_TYPE_MIL_INT, &InternalNumberOfElementsForStdVector);

   UserVarPtr.resize(InternalNumberOfElementsForStdVector);

   if(InternalNumberOfElementsForStdVector > 0)
      {
      return M3dmodInquire(ContextOrResult3dmodId, Index, InquireType, &UserVarPtr[0]);
      }
   return 0;
   }
template <typename UserType>
inline MIL_DOUBLE MFTYPE M3dmodGetResult(MIL_ID Result3dmodId, MIL_INT64 Index, MIL_INT64  ResultType, std::vector<UserType> &ResultArrayPtr)
   {
   //! If the given MIL data type is not the same as the SrcType, change it to the correct one
   //! and give a warning.
   MIL_INT64 InternalTrueDataTypeForStdVector = MilTraits<UserType>::TypeFlag;

#if M_MIL_USE_SAFE_TYPE
   if(M_GET_HLVLDATATYPE(ResultType) != 0)
      {
      SafeTypeError(MIL_TEXT("M3dmodGetResult"), MIL_TEXT("Combination value for the required data type is not supported with std::vector overload."));
      }
#endif

   ResultType = M_STRIP_HLVLDATATYPE(ResultType) + InternalTrueDataTypeForStdVector;

   MIL_INT InternalNumberOfElementsForStdVector = 0;
   M3dmodGetResult(Result3dmodId, Index, M_STRIP_HLVLDATATYPE(ResultType) + M_NB_ELEMENTS + M_TYPE_MIL_INT, &InternalNumberOfElementsForStdVector);

   ResultArrayPtr.resize(InternalNumberOfElementsForStdVector);

   if(InternalNumberOfElementsForStdVector > 0)
      {
      M3dmodGetResult(Result3dmodId, Index, ResultType, &ResultArrayPtr[0]);
      }
   return 0.0;
   }

// Overloads for std::vector in M3dmodStream.
inline void MFTYPE M3dmodStream(std::vector<MIL_UINT8> &MemPtrOrFileName,
                                MIL_ID                 SysId,
                                MIL_INT64              Operation,
                                MIL_INT64              StreamType,
                                MIL_DOUBLE             Version,
                                MIL_INT64              ControlFlag,
                                MIL_ID*                Context3dmodIdPtr,
                                MIL_INT*               SizeByteVarPtr)
   {
   MxxxStreamForStdVector(MemPtrOrFileName,
                          SysId,
                          Operation,
                          StreamType,
                          Version,
                          ControlFlag,
                          Context3dmodIdPtr,
                          SizeByteVarPtr,
                          M3dmodStream);
   }

#endif // defined(M_MIL_USE_VECTOR) && M_MIL_USE_VECTOR
#if M_MIL_USE_STRING
/***************************************************************************/
/* 3dmod MODULE                                                              */
/***************************************************************************/
#if M_MIL_USE_UNICODE
#if M_MIL_UNICODE_API

inline void MFTYPE M3dmodSaveW(const MIL_STRING& FileName, MIL_ID Context3dmodId, MIL_INT64 ControlFlag)
   {
   return M3dmodSaveW(FileName.c_str(), Context3dmodId, ControlFlag);
   }

inline MIL_ID MFTYPE M3dmodRestoreW(const MIL_STRING& FileName, MIL_ID SysId, MIL_INT64 ControlFlag, MIL_ID* Context3dmodIdPtr)
   {
   return M3dmodRestoreW(FileName.c_str(), SysId, ControlFlag, Context3dmodIdPtr);
   }

#else // M_MIL_UNICODE_API
inline void MFTYPE M3dmodSaveA(const MIL_STRING& FileName, MIL_ID Context3dmodId, MIL_INT64 ControlFlag)
   {
   return M3dmodSaveA(FileName.c_str(), Context3dmodId, ControlFlag);
   }

inline MIL_ID MFTYPE M3dmodRestoreA(const MIL_STRING& FileName, MIL_ID SysId, MIL_INT64 ControlFlag, MIL_ID* Context3dmodIdPtr)
   {
   return M3dmodRestoreA(FileName.c_str(), SysId, ControlFlag, Context3dmodIdPtr);
   }

#endif /* M_MIL_UNICODE_API*/

#else // M_MIL_USE_UNICODE
inline void MFTYPE M3dmodSave(const MIL_STRING& FileName, MIL_ID ContextOrResult3dmodId, MIL_INT64 ControlFlag)
   {
   return M3dmodSave(FileName.c_str(), ContextOrResult3dmodId, ControlFlag);
   }

inline MIL_ID MFTYPE M3dmodRestore(const MIL_STRING& FileName, MIL_ID SysId, MIL_INT64 ControlFlag, MIL_ID* Context3dmodIdPtr)
   {
   return M3dmodRestore(FileName.c_str(), SysId, ControlFlag, Context3dmodIdPtr);
   }

#endif /* M_MIL_USE_UNICODE */

#if M_MIL_USE_SAFE_TYPE

#if M_MIL_UNICODE_API

inline MIL_DOUBLE MFTYPE M3dmodGetResultSafeType(MIL_ID Result3dmodId, MIL_INT64 ResultIndex, MIL_INT64 ResultType, MIL_STRING& ResultArrayPtr)
   {
#if MIL_COMPILE_VERSION >= MIL_COMPILE_TRUNK_VERSION && M_MIL_USE_SAFE_TYPE
   if((ResultType & M_CLIENT_ENCODING) != M_CLIENT_ENCODING)
      {
      SafeTypeError(MIL_TEXT("M3dmodGetResult: Result Type not supported with MIL_STRING."));
      }
#endif

   MIL_INT InternalStringSize = 0;

   M3dmodGetResult(Result3dmodId, ResultIndex, (ResultType & (~M_HLVLDATATYPE_MASK)) + M_STRING_SIZE + M_TYPE_MIL_INT, &InternalStringSize);

   if(InternalStringSize > 0)
      {
      if(ResultArrayPtr.size() < (MIL_UINT)InternalStringSize)
         {
         ResultArrayPtr.resize((MIL_UINT)InternalStringSize);
         }
      }

   M3dmodGetResult(Result3dmodId, ResultIndex, ResultType, &ResultArrayPtr[0]);
   return 0.0;
   }
#endif /* M_MIL_UNICODE_API */
#else
//M3dmodGetResult is only defined in UNICODE
#if M_MIL_UNICODE_API
inline MIL_DOUBLE MFTYPE M3dmodGetResult(MIL_ID Result3dmodId,MIL_INT64 Index, MIL_INT64 ResultType, MIL_STRING   &ResultArrayPtr)
   {

   MIL_INT InternalStringSize = 0;

   //Inquire the byte content
   M3dmodGetResult(Result3dmodId, Index, (ResultType & (~M_HLVLDATATYPE_MASK)) + M_STRING_SIZE + M_TYPE_MIL_INT, &InternalStringSize);

   if(InternalStringSize > 0)
      {
      ResultArrayPtr.assign(InternalStringSize, MIL_TEXT('\0'));
      M3dmodGetResult(Result3dmodId, Index, ResultType, &ResultArrayPtr[0]);
      ResultArrayPtr.resize(InternalStringSize);
      }
   return 0.0;
   }

#endif
#endif
#endif /* M_MIL_USE_STRING*/

////////////////////////////////////////////////////////////////////////////////
// MIL_UNIQUE_ID support

#if M_MIL_USE_MIL_UNIQUE_ID

#if M_MIL_USE_SAFE_TYPE
template <> inline bool MilIsCorrectObjectType<&M3dmodFree>(MIL_INT64 ObjectType)
   {
   return (ObjectType & ~M_USER_DEFINE_LOW_ATTRIBUTE) == M_3DMOD_OBJECT;
   }
#endif

typedef MIL_UNIQUE_ID<&M3dmodFree> MIL_UNIQUE_3DMOD_ID;

#if M_MIL_USE_MOVE_SEMANTICS

inline MIL_UNIQUE_3DMOD_ID M3dmodAlloc(MIL_ID SysId, MIL_INT64 ObjectType, MIL_INT64 InitFlag, MIL_UNIQUE_ID_TAG)
   {
   return MIL_UNIQUE_3DMOD_ID(M3dmodAlloc(SysId, ObjectType, InitFlag, M_NULL));
   }
inline MIL_UNIQUE_3DMOD_ID M3dmodAllocResult(MIL_ID SysId, MIL_INT64 ResultType, MIL_INT64 ControlFlag, MIL_UNIQUE_ID_TAG)
   {
   return MIL_UNIQUE_3DMOD_ID(M3dmodAllocResult(SysId, ResultType, ControlFlag, M_NULL));
   }
inline MIL_UNIQUE_3DMOD_ID M3dmodRestore(MIL_CONST_TEXT_PTR FileName, MIL_ID SysId, MIL_INT64 ControlFlag, MIL_UNIQUE_ID_TAG)
   {
   return MIL_UNIQUE_3DMOD_ID(M3dmodRestore(FileName, SysId, ControlFlag, M_NULL));
   }
#if M_MIL_USE_STRING
inline MIL_UNIQUE_3DMOD_ID M3dmodRestore(const MIL_STRING& FileName, MIL_ID SysId, MIL_INT64 ControlFlag, MIL_UNIQUE_ID_TAG)
   {
   return MIL_UNIQUE_3DMOD_ID(M3dmodRestore(FileName.c_str(), SysId, ControlFlag, M_NULL));
   }
#endif // M_MIL_USE_STRING
template <MilFreeFuncType FreeFunc> inline void M3dmodFree(const MIL_UNIQUE_ID<FreeFunc>&) = delete;

inline void M3dmodStream(MilStreamParam       MemPtrOrFileName,
                         MIL_ID               SysId,
                         MIL_INT64            Operation,
                         MIL_INT64            StreamType,
                         MIL_DOUBLE           Version,
                         MIL_INT64            ControlFlag,
                         MIL_UNIQUE_3DMOD_ID* Context3dmodIdPtr,
                         MIL_INT*             SizeByteVarPtr)
   {
   MxxxStreamForMilUniqueId(MemPtrOrFileName, SysId, Operation, StreamType, Version, ControlFlag, Context3dmodIdPtr, SizeByteVarPtr, M3dmodStream);
   }

#endif // M_MIL_USE_MOVE_SEMANTICS
#endif // M_MIL_USE_MIL_UNIQUE_ID

// End of MIL_UNIQUE_ID support
////////////////////////////////////////////////////////////////////////////////

#endif // !M_MIL_LITE
#endif // __MIL_3DMOD_H__
