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

#ifndef __MIL_3DMET_H__
#define __MIL_3DMET_H__


#if !defined(__MIL3DGEO_H__)
#include <mildyn/mil3dgeo.h>
#endif

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


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

//==============================================================================
// M3dmetAlloc ContextTypes
#define M_STATISTICS_CONTEXT                          16L   // already defined in milim.h
#define M_FIT_CONTEXT                                 3646L

#define M_VOLUME_CONTEXT                              5788L //
#define M_DRAW_3D_CONTEXT                             3815  // already defined in milcal.h

//==============================================================================   
// Indexing, used in other M3dmet functions (M3dmetInquire(), M3dmetControl(), ...)
#define M_DEFAULT                               0x10000000L // already defined
#define M_CONTEXT                               0x08000000L // already defined
#define M_GENERAL                               0x20000000L // already defined
#define M_ALL                                   0x40000000L // already defined

#define M_ANY                                   0x11000000L // already defined

#define M_MODIFICATION_COUNT                          5010L // already defined

//==============================================================================
#define M_ALLOCATION_FAILURE_REAL_TEST_FLAG            971L // also in milblob.h, milstr.h

//==============================================================================
//M3dmetDistance
#define M_DISTANCE_TO_CENTER                          2983L 
#define M_DISTANCE_TO_CENTER_SQUARED                  2984L
#define M_DISTANCE_TO_CENTER_AXIS                     3017L 
#define M_DISTANCE_TO_CENTER_AXIS_SQUARED             3034L 
#define M_ABSOLUTE_DISTANCE_Z_TO_SURFACE              2985L 
#define M_ABSOLUTE_DISTANCE_TO_SURFACE                2986L 
#define M_SIGNED_DISTANCE_Z_TO_SURFACE                2987L 
#define M_SIGNED_DISTANCE_TO_SURFACE                  2988L 
#define M_DISTANCE_TO_NEAREST_NEIGHBOR                3444  // already defined in mil3dim.h
#define M_DISTANCE_TO_MESH                            3543L
#define M_MANHATTAN_DISTANCE_TO_SURFACE               3736L
#define M_DISTANCE_TO_LINE                            3934L
#define M_DISTANCE_TO_LINE_SQUARED                    3935L
#define M_DISTANCE_TO_POINT                           4749L
#define M_DISTANCE_TO_POINT_SQUARED                   4751L

//M3dmetFit
// Context
#define M_FIT_ITERATIONS_MAX                           104L // already defined in milmetrol.h
#define M_RMS_ERROR_THRESHOLD                         3565  // already defined in mil3dreg.h
#define M_INLIER_AMOUNT_THRESHOLD                     3599L

#define M_ESTIMATION_MODE                             3600L
#define M_RANDOM_SAMPLING                             3601L
#define M_NO_SAMPLING                                 3602L
#define M_FROM_GEOMETRY                               3603L

#define M_RANDOM_SAMPLING_CONFIDENCE                  3604L
#define M_RANDOM_SAMPLING_NUMBER_OF_TEST_POINTS       3605L
#define M_EXPECTED_OUTLIER_PERCENTAGE                 3606L

#define M_AUTO_VALUE                                  MAKE_INT64(0x0000000100000000)   // already defined in milim.h

//M3dmetCopy
#define M_ESTIMATE_GEOMETRY                           3607L

// Result
#define M_SUCCESS                               0x00000000L // Already defined in milreg.h, milcolor.h
#define M_NOT_INITIALIZED                                3L // Already defined in milcal.h
#define M_ALL_POINTS_COPLANAR                         4742L
#define M_NOT_ENOUGH_VALID_DATA                       1336L 
#define M_BAD_ESTIMATE                                3616L
#define M_MATHEMATICAL_EXCEPTION                         8L
#define M_ALL_POINTS_COLLINEAR                        1337L

#define M_NUMBER_OF_POINTS_TOTAL                      3485  // already defined in mil3dim.h
#define M_NUMBER_OF_POINTS_VALID                      3440  // already defined in mil3dim.h
#define M_NUMBER_OF_POINTS_MISSING_DATA               3484  // already defined in mil3dim.h
#define M_NUMBER_OF_POINTS_INLIERS                    3557L
#define M_NUMBER_OF_POINTS_OUTLIERS                   3558L
#define M_FIT_RMS_ERROR                               1333L // already defined in mil3dmap.h
#define M_RESULT_IMAGE_SIZE_X                         5226L
#define M_RESULT_IMAGE_SIZE_Y                         5227L
#define M_RESULT_ELEMENT_IMAGE_SIZE_X                 5876L
#define M_RESULT_ELEMENT_IMAGE_SIZE_Y                 5877L
#define M_OUTLIER_DISTANCE                            5766L

//M3dmetCopyResult
#define M_FITTED_GEOMETRY                             3559L
#define M_FITTED_GEOMETRY_INFINITE                    4841L
#define M_INLIER_MASK                                 3590L
#define M_OUTLIER_MASK                                3995L
#define M_FIXTURING_MATRIX                            3878L
#define M_VOLUME_SOURCE_POINTS_MASK                   5789L 
#define M_VOLUME_SOURCE_POINTS_STATUS_IMAGE           5790L 
#define M_VOLUME_REFERENCE_CONTAINER                  5795L 
#define M_VOLUME_REFERENCE_DEPTH_MAP                  5796L

#define M_VOLUME_ELEMENT_INDEX_IMAGE                  5878L
#define M_VOLUME_ELEMENT_MASK                         5879L
#define M_VOLUME_ELEMENT_STATUS_IMAGE                 5880L

//M3dmetStat
#define M_STAT_MIN                                    2502  // already defined in milim.h
#define M_STAT_MAX                                    2503  // already defined in milim.h
#define M_STAT_MIN_ABS                                2504
#define M_STAT_MAX_ABS                                2505
#define M_STAT_SUM_ABS                                2506
#define M_STAT_SUM_OF_SQUARES                         2507
#define M_STAT_SUM                                    2508
#define M_STAT_MEAN                                   2509
#define M_STAT_STANDARD_DEVIATION                     2510  // already defined in milim.h
#define M_STAT_NUMBER                                 1009L // already defined in milim.h
#define M_STAT_RMS                                    3562L
#define M_STAT_MEAN_ABS                               4843L
#define M_IN_RANGE                                      1L          // Already defined in    milblob.h, mil.h, miledge.h
#define M_GREATER                                       5L          // Already defined in    milblob.h, mil.h, miledge.h
#define M_LESS                                          6L          // Already defined in    milblob.h, mil.h, miledge.h
#define M_GREATER_OR_EQUAL                              7L          // Already defined in    milblob.h, mil.h, miledge.h
#define M_LESS_OR_EQUAL                                 8L          // Already defined in    milblob.h, mil.h, miledge.h
//M3dmetStat pseudo ids
#define M_STAT_CONTEXT_MIN                            (M_STAT_MIN | M_PSEUDO_ID)
#define M_STAT_CONTEXT_MAX                            (M_STAT_MAX | M_PSEUDO_ID)
#define M_STAT_CONTEXT_MIN_ABS                        (M_STAT_MIN_ABS | M_PSEUDO_ID)
#define M_STAT_CONTEXT_MAX_ABS                        (M_STAT_MAX_ABS | M_PSEUDO_ID)
#define M_STAT_CONTEXT_SUM_ABS                        (M_STAT_SUM_ABS | M_PSEUDO_ID)
#define M_STAT_CONTEXT_SUM_OF_SQUARES                 (M_STAT_SUM_OF_SQUARES | M_PSEUDO_ID)
#define M_STAT_CONTEXT_SUM                            (M_STAT_SUM | M_PSEUDO_ID)
#define M_STAT_CONTEXT_MEAN                           (M_STAT_MEAN | M_PSEUDO_ID)
#define M_STAT_CONTEXT_STANDARD_DEVIATION             (M_STAT_STANDARD_DEVIATION | M_PSEUDO_ID)
#define M_STAT_CONTEXT_NUMBER                         (M_STAT_NUMBER | M_PSEUDO_ID)
#define M_STAT_CONTEXT_RMS                            (M_STAT_RMS | M_PSEUDO_ID)
#define M_STAT_CONTEXT_MEAN_ABS                       (M_STAT_MEAN_ABS | M_PSEUDO_ID)

//M3dmetVolume
#define M_VOLUME_MODE                                 5798L

#define M_ABOVE                                       4076L // already defined in milmetrol.h
#define M_UNDER                                       4077L // already defined in milmetrol.h
#define M_TOTAL                                       3627L
#define M_DIFFERENCE                                  3628L

#define M_VOLUME_STATUS                               5906L
#define M_WARNING_GAPS                                3629L
#define M_FAIL_GAPS                                   3676L
#define M_FAIL_INVALID_MESH                           3675L

#define M_VOLUME_NB_ELEMENTS                          5800L
#define M_VOLUME_NB_POSITIVE_ELEMENTS                 5801L
#define M_VOLUME_NB_NEGATIVE_ELEMENTS                 5802L
#define M_VOLUME_NB_UNUSED_ELEMENTS                   5803L
#define M_VOLUME_REFERENCE_TYPE                       5808L

#define M_SAVE_VOLUME_INFO                            5809L

// Result control
#define M_VOLUME_OUTPUT_MODE                          5810L

//M3dmetVolumeEx pseudo ids                    
#define M_VOLUME_CONTEXT_TOTAL                        (M_TOTAL | M_PSEUDO_ID)     
#define M_VOLUME_CONTEXT_ABOVE                        (M_ABOVE | M_PSEUDO_ID)     
#define M_VOLUME_CONTEXT_UNDER                        (M_UNDER | M_PSEUDO_ID)     
#define M_VOLUME_CONTEXT_DIFFERENCE                   (M_DIFFERENCE | M_PSEUDO_ID)

//M3dmetFeature
#define M_ANGLE                                 0x00000800L // already defined in mil.h
#define M_PARALLELISM                                    4L // already defined in milmetrol.h
#define M_PERPENDICULARITY                               1L // already defined in milmetrol.h
#define M_INTERSECTION                              0x0022L // already defined in milmetrol.h
#define M_PROJECTION                                  3417  // already defined in mil3dgeo.h
#define M_INTERPOLATION                               4774L
#define M_SHORTEST_LINE                               4776L
#define M_FARTHEST_POINT                              4777L
#define M_RAY_CAST                                    4778L
#define M_NORMAL_AT_POSITION                          4779L
#define M_POINT_ON_LINE                               4780L
#define M_POINT_ON_LINE_CLIPPED                       4781L
#define M_IS_INSIDE                                   4782L
#define M_PARTIALLY_INSIDE                            4783L
#define M_ANGLE_TO_EDGE_CASE                          4784L
#define M_ORTHOGONALIZE                               4849L
#define M_EXTRUSION_CENTER                           5832L
#define M_EXTRUSION_BORDER                          5833L
#define M_EXTRUSION_STATUS                            5834L
#define M_CLOSEST_POINT                                 12L // already defined in milbead.h
#define M_BOUNDING_BOX                          0x00000003L // already defined in mil3dim.h
#define M_CLIP                                      0x0010L // already defined in milcal.h
#define M_DISTANCE                              0x00080000L // already defined in milim.h
#define M_OUTSIDE                                        0L // already defined in mil.h
#define M_INSIDE                                         1L // already defined in mil.h
#define M_OVERLAP                                     1966L // already defined in mil3dreg.h
#define M_UNION                                       3797L // already defined in milclass.h
#define M_CALCULATED_OBJECT_TYPE                      5525L
#define M_CALCULATED_OBJECT_FLAG                      4785L
#define M_DISTANCE_ALONG_LINE_FLAG                    4793L
#define M_CALCULATED_OBJECT(N)                 (M_CALCULATED_OBJECT_FLAG + (N))
#define M_DISTANCE_ALONG_LINE(N)               (M_DISTANCE_ALONG_LINE_FLAG + (N))

//M3dgeo
#define M_GEOMETRY_TYPE                               1321L // Already define in mil3dgeo
#define M_GEOMETRY                                    1306L // Already define in mil3dgeo
#define M_PLANE                                       1353L // Already defined in mil3dgeo
#define M_SPHERE                                      2931L // Already defined in mil3dgeo
#define M_CYLINDER                                    3656  // Already defined in mil3dgeo
#define M_BOX                                        0x101L // Already defined in milblob.h
#define M_LINE                                  0x00000080L // Already defined
#define M_POINT                                          1L // Already defined in mil3dgeo
//Sphere
#define M_CENTER_X                                       4L // also in mil.h
#define M_CENTER_Y                                       5L
#define M_CENTER_Z                                    3400
#define M_RADIUS                                0x00000040L       // Already defined in MilMod.h
//Plane
#define M_COEFFICIENT_A                              3401 // Already defined in mil3dgeo
#define M_COEFFICIENT_B                              3402 // Already defined in mil3dgeo
#define M_COEFFICIENT_C                              3403
#define M_COEFFICIENT_D                              3404
#define M_NORMAL_X                                   3537
#define M_NORMAL_Y                                   3538
#define M_NORMAL_Z                                   3539
#define M_CLOSEST_TO_ORIGIN_X                        3540
#define M_CLOSEST_TO_ORIGIN_Y                        3541
#define M_CLOSEST_TO_ORIGIN_Z                        3542
//Cylinder
#define M_TWO_POINTS                                 3657
#define M_START_POINT_X                              3658
#define M_START_POINT_Y                              3659                               
#define M_START_POINT_Z                              3660
#define M_END_POINT_X                                3661
#define M_END_POINT_Y                                3662
#define M_END_POINT_Z                                3663
#define M_AXIS_X                                     3664
#define M_AXIS_Y                                     3665
#define M_AXIS_Z                                     3666
#define M_FINITE                                     3016L
#define M_INFINITE                                     -1L // Also defined in Mil.h

//==============================================================================
// M3dmetControl / M3dmetInquire
// Context 
#define M_ROOT_NODE                                      0  // already defined in mil3dgra.h
#define M_ENABLE                                     -9997L // also in mil.h
#define M_DISABLE                                    -9999L // also in mil.h

#define M_AUTO                                         444L // also in mil.h
#define M_USER_DEFINED                                  21L // also in mil.h

#define M_SIZE_X                                      1536L // also in mil.h
#define M_SIZE_Y                                      1537L // also in mil.h
#define M_SIZE_Z                                      1538L // also in mil.h

//==============================================================================
// M3dmetInquire 
// Context
#define M_INVALID                                        -1 // also in mil.h

//==============================================================================
// M3dmetControlDraw/M3dmetInquireDraw
// Draw context
#define M_ROOT_NODE                                      0 // already defined in mil3dgra.h
#define M_GLOBAL_DRAW_SETTINGS                   M_CONTEXT
#define M_DRAW_VOLUME_ELEMENTS                 0x00004000L 
#define M_DRAW_VOLUME_POSITIVE_ELEMENTS        0x00008000L 
#define M_DRAW_VOLUME_NEGATIVE_ELEMENTS        0x00010000L 

#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_OPACITY                                    4728  // already defined in mil3dgra.h
#define M_APPEARANCE                                 4679  // already defined in mil3dgra.h
#define M_COLOR                                0x00000100L // already defined in mil3dgra.h
#define M_VOLUME_ELEMENT_APPEARANCE                  5811L
#define M_VOLUME_ELEMENT_INDEX                       5812L
#define M_SURFACE                                    1021L // already defined in mil.h
#define M_VOLUME                                     1360L
#define M_SURFACE_REFERENCE                          5887L
#define M_SURFACE_SOURCE                             5889L


//==============================================================================
// M3dmetAllocResult ResultTypes

//==============================================================================
// M3dmetGetResult ResultTypes
#define M_STATISTICS_RESULT                          MAKE_INT64(0x0001000000000000) // also in mil.h
#define M_FIT_RESULT                                 3645L
#define M_CALCULATE_RESULT                           5011L

// General
#define M_STATUS                                0x00008002L // already defined in milbead
#define M_COMPLETE                              0x00000000L // already defined in mil3dreg
#define M_INTERNAL_ERROR                                 5L // already defined in milreg.h

//==============================================================================
// Other defines

//==============================================================================
// CAPI function prototypes
MIL_ID MFTYPE M3dmetAlloc(MIL_ID    SysId,
                                            MIL_INT64 ContextType,
                                            MIL_INT64 ControlFlag,
                                            MIL_ID*   Context3dmetIdPtr);

MIL_ID MFTYPE M3dmetAllocResult(MIL_ID    SysId,
                                                  MIL_INT64 ResultType,
                                                  MIL_INT64 ControlFlag,
                                                  MIL_ID*   Result3dmetIdPtr);

void MFTYPE M3dmetFree(MIL_ID ContextOrResult3dmetId);


  
//#if M_MIL_USE_64BIT
   // Prototypes for 64 bits OSs
void MFTYPE M3dmetControlInt64(MIL_ID     ContextOrResult3dmetId,
                               MIL_INT64  ControlType,
                               MIL_INT64  ControlValue);
 void MFTYPE M3dmetControlDouble(MIL_ID     ContextOrResult3dmetId,
                                 MIL_INT64  ControlType,
                                 MIL_DOUBLE ControlValue);

 MIL_INT64 MFTYPE M3dmetInquire(MIL_ID    ContextOrResult3dmetId,
                                MIL_INT64 InquireType,
                                void*     UserVarPtr);

 MIL_DOUBLE MFTYPE M3dmetGetResult(MIL_ID    Result3dmetId,
                                   MIL_INT64 ResultType,
                                   void*     ResultArrayPtr);

 void MFTYPE  M3dmetDistance(MIL_ID     SrcContainerOrImageBufId,
                             MIL_ID     RefMilObjectId,
                             MIL_ID     DstImageBufId,
                             MIL_INT64  DistanceType,
                             MIL_DOUBLE Param,
                             MIL_INT64  ControlFlag);

 void MFTYPE  M3dmetFit(MIL_ID     Context3dmetId,
                        MIL_ID     SrcContainerOrImageBufId,
                        MIL_INT    GeometryType,
                        MIL_ID     Result3dmetOr3dgeoId,
                        MIL_DOUBLE OutlierDistance,
                        MIL_INT64  ControlFlag);

 void MFTYPE  M3dmetCopyResult(MIL_ID    SrcResult3dmetId,
                               MIL_ID    DstMilObjectId,
                               MIL_INT64 CopyType,
                               MIL_INT64 ControlFlag);


 void MFTYPE   M3dmetStat(MIL_ID     StatContext3dmetId,
                          MIL_ID     SrcContainerOrImageBufId,
                          MIL_ID     RefMilObjectId,
                          MIL_ID     StatResult3dmetId,
                          MIL_INT64  DistanceType,
                          MIL_INT64  Condition,
                          MIL_DOUBLE CondLow,
                          MIL_DOUBLE CondHigh,
                          MIL_INT64  ControlFlag);

 void MFTYPE M3dmetCopy(MIL_ID    SrcMilObjectId,
                        MIL_ID    DstMilObjectId,
                        MIL_INT64 CopyType,
                        MIL_INT64 ControlFlag);

 void MFTYPE M3dmetVolumeEx(MIL_ID     Volume3dmetContextId,
                            MIL_ID     SrcContainerOrImageBufId,
                            MIL_ID     Reference3dgeoOrImageBufId,
                            MIL_ID     Calculate3dmetResultId,
                            MIL_INT64  ControlFlag);

 MIL_DOUBLE MFTYPE M3dmetVolume(MIL_ID      SrcContainerOrImageBufId,
                                MIL_ID      Reference3dgeoOrImageBufId,
                                MIL_INT64   Options,
                                MIL_INT64   ControlFlag,
                                MIL_DOUBLE* VolumePtr,
                                MIL_INT64*  StatusPtr);

 void MFTYPE M3dmetControlDrawInt64(MIL_ID     DrawContext3dmetId,
                                    MIL_INT64  Operation,
                                    MIL_INT64  ControlType,
                                    MIL_INT64  ControlValue);

 void MFTYPE M3dmetControlDrawDouble(MIL_ID     DrawContext3dmetId,
                                     MIL_INT64  Operation,
                                     MIL_INT64  ControlType,
                                     MIL_DOUBLE ControlValue);

 MIL_INT64 MFTYPE M3dmetInquireDraw(MIL_ID     DrawContext3dmetId,
                                    MIL_INT64  Operation,
                                    MIL_INT64  InquireType,
                                    void*     UserVarPtr);

 MIL_INT64 MFTYPE M3dmetDraw3d(MIL_ID    OperationDraw3dContext3dmetId,
                               MIL_ID    SrcResult3dmetId,
                               MIL_ID    DstList3dgraId,
                               MIL_INT64 DstParentLabel,
                               MIL_INT64 ControlFlag);
  
 void MFTYPE M3dmetFeatureEx(MIL_ID     Feature3dmetContextId,
                             MIL_ID     Src1GeometryOrMatrix3dgeoId,
                             MIL_ID     Src2GeometryOrMatrix3dgeoId,
                             MIL_ID     Src3Geometry3dgeoId,
                             MIL_ID     Result3dmetOr3dgeoId,
                             MIL_INT64  Operation,
                             MIL_DOUBLE Param,
                             MIL_INT64  ControlFlag);

 MIL_DOUBLE MFTYPE M3dmetFeature(MIL_ID      Src1GeometryOrMatrix3dgeoId,
                                 MIL_ID      Src2GeometryOrMatrix3dgeoId,
                                 MIL_INT64   Operation,
                                 MIL_DOUBLE  Param,
                                 MIL_DOUBLE* ResultPtr);

#if M_MIL_USE_UNICODE
   void MFTYPE M3dmetSaveA(MIL_CONST_TEXTA_PTR FileName,
                           MIL_ID      Context3dmetId,
                           MIL_INT64   ControlFlag);

   MIL_ID MFTYPE M3dmetRestoreA(MIL_CONST_TEXTA_PTR FileName,
                                MIL_ID      SysId,
                                MIL_INT64   ControlFlag,
                                MIL_ID*     Context3dmetIdPtr);

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



   void MFTYPE M3dmetSaveW(MIL_CONST_TEXTW_PTR FileName,
                           MIL_ID              Context3dmetId,
                           MIL_INT64           ControlFlag);

   MIL_ID MFTYPE M3dmetRestoreW(MIL_CONST_TEXTW_PTR FileName,
                                MIL_ID              SysId,
                                MIL_INT64           ControlFlag,
                                MIL_ID*             Context3dmetIdPtr);

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

#if M_MIL_UNICODE_API
#define M3dmetSave               M3dmetSaveW
#define M3dmetRestore            M3dmetRestoreW
#define M3dmetStream             M3dmetStreamW
#else
#define M3dmetSave               M3dmetSaveA
#define M3dmetRestore            M3dmetRestoreA
#define M3dmetStream             M3dmetStreamA
#endif //M_MIL_UNICODE_API

#else

 void MFTYPE   M3dmetSave(MIL_CONST_TEXT_PTR FileName,
                          MIL_ID             Context3dmetId,
                          MIL_INT64          ControlFlag);

 MIL_ID MFTYPE M3dmetRestore(MIL_CONST_TEXT_PTR FileName,
                             MIL_ID             SysId,
                             MIL_INT64          ControlFlag,
                             MIL_ID*            Context3dmetIdPtr);

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

#endif //M_MIL_USE_UNICODE

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

////////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
   inline void MFTYPE M3dmetStreamCpp(MilStreamParam MemPtrOrFileName,
                                      MIL_ID         SysId,
                                      MIL_INT64      Operation,
                                      MIL_INT64      StreamType,
                                      MIL_DOUBLE     Version,
                                      MIL_INT64      ControlFlag,
                                      MIL_ID*        Context3dmetIdPtr,
                                      MIL_INT*       SizeByteVarPtr)
   {
   M3dmetStream(MemPtrOrFileName.m_Param, SysId, Operation, StreamType, Version, ControlFlag, Context3dmetIdPtr, SizeByteVarPtr);
   }

#undef  M3dmetStream
#define M3dmetStream M3dmetStreamCpp

#endif // __cplusplus

//////////////////////////////////////////////////////////////
// Overload or define to support Old API.
//////////////////////////////////////////////////////////////

// New API call so redirect it to the good entry point
#define M3dmetCalculate          M3dmetFeatureEx
#define M3dmetCalculateScalar    M3dmetFeature

#ifdef __cplusplus


// Support Old API through inline in C++
inline void M3dmetCalculate(MIL_ID     Src1GeometryOrMatrix3dgeoId,
                            MIL_ID     Src2GeometryOrMatrix3dgeoId,
                            MIL_ID     Src3Geometry3dgeoId,
                            MIL_ID     Result3dmetOr3dgeoId,
                            MIL_INT64  Operation,
                            MIL_DOUBLE Param,
                            MIL_INT64  ControlFlag)
   {
   M3dmetFeatureEx(M_DEFAULT,
                   Src1GeometryOrMatrix3dgeoId,
                   Src2GeometryOrMatrix3dgeoId,
                   Src3Geometry3dgeoId,
                   Result3dmetOr3dgeoId,
                   Operation,
                   Param,
                   ControlFlag);
   }
#endif

#ifdef __cplusplus
#if M_MIL_USE_SAFE_TYPE

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

// ----------------------------------------------------------
// M3dmetInquire

inline MIL_INT64 MFTYPE M3dmetInquireSafeType(MIL_ID ContextOrResult3dmetId, 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)))
      {
      M3dmetInquire(ContextOrResult3dmetId, InquireType | M_DEFAULT_DATA_TYPE, &RequiredParamType);
      }
   if(!MfuncPointerIsCompatible(RequiredParamType, UserVarPtr.Type, InquireType))
      {
      SafeTypeError(MIL_TEXT("M3dmetInquire"));
      }
   return M3dmetInquire(ContextOrResult3dmetId, InquireType, UserVarPtr.Ptr);
   }

inline MIL_INT64 MFTYPE M3dmetInquireUnsafe(MIL_ID ContextOrResult3dmetId, MIL_INT64 InquireType, void* UserVarPtr)
   {
   return M3dmetInquire(ContextOrResult3dmetId, InquireType, UserVarPtr);
   }

inline MIL_INT64 MFTYPE M3dmetInquireDrawSafeType(MIL_ID DrawContext3dmetId, 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)))
      {
      M3dmetInquireDraw(DrawContext3dmetId, Operation, InquireType | M_DEFAULT_DATA_TYPE, &RequiredParamType);
      }
   if(!MfuncPointerIsCompatible(RequiredParamType, UserVarPtr.Type, InquireType))
      {
      SafeTypeError(MIL_TEXT("M3dblobInquireDraw"));
      }
   return M3dmetInquireDraw(DrawContext3dmetId, Operation, InquireType, UserVarPtr.Ptr);
   }

inline MIL_INT64 MFTYPE M3dmetInquireDrawUnsafe(MIL_ID DrawContext3dblobId, MIL_INT64 Operation, MIL_INT64 InquireType, void* UserVarPtr)
   {
   return M3dmetInquireDraw(DrawContext3dblobId, Operation, InquireType, UserVarPtr);
   }

#define M3dmetInquire           M3dmetInquireSafeType
#define M3dmetInquireDraw       M3dmetInquireDrawSafeType

#else // #if M_MIL_USE_SAFE_TYPE
#define M3dmetInquireUnsafe     M3dmetInquire
#define M3dmetInquireDrawUnsafe M3dmetInquireDraw
#endif // #if M_MIL_USE_SAFE_TYPE

#if M_MIL_USE_SAFE_TYPE
// -------------------------------------------------------------------------
// M3dmetGetResult safe type definitions
// 
inline MIL_DOUBLE MFTYPE M3dmetGetResultSafeType(MIL_ID Result3dmetId, 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)))
      {
      M3dmetGetResult(Result3dmetId, ResultType | M_DEFAULT_DATA_TYPE, &RequiredParamType);
      }
   if(!MfuncPointerIsCompatible(RequiredParamType, ResultArrayPtr.Type, ResultType))
      {
      SafeTypeError(MIL_TEXT("M3dmetGetResult"));
      }
   return M3dmetGetResult(Result3dmetId, ResultType, ResultArrayPtr.Ptr);
   }

inline MIL_DOUBLE MFTYPE M3dmetGetResultUnsafe(MIL_ID Result3dmetId, MIL_INT64 ResultType, void* ResultArrayPtr)
   {
   return M3dmetGetResult(Result3dmetId, ResultType, ResultArrayPtr);
   }

#define M3dmetGetResult            M3dmetGetResultSafeType

#else // #if M_MIL_USE_SAFE_TYPE
#define M3dmetGetResultUnsafe            M3dmetGetResult
#endif // #if M_MIL_USE_SAFE_TYPE

#endif // __cplusplus

//#if M_MIL_USE_64BIT
#ifdef __cplusplus

//=========================================================
// M3dmetControl function overloads when compiling c++ files
//=========================================================
template <typename T>
inline void M3dmetControl(MIL_ID ContextOrResult3dmetId, MIL_INT64 ControlType, T ControlValue)
   {
   M3dmetControlInt64(ContextOrResult3dmetId, ControlType, ControlValue);
   }

inline void M3dmetControl(MIL_ID ContextOrResult3dmetId, MIL_INT64 ControlType, float ControlValue)
   {
   M3dmetControlDouble(ContextOrResult3dmetId, ControlType, ControlValue);
   }

inline void M3dmetControl(MIL_ID ContextOrResult3dmetId, MIL_INT64 ControlType, MIL_DOUBLE ControlValue)
   {
   M3dmetControlDouble(ContextOrResult3dmetId, ControlType, ControlValue);
   }

template <typename T>
inline void M3dmetControlDraw(MIL_ID DrawContext3dmetId, MIL_INT64 Operation, MIL_INT64 ControlType, T ControlValue)
   {
   M3dmetControlDrawInt64(DrawContext3dmetId, Operation, ControlType, ControlValue);
   }

inline void M3dmetControlDraw(MIL_ID DrawContext3dmetId, MIL_INT64 Operation, MIL_INT64 ControlType, float ControlValue)
   {
   M3dmetControlDrawDouble(DrawContext3dmetId, Operation, ControlType, ControlValue);
   }

inline void M3dmetControlDraw(MIL_ID DrawContext3dmetId, MIL_INT64 Operation, MIL_INT64 ControlType, MIL_DOUBLE ControlValue)
   {
   M3dmetControlDrawDouble(DrawContext3dmetId, Operation, ControlType, ControlValue);
   }

#else // __cplusplus
//=========================================================
// For C file, call the default function, i.e. Double one
//=========================================================
#define M3dmetControl            M3dmetControlDouble
#define M3dmetControlDraw        M3dmetControlDrawDouble
#endif // __cplusplus
//#endif // M_MIL_USE_64BIT

#if M_MIL_USE_STRING
/***************************************************************************/
/* 3dmet MODULE                                                              */
/***************************************************************************/
#if M_MIL_USE_UNICODE
#if M_MIL_UNICODE_API

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

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

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

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

#endif /* M_MIL_UNICODE_API*/

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

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

//inline void MFTYPE M3dmetStream(const MIL_STRING& MemPtrOrFileName, MIL_ID SysId, MIL_INT64 Operation, MIL_INT64 StreamType,
//                              MIL_DOUBLE Version, MIL_INT64 ControlFlag, MIL_ID* Context3dmetId, MIL_INT* SizeByteVarPtr)
//   {
//   M3dmetStream((MIL_TEXT_PTR)MemPtrOrFileName.c_str(), SysId, Operation, StreamType, Version, ControlFlag, Context3dmetId, SizeByteVarPtr);
//   }

#endif /* M_MIL_USE_UNICODE */

#if M_MIL_USE_SAFE_TYPE

#if M_MIL_UNICODE_API

inline MIL_DOUBLE MFTYPE M3dmetGetResultSafeType(MIL_ID Result3dmetId, 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("M3dmetGetResult"), MIL_TEXT(" Result Type not supported with MIL_STRING."));
      }
#endif

   MIL_INT InternalStringSize = 0;

   M3dmetGetResult(Result3dmetId, (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);
         }
      }

   M3dmetGetResult(Result3dmetId, ResultType, &ResultArrayPtr[0]);

   return 0.0;
   }
#endif /* M_MIL_UNICODE_API */
#else
//M3dmetGetResult is only defined in UNICODE
#if M_MIL_UNICODE_API
inline MIL_DOUBLE MFTYPE M3dmetGetResult(MIL_ID Result3dmetId, MIL_INT64 ResultType, MIL_STRING   &ResultArrayPtr)
   {
   MIL_INT InternalStringSize = 0;

   //Inquire the byte content
   M3dmetGetResult(Result3dmetId, (ResultType & (~M_HLVLDATATYPE_MASK)) + M_STRING_SIZE + M_TYPE_MIL_INT, &InternalStringSize);

   if(InternalStringSize > 0)
      {
      ResultArrayPtr.assign(InternalStringSize, MIL_TEXT('\0'));
      M3dmetGetResult(Result3dmetId, ResultType, &ResultArrayPtr[0]);
      ResultArrayPtr.resize(InternalStringSize);
      }

   return 0.0;
   }

#endif
#endif
#endif /* M_MIL_USE_STRING*/

#ifndef M_MIL_WARN_ON_DEPRECATED_MIL3DMET
#define M_MIL_WARN_ON_DEPRECATED_MIL3DMET 1
#endif
#if defined(M_MIL_WARN_ON_DEPRECATED_MIL3DMET) && M_MIL_WARN_ON_DEPRECATED_MIL3DMET
MIL_DEPRECATED(M3dmetCalculateScalar, 1060) // Use M3dmetFeature instead.
MIL_DEPRECATED(M3dmetCalculate, 1060)       // Use M3dmetFeatureEx instead.
#endif

// ----------------------------------------------------------
// Overload for std::vector.
#if defined(M_MIL_USE_VECTOR) && M_MIL_USE_VECTOR
// ----------------------------------------------------------
template <typename UserType>
inline MIL_INT64 MFTYPE M3dmetInquire(MIL_ID ContextOrResult3dmetId, 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("M3dmetInquire"), 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;
   M3dmetInquire(ContextOrResult3dmetId, M_STRIP_HLVLDATATYPE(InquireType) + M_NB_ELEMENTS + M_TYPE_MIL_INT, &InternalNumberOfElementsForStdVector);

   UserVarPtr.resize(InternalNumberOfElementsForStdVector);

   if(InternalNumberOfElementsForStdVector > 0)
      {
      return M3dmetInquire(ContextOrResult3dmetId, InquireType, &UserVarPtr[0]);
      }
   return 0;
   }
template <typename UserType>
inline MIL_DOUBLE MFTYPE M3dmetGetResult(MIL_ID Result3dmetId, 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("M3dmetGetResult"), 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;
   M3dmetGetResult(Result3dmetId, M_STRIP_HLVLDATATYPE(ResultType) + M_NB_ELEMENTS + M_TYPE_MIL_INT, &InternalNumberOfElementsForStdVector);

   ResultArrayPtr.resize(InternalNumberOfElementsForStdVector);

   if(InternalNumberOfElementsForStdVector > 0)
      {
      M3dmetGetResult(Result3dmetId, ResultType, &ResultArrayPtr[0]);
      }
   return 0.0;
   }
// ----------------------------------------------------------
// Overloads for std::vector in M3dmetStream.
inline void MFTYPE M3dmetStream(std::vector<MIL_UINT8> &MemPtrOrFileName,
                                MIL_ID                 SysId,
                                MIL_INT64              Operation,
                                MIL_INT64              StreamType,
                                MIL_DOUBLE             Version,
                                MIL_INT64              ControlFlag,
                                MIL_ID*                Context3dmetIdPtr,
                                MIL_INT*               SizeByteVarPtr)
   {
   MxxxStreamForStdVector(MemPtrOrFileName,
                          SysId,
                          Operation,
                          StreamType,
                          Version,
                          ControlFlag,
                          Context3dmetIdPtr,
                          SizeByteVarPtr,
                          M3dmetStream);
   }
#endif // defined(M_MIL_USE_VECTOR) && M_MIL_USE_VECTOR
//==============================================================================
////////////////////////////////////////////////////////////////////////////////
// MIL_UNIQUE_ID support

#if M_MIL_USE_MIL_UNIQUE_ID

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

typedef MIL_UNIQUE_ID<&M3dmetFree> MIL_UNIQUE_3DMET_ID;

#if M_MIL_USE_MOVE_SEMANTICS

inline MIL_UNIQUE_3DMET_ID M3dmetAlloc(MIL_ID SysId, MIL_INT64 ObjectType, MIL_INT64 InitFlag, MIL_UNIQUE_ID_TAG)
   {
   return MIL_UNIQUE_3DMET_ID(M3dmetAlloc(SysId, ObjectType, InitFlag, M_NULL));
   }
inline MIL_UNIQUE_3DMET_ID M3dmetAllocResult(MIL_ID     SysId, MIL_INT64  ResultType, MIL_INT64  ControlFlag, MIL_UNIQUE_ID_TAG)
   {
   return MIL_UNIQUE_3DMET_ID(M3dmetAllocResult(SysId, ResultType, ControlFlag, M_NULL));
   }
inline MIL_UNIQUE_3DMET_ID M3dmetRestore(MIL_CONST_TEXT_PTR FileName, MIL_ID SysId, MIL_INT64 ControlFlag, MIL_UNIQUE_ID_TAG)
   {
   return MIL_UNIQUE_3DMET_ID(M3dmetRestore(FileName, SysId, ControlFlag, M_NULL));
   }
#if M_MIL_USE_STRING
inline MIL_UNIQUE_3DMET_ID M3dmetRestore(const MIL_STRING& FileName, MIL_ID SysId, MIL_INT64 ControlFlag, MIL_UNIQUE_ID_TAG)
   {
   return MIL_UNIQUE_3DMET_ID(M3dmetRestore(FileName.c_str(), SysId, ControlFlag, M_NULL));
   }
#endif // M_MIL_USE_STRING
template <MilFreeFuncType FreeFunc> inline void M3dmetFree(const MIL_UNIQUE_ID<FreeFunc>&) = delete;

inline void M3dmetStream(MilStreamParam       MemPtrOrFileName,
                         MIL_ID               SysId,
                         MIL_INT64            Operation,
                         MIL_INT64            StreamType,
                         MIL_DOUBLE           Version,
                         MIL_INT64            ControlFlag,
                         MIL_UNIQUE_3DMET_ID* Context3dmetIdPtr,
                         MIL_INT*             SizeByteVarPtr)
   {
   MxxxStreamForMilUniqueId(MemPtrOrFileName, SysId, Operation, StreamType, Version, ControlFlag, Context3dmetIdPtr, SizeByteVarPtr, M3dmetStream);
   }

#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_3DMET_H__
