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

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

		Author:	Charles
		Date:	10/4/2002

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

#ifndef __I3DExVertex__
#define __I3DExVertex__

#if CP_PRAGMA_ONCE
#pragma once
#endif

#include "MCCompObj.h"
#include "InterfaceIDs.h"
#include "Vector2Fwd.h"
#include "Vector3Fwd.h"

struct IEdge;
struct IPolymesh;
class  TVertexSkinInfo;
class  TJointIndex;
class  TVertexPrimSkinInfo;
class  TMorphIDList;
class  TMCPoint;
template <class T> class TMCPtrArray;
template <class T> class TMCArray;




//****** Globally Unique Ids *************************************************

MCDEFINE_GUID_SAFELIB2(IID_I3DExVertex, R_IID_I3DExVertex);


/// \addtogroup ExternalInterface
/// \{

/// This interface can be used to access a vertex inside a vertex primitive.
///
struct I3DExVertex: public IMCUnknown 
{
	// ****************************************************************************
	//								GetPosition
	// 
	/// Returns the position of the vertex.
	///
	virtual void			MCCOMAPI GetPosition(TVector3 &position) =0;

	// ****************************************************************************
	//								SetPosition
	// 
	/// Sets the position of the vertex.
	///
	virtual void			MCCOMAPI SetPosition(TVector3 &position) =0;

	// ****************************************************************************
	//								SetSelection
	// 
	/// Select or unselect the vertex. Depending on the mode used, edges
	/// around can be selected
	///
	/// \param selected			True to select, false to deselect
	///	\param autoSelection	True to complete the selection
	/// \param selectAllUV		True is all uv should be selected
	///
	virtual void			MCCOMAPI SetSelection(boolean selected, boolean autoSelection=true, boolean selectAllUV=true) =0;
	
	// ****************************************************************************
	//								SetSelection
	//
	/// Returns true if the vertex is selected.
	///
	virtual boolean			MCCOMAPI GetSelection(boolean useSymmetry=false)=0;
	virtual void			MCCOMAPI Delete( boolean preserveTopology=false )=0;
	virtual IEdge*			MCCOMAPI CreateEdge(I3DExVertex *v) =0;
	virtual IPolymesh*		MCCOMAPI GetPolymesh()=0;					
	virtual long			MCCOMAPI GetNbEdges()=0;	
	virtual IEdge*			MCCOMAPI GetEdge(long index) =0;

	///Find if there is an edge between two vertices
	virtual IEdge*			MCCOMAPI FindEdge	(I3DExVertex* vertex) = 0;

	virtual void			MCCOMAPI SetHidden(boolean hidden) =0;
	virtual boolean			MCCOMAPI GetHidden() const = 0;

	// ****************************************************************************
	//								SetUsed
	// 
	/// Set On or Off a flag in the vertex. The flag status can then be checked
	///	with GetUsed
	virtual void			MCCOMAPI SetUsed(boolean used) =0;

	// ****************************************************************************
	//								GetUsed
	// 
	/// Returns the Used flag status. This flag can be set On or Off with SetUsed
	///
	virtual boolean			MCCOMAPI GetUsed()=0;

	virtual void			MCCOMAPI MergeEdges()=0;
	virtual void			MCCOMAPI SetBooleanClassification(const long classification) =0;
	virtual const long		MCCOMAPI GetBooleanClassification()=0;
	virtual boolean			MCCOMAPI Weld(I3DExVertex *v, boolean keepUVs) =0;
	virtual IEdge*			MCCOMAPI Link(I3DExVertex *v) =0;
	virtual boolean			MCCOMAPI GetBestPlane(TVector3 &ii,TVector3 &jj,TVector3 &kk,TVector3 &center) =0;
	virtual void			MCCOMAPI GetNeighborVertices(TMCPtrArray<I3DExVertex> &vertices,boolean extended) =0;
	virtual boolean			MCCOMAPI GetBestPlane2(TMCPtrArray<I3DExVertex> &vertices,TVector3 &ii,TVector3 &jj,TVector3 &kk,TVector3 &center) =0;
	virtual I3DExVertex*	MCCOMAPI CloneConjugate()=0;

	// ****************************************************************************
	//								GetNormal
	// 
	/// Returns the average of all the normals on this vertex
	///
	virtual void			MCCOMAPI GetNormal(TVector3 &normal) =0;

	// ****************************************************************************
	//								GetNormal
	// 
	/// Returns the ieme normal on the vertex.
	/// 
	/// \param normal	The vector of the normal that is returned.
	/// \param index	The index of the normal (0<= index < GetNormalCount())
	///
	virtual void			MCCOMAPI GetNormal(TVector3 &normal, const int32 index) =0;

	// ****************************************************************************
	//								GetNormalCount
	// 
	///	Returns the number of normals on this vertex ( == smoother count )
	///
	virtual int32			MCCOMAPI GetNormalCount() =0;

	virtual void			MCCOMAPI SetIndex(long index) =0;
	virtual long			MCCOMAPI GetIndex()=0;
	virtual void			MCCOMAPI GetName(char* name)=0;
	virtual void			MCCOMAPI SetName(char* name)=0;
//	virtual real			MCCOMAPI GetUVCustomValue(long axis) =0;
//	virtual void			MCCOMAPI SetUVCustomValue(long shadeAxis, real value) =0;


	// ****************************************************************************
	//								GetUVCount
	// 
	/// Returns the number of UV stored on this vertex
	///
	virtual int32			MCCOMAPI GetUVCount() = 0;
	
	// ****************************************************************************
	//								AddUV
	//
	/// Adds new uv coordinates (texture coordinates) on this vertex.
	///
	/// \param uv	Value of the uv to add.
	///
	/// \return The index of the uv created on this vertex.
	///
	virtual int32			MCCOMAPI AddUV(const TVector2& uv) = 0;

	// ****************************************************************************
	//								ClearUV
	// 
	/// Clear the UV list on this vertex.
	/// Important: this method does not clean the reference to the UV
	///	list in the surrounding polygons.
	///
	virtual void			MCCOMAPI ClearUV() = 0;

	// ****************************************************************************
	//								RemoveUV
	// 
	/// Removes an UV from the list. The last element of the list 
	/// will be copy in place of the removed UV => order in the UV list 
	///	is modified. The references to the removed index in the polygons
	///	arround are set to the UVReplacement index.
	///
	/// \param UVIndex			the UV to be removed
	///	\param UVReplacement	the new index for the surrounding polygons. 
	///
	/// \return	-1 if could perform the removal ( index out of range, or 
	///	UVIndex == UVReplacement), else return the new UVReplacement index
	///
	virtual int32			MCCOMAPI RemoveUV(const int32 UVIndex, const int32 UVReplacement=0) = 0;

	/// Returns the value of the uv (texture coordinates) of the vertex
	///
	/// \param index	index of the uv coordinates to set (a vertex can have several)
	///
	virtual const TVector2&	MCCOMAPI GetUV(int32 index) = 0;

	/// Sets the value of the uv (texture coordinates) of the vertex
	///
	/// \param index	index of the uv coordinates to set (a vertex can have several)
	/// \param uv	The new uv coordinates.
	///
	virtual void			MCCOMAPI SetUV(int32 index,const TVector2& uv) = 0;

	/// Returns the selection state of the given uv.
	///
	virtual boolean			MCCOMAPI IsUVSelected(int32 index) = 0;

	/// Returns the visibility state of the given uv.
	///
	virtual boolean			MCCOMAPI IsUVHidden(int32 index) = 0;

	/// Selects the uv.
	///
	virtual void			MCCOMAPI SelectUV(int32 index, boolean select) = 0;

	/// Sets the mode for the default uvs (custom or calculated)
	///
	/// \param mode		the new uv mode
	/// \param axis		the axis (-1 means both)
	///
	virtual void			MCCOMAPI SetCustomUVMode(int32 mode, int32 axis=-1) =0;

	/// Gets the mode for the default uvs (custom or calculated)
	///
	virtual int32			MCCOMAPI GetCustomUVMode(int32 axis) =0;

	/// Returns the information related to the skinning of this vertex
	///
	virtual TVertexSkinInfo* MCCOMAPI GetSkiningData() const = 0;

	///	Sets the skining info on a vertex.
	///	The vertex primitive is supposed to be attached to a skeleton
	virtual void			MCCOMAPI SetSkiningData(const TVertexSkinInfo& skinInfo) = 0;

	// ****************************************************************************
	//								SetSpecial
	// 
	/// Sets the value of the flag 'special' of the vertex
	///
	/// \param special		Value to be set.
	///
	virtual void			MCCOMAPI SetSpecial(boolean special)=0;

	// ****************************************************************************
	//								SetUVUnfoldPinning
	// 
	/// Sets the value of the flag 'UV unfold pinning point' of the vertex
	///
	/// \param special		Value to be set.
	///
	virtual void			MCCOMAPI SetUVUnfoldPinning(boolean pinning)=0;

	// ****************************************************************************
	//								GetUVUnfoldPinning
	// 
	/// Gets the value of the flag 'UV unfold pinning point' of the vertex
	///
	///
	virtual boolean			MCCOMAPI GetUVUnfoldPinning() const = 0;

	// ****************************************************************************
	//								SetNonDisplayedSpecial
	// 
	///	Sets the value of the flag 'special non-displayed' of the vertex. The non-
	///	displayed special vertex is a vertex that can be found at the primitive level
	///	and that's not visible on the screen ( as opposed to the special vertex who 
	///	appears yellow on the mesh )
	///
	virtual void			MCCOMAPI SetNonDisplayedSpecial(boolean special)=0;

	// get the morph area for this vertex
	virtual int32			MCCOMAPI GetMorphAreaIndex() const =0;

	/// Sets the morph offset for a given morph target index for this vertex.
	virtual void			MCCOMAPI SetMorphOffset( const int32 targetIndex, const TVector3& offset ) =0;

	/// Gets the morph offset for a given morph target index for this vertex.
	virtual void			MCCOMAPI GetMorphOffset( const int32 targetIndex, TVector3& offset ) =0;

	/// Gets the symmetrical vertex if any in the mesh and if the symmetrical modeling is enabled
	virtual I3DExVertex*	MCCOMAPI GetSymmetricalVertex() = 0;

	///		Gets the skinned position of the vertex
	// -Parameters:
	//		inMeshSkinInfo: the info necessary for the skinning
	//		inRecomputeCache: if true, the cached skinned position will be updated
	// -Returns:
	//		outSkinedPosition: the skinned position of the vertex
	//


	virtual void			MCCOMAPI GetPositionWithOptions	( TVector3&	outPosition, TVertexPrimSkinInfo* inMeshSkinInfo, const boolean	inRecomputeCache) const = 0;


	virtual const TMCPoint&	MCCOMAPI GetOriginIndexInFigure	() const = 0;


	/// Gets the regular position of the vertex or the morphed position if applicable
	virtual void			MCCOMAPI GetPositionWithMorphs(const TMorphIDList* morphsToApply, TVector3& outPosition) const = 0;
};


/// \}




#endif





