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

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

		Author:	Charles
		Date:	10/7/2002

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

#ifndef __IPolygon__
#define __IPolygon__

#if CP_PRAGMA_ONCE
#pragma once
#endif

#include "MCBasicTypes.h"
#include "VMTypes.h"

struct IEdge;
struct I3DExVertex;
struct IPolymesh;


/// \addtogroup ExternalInterface
/// \{

struct IFacet: public IMCUnknown 
{
	virtual void MCCOMAPI GetFacet3D(TFacet3D &facet3d) =0;
    virtual boolean MCCOMAPI GetDegenerate() const =0;
    virtual boolean MCCOMAPI GetHidden() = 0;
    virtual I3DExVertex* MCCOMAPI GetVertex(int32 i) const = 0;    
};

/// \}


/// \addtogroup ExternalInterface
/// \{

/// <P>A Polygon is the basic 3D primitive that make up a Polymesh.  The have at least 3 vertices,
/// but can have more.  Polygons with more than three vertices will be tessellated into triangular 
/// facets for display. Polygons as viewed in the plane from above the normal have vertices numbered 
/// clockwise.</P>
/// \see { IEdge IPolymesh }
///
struct IPolygon: public IMCUnknown
{
public:

	// ****************************************************************************
	//								GetNbVertices
	// 
	/// \return The number of vertices in the polygon (which will equal the number of edges).
	/// 
	virtual long			MCCOMAPI	GetNbVertices() const =0;

	// ****************************************************************************
	//								GetVertex
	// 
	/// Returns the indexed vertex of the polygon
	/// 
	/// \param indexInPolygon  The index of the vertex to get
	/// \return A pointer to the vertex indexed, or NULL if the index is out of range
	virtual I3DExVertex*	MCCOMAPI	GetVertex(long indexInPolygon) =0;

	// ****************************************************************************
	//								GetEdge
	// 
	/// Returns the indexed edge of the polygon
	/// 
	/// \param indexInPolygon  The index of the edge to get
	/// \return A pointer to the Edge indexed, or NULL if the index is out of range
	/// 
	virtual IEdge*			MCCOMAPI	GetEdge(long indexInPolygon) =0;
	
	// ****************************************************************************
	//								Delete
	// 
	/// Removes this Polygon from its Polymesh and deletes it.
	/// 
	virtual void			MCCOMAPI	Delete()=0;
	
	// ****************************************************************************
	//								GetFacet
	// 
	/// Returns the indexed facet in the polygon
	/// 
	/// \param indexInPolygon  The index of the Facet to get
	/// \return A pointer to the Facet indexed, or NULL if the index is out of range
	/// 
	virtual IFacet*			MCCOMAPI	GetFacet(long indexInPolygon) =0;
		// ****************************************************************************
	//								FacetCount
	// 
	/// Returns number of facets in the polygon.
    ///
    //// \return Number of facets in the polygon.
	///
    virtual int32 MCCOMAPI	FacetCount() =0;
	// ****************************************************************************
	//								GetBoundingBox
	// 
	/// Calculates the 3D bounding box of the Polygon
	/// 
	/// \param bbox  Returns the bounding box
	/// 
	virtual void			MCCOMAPI	GetBoundingBox(TBBox3D &bbox) =0;

	// ****************************************************************************
	//								SetSelection
	// 
	// -Description: Select or unselect the polygon. Depending on the mode used, edges
	//				and polygons around can be selected
	//
	// -Parameters: selected: true to select, false to deselect
	//				autoSelection: true to complete the selection
	//
	// ****************************************************************************
	//								SetSelection
	// 
	/// Sets the selection state of the Polygon.
	/// 
	/// \param selected      If true, selects the Polygon.  If false, deselects it.
	/// \param autoSelection If true, completes the selection with neighboring selected vertices and edges  
	/// 
	virtual void			MCCOMAPI	SetSelection(boolean selected, boolean autoSelection=true ) =0;
	
	// ****************************************************************************
	//								GetSelection
	// 
	/// \return True if the Polygon is selected
	/// 
	virtual boolean			MCCOMAPI	GetSelection(boolean useSymmetry=false)=0;
	
	// ****************************************************************************
	//								GetBestPlane
	// 
	/// This function calculates ii, jj, and kk - an orthogonal basis for a plane approximation 
	/// of the Polygon.  Also computes a centroid for the vertices of the Polygon.  This version
	/// of the function verifies that kk is pointing the same direction as the Polygon's normal,
	/// and flips the resulting plane if necessary.
	/// 
	/// \param ii      Returns a basis vector
	/// \param jj      Returns a basis vector
	/// \param kk      Returns a basis vector
	/// \param center  Returns the centroid
	/// \return True if the operation succeeded and the output parameters contain correct results.
	///
	virtual boolean			MCCOMAPI	GetBestPlane(TVector3 &ii,TVector3 &jj,TVector3 &kk,TVector3 &center) =0;
	
	// ****************************************************************************
	//								GetPolymesh
	// 
	/// Gets the Polymesh to which this Polygon belongs
	/// 
	/// \param iPolymesh  Returns the Polymesh
	/// 
	virtual void			MCCOMAPI	GetPolymesh(IPolymesh** iPolymesh)=0;							
    
	// ****************************************************************************
	//								Triangulate
	// 
	/// Triangulates this Polygon, regardless of selection state.
	/// 
	virtual void			MCCOMAPI	Triangulate()=0;

	// ****************************************************************************
	//								SetBooleanClassification
	// 
	/// The Boolean Classification field is an auxilliary field used to store an extra 
	/// number associated with the Polygon.  Do not rely on its being initialized, but 
	/// you can initialize it and then use it.  SetBooleanClassification sets the 
	/// field for this Polygon.
	/// 
	/// \param classification  Value to store in the Boolean Classification
	/// 
	virtual void			MCCOMAPI	SetBooleanClassification(const long classification) =0;
	
	// ****************************************************************************
	//								GetBooleanClassification
	// 
	/// The Boolean Classification field is an auxilliary field used to store an extra 
	/// number associated with the Polygon.  Do not rely on its being initialized, but 
	/// you can initialize it and then use it.  GetBooleanClassification gets the 
	/// field for this Polygon.
	/// \return The value stored in this Polygon's Boolean Classification field
	/// 
	virtual const long		MCCOMAPI	GetBooleanClassification()=0;

	// ****************************************************************************
	//								GetNormal
	// 
	/// Returns the normal to the Polygon.
	/// 
	/// \param normal    Returns the normalized vector normal to the Polygon
	/// \param smoothed  If true, smoothing of the edges will affect the normal computation
	/// 
	virtual void			MCCOMAPI	GetNormal(TVector3 &normal, boolean smoothed=true) =0;

	// ****************************************************************************
	//								GetVertexNormal
	// 
	/// Returns the normal for the indexed vertex in this Polygon
	/// 
	/// \param normal       Returns the normal vector for the vertex
	/// \param vertexIndex  Index to the vertex
	/// 
	virtual void			MCCOMAPI	GetVertexNormal(TVector3 &normal, int32 vertexIndex) =0;

	// ****************************************************************************
	//								GetCenter
	// 
	/// Returns the barycenter of the Polygon
	/// 
	/// \param center  Returns the barycenter of the Polygon
	/// 
	virtual void			MCCOMAPI	GetCenter(TVector3 &center) =0;

	// ****************************************************************************
	//								Subdivide
	// 
	/// This Subdivide function divides the Polygon into two by creating an edge between 
	/// v1 and v2.
	///
	/// \param v1  First vertex to split along
	/// \param v2  Second vertex to split along
	/// \return A pointer to the new Polygon created.
	///
	virtual IPolygon*		MCCOMAPI	Subdivide(I3DExVertex *v1, I3DExVertex *v2) =0;

	// ****************************************************************************
	//								Subdivide
	// 
	/// Subdivides the Polygon according to the mode specified in the parameter.  See VMTypes.h
	/// for the list of Subdivision modes.
	/// 
	/// \param mode  Tessellation mode to use in subdividing
	/// 
	virtual void			MCCOMAPI	Subdivide( ETesselateMode mode ) =0;

	// ****************************************************************************
	//								GetOtherEdge
	// 
	/// Given an edge and a vertex attached to the edge, will return the other edge attached to that vertex.
	/// 
	/// \param vertex  A pointer to a Vertex in the Polygon
	/// \param edge    A pointer to an Edge in the Polygon that contains vertex
	/// \return A pointer to the other Edge attached to vertex
	/// 
	virtual IEdge*			MCCOMAPI	GetOtherEdge(I3DExVertex *vertex,IEdge *edge) =0;
	
	// ****************************************************************************
	//								CloneConjugate
	// 
	/// Accessor to this Polygon's clone conjugate.  Vertex Modeler specific, generally 
	/// should not be used elsewhere.
	/// \return A pointer to the Clone Conjugate of this Polygon
	/// 
	/// 
	virtual IPolygon*		MCCOMAPI	CloneConjugate()=0;

	// ****************************************************************************
	//								GetBestPlane2
	// 
	/// This function calculates ii, jj, and kk - an orthogonal basis for a plane approximation 
	/// of the Polygon.  Also computes a centroid for the vertices of the Polygon.  
	/// 
	/// \param ii      Returns a basis vector
	/// \param jj      Returns a basis vector
	/// \param kk      Returns a basis vector
	/// \param center  Returns the centroid
	/// \return True if the operation succeeded and the output parameters contain correct results.
	///
	virtual boolean			MCCOMAPI	GetBestPlane2(TVector3 &ii,TVector3 &jj,TVector3 &kk,TVector3 &center) =0;

	// ****************************************************************************
	//								ClassifyPolygon
	// 
	/// This function Classifies the Polygon with respect to the Polymesh passed in the parameter.
	/// Used internally for Boolean operations.  Do not use elsewhere.
	/// 
	/// \param object A pointer to the Polymesh with which to classify this Polygon.
	/// 
	virtual void			MCCOMAPI	ClassifyPolygon( IPolymesh* object) =0;

	//	virtual boolean			MCCOMAPI	Flipped()=0;

	// ****************************************************************************
	//								GetName
	// 
	/// Gets a pointer to a C string name for the Polygon.  Do not use.
	/// 
	/// \param name  Returns a pointer to a string containing a name for this Polygon
	/// 
	virtual void			MCCOMAPI	GetName(char* name)=0;
	
	// ****************************************************************************
	//								SetName
	// 
	/// Sets the name of the Polygon from a C string.  Do not use.
	/// 
	/// \param name  A pointer to the string containing the name
	/// 
	virtual void			MCCOMAPI	SetName(char* name)=0;

	// ****************************************************************************
	//								GetFacetInfo
	// 
	/// When passed an index to a facet in the Polygon, fills the array at info
	/// with the indices of the vertices in that facet.
	/// 
	/// \param index  Index of the facet in question
	/// \param info   pointer to int32[3] to hold vertex indices
	/// 
	virtual void			MCCOMAPI	GetFacetInfo(int32 index, int32* info)=0;
	
	// ****************************************************************************
	//								GetSmoothingID
	// 
	/// \return The smoothing ID for this Polygon
	/// 
	virtual uint32			MCCOMAPI	GetSmoothingID()=0;

	// ****************************************************************************
	//								GetShadingDomainID
	// 
	/// \return The shading domain ID for this Polygon
	/// 
	virtual int16			MCCOMAPI	GetShadingDomainID()=0;

	// ****************************************************************************
	//								SetShadingDomainID
	// 
	/// Sets the shading domain to use for this Polygon.
	/// 
	/// \param id  The shading domain ID to use
	/// 
	virtual void			MCCOMAPI	SetShadingDomainID(int16 id)=0;

	// ****************************************************************************
	//								GetUVIndexForVertex
	// 
	/// Accessor for the index of the UV in the UV List of the vertex to use with the 
	/// Vertex in this Polygon.
	/// 
	/// \param vertexIndexInPolygon  Index of the vertex in the Polygon
	/// \return The UV index to use, or -1 if not found.
	/// 
	virtual int32			MCCOMAPI	GetUVIndexForVertex(int32 vertexIndexInPolygon) =0;

	// ****************************************************************************
	//								GetUVIndexForVertex
	// 
	/// Accessor for the index of the UV in the UV List of the vertex to use with the 
	/// Vertex in this Polygon.  Note that this version is slower than the one passed 
	/// an index to the Vertex in the Polygon.
	/// 
	/// \param vertex  Pointer to a Vertex in the Polygon
	/// \return The UV index to use, or -1 if not found.
	/// 
	virtual int32			MCCOMAPI	GetUVIndexForVertex(I3DExVertex* vertex) =0;

	// ****************************************************************************
	//								SetUVIndexForVertex
	// 
	/// Sets the index of the UV in the UV List of the Vertex to use by the Vertex in this 
	/// Polygon.  
	/// 
	/// \param vertexIndex  Index of the Vertex in the Polygon
	/// \param uvIndex      The UV index to use
	/// 
	virtual void			MCCOMAPI	SetUVIndexForVertex(int32 vertexIndex,int32 uvIndex) = 0;

	// ****************************************************************************
	//								SetUVIndexForVertex
	// 
	/// Sets the index of the UV in the UV List of the Vertex to use by the Vertex in this 
	/// Polygon.  Note that this version is slower than the one passed an index to the Vertex
	/// in the Polygon.
	/// 
	/// \param vertex  Pointer to the Vertex in the Polygon
	/// \param uvIndex The UV index to use
	/// 
	virtual void			MCCOMAPI	SetUVIndexForVertex(I3DExVertex* vertex,int32 uvIndex)=0;

	/// Sets the polygon's marker (or index)
	/// Can be used to remember where the poly is coming from when importing an object
	virtual void			MCCOMAPI	SetMarker			(int32 marker) = 0;

	/// Gets the polygon's marker
	/// Can be used to remember where the poly is coming from when importing an object
	virtual int32			MCCOMAPI	GetMarker			() = 0;
	
	/// Returns the index of the vertex in the polygon
	/// Returns kUnusedIndex if the vertex isn't used by the polygon.
	virtual int32			MCCOMAPI	GetVertexIndex		(const I3DExVertex* vertex) = 0;

	virtual void			MCCOMAPI	Hide(boolean hide) = 0;
	virtual boolean			MCCOMAPI	Hidden() = 0;

	/// Gets the symmetrical polygon if any in the mesh and if the symmetrical modeling is enabled
	virtual IPolygon*		MCCOMAPI GetSymmetricalPolygon() = 0;

	long GetNbEdges() {return GetNbVertices();}
};


/// \}

#endif
