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

#ifndef __MIL_3DBLOB_H__
#define __MIL_3DBLOB_H__


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


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

//==============================================================================
// M3dblobAlloc ContextTypes
#define M_SEGMENTATION_CONTEXT                     5055L
#define M_DRAW_3D_CONTEXT                          3815  // already defined in mil3dmap.h
#define M_CALCULATE_CONTEXT                        5269L

//==============================================================================   
// Indexing, used in other M3dblob functions (M3dblobInquire(), M3dblobControl(), ...)
#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_ALL_BLOBS                             0x40000000L // already defined in milblob.h
#define M_BLOB_LABEL(BlobLabel)                 (BlobLabel) // already defined in milblob.h
#define M_BLOB_INDEX_FLAG                       0x04000000L // already defined in milblob.h
#define M_BLOB_INDEX(BlobIndex)                ((BlobIndex) | M_BLOB_INDEX_FLAG) // already defined in milblob.h


#define M_MODIFICATION_COUNT                          5010L // already defined

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

//==============================================================================
//M3dblobCopyResult
#define M_LABEL_IMAGE                              5044L
#define M_INDEX_IMAGE                              5046L
#define M_MASK_IMAGE                               1020L // already defined in milreg.h
#define M_RESULT                             0x00001000L // already defined in milmod.h

// M3dblobExtract
#define M_APPLY_TO_ALL_COMPONENTS             0x0001000L // already defined in mil3dim.h
#define M_ALLOW_CHILD                         0x0002000L
#define M_SAME                                       -1L // already defined
#define M_UNORGANIZED                              1919L // already defined in mil3dmap.h
#define M_SHRINK                                   3409  // already defined in mil3dim.h
#define M_SHRINK_VERTICALLY                        5438L

// M3dblobSelect
#define M_IN_RANGE                                    1L // already defined in mil.h
#define M_OUT_RANGE                                   2L // already defined in mil.h
#define M_EQUAL                                       3L // already defined in mil.h
#define M_NOT_EQUAL                                   4L // already defined in mil.h
#define M_GREATER                                     5L // already defined in mil.h
#define M_LESS                                        6L // already defined in mil.h
#define M_GREATER_OR_EQUAL                            7L // already defined in mil.h
#define M_LESS_OR_EQUAL                               8L // already defined in mil.h
#define M_NOT_AVAILABLE                            5511L

// M3dblobSort
#define M_INFINITE                                   -1L // already defined in mil.h
#define M_FRONT                              0x00000010L
#define M_BACK                               0x00000020L
#define M_UP                                 0x00000000L // already defined in milblob.h
#define M_DOWN                               0x08000000L // already defined in milblob.h
#define M_FEATURE_REQUIRED                            4L

// M3dblobCombine
#define M_SUB                                    0x0001L // already defined in milim.h
#define M_OR                                     0x0016L // already defined in milim.h
#define M_AND                                    0x0017L // already defined in milim.h
#define M_XOR                                    0x0018L // already defined in milim.h

// M3dblobSegment
#define M_SEGMENTATION_CONTEXT_WHOLE_IMAGE         (M_3DBLOB_PSEUDO_ID + M_WHOLE_IMAGE) 
#define M_SEGMENTATION_CONTEXT_LABEL_IMAGE         (M_3DBLOB_PSEUDO_ID + M_LABEL_IMAGE) 



//==============================================================================
// M3dblobControl / M3dblobInquire
// Segmentation context
#define M_NUMBER_OF_POINTS_MIN                        5060L
#define M_NUMBER_OF_POINTS_MAX                        5062L
#define M_MAX_DISTANCE                                  12L // already defined in milcol.h
#define M_NORMAL_DISTANCE_MAX                         5075L
#define M_NORMAL_DISTANCE_MODE                        5212L
#define M_COLOR_DISTANCE_MAX                          5081L
#define M_COLOR_DISTANCE_MODE                         5211L
#define M_CUSTOM_DISTANCE_MAX                         5084L
#define M_CUSTOM_DISTANCE_COMPONENT                   5232L
#define M_GLOBAL_NORMAL_DISTANCE_MAX                  5586L
#define M_GLOBAL_PLANE_DISTANCE_MAX                   5587L
#define M_MAX_DISTANCE_MODE                           5757L
#define M_NORMAL_DISTANCE_MAX_MODE                    5758L
#define M_NEIGHBOR_SEARCH_MODE                        3041L // already defined in mil3dim.h
#define M_TREE                                        3042L // already defined in mil3dim.h
#define M_ORGANIZED                                   3418  // already defined in mil3dim.h
#define M_MESH                                        3994  // already defined in mil3dim.h
#define M_MAXIMUM_NUMBER_NEIGHBORS                    3316  // already defined in mil3dim.h
#define M_NEIGHBORHOOD_ORGANIZED_SIZE                 1943L // already defined in mil3dim.h
#define M_ORIENTATION                           0x00002400L // already defined in milmeas.h
#define M_DIRECTION                                   5229L
#define M_RELABEL_CONSECUTIVE                         2713L // already defined in milblob.h
#define M_SEGMENTATION_MODE                           5352L
#define M_EUCLIDEAN                                      2L // already defined in milcol.h
#define M_WHOLE_IMAGE                                    1L // already defined in milblob.h

// Draw context
#define M_ROOT_NODE                                      0  // already defined in mil3dgra.h
#define M_GLOBAL_DRAW_SETTINGS                   M_CONTEXT
#define M_DRAW_BLOBS                            0x00000400L // already defined in milblob.h
#define M_DRAW_EXCLUDED_POINTS                  0x00003000L
#define M_DRAW_BOX                              0x00000020L // already defined in milblob.h
#define M_DRAW_PCA_BOX                          0x00006000L
#define M_DRAW_PCA                              0x00007000L
#define M_DRAW_NEAREST_BLOB                     0x00009000L
#define M_DRAW_SEMI_ORIENTED_BOX                0x0000A000L
#define M_DRAW_FERET_MIN                        0x00001000L // already defined in milblob.h
#define M_DRAW_FERET_MAX                        0x00000008L // already defined in milblob.h
#define M_DRAW_FERET_GENERAL                    0x00100000L // already defined in milblob.h
#define M_PSEUDO_COLOR                              0x4000L // already defined in milclass.h
#define M_PSEUDO_COLOR_OFFSET                         5439L
#define M_GRAPHIC_LIST_DEFAULT                  0x04005526L
#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_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

// Result
#define M_RESET                                          9L // already defined in milblob.h
#define M_MERGE                                 0x00000040L // already defined in milblob.h
#define M_INDEX_MODE                                  5402L // already defined in milblob.h
#define M_LABEL                                       5403L // already defined in milblob.h
#define M_INDEX                                       217L  // already defined in milblob.h
#define M_USE_MACRO                                   5404L // already defined in milblob.h

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

//==============================================================================
// M3dblobAllocResult ResultTypes
#define M_SEGMENTATION_RESULT                         5263L

//==============================================================================
// M3dblobGetResult ResultTypes
#define M_NUMBER                                      1009L // already defined in milblob.h
#define M_MAX_LABEL_VALUE                             2939L // already defined in milblob.h
#define M_CONTAINER_ID                                4675  // already defined in mil3dgra.h
#define M_SEGMENTATION_UUID                           5228L
#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_BLOB_TOUCHING_IMAGE_BORDERS                  118L // already defined in milblob.h
#define M_TOTAL_NUMBER_OF_POINTS                      5331L
#define M_INDEX_IMAGE_SIZE_BIT                        5355L
#define M_LABEL_IMAGE_SIZE_BIT                        5356L
#define M_FIRST_PIXEL_X                               5495L
#define M_FIRST_PIXEL_Y                               5496L
#define M_NUMBER_OF_POINTS                         M_NUMBER // already defined in mil3dim.h

#define M_PIXEL_X                                     3891  // already defined in mil3dim.h
#define M_PIXEL_Y                                     3892  // already defined in mil3dim.h
#define M_PIXEL_PACKED                                5047L
#define M_PIXEL_MIN_X                                 5048L
#define M_PIXEL_MIN_Y                                 5049L
#define M_PIXEL_MAX_X                                 5050L
#define M_PIXEL_MAX_Y                                 5051L

#define M_ALL_FEATURES                               0x100L // already defined in milblob.h
#define M_NEAREST_BLOB                          0x0000C000L
#define M_NEAREST_BLOB_DISTANCE                       5287L
#define M_NEAREST_POINT_1                             5288L
#define M_NEAREST_POINT_X1                            5289L
#define M_NEAREST_POINT_Y1                            5290L
#define M_NEAREST_POINT_Z1                            5291L
#define M_NEAREST_POINT_2                             5292L
#define M_NEAREST_POINT_X2                            5293L
#define M_NEAREST_POINT_Y2                            5294L
#define M_NEAREST_POINT_Z2                            5295L

#define M_PLANARITY                                   5267L
#define M_LINEARITY                                   5268L
#define M_BOUNDING_BOX                          0x00000003L // Already defined in mil3dim
#define M_PCA_BOX                               0x0000D000L
#define M_SEMI_ORIENTED_BOX                     0x0000E000L
#define M_MIN_X                                       3382  // Already defined in mil3dim
#define M_MIN_Y                                       3383  // Already defined in mil3dim
#define M_MIN_Z                                       3384  // Already defined in mil3dim
#define M_MAX_X                                       3385  // Already defined in mil3dim
#define M_MAX_Y                                       3386  // Already defined in mil3dim
#define M_MAX_Z                                       3387  // Already defined in mil3dim
#define M_BOX_CENTER                            0x0000B400L // Already defined in mil3dim
#define M_BOX_CENTER_X                                3445  // Already defined in mil3dim
#define M_BOX_CENTER_Y                                3446  // Already defined in mil3dim
#define M_BOX_CENTER_Z                                3447  // Already defined in mil3dim
#define M_SIZE_X                                      1536L // Already defined in mil3dim 
#define M_SIZE_Y                                      1537L // Already defined in mil3dim 
#define M_SIZE_Z                                      1538L // Already defined in mil3dim 
#define M_SEMI_ORIENTED_BOX_ANGLE                     5360L // Already defined in mil3dim 
#define M_PCA_BOX_CENTER                              (M_PCA_BOX | M_BOX_CENTER)
#define M_SEMI_ORIENTED_BOX_CENTER                    (M_SEMI_ORIENTED_BOX | M_BOX_CENTER)

#define M_FERET_X                                       72L // already defined in milblob.h
#define M_FERET_Y                                        5L // already defined in milblob.h
#define M_FERET_Z                                     5286L
#define M_FERET_MIN_DIAMETER                            14L // already defined in milblob.h
#define M_FERET_MAX_DIAMETER                            16L // already defined in milblob.h
#define M_FERET_GENERAL                              0x400L // already defined in milblob.h
#define M_FERET_AT_PRINCIPAL_AXIS_1                   5273L
#define M_FERET_AT_PRINCIPAL_AXIS_2                   5274L
#define M_FERET_AT_PRINCIPAL_AXIS_3                   5275L
#define M_FERET_SEMI_ORIENTED_WIDTH                   5367L
#define M_FERET_SEMI_ORIENTED_HEIGHT                  5368L
#define M_SEMI_ORIENTED_BOX_ELONGATION                5437L

#define M_FERET_CONTACT_POINTS                     0x30000L // already defined in milblob.h
#define M_FERET_CONTACT_POINTS_X1                  0x50000L // already defined in milblob.h
#define M_FERET_CONTACT_POINTS_Y1                  0x60000L // already defined in milblob.h
#define M_FERET_CONTACT_POINTS_X2                  0x70000L // already defined in milblob.h
#define M_FERET_CONTACT_POINTS_Y2                  0x80000L // already defined in milblob.h
#define M_FERET_CONTACT_POINTS_Z1                  0x90000L
#define M_FERET_CONTACT_POINTS_Z2                  0xA0000L
#define M_FERET_DIRECTION_X                        0xB0000L
#define M_FERET_DIRECTION_Y                        0xC0000L
#define M_FERET_DIRECTION_Z                        0xD0000L
#define M_FERET_CONTACT_POINT_1                    0xE0000L
#define M_FERET_CONTACT_POINT_2                    0xF0000L
#define M_FERET_PRECISION                         0x110000L

#define M_CENTROID                                    1956L // already defined in mil3dim.h
#define M_CENTROID_X                                  3451  // already defined in mil3dim.h
#define M_CENTROID_Y                                  3452  // already defined in mil3dim.h
#define M_CENTROID_Z                                  3453  // already defined in mil3dim.h
#define M_PCA                                         4855L // already defined in mil3dim.h
#define M_MOMENTS                                     4856L // already defined in mil3dim.h
#define M_MOMENT_ORDER                                4857L // already defined in mil3dim.h
#define M_CENTRAL                                    0x800L // already defined in mil3dim.h
#define M_ORDINARY                                   0x400L // already defined in mil3dim.h
#define M_EIGENVALUE_1                                4869L // already defined in mil3dim.h
#define M_EIGENVALUE_2                                4870L // already defined in mil3dim.h
#define M_EIGENVALUE_3                                4871L // already defined in mil3dim.h
#define M_PRINCIPAL_AXIS_1                            4872L // already defined in mil3dim.h
#define M_PRINCIPAL_AXIS_2                            4873L // already defined in mil3dim.h
#define M_PRINCIPAL_AXIS_3                            4874L // already defined in mil3dim.h
#define M_PRINCIPAL_AXIS_1_X                          4875L // already defined in mil3dim.h
#define M_PRINCIPAL_AXIS_1_Y                          4876L // already defined in mil3dim.h
#define M_PRINCIPAL_AXIS_1_Z                          4877L // already defined in mil3dim.h
#define M_PRINCIPAL_AXIS_2_X                          4878L // already defined in mil3dim.h
#define M_PRINCIPAL_AXIS_2_Y                          4879L // already defined in mil3dim.h
#define M_PRINCIPAL_AXIS_2_Z                          4880L // already defined in mil3dim.h
#define M_PRINCIPAL_AXIS_3_X                          4881L // already defined in mil3dim.h
#define M_PRINCIPAL_AXIS_3_Y                          4882L // already defined in mil3dim.h
#define M_PRINCIPAL_AXIS_3_Z                          4883L // already defined in mil3dim.h
#define M_PCA_MATRIX                                  4884L // already defined in mil3dim.h
#define M_COVARIANCE_MATRIX                           4885L // already defined in mil3dim.h
#define M_FIXTURING_MATRIX                            3878L // already defined in mil3dim.h
#define M_APPROX_PRINCIPAL_AXIS_1_X                   5322L // already defined in mil3dim.h
#define M_APPROX_PRINCIPAL_AXIS_1_Y                   5323L // already defined in mil3dim.h
#define M_APPROX_PRINCIPAL_AXIS_1_Z                   5324L // already defined in mil3dim.h
#define M_APPROX_PRINCIPAL_AXIS_2_X                   5338L // already defined in mil3dim.h
#define M_APPROX_PRINCIPAL_AXIS_2_Y                   5339L // already defined in mil3dim.h
#define M_APPROX_PRINCIPAL_AXIS_2_Z                   5340L // already defined in mil3dim.h
#define M_STANDARD_DEVIATION_X                        5033  // already defined in mil3dim.h
#define M_STANDARD_DEVIATION_Y                        5034  // already defined in mil3dim.h
#define M_STANDARD_DEVIATION_Z                        5035  // already defined in mil3dim.h
#define M_AVERAGE_NORMAL_X                            5903L
#define M_AVERAGE_NORMAL_Y                            5904L
#define M_AVERAGE_NORMAL_Z                            5905L

// already defined in mil3dim.h
#define M_MOMENT_XYZ(PowerX, PowerY, PowerZ)          (M_MOMENTS | M_ORDINARY | ((PowerX) << 16) | ((PowerY) << 20) | ((PowerZ) << 24))
#define M_MOMENT_CENTRAL_XYZ(PowerX, PowerY, PowerZ)  (M_MOMENTS | M_CENTRAL  | ((PowerX) << 16) | ((PowerY) << 20) | ((PowerZ) << 24))
#define M_MOMENT_XYZ_X(Moment)                        (((Moment) >> 16) & 0x0F)
#define M_MOMENT_XYZ_Y(Moment)                        (((Moment) >> 20) & 0x0F)
#define M_MOMENT_XYZ_Z(Moment)                        (((Moment) >> 24) & 0x0F)


#define M_CUSTOM_FEATURE_MAX                          1024L
#define M_CUSTOM_FEATURE_FLAG                         0x00200000
#define M_CUSTOM_FEATURE(N)                           ((N) | M_CUSTOM_FEATURE_FLAG)
#define M_REMOVE_FEATURE                              5053L

// 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

#define M_MISSING_COMPONENT_NORMALS_MIL                4183 // already defined in mil3dmod.h
#define M_MISSING_COMPONENT_MESH_MIL                   5214 // already defined in mil3dmod.h
#define M_CONTAINER_NOT_ORGANIZED                      5218 // already defined in mil3dmod.h

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

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

MIL_ID MFTYPE M3dblobAllocResult(MIL_ID    SysId,
                                 MIL_INT64 ResultType,
                                 MIL_INT64 ControlFlag,
                                 MIL_ID*   Result3dblobIdPtr);

void MFTYPE M3dblobFree(MIL_ID ContextOrResult3dblobId);


  
//#if M_MIL_USE_64BIT
   // Prototypes for 64 bits OSs
void MFTYPE M3dblobControlInt64(MIL_ID     ContextOrResult3dblobId,
                                MIL_INT64  LabelOrIndex,
                                MIL_INT64  ControlType,
                                MIL_INT64  ControlValue);
 void MFTYPE M3dblobControlDouble(MIL_ID     ContextOrResult3dblobId,
                                  MIL_INT64  LabelOrIndex,
                                  MIL_INT64  ControlType,
                                  MIL_DOUBLE ControlValue);

 MIL_INT64 MFTYPE M3dblobInquire(MIL_ID    ContextOrResult3dblobId,
                                 MIL_INT64 LabelOrIndex,
                                 MIL_INT64 InquireType,
                                 void*     UserVarPtr);

 void MFTYPE M3dblobControlDrawInt64(MIL_ID     DrawContext3dblobId,
                                     MIL_INT64  Operation,
                                     MIL_INT64  ControlType,
                                     MIL_INT64  ControlValue);
 void MFTYPE M3dblobControlDrawDouble(MIL_ID     DrawContext3dblobId,
                                      MIL_INT64  Operation,
                                      MIL_INT64  ControlType,
                                      MIL_DOUBLE ControlValue);

 MIL_INT64 MFTYPE M3dblobInquireDraw(MIL_ID     DrawContext3dblobId,
                                     MIL_INT64  Operation,
                                     MIL_INT64  InquireType,
                                     void*     UserVarPtr);

 MIL_DOUBLE MFTYPE M3dblobGetResult(MIL_ID    Result3dblobId,
                                    MIL_INT64 LabelOrIndex,
                                    MIL_INT64 ResultType,
                                    void*     ResultArrayPtr);

 void MFTYPE M3dblobCopyResult(MIL_ID    SrcResult3dblobId,
                               MIL_INT64 SrcLabelOrIndex,
                               MIL_ID    DstMilObjectId,
                               MIL_INT64 CopyType,
                               MIL_INT64 ControlFlag);

 void MFTYPE M3dblobSegment(MIL_ID     SegmentationContext3dblobId,
                            MIL_ID     ContainerOrLabelImageBufId,
                            MIL_ID     Result3dblobId,
                            MIL_INT64  ControlFlag);

 void MFTYPE M3dblobSelect(MIL_ID     SrcResult3dblobId,
                           MIL_ID     DstResult3dblobId,
                           MIL_INT64  SelectionCriterion,
                           MIL_INT64  Condition,
                           MIL_DOUBLE CondLow,
                           MIL_DOUBLE CondHigh,
                           MIL_INT64  ControlFlag);

 void MFTYPE M3dblobSort(MIL_ID    SrcResult3dblobId,
                         MIL_ID    DstResult3dblobId,
                         MIL_INT64 Feature1,
                         MIL_INT64 Feature2,
                         MIL_INT64 Feature3,
                         MIL_INT   NbBlobsToKeep,
                         MIL_INT64 ControlFlag);

 void MFTYPE M3dblobCombine(MIL_ID    Src1Result3dblobId,
                            MIL_ID    Src2Result3dblobId,
                            MIL_ID    DstResult3dblobId,
                            MIL_INT64 Operation,
                            MIL_INT64 ControlFlag);

 void MFTYPE M3dblobExtract(MIL_ID    SrcContainerBufId,
                            MIL_ID    Result3dblobId,
                            MIL_INT64 LabelOrIndex,
                            MIL_ID    DstContainerBufId,
                            MIL_INT64 Options,
                            MIL_INT64 ControlFlag);

 MIL_INT64 MFTYPE M3dblobDraw3d(MIL_ID     Draw3dContext3dblobId,
                                MIL_ID     ContainerBufId,
                                MIL_ID     Result3dblobId,
                                MIL_INT64  LabelOrIndex,
                                MIL_ID     DstList3dgraId,
                                MIL_INT64  DstParentLabel,
                                MIL_INT64  ControlFlag);

 void MFTYPE M3dblobCalculate(MIL_ID     CalculateContext3dblobId,
                              MIL_ID     ContainerBufId,
                              MIL_ID     Result3dblobId,
                              MIL_INT64  LabelOrIndex,
                              MIL_INT64  ControlFlag);

#if M_MIL_USE_UNICODE
   void MFTYPE M3dblobSaveA(MIL_CONST_TEXTA_PTR FileName,
                            MIL_ID      Context3dblobId,
                            MIL_INT64   ControlFlag);

   MIL_ID MFTYPE M3dblobRestoreA(MIL_CONST_TEXTA_PTR FileName,
                                 MIL_ID      SysId,
                                 MIL_INT64   ControlFlag,
                                 MIL_ID*     Context3dblobIdPtr);

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

   void MFTYPE M3dblobSaveW(MIL_CONST_TEXTW_PTR FileName,
                            MIL_ID              Context3dblobId,
                            MIL_INT64           ControlFlag);

   MIL_ID MFTYPE M3dblobRestoreW(MIL_CONST_TEXTW_PTR FileName,
                                 MIL_ID              SysId,
                                 MIL_INT64           ControlFlag,
                                 MIL_ID*             Context3dblobIdPtr);

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

#if M_MIL_UNICODE_API
#define M3dblobSave               M3dblobSaveW
#define M3dblobRestore            M3dblobRestoreW
#define M3dblobStream             M3dblobStreamW
#else
#define M3dblobSave               M3dblobSaveA
#define M3dblobRestore            M3dblobRestoreA
#define M3dblobStream             M3dblobStreamA
#endif //M_MIL_UNICODE_API

#else

 void MFTYPE   M3dblobSave(MIL_CONST_TEXT_PTR FileName,
                           MIL_ID             Context3dblobId,
                           MIL_INT64          ControlFlag);

 MIL_ID MFTYPE M3dblobRestore(MIL_CONST_TEXT_PTR FileName,
                              MIL_ID             SysId,
                              MIL_INT64          ControlFlag,
                              MIL_ID*            Context3dblobIdPtr);

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

#endif //M_MIL_USE_UNICODE

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

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

#undef  M3dblobStream
#define M3dblobStream M3dblobStreamCpp

#endif // __cplusplus

#ifdef __cplusplus
// ----------------------------------------------------------
// M3dblobInquire
#if M_MIL_USE_SAFE_TYPE

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

inline MIL_INT64 MFTYPE M3dblobInquireUnsafe(MIL_ID Context3dblobId, MIL_INT64 LabelOrIndex, MIL_INT64 InquireType, void* UserVarPtr)
   {
   return M3dblobInquire(Context3dblobId, LabelOrIndex, InquireType, UserVarPtr);
   }

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

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

#define M3dblobInquire           M3dblobInquireSafeType
#define M3dblobInquireDraw       M3dblobInquireDrawSafeType

#else // #if M_MIL_USE_SAFE_TYPE
#define M3dblobInquireUnsafe     M3dblobInquire
#define M3dblobInquireDrawUnsafe M3dblobInquireDraw
#endif // #if M_MIL_USE_SAFE_TYPE

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

inline MIL_DOUBLE MFTYPE M3dblobGetResultUnsafe(MIL_ID Result3dblobId, MIL_INT64 LabelOrIndex, MIL_INT64 ResultType, void* ResultArrayPtr)
   {
   return M3dblobGetResult(Result3dblobId, LabelOrIndex, ResultType, ResultArrayPtr);
   }

#define M3dblobGetResult            M3dblobGetResultSafeType

#else // #if M_MIL_USE_SAFE_TYPE
#define M3dblobGetResultUnsafe            M3dblobGetResult
#endif // #if M_MIL_USE_SAFE_TYPE

#endif // __cplusplus

//#if M_MIL_USE_64BIT
#ifdef __cplusplus

//=========================================================
// M3dblobControl function overloads when compiling c++ files
//=========================================================
template <typename T>
inline void M3dblobControl(MIL_ID Context3dblobId, MIL_INT64 LabelOrIndex, MIL_INT64 ControlType, T ControlValue)
   {
   M3dblobControlInt64(Context3dblobId, LabelOrIndex, ControlType, ControlValue);
   }

inline void M3dblobControl(MIL_ID Context3dblobId, MIL_INT64 LabelOrIndex, MIL_INT64 ControlType, float ControlValue)
   {
   M3dblobControlDouble(Context3dblobId, LabelOrIndex, ControlType, ControlValue);
   }

inline void M3dblobControl(MIL_ID Context3dblobId, MIL_INT64 LabelOrIndex, MIL_INT64 ControlType, MIL_DOUBLE ControlValue)
   {
   M3dblobControlDouble(Context3dblobId, LabelOrIndex, ControlType, ControlValue);
   }

template <typename T>
inline void M3dblobControlDraw(MIL_ID DrawContext3dblobId, MIL_INT64 Operation, MIL_INT64 ControlType, T ControlValue)
   {
   M3dblobControlDrawInt64(DrawContext3dblobId, Operation, ControlType, ControlValue);
   }

inline void M3dblobControlDraw(MIL_ID DrawContext3dblobId, MIL_INT64 Operation, MIL_INT64 ControlType, float ControlValue)
   {
   M3dblobControlDrawDouble(DrawContext3dblobId, Operation, ControlType, ControlValue);
   }

inline void M3dblobControlDraw(MIL_ID DrawContext3dblobId, MIL_INT64 Operation, MIL_INT64 ControlType, MIL_DOUBLE ControlValue)
   {
   M3dblobControlDrawDouble(DrawContext3dblobId, Operation, ControlType, ControlValue);
   }
#else // __cplusplus
//=========================================================
// For C file, call the default function, i.e. Double one
//=========================================================
#define M3dblobControl            M3dblobControlDouble
#define M3dblobControlDraw        M3dblobControlDrawDouble
#endif // __cplusplus
//#endif // M_MIL_USE_64BIT

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

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

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

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

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

#endif /* M_MIL_UNICODE_API*/

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

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

#endif /* M_MIL_USE_UNICODE */

#if M_MIL_USE_SAFE_TYPE

#if M_MIL_UNICODE_API

inline MIL_DOUBLE MFTYPE M3dblobGetResultSafeType(MIL_ID Result3dblobId, MIL_INT64 LabelOrIndex, 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("M3dblobGetResult"), MIL_TEXT(" Result Type not supported with MIL_STRING."));
      }
#endif

   MIL_INT InternalStringSize = 0;

   M3dblobGetResult(Result3dblobId, LabelOrIndex, (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);
         }
      }

   M3dblobGetResult(Result3dblobId, LabelOrIndex, ResultType, &ResultArrayPtr[0]);

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

   //Inquire the byte content
   M3dblobGetResult(Result3dblobId, LabelOrIndex, (ResultType & (~M_HLVLDATATYPE_MASK)) + M_STRING_SIZE + M_TYPE_MIL_INT, &InternalStringSize);

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

   return 0.0;
   }

#endif
#endif
#endif /* M_MIL_USE_STRING*/


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

   UserVarPtr.resize(InternalNumberOfElementsForStdVector);

   if(InternalNumberOfElementsForStdVector > 0)
      {
      return M3dblobInquire(Context3dblobId, LabelOrIndex, InquireType, &UserVarPtr[0]);
      }
   return 0;
   }
template <typename UserType>
inline MIL_DOUBLE MFTYPE M3dblobGetResult(MIL_ID Result3dblobId, MIL_INT64 LabelOrIndex, 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("M3dblobGetResult"), 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;
   M3dblobGetResult(Result3dblobId, LabelOrIndex, M_STRIP_HLVLDATATYPE(ResultType) + M_NB_ELEMENTS + M_TYPE_MIL_INT, &InternalNumberOfElementsForStdVector);

   ResultArrayPtr.resize(InternalNumberOfElementsForStdVector);

   if(InternalNumberOfElementsForStdVector > 0)
      {
      M3dblobGetResult(Result3dblobId, LabelOrIndex, ResultType, &ResultArrayPtr[0]);
      }
   return 0.0;
   }
// ----------------------------------------------------------
// Overloads for std::vector in M3dblobStream.
inline void MFTYPE M3dblobStream(std::vector<MIL_UINT8> &MemPtrOrFileName,
                                 MIL_ID                 SysId,
                                 MIL_INT64              Operation,
                                 MIL_INT64              StreamType,
                                 MIL_DOUBLE             Version,
                                 MIL_INT64              ControlFlag,
                                 MIL_ID*                Context3dblobIdPtr,
                                 MIL_INT*               SizeByteVarPtr)
   {
   MxxxStreamForStdVector(MemPtrOrFileName,
                          SysId,
                          Operation,
                          StreamType,
                          Version,
                          ControlFlag,
                          Context3dblobIdPtr,
                          SizeByteVarPtr,
                          M3dblobStream);
   }
#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<&M3dblobFree>(MIL_INT64 ObjectType)
   {
   return (ObjectType & ~M_USER_DEFINE_LOW_ATTRIBUTE) == M_3DBLOB_OBJECT;
   }
#endif

typedef MIL_UNIQUE_ID<&M3dblobFree> MIL_UNIQUE_3DBLOB_ID;

#if M_MIL_USE_MOVE_SEMANTICS

inline MIL_UNIQUE_3DBLOB_ID M3dblobAlloc(MIL_ID SysId, MIL_INT64 ObjectType, MIL_INT64 InitFlag, MIL_UNIQUE_ID_TAG)
   {
   return MIL_UNIQUE_3DBLOB_ID(M3dblobAlloc(SysId, ObjectType, InitFlag, M_NULL));
   }
inline MIL_UNIQUE_3DBLOB_ID M3dblobAllocResult(MIL_ID     SysId, MIL_INT64  ResultType, MIL_INT64  ControlFlag, MIL_UNIQUE_ID_TAG)
   {
   return MIL_UNIQUE_3DBLOB_ID(M3dblobAllocResult(SysId, ResultType, ControlFlag, M_NULL));
   }
inline MIL_UNIQUE_3DBLOB_ID M3dblobRestore(MIL_CONST_TEXT_PTR FileName, MIL_ID SysId, MIL_INT64 ControlFlag, MIL_UNIQUE_ID_TAG)
   {
   return MIL_UNIQUE_3DBLOB_ID(M3dblobRestore(FileName, SysId, ControlFlag, M_NULL));
   }
#if M_MIL_USE_STRING
inline MIL_UNIQUE_3DBLOB_ID M3dblobRestore(const MIL_STRING& FileName, MIL_ID SysId, MIL_INT64 ControlFlag, MIL_UNIQUE_ID_TAG)
   {
   return MIL_UNIQUE_3DBLOB_ID(M3dblobRestore(FileName.c_str(), SysId, ControlFlag, M_NULL));
   }
#endif // M_MIL_USE_STRING
template <MilFreeFuncType FreeFunc> inline void M3dblobFree(const MIL_UNIQUE_ID<FreeFunc>&) = delete;

inline void M3dblobStream(MilStreamParam       MemPtrOrFileName,
                          MIL_ID               SysId,
                          MIL_INT64            Operation,
                          MIL_INT64            StreamType,
                          MIL_DOUBLE           Version,
                          MIL_INT64            ControlFlag,
                          MIL_UNIQUE_3DBLOB_ID* Context3dblobIdPtr,
                          MIL_INT*             SizeByteVarPtr)
   {
   MxxxStreamForMilUniqueId(MemPtrOrFileName, SysId, Operation, StreamType, Version, ControlFlag, Context3dblobIdPtr, SizeByteVarPtr, M3dblobStream);
   }

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