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

#ifndef __MIL_3DIM_H__
#define __MIL_3DIM_H__

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

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

//==============================================================================
// M3dimAlloc ContextTypes
#define M_CALCULATE_MAP_SIZE_CONTEXT                  3378L
#define M_MESH_CONTEXT                                3314  
#define M_NORMALS_CONTEXT                             3438
#define M_SUBSAMPLE_CONTEXT                           3639
#define M_STATISTICS_CONTEXT                          16L //Already defined in milim
#define M_FILL_GAPS_CONTEXT                           3759
#define M_SURFACE_SAMPLE_CONTEXT                      3799
#define M_FILTER_CONTEXT                              4846
#define M_REMAP_CONTEXT                               5405L
#define M_OUTLIERS_CONTEXT                            5716L
//==============================================================================   
// Indexing, used in other M3dim functions (M3dimInquire(), M3dimControl(), ...)
#define M_DEFAULT                               0x10000000L // already defined
#define M_CONTEXT                               0x08000000L // already defined
                                         
#define M_MODIFICATION_COUNT                          5010L // already defined

//==============================================================================
//M3dimCrop
#define M_SHRINK                                      3409
#define M_SAME                                         -1L//Already defined
#define M_INVERSE                                  0x00100//already defined in mil3d
#define M_UNORGANIZED                                1919L//Already defined in mil3dmap
//M3dimSample
#define M_ORGANIZED                                   3418
#define M_SUBSAMPLE_DECIMATE                          3046L
#define M_SUBSAMPLE_RANDOM                            3047L
#define M_SUBSAMPLE_GRID                              3049L
#define M_SUBSAMPLE_NORMAL                            3109L
#define M_SUBSAMPLE_GEOMETRIC                         5585L
#define M_INFINITE                                    -1L // Also defined in Mil.h
//M3dimMesh
#define M_MESH_SMOOTHED                               3097L
#define M_MESH_ORGANIZED                              3320L
#define M_MESH_LOCAL_PLANE                            5852L
//M3dimCopy
#define M_EXTENT_BOX                                  3466
//M3dimProject
#define M_POINT_BASED                                 3300
#define M_MESH_BASED                                  3301
#define M_OVERWRITE                                   1861L
#define M_MAX_INTENSITY                               2251L  // Already defined in mildmr
#define M_MIN_INTENSITY                                 12L  // Already defined in mildmr
//M3dimRotate
 #define M_GEOMETRY_CENTER                            3794
//Remove invalid
#define M_INVALID_POINTS_ONLY                         3734  
#define M_INVALID_NORMALS                             3735
#define M_NOT_MESH_POINTS                             4773
#define M_APPLY_TO_ALL_COMPONENTS                0x0001000L
//M3dimFix
#define M_RANGE_FINITE                          0x00000001L
#define M_NORMALS_FINITE                        0x00000002L
#define M_NORMALS_NORMALIZED                    0x00000004L
#define M_MESH_VALID_POINTS                     0x00000008L
#define M_MESH_VALID_NEIGHBORS                  0x00000010L
//M3dimTransformList
#define M_ROTATION_AND_SCALE                           3993
#define M_PLANAR                                0x00040000L //already defined in mil
#define M_PACKED                                0x00020000L             // Already defined in    mil.h, miledge.h
//M3dimMerge
//==============================================================================
// M3dimControl / M3dimInquire
// 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_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_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_ALLOCATION_FAILURE_REAL_TEST_FLAG            971L // also in milblob.h, milstr.h

 //Mesh Context
#define M_MESH_MODE                                   3430   
#define M_MAXIMUM_ORIENTATION_ANGLE_DIFFERENCE        3315
#define M_MAXIMUM_NUMBER_NEIGHBORS                    3316
#define M_NUMBER_POINTS_PER_CELL                      3317
#define M_MESH_TRIMMING_LEVEL                         5374
#define M_MAX_TREE_DEPTH                              3318
#define M_MAX_DISTANCE_TO_SOURCE                      3321
#define M_MESH_STEP_X                                 3322
#define M_MESH_STEP_Y                                 3323
#define M_MAX_DISTANCE                                 12L  // already defined
#define M_SURFACE_ANGLE_MAX                          5849L
#define M_TRIANGLE_ANGLE_MIN                         5850L
#define M_TRIANGLE_ANGLE_MAX                         5851L
//Normal Context
#define M_DIRECTION_MODE                              3431                
#define M_TOWARDS_POSITION                            3432
#define M_AWAY_FROM_POSITION                          3433
#define M_TOWARDS_DIRECTION                           3434
#define M_DIRECTION_REFERENCE_X                       3435
#define M_DIRECTION_REFERENCE_Y                       3436
#define M_DIRECTION_REFERENCE_Z                       3437
#define M_NEIGHBOR_SEARCH_MODE                        3041L 
#define M_TREE                                        3042L 
#define M_NEIGHBORHOOD_ORGANIZED_SIZE                 1943L
#define M_ENFORCE_CONTINUITY                          M_SMOOTH
#define M_SMOOTH                                      (M_ID_OFFSET_OF_DEFAULT_KERNEL +  0L)  // already defined in milim.h
#define M_NEIGHBORHOOD_DISTANCE                       3313
#define M_MESH                                        3994
#define M_ADD_CURVATURE                               5425  
 //Stat Context
#define M_BOUNDING_BOX                       0x00000003L 
#define M_BOUNDING_BOX_ALGORITHM                   1990L
#define M_BOUNDING_BOX_OUTLIER_RATIO_X             1991L 
#define M_BOUNDING_BOX_OUTLIER_RATIO_Y             1992L
#define M_BOUNDING_BOX_OUTLIER_RATIO_Z             1993L
#define M_BOUNDING_BOX_SECURITY_FACTOR_X           1994L
#define M_BOUNDING_BOX_SECURITY_FACTOR_Y           1995L
#define M_BOUNDING_BOX_SECURITY_FACTOR_Z           1996L
#define M_BOUNDING_BOX_CLAMP_TO_INLIERS            1997L
#define M_CENTROID                                 1956L
#define M_PCA                                      4855L
#define M_MOMENTS                                  4856L
#define M_MOMENT_ORDER                             4857L
#define M_COMPONENT_OF_INTEREST                    4858L
#define M_PCA_MODE                                 4859L
#define M_CENTRAL                                 0x800L // already defined in milblob.h
#define M_ORDINARY                                0x400L // already defined in milblob.h
#define M_EIGENVALUE_1                             4869L
#define M_EIGENVALUE_2                             4870L
#define M_EIGENVALUE_3                             4871L
#define M_PRINCIPAL_AXIS_1                         4872L
#define M_PRINCIPAL_AXIS_2                         4873L
#define M_PRINCIPAL_AXIS_3                         4874L
#define M_PRINCIPAL_AXIS_1_X                       4875L
#define M_PRINCIPAL_AXIS_1_Y                       4876L
#define M_PRINCIPAL_AXIS_1_Z                       4877L
#define M_PRINCIPAL_AXIS_2_X                       4878L
#define M_PRINCIPAL_AXIS_2_Y                       4879L
#define M_PRINCIPAL_AXIS_2_Z                       4880L
#define M_PRINCIPAL_AXIS_3_X                       4881L
#define M_PRINCIPAL_AXIS_3_Y                       4882L
#define M_PRINCIPAL_AXIS_3_Z                       4883L
#define M_PCA_MATRIX                               4884L
#define M_NORMALIZATION_MATRIX                     5023
#define M_COVARIANCE_MATRIX                        4885L
#define M_FIXTURING_MATRIX                         3878L // already defined in mil3dmet.h
#define M_NORMALIZATION_MODE                       5024
#define M_NORMALIZE_UNSIGNED                       5025
#define M_NORMALIZE_SIGNED                         5026
#define M_NORMALIZATION_SCALE                      2856L //already defined in milclass.h
#define M_UNIFORM                                  1     // Already defined MimHistogramEqualize(), milim.h
#define M_NON_UNIFORM                              5027
#define M_STANDARDIZATION_MATRIX                   5032
#define M_STANDARD_DEVIATION_X                     5033
#define M_STANDARD_DEVIATION_Y                     5034
#define M_STANDARD_DEVIATION_Z                     5035
#define M_APPROX_PRINCIPAL_AXIS_1_X                5322L
#define M_APPROX_PRINCIPAL_AXIS_1_Y                5323L
#define M_APPROX_PRINCIPAL_AXIS_1_Z                5324L
#define M_APPROX_PRINCIPAL_AXIS_2_X                5338L
#define M_APPROX_PRINCIPAL_AXIS_2_Y                5339L
#define M_APPROX_PRINCIPAL_AXIS_2_Z                5340L
#define M_APPROX_PRINCIPAL_AXIS_2_Z                5340L
#define M_BOX_ORIENTATION                          3814  // already defined in mil3dgeo.h
#define M_SEMI_ORIENTED                            5359L
#define M_AXIS_ALIGNED                       0x00040000  // already defined in mil.h
#define M_SEMI_ORIENTED_BOX_ANGLE                  5360L
#define M_CALCULATE_MIN                            5825L
#define M_CALCULATE_MAX                            5826L
#define M_CALCULATE_AVERAGE                        5827L
#define M_CALCULATE_STDEV                          5828L
#define M_CALCULATE_MEDIAN                         5829L
#define M_CALCULATE_ROBUST_STDEV                   5830L

 // Control Values for M_BOUNDING_BOX_ALGORITHM
#define M_ALL_POINTS                               1998L
#define M_ROBUST                                   1999L
//MapSize Context
#define M_PIXEL_ASPECT_RATIO                       5L//already defined
#define M_PIXEL_SIZE_X                                 139L // also in milcal.h
#define M_PIXEL_SIZE_Y                                 140L // also in milcal.h
#define M_SIZE_X                                      1536L // also in mil.h
#define M_SIZE_Y                                      1537L // also in mil.h
#define M_CALCULATE_MODE                              5443L 
#define M_NUMBER_OF_SAMPLES                             35L // already defined in milcol.h

 //Subsampling context
#define M_SUBSAMPLE_MODE                              3630
#define M_FRACTION_OF_POINTS                          3631
#define M_GRID_SIZE_X                                 3632
#define M_GRID_SIZE_Y                                 3633
#define M_GRID_SIZE_Z                                 3634
#define M_POINT_SELECTED                              3635
#define M_DISTINCT_ANGLE_DIFFERENCE                   3636
#define M_SUBSAMPLE_NORMAL_MODE                       3637
#define M_ORGANIZATION_TYPE                           3638
#define M_PRECISE                                     0x00040000L //already defined
#define M_FAST                                        0x00002000L // already defined in milim.h
#define M_STEP_SIZE_X                                 2153  // already defined
#define M_STEP_SIZE_Y                                 2160  // already defined
#define M_SEED_VALUE                                  2867L // already defined
//Fill gaps
#define M_FILL_MODE                                   3L 
#define M_FILL_SHARP_ELEVATION                        4L 
#define M_FILL_SHARP_ELEVATION_DEPTH                  5L
#define M_FILL_THRESHOLD_X                         1674L 
#define M_FILL_THRESHOLD_Y                         1675L 
#define M_FILL_BORDER                              3050L 
#define M_X_THEN_Y                                    1L
#define M_Y_THEN_X                                 1773L 
//surface sample context
#define M_RESOLUTION                                  7L // already defined
//filter context
#define M_FILTER_MODE                               122L  // already defined in miledge.h
#define M_POLYNOMIAL_ORDER                         4844
#define M_DISTANCE_WEIGHT                          4845
#define M_SMOOTH_MLS                               4847
#define M_SMOOTH_BILATERAL                         4848
#define M_NORMALS_WEIGHT_FACTOR                    4850
#define M_USE_SOURCE_NORMALS                       4852
#define M_NORMALS_CONTEXT_ID                       4854
#define M_WEIGHT_MODE                              4861
#define M_ABSOLUTE                                  1L      // already defined in milpat.h, milcol.h
#define M_RELATIVE                                 21L      // already defined in milcol.h

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

//==============================================================================
// M3dimAllocResult ResultTypes
#define M_STATISTICS_RESULT                           MAKE_INT64(0x0001000000000000)//Already defined
#define M_PROFILE_RESULT                              3910
#define M_FIND_TRANSFORMATION_RESULT                  5395
//==============================================================================
// M3dimGetResult ResultTypes
//Stat Result
#define M_NUMBER_OF_POINTS                        M_NUMBER //previously defined in metrol,  1009L
#define M_NUMBER_OF_POINTS_VALID                      3440
#define M_NUMBER_OF_POINTS_MISSING_DATA               3484
#define M_NUMBER_OF_POINTS_TOTAL                      3485
//Box
#define M_MIN_X                                       3382
#define M_MIN_Y                                       3383
#define M_MIN_Z                                       3384
#define M_MAX_X                                       3385
#define M_MAX_Y                                       3386
#define M_MAX_Z                                       3387
#define M_BOX_CENTER_X                                3445
#define M_BOX_CENTER_Y                                3446
#define M_BOX_CENTER_Z                                3447
#define M_SIZE_X                                      1536L       // Already defined in    milcode.h, mil.h
#define M_SIZE_Y                                      1537L       // Already defined in    milcode.h, mil.h
#define M_SIZE_Z                                      1538L // also in mil.h
//Distance
#define M_DISTANCE_TO_NEAREST_NEIGHBOR_MIN            3441
#define M_DISTANCE_TO_NEAREST_NEIGHBOR_AVERAGE        3442
#define M_DISTANCE_TO_NEAREST_NEIGHBOR_MAX            3443
#define M_DISTANCE_TO_NEAREST_NEIGHBOR_STDEV          5819
#define M_DISTANCE_TO_NEAREST_NEIGHBOR_MEDIAN         5820
#define M_DISTANCE_TO_NEAREST_NEIGHBOR_ROBUST_STDEV   5821
#define M_DISTANCE_TO_NEAREST_NEIGHBOR                3444
#define M_SURFACE_VARIATION_MIN                       4154
#define M_SURFACE_VARIATION_MAX                       4155
#define M_SURFACE_VARIATION_AVERAGE                   4156
#define M_SURFACE_VARIATION_STDEV                     5822
#define M_SURFACE_VARIATION_MEDIAN                    5823
#define M_SURFACE_VARIATION_ROBUST_STDEV              5824
#define M_SURFACE_VARIATION                           4157
//Centroid
#define M_CENTROID_X                                  3451
#define M_CENTROID_Y                                  3452
#define M_CENTROID_Z                                  3453
//Moments  
#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)

//Profile result
#define M_PROFILE_TYPE                                3890
#define M_PIXEL_X                                     3891
#define M_PIXEL_Y                                     3892
#define M_PROFILE_PLANE_X                             3893
#define M_PROFILE_PLANE_Y                             3894
#define M_WORLD_X                                     3895
#define M_WORLD_Y                                     3896
#define M_WORLD_Z                                     3897
#define M_MATRIX_WORLD_TO_PROFILE_PLANE               3898
#define M_MATRIX_PROFILE_PLANE_TO_WORLD               3899
//==============================================================================
//M3dimProfile
#define M_PROFILE_DEPTH_MAP                          3900
#define M_PROFILE_POINT_CLOUD                        3901
#define M_PROFILE_MESH                               3902
#define M_PROFILE_GEOMETRY                           5469
#define M_INFINITE_PROFILE                           4010
#define M_NO_PROFILE                                 5393
//M3dimArith
#define M_ADD                                        0x0000L //already defined
#define M_DIST_NN_SIGNED_TAG                         0x0200L
#define M_DIST_NN_TAG                                0x0600L
#define M_REPLACE_MISSING_DATA                        3090L
#define M_SUB                                        0x0001L // Already defined in milim.h
#define M_SUB_ABS                                    0x0011L // Already defined in milim.h
#define M_VALIDITY_MAP                               0x0800L
#define M_USE_SOURCE1_SCALES                           3091L
#define M_USE_SOURCE2_SCALES                           3092L
#define M_FIT_SCALES                                   1366L
#define M_SET_WORLD_OFFSET_Z                           1367L
#define M_USE_DESTINATION_SCALES                       1335L
#define M_DIST_NN_SIZE_MASK                           0x007FL
#define M_DIST_NN_SIGNED(N)             ((((N) >> 1) & M_DIST_NN_SIZE_MASK) | M_DIST_NN_SIGNED_TAG)
#define M_DIST_NN(N)                    ((((N) >> 1) & M_DIST_NN_SIZE_MASK) | M_DIST_NN_TAG)
#define M_NO_SRC_VALID_LABEL                          0L  
#define M_ONLY_SRC1_VALID_LABEL                      85L 
#define M_ONLY_SRC2_VALID_LABEL                     170L 
#define M_BOTH_SRC_VALID_LABEL                      255L
#define M_FLIP_Z                                    4748
//Calibrated depth map
#define M_POSITIVE                                    2L // Already defined in milmeas.h
#define M_NEGATIVE                                   -2L // Already defined in milmeas.h
//M3dimProject
#define M_ACCUMULATE                                 0x200L // already defined in milcal.h
#define M_SATURATION                                 0x2000L 
//M3dimRotate
#define M_ROTATION_AXIS_ANGLE                          2L //already defined in milcal.h
#define M_ROTATION_QUATERNION                          3L
#define M_ROTATION_YXZ                                 4L
#define M_ROTATION_X                                   7L
#define M_ROTATION_Y                                   8L
#define M_ROTATION_Z                                   9L
#define M_ROTATION_XYZ                                10L
#define M_ROTATION_XZY                                11L
#define M_ROTATION_YZX                                12L
#define M_ROTATION_ZXY                                13L
#define M_ROTATION_ZYX                                14L
#define M_ROTATION_AXIS_X                             17L
#define M_ROTATION_AXIS_Y                             18L
#define M_ROTATION_AXIS_Z                             19L
//M3dimFindTransformation
#define M_NOT_ENOUGH_POINT_PAIRS                     1972L // already defined in mil3dreg.h
#define M_MATHEMATICAL_EXCEPTION                        8L // already defined in milcal.h
#define M_NUMBER_OF_POINT_PAIRS                      5396L
#define M_RIGID                                      3411  // already defined in mil3dgeo.h
#define M_AFFINE                                     3416  // already defined in mil3dgeo.h
//M3dimRemapDepthMap
#define M_REMAP_MODE                                 5421L
#define M_DATA_EXTREMES                              5422L
#define M_BUFFER_LIMITS                              4672  // already defined in mil3dgra.h
#define M_GAUSSIAN                                  0x805L // already defined in miledge.h
#define M_USE_DESTINATION_CALIBRATION              0x0040L // already defined in milcal.h
#define M_REVERSE                                       4L // already defined in Mil.h
#define M_STANDARD_DEVIATION_FACTOR                  5423L
#define M_DIRECTION_Z                                5424L
//M3dimGetList
#define M_INCLUDE_INVALID_POINTS               0x00000100L
#define M_SKIP_INVALID_POINTS                  0x00000200L
#define M_BICUBIC                              0x00000010L // already defined in mil.h
#define M_BILINEAR                             0x00000008L // already defined in mil.h
#define M_NEAREST_NEIGHBOR                     0x00000040L // already defined in mil.h
//M3dimOutliers          
#define M_MINIMUM_NUMBER_NEIGHBORS             5727
#define M_OUTLIER_MODE                         5728               
#define M_NEIGHBORHOOD_DISTANCE_MODE           5729
#define M_NUMBER_WITHIN_DISTANCE               5730
#define M_LOCAL_DISTANCE                       5731
#define M_LOCAL_DENSITY_PROBABILITY            5732
#define M_PROBABILITY_THRESHOLD_FACTOR         5733
#define M_DISTANCE_THRESHOLD_MODE              5750         
#define M_RELATIVE_LOCAL_DISTANCE              5751       
#define M_NUMBER_NEIGHBORS                     5734
#define M_STD_DEVIATION                        5752 
#define M_ROBUST_STD_DEVIATION                 5753      
#define M_STD_DEVIATION_FACTOR                 5762
#define M_NEIGHBORHOOD_DISTANCE_METRIC         5815 

//==============================================================================
// Pseudo Ids
#define M_MESH_CONTEXT_SMOOTHED                       (M_3DIM_PSEUDO_ID + M_MESH_SMOOTHED)  // Used by M3dimMesh
#define M_MESH_CONTEXT_ORGANIZED                      (M_3DIM_PSEUDO_ID + M_MESH_ORGANIZED)  // Used by M3dimMesh
#define M_MESH_CONTEXT_LOCAL_PLANE                    (M_3DIM_PSEUDO_ID + M_MESH_LOCAL_PLANE)  // Used by M3dimMesh
#define M_NORMALS_CONTEXT_TREE                        (M_3DIM_PSEUDO_ID + M_TREE)  // Used by M3dimNormals
#define M_NORMALS_CONTEXT_ORGANIZED                   (M_3DIM_PSEUDO_ID + M_ORGANIZED)  // Used by M3dimNormals
#define M_NORMALS_CONTEXT_MESH                        (M_3DIM_PSEUDO_ID + M_MESH)  // Used by M3dimNormals
#define M_FIND_TRANSFORMATION_CONTEXT_RIGID           (M_3DIM_PSEUDO_ID + M_RIGID)  // Used by M3dimFindTransformation
#define M_FIND_TRANSFORMATION_CONTEXT_AFFINE          (M_3DIM_PSEUDO_ID + M_AFFINE)  // Used by M3dimFindTransformation
#define M_REMAP_CONTEXT_BUFFER_LIMITS                 (M_3DIM_PSEUDO_ID + M_BUFFER_LIMITS)  // Used by M3dimRemapDepthMap
#define M_REMAP_CONTEXT_DATA_EXTREMES                 (M_3DIM_PSEUDO_ID + M_DATA_EXTREMES)  // Used by M3dimRemapDepthMap
#define M_REMAP_CONTEXT_USE_DESTINATION               (M_3DIM_PSEUDO_ID + M_USE_DESTINATION_CALIBRATION)  // Used by M3dimRemapDepthMap

#define M_3DIM_STAT_PSEUDO_ID                         (M_3DIM_PSEUDO_ID +0x030000)
#define M_STAT_CONTEXT_BOUNDING_BOX                   (M_3DIM_STAT_PSEUDO_ID + M_BOUNDING_BOX)
#define M_STAT_CONTEXT_NUMBER_OF_POINTS               (M_3DIM_STAT_PSEUDO_ID + M_NUMBER_OF_POINTS)
#define M_STAT_CONTEXT_DISTANCE_TO_NEAREST_NEIGHBOR   (M_3DIM_STAT_PSEUDO_ID + M_DISTANCE_TO_NEAREST_NEIGHBOR)
#define M_STAT_CONTEXT_CENTROID                       (M_3DIM_STAT_PSEUDO_ID + M_CENTROID)
#define M_STAT_CONTEXT_PCA                            (M_3DIM_STAT_PSEUDO_ID + M_PCA)
#define M_STAT_CONTEXT_PCA_NORMALS                    (M_3DIM_STAT_PSEUDO_ID + M_PCA + M_NORMAL)
#define M_STAT_CONTEXT_SEMI_ORIENTED_BOX              (M_3DIM_STAT_PSEUDO_ID + M_SEMI_ORIENTED)

// 3dimoutliers
#define M_OUTLIERS_CONTEXT_ROBUST_STD_DEVIATION       (M_3DIM_PSEUDO_ID + M_LOCAL_DISTANCE + M_ROBUST_STD_DEVIATION)
#define M_OUTLIERS_CONTEXT_STD_DEVIATION              (M_3DIM_PSEUDO_ID + M_LOCAL_DISTANCE + M_STD_DEVIATION)
#define M_OUTLIERS_CONTEXT_NUMBER_WITHIN_DISTANCE     (M_3DIM_PSEUDO_ID + M_NUMBER_WITHIN_DISTANCE)
#define M_OUTLIERS_CONTEXT_PROBABILITY                (M_3DIM_PSEUDO_ID + M_LOCAL_DENSITY_PROBABILITY)

////////////////////////////////////////////////////////////////////////////////
// Deprecated starting 10 SP6                                                 //
////////////////////////////////////////////////////////////////////////////////
#if OldDefinesSupport
#define M_MIN_DISTANCE_TO_NEAREST_NEIGHBOR        3441
#define M_AVG_DISTANCE_TO_NEAREST_NEIGHBOR        3442
#define M_MAX_DISTANCE_TO_NEAREST_NEIGHBOR        3443

MIL_DEPRECATED(M_MIN_DISTANCE_TO_NEAREST_NEIGHBOR, 1060)
MIL_DEPRECATED(M_MAX_DISTANCE_TO_NEAREST_NEIGHBOR, 1060)
MIL_DEPRECATED(M_AVG_DISTANCE_TO_NEAREST_NEIGHBOR, 1060)
#endif

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

 MIL_ID MFTYPE M3dimAllocResult(MIL_ID    SysId,
                                MIL_INT64 ResultType,
                                MIL_INT64 ControlFlag,
                                MIL_ID*   Result3dimIdPtr);

 void MFTYPE M3dimFree(MIL_ID ContextOrResult3dimId);

 void MFTYPE M3dimTranslate(MIL_ID     SrcContainerBufOrGeometry3dgeoId,
                                            MIL_ID     DstContainerBufOrGeometry3dgeoId,
                                            MIL_DOUBLE TranslationX,
                                            MIL_DOUBLE TranslationY,
                                            MIL_DOUBLE TranslationZ,
                                            MIL_INT64  ControlFlag);

 void MFTYPE M3dimScale(MIL_ID     SrcContainerBufOrGeometry3dgeoId,
                                        MIL_ID     DstContainerBufOrGeometry3dgeoId,
                                        MIL_DOUBLE ScaleX,
                                        MIL_DOUBLE ScaleY,
                                        MIL_DOUBLE ScaleZ,
                                        MIL_DOUBLE CenterX,
                                        MIL_DOUBLE CenterY,
                                        MIL_DOUBLE CenterZ,
                                        MIL_INT64  ControlFlag);

  void MFTYPE M3dimRotate(MIL_ID     SrcContainerBufOrGeometry3dgeoId,
                                          MIL_ID     DstContainerBufOrGeometry3dgeoId,
                                          MIL_INT64  RotationType,
                                          MIL_DOUBLE Param1,
                                          MIL_DOUBLE Param2,
                                          MIL_DOUBLE Param3,
                                          MIL_DOUBLE Param4,
                                          MIL_DOUBLE CenterX,
                                          MIL_DOUBLE CenterY,
                                          MIL_DOUBLE CenterZ,
                                          MIL_INT64  ControlFlag);

 void MFTYPE M3dimMatrixTransform(MIL_ID    SrcContainerBufOrGeometry3dgeoId,
                                                  MIL_ID    DstContainerBufOrGeometry3dgeoId,
                                                  MIL_ID    Matrix3dgeoId,
                                                  MIL_INT64 ControlFlag);

 void MFTYPE M3dimCrop(MIL_ID    SrcContainerBufId,
                       MIL_ID    DstContainerBufId,
                       MIL_ID    ImageBufOrGeometry3dgeoId,
                       MIL_ID    Matrix3dgeoId,
                       MIL_INT64 OrganizationType,
                       MIL_INT64 ControlFlag);

 void MFTYPE M3dimMerge(const MIL_ID* SrcContainerBufIdArrayPtr,
                        MIL_ID        DstContainerBufId,
                        MIL_INT       NumContainers,
                        MIL_ID        SubsampleContext3dimId,
                        MIL_INT64     ControlFlag);


  void MFTYPE  M3dimSample(MIL_ID     SampleContext3dimId,
                           MIL_ID     SrcContainerBufOrGeometry3dgeoId,
                           MIL_ID     DstContainerBufId,
                           MIL_INT64  ControlFlag);

  void MFTYPE M3dimNormals(MIL_ID    NormalsContext3dimId,
                           MIL_ID    SrcContainerBufId,
                           MIL_ID    DstContainerBufId,
                           MIL_INT64 ControlFlag);

  void MFTYPE M3dimMesh(MIL_ID    MeshContext3dimId,
                        MIL_ID    SrcContainerBufId,
                        MIL_ID    DstContainerBufId,
                        MIL_INT64 ControlFlag);

  void MFTYPE M3dimStat(MIL_ID      StatContext3dimId,
                        MIL_ID      MilObjectId,
                        MIL_ID      StatResult3dimOrGeometry3dgeoId,
                        MIL_INT64   ControlFlag);

 void MFTYPE M3dimCopyResult(MIL_ID     SrcResult3dimId,
                             MIL_ID     DstGeometryOrMatrix3dgeoId,
                             MIL_INT64  CopyType,
                             MIL_INT64  ControlFlag);

 void MFTYPE M3dimProject(MIL_ID    SrcContainerBufOrGeometry3dgeoId,
                          MIL_ID    DepthMapImageBufId,
                          MIL_ID    IntensityMapImageBufId,
                          MIL_INT64 ProjectionMode,
                          MIL_INT64 OverlapMode,
                          MIL_INT64 Options,
                          MIL_INT64 ControlFlag);

 void MFTYPE M3dimCopy(MIL_ID     SrcDepthMapImageBufId,
                       MIL_ID     DstGeometry3dgeoId,
                       MIL_INT64  CopyType,
                       MIL_INT64  ControlFlag);

 void MFTYPE M3dimCalibrateDepthMap(MIL_ID     SrcContainerBufOrGeometry3dgeoId,
                                    MIL_ID     DepthMapImageBufId,
                                    MIL_ID     IntensityMapImageBufId,
                                    MIL_ID     CalibrationMilObjectOrMatrix3dgeoId,
                                    MIL_DOUBLE PixelSizeAspectRatio,
                                    MIL_INT64  ZSign,
                                    MIL_INT64  ControlFlag);

 void MFTYPE M3dimMatrixTransformListDouble(MIL_ID            Matrix3dgeoId,
                                            MIL_INT           NumPoints,
                                            const MIL_DOUBLE* SrcCoordXArrayPtr,
                                            const MIL_DOUBLE* SrcCoordYArrayPtr,
                                            const MIL_DOUBLE* SrcCoordZArrayPtr,
                                            MIL_DOUBLE*       DstCoordXArrayPtr,
                                            MIL_DOUBLE*       DstCoordYArrayPtr,
                                            MIL_DOUBLE*       DstCoordZArrayPtr,
                                            MIL_INT64         ControlFlag);

 void MFTYPE M3dimMatrixTransformListFloat(MIL_ID           Matrix3dgeoId,
                                           MIL_INT          NumPoints,
                                           const MIL_FLOAT* SrcCoordXArrayPtr,
                                           const MIL_FLOAT* SrcCoordYArrayPtr,
                                           const MIL_FLOAT* SrcCoordZArrayPtr,
                                           MIL_FLOAT*       DstCoordXArrayPtr,
                                           MIL_FLOAT*       DstCoordYArrayPtr,
                                           MIL_FLOAT*       DstCoordZArrayPtr,
                                           MIL_INT64        ControlFlag);

 void MFTYPE M3dimCalculateMapSize(MIL_ID    CalculateMapSizeContext3dimId,
                                   MIL_ID    SrcContainerBufId,
                                   MIL_ID    AABox3dgeoId,
                                   MIL_INT64 ControlFlag,
                                   MIL_INT*  DepthMapSizeXPtr,
                                   MIL_INT*  DepthMapSizeYPtr);

 void MFTYPE M3dimRemovePoints(MIL_ID    SrcContainerBufId,
                               MIL_ID    DstContainerBufId,
                               MIL_INT64 Option,
                               MIL_INT64 ControlFlag);

 void MFTYPE M3dimArith(MIL_ID    Src1ImageBufOrGeometry3dgeoId,
                        MIL_ID    Src2ImageBufOrGeometry3dgeoId,
                        MIL_ID    DstImageBufId,
                        MIL_ID    MaskBufId,
                        MIL_INT64 Operation,
                        MIL_INT64 SignMode,
                        MIL_INT64 ControlFlag);

 void MFTYPE M3dimFillGaps(MIL_ID     GapFillingContext3dimId,
                           MIL_ID     DepthMapImageBufId,
                           MIL_ID     IntensityMapImageBufId,
                           MIL_INT64  ControlFlag);

 void MFTYPE M3dimFix(MIL_ID     SrcContainerBufId,
                      MIL_ID     DstContainerBufId,
                      MIL_INT64  Conditions,
                      MIL_INT64  ControlFlag,
                      MIL_INT64* ResultPtr);

 void MFTYPE M3dimProfile(MIL_ID    SrcMilObjectId,
                          MIL_ID    ProfileResult3dimId,
                          MIL_INT64 ProfileType,
                          MIL_INT64 Param1,
                          MIL_DOUBLE Param2,
                          MIL_DOUBLE Param3,
                          MIL_DOUBLE Param4,
                          MIL_DOUBLE Param5,
                          MIL_INT64  ControlFlag);

 MIL_INT64 MFTYPE M3dimDraw3d(MIL_ID    OperationDraw3dContext3dimId,
                              MIL_ID    SrcProfileResult3dimId,
                              MIL_ID    DstList3dgraId,
                              MIL_INT64 DstParentLabel,
                              MIL_INT64 ControlFlag);

 void MFTYPE M3dimFilter(MIL_ID    FilterContext3dimId,
                         MIL_ID    SrcContainerBufId,
                         MIL_ID    DstContainerBufId,
                         MIL_INT64 ControlFlag);


 void MFTYPE M3dimOutliers(MIL_ID    OutliersContext3dimId   ,
                           MIL_ID    SrcContainerOrImageBufId,
                           MIL_ID    Dst1ContainerOrImageBufId,
                           MIL_ID    Dst2ImageBufId,
                           MIL_INT64 ControlFlag);

 void MFTYPE M3dimFindTransformation(MIL_ID    FindTransformationContext3dimId,
                                     MIL_ID    SourceContainerOrArrayBufId,
                                     MIL_ID    TargetContainerOrArrayBufId,
                                     MIL_ID    Result3dimOrMatrix3dgeoId,
                                     MIL_INT64 ControlFlag);

 void MFTYPE M3dimRemapDepthMap(MIL_ID    RemapContext3dimId,
                                MIL_ID    SrcImageBufId,
                                MIL_ID    DstImageBufId,
                                MIL_INT64 ControlFlag);

 MIL_INT MFTYPE M3dimGetFloat(MIL_ID      ContainerOrImageBufId,
                              MIL_INT64   Component,
                              MIL_INT     ArraySize,
                              MIL_INT64   Options,
                              MIL_FLOAT*  DstCoord1OrPackedArrayPtr,
                              MIL_FLOAT*  DstCoord2ArrayPtr,
                              MIL_FLOAT*  DstCoord3ArrayPtr);
 MIL_INT MFTYPE M3dimGetDouble(MIL_ID       ContainerOrImageBufId,
                               MIL_INT64    Component,
                               MIL_INT      ArraySize,
                               MIL_INT64    Options,
                               MIL_DOUBLE*  DstCoord1OrPackedArrayPtr,
                               MIL_DOUBLE*  DstCoord2ArrayPtr,
                               MIL_DOUBLE*  DstCoord3ArrayPtr);
 MIL_INT MFTYPE M3dimGetUint32(MIL_ID       ContainerOrImageBufId,
                               MIL_INT64    Component,
                               MIL_INT      ArraySize,
                               MIL_INT64    Options,
                               MIL_UINT32*  DstCoord1OrPackedArrayPtr,
                               MIL_UINT32*  DstCoord2ArrayPtr,
                               MIL_UINT32*  DstCoord3ArrayPtr);
 MIL_INT MFTYPE M3dimGetUint16(MIL_ID       ContainerOrImageBufId,
                               MIL_INT64    Component,
                               MIL_INT      ArraySize,
                               MIL_INT64    Options,
                               MIL_UINT16*  DstCoord1OrPackedArrayPtr,
                               MIL_UINT16*  DstCoord2ArrayPtr,
                               MIL_UINT16*  DstCoord3ArrayPtr);
 MIL_INT MFTYPE M3dimGetUint8(MIL_ID      ContainerOrImageBufId,
                              MIL_INT64   Component,
                              MIL_INT     ArraySize,
                              MIL_INT64   Options,
                              MIL_UINT8*  DstCoord1OrPackedArrayPtr,
                              MIL_UINT8*  DstCoord2ArrayPtr,
                              MIL_UINT8*  DstCoord3ArrayPtr);
 MIL_INT MFTYPE M3dimGetInt32(MIL_ID      ContainerOrImageBufId,
                              MIL_INT64   Component,
                              MIL_INT     ArraySize,
                              MIL_INT64   Options,
                              MIL_INT32*  DstCoord1OrPackedArrayPtr,
                              MIL_INT32*  DstCoord2ArrayPtr,
                              MIL_INT32*  DstCoord3ArrayPtr);
 MIL_INT MFTYPE M3dimGetInt16(MIL_ID      ContainerOrImageBufId,
                              MIL_INT64   Component,
                              MIL_INT     ArraySize,
                              MIL_INT64   Options,
                              MIL_INT16*  DstCoord1OrPackedArrayPtr,
                              MIL_INT16*  DstCoord2ArrayPtr,
                              MIL_INT16*  DstCoord3ArrayPtr);
 MIL_INT MFTYPE M3dimGetInt8(MIL_ID     ContainerOrImageBufId,
                             MIL_INT64  Component,
                             MIL_INT    ArraySize,
                             MIL_INT64  Options,
                             MIL_INT8*  DstCoord1OrPackedArrayPtr,
                             MIL_INT8*  DstCoord2ArrayPtr,
                             MIL_INT8*  DstCoord3ArrayPtr);

 // M3dimGetList is declared by a macro to not pollute the header.
#define M_DECLARE_M3DIMGETLIST(FuncName, InType, OutType, IndexType)             \
 MIL_INT MFTYPE FuncName(MIL_ID        ContainerOrImageBufId,                    \
                         MIL_INT64     Component,                                \
                         MIL_INT       SrcArraySize,                             \
                         const InType* SrcPixelXArrayPtr,                        \
                         const InType* SrcPixelYArrayPtr,                        \
                         MIL_INT64     Options,                                  \
                         OutType*      DstCoord1OrPackedArrayPtr,                \
                         OutType*      DstCoord2ArrayPtr,                        \
                         OutType*      DstCoord3ArrayPtr,                        \
                         IndexType*    IndexArrayPtr);                           \
M_DECLARE_M3DIMGETLIST_OVERLOAD(FuncName, InType, OutType, IndexType)

#ifdef __cplusplus
#define M_DECLARE_M3DIMGETLIST_OVERLOAD(FuncName, InType, OutType, IndexType)    \
}                                                                                \
 inline MIL_INT M3dimGetListCpp(MIL_ID        ContainerOrImageBufId,             \
                                MIL_INT64     Component,                         \
                                MIL_INT       SrcArraySize,                      \
                                const InType* SrcPixelXArrayPtr,                 \
                                const InType* SrcPixelYArrayPtr,                 \
                                MIL_INT64     Options,                           \
                                OutType*      DstCoord1OrPackedArrayPtr,         \
                                OutType*      DstCoord2ArrayPtr,                 \
                                OutType*      DstCoord3ArrayPtr,                 \
                                IndexType*    IndexArrayPtr)                     \
    {                                                                            \
    return FuncName(ContainerOrImageBufId,                                       \
                    Component,                                                   \
                    SrcArraySize,                                                \
                    SrcPixelXArrayPtr,                                           \
                    SrcPixelYArrayPtr,                                           \
                    Options,                                                     \
                    DstCoord1OrPackedArrayPtr,                                   \
                    DstCoord2ArrayPtr,                                           \
                    DstCoord3ArrayPtr,                                           \
                    IndexArrayPtr);                                              \
    }                                                                            \
 extern "C" {
#else
#define M_DECLARE_M3DIMGETLIST_OVERLOAD(FuncName, InType, OutType, IndexType)
#endif

 M_DECLARE_M3DIMGETLIST(M3dimGetListInt32Int8,    MIL_INT32,  MIL_INT8,   MIL_INT32);
 M_DECLARE_M3DIMGETLIST(M3dimGetListInt32Int16,   MIL_INT32,  MIL_INT16,  MIL_INT32);
 M_DECLARE_M3DIMGETLIST(M3dimGetListInt32Int32,   MIL_INT32,  MIL_INT32,  MIL_INT32);
 M_DECLARE_M3DIMGETLIST(M3dimGetListInt32Uint8,   MIL_INT32,  MIL_UINT8,  MIL_INT32);
 M_DECLARE_M3DIMGETLIST(M3dimGetListInt32Uint16,  MIL_INT32,  MIL_UINT16, MIL_INT32);
 M_DECLARE_M3DIMGETLIST(M3dimGetListInt32Uint32,  MIL_INT32,  MIL_UINT32, MIL_INT32);
 M_DECLARE_M3DIMGETLIST(M3dimGetListInt32Float,   MIL_INT32,  MIL_FLOAT,  MIL_INT32);
 M_DECLARE_M3DIMGETLIST(M3dimGetListInt32Double,  MIL_INT32,  MIL_DOUBLE, MIL_INT32);
 
 M_DECLARE_M3DIMGETLIST(M3dimGetListDoubleInt8,   MIL_DOUBLE, MIL_INT8,   MIL_INT32);
 M_DECLARE_M3DIMGETLIST(M3dimGetListDoubleInt16,  MIL_DOUBLE, MIL_INT16,  MIL_INT32);
 M_DECLARE_M3DIMGETLIST(M3dimGetListDoubleInt32,  MIL_DOUBLE, MIL_INT32,  MIL_INT32);
 M_DECLARE_M3DIMGETLIST(M3dimGetListDoubleUint8,  MIL_DOUBLE, MIL_UINT8,  MIL_INT32);
 M_DECLARE_M3DIMGETLIST(M3dimGetListDoubleUint16, MIL_DOUBLE, MIL_UINT16, MIL_INT32);
 M_DECLARE_M3DIMGETLIST(M3dimGetListDoubleUint32, MIL_DOUBLE, MIL_UINT32, MIL_INT32);
 M_DECLARE_M3DIMGETLIST(M3dimGetListDoubleFloat,  MIL_DOUBLE, MIL_FLOAT,  MIL_INT32);
 M_DECLARE_M3DIMGETLIST(M3dimGetListDoubleDouble, MIL_DOUBLE, MIL_DOUBLE, MIL_INT32);

#undef M_DECLARE_M3DIMGETLIST
#undef M_DECLARE_M3DIMGETLIST_OVERLOAD


//#if M_MIL_USE_64BIT
// Prototypes for 64 bits OSs
 void MFTYPE M3dimControlInt64(MIL_ID     Context3dimId,
                                               MIL_INT64  ControlType,
                                               MIL_INT64  ControlValue);
 void MFTYPE M3dimControlDouble(MIL_ID     Context3dimId,
                                                MIL_INT64  ControlType,
                                                MIL_DOUBLE ControlValue);

 MIL_INT64 MFTYPE M3dimInquire(MIL_ID    Context3dimId,
                                               MIL_INT64 InquireType,
                                               void*     UserVarPtr);

 MIL_DOUBLE MFTYPE M3dimGetResult(MIL_ID    Result3dimId,
                                  MIL_INT64 ResultType,
                                  void*     ResultArrayPtr);

#if M_MIL_USE_UNICODE
 void MFTYPE M3dimSaveA(MIL_CONST_TEXTA_PTR FileName,
                                        MIL_ID              Context3dimId,
                                        MIL_INT64           ControlFlag);

 MIL_ID MFTYPE M3dimRestoreA(MIL_CONST_TEXTA_PTR FileName,
                                             MIL_ID              SysId,
                                             MIL_INT64           ControlFlag,
                                             MIL_ID*             Context3dimIdPtr);

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



 void MFTYPE M3dimSaveW(MIL_CONST_TEXTW_PTR FileName,
                                        MIL_ID              Context3dimId,
                                        MIL_INT64           ControlFlag);

 MIL_ID MFTYPE M3dimRestoreW(MIL_CONST_TEXTW_PTR FileName,
                                             MIL_ID              SysId,
                                             MIL_INT64           ControlFlag,
                                             MIL_ID*             Context3dimIdPtr);

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

#if M_MIL_UNICODE_API
#define M3dimSave               M3dimSaveW
#define M3dimRestore            M3dimRestoreW
#define M3dimStream             M3dimStreamW
#else
#define M3dimSave               M3dimSaveA
#define M3dimRestore            M3dimRestoreA
#define M3dimStream             M3dimStreamA
#endif //M_MIL_UNICODE_API

#else

 void MFTYPE   M3dimSave(MIL_CONST_TEXT_PTR FileName,
                                         MIL_ID             Context3dimId,
                                         MIL_INT64          ControlFlag);

 MIL_ID MFTYPE M3dimRestore(MIL_CONST_TEXT_PTR FileName,
                                            MIL_ID             SysId,
                                            MIL_INT64          ControlFlag,
                                            MIL_ID*            Context3dimIdPtr);

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

#endif //M_MIL_USE_UNICODE

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

////////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
//C++ overloads
inline void M3dimMatrixTransformList(MIL_ID            Matrix3dgeoId,
                                     MIL_INT           NumPoints,
                                     const MIL_DOUBLE* SrcCoordXArrayPtr,
                                     const MIL_DOUBLE* SrcCoordYArrayPtr,
                                     const MIL_DOUBLE* SrcCoordZArrayPtr,
                                     MIL_DOUBLE*       DstCoordXArrayPtr,
                                     MIL_DOUBLE*       DstCoordYArrayPtr,
                                     MIL_DOUBLE*       DstCoordZArrayPtr,
                                     MIL_INT64         ControlFlag)
   {
   return M3dimMatrixTransformListDouble(Matrix3dgeoId,
                                         NumPoints,
                                         SrcCoordXArrayPtr,
                                         SrcCoordYArrayPtr,
                                         SrcCoordZArrayPtr,
                                         DstCoordXArrayPtr,
                                         DstCoordYArrayPtr,
                                         DstCoordZArrayPtr,
                                         ControlFlag);
   }
inline void M3dimMatrixTransformList(MIL_ID           Matrix3dgeoId,
                                     MIL_INT          NumPoints,
                                     const MIL_FLOAT* SrcCoordXArrayPtr,
                                     const MIL_FLOAT* SrcCoordYArrayPtr,
                                     const MIL_FLOAT* SrcCoordZArrayPtr,
                                     MIL_FLOAT*       DstCoordXArrayPtr,
                                     MIL_FLOAT*       DstCoordYArrayPtr,
                                     MIL_FLOAT*       DstCoordZArrayPtr,
                                     MIL_INT64        ControlFlag)
   {
   return M3dimMatrixTransformListFloat(Matrix3dgeoId,
                                        NumPoints,
                                        SrcCoordXArrayPtr,
                                        SrcCoordYArrayPtr,
                                        SrcCoordZArrayPtr,
                                        DstCoordXArrayPtr,
                                        DstCoordYArrayPtr,
                                        DstCoordZArrayPtr,
                                        ControlFlag);
   }
inline void MFTYPE M3dimStreamCpp(MilStreamParam MemPtrOrFileName,
                                  MIL_ID         SysId,
                                  MIL_INT64      Operation,
                                  MIL_INT64      StreamType,
                                  MIL_DOUBLE     Version,
                                  MIL_INT64      ControlFlag,
                                  MIL_ID*        Context3dimIdPtr,
                                  MIL_INT*       SizeByteVarPtr)
   {
   M3dimStream(MemPtrOrFileName.m_Param, SysId, Operation, StreamType, Version, ControlFlag, Context3dimIdPtr, SizeByteVarPtr);
   }

#undef  M3dimStream
#define M3dimStream M3dimStreamCpp
#else
#define M3dimMatrixTransformList M3dimMatrixTransformListDouble
#endif // __cplusplus

#ifdef __cplusplus
inline MIL_INT M3dimGet(MIL_ID       ContainerOrImageBufId,
                        MIL_INT64    Component,
                        MIL_INT      ArraySize,
                        MIL_INT64    Options,
                        MIL_DOUBLE*  DstCoord1OrPackedArrayPtr,
                        MIL_DOUBLE*  DstCoord2ArrayPtr,
                        MIL_DOUBLE*  DstCoord3ArrayPtr)
   {
   return M3dimGetDouble(ContainerOrImageBufId,
                         Component,
                         ArraySize,
                         Options,
                         DstCoord1OrPackedArrayPtr,
                         DstCoord2ArrayPtr,
                         DstCoord3ArrayPtr);
   }
inline MIL_INT M3dimGet(MIL_ID      ContainerOrImageBufId,
                        MIL_INT64   Component,
                        MIL_INT     ArraySize,
                        MIL_INT64   Options,
                        MIL_FLOAT*  DstCoord1OrPackedArrayPtr,
                        MIL_FLOAT*  DstCoord2ArrayPtr,
                        MIL_FLOAT*  DstCoord3ArrayPtr)
   {
   return M3dimGetFloat(ContainerOrImageBufId,
                        Component,
                        ArraySize,
                        Options,
                        DstCoord1OrPackedArrayPtr,
                        DstCoord2ArrayPtr,
                        DstCoord3ArrayPtr);
   }
inline MIL_INT M3dimGet(MIL_ID       ContainerOrImageBufId,
                        MIL_INT64    Component,
                        MIL_INT      ArraySize,
                        MIL_INT64    Options,
                        MIL_UINT32*  DstCoord1OrPackedArrayPtr,
                        MIL_UINT32*  DstCoord2ArrayPtr,
                        MIL_UINT32*  DstCoord3ArrayPtr)
   {
   return M3dimGetUint32(ContainerOrImageBufId,
                         Component,
                         ArraySize,
                         Options,
                         DstCoord1OrPackedArrayPtr,
                         DstCoord2ArrayPtr,
                         DstCoord3ArrayPtr);
   }
inline MIL_INT M3dimGet(MIL_ID       ContainerOrImageBufId,
                        MIL_INT64    Component,
                        MIL_INT      ArraySize,
                        MIL_INT64    Options,
                        MIL_UINT16*  DstCoord1OrPackedArrayPtr,
                        MIL_UINT16*  DstCoord2ArrayPtr,
                        MIL_UINT16*  DstCoord3ArrayPtr)
   {
   return M3dimGetUint16(ContainerOrImageBufId,
                         Component,
                         ArraySize,
                         Options,
                         DstCoord1OrPackedArrayPtr,
                         DstCoord2ArrayPtr,
                         DstCoord3ArrayPtr);
   }
inline MIL_INT M3dimGet(MIL_ID      ContainerOrImageBufId,
                        MIL_INT64   Component,
                        MIL_INT     ArraySize,
                        MIL_INT64   Options,
                        MIL_UINT8*  DstCoord1OrPackedArrayPtr,
                        MIL_UINT8*  DstCoord2ArrayPtr,
                        MIL_UINT8*  DstCoord3ArrayPtr)
   {
   return M3dimGetUint8(ContainerOrImageBufId,
                        Component,
                        ArraySize,
                        Options,
                        DstCoord1OrPackedArrayPtr,
                        DstCoord2ArrayPtr,
                        DstCoord3ArrayPtr);
   }
inline MIL_INT M3dimGet(MIL_ID      ContainerOrImageBufId,
                        MIL_INT64   Component,
                        MIL_INT     ArraySize,
                        MIL_INT64   Options,
                        MIL_INT32*  DstCoord1OrPackedArrayPtr,
                        MIL_INT32*  DstCoord2ArrayPtr,
                        MIL_INT32*  DstCoord3ArrayPtr)
   {
   return M3dimGetInt32(ContainerOrImageBufId,
                         Component,
                         ArraySize,
                         Options,
                         DstCoord1OrPackedArrayPtr,
                         DstCoord2ArrayPtr,
                         DstCoord3ArrayPtr);
   }
inline MIL_INT M3dimGet(MIL_ID      ContainerOrImageBufId,
                        MIL_INT64   Component,
                        MIL_INT     ArraySize,
                        MIL_INT64   Options,
                        MIL_INT16*  DstCoord1OrPackedArrayPtr,
                        MIL_INT16*  DstCoord2ArrayPtr,
                        MIL_INT16*  DstCoord3ArrayPtr)
   {
   return M3dimGetInt16(ContainerOrImageBufId,
                        Component,
                        ArraySize,
                        Options,
                        DstCoord1OrPackedArrayPtr,
                        DstCoord2ArrayPtr,
                        DstCoord3ArrayPtr);
   }
inline MIL_INT M3dimGet(MIL_ID     ContainerOrImageBufId,
                        MIL_INT64  Component,
                        MIL_INT    ArraySize,
                        MIL_INT64  Options,
                        MIL_INT8*  DstCoord1OrPackedArrayPtr,
                        MIL_INT8*  DstCoord2ArrayPtr,
                        MIL_INT8*  DstCoord3ArrayPtr)
   {
   return M3dimGetInt8(ContainerOrImageBufId,
                       Component,
                       ArraySize,
                       Options,
                       DstCoord1OrPackedArrayPtr,
                       DstCoord2ArrayPtr,
                       DstCoord3ArrayPtr);
   }
#if M_MIL_USE_NULLPTR
inline MIL_INT M3dimGet(MIL_ID      ContainerOrImageBufId,
                        MIL_INT64   Component,
                        MIL_INT     ArraySize,
                        MIL_INT64   Options,
                        std::nullptr_t ,
                        std::nullptr_t ,
                        std::nullptr_t )
   {
   return M3dimGetUint8(ContainerOrImageBufId,
                        Component,
                        ArraySize,
                        Options,
                        M_NULL,
                        M_NULL,
                        M_NULL);
   }
#endif

// Helper structs used in M3dimGetList's c++ overloads.
template<typename T> struct MIL_PointerTraits;
template<typename T> struct MIL_PointerTraits<T*> { typedef T ElemType; };
template<> struct MIL_PointerTraits<int> { typedef MIL_INT32 ElemType; };
#if M_MIL_USE_NULLPTR
template<> struct MIL_PointerTraits<std::nullptr_t> { typedef MIL_INT32 ElemType; };
#endif

template<typename T> T* MIL_ForwardPtr(T* Ptr) { return Ptr; }
template<typename T> T* MIL_ForwardPtr(int Ptr)
   {
#if M_MIL_USE_SAFE_TYPE
   if(Ptr)
      SafeTypeError(MIL_TEXT("M3dimGetList"), MIL_TEXT("The arrays cannot be a non-zero integer."));
#else
   UNREFERENCED_PARAMETER(Ptr);
#endif
   return M_NULL;
   }
#if M_MIL_USE_NULLPTR
template<typename T> T* MIL_ForwardPtr(std::nullptr_t) { return M_NULL; }
#endif

template<typename, typename, typename, typename, typename = void>
struct MIL_M3dimGetListSFINAE { typedef MIL_INT Type; };

template <typename InPtrType1, typename InPtrType2, typename OutPtrType1, typename OutPtrType2, typename IndexPtrType>
typename MIL_M3dimGetListSFINAE<typename MIL_PointerTraits<InPtrType1>::ElemType,
                                typename MIL_PointerTraits<InPtrType2>::ElemType,
                                typename MIL_PointerTraits<OutPtrType1>::ElemType,
                                typename MIL_PointerTraits<OutPtrType2>::ElemType,
                                typename MIL_PointerTraits<IndexPtrType>::ElemType>::Type
M3dimGetList(MIL_ID       ContainerOrImageBufId,
             MIL_INT64    Component,
             MIL_INT      SrcArraySize,
             InPtrType1   SrcPixelXArrayPtr,          // const InType*, int, nullptr
             InPtrType2   SrcPixelYArrayPtr,          // const InType*, int, nullptr
             MIL_INT64    Options,
             OutPtrType1  DstCoord1OrPackedArrayPtr,  // OutType*, int, nullptr
             OutPtrType2  DstCoord2ArrayPtr,          // OutType*, int, nullptr
             OutPtrType2  DstCoord3ArrayPtr,          // OutType*, int, nullptr
             IndexPtrType IndexArrayPtr)              // IndexType*, int, nullptr
   {
   typedef typename MIL_PointerTraits<InPtrType1>::ElemType InType;
   typedef typename MIL_PointerTraits<OutPtrType1>::ElemType OutType;
   typedef typename MIL_PointerTraits<IndexPtrType>::ElemType IndexType;
   return M3dimGetListCpp(ContainerOrImageBufId,
                          Component,
                          SrcArraySize,
                          MIL_ForwardPtr<const InType>(SrcPixelXArrayPtr),
                          MIL_ForwardPtr<const InType>(SrcPixelYArrayPtr),
                          Options,
                          MIL_ForwardPtr<OutType>(DstCoord1OrPackedArrayPtr),
                          MIL_ForwardPtr<OutType>(DstCoord2ArrayPtr),
                          MIL_ForwardPtr<OutType>(DstCoord3ArrayPtr),
                          MIL_ForwardPtr<IndexType>(IndexArrayPtr));
   }

#else
#define M3dimGet M3dimGetDouble
#define M3dimGetList M3dimGetListDoubleDouble
#endif
//==============================================================================

#ifdef __cplusplus

inline MIL_INT M3dimGet(MIL_ID      ContainerOrImageBufId,
                        MIL_INT64   Component,
                        MIL_INT     ArraySize,
                        MIL_INT64   Options,
                        int         DstCoord1OrPackedArrayPtr,
                        int         DstCoord2ArrayPtr,
                        int         DstCoord3ArrayPtr)
   {
#if M_MIL_USE_SAFE_TYPE
   if(DstCoord1OrPackedArrayPtr ||
      DstCoord2ArrayPtr ||
      DstCoord3ArrayPtr)
      SafeTypeError(MIL_TEXT("M3dimGet"), MIL_TEXT("CoordArrayPtr must be M_NULL."));
#else
   UNREFERENCED_PARAMETER(DstCoord1OrPackedArrayPtr);
   UNREFERENCED_PARAMETER(DstCoord2ArrayPtr);
   UNREFERENCED_PARAMETER(DstCoord3ArrayPtr);
#endif // #if M_MIL_USE_SAFE_TYPE
   return M3dimGetInt32(ContainerOrImageBufId,
                        Component,
                        ArraySize,
                        Options,
                        NULL,
                        NULL,
                        NULL);
   }

// ----------------------------------------------------------
// M3dimInquire
#if M_MIL_USE_SAFE_TYPE
inline MIL_INT64 MFTYPE M3dimInquireSafeType(MIL_ID Context3dimId, 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)))
      {
      M3dimInquire(Context3dimId, InquireType | M_DEFAULT_DATA_TYPE, &RequiredParamType);
      }
   if(!MfuncPointerIsCompatible(RequiredParamType, UserVarPtr.Type, InquireType))
      {
      SafeTypeError(MIL_TEXT("M3dimInquire"));
      }
   return M3dimInquire(Context3dimId, InquireType, UserVarPtr.Ptr);
   }

inline MIL_INT64 MFTYPE M3dimInquireUnsafe(MIL_ID ContextOrResult3dimId, MIL_INT64 InquireType, void* UserVarPtr)
   {
   return M3dimInquire(ContextOrResult3dimId, InquireType, UserVarPtr);
   }

#define M3dimInquire           M3dimInquireSafeType

#else // #if M_MIL_USE_SAFE_TYPE
#define M3dimInquireUnsafe     M3dimInquire
#endif // #if M_MIL_USE_SAFE_TYPE


#if M_MIL_USE_SAFE_TYPE
// -------------------------------------------------------------------------
// M3dimGetResult safe type definitions
// 

inline MIL_DOUBLE MFTYPE M3dimGetResultSafeType(MIL_ID Result3dimId, 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)))
      {
      M3dimGetResult(Result3dimId, ResultType | M_DEFAULT_DATA_TYPE, &RequiredParamType);
      }
   if(!MfuncPointerIsCompatible(RequiredParamType, ResultArrayPtr.Type, ResultType))
      {
      SafeTypeError(MIL_TEXT("M3dimGetResult"));
      }
   return M3dimGetResult(Result3dimId, ResultType, ResultArrayPtr.Ptr);
   }

inline MIL_DOUBLE MFTYPE M3dimGetResultUnsafe(MIL_ID Result3dimId, MIL_INT64 ResultType, void* ResultArrayPtr)
   {
   return M3dimGetResult(Result3dimId, ResultType, ResultArrayPtr);
   }

#define M3dimGetResult            M3dimGetResultSafeType

#else // #if M_MIL_USE_SAFE_TYPE
#define M3dimGetResultUnsafe            M3dimGetResult
#endif // #if M_MIL_USE_SAFE_TYPE

#endif // __cplusplus

//#if M_MIL_USE_64BIT
#ifdef __cplusplus

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

inline void M3dimControl(MIL_ID Context3dimId,  MIL_INT64 ControlType, float ControlValue)
   { M3dimControlDouble(Context3dimId,  ControlType, ControlValue); }

inline void M3dimControl(MIL_ID Context3dimId,  MIL_INT64 ControlType, MIL_DOUBLE ControlValue)
   { M3dimControlDouble(Context3dimId,  ControlType, ControlValue); }
#else // __cplusplus
//=========================================================
// For C file, call the default function, i.e. Double one
//=========================================================
#define M3dimControl            M3dimControlDouble
#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 M3dimInquire(MIL_ID Context3dimId, 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("M3dimInquire"), 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;
   M3dimInquire(Context3dimId, M_STRIP_HLVLDATATYPE(InquireType) + M_NB_ELEMENTS + M_TYPE_MIL_INT, &InternalNumberOfElementsForStdVector);

   UserVarPtr.resize(InternalNumberOfElementsForStdVector);

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

   ResultArrayPtr.resize(InternalNumberOfElementsForStdVector);

   if(InternalNumberOfElementsForStdVector > 0)
      {
      M3dimGetResult(Result3dimId, ResultType, &ResultArrayPtr[0]);
      }
   return 0.0;
   }
// ----------------------------------------------------------
// Overloads for std::vector in  M3dimMerge. 
inline void MFTYPE  M3dimMerge(const std::vector<MIL_ID>& SrcContainerBufIdArrayPtr,
                               MIL_ID                     DstContainerBufId,
                               MIL_INT                    NumContainers,
                               MIL_ID                     SubsampleContext3dimId,
                               MIL_INT64                  ControlFlag)
   {
#if M_MIL_USE_SAFE_TYPE
   if(SrcContainerBufIdArrayPtr.empty())
      {
      SafeTypeError(MIL_TEXT("M3dimMerge"), MIL_TEXT("The input vectors cannot be empty."));
      }
   if(NumContainers <= 0)
      {
      SafeTypeError(MIL_TEXT("M3dimMerge"), MIL_TEXT("NumContainers parameter must be greater than zero."));
      }
   if(NumContainers > (MIL_INT)SrcContainerBufIdArrayPtr.size() && NumContainers != M_DEFAULT)
      {
      SafeTypeError(MIL_TEXT("M3dimMerge"), 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)SrcContainerBufIdArrayPtr.size())
      {
      NumContainers = (MIL_INT)SrcContainerBufIdArrayPtr.size();
      }

   M3dimMerge(&SrcContainerBufIdArrayPtr[0],
              DstContainerBufId,
              NumContainers,
              SubsampleContext3dimId,
              ControlFlag);
   }
// Overloads for std::vector in M3dimStream.
inline void MFTYPE M3dimStream(std::vector<MIL_UINT8> &MemPtrOrFileName,
                               MIL_ID                 SysId,
                               MIL_INT64              Operation,
                               MIL_INT64              StreamType,
                               MIL_DOUBLE             Version,
                               MIL_INT64              ControlFlag,
                               MIL_ID*                Context3dimIdPtr,
                               MIL_INT*               SizeByteVarPtr)
   {
   MxxxStreamForStdVector(MemPtrOrFileName,
                          SysId,
                          Operation,
                          StreamType,
                          Version,
                          ControlFlag,
                          Context3dimIdPtr,
                          SizeByteVarPtr,
                          M3dimStream);
   }
template <typename T>
inline void MFTYPE M3dimMatrixTransformList(MIL_ID                Matrix3dgeoId,
                                            MIL_INT               NumPoints,
                                            const std::vector<T>& SrcCoordXArrayPtr,
                                            CMilArrayParamIn      SrcCoordYArrayPtr,
                                            CMilArrayParamIn      SrcCoordZArrayPtr,
                                            std::vector<T>&       DstCoordXArrayPtr,
                                            CMilArrayParamOut     DstCoordYArrayPtr,
                                            CMilArrayParamOut     DstCoordZArrayPtr,
                                            MIL_INT64             ControlFlag)
   {
#if M_MIL_USE_SAFE_TYPE
   if(!SrcCoordYArrayPtr.IsValidParam() ||
      !SrcCoordZArrayPtr.IsValidParam() ||
      !DstCoordYArrayPtr.IsValidParam() ||
      !DstCoordZArrayPtr.IsValidParam())
      {
      SafeTypeError(MIL_TEXT("M3dimMatrixTransformList"), MIL_TEXT("The input arrays cannot be a non-zero integer."));
      }
   if((!SrcCoordYArrayPtr.IsNullPtr() && SrcCoordYArrayPtr.GetMilDataType() != MilTraits<T>::TypeFlag) ||
      (!SrcCoordZArrayPtr.IsNullPtr() && SrcCoordZArrayPtr.GetMilDataType() != MilTraits<T>::TypeFlag) ||
      (!DstCoordYArrayPtr.IsNullPtr() && DstCoordYArrayPtr.GetMilDataType() != MilTraits<T>::TypeFlag) ||
      (!DstCoordZArrayPtr.IsNullPtr() && DstCoordZArrayPtr.GetMilDataType() != MilTraits<T>::TypeFlag))
      {
      SafeTypeError(MIL_TEXT("M3dimMatrixTransformList"), MIL_TEXT("The arrays must all have the same data type."));
      }
   if(SrcCoordYArrayPtr.IsNullPtr() != SrcCoordZArrayPtr.IsNullPtr() || DstCoordYArrayPtr.IsNullPtr() != DstCoordZArrayPtr.IsNullPtr())
      {
      SafeTypeError(MIL_TEXT("M3dimMatrixTransformList"), MIL_TEXT("The Y and Z arrays must either both be null or not null."));
      }
   if(SrcCoordYArrayPtr.IsNullPtr() != DstCoordYArrayPtr.IsNullPtr() && &SrcCoordXArrayPtr == &DstCoordXArrayPtr)
      {
      SafeTypeError(MIL_TEXT("M3dimMatrixTransformList"), MIL_TEXT("The transformation cannot be inplace when source and destination have a different packing type."));
      }
   if(!SrcCoordYArrayPtr.IsNullPtr() && ((MIL_INT)SrcCoordXArrayPtr.size() != SrcCoordYArrayPtr.Size<T>() || (MIL_INT)SrcCoordXArrayPtr.size() != SrcCoordZArrayPtr.Size<T>()))
      {
      SafeTypeError(MIL_TEXT("M3dimMatrixTransformList"), MIL_TEXT("The input vectors must have the same size."));
      }
   if(SrcCoordXArrayPtr.empty())
      {
      SafeTypeError(MIL_TEXT("M3dimMatrixTransformList"), MIL_TEXT("The input vectors cannot be empty."));
      }
   if(NumPoints <= 0)
      {
      SafeTypeError(MIL_TEXT("M3dimMatrixTransformList"), MIL_TEXT("NumPoints parameter must be greater than zero."));
      }
#endif

   MIL_INT NeededNumPoints = SrcCoordYArrayPtr.IsNullPtr() ? (MIL_INT)SrcCoordXArrayPtr.size() / 3 : (MIL_INT)SrcCoordXArrayPtr.size();

   if(NumPoints == M_DEFAULT || NumPoints > NeededNumPoints)
      {
#if M_MIL_USE_SAFE_TYPE
      if(NumPoints != M_DEFAULT)
         {
         SafeTypeError(MIL_TEXT("M3dimMatrixTransformList"), MIL_TEXT("NumPoints parameter must be smaller or equal (M_DEFAULT) to the size of input vectors."));
         }
      if(SrcCoordYArrayPtr.IsNullPtr() && SrcCoordXArrayPtr.size() % 3 != 0)
         {
         SafeTypeError(MIL_TEXT("M3dimMatrixTransformList"), MIL_TEXT("The packed input vector's size should be a multiple of 3."));
         }
#endif
      NumPoints = NeededNumPoints;
      }

   DstCoordXArrayPtr.resize(DstCoordYArrayPtr.IsNullPtr() ? NumPoints * 3 : NumPoints);
   DstCoordYArrayPtr.Resize<T>(NumPoints);
   DstCoordZArrayPtr.Resize<T>(NumPoints);

   M3dimMatrixTransformList(Matrix3dgeoId,
                            NumPoints,
                            &SrcCoordXArrayPtr[0],
                            SrcCoordYArrayPtr.GetData<T>(),
                            SrcCoordZArrayPtr.GetData<T>(),
                            &DstCoordXArrayPtr[0],
                            DstCoordYArrayPtr.GetData<T>(),
                            DstCoordZArrayPtr.GetData<T>(),
                            ControlFlag);
   }
template <typename T>
inline MIL_INT M3dimGet(MIL_ID            ContainerOrImageBufId,
                        MIL_INT64         Component,
                        MIL_INT           ArraySize,
                        MIL_INT64         Options,
                        std::vector<T>&   DstCoord1OrPackedArrayPtr,
                        CMilArrayParamOut DstCoord2ArrayPtr,
                        CMilArrayParamOut DstCoord3ArrayPtr)
   {
#if M_MIL_USE_SAFE_TYPE
   if(!DstCoord2ArrayPtr.IsValidParam() ||
      !DstCoord3ArrayPtr.IsValidParam() )
      {
      SafeTypeError(MIL_TEXT("M3dimGet"), MIL_TEXT("The input arrays cannot be a non-zero integer."));
      }
   if((!DstCoord2ArrayPtr.IsNullPtr() && DstCoord2ArrayPtr.GetMilDataType() != MilTraits<T>::TypeFlag) ||
      (!DstCoord3ArrayPtr.IsNullPtr() && DstCoord3ArrayPtr.GetMilDataType() != MilTraits<T>::TypeFlag)  )
      {
      SafeTypeError(MIL_TEXT("M3dimGet"), MIL_TEXT("The arrays must all have the same data type."));
      }
   if(DstCoord2ArrayPtr.IsNullPtr() != DstCoord3ArrayPtr.IsNullPtr() )
      {
      SafeTypeError(MIL_TEXT("M3dimGet"), MIL_TEXT("The second and third arrays must either both be null or not null."));
      }
   if((Options & M_PACKED) && (!DstCoord2ArrayPtr.IsNullPtr() || !DstCoord3ArrayPtr.IsNullPtr()))
      {
      SafeTypeError(MIL_TEXT("M3dimGet"), MIL_TEXT("The second and third arrays must both be null when Options is M_PACKED."));
      }
   if(ArraySize < 0)
      {
      SafeTypeError(MIL_TEXT("M3dimGet"), MIL_TEXT("ArraySize must be greater than or equal to zero."));
      }
#endif

   bool IsPacked = (Options & M_PACKED) && (Component == M_DEFAULT || MbufInquireContainer(ContainerOrImageBufId, Component, M_SIZE_BAND, M_NULL) > 1);

   // Calculate the maximum possible size from the component.
   MIL_ID ComponentId = ContainerOrImageBufId;
   MIL_INT64 ObjectType = M_NULL;
   MobjInquire(ContainerOrImageBufId, M_OBJECT_TYPE, &ObjectType);
   if(ObjectType == M_CONTAINER)
      {
      ComponentId = MbufInquireContainer(ContainerOrImageBufId, M_COMPONENT_RANGE, M_COMPONENT_ID, M_NULL);
      }

   MIL_INT MaxNumPoints = MbufInquire(ComponentId, M_SIZE_X, M_NULL) * MbufInquire(ComponentId, M_SIZE_Y, M_NULL);
   if(ArraySize != M_DEFAULT && ArraySize < MaxNumPoints)
      {
      MaxNumPoints = ArraySize;
      }

   // Determine the new size depending on the capacity.
   MIL_INT NumPoints = 0;
   MIL_INT Capacity = DstCoord1OrPackedArrayPtr.capacity();
   MIL_INT RequiredCapacity = IsPacked ? MaxNumPoints * 3 : MaxNumPoints;
   if(Capacity >= RequiredCapacity || ArraySize == MaxNumPoints)
      { // The capacity is large enough to hold the max number of elements, so no need to compute anything.
      NumPoints = MaxNumPoints;
      }
   else
      { // Since the arrays will need to be reallocated, compute the actual number of elements.
      NumPoints = M3dimGet(ContainerOrImageBufId, Component, NumPoints, Options, M_NULL, M_NULL, M_NULL);
      }

   // Resize the arrays to the estimated number of points, perhaps too large.
   DstCoord1OrPackedArrayPtr.resize(IsPacked ? NumPoints * 3 : NumPoints);
   DstCoord2ArrayPtr.Resize<T>(NumPoints);
   DstCoord3ArrayPtr.Resize<T>(NumPoints);
   
   if(NumPoints == 0)
      return NumPoints;

   NumPoints = M3dimGet(ContainerOrImageBufId, Component, NumPoints, Options, &DstCoord1OrPackedArrayPtr[0], DstCoord2ArrayPtr.GetData<T>(), DstCoord3ArrayPtr.GetData<T>());

   // Resize the arrays to the actual number of points.
   DstCoord1OrPackedArrayPtr.resize(IsPacked ? NumPoints * 3 : NumPoints);
   DstCoord2ArrayPtr.Resize<T>(NumPoints);
   DstCoord3ArrayPtr.Resize<T>(NumPoints);

   return NumPoints;
   }


template <typename InType, typename OutType, typename IndexType>
inline MIL_INT M3dimGetListVector(MIL_ID               ContainerOrImageBufId,
                                  MIL_INT64                  Component,
                                  MIL_INT                    SrcArraySize,
                                  const std::vector<InType>& SrcPixelXArrayPtr,
                                  CMilArrayParamIn           SrcPixelYArrayPtr,
                                  MIL_INT64                  Options,
                                  CMilArrayParamOut          DstCoord1OrPackedArrayPtr,
                                  CMilArrayParamOut          DstCoord2ArrayPtr,
                                  CMilArrayParamOut          DstCoord3ArrayPtr,
                                  CMilArrayParamOut          IndexArrayPtr)
   {
#if M_MIL_USE_SAFE_TYPE
   if(!SrcPixelYArrayPtr.IsValidParam() ||
      !DstCoord1OrPackedArrayPtr.IsValidParam() ||
      !DstCoord2ArrayPtr.IsValidParam() ||
      !DstCoord3ArrayPtr.IsValidParam() ||
      !IndexArrayPtr.IsValidParam())
      {
      SafeTypeError(MIL_TEXT("M3dimGetList"), MIL_TEXT("The arrays cannot be a non-zero integer."));
      }
   if(!SrcPixelYArrayPtr.IsNullPtr() && SrcPixelYArrayPtr.GetMilDataType() != MilTraits<InType>::TypeFlag)
      {
      SafeTypeError(MIL_TEXT("M3dimGetList"), MIL_TEXT("The input arrays must all have the same data type."));
      }
   if(!SrcPixelYArrayPtr.IsNullPtr() && (MIL_INT)SrcPixelXArrayPtr.size() != SrcPixelYArrayPtr.Size<InType>())
      {
      SafeTypeError(MIL_TEXT("M3dimGetList"), MIL_TEXT("The input arrays must all have the same size."));
      }
   if(SrcArraySize > (MIL_INT)SrcPixelXArrayPtr.size() && SrcArraySize != M_DEFAULT)
      {
      SafeTypeError(MIL_TEXT("MbufGetList"), MIL_TEXT("SrcArraySize parameter must be smaller or equal (M_DEFAULT) to the size of input vectors."));
      }
   if(SrcArraySize < 0)
      {
      SafeTypeError(MIL_TEXT("MbufGetList"), MIL_TEXT("SrcArraySize must be greater than or equal to zero."));
      }
   if((!DstCoord1OrPackedArrayPtr.IsNullPtr() && DstCoord1OrPackedArrayPtr.GetMilDataType() != MilTraits<OutType>::TypeFlag) ||
      (!DstCoord2ArrayPtr.IsNullPtr() && DstCoord2ArrayPtr.GetMilDataType() != MilTraits<OutType>::TypeFlag) ||
      (!DstCoord3ArrayPtr.IsNullPtr() && DstCoord3ArrayPtr.GetMilDataType() != MilTraits<OutType>::TypeFlag))
      {
      SafeTypeError(MIL_TEXT("M3dimGetList"), MIL_TEXT("The output arrays must all have the same data type."));
      }
   if(DstCoord2ArrayPtr.IsNullPtr() != DstCoord3ArrayPtr.IsNullPtr())
      {
      SafeTypeError(MIL_TEXT("M3dimGetList"), MIL_TEXT("The second and third output arrays must either both be null or not null."));
      }
   if((Options & M_PACKED) && (!DstCoord2ArrayPtr.IsNullPtr() || !DstCoord3ArrayPtr.IsNullPtr()))
      {
      SafeTypeError(MIL_TEXT("M3dimGetList"), MIL_TEXT("The second and third output arrays must both be null when Options is M_PACKED."));
      }
#endif

   if(SrcArraySize == M_DEFAULT)
      SrcArraySize = (MIL_INT)SrcPixelXArrayPtr.size();

   // Resize the arrays to the ArraySize. This overestimates the required size. The arrays will be shrunk after M3dimGetList.
   bool IsPacked = (Options & M_PACKED) && (Component == M_DEFAULT || MbufInquireContainer(ContainerOrImageBufId, Component, M_SIZE_BAND, M_NULL) > 1);
   DstCoord1OrPackedArrayPtr.Resize<OutType>(IsPacked ? SrcArraySize * 3 : SrcArraySize);
   DstCoord2ArrayPtr.Resize<OutType>(SrcArraySize);
   DstCoord3ArrayPtr.Resize<OutType>(SrcArraySize);
   IndexArrayPtr.Resize<IndexType>(SrcArraySize);

   if(SrcArraySize == 0)
      return SrcArraySize;

   SrcArraySize = M3dimGetList(ContainerOrImageBufId,
                            Component,
                            SrcArraySize,
                            &SrcPixelXArrayPtr[0],
                            SrcPixelYArrayPtr.GetData<InType>(),
                            Options,
                            DstCoord1OrPackedArrayPtr.GetData<OutType>(),
                            DstCoord2ArrayPtr.GetData<OutType>(),
                            DstCoord3ArrayPtr.GetData<OutType>(),
                            IndexArrayPtr.GetData<IndexType>());

   // Resize the arrays to the actual number of points.
   DstCoord1OrPackedArrayPtr.Resize<OutType>(IsPacked ? SrcArraySize * 3 : SrcArraySize);
   DstCoord2ArrayPtr.Resize<OutType>(SrcArraySize);
   DstCoord3ArrayPtr.Resize<OutType>(SrcArraySize);
   IndexArrayPtr.Resize<IndexType>(SrcArraySize);

   return SrcArraySize;
   }

// Helper structs used in M3dimGetList's vector overloads.
template<typename T> struct MIL_VectorTraits;
template<typename T> struct MIL_VectorTraits<std::vector<T>&> { typedef T ElemType; };
template<typename T> struct MIL_VectorTraits<const std::vector<T>&> { typedef const T ElemType; };
template<> struct MIL_VectorTraits<const int&> { typedef MIL_INT32 ElemType; };
#if M_MIL_USE_NULLPTR
template<> struct MIL_VectorTraits<const std::nullptr_t&> { typedef MIL_INT32 ElemType; };
#endif

#define M_DECLARE_M3DIMGETLIST_VECTOR_OVERLOAD(A, B, C)                                                                          \
template <typename InType, typename InVecType2, typename OutVecType1, typename OutVecType2, typename IndexVecType>               \
typename MIL_M3dimGetListSFINAE<typename MIL_VectorTraits<const InVecType2&>::ElemType,                                          \
                                typename MIL_VectorTraits<A OutVecType1&>::ElemType,                                             \
                                typename MIL_VectorTraits<B OutVecType2&>::ElemType,                                             \
                                typename MIL_VectorTraits<C IndexVecType&>::ElemType>::Type                                      \
M3dimGetList(MIL_ID                     ContainerOrImageBufId,                                                                   \
             MIL_INT64                  Component,                                                                               \
             MIL_INT                    SrcArraySize,                                                                            \
             const std::vector<InType>& SrcPixelXArrayPtr,         /* const std::vector<InType>&                             */  \
             const InVecType2&          SrcPixelYArrayPtr,         /* const std::vector<InType>&, const int&, const nullptr& */  \
             MIL_INT64                  Options,                                                                                 \
             A OutVecType1&             DstCoord1OrPackedArrayPtr, /* std::vector<OutType>&, const int&, const nullptr&      */  \
             B OutVecType2&             DstCoord2ArrayPtr,         /* std::vector<OutType>&, const int&, const nullptr&      */  \
             B OutVecType2&             DstCoord3ArrayPtr,         /* std::vector<OutType>&, const int&, const nullptr&      */  \
             C IndexVecType&            IndexArrayPtr)             /* std::vector<IndexType>&, const int&, const nullptr&    */  \
   {                                                                                                                             \
   typedef typename MIL_VectorTraits<A OutVecType1&>::ElemType OutType;                                                          \
   typedef typename MIL_VectorTraits<C IndexVecType&>::ElemType IndexType;                                                       \
   return M3dimGetListVector<InType, OutType, IndexType>(ContainerOrImageBufId,                                                  \
                                                         Component,                                                              \
                                                         SrcArraySize,                                                           \
                                                         SrcPixelXArrayPtr,                                                      \
                                                         SrcPixelYArrayPtr,                                                      \
                                                         Options,                                                                \
                                                         DstCoord1OrPackedArrayPtr,                                              \
                                                         DstCoord2ArrayPtr,                                                      \
                                                         DstCoord3ArrayPtr,                                                      \
                                                         IndexArrayPtr);                                                         \
   }

M_DECLARE_M3DIMGETLIST_VECTOR_OVERLOAD(     ,      ,      );
M_DECLARE_M3DIMGETLIST_VECTOR_OVERLOAD(     ,      , const);
M_DECLARE_M3DIMGETLIST_VECTOR_OVERLOAD(     , const,      );
M_DECLARE_M3DIMGETLIST_VECTOR_OVERLOAD(     , const, const);
M_DECLARE_M3DIMGETLIST_VECTOR_OVERLOAD(const, const, const);

#undef M_DECLARE_M3DIMGETLIST_VECTOR_OVERLOAD

#endif // defined(M_MIL_USE_VECTOR) && M_MIL_USE_VECTOR

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

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

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

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

inline MIL_ID MFTYPE M3dimRestoreA(const MIL_STRING& FileName, MIL_ID SysId, MIL_INT64 ControlFlag, MIL_ID* Context3dimIdPtr)
   {
   return M3dimRestoreA(FileName.c_str(), SysId, ControlFlag, Context3dimIdPtr);
   }
#endif /* M_MIL_UNICODE_API*/

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

inline MIL_ID MFTYPE M3dimRestore(const MIL_STRING& FileName, MIL_ID SysId, MIL_INT64 ControlFlag, MIL_ID* Context3dimIdPtr)
   {
   return M3dimRestore(FileName.c_str(), SysId, ControlFlag, Context3dimIdPtr);
   }
#endif /* M_MIL_USE_UNICODE */

#if M_MIL_USE_SAFE_TYPE

#if M_MIL_UNICODE_API

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

   MIL_INT InternalStringSize = 0;

   M3dimGetResult(Result3dimId, (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);
         }
      }

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

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

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

typedef MIL_UNIQUE_ID<&M3dimFree> MIL_UNIQUE_3DIM_ID;

#if M_MIL_USE_MOVE_SEMANTICS

inline MIL_UNIQUE_3DIM_ID M3dimAlloc(MIL_ID SysId, MIL_INT64 ObjectType, MIL_INT64 InitFlag, MIL_UNIQUE_ID_TAG)
   {
   return MIL_UNIQUE_3DIM_ID(M3dimAlloc(SysId, ObjectType, InitFlag, M_NULL));
   }
inline MIL_UNIQUE_3DIM_ID M3dimAllocResult(MIL_ID SysId, MIL_INT64 ResultType, MIL_INT64 ControlFlag, MIL_UNIQUE_ID_TAG)
   {
   return MIL_UNIQUE_3DIM_ID(M3dimAllocResult(SysId, ResultType, ControlFlag, M_NULL));
   }
inline MIL_UNIQUE_3DIM_ID M3dimRestore(MIL_CONST_TEXT_PTR FileName, MIL_ID SysId, MIL_INT64 ControlFlag, MIL_UNIQUE_ID_TAG)
   {
   return MIL_UNIQUE_3DIM_ID(M3dimRestore(FileName, SysId, ControlFlag, M_NULL));
   }
#if M_MIL_USE_STRING
inline MIL_UNIQUE_3DIM_ID M3dimRestore(const MIL_STRING& FileName, MIL_ID SysId, MIL_INT64 ControlFlag, MIL_UNIQUE_ID_TAG)
   {
   return MIL_UNIQUE_3DIM_ID(M3dimRestore(FileName.c_str(), SysId, ControlFlag, M_NULL));
   }
#endif // M_MIL_USE_STRING
template <MilFreeFuncType FreeFunc> inline void M3dimFree(const MIL_UNIQUE_ID<FreeFunc>&) = delete;

inline void M3dimStream(MilStreamParam     MemPtrOrFileName,
                        MIL_ID             SysId,
                        MIL_INT64          Operation,
                        MIL_INT64          StreamType,
                        MIL_DOUBLE         Version,
                        MIL_INT64          ControlFlag,
                        MIL_UNIQUE_3DIM_ID* Context3dimIdPtr,
                        MIL_INT*            SizeByteVarPtr)
   {
   MxxxStreamForMilUniqueId(MemPtrOrFileName, SysId, Operation, StreamType, Version, ControlFlag, Context3dimIdPtr, SizeByteVarPtr, M3dimStream);
   }
inline void M3dimMerge(MilConstArrayIdParam ContArrayPtr, MIL_ID DstContainerId, MIL_INT NumContainers, MIL_ID SubsampleContext3dimId, MIL_INT64 ControlFlag)
   {
   M3dimMerge(ContArrayPtr.m_IdArrayPtr, DstContainerId, NumContainers, 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_3DIM_H__
