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

#ifndef __MIL_3DREG_H__
#define __MIL_3DREG_H__

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

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

//==============================================================================
// M3dregAlloc ContextTypes
#define M_PAIRWISE_REGISTRATION_CONTEXT                3507
#define M_DRAW_3D_CONTEXT                              3815     // already defined in milcal.h
//==============================================================================   
// Indexing, used in other M3dreg functions (M3dregInquire(), M3dregControl(), ...)
#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_REGISTRATION_INDEX_FLAG               0x00200000L

#define M_REGISTRATION_INDEX_VALUE                    3534

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

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

//==============================================================================
// M3dregControl / M3dregInquire
// 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_MIN                                   0x02000000L // Already defined in    milmeas.h, mil.h, miledge.h
#define M_MAX                                   0x04000000L // also in mil.h
#define M_AVERAGE                               0x00000020L // also in milim.h
#define M_CENTER                                0x00000080L // already defined in milim.h
#define M_SAVE_PAIRS_INFO                             5549L

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

// Context
#define M_COMPUTATION_DIRECTION                        3587               
#define M_TO_REFERENCE                                 3588
#define M_FROM_REFERENCE                               3589
#define M_STOP_CALCULATE                               116L  // also in milblob.h
#define M_CENTROID                                     1956L // already defined in mil3dim
#define M_POINT_TO_POINT                               1957L                                     
#define M_POINT_TO_PLANE                               1958L
//==============================================================================
// M3dregInquire 
// Context
#define M_NUMBER_OF_REGISTRATION_ELEMENTS             2L //already defined in milreg.h
#define M_PREREGISTRATION_MODE                     3564
#define M_RMS_ERROR_THRESHOLD                      3565
#define M_RMS_ERROR_RELATIVE_THRESHOLD             3566
#define M_ITERATION_INDEX                          3568
#define M_ERROR_MINIMIZATION_METRIC                1946L
#define M_OVERLAP                                  1966L
#define M_ANTICIPATE_OCCLUSIONS                    5606L
#define M_UNORGANIZED                              1919L // already defined in mil3dmap.h
#define M_PAIRS_REJECTION_FACTOR                    5552L
#define M_PAIRS_REJECTION_MODE                     5553L
#define M_PAIRS_CREATION_MAX_POINT_DISTANCE        5649L 
#define M_MAX_ITERATIONS                           1504L // Already defined in milmeas.h
#define M_ALL_ITERATIONS                     0x01000000L 
#define M_INVALID                                     -1 // also in mil.h
#define M_SUBSAMPLE                                 5091L
#define M_SUBSAMPLE_CONTEXT_ID                      3641
#define M_SUBSAMPLE_REFERENCE                       5567L
#define M_SUBSAMPLE_REFERENCE_CONTEXT_ID            5568L
#define M_SUBSAMPLE_TARGET                          5569L
#define M_SUBSAMPLE_TARGET_CONTEXT_ID               5570L
#define M_SET_LOCATION_REFERENCE                   1010L
#define M_PAIRS_LIMIT_PER_TARGET_POINT_MODE        5555L 
#define M_PAIRS_CREATION_FROM_TARGET               5556L 
#define M_PAIRS_CREATION_PER_REFERENCE_POINT_MODE  5564L 
#define M_ROBUST_STANDARD_DEVIATION                5565L
#define M_PAIRS_RANK                               5574L
#define M_SINGLE                                   0x01000000L // Also defined in Mil.h
#define M_MULTIPLE                                 0x00400000L // Also defined in milpat.h
#define M_GEOMETRIC_STABLE_PARTITIONING            5706L
#define M_CACHE_REFERENCE                          5750L

//Result
#define M_MERGE_LOCATION                           4771

//==============================================================================
// M3dregAllocResult ResultTypes
#define M_PAIRWISE_REGISTRATION_RESULT               3500
#define M_REGISTRATION_COMPLETED                     3501
#define M_RMS_ERROR                                  3502
#define M_RMS_ERROR_RELATIVE                         3503
#define M_REGISTRATION_MATRIX                        3504
#define M_PREREGISTRATION_MATRIX                     3560
#define M_RMS_ERROR_THRESHOLD_REACHED                3569
#define M_RMS_ERROR_RELATIVE_THRESHOLD_REACHED       3570
#define M_MAX_ITERATIONS_REACHED                     1965L
#define M_NOT_ENOUGH_POINT_PAIRS                     1972L
#define M_NO_VALID_POINTS                            2097L
#define M_LAST_ITERATION                             -1
#define M_REGISTRATION_GLOBAL                   0x02000000L
#define M_STATUS_REGISTRATION_ELEMENT                 3925
#define M_INTERMEDIATE_ITERATION                 0x00050000L
#define M_NB_ITERATIONS                            1893L // Already defined in milim.h
//==============================================================================
// M3dregGetResult ResultTypes
// General
#define M_STATUS                                0x00008002L // already defined
#define M_EMPTY                                        236L // also in milmod.h, mildmr.h
#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_MAX_PAIRS_RANK                              5575L
#define M_RESULT_IMAGE_SIZE_X                         5226L // already defined in mil3dmet.h
#define M_RESULT_IMAGE_SIZE_Y                         5227L // already defined in mil3dmet.h

//==============================================================================
// M3dregSetLocation
#define M_PREVIOUS                              0x40000003L
#define M_NEXT                                  0x40000004L
#define M_UNCHANGED                             0x40000005L
//==============================================================================
// M3dregMerge
#define M_APPLY_TO_ALL_COMPONENTS                0x0001000L // already defined in mil3dim.h

//==============================================================================
// M3dregCopyResult
#define M_DISTANCE_IMAGE                              5576L
#define M_PAIR_INDEX_IMAGE                            5577L
#define M_OVERLAP_MASK                                5578L
#define M_SUBSAMPLED_CONTAINER_REFERENCE              5579L
#define M_SUBSAMPLED_CONTAINER_TARGET                 5581L 

// Draw context
#define M_ROOT_NODE                                      0  // already defined in mil3dgra.h
#define M_GLOBAL_DRAW_SETTINGS                   M_CONTEXT
#define M_DRAW_OVERLAP_POINTS                   0x00000400L 
#define M_DRAW_EXCLUDED_POINTS                  0x00003000L // already defined in mil3dblob
#define M_DRAW_PAIRS                            0x00000020L 
#define M_PSEUDO_COLOR                              0x4000L // already defined in milclass.h
#define M_PSEUDO_COLOR_OFFSET                         5439L
#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

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

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

MIL_ID MFTYPE M3dregAllocResult(MIL_ID    SysId,
                                MIL_INT64 ResultType,
                                MIL_INT64 ControlFlag,
                                MIL_ID*   Result3dregIdPtr);

void MFTYPE M3dregFree(MIL_ID ContextOrResult3dregId);

void MFTYPE M3dregCopyResult(MIL_ID     SrcResult3dregId,
                             MIL_INT    SrcIndex        ,
                             MIL_INT    SrcReference    ,
                             MIL_ID     DstMilObjectId  ,
                             MIL_INT64  CopyType        ,
                             MIL_INT64  ControlFlag);

void MFTYPE M3dregCalculate(MIL_ID        Context3dregId,
                            const MIL_ID* ContainerBufIdArrayPtr,
                            MIL_INT       NumContainers,
                            MIL_ID        Result3dregId,
                            MIL_INT64     ControlFlag);

void MFTYPE M3dregCopy(MIL_ID     SrcContext3dregId,
                       MIL_INT    SrcIndex,
                       MIL_ID     DstMatrix3dgeoId,
                       MIL_INT    DstIndex,
                       MIL_INT64  CopyType,
                       MIL_INT64  ControlFlag);

void MFTYPE M3dregSetLocation(MIL_ID     Context3dregId,
                              MIL_INT    Index,
                              MIL_INT    Reference,
                              MIL_ID     ParamId,
                              MIL_INT    ParamIndex,
                              MIL_INT    ParamReference,
                              MIL_INT64  ControlFlag);

void MFTYPE M3dregMerge(MIL_ID        Result3dregId,
                        const MIL_ID* ContainerBufIdArrayPtr,
                        MIL_INT       NumContainers,
                        MIL_ID        DstContainerBufId,
                        MIL_ID        SubsampleContext3dimId,
                        MIL_INT64     ControlFlag);
//#if M_MIL_USE_64BIT
void MFTYPE M3dregControlInt64(MIL_ID     ContextOrResult3dregId,
                               MIL_INT64  Index,
                               MIL_INT64  ControlType,
                               MIL_INT64  ControlValue);
void MFTYPE M3dregControlDouble(MIL_ID     ContextOrResult3dregId,
                                MIL_INT64  Index,
                                MIL_INT64  ControlType,
                                MIL_DOUBLE ControlValue);


MIL_INT64 MFTYPE M3dregInquire(MIL_ID    ContextOrResult3dregId,
                               MIL_INT64 Index,
                               MIL_INT64 InquireType,
                               void*     UserVarPtr);

void MFTYPE M3dregControlDrawInt64(MIL_ID     DrawContext3dregId,
                                   MIL_INT64  Operation,
                                   MIL_INT64  ControlType,
                                   MIL_INT64  ControlValue);

void MFTYPE M3dregControlDrawDouble(MIL_ID     DrawContext3dregId,
                                    MIL_INT64  Operation,
                                    MIL_INT64  ControlType,
                                    MIL_DOUBLE ControlValue);

MIL_INT64 MFTYPE M3dregInquireDraw(MIL_ID     DrawContext3dregId,
                                   MIL_INT64  Operation,
                                   MIL_INT64  InquireType,
                                   void*     UserVarPtr);

MIL_DOUBLE MFTYPE M3dregGetResult(MIL_ID    Result3dregId,
                                  MIL_INT64 ResultIndex,
                                  MIL_INT64 ResultType,
                                  void*     ResultArrayPtr);

MIL_INT64 MFTYPE M3dregDraw3d(MIL_ID       OperationDraw3dContext3dregId,
                              MIL_ID       SrcResult3dregId,
                              MIL_INT      Index,
                              MIL_INT      IterationIndex,
                              MIL_INT      PairsRank,
                              MIL_ID       DstList3dgraId,
                              MIL_INT64    DstParentLabel,
                              MIL_INT64    ControlFlag);

#if M_MIL_USE_UNICODE
void MFTYPE M3dregSaveA(MIL_CONST_TEXTA_PTR FileName,
                        MIL_ID              ContextOrResult3dregId,
                        MIL_INT64           ControlFlag);

MIL_ID MFTYPE M3dregRestoreA(MIL_CONST_TEXTA_PTR FileName,
                             MIL_ID              SysId,
                             MIL_INT64           ControlFlag,
                             MIL_ID*             ContextOrResult3dregIdPtr);

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



void MFTYPE M3dregSaveW(MIL_CONST_TEXTW_PTR FileName,
                                          MIL_ID              ContextOrResult3dregId,
                                          MIL_INT64           ControlFlag);

MIL_ID MFTYPE M3dregRestoreW(MIL_CONST_TEXTW_PTR FileName,
                                               MIL_ID              SysId,
                                               MIL_INT64           ControlFlag,
                                               MIL_ID*             ContextOrResult3dregIdPtr);

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



#if M_MIL_UNICODE_API
#define M3dregSave               M3dregSaveW
#define M3dregRestore            M3dregRestoreW
#define M3dregStream             M3dregStreamW
#else
#define M3dregSave               M3dregSaveA
#define M3dregRestore            M3dregRestoreA
#define M3dregStream             M3dregStreamA
#endif //M_MIL_UNICODE_API

#else

void MFTYPE   M3dregSave(MIL_CONST_TEXT_PTR FileName,
                                           MIL_ID             ContextOrResult3dregId,
                                           MIL_INT64          ControlFlag);

MIL_ID MFTYPE M3dregRestore(MIL_CONST_TEXT_PTR FileName,
                                            MIL_ID             SysId,
                                            MIL_INT64          ControlFlag,
                                            MIL_ID*            ContextOrResult3dregIdPtr);

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

#endif //M_MIL_USE_UNICODE

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

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

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

#undef  M3dregStream
#define M3dregStream M3dregStreamCpp
#else

#endif // __cplusplus


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

#ifdef __cplusplus
#if M_MIL_USE_SAFE_TYPE

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

// ----------------------------------------------------------
// M3dregInquire

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

inline MIL_INT64 MFTYPE M3dregInquireUnsafe(MIL_ID ContextOrResult3dregId, MIL_INT64 Index, MIL_INT64 InquireType, void* UserVarPtr)
   {
   return M3dregInquire(ContextOrResult3dregId,Index, InquireType, UserVarPtr);
   }

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

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

#define M3dregInquire           M3dregInquireSafeType
#define M3dregInquireDraw       M3dregInquireDrawSafeType

#else // #if M_MIL_USE_SAFE_TYPE
#define M3dregInquireUnsafe     M3dregInquire
#define M3dregInquireDrawUnsafe M3dregInquireDraw
#endif // #if M_MIL_USE_SAFE_TYPE

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

inline MIL_DOUBLE MFTYPE M3dregGetResultUnsafe(MIL_ID Result3dregId, MIL_INT64 ResultIndex, MIL_INT64 ResultType, void* ResultArrayPtr)
   {
   return M3dregGetResult(Result3dregId, ResultIndex, ResultType, ResultArrayPtr);
   }

#define M3dregGetResult            M3dregGetResultSafeType

#else // #if M_MIL_USE_SAFE_TYPE
#define M3dregGetResultUnsafe            M3dregGetResult
#endif // #if M_MIL_USE_SAFE_TYPE

#endif // __cplusplus

//#if M_MIL_USE_64BIT
#ifdef __cplusplus

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

inline void M3dregControl(MIL_ID ContextOrResult3dregId, MIL_INT64 Index, MIL_INT64 ControlType, float ControlValue)
   { M3dregControlDouble(ContextOrResult3dregId, Index, ControlType, ControlValue); }

inline void M3dregControl(MIL_ID ContextOrResult3dregId, MIL_INT64 Index, MIL_INT64 ControlType, MIL_DOUBLE ControlValue)
   { M3dregControlDouble(ContextOrResult3dregId, Index, ControlType, ControlValue); }

template <typename T>
inline void M3dregControlDraw(MIL_ID DrawContext3dregId, MIL_INT64 Operation, MIL_INT64 ControlType, T ControlValue)
   {
   M3dregControlDrawInt64(DrawContext3dregId, Operation, ControlType, ControlValue);
   }

inline void M3dregControlDraw(MIL_ID DrawContext3dregId, MIL_INT64 Operation, MIL_INT64 ControlType, float ControlValue)
   {
   M3dregControlDrawDouble(DrawContext3dregId, Operation, ControlType, ControlValue);
   }

inline void M3dregControlDraw(MIL_ID DrawContext3dregId, MIL_INT64 Operation, MIL_INT64 ControlType, MIL_DOUBLE ControlValue)
   {
   M3dregControlDrawDouble(DrawContext3dregId, Operation, ControlType, ControlValue);
   }

#else // __cplusplus
//=========================================================
// For C file, call the default function, i.e. Double one
//=========================================================
#define M3dregControl            M3dregControlDouble
#define M3dregControlDraw        M3dregControlDrawDouble
#endif // __cplusplus
//#endif // M_MIL_USE_64BIT

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

   UserVarPtr.resize(InternalNumberOfElementsForStdVector);

   if(InternalNumberOfElementsForStdVector > 0)
      {
      return M3dregInquire(ContextOrResult3dregId, Index, InquireType, &UserVarPtr[0]);
      }
   return 0;
   }
template <typename UserType>
inline MIL_DOUBLE MFTYPE M3dregGetResult(MIL_ID Result3dregId, MIL_INT 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("M3dregGetResult"), 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;
   M3dregGetResult(Result3dregId, Index, M_STRIP_HLVLDATATYPE(ResultType) + M_NB_ELEMENTS + M_TYPE_MIL_INT, &InternalNumberOfElementsForStdVector);

   ResultArrayPtr.resize(InternalNumberOfElementsForStdVector);

   if(InternalNumberOfElementsForStdVector > 0)
      {
      M3dregGetResult(Result3dregId, Index, ResultType, &ResultArrayPtr[0]);
      }
   return 0.0;
   }
// ----------------------------------------------------------
// Overloads for std::vector in M3dregCalculate
inline void MFTYPE M3dregCalculate(MIL_ID                     Context3dregId,
                                   const std::vector<MIL_ID>& ContainerBufIdArrayPtr,
                                   MIL_INT                    NumContainers,
                                   MIL_ID                     ResultId,
                                   MIL_INT64                  ControlFlag)
   {
#if M_MIL_USE_SAFE_TYPE
   if(ContainerBufIdArrayPtr.empty())
      {
      SafeTypeError(MIL_TEXT("M3dregCalculate"), MIL_TEXT("The input vectors cannot be empty."));
      }
   if(NumContainers <= 0)
      {
      SafeTypeError(MIL_TEXT("M3dregCalculate"), MIL_TEXT("NumContainers parameter must be greater than zero."));
      }
   if(NumContainers > (MIL_INT)ContainerBufIdArrayPtr.size() && NumContainers != M_DEFAULT)
      {
      SafeTypeError(MIL_TEXT("M3dregCalculate"), MIL_TEXT("NumContainers parameter must be smaller or equal (M_DEFAULT) to the size of input vector."));
      }
#endif

   if(NumContainers == M_DEFAULT || NumContainers > (MIL_INT)ContainerBufIdArrayPtr.size())
      {
      NumContainers = (MIL_INT)ContainerBufIdArrayPtr.size();
      }

   M3dregCalculate(Context3dregId,
                   &ContainerBufIdArrayPtr[0],
                   NumContainers,
                   ResultId,
                   ControlFlag);
   }
// ----------------------------------------------------------
// Overloads for std::vector in M3dregMerge
inline void MFTYPE M3dregMerge(MIL_ID        Result3dregId,
                               const std::vector<MIL_ID>&  ContainerBufIdArrayPtr,
                               MIL_INT       NumContainers,
                               MIL_ID        DstContainerBufId,
                               MIL_ID        SubsampleContext3dimId,
                               MIL_INT64     ControlFlag)
   {
#if M_MIL_USE_SAFE_TYPE
   if(ContainerBufIdArrayPtr.empty())
      {
      SafeTypeError(MIL_TEXT("M3dregMerge"), MIL_TEXT("The input vectors cannot be empty."));
      }
   if(NumContainers <= 1)
      {
      SafeTypeError(MIL_TEXT("M3dregMerge"), MIL_TEXT("NumContainers parameter must be greater than one."));
      }
   if(NumContainers > (MIL_INT)ContainerBufIdArrayPtr.size() && NumContainers != M_DEFAULT)
      {
      SafeTypeError(MIL_TEXT("M3dregMerge"), MIL_TEXT("NumContainers parameter must be smaller or equal (M_DEFAULT) to the size of input vector."));
      }
#endif

   if(NumContainers == M_DEFAULT || NumContainers > (MIL_INT)ContainerBufIdArrayPtr.size())
      {
      NumContainers = (MIL_INT)ContainerBufIdArrayPtr.size();
      }

   M3dregMerge(Result3dregId,
               &ContainerBufIdArrayPtr[0],
               NumContainers,
               DstContainerBufId,
               SubsampleContext3dimId,
               ControlFlag);
   }
// Overloads for std::vector in M3dregStream.
inline void MFTYPE M3dregStream(std::vector<MIL_UINT8> &MemPtrOrFileName,
                                MIL_ID                 SysId,
                                MIL_INT64              Operation,
                                MIL_INT64              StreamType,
                                MIL_DOUBLE             Version,
                                MIL_INT64              ControlFlag,
                                MIL_ID*                ContextOrResult3dregIdPtr,
                                MIL_INT*               SizeByteVarPtr)
   {
   MxxxStreamForStdVector(MemPtrOrFileName,
                          SysId,
                          Operation,
                          StreamType,
                          Version,
                          ControlFlag,
                          ContextOrResult3dregIdPtr,
                          SizeByteVarPtr,
                          M3dregStream);
   }

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

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

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

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

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

#endif /* M_MIL_UNICODE_API*/

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

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

#endif /* M_MIL_USE_UNICODE */

#if M_MIL_USE_SAFE_TYPE

#if M_MIL_UNICODE_API

inline MIL_DOUBLE MFTYPE M3dregGetResultSafeType(MIL_ID Result3dregId, 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("M3dregGetResult: Result Type not supported with MIL_STRING."));
      }
#endif

   MIL_INT InternalStringSize = 0;

   M3dregGetResult(Result3dregId, 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);
         }
      }

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

   MIL_INT InternalStringSize = 0;

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

   if(InternalStringSize > 0)
      {
      ResultArrayPtr.assign(InternalStringSize, MIL_TEXT('\0'));
      M3dregGetResult(Result3dregId, 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<&M3dregFree>(MIL_INT64 ObjectType)
   {
   return (ObjectType & ~M_USER_DEFINE_LOW_ATTRIBUTE) == M_3DREG_OBJECT;
   }
#endif

typedef MIL_UNIQUE_ID<&M3dregFree> MIL_UNIQUE_3DREG_ID;

#if M_MIL_USE_MOVE_SEMANTICS

inline MIL_UNIQUE_3DREG_ID M3dregAlloc(MIL_ID SysId, MIL_INT64 ObjectType, MIL_INT64 InitFlag, MIL_UNIQUE_ID_TAG)
   {
   return MIL_UNIQUE_3DREG_ID(M3dregAlloc(SysId, ObjectType, InitFlag, M_NULL));
   }
inline MIL_UNIQUE_3DREG_ID M3dregAllocResult(MIL_ID SysId, MIL_INT64 ResultType, MIL_INT64 ControlFlag, MIL_UNIQUE_ID_TAG)
   {
   return MIL_UNIQUE_3DREG_ID(M3dregAllocResult(SysId, ResultType, ControlFlag, M_NULL));
   }
inline MIL_UNIQUE_3DREG_ID M3dregRestore(MIL_CONST_TEXT_PTR FileName, MIL_ID SysId, MIL_INT64 ControlFlag, MIL_UNIQUE_ID_TAG)
   {
   return MIL_UNIQUE_3DREG_ID(M3dregRestore(FileName, SysId, ControlFlag, M_NULL));
   }
#if M_MIL_USE_STRING
inline MIL_UNIQUE_3DREG_ID M3dregRestore(const MIL_STRING& FileName, MIL_ID SysId, MIL_INT64 ControlFlag, MIL_UNIQUE_ID_TAG)
   {
   return MIL_UNIQUE_3DREG_ID(M3dregRestore(FileName.c_str(), SysId, ControlFlag, M_NULL));
   }
#endif // M_MIL_USE_STRING
template <MilFreeFuncType FreeFunc> inline void M3dregFree(const MIL_UNIQUE_ID<FreeFunc>&) = delete;

inline void M3dregStream(MilStreamParam       MemPtrOrFileName,
                         MIL_ID               SysId,
                         MIL_INT64            Operation,
                         MIL_INT64            StreamType,
                         MIL_DOUBLE           Version,
                         MIL_INT64            ControlFlag,
                         MIL_UNIQUE_3DREG_ID* Context3dregIdPtr,
                         MIL_INT*             SizeByteVarPtr)
   {
   MxxxStreamForMilUniqueId(MemPtrOrFileName, SysId, Operation, StreamType, Version, ControlFlag, Context3dregIdPtr, SizeByteVarPtr, M3dregStream);
   }
inline void M3dregCalculate(MIL_ID ContextId, MilConstArrayIdParam ContArrayPtr, MIL_INT NumContainers, MIL_ID  ResultorMatrixId, MIL_INT64  ControlFlag)
   {
   M3dregCalculate(ContextId, ContArrayPtr.m_IdArrayPtr, NumContainers, ResultorMatrixId, ControlFlag);
   }
inline void MFTYPE M3dregMerge(MIL_ID Result3dregId, MilConstArrayIdParam  ContainerArrayPtr, MIL_INT NumContainers, MIL_ID DstContainerId, MIL_ID SubsampleContext3dimId, MIL_INT64 ControlFlag)
   {
   M3dregMerge(Result3dregId, ContainerArrayPtr.m_IdArrayPtr, NumContainers, DstContainerId, SubsampleContext3dimId, ControlFlag);
   }

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