/////////////////////////////////////////////////////////////////
//
// Filename          :  MIL3DGEO.H
// Content           :  Define for the MIL 3D module
// Revision          :  10.60.0776
//
// Copyright © Matrox Electronic Systems Ltd., 1992-2023.
// All Rights Reserved
//
/////////////////////////////////////////////////////////////////


#ifndef __MIL3DGEO_H__
#define __MIL3DGEO_H__


////////////////////////////////////////////////////////////////////////////////////////////////
// M3DGEO
////////////////////////////////////////////////////////////////////////////////////////////////
/* C++ directive if needed */
#ifdef __cplusplus
extern "C"
   {
#endif
#define M_GEOMETRY_TYPE                                     1321L 
#define M_GEOMETRY                                          1306L // Already defined
#define M_PLANE                                             1353L // Already defined in 3dmap
#define M_SPHERE                                            2931L
#define M_CYLINDER                                          3656
#define M_BOX                                               0x101L      // Already defined in    milblob.h
#define M_LINE                                         0x00000080L   // Already defined
#define M_POINT                                                1L  // Already defined in    milmeas.h
#define M_UNCHANGED                                    0x40000005L // Already defined
#define M_DIMENSION                                         5058
//BoX
#define M_SIZE_X                                            1536L    //Already defined elsewhere
#define M_SIZE_Y                                            1537L    //Already defined elsewhere
#define M_SIZE_Z                                            1538L // also in mil.h
#define M_AXIS_ALIGNED                                 0x00040000 // Already defined in mil.h
#define M_BOX_ORIENTATION                                    3814
#define M_CORNER_X(N)                                     (1221L + (N)+ ((N) > 3 ? 2595 : 0))
#define M_CORNER_Y(N)                                     (1225L + (N)+ ((N) > 3 ? 2595 : 0))
#define M_CORNER_Z(N)                                     (3828+(N))
#define M_CORNER_X_ALL                                     3847                     
#define M_CORNER_Y_ALL                                     3848
#define M_CORNER_Z_ALL                                     3849
#define M_UNROTATED_MIN_X                                  3850
#define M_UNROTATED_MIN_Y                                  3851
#define M_UNROTATED_MIN_Z                                  3852
#define M_UNROTATED_MAX_X                                  3853
#define M_UNROTATED_MAX_Y                                  3854
#define M_UNROTATED_MAX_Z                                  3855
#define M_ORIENTATION_UNCHANGED                            0x8000L
//Plane type
#define M_COEFFICIENTS                                       3388
#define M_POINT_AND_NORMAL                                   3389
#define M_THREE_POINTS                                       3390
#define M_POINT_AND_TWO_VECTORS                              3391
//Sphere
#define M_CENTER_Z                                           3400
#define M_RADIUS                                       0x00000040L       // Already defined in MilMod.h
//Plane
#define M_COEFFICIENT_A                                     3401
#define M_COEFFICIENT_B                                     3402
#define M_COEFFICIENT_C                                     3403
#define M_COEFFICIENT_D                                     3404
#define M_NORMAL_X                                          3537
#define M_NORMAL_Y                                          3538
#define M_NORMAL_Z                                          3539
#define M_CLOSEST_TO_ORIGIN_X                               3540
#define M_CLOSEST_TO_ORIGIN_Y                               3541
#define M_CLOSEST_TO_ORIGIN_Z                               3542
//Cylinder
#define M_TWO_POINTS                                        3657
#define M_START_POINT_X                                     3658
#define M_START_POINT_Y                                     3659                               
#define M_START_POINT_Z                                     3660
#define M_END_POINT_X                                       3661
#define M_END_POINT_Y                                       3662
#define M_END_POINT_Z                                       3663
#define M_AXIS_X                                            3664
#define M_AXIS_Y                                            3665
#define M_AXIS_Z                                            3666
#define M_INFINITE                                            -1L // Also defined in Mil.h
#define M_POINT_AND_VECTOR                                  4670
#define M_WITHOUT_BASES                                     0x00000040L
#define M_WITH_BASES                                        0x00000080L
#define M_BASES                                             4153  // Also in mil3dgra.h
// Point
#define M_POSITION_X                                               0x00003400L // Already defined in mil3dgra.h
#define M_POSITION_Y                                               0x00004400L // Already defined in mil3dgra.h
#define M_POSITION_Z                                                     3960L // Already defined in mil3dgra.h
//SetMatrix
#define M_TRANSFORMATION_MATRIX                               72L  // Already defined in milreg.h
#define M_TRANSFORM_TYPES_SHIFT                   8L  // =utilities=   (also defined in milcal.h)
#define M_ASSIGN                                (1 << M_TRANSFORM_TYPES_SHIFT)      /* (also defined in milcal.h) */
#define M_COMPOSE_WITH_CURRENT                  (2 << M_TRANSFORM_TYPES_SHIFT)      /* (also defined in milcal.h) */


#define M_TRANSFORMATION_TYPE                                      3L    // Already defined in Milreg.h
#define M_INVERSE                                             0x00100
#define M_IDENTITY                                           6L // already defined in milcal.h
#define M_TRANSLATION                                        1L // already defined in milcal.h 
#define M_ROTATION                                           3410
#define M_RIGID                                              3411 
#define M_SCALE_UNIFORM                                      3413   
#define M_SIMILARITY                                         3415
#define M_AFFINE                                             3416
#define M_PROJECTION                                         3417
#define M_COMPOSE_TWO_MATRICES                               3766
#define M_ROTATION_AXIS_ANGLE                                  2L // already defined in milcal.h
#define M_ROTATION_QUATERNION                                  3L // already defined in milcal.h
#define M_ROTATION_X                                           7L // already defined in milcal.h
#define M_ROTATION_Y                                           8L // already defined in milcal.h
#define M_ROTATION_Z                                           9L // already defined in milcal.h
#define M_ROTATION_YXZ                                         4L // already defined in milcal.h
#define M_ROTATION_XYZ                                        10L // already defined in milcal.h
#define M_ROTATION_XZY                                        11L // already defined in milcal.h
#define M_ROTATION_YZX                                        12L // already defined in milcal.h
#define M_ROTATION_ZXY                                        13L // already defined in milcal.h
#define M_ROTATION_ZYX                                        14L // already defined in milcal.h
#define M_ROTATION_AXIS_X                                     17L // already defined in milcal.h
#define M_ROTATION_AXIS_Y                                     18L // already defined in milcal.h
#define M_ROTATION_AXIS_Z                                     19L // already defined in milcal.h
#define M_FIXTURE_TO_PLANE                                    20L // already defined in milcal.h
#define M_FIXTURE_TO_GEOMETRY                                 21L // already defined in milcal.h
//MatrixDefine
#define M_XY_AXES                                           3926L
#define M_XZ_AXES                                           3927L
#define M_YX_AXES                                           3928L
#define M_YZ_AXES                                           3929L
#define M_ZX_AXES                                           3930L
#define M_ZY_AXES                                           3931L
////////////////////////////////////////////////////////////////////////////////
// Deprecated starting 10 SP6                                                 //
////////////////////////////////////////////////////////////////////////////////
#if OldDefinesSupport
#define M_FORWARD_TRANSFORMATION                      0x00001000L
#define M_BACKWARD_TRANSFORMATION                     0x00002000L
MIL_DEPRECATED(M_FORWARD_TRANSFORMATION , 1060)
MIL_DEPRECATED(M_BACKWARD_TRANSFORMATION, 1060)
#endif
#define M_POSITION_TRANSFORMATION                     0x00001000L
#define M_COORDINATE_SYSTEM_TRANSFORMATION            0x00002000L

//Draw3d
#define M_ROOT_NODE                                            0
//Copy
#define M_ROTATION_AND_SCALE                                 3993
//Construct
#define M_START_POINT                                       4762L
#define M_END_POINT                                         4763L
#define M_CENTER                                      0x00000080L // already defined in milim.h
#define M_CLOSEST_TO_ORIGIN                                 4764L
#define M_NORMAL                                               8L // already defined in milmeas.h
#define M_EDGE                                                 2L // already defined in milmeas.h
#define M_AXIS                                              4765L
#define M_LINE_AND_POINT                                    4766L
#define M_FACE                                              4767L
#define M_CENTER_AND_RADIUS                                 4768L
#define M_DIAMETER                                          4769L
#define M_CORNER                                            4770L

//Evaluation 
#define M_EVAL_X                                            5219L
#define M_EVAL_Y                                            5220L
#define M_EVAL_Z                                            5221L
#define M_EVAL_XY                                           5223L
#define M_EVAL_XZ                                           5224L
#define M_EVAL_YZ                                           5225L
#define M_MIN_VALUE                                         MAKE_INT64(0x0000010000000000) // already defined in milim.h
#define M_MAX_VALUE                                         MAKE_INT64(0x0000020000000000) // already defined in milim.h
#define M_PACKED                                            0x00020000L // Already defined in mil.h, miledge.h
#define M_PACKED_SRC                                        0x00040000L
#define M_PACKED_DST                                        0x00080000L
#define M_NONE                                              0x08000000L // Already defined in milstr.h
   // CAPI function prototypes
   MIL_ID  MFTYPE M3dgeoAlloc(MIL_ID     SysId,
                              MIL_INT64  ObjectType,
                              MIL_INT64  ControlFlag,
                              MIL_ID*    GeometryOrMatrix3dgeoIdPtr);

   MIL_DOUBLE MFTYPE M3dgeoInquire(MIL_ID     GeometryOrMatrix3dgeoId,
                                   MIL_INT64  InquireType,
                                   void*      UserVarPtr);

   void MFTYPE M3dgeoFree(MIL_ID GeometryOrMatrix3dgeoId);

   void MFTYPE M3dgeoBox(MIL_ID     Geometry3dgeoId,
                         MIL_INT64  CreationMode,
                         MIL_DOUBLE XPos1,
                         MIL_DOUBLE YPos1,
                         MIL_DOUBLE ZPos1,
                         MIL_DOUBLE XPos2OrLength,
                         MIL_DOUBLE YPos2OrLength,
                         MIL_DOUBLE ZPos2OrLength,
                         MIL_INT64  ControlFlag);

   void MFTYPE M3dgeoSphere(MIL_ID     Geometry3dgeoId,
                            MIL_DOUBLE CenterX,
                            MIL_DOUBLE CenterY,
                            MIL_DOUBLE CenterZ,
                            MIL_DOUBLE Radius,
                            MIL_INT64  ControlFlag);

   void MFTYPE M3dgeoPoint(MIL_ID     Geometry3dgeoId,
                           MIL_DOUBLE PositionX,
                           MIL_DOUBLE PositionY,
                           MIL_DOUBLE PositionZ,
                           MIL_INT64  ControlFlag);

   void MFTYPE M3dgeoPlane(MIL_ID     Geometry3dgeoId,
                           MIL_INT64  CreationMode,
                           MIL_DOUBLE X1,
                           MIL_DOUBLE Y1,
                           MIL_DOUBLE Z1,
                           MIL_DOUBLE X2OrD,
                           MIL_DOUBLE Y2,
                           MIL_DOUBLE Z2,
                           MIL_DOUBLE X3,
                           MIL_DOUBLE Y3,
                           MIL_DOUBLE Z3,
                           MIL_INT64  ControlFlag);

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

   void MFTYPE M3dgeoMatrixSetTransformDouble(MIL_ID     Matrix3dgeoId,
                                              MIL_INT64  TransformType,
                                              MIL_DOUBLE Param1,
                                              MIL_DOUBLE Param2,
                                              MIL_DOUBLE Param3,
                                              MIL_DOUBLE Param4,
                                              MIL_INT64  ControlFlag);

   void MFTYPE M3dgeoMatrixPutDouble(MIL_ID            Matrix3dgeoId,
                                     MIL_INT64         PutType,
                                     const MIL_DOUBLE* UserArrayPtr);
   void MFTYPE M3dgeoMatrixPutFloat(MIL_ID           Matrix3dgeoId,
                                    MIL_INT64        PutType,
                                    const MIL_FLOAT* UserArrayPtr);

   void MFTYPE M3dgeoMatrixGetDouble(MIL_ID      Matrix3dgeoId,
                                     MIL_INT64   GetType,
                                     MIL_DOUBLE* UserArrayPtr);
   void MFTYPE M3dgeoMatrixGetFloat(MIL_ID      Matrix3dgeoId,
                                    MIL_INT64   GetType,
                                    MIL_FLOAT*  UserArrayPtr);

   void  MFTYPE M3dgeoMatrixGetTransform(MIL_ID     Matrix3dgeoId,
                                         MIL_INT64  InquireType,
                                         MIL_DOUBLE *Param1Ptr,
                                         MIL_DOUBLE *Param2Ptr,
                                         MIL_DOUBLE *Param3Ptr,
                                         MIL_DOUBLE *Param4Ptr,
                                         MIL_INT64  ControlFlag);

   void MFTYPE M3dgeoCylinder(MIL_ID     Geometry3dgeoId,
                              MIL_INT64  CreationMode,
                              MIL_DOUBLE XPos1,
                              MIL_DOUBLE YPos1,
                              MIL_DOUBLE ZPos1,
                              MIL_DOUBLE XPos2OrVector,
                              MIL_DOUBLE YPos2OrVector,
                              MIL_DOUBLE ZPos2OrVector,
                              MIL_DOUBLE Radius,
                              MIL_DOUBLE Length,
                              MIL_INT64  ControlFlag);

   MIL_INT64 MFTYPE M3dgeoDraw3d(MIL_ID     OperationDraw3dContext3dgeoId,
                                 MIL_ID     SrcGeometry3dgeoId,
                                 MIL_ID     DstList3dgraId,
                                 MIL_INT64  DstParentLabel,
                                 MIL_INT64  ControlFlag);


   void MFTYPE M3dgeoLine(MIL_ID     Geometry3dgeoId,
                          MIL_INT64  CreationMode,
                          MIL_DOUBLE XPos1,
                          MIL_DOUBLE YPos1,
                          MIL_DOUBLE ZPos1,
                          MIL_DOUBLE XPos2OrVector,
                          MIL_DOUBLE YPos2OrVector,
                          MIL_DOUBLE ZPos2OrVector,
                          MIL_DOUBLE Length,
                          MIL_INT64  ControlFlag);

   void MFTYPE M3dgeoMatrixSetWithAxes(MIL_ID     Matrix3dgeoId,
                                       MIL_INT64  Mode,
                                       MIL_DOUBLE OriginX,
                                       MIL_DOUBLE OriginY,
                                       MIL_DOUBLE OriginZ,
                                       MIL_DOUBLE Axis1VectorX,
                                       MIL_DOUBLE Axis1VectorY,
                                       MIL_DOUBLE Axis1VectorZ,
                                       MIL_DOUBLE Axis2VectorX,
                                       MIL_DOUBLE Axis2VectorY,
                                       MIL_DOUBLE Axis2VectorZ,
                                       MIL_INT64  ControlFlag);

   void MFTYPE M3dgeoConstruct(MIL_ID     Src1Geometry3dgeoId,
                               MIL_ID     Src2Geometry3dgeoId,
                               MIL_ID     DstGeometry3dgeoId,
                               MIL_INT    GeometryType,
                               MIL_INT64  Operation,
                               MIL_DOUBLE Param,
                               MIL_INT64  ControlFlag);

   MIL_INT MFTYPE M3dgeoEvalCurveDouble(MIL_ID            Geometry3dgeoId,
                                        MIL_INT64         Operation,
                                        MIL_INT           NumPoints,
                                        const MIL_DOUBLE* SrcCoordArrayPtr,
                                        MIL_DOUBLE*       Dst1CoordArrayPtr,
                                        MIL_DOUBLE*       Dst2CoordArrayPtr,
                                        MIL_INT64         ControlFlag);

   MIL_INT MFTYPE M3dgeoEvalCurveFloat(MIL_ID            Geometry3dgeoId,
                                       MIL_INT64         Operation,
                                       MIL_INT           NumPoints,
                                       const MIL_FLOAT*  SrcCoordArrayPtr,
                                       MIL_FLOAT*        Dst1CoordArrayPtr,
                                       MIL_FLOAT*        Dst2CoordArrayPtr,
                                       MIL_INT64         ControlFlag);

   MIL_INT MFTYPE M3dgeoEvalSurfaceDouble(MIL_ID            Geometry3dgeoId,
                                          MIL_INT64         Operation,
                                          MIL_INT           NumPoints,
                                          const MIL_DOUBLE* Src1CoordArrayPtr,
                                          const MIL_DOUBLE* Src2CoordArrayPtr,
                                          MIL_DOUBLE*       DstCoordArrayPtr,
                                          MIL_INT64         ControlFlag);

   MIL_INT MFTYPE M3dgeoEvalSurfaceFloat(MIL_ID            Geometry3dgeoId,
                                         MIL_INT64         Operation,
                                         MIL_INT           NumPoints,
                                         const MIL_FLOAT*  Src1CoordArrayPtr,
                                         const MIL_FLOAT*  Src2CoordArrayPtr,
                                         MIL_FLOAT*        DstCoordArrayPtr,
                                         MIL_INT64         ControlFlag);

   //M3dgeo Control  



#if M_MIL_USE_UNICODE
   void MFTYPE M3dgeoSaveA(MIL_CONST_TEXTA_PTR FileName,
                           MIL_ID              GeometryOrMatrix3dgeoId,
                           MIL_INT64           ControlFlag);

   MIL_ID MFTYPE M3dgeoRestoreA(MIL_CONST_TEXTA_PTR FileName,
                                MIL_ID              SysId,
                                MIL_INT64           ControlFlag,
                                MIL_ID*             GeometryOrMatrix3dgeoIdPtr);

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

   void MFTYPE M3dgeoSaveW(MIL_CONST_TEXTW_PTR FileName,
                           MIL_ID              GeometryOrMatrix3dgeoId,
                           MIL_INT64           ControlFlag);

   MIL_ID MFTYPE M3dgeoRestoreW(MIL_CONST_TEXTW_PTR FileName,
                                MIL_ID              SysId,
                                MIL_INT64           ControlFlag,
                                MIL_ID*             GeometryOrMatrix3dgeoIdPtr);

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



#if M_MIL_UNICODE_API
#define M3dgeoSave               M3dgeoSaveW
#define M3dgeoRestore            M3dgeoRestoreW
#define M3dgeoStream             M3dgeoStreamW
//#define M3dgeoImport             M3dgeoImportW
#else
#define M3dgeoSave               M3dgeoSaveA
#define M3dgeoRestore            M3dgeoRestoreA
#define M3dgeoStream             M3dgeoStreamA
//#define M3dgeoImport             M3dgeoImportA
#endif

#else

   void MFTYPE   M3dgeoSave(MIL_CONST_TEXT_PTR FileName,
                            MIL_ID             GeometryOrMatrix3dgeoId,
                            MIL_INT64          ControlFlag);

   MIL_ID MFTYPE   M3dgeoRestore(MIL_CONST_TEXT_PTR FileName,
                                 MIL_ID             SysId,
                                 MIL_INT64          ControlFlag,
                                 MIL_ID*            GeometryOrMatrix3dgeoIdPtr);

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

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

#ifdef __cplusplus
   inline void MFTYPE M3dgeoStreamCpp(MilStreamParam MemPtrOrFileName,
                                      MIL_ID         SysId,
                                      MIL_INT64      Operation,
                                      MIL_INT64      StreamType,
                                      MIL_DOUBLE     Version,
                                      MIL_INT64      ControlFlag,
                                      MIL_ID*        GeometryOrMatrix3dgeoIdPtr,
                                      MIL_INT*       SizeByteVarPtr)
      {
      M3dgeoStream(MemPtrOrFileName.m_Param, SysId, Operation, StreamType, Version, ControlFlag, GeometryOrMatrix3dgeoIdPtr, SizeByteVarPtr);
      }

#undef  M3dgeoStream
#define M3dgeoStream M3dgeoStreamCpp

#endif // __cplusplus
#ifdef __cplusplus
   inline void M3dgeoMatrixGet(MIL_ID      Matrix3dgeoId,
                               MIL_INT64   GetType,
                               MIL_DOUBLE* UserArrayPtr)
      {
      return M3dgeoMatrixGetDouble(Matrix3dgeoId, GetType, UserArrayPtr);
      }
   inline void M3dgeoMatrixGet(MIL_ID      Matrix3dgeoId,
                               MIL_INT64   GetType,
                               MIL_FLOAT*  UserArrayPtr)
      {
      return M3dgeoMatrixGetFloat(Matrix3dgeoId, GetType, UserArrayPtr);
      }
   inline void M3dgeoMatrixPut(MIL_ID            Matrix3dgeoId,
                               MIL_INT64         PutType,
                               const MIL_DOUBLE* UserArrayPtr)
      {
      return M3dgeoMatrixPutDouble(Matrix3dgeoId, PutType, UserArrayPtr);
      }
   inline void M3dgeoMatrixPut(MIL_ID            Matrix3dgeoId,
                               MIL_INT64         PutType,
                               const MIL_FLOAT*  UserArrayPtr)
      {
      return M3dgeoMatrixPutFloat(Matrix3dgeoId, PutType, UserArrayPtr);
      }

   inline MIL_INT M3dgeoEvalCurve(MIL_ID            Geometry3dgeoId,
                                  MIL_INT64         Operation,
                                  MIL_INT           NumPoints,
                                  const MIL_DOUBLE* SrcCoordArrayPtr,
                                  MIL_DOUBLE*       Dst1CoordArrayPtr,
                                  MIL_DOUBLE*       Dst2CoordArrayPtr,
                                  MIL_INT64         ControlFlag)
      {
      return M3dgeoEvalCurveDouble(Geometry3dgeoId,
                                   Operation,
                                   NumPoints,
                                   SrcCoordArrayPtr,
                                   Dst1CoordArrayPtr,
                                   Dst2CoordArrayPtr,
                                   ControlFlag);
      }

   inline MIL_INT M3dgeoEvalCurve(MIL_ID            Geometry3dgeoId,
                                  MIL_INT64         Operation,
                                  MIL_INT           NumPoints,
                                  const MIL_FLOAT*  SrcCoordArrayPtr,
                                  MIL_FLOAT*        Dst1CoordArrayPtr,
                                  MIL_FLOAT*        Dst2CoordArrayPtr,
                                  MIL_INT64         ControlFlag)
      {
      return M3dgeoEvalCurveFloat(Geometry3dgeoId,
                                  Operation,
                                  NumPoints,
                                  SrcCoordArrayPtr,
                                  Dst1CoordArrayPtr,
                                  Dst2CoordArrayPtr,
                                  ControlFlag);
      }

   inline MIL_INT M3dgeoEvalSurface(MIL_ID            Geometry3dgeoId,
                                    MIL_INT64         Operation,
                                    MIL_INT           NumPoints,
                                    const MIL_DOUBLE* Src1CoordArrayPtr,
                                    const MIL_DOUBLE* Src2CoordArrayPtr,
                                    MIL_DOUBLE*       DstCoordArrayPtr,
                                    MIL_INT64         ControlFlag)
      {
      return M3dgeoEvalSurfaceDouble(Geometry3dgeoId,
                                     Operation,
                                     NumPoints,
                                     Src1CoordArrayPtr,
                                     Src2CoordArrayPtr,
                                     DstCoordArrayPtr,
                                     ControlFlag);
      }

   inline MIL_INT M3dgeoEvalSurface(MIL_ID            Geometry3dgeoId,
                                    MIL_INT64         Operation,
                                    MIL_INT           NumPoints,
                                    const MIL_FLOAT*  Src1CoordArrayPtr,
                                    const MIL_FLOAT*  Src2CoordArrayPtr,
                                    MIL_FLOAT*        DstCoordArrayPtr,
                                    MIL_INT64         ControlFlag)
      {
      return M3dgeoEvalSurfaceFloat(Geometry3dgeoId,
                                    Operation,
                                    NumPoints,
                                    Src1CoordArrayPtr,
                                    Src2CoordArrayPtr,
                                    DstCoordArrayPtr,
                                    ControlFlag);
      }

#else
#define M3dgeoMatrixGet   M3dgeoMatrixGetDouble
#define M3dgeoMatrixPut   M3dgeoMatrixPutDouble
#define M3dgeoEvalCurve   M3dgeoEvalCurveDouble
#define M3dgeoEvalSurface M3dgeoEvalSurfaceDouble
#endif

#ifdef __cplusplus
#if M_MIL_USE_SAFE_TYPE
// ----------------------------------------------------------
// M3dgeoInquire
inline MIL_DOUBLE MFTYPE M3dgeoInquireSafeType(MIL_ID GeometryOrMatrix3dgeoId, 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)))
      {
      M3dgeoInquire(GeometryOrMatrix3dgeoId, InquireType | M_DEFAULT_DATA_TYPE, &RequiredParamType);
      }
   if(!MfuncPointerIsCompatible(RequiredParamType, UserVarPtr.Type, InquireType))
      {
      SafeTypeError(MIL_TEXT("M3dgeoInquire"));
      }
   return M3dgeoInquire(GeometryOrMatrix3dgeoId, InquireType, UserVarPtr.Ptr);
   }

inline MIL_DOUBLE MFTYPE M3dgeoInquireUnsafe(MIL_ID GeometryOrMatrix3dgeoId, MIL_INT64 InquireType, void* UserVarPtr)
   {
   return M3dgeoInquire(GeometryOrMatrix3dgeoId, InquireType, UserVarPtr);
   }

#define M3dgeoInquire           M3dgeoInquireSafeType

#else // #if M_MIL_USE_SAFE_TYPE
#define M3dgeoInquireUnsafe     M3dgeoInquire
#endif // #if M_MIL_USE_SAFE_TYPE

#endif
#if M_MIL_USE_STRING
   inline void MFTYPE M3dgeoSave(const MIL_STRING& FileName, MIL_ID GeometryOrMatrix3dgeoId, MIL_INT64 ControlFlag)
      {
      return M3dgeoSave(FileName.c_str(), GeometryOrMatrix3dgeoId, ControlFlag);
      }

   inline MIL_ID MFTYPE M3dgeoRestore(const MIL_STRING& FileName, MIL_ID SysId, MIL_INT64 ControlFlag, MIL_ID* GeometryOrMatrix3dgeoIdPtr)
      {
      return M3dgeoRestore(FileName.c_str(), SysId, ControlFlag, GeometryOrMatrix3dgeoIdPtr);
      }
#endif /* M_MIL_USE_STRING */
   // ----------------------------------------------------------
// Overload for std::vector.
#if defined(M_MIL_USE_VECTOR) && M_MIL_USE_VECTOR
// ----------------------------------------------------------
// Overloads for std::vector in  M3dgeoInquire.
   template <typename UserType>
   inline MIL_DOUBLE MFTYPE M3dgeoInquire(MIL_ID GeometryOrMatrix3dgeoId, 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("M3dgeoInquire"), 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;
      M3dgeoInquire(GeometryOrMatrix3dgeoId, M_STRIP_HLVLDATATYPE(InquireType) + M_NB_ELEMENTS + M_TYPE_MIL_INT, &InternalNumberOfElementsForStdVector);

      UserVarPtr.resize(InternalNumberOfElementsForStdVector);

      if(InternalNumberOfElementsForStdVector > 0)
         {
         return M3dgeoInquire(GeometryOrMatrix3dgeoId, InquireType, &UserVarPtr[0]);
         }
      return 0;
      }
   // ----------------------------------------------------------
   // Overloads for std::vector in  M3dgeoMatrixPut.
   template <typename T>
   inline void MFTYPE  M3dgeoMatrixPut(MIL_ID                Matrix3dgeoId,
                                       MIL_INT64             PutType,
                                       const std::vector<T>& ArrayPtr)
      {
#if M_MIL_USE_SAFE_TYPE
      if(ArrayPtr.empty())
         {
         SafeTypeError(MIL_TEXT("M3dgeoMatrixPut"), MIL_TEXT("The input vector cannot be empty."));
         }

      if(ArrayPtr.size() != 16)
         {
         SafeTypeError(MIL_TEXT("M3dgeoMatrixPut"), MIL_TEXT("The size of the input vector must be 16."));
         }
#endif
      M3dgeoMatrixPut(Matrix3dgeoId,
                      PutType,
                      &ArrayPtr[0]);
      }
   // Overloads for std::vector in M3dgeoMatrixGet.
   template <typename T>
   inline void M3dgeoMatrixGet(MIL_ID          Matrix3dgeoId,
                               MIL_INT64       GetType,
                               std::vector<T>& ArrayPtr)
      {
      ArrayPtr.resize(16);//InternalNbElementRequired
      M3dgeoMatrixGet(Matrix3dgeoId,
                      GetType,
                      &ArrayPtr[0]);
      }

   // Overloads for std::vector in M3dgeoEvalCurve.
   template <typename T>
   inline MIL_INT MFTYPE M3dgeoEvalCurve(MIL_ID                Geometry3dgeoId,
                                         MIL_INT64             Operation,
                                         MIL_INT               NumPoints,
                                         const std::vector<T>& SrcCoordArrayPtr,
                                         std::vector<T>&       Dst1CoordArrayPtr,
                                         CMilArrayParamOut     Dst2CoordArrayPtr,
                                         MIL_INT64             ControlFlag)
      {
      const bool PackedSource = ((Operation & M_PACKED) == M_PACKED) || ((Operation & M_PACKED_SRC) == M_PACKED_SRC);
      const bool PackedDestination = ((Operation & M_PACKED) == M_PACKED) || ((Operation & M_PACKED_DST) == M_PACKED_DST);

#if M_MIL_USE_SAFE_TYPE
      if(!Dst2CoordArrayPtr.IsValidParam())
         {
         SafeTypeError(MIL_TEXT("M3dgeoEvalCurve"), MIL_TEXT("The arrays cannot be a non-zero integer."));
         }
      if(!Dst2CoordArrayPtr.IsNullPtr() && Dst2CoordArrayPtr.GetMilDataType() != MilTraits<T>::TypeFlag)
         {
         SafeTypeError(MIL_TEXT("M3dgeoEvalCurve"), MIL_TEXT("The output arrays must have the same data type."));
         }
      if(NumPoints > (MIL_INT)SrcCoordArrayPtr.size() && NumPoints != M_DEFAULT)
         {
         SafeTypeError(MIL_TEXT("M3dgeoEvalCurve"), MIL_TEXT("NumPoints parameter must be smaller or equal (M_DEFAULT) to the size of input vector."));
         }
      if(NumPoints <= 0)
         {
         SafeTypeError(MIL_TEXT("M3dgeoEvalCurve"), MIL_TEXT("NumPoints must be greater than zero."));
         }
      if(PackedSource && SrcCoordArrayPtr.size() % 3 != 0)
         {
         SafeTypeError(MIL_TEXT("M3dgeoEvalCurve"), MIL_TEXT("Packed source array length is not multiple of 3"));
         }
      if(PackedDestination && !Dst2CoordArrayPtr.IsNullPtr())
         {
         SafeTypeError(MIL_TEXT("M3dimGetList"), MIL_TEXT("The second output array must be null when the output is M_PACKED."));
         }
#endif

      MIL_INT EffectiveNumPoints = (MIL_INT)(PackedSource ? SrcCoordArrayPtr.size() / 3 : SrcCoordArrayPtr.size());
      if(EffectiveNumPoints > NumPoints)
         EffectiveNumPoints = NumPoints;

      Dst1CoordArrayPtr.resize((PackedDestination ? 3 : 1) * EffectiveNumPoints);
      Dst2CoordArrayPtr.Resize<T>(EffectiveNumPoints);

      if(EffectiveNumPoints == 0)
         return EffectiveNumPoints;

      return M3dgeoEvalCurve(Geometry3dgeoId,
                             Operation,
                             EffectiveNumPoints,
                             &SrcCoordArrayPtr[0],
                             &Dst1CoordArrayPtr[0],
                             Dst2CoordArrayPtr.GetData<T>(),
                             ControlFlag);
      }

   // Overloads for std::vector in M3dgeoEvalSurface.
   template <typename T>
   inline MIL_INT M3dgeoEvalSurface(MIL_ID                Geometry3dgeoId,
                                    MIL_INT64             Operation,
                                    MIL_INT               NumPoints,
                                    const std::vector<T>& Src1CoordArrayPtr,
                                    CMilArrayParamIn      Src2CoordArrayPtr,
                                    std::vector<T>&       DstCoordArrayPtr,
                                    MIL_INT64             ControlFlag)
      {
      const bool PackedSource = ((Operation & M_PACKED) == M_PACKED) || ((Operation & M_PACKED_SRC) == M_PACKED_SRC);
      const bool PackedDestination = ((Operation & M_PACKED) == M_PACKED) || ((Operation & M_PACKED_DST) == M_PACKED_DST);

#if M_MIL_USE_SAFE_TYPE
      if(!Src2CoordArrayPtr.IsValidParam())
         {
         SafeTypeError(MIL_TEXT("M3dgeoEvalSurface"), MIL_TEXT("The arrays cannot be a non-zero integer."));
         }
      if(!Src2CoordArrayPtr.IsNullPtr() && Src2CoordArrayPtr.GetMilDataType() != MilTraits<T>::TypeFlag)
         {
         SafeTypeError(MIL_TEXT("M3dgeoEvalSurface"), MIL_TEXT("The input arrays must have the same data type."));
         }
      if(!Src2CoordArrayPtr.IsNullPtr() && (MIL_INT)Src1CoordArrayPtr.size() != Src2CoordArrayPtr.Size<T>())
         {
         SafeTypeError(MIL_TEXT("M3dgeoEvalSurface"), MIL_TEXT("The input arrays must have the same size."));
         }
      if(NumPoints > (MIL_INT)Src1CoordArrayPtr.size() && NumPoints != M_DEFAULT)
         {
         SafeTypeError(MIL_TEXT("M3dgeoEvalSurface"), MIL_TEXT("NumPoints parameter must be smaller or equal (M_DEFAULT) to the size of input vector."));
         }
      if(NumPoints <= 0)
         {
         SafeTypeError(MIL_TEXT("M3dgeoEvalSurface"), MIL_TEXT("NumPoints must be greater than zero."));
         }
      if(PackedSource && Src1CoordArrayPtr.size() % 3 != 0)
         {
         SafeTypeError(MIL_TEXT("M3dgeoEvalSurface"), MIL_TEXT("Packed source array length is not multiple of 3"));
         }
      if(PackedSource && !Src2CoordArrayPtr.IsNullPtr())
         {
         SafeTypeError(MIL_TEXT("M3dgeoEvalSurface"), MIL_TEXT("The second input array must be null when the input is M_PACKED."));
         }
#endif

      MIL_INT EffectiveNumPoints = (MIL_INT)(PackedSource ? Src1CoordArrayPtr.size() / 3 : Src1CoordArrayPtr.size());
      if(EffectiveNumPoints > NumPoints)
         EffectiveNumPoints = NumPoints;

      DstCoordArrayPtr.resize((PackedDestination ? 3 : 1) * EffectiveNumPoints);

      return M3dgeoEvalSurface(Geometry3dgeoId,
                               Operation,
                               EffectiveNumPoints,
                               &Src1CoordArrayPtr[0],
                               Src2CoordArrayPtr.GetData<T>(),
                               &DstCoordArrayPtr[0],
                               ControlFlag);
      }

   // ----------------------------------------------------------
// Overloads for std::vector in M3dgeoStream.
   inline void MFTYPE M3dgeoStream(std::vector<MIL_UINT8> &MemPtrOrFileName,
                                   MIL_ID                 SysId,
                                   MIL_INT64              Operation,
                                   MIL_INT64              StreamType,
                                   MIL_DOUBLE             Version,
                                   MIL_INT64              ControlFlag,
                                   MIL_ID*                GeometryOrMatrix3dgeoIdPtr,
                                   MIL_INT*               SizeByteVarPtr)
      {
      MxxxStreamForStdVector(MemPtrOrFileName,
                             SysId,
                             Operation,
                             StreamType,
                             Version,
                             ControlFlag,
                             GeometryOrMatrix3dgeoIdPtr,
                             SizeByteVarPtr,
                             M3dgeoStream);
      }
#endif // defined(M_MIL_USE_VECTOR) && M_MIL_USE_VECTOR
 // Automatic double casting
#define M3dgeoMatrixSetTransform(Matrix3dgeoId, TransformType, Param1, Param2, Param3, Param4, ControlFlag) \
        M3dgeoMatrixSetTransformDouble(Matrix3dgeoId, TransformType, M_MILID_TO_DOUBLE(Param1), M_MILID_TO_DOUBLE(Param2), M_MILID_TO_DOUBLE(Param3), M_MILID_TO_DOUBLE(Param4), ControlFlag)
////////////////////////////////////////////////////////////////////////////////
// MIL_UNIQUE_ID support

#if M_MIL_USE_MIL_UNIQUE_ID

#if M_MIL_USE_SAFE_TYPE
   template <> inline bool MilIsCorrectObjectType<&M3dgeoFree>(MIL_INT64 ObjectType)
      {
      return (ObjectType == M_3DGEO_GEOMETRY || ObjectType == M_3DGEO_TRANSFORMATION_MATRIX);
      }
#endif

   typedef MIL_UNIQUE_ID<&M3dgeoFree > MIL_UNIQUE_3DGEO_ID;

#if M_MIL_USE_MOVE_SEMANTICS

   //3DGEO
   inline  MIL_UNIQUE_3DGEO_ID M3dgeoAlloc(MIL_ID SysId, MIL_INT64 ObjectType, MIL_INT64 InitFlag, MIL_UNIQUE_ID_TAG)
      {
      return MIL_UNIQUE_3DGEO_ID(M3dgeoAlloc(SysId, ObjectType, InitFlag, M_NULL));
      }
   inline MIL_UNIQUE_3DGEO_ID M3dgeoRestore(MIL_CONST_TEXT_PTR FileName, MIL_ID SysId, MIL_INT64 ControlFlag, MIL_UNIQUE_ID_TAG)
      {
      return MIL_UNIQUE_3DGEO_ID(M3dgeoRestore(FileName, SysId, ControlFlag, M_NULL));
      }
#if M_MIL_USE_STRING
   inline MIL_UNIQUE_3DGEO_ID M3dgeoRestore(const MIL_STRING& FileName, MIL_ID SysId, MIL_INT64 ControlFlag, MIL_UNIQUE_ID_TAG)
      {
      return MIL_UNIQUE_3DGEO_ID(M3dgeoRestore(FileName.c_str(), SysId, ControlFlag, M_NULL));
      }
#endif // M_MIL_USE_STRING
   template <MilFreeFuncType FreeFunc> inline void M3dgeoFree(const MIL_UNIQUE_ID<FreeFunc>&) = delete;

   inline void M3dgeoStream(MilStreamParam       MemPtrOrFileName,
                            MIL_ID               SysId,
                            MIL_INT64            Operation,
                            MIL_INT64            StreamType,
                            MIL_DOUBLE           Version,
                            MIL_INT64            ControlFlag,
                            MIL_UNIQUE_3DGEO_ID* Context3dgeoIdPtr,
                            MIL_INT*             SizeByteVarPtr)
      {
      MxxxStreamForMilUniqueId(MemPtrOrFileName, SysId, Operation, StreamType, Version, ControlFlag, Context3dgeoIdPtr, SizeByteVarPtr, M3dgeoStream);
      }
#endif // M_MIL_USE_MOVE_SEMANTICS
#endif // M_MIL_USE_MIL_UNIQUE_ID

// End of MIL_UNIQUE_ID support


////////////////////////////////////////////////////////////////////////////////

   /* C++ directive if needed */
#ifdef __cplusplus
extern "C"
   {
#endif
   // MbufConvert3d
#define M_COMPENSATE                   3713
#define M_REMOVE_NON_FINITE            0x00000001L


//Export
#define M_WITH_ORGANIZATION              0x0100000

   void MFTYPE MbufConvert3d(MIL_ID    SrcContainerOrImageBufId,
                             MIL_ID    DstContainerOrImageBufId,
                             MIL_ID    ExternalYArrayBufId,
                             MIL_INT64 DstOptions,
                             MIL_INT64 ControlFlag);



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

////////////////////////////////////////////////////////////////////////////////
#endif // __MIL3D_H__
