/****************************************************************************************************

		IPolymesh.h
		Copyright: (c) 2001 Eovia Corp. All rights reserved.

		Author:	Charles
		Date:	10/4/2002

****************************************************************************************************/

#ifndef __IPolymesh__
#define __IPolymesh__

#if CP_PRAGMA_ONCE
#pragma once
#endif

#include "MCCompObj.h"
#include "VMTypes.h"
#include "I3DExVertex.h"
#include "I3dShFacetMesh.h"

struct IEdge;
struct IPolygon;
struct TDisplacementBrushContext;
struct IShRasterLayer;
class  TDisplacementMap;
class  TSegmentMesh;

template<class T> class TMCCopyOnWritePtr;

/// Stores a pointer to a vertex (I3DExVertex), and the associated UV index (to deal with multiple UVs per point.
///
struct TVMIVertexPtr : public TMCObject
{
	TVMIVertexPtr() : fUVIndex(0) {}
	TVMIVertexPtr(I3DExVertex* vertex,int32 uvIndex) : fVertex(vertex),fUVIndex(uvIndex) {}

	TMCCountedPtr<I3DExVertex>		fVertex;
	int32							fUVIndex;
};

const int32 kOpenSurfaces=0;
const int32 kClosedSurfaces=1;
const int32 kNoPolygons=2;
const int32 kDisconnectedVertices=3;
const int32 kNumberOfCases=4;

enum ESubdivisionType
{
	eSubdivisionNone='none',
	eSubdivisionCatm='catm'
};

// This enum corresponds to the Radio Cluster for the Symmetry Plane,
//so the 4 char id there should be same as in here.
enum ESymmetryPlaneType
{
	eSymmetryPlaneX='SymX',
	eSymmetryPlaneY='SymY',
	eSymmetryPlaneZ='SymZ'
};

//	UV Mapping modes
enum EUVMappingModes
{
	kUVSpherical	=	0,
	kUVCylindrical	=	1,
	kUVPlane		=	2,
	kUVCustom		=	3,
	kUVBox			=	4,
	kUVInvalidMode	=	0xFFFFFFFF
};


/// \addtogroup Data 
/// \{

/// Data used by IPolymesh::BoxProjection
///
struct TBoxProjectionData : public TMCObject
{
	TBoxProjectionData(){fGap=false; fProjectionMode=eCoverAll; fCustomAxis=false;}

	BoxProjectionMode fProjectionMode;

	boolean fCustomAxis;

	boolean fGap; ///< makes an emty area around the projection 
};

/// Data used by IPolymesh::SphereProjection and IPolymesh::CylinderProjection
///
struct TSphereProjectionData : public TMCObject
{
	TSphereProjectionData(){fGap=false;fAlign=kAxisX;/*fYaw=fPitch=fRoll=0;*/fOffset=TVector3::kZero;}

	 // kAxisX, kAxisY, kAxisZ or kAxisCustom
	int32 fAlign;

	// if kAxisCustom
// Not use for now	real32 fYaw;
// Not use for now	real32 fPitch;
// Not use for now	real32 fRoll;

	TVector3 fOffset;

	boolean fGap; ///< makes an emty area around the projection 
};

/// Data used by IPolymesh::PlanarProjection
///
struct TPlanarProjectionData : public TMCObject
{
	TPlanarProjectionData(){fAlign=kAxisX;/*fYaw=fPitch=fRoll=0;*/fProjectionMode=eNoSplit;fOffset=0;fGap=false;}

	 // kAxisX, kAxisY, kAxisZ or kAxisCustom
	int32 fAlign;

	// if kAxisCustom
// Not use for now	real32 fYaw;
// Not use for now	real32 fPitch;
// Not use for now	real32 fRoll;

	PlanarProjectionMode fProjectionMode;
	
	real32 fOffset;		///< if PlanarProjectionMode by position
	boolean fGap;		///< makes an emty area around the projection 
};

/// \}


const int32 kUVInterpolated		= 0;
const int32 kUVMixed			= 1;
const int32 kUVSpecified		= 2;

const int32 kUVAxisX			= 0;
const int32 kUVAxisY			= 1;
const int32 kUVAxisZ			= 2;
const int32 kUVAxisCustom		= 3;


/// \addtogroup ExternalInterface
/// \{

struct IMorphTargetData
{
	virtual void	MCCOMAPI ClearAllDeltas()=0;
	virtual void	MCCOMAPI AllocateDelta(int32 deltaCount)=0;
	virtual void	MCCOMAPI ComAddDelta(int32 vertexIndex,const TVector3& delta)=0;
	virtual int32	MCCOMAPI GetDeltaCount()=0;
	virtual void	MCCOMAPI GetDelta(int32 deltaIndex,int32& vertexIndex,TVector3& delta)=0;
};

struct IMorphAreaData
{
	virtual IMorphTargetData* MCCOMAPI ComGetMorphTargetData(int32 targetIndex) =0;
	virtual IMorphTargetData* MCCOMAPI ComCreateMorphTargetData(int32 targetIndex)=0;
};

struct IVertexCallback;
struct IPolygonCallback;

struct TSurfaceBrushParam : public TMCObject
{
public:
	TVector3		fBrushPosition;
	TVector3		fBrushNormal;
	TVector3		fI;
	TVector3		fJ;
	real			fBrushSize;
	real			fBrushStrength;
};

struct TDisplacementBrushParam : public TSurfaceBrushParam
{
public:
	enum EBrushMode
	{
		kDisplaceMode='disp',
		kSmoothMode='smoo'
	};
public:
	TDisplacementBrushParam() : fBrushAlphaMap(NULL) {}

	EBrushMode		fBrushMode;
	TMCArray<real>*	fBrushAlphaMap;		// brush alpha map if any
};

struct TWeightBrushParam : public TSurfaceBrushParam
{
	int32		fRootJointIndex;
	int32		fJointIndex;
	int32		fParentJointIndex;
	int32		fChannelIndex;
	boolean		fIsFigure;

	real32		fSmooth;
	real32		fFactor;
	real32		fInvMaxDistanceSqr;

	real32		fGaussAlpha;
	real32		fGaussOffset;
	real32		fGaussNorm;
};

struct TDisplacementExportParameters : public TMCObject
{
public:
	TDisplacementExportParameters()
	{
		fSubdivisionLevel = 0;
		fSubLevelReference = 0;
		fEnableDisplacement = false;
	}

	struct MapInfo
	{
		TMCDynamicString	fFilePath;
		IDType				fFileFormat;
		int32				fSize;	// maps are square
	};

	TMCClassArray<MapInfo>		fMaps;
	TMCArray<int32>				fMapPerShadingDomain;

	int32		fSubdivisionLevel;			// level of subdivision of the final displacement
	int32		fSubLevelReference;			// level of subdivision of the reference mesh
	boolean		fEnableDisplacement;		// enable displacement of the reference mesh
};

struct TSplitHandleInfo : public TMCObject
{
	TMCCountedPtr<IPolygon>		fPolygon;
	int32						fVertexIndex;
};

struct TSplitHandles : public TMCObject
{
	TPointMesh							fPointMesh;
	TMCClassArray<TSplitHandleInfo>		fInfos;
};


/// <P>A Polymesh is a 3D object consisting of vertices with edges and polygons defined
/// on the set of vertices.  It can apply various UV mappings to its set of vertices, and 
/// it can compute subdivision surfaces using its polygons as the control mesh.  For rendering
/// and display, it can output a facet mesh based on its polygons or the subdivision surface.</P>
///
struct IPolymesh: public IMCUnknown 
{
public:
	virtual void MCCOMAPI SetSelection(boolean selected) =0;		// acts on all vertices
	virtual boolean MCCOMAPI GetSelection()=0;
	virtual boolean MCCOMAPI GetPartialSelection()=0;
	virtual boolean MCCOMAPI HasSelectedPolygon(boolean useSymmetry=false)=0;
	virtual boolean MCCOMAPI HasSelectedEdge()=0;
	virtual boolean	MCCOMAPI GetSelectedPolygonsIndex(TMCArray<int32>& selectionsIndexes)=0;
	virtual boolean	MCCOMAPI GetSelectedEdgesIndex(TMCArray<int32>& selectionsIndexes)=0;

	// -Description: Returns the number of vertices in the polymesh
	//
	virtual int32 MCCOMAPI  GetNbVertices()=0;
	
	// -Description: Returns a pointer to a vertex
	//
	// -Parameters:
	// 
	// index:		index of the vertex to return
	//
	virtual I3DExVertex* MCCOMAPI GetVertexNoAddRef(int32 index) =0;

	///Fills an array with the list of all the vertices of the polymesh
	virtual void		MCCOMAPI GetVertices	(TMCPtrArray<I3DExVertex>& outVertices) = 0;

	virtual void		MCCOMAPI ForAllVertices(IVertexCallback* callback) = 0;
	virtual void		MCCOMAPI ForAllPolygons(IPolygonCallback* callback) = 0;

	virtual int32		MCCOMAPI GetNbEdges() const = 0;
	virtual IEdge*		MCCOMAPI GetEdgeNoAddRef(int32 index) =0;

	///Fills an array with the list of all the edges of the polymesh
	virtual void		MCCOMAPI GetEdges	(TMCPtrArray<IEdge>& outEdges) = 0;

	virtual int32		MCCOMAPI GetNbPolygons()=0;
	virtual IPolygon*	MCCOMAPI GetPolygonNoAddRef(int32 index) =0;

	///Fills an array with the list of all the polygons of the polymesh
	virtual void		MCCOMAPI GetPolygons(TMCPtrArray<IPolygon>& outPolygons) = 0;


	// -Description: Creates a new vertex
	//
	// -Parameters:
	//
	// vertexPtr	: a pointer to the vertex created
	// position		: The position of the new vertex
	//
	virtual void		MCCOMAPI CreateVertex(I3DExVertex** vertexPtr,const TVector3 &position)=0;

	// Looks for a vertex at position, and if it exists, returns it, otherwise creates one there.
	virtual void		MCCOMAPI CreateOrFindVertex(I3DExVertex** vertexPtr,const TVector3 &position)=0;

	virtual ErrorCode	MCCOMAPI FillPolygons(boolean useSymmetry)=0;					// acts on selected polylines
	virtual void		MCCOMAPI Delete()=0;
	virtual void		MCCOMAPI DeleteSelectedEdges()=0;
	virtual void		MCCOMAPI DeleteSelectedVertices(boolean useSymmetry)=0;
	virtual void		MCCOMAPI DeleteSelectedPolygons(boolean useSymmetry)=0;

	// ****************************************************************************
	//								GetBoundingBox
	// 
	// -Description: return the bounding box of the polymesh or the bounding box of
	//				the selected vertices of the polymesh
	//
	// -Parameters: set selection to true to get the bounding box of the selected 
	//				vertices only. If includeSymSelection is also true, the bounding
	//				is computed also for the symetric selected vertices.
	//
	// -Returns: return true if something was found
	//
	virtual boolean		MCCOMAPI GetBoundingBox(TBBox3D &bbox, boolean selection, boolean includeSymSelection=false, boolean ignoreSkinning=true ) =0;
	virtual boolean		MCCOMAPI GetUVBoundingBox(TBBox2D &bbox, boolean selection=false) = 0;

    virtual void		MCCOMAPI Triangulate()=0;								//	Applies to selected polygons
	virtual ErrorCode	MCCOMAPI GetPolylineHeads(TMCPtrArray<I3DExVertex> &vertices,TMCArray<boolean>& AreClosed,boolean useSymmetry) =0;
	virtual void		MCCOMAPI Clone(IPolymesh**)=0;							//	Remember to Release this object
	virtual boolean		MCCOMAPI Weld(real tolerance, boolean alignOnly) =0;
	virtual void		MCCOMAPI Merge(IPolymesh *polymesh) =0;
	virtual void		MCCOMAPI InvertNormals()=0;
	virtual void		MCCOMAPI FlipCheck(boolean force) = 0;
	virtual void		MCCOMAPI EnableFlipCheck(boolean value, boolean checkNow = true) = 0;
	virtual boolean		MCCOMAPI IsPolymeshManifold() = 0;
	
	// ****************************************************************************
	//								MakePolygon
	// 
	/// Creates a new polygon in this Polymesh.
	/// 
	/// \param vertices  Array of vertices in the new Polygon
	/// \return A pointer to the new Polygon created
	///
	virtual IPolygon* MCCOMAPI MakePolygon(const TMCClassArray<TVMIVertexPtr> &vertices) =0;	//	Remember to Release this object

	// ****************************************************************************
	//								MakePolygonCarefully
	// 
	/// Creates a new polygon.  Note that MakePolygonCarefully checks first to make
	/// sure that a polygon with these vertices doesn't already exist in the polymesh.
	///
	/// \param ivertices  Array of vertices in the new Polygon
	/// \return A pointer to the new Polygon created
	/// 
	virtual IPolygon* MCCOMAPI MakePolygonCarefully(const TMCClassArray<TVMIVertexPtr> &ivertices) =0;	//	Remember to Release this object

	// ****************************************************************************
	//								MakePolygonByForce
	// 
	/// Creates a new polygon.  MakePolygonByForce inserts the polygon, regardless of whether or not the edges
	/// of the polgon already have two polygons, by creating new edges.
	/// 
	/// \param ivertices  Array of vertices in the new Polygon
	/// \return A pointer to the new Polygon created
	/// 
	virtual IPolygon* MCCOMAPI MakePolygonByForce(const TMCClassArray<TVMIVertexPtr> &ivertices) =0;
	 
	// -Description: Import a vertex in the polymesh
	//
	// -Parameters:
	//
	// vertex3d			: the vertex data
	// useUV			: if true the uv are taken into account
	// index			: a unique index used to refer to this vertex
	//
	// -Returns: A reference to the new vertex created
	//
	virtual TVMIVertexPtr MCCOMAPI ImportVertex(const TVertex3D &vertex3d,boolean useUV,int32 index) =0;	//	Remember to Release this object

	virtual void MCCOMAPI Topology(int32 counts[kNumberOfCases]) =0;
	virtual void MCCOMAPI StartEdgeTransfer()=0;
	virtual int32 MCCOMAPI EdgeTransfer(EdgeData edgeBuffer[], int32 bufferSize) =0;
	virtual void MCCOMAPI ConsistencyCheck()=0;
	virtual void MCCOMAPI PreBoolean()=0;
	virtual void MCCOMAPI Split(IPolymesh *polymesh) =0;
	virtual void MCCOMAPI GetName(char* name) =0;
	virtual void MCCOMAPI SetName(char* name) =0;

	//	UV mapping
	virtual void	MCCOMAPI SetUVPlaneAxis(int32 shadeAxis,int32 spaceAxis,boolean positive) =0;
	virtual int32	MCCOMAPI GetUVPlaneAxis(int32 shadeAxis) =0;
	virtual real	MCCOMAPI GetUVValue(int32 shadeAxis) =0;
	virtual boolean MCCOMAPI GetUVPlanePositive(int32 shadeAxis) =0;

	// ****************************************************************************
	//								SetUVCustomMode
	// 
	// -Description:
	//		Set the interpolated status of the vertices to kUVInterpolated or kUVSpecified
	// -Parameters:
	//		axis: 0: U axis, 1: V axis
	//		mode: kUVInterpolated or kUVSpecified
	//		onSelection: true to apply only on selected vertices
	virtual void MCCOMAPI SetUVCustomMode(int32 axis, int32 mode, boolean onSelection) =0;

	// ****************************************************************************
	//								GetUVCustomMode
	// 
	// -Description:
	//		return the interpolated status of the selection when the projection mapping
	//		is set to Custom
	// -Parameters:
	//		0: U axis, 1: V axis
	// -Returns: 
	//		kUVInterpolated if all the selected vertices are interpolated,
	//		kUVSpecified if all the selected vertices are specified
	//		kUVMixed otherwise
	virtual int32 MCCOMAPI GetUVCustomMode(int32 axis) =0;

	virtual void			MCCOMAPI SetUVMode(EUVMappingModes mode) =0;
	virtual EUVMappingModes	MCCOMAPI GetUVMode()=0;

	// Gets the UV wrapping
	virtual void MCCOMAPI GetUVWraparound	(boolean& outWrapU, boolean& outWrapV) = 0;

	// Sets the UV wrapping
	virtual void MCCOMAPI SetUVWraparound	(const boolean inWrapU, const boolean inWrapV) = 0;
	

	virtual void MCCOMAPI SetUVAxisMode		(int32 mode) =0;
	virtual int32 MCCOMAPI GetUVAxisMode		()=0;
	virtual void MCCOMAPI SetUVAxis			(real roll,real pitch,real yaw) =0;
	virtual void MCCOMAPI GetUVAxis			(real &roll,real &pitch,real &yaw) =0;

	// ****************************************************************************
	//								BoxProjection
	// 
	// -Description: project the UV mapping of the polymesh on a Box.
	//				 Note: this projection is effective only if the UVMode of the polymesh
	//				 is set to kUVCustom.
	//
	// -Parameters: onSelection: project only the selected vertices or the whole polymesh.
	//				data: projection parameters.
	//
	virtual void MCCOMAPI BoxProjection( boolean onSelection, TBoxProjectionData& data )=0;

	// ****************************************************************************
	//								SphereProjection
	// 
	// -Description: project the UV mapping of the polymesh on a Sphere.
	//				 Note: this projection is effective only if the UVMode of the polymesh
	//				 is set to kUVCustom.
	//
	// -Parameters: onSelection: project only the selected vertices or the whole polymesh.
	//				data: projection parameters.
	//
	virtual void MCCOMAPI SphereProjection( boolean onSelection, TSphereProjectionData& data )=0;

	// ****************************************************************************
	//								CylinderProjection
	// 
	// -Description: project the UV mapping of the polymesh on a Cylinder.
	//				 Note: this projection is effective only if the UVMode of the polymesh
	//				 is set to kUVCustom.
	//
	// -Parameters: onSelection: project only the selected vertices or the whole polymesh.
	//				data: projection parameters.
	//
	virtual void MCCOMAPI CylinderProjection( boolean onSelection, TSphereProjectionData& data )=0;

	// ****************************************************************************
	//								PlanarProjection
	// 
	// -Description: project the UV mapping of the polymesh on a Plane.
	//				 Note: this projection is effective only if the UVMode of the polymesh
	//				 is set to kUVCustom.
	//
	// -Parameters: onSelection: project only the selected vertices or the whole polymesh.
	//				data: projection parameters.
	//
	virtual void MCCOMAPI PlanarProjection( boolean onSelection, TPlanarProjectionData& data )=0;

	virtual void MCCOMAPI  SetMarker(int32 iD) =0;
	virtual int32 MCCOMAPI  GetMarker() =0;
	virtual	void MCCOMAPI  GetVertexIndexList( I3DExVertex *v, TMCArray<int32> &Index ) = 0;
	virtual void MCCOMAPI  FlushOptimizer(void) = 0;
	virtual void MCCOMAPI  Transform(const TTransform3D &trans ) = 0;
	virtual void MCCOMAPI InvertSelection( int32 selectionFlag ) = 0;

	// hide/show all the vertices
	virtual void MCCOMAPI SetVerticesHidden(boolean hidden) = 0;
	
	// ****************************************************************************
	//								SetIsSymmetryEnabled
	// 
	// -Description:
	//		Set If Symmetry is enabled
	// -Parameters:
	//			type: boolean 
	virtual void	MCCOMAPI SetSymmetricModelingEnabled(boolean enable) = 0;

	// ****************************************************************************
	//								GetIsSymmetryEnabled
	// 
	// -Description:
	//			Return If Symmetry is enabled
	// -Returns:
	//			boolean 
	virtual boolean	MCCOMAPI GetIsSymmetricModelingEnabled() = 0;

	// ****************************************************************************
	//								SetSymmetryPlane
	// 
	// -Description:
	//		Set the plane of symmetry for symmetric modelling
	virtual void				MCCOMAPI SetSymmetryPlane(const TVector3& axis, const TVector3& center) = 0;

	// ****************************************************************************
	//								GetSymmetryPlane
	// 
	// -Description:
	//			Return the current plane of symmetry for symmetric modelling
	virtual void				MCCOMAPI GetSymmetryPlane(TVector3& axis, TVector3& center) = 0;


	// ****************************************************************************
	//								SetSubdivisionType
	// 
	// -Description:
	//			Set the type of subdivision to be applyed on the polymesh. If the type
	//		is different from eSubdivisionNone, the subdivision of the polymesh is 
	//		determined by the subdivision level (see SetSubdivisionLevel(int32 level))
	// -Parameters:
	//			type: eSubdivisionCatm == Catmull Clark subdivision
	virtual void				MCCOMAPI SetSubdivisionType(ESubdivisionType type) = 0;

	// ****************************************************************************
	//								GetSubdivisionType
	// 
	// -Description:
	//			Return the current subdivision type applyed onm the polymesh
	// -Returns:
	//			eSubdivisionCatm == Catmull Clark subdivision
	virtual ESubdivisionType	MCCOMAPI GetSubdivisionType() = 0;

	// ****************************************************************************
	//								SetSubdivisionLevel
	// 
	/// Determines the level of subdivision applied on the mesh when the 
	/// subdivision type is different from eSubdivisionNone
	/// 
	/// \param level          The number of subdivision passes applied on the mesh
	/// \param renderingMesh  True if it is for the rendering mesh (false means modeling mesh)
	/// 
	virtual void				MCCOMAPI SetSubdivisionLevel(int32 level,boolean renderingMesh) = 0;

	// ****************************************************************************
	//								GetSubdivisionLevel
	// 
	// -Description:
	//			
	// ****************************************************************************
	//								GetSubdivisionLevel
	// 
	/// Returns the current subdivision level applyed on the polymesh
	/// 
	/// \param renderingMesh  True if we are asking for the rendering mesh
	/// 
	virtual int32				MCCOMAPI GetSubdivisionLevel(boolean renderingMesh) = 0;

	// ****************************************************************************
	//								ConvertSubdivisionToPolygons
	// 
	// -Description: use the polymesh 'this' and its subbivision to create a new one
	//
	// -Returns:	iPolymesh: the newly created polymesh. NULL if there's no subdivision on 
	//			this polymesh
	//
	virtual void				MCCOMAPI ConvertSubdivisionToPolygons( IPolymesh** iPolymesh )=0;

	// ****************************************************************************
	//								GetPolyMeshFacetMesh
	// 
	// -Description: 
	//			create a facet mesh using the polymesh
	// -Parameters: 
	//			the facet mesh to be build
	virtual void				MCCOMAPI GetPolyMeshFacetMesh( FacetMesh** outMesh )=0;

	// ****************************************************************************
	//								Resize
	// 
	// -Description: scale the polymesh
	//
	// -Parameters: scale: value along X, Y and Z axis
	//				center: center of scaling
	//
	virtual void				MCCOMAPI Resize(TVector3& scale, TVector3& center, boolean useSymmetry) = 0;

	// ****************************************************************************
	//								GetPolymeshVisibility
	// 
	/// Returns the visibility of the polymesh. Note that this flag is different compared
	/// to the hidden property of the vertices. The flag on the vertices affects only the
	/// modeler. This function returns the visibility of the polymesh in the scene (both
	/// 3DView and rendering).
	///
	virtual boolean				MCCOMAPI GetPolymeshVisibility() const = 0;

	// ****************************************************************************
	//								SetPolymeshVisibility
	// 
	/// Sets the visibility of the polymesh. Note that this flag is different compared
	/// to the hidden property of the vertices. The flag on the vertices affects only the
	/// modeler. This function sets the visibility of the polymesh in the scene (both
	/// 3DView and rendering).
	///
	/// \param visible		The new visibility flag
	///
	virtual void				MCCOMAPI SetPolymeshVisibility(boolean visible) = 0;

	// ****************************************************************************
	//								SetPolymeshVisibility
	// 
	/// Returns a pointer to the data for a morph area on a given polymesh
	///
	/// \param morphAreaIndex		The index of the morph area
	///
	virtual IMorphAreaData* MCCOMAPI GetMorphAreaData(int32 morphAreaIndex)=0;

	// ****************************************************************************
	//								ApplyDisplacementBrush
	// 
	/// Applies a displacement brush to the polymesh.
	///
	/// \param displacementParam		The index of the morph area
	///
	virtual void MCCOMAPI ApplyDisplacementBrush(const TDisplacementBrushParam& displacementParam,TDisplacementBrushContext& context)=0;

	// ****************************************************************************
	//								BuildDisplacementMaps
	// 
	/// Fills the displacement maps associated with a given model
	///
	/// \param rasterLayers			The maps to fill
	/// \param exportParameters		The parameters to control the creation of the maps
	///
	virtual void MCCOMAPI BuildDisplacementMaps(TMCCountedPtrArray<IShRasterLayer>&		rasterLayers,
												const TDisplacementExportParameters&	exportParameters)=0;

	// ****************************************************************************
	//								CleanDisplacementAlpha
	// 
	/// Clean the alpha map for this particular polymesh.
	///
	///
	virtual void MCCOMAPI CleanDisplacementAlpha()=0;

	// ****************************************************************************
	//								UpdateDisplacementBetweenLevels
	// 
	/// Propagate the changes of the displacement from maxLevel to minLevel
	///
	virtual void MCCOMAPI UpdateDisplacementBetweenLevels(int32 minLevel,int32 maxLevel)=0;

	// ****************************************************************************
	//								SwapDisplacementMap
	// 
	/// Swaps the displacement maps at a subdivision given level
	///
	///
	virtual void MCCOMAPI SwapDisplacementMap(int32 subdivisionLevel,TMCCopyOnWritePtr< TDisplacementMap >& displacementMap)=0;


	// ****************************************************************************
	//								GetDisplacementMap
	// 
	/// Returns the displacement map at a subdivision given level
	///
	virtual void MCCOMAPI GetDisplacementMap(int32 subdivisionLevel,TMCCopyOnWritePtr< TDisplacementMap >& displacementMap)=0;


	// ****************************************************************************
	//								SetDisplacementMap
	// 
	/// Sets the displacement map at a subdivision given level
	///
	virtual void MCCOMAPI SetDisplacementMap(int32 subdivisionLevel,const TMCCopyOnWritePtr< TDisplacementMap >& displacementMap)=0;

	// ****************************************************************************
	//								HasDisplacement
	// 
	/// Return if polymesh has displacement maps
	///
	virtual boolean MCCOMAPI HasDisplacement()=0;
	
	// ****************************************************************************
	//								GetLastDisplacementLevelModified
	// 
	/// Returns the index of the last displacement levle that was modified. This is
	/// used to apply the changes to the lower levels of resolutions.
	///
	virtual int32 MCCOMAPI GetLastDisplacementLevelModified()=0;

	// ****************************************************************************
	//								SetLastDisplacementLevelModified
	// 
	/// Sets the index of the last displacement levle that was modified. This is
	/// used to apply the changes to the lower levels of resolutions.
	///
	virtual void MCCOMAPI SetLastDisplacementLevelModified(int32 level)=0;

	// ****************************************************************************
	//								StoreNormalsRayHit
	// 
	/// Stores the normals of the mesh for use in I3DExVertexPrimitive::RayHit().
	///
	virtual void MCCOMAPI StoreNormalsForRayHit()=0;

	// ****************************************************************************
	//								DeleteStoredNormals
	// 
	/// Delete the normal stored with StoreNormalsForRayHit
	///
	virtual void MCCOMAPI DeleteStoredNormals()=0;

	// ****************************************************************************
	//								HasSelectedParts
	// 
	/// Returns true if some elements of the polymesh are selected
	///
	virtual boolean MCCOMAPI HasSelectedParts()=0;

	// ****************************************************************************
	//								FinishDisplacement
	// 
	/// Clean the structures and unset the flags used for displacement
	///
	virtual void MCCOMAPI FinishDisplacement()=0;
	// ****************************************************************************
	//								FinishDisplacement
	// 
	/// Clean the Selection Cache build for displacement
	///
	virtual void MCCOMAPI ClearSelectionCache()=0;

	// ****************************************************************************
	//								GetSubdivisionUVMode
	// 
	/// Return the current UV subdivision mode applyed on the polymesh
	///
	virtual boolean	MCCOMAPI GetSubdivisionUVMode() = 0;

	// ****************************************************************************
	//								SetSubdivisionUVMode
	// 
	/// Sets the mode of UV subdivision used for this polymesh
	/// 
	/// \param subUVMode       The mode of UV subdivision applied on the mesh
	/// 
	virtual void MCCOMAPI SetSubdivisionUVMode(boolean subUVMode) = 0;

	// ****************************************************************************
	//								SetDisplacementMode
	// 
	/// Enable/Disable the displacement applyed on the polymesh
	/// 
	/// \param enableDisp  True if displacement is enable
	/// 
	virtual void				MCCOMAPI SetDisplacementMode(boolean enableDisp) = 0;

	// ****************************************************************************
	//								GetDisplacementMode
	// 
	/// Returns true if the displacement applyed on the polymesh is emable
	/// 
	/// 
	virtual boolean				MCCOMAPI GetDisplacementMode() = 0;

	// ****************************************************************************
	//								DeleteDisplacement
	// 
	/// Swap to original positions and delete actual displacement
	/// 
	/// 
	virtual	void				MCCOMAPI DeleteDisplacement() = 0;

	// ****************************************************************************
	//								CleanDisplacementMap
	// 
	/// Clean original position and displacement maps.
	///	Original positions will become actual positions (displaced or not)
	/// 
	virtual	void				MCCOMAPI CleanDisplacementMap() = 0;

	// ****************************************************************************
	//								GetPositionsBeforeDisplacementMap
	// 
	/// Return position before displacement map.
	///	
	/// \param originalPositions	position before displacement map.
	/// 
	virtual	void				MCCOMAPI GetPositionsBeforeDisplacementMap(TMCCopyOnWritePtr<TDisplacementMap>& originalPositions) = 0;

	// ****************************************************************************
	//								SwapPositionsBeforeDisplacementMap
	// 
	/// Swap position before displacement map.
	///	
	/// \param originalPositions	position before displacement map.
	/// 
	virtual	void				MCCOMAPI SwapPositionsBeforeDisplacementMap(TMCCopyOnWritePtr<TDisplacementMap>& originalPositions) = 0;

	// ****************************************************************************
	//								SwapPositionsForMorphEdition
	// 
	/// Swap displacement map before or after Moprh edition.
	///	
	/// \param isEditing	True if we are in Morph Edition Mode.
	/// 
	virtual	void				MCCOMAPI SwapPositionsForMorphEdition(boolean isEditing) = 0;

	virtual void				MCCOMAPI FlipCheckIfSuccessful(boolean force) = 0;

	// ****************************************************************************
	//								ApplyWeightBrush
	// 
	/// Applies a weight brush to the polymesh.
	///	
	/// \param weightParam	Holds information about the brush's location.
	/// 
	virtual void				MCCOMAPI ApplyWeightBrush(const TWeightBrushParam& weightParam) = 0;

	// ****************************************************************************
	//								GetUVModelerData
	// 
	/// Get the UV modeler data.
	///	
	virtual void				MCCOMAPI GetUVModelerData(TSegmentMesh& segmentMesh, TPointMesh& pointMesh, int32 shadingDomain, TSplitHandles* splitHandles, TMCColorRGBA8& meshBaseColor) = 0;
	
	// ****************************************************************************
	//								SelectUVPatch
	// 
	/// Select/UnSelect a UV patch
	///
    virtual void				MCCOMAPI SelectUVPatch(I3DExVertex *vertexInPatch, int32 uvIndex, boolean select) = 0;
	// ****************************************************************************
	//								UpdateUVColorData
	// 
	/// Get the UV modeler data.
	///	
	virtual void				MCCOMAPI UpdateUVColorData(TSegmentMesh& segmentMesh, TPointMesh& pointMesh, int32 shadingDomain, TSplitHandles* splitHandles, TMCColorRGBA8& meshBaseColor) = 0;
	// ****************************************************************************
	//								SetUVBoundingBox
	// 
	/// Set the bounding box of the UVs
	///	
	virtual boolean		MCCOMAPI SetUVBoundingBox(const TBBox2D &bbox) = 0;

	// ****************************************************************************
	//								GetUVModelerData2
	// 
	/// Get the UV modeler data.
	///	
	virtual void				MCCOMAPI GetUVModelerData2(TSegmentMesh& segmentMesh, TPointMesh& pointMesh, int32 shadingDomain, TSplitHandles* splitHandles, TMCColorRGBA8& meshBaseColor, boolean wrap) = 0;
};

/// \}

#endif
