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

		I3DShObject.h

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

		I3DShObject                                                               
		I3DShPrimitive                                                            
		I3DShPolygonList                                                          
		I3DShPolygonArray                                                         
		I3DShPatchList                                                            
		I3DShPatchArray                                                         
		I3DShFacetMesh                                           

		Author:	Ray Dream
		Date:	3/2/98

		Revision History

		when		who			what & why
		==========	==========	======================================================
		10/29/99	David		Added I3DShPatchList::GetUVSpaceCount, I3DShPatchList::GetIndPatches and I3DShPolygonList::GetUVSpaceCount
		10/21/99	Yann		Added I3DShPatchList::BuildFacetMesh and I3DShPatchArray::BuildFacetMesh
		08/24/99	cph			Removed old CLSIDs for standard built-in primitives
		08/10/99	Arnaud		FacetMesh is now counted.
		7/29/99		Yann		Added comments to I3DShObject
		2/25/99		Alec		Added the primitive component interface
		2/19/99		Joshua		Added I3DShObject::GetEditor

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

#ifndef __I3DSHOBJECT__
#define __I3DSHOBJECT__

#if CP_PRAGMA_ONCE
#pragma once
#endif

#include "ComTypes.h"
#include "APITypes.h"
#include "MCCountedPtr.h"
#include "Matrix33Fwd.h"

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

MCDEFINE_GUID_SAFELIB(IID_I3DShObject, 0xBDEA68A0L, 0x3A02, 0x101C, 0x88, 0x5F, 0x04, 0x02, 0x1C, 0x00, 0x70, 0x02);
MCDEFINE_GUID_SAFELIB(IID_I3DShPrimitive, 0x5C9601A7L, 0x7CC3, 0x101C, 0x88, 0x5F, 0x04, 0x02, 0x1C, 0x00, 0x70, 0x02);
MCDEFINE_GUID_SAFELIB(IID_I3DShExternalPrimitive, 0x7400ca6, 0x15f9, 0x11d2, 0x84, 0x6a, 0x0, 0x60, 0x97, 0xb, 0xc5, 0x21);
MCDEFINE_GUID_SAFELIB(IID_I3DShPolygonList, 0xBFBEDA80L, 0x3A02, 0x101C, 0x88, 0x5F, 0x04, 0x02, 0x1C, 0x00, 0x70, 0x02);
MCDEFINE_GUID_SAFELIB(IID_I3DShPolygonArray, 0xC1840A20L, 0x3A02, 0x101C, 0x88, 0x5F, 0x04, 0x02, 0x1C, 0x00, 0x70, 0x02);
MCDEFINE_GUID_SAFELIB(IID_I3DShPatchList, 0xBFBEDA81L, 0x3A02, 0x101C, 0x88, 0x5F, 0x04, 0x02, 0x1C, 0x00, 0x70, 0x02);
MCDEFINE_GUID_SAFELIB(IID_I3DShPatchArray, 0xC361A3C0L, 0x3A02, 0x101C, 0x88, 0x5F, 0x04, 0x02, 0x1C, 0x00, 0x70, 0x02);
MCDEFINE_GUID_SAFELIB(IID_I3DShFlatSurface, 0xC546DE80L, 0x3A02, 0x101C, 0x88, 0x5F, 0x04, 0x02, 0x1C, 0x00, 0x70, 0x02);
MCDEFINE_GUID_SAFELIB(IID_I3DShPrimitiveComponent, 0xf1fb0740,0xcc0c,0x11d2,0xa0,0x37,0x44,0x45,0x53,0x54,0x0,0x0 );

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

struct FacetMesh;
struct ShadingShape;
struct I3DShShader;
struct I3DShScene;
struct IShComponent;
struct UVSpaceInfo;
struct I3DShInstance;
struct UVSpaceInfoRDS5;
struct I3DShMaster;
struct TFaceSet;
struct I3DExGeometricPrimitive;
struct I3DShMasterShader;

class TBBox3D;
class TMCString;
template <class T> class TMCCountedPtrArray;

namespace MeshDataStructure
{
	class TMesh;
	class TMeshList;
}

/// \addtogroup ShellInterface
/// \{

struct RayHitParameters;
struct I3DShPrimitiveComponent;

/*****************************************************************************\
*  I3DShObject                                                                *
*                                                                             *
\*****************************************************************************/

// ****************************************************************************
//								I3DShObject
// 
/// 
/// <P>I3DShObject stores the geometry of the objects (master objects)
/// in a scene.</P>
///
/// <P>Master Objects are kept in a list in the scene (the Objects List), and can be
/// instanciated as many times as needed in a scene.</P>
///
/// <P>There are two types of Master Objects: Primitives and Master Groups. 
/// See I3DShPrimitive and I3DMasterGroup.</P>
///
/// <P>Other supported interfaces:</P>
///	 - I3DShMaster
///	 - ISelectableObject
///
struct I3DShObject : public IMCUnknown
{
	// ****************************************************************************
	//								SetName
	// 
	/// Sets the name of a master object. Note that you should not call this method
	/// once the object is inserted in a scene because it does not garantee the
	/// unicity of the name. If you want to change the name of a Master Object once
	/// it is inserted in a scene, you should call: I3DShScene::Rename3DObject().
	/// 
	/// \param name  The new name of the master object.
	/// 
	virtual MCCOMErr	MCCOMAPI SetName			(const TMCString& name) = 0;		// -> New name

	// ****************************************************************************
	//								GetName
	// 
	/// Returns the name of the master object.
	/// 
	/// \param name  The name of the master object.
	/// 
	virtual MCCOMErr	MCCOMAPI GetName			(TMCString& name) = 0;				// <- Returned object name

	// ****************************************************************************
	//								GetInstancesCount
	// 
	/// Returns the number of instances of this object. Exact same call as I3DShMaster::GetInstancesCount
	/// 
	virtual uint32		MCCOMAPI GetInstancesCount	() = 0;

	// ****************************************************************************
	//								GetInstanceArray
	// 
	/// Builds the array of all the instances of this object.
	/// The array should be empty when the function is called.
	///
	/// \param instances  An array to store the list of instances.
	/// 
	virtual void		MCCOMAPI GetInstanceArray	(TMCCountedPtrArray<I3DShInstance>& instances) = 0;	
	
	// ****************************************************************************
	//								GetInstanceArray
	// 
	/// Returns an array of all the instances that points to that class.
	/// 
	/// \param instances  An array of instances.
	/// 
	virtual void 	 MCCOMAPI	GetInstanceArray		(TMCCountedPtrArray<I3DShTreeElement>& instances) = 0;

	// ****************************************************************************
	//								GetUVSpaceCount
	// 
	/// Return the number of UV spaces for this object. If 0 is returned only projection
	/// mapping can be performed on the object
	/// 
	virtual uint32		MCCOMAPI GetUVSpaceCount	() = 0;

	// ****************************************************************************
	//								GetUVSpace
	// 
	/// Gets information on a specific UV Space
	/// 
	/// \param uvSpaceID        The index (0 based) of the shading domaine (= uv space).
	/// \param uvSpaceInfo		A pointer to a struct that will contain the definition of the shading domain.
	/// 
	virtual MCCOMErr	MCCOMAPI GetUVSpace			(uint32 uvSpaceID,
													 UVSpaceInfo* uvSpaceInfo) = 0;

	// ****************************************************************************
	//								CanRenameUVSpace
	// 
	/// Returns true if the primitive can rename uv spaces (ie. implements RenameUVSpace()).
	///
	virtual boolean	   MCCOMAPI CanRenameUVSpace	() = 0;
	
	// ****************************************************************************
	//								RenameUVSpace
	// 
	/// Rename a particular uvSpace (= shading domain).
	///
	/// \param uvSpaceID The ID of the uvspace (0 based index)
	/// \param name		 The new name of the uvspace.
	///
	virtual MCCOMErr   MCCOMAPI RenameUVSpace		(uint32 uvSpaceID, const TMCString& name) = 0;

	// ****************************************************************************
	//								GetScene
	// 
	/// Returns the scene that contains this object.
	/// 
	/// \param scene  A pointer to the scene.
	/// 
	virtual void		MCCOMAPI GetScene			(I3DShScene** scene) = 0;			// <- Scene of the object

	// ****************************************************************************
	//								IsInfiniteObject
	// 
	/// Returns TRUE if the object is infinite (like the infinite plane)
	/// 
	virtual boolean		MCCOMAPI IsInfiniteObject	() = 0;
	
	// ****************************************************************************
	//								GetBoundingBox
	// 
	/// Gets the bounding box of the object (in local coordinates)
	/// 
	/// \param bbox			A struct where the result is stored.
	/// \param rendering	Need a bbox for rendering (more precise)
	/// 
	virtual void		MCCOMAPI GetBoundingBox		(TBBox3D& bbox, boolean rendering = true) = 0;					// <- Returned bounding box

	// ****************************************************************************
	//								GetFacetBoundingBox
	// 
	/// The bounding box calculated here fit exactly the facets of the object in a given direction.
	/// The FacetBounding boxes are cached inside the Object because it can take a long time to calculate.
	/// We added a listener here to accelerate the Get. So we don't have to compare mappingTransform (TMatrix33) in the look-up table.
	/// A last hit is provide inside the GetFacetBoundingBox method to make the Get on same listener very fast.
	/// Each time the BoudingBox of the object changed , the list is flushed.
	/// \param bbox                The bounding box that is returned.
	/// \param mappingTransform    The transform of the bounding box
	/// \param listener            A listener
	/// \param matrixChangedPhase  Each time you ask with a new mappingTransform, increment the matrixChangedPhase.
	/// 
	virtual void	 MCCOMAPI GetFacetBoundingBox(  TBBox3D &bbox, const TMatrix33 &mappingTransform, void *listener, uint32 matrixChangedPhase )= 0;

	// ****************************************************************************
	//								Clone
	// 
	/// Creates a copy of the object.
	/// 
	/// \param clone      A pointer to the new copy of the object.
	/// \param cloneMode  The clone mode (see ECloneMode)
	/// 
	virtual MCCOMErr	MCCOMAPI Clone				(I3DShObject** clone,
													 ECloneMode cloneMode) const = 0;

	// ****************************************************************************
	//								GetEditor
	// 
	/// Returns the class ID of the Editor (i.e. the module) capable of editing this
	/// object in the Modeling room
	/// 
	virtual int32		MCCOMAPI GetEditor			() = 0;

	// ****************************************************************************
	//								GetObjectID
	// 
	/// Returns the ID of the object. In the case of a Primitive, it will be its Class ID.
	/// For a Master Group, it is 'sc  '
	/// 
	virtual int32		MCCOMAPI GetObjectID		() = 0;

	// ****************************************************************************
	//								IsExcludedFromTripleBuffer
	// 
	/// Returns true if its instances should be excluded from the triple buffer
	/// (eg used for skinning)
	/// 
	virtual boolean		MCCOMAPI IsExcludedFromTripleBuffer() = 0;

	// ****************************************************************************
	//								GetPreviewObject
	// 
	/// Return the Master object to preview if different from main one.
	/// Return NULL if it is the same,
	/// \param masterShader			the master shader being previewed
	/// \param object				the object to use to preview the shader
	/// \param previewTree			a tree to set the transform of the preview object (only the transform will be used)
	/// \param additionnalChild		the master object can also add an instance that will be used for the preview as well, puting it
	///								as child of the previewed object
	/// 
	virtual void		MCCOMAPI GetPreviewObject(I3DShMasterShader* masterShader, I3DShObject** object, I3DShTreeElement** previewTree, I3DShTreeElement** additionnalChildInstance) = 0;

	///Returns the total number of instances of this master object
	///NOTE: Some instances may not be in the same scene than the master object...
	///(Use this and GetInstanceByIndex when you need to avoid the memory allocation(s) caused by GetInstanceArray)
	virtual int32			MCCOMAPI GetAllInstancesCount	() = 0;

	///Returns the inIndex(th) instance of this master object.
	///NOTE: Some instances may not be in the same scene than the master object...
	///(Use this and GetAllInstancesCount when you need to avoid the memory allocation(s) caused by GetInstanceArray)
	virtual I3DShInstance*	MCCOMAPI GetInstanceByIndex	(uint32 inIndex) = 0;

	///Returns the scene that contains this object.
	virtual I3DShScene*		MCCOMAPI GetSceneNoAddRef	() = 0;

	// ****************************************************************************
	//								GetThisMaster
	// 
	/// Returns the I3DShMaster interface.
	/// 
	virtual I3DShMaster*	MCCOMAPI GetThisMaster	() = 0;

	///Returns an approximation of the bounding box
	virtual MCCOMErr	MCCOMAPI GetApproximateBoundingBox(TBBox3D &bbox) = 0;

	// ****************************************************************************
	//								ShouldDeleteWithInstance
	// 
	/// Tells if the master should be deleted when the user deletes the given instance
	///
	/// \param inInstance			The instance that is being deleted
	///
	virtual boolean	MCCOMAPI ShouldDeleteWithInstance	(I3DShInstance* inInstance) = 0;

	// ****************************************************************************
	//								IsReferencedByThisSubTree
	// 
	/// Return true if the given sub tree keeps a reference to that master object
	///
	/// \param subTree		The sub tree that might reference that master object
	/// \param scene		The scene that contains that sub tree.
	/// 
	virtual boolean MCCOMAPI IsReferencedByThisSubTree(I3DShTreeElement* subTree,I3DShScene* scene) = 0;
};


// ****************************************************************************
//								I3DShPrimitive
// 
/// <P>A Primitive is a geometric Object that can be instantiated multiple time
/// in a scene.</P>
/// 
/// <P>Most primitives created in Carrara are external primitives (see I3DShExternalPrimitive
/// for a more information on external primitives).</P>
/// 
/// <P>A primitive always supports the following interfaces: I3DShObject, I3DShMaster.</P>
///
struct I3DShPrimitive: public IMCUnknown
{
	// ****************************************************************************
	//								IsPatchBased
	// 
	/// Returns true if the primitive is composed of Beziers patches.
	/// 
	virtual boolean  MCCOMAPI IsPatchBased	() = 0;
	
	// ****************************************************************************
	//								EnumPatches
	// 
	/// Enumerates the list of patches that compose the primitive.
	/// 
	/// \param callback  A callback function.
	/// \param privData  Data that are passed to the callback
	/// \param closed    True if the primitive is closed (used for backface culling).
	/// 
	virtual MCCOMErr MCCOMAPI EnumPatches	(EnumPatchesCallback callback, void* privData, boolean& closed) = 0;
	
	// ****************************************************************************
	//								ChangedData
	// 
	/// Call this if you changed some data of the Primitive, so the Shell hear about it
	/// 
	virtual MCCOMErr MCCOMAPI ChangedData	() = 0;

	// ****************************************************************************
	//								PostPrimitiveChange
	// 
	/// Post a change message for this primitive.
	/// 
	virtual MCCOMErr MCCOMAPI PostPrimitiveChange	(int32 inChangeID) = 0;
	
	// ****************************************************************************
	//								GetFMesh
	// 
	/// Returns the facet mesh for a given level of detail. (This is the quality
	/// that is used for the 3D view. To get the full detail mesh,
	/// call GetRenderingFacetMesh()).
	/// 
	/// \param lod   The level of detail (0 is the most precise)
	/// \param mesh  A pointer to the facetmesh.
	/// 
	virtual MCCOMErr MCCOMAPI GetFMesh		(real lod, FacetMesh** mesh) = 0;

	// ****************************************************************************
	//								RenderingFacetMeshDifferentFromLodZero
	// 
	/// Returns true if the lod 0 and the rendering facet are different.
	///
	virtual boolean		MCCOMAPI RenderingFacetMeshDifferentFromLodZero() = 0;

	// ****************************************************************************
	//								GetRenderingFacetMesh
	// 
	/// Returns the facet mesh associated with the primitive that should be used
	/// for the final rendering.
	/// 
	/// \param mesh  A pointer to the facetmesh
	///
	virtual void MCCOMAPI GetRenderingFacetMesh(FacetMesh** mesh) = 0;

	// ****************************************************************************
	//								GetRenderingMesh
	// 
	/// Returns a pointer to the rendering mesh associated with the primitive. Note
	/// that the mesh should not be cached by the primitive so it can be modified
	/// by the caller.
	///
	/// It is the caller responsability to call release on the mesh once it is not used
	/// anymore.
	///
	/// \param meshList  The mesh list that is returned. NULL if this call is not
	///					 supported (in which case the caller can use the facet mesh)
	/// 
	virtual void MCCOMAPI GetRenderingMesh(MeshDataStructure::TMeshList** meshList) = 0;

	// ****************************************************************************
	//								GetFaceSetList
	// 
	/// Gets the list of face sets associated with the primitive.
	///
	/// \param faceSetList  The face set list that is returned.
	///
	virtual void MCCOMAPI GetFaceSetList(TMCCountedPtrArray<TFaceSet>& faceSetList) = 0;
	
	// ****************************************************************************
	//								IsVolumic
	// 
	/// Returns true if the primitive is a volumic primitive (see IVolumePrimitive).
	/// 
	virtual boolean  MCCOMAPI IsVolumic		() = 0;
	
	// ****************************************************************************
	//								BeginUV2XYZ
	// 
	/// Call this function before UV2XYZ().
	/// 
	virtual void MCCOMAPI BeginUV2XYZ()=0;

	// ****************************************************************************
	//								UV2XYZ
	// 
	/// Returns the 3D position of a point given it's uv coordinates. Note that if
	/// the uv coordinates are degenerated, there might be several points on the mesh
	/// that could be returned...
	/// 
	/// \param uv         The texture coordinates
	/// \param uvSpaceID  The ID of the uvspace
	/// \param thePos3D   The returned position in local coordinates.
	/// \param normal     The normal at that point.
	/// 
	virtual boolean  MCCOMAPI UV2XYZ		(const TVector2& uv,uint32 uvSpaceID,TVector3& thePos3D,TVector3* normal) = 0;

	// ****************************************************************************
	//								EndUV2XYZ
	// 
	/// Call this function after UV2XYZ() to delete caches.
	/// 
	virtual void MCCOMAPI EndUV2XYZ()=0;

	// ****************************************************************************
	//								GetI3DShObject
	// 
	/// Returns a pointer to I3DShObject. (This method is faster than calling QueryInterface).
	/// 
	virtual I3DShObject* MCCOMAPI GetI3DShObject() = 0;

	// ****************************************************************************
	//								GetNbrLOD
	// 
	/// Returns the number of LOD (level of details) that are supported by this
	/// primitive.
	/// 
	virtual int16	MCCOMAPI GetNbrLOD() const = 0;
	
	// ****************************************************************************
	//								GetLOD
	// 
	/// Returns the precision for a given Level of Detail.
	/// 
	/// \param index  The index of the LOD.
	/// 
	virtual real	MCCOMAPI GetLOD(int16 index) const = 0;

	// ****************************************************************************
	//								SetChildPrimitive
	// 
	/// Sets a child primitive for this primitive
	/// 
	/// \param primitive  A pointer to the child primitive
	/// 
	virtual void MCCOMAPI SetChildPrimitive(I3DShPrimitive* primitive) = 0;

	// ****************************************************************************
	//								GetChildPrimitive
	// 
	/// Returns a pointer to the child primitive of this primitive. Returns NULL if
	/// there is no child primitive.
	/// 
	virtual I3DShPrimitive* MCCOMAPI GetChildPrimitive() = 0;

	// ****************************************************************************
	//								GetRayHit
	// 
	/// Calculates the intersection of a ray and this primitive
	/// 
	virtual boolean MCCOMAPI GetRayHit(RayHitParameters &params) = 0;

	// ****************************************************************************
	//								RayHitFacet
	// 
	/// calculates the intersection between a ray and a triangle of a primitive. Note
	/// that if the primitive is self-Raytracable, the facetIndex is ignored and the
	/// intersection is calculated with the whole primitive.
	/// 
	/// \param params      the raytracing parameters (ray, hit...)
	/// \param facetIndex  the index of the facet to intersect
	/// \param lod         the lod of the primitive from which the facet is coming from
	///
	virtual boolean  MCCOMAPI RayHitFacet( RayHitParameters &params,uint32 facetIndex,real lod)=0;

	// ****************************************************************************
	//								BeginUV2XYZForShadingDomain
	// 
	/// Call this function before UV2XYZ() if you are only going to call it for a
	/// given shading domain. (It is faster that BeginUV2XYZ()).
	/// 
	/// \param shadingDomain  The ID of the shading domain. (-1 means all shadingDomains)
	/// 
	virtual void MCCOMAPI BeginUV2XYZForShadingDomain(int32 shadingDomain)=0;

	// ****************************************************************************
	//								GetPrimitiveExtension
	// 
	/// Returns a pointer to the primitive extension if there is one. Returns NULL if
	/// this primitive is an internal primitive.
	/// 
	/// 
	virtual I3DExGeometricPrimitive* MCCOMAPI GetPrimitiveExtension()=0;

	// ****************************************************************************
	//								IsSelfRaytracablePrimitive
	// 
	/// Returns true if the primitive is a self raytraceable (ie. the facet mesh may not
	/// be the geometry that is rendered).
	/// 
	virtual boolean			MCCOMAPI IsSelfRaytracablePrimitive() = 0;
};


// ****************************************************************************
//								I3DShExternalPrimitive
// 
/// <P>I3DShExternalPrimitive is interface for external primitives. All primitives
/// in Carrara are External Primitives. However some primitives imported from
/// Raydream are still stored internally.</P>
///
/// <P>Primitive is one particular type of Master Objects (see I3DShObject). They
/// can be instantianted multiple times.</P>
///
/// <P>There are 2 COM objects to consider:</P>
///  - The <B>Primitive</B> that supports I3DShExternalPrimitive, I3DShPrimitive and I3DShObject.
///  - The <B>Primitive Component</B> that supports IShComponent, I3DShPrimitiveComponent and I3DExGeometricPrimitive
///
/// <P>For advanced users: You should note that there are actually 3 C++ object (The primitive,
/// the primitive component and the primitive light). However the primitive component and the external
/// primitive are aggregated by COM which means that you can be considered as one single COM object).
///
/// <P>To get a pointer to a I3DShExternalPrimitive from a I3DExGeometricPrimitive, you can use the following code:</P>
///
/// \code
///
/// TMCCountedPtr<I3DShPrimitiveComponent> primitiveComponent;
/// exPrimitive->QueryInterface(IID_I3DShPrimitiveComponent,(void**)&primitiveComponent);
/// ThrowIfNil(primitiveComponent);
///
/// TMCCountedPtr<I3DShPrimitive> primitive;
/// primitiveComponent->GetPrimitive(&primitive);
/// ThrowIfNil(primitive);
///
/// TMCCountedPtr<I3DShExternalPrimitive> externalPrimitive;
/// primitive->QueryInterface(IID_I3DShExternalPrimitive.(void**)&externalPrimitive);
///
/// \endcode
///
/// <P>To access I3DExGeometricPrimitive from I3DShPrimitive, you can use the following code: </P>
///
/// \code
///
/// TMCCountedPtr<I3DShExternalPrimitive> externalPrimitive;
/// shPrimitive->QueryInterface(IID_I3DShExternalPrimitive,(void**)&externalPrimitive);
/// ThrowIfNil(externalPrimitive);
/// 
/// TMCCountedPtr<IShComponent> primitiveComponent;
/// externalPrimitive->GetPrimitiveComponent(&primitiveComponent);
/// ThrowIfNil(primitiveComponent);
///
/// TMCCountedPtr<I3DExGeometricPrimitive> externalPrimitive;
/// primitiveComponent->QueryInterface(IID_I3DExGeometricPrimitive,(void**)&externalPrimitive);
///
/// \endcode
///
/// <P>This code might seem a bit complicated at first but it is actually simple. You have two COM objects
/// that point on each other. I3DShExternalPrimitive::GetPrimitiveComponent() and I3DShPrimitiveComponent::GetPrimitive()
/// allow you to get a pointer from one object to the other. The rest is only calling QueryInterface to get
/// the right interface on each object.</P>
///
/// \see I3DShPrimitiveComponent
/// \see I3DExGeometricPrimitive
/// \see I3DShPrimitive
/// 
struct I3DShExternalPrimitive: public IMCUnknown
{
	// ****************************************************************************
	//								SetPrimitiveComponent
	// 
	/// Sets the primitive component associated with this primitive.
	/// 
	/// \param primitiveComponent  The new primitive component.
	/// \param cloneMode           The clone mode (see ECloneMode).
	/// 
	virtual MCCOMErr MCCOMAPI SetPrimitiveComponent	(IShComponent* primitiveComponent, ECloneMode cloneMode) = 0;
	
	// ****************************************************************************
	//								GetPrimitiveComponent
	// 
	/// Returns a pointer to the primitive component associated with this primitive.
	/// 
	/// \param primitiveComponent  A pointer to the primitive component.
	/// 
	virtual MCCOMErr MCCOMAPI GetPrimitiveComponent	(IShComponent** primitiveComponent) = 0;

	// ****************************************************************************
	//								GetPrimitiveComponent
	// 
	/// Returns a pointer to the primitive component associated with this primitive.
	/// 
	virtual IShComponent* MCCOMAPI GetPrimitiveComponent() =0;
	
	// ****************************************************************************
	//								GetPrimitive
	// 
	/// Returns a pointer to the primitive interface. (This is a bit faster than
	/// using QueryInterface).
	/// 
	virtual I3DShPrimitive* MCCOMAPI GetPrimitive() = 0;

	// ****************************************************************************
	//							GetOriginalPrimitive
	// 
	/// Returns a pointer to the primitive interface to which this primitive is 
	///	applied when it is a deformer. Returns MC_S_OK if the primitive was indeed
	/// a deformer and MC_S_FALSE otherwise.
	///
	/// \param origPrimitive  A pointer to the shell primitive
	/// 
	virtual MCCOMErr MCCOMAPI GetOriginalPrimitive(I3DShPrimitive** origPrimitive) = 0;
};

// ****************************************************************************
//								I3DShPrimitiveComponent
// 
/// <P>I3DShPrimitiveComponent provides access to the External Primitive attached
/// to it (see I3DShExternalPrimitive).</P>
///
/// <P>Other interfaces supported: IShComponent, I3DExGeometricPrimitive</P>
///
struct I3DShPrimitiveComponent : public IMCUnknown
{
	// ****************************************************************************
	//								GetPrimitive
	// 
	/// Returns a pointer to the external primitive associated with this component.
	/// (see I3DShExternalPrimitive).
	/// 
	/// \param primitive  A pointer to the primitive associated with this component.
	/// 
	virtual void MCCOMAPI GetPrimitive(I3DShPrimitive** primitive) = 0;	

	// ****************************************************************************
	//								GetExternalPrimitive
	// 
	/// Returns a pointer to the external part of the primitive (I3DExGeometricPrimitive).
	/// Note that the name of this function is confusing. It refers to the
	/// C++ object located in an external plugin by opposition to the object located
	/// inside the Shell. It should not be confused with I3DShExternalPrimitive
	/// which is the interface of a internal primitive that is implemented using
	/// a component.
	/// 
	/// \param extPrimitive  A pointer to the primitive that is returned.
	/// 
	virtual MCCOMErr MCCOMAPI GetExternalPrimitive(IMCUnknown** extPrimitive) = 0;

	// ****************************************************************************
	//								GetMasterObject
	// 
	/// Returns a pointer to the master object associated with the primitive component.
	//
	/// \param object  A pointer to the master object that is returned.
	/// 
	virtual void MCCOMAPI GetMasterObject(I3DShObject** object) = 0;
};


// ****************************************************************************
//								I3DShPolygonList
//
/// \deprecated
///
/// I3DShPolygonList is simply a bag of triangular facets.
/// Other interfaces supported: I3DShObject, I3DShPrimitive
///
struct I3DShPolygonList: public IMCUnknown
{
	//-- Init calls
	virtual MCCOMErr	MCCOMAPI Init				(boolean hasNormals, boolean hasUV) = 0;
	//-- Facets handling
	virtual MCCOMErr	MCCOMAPI PreAllocateFacets	(uint32 nbFacets) = 0;		// Use this if you know in advance how many facets you will build
	virtual MCCOMErr	MCCOMAPI AddFacet			(TFacet3D* facet) = 0;
	virtual uint32		MCCOMAPI CountFacets		() = 0;
	virtual MCCOMErr	MCCOMAPI CalcNormals		(real smoothAngle) = 0;		// Use this call if you do not know how to make the normals
	virtual TFacet3D*	MCCOMAPI GetIndFacets		(uint32 index) = 0;			// (index is 1 based)
	//--Init call
	virtual MCCOMErr	MCCOMAPI SetHasUVSpace		(boolean hasUV) = 0;		// If false, will remove all previous UV Space definitions
	virtual MCCOMErr	MCCOMAPI SetUVSpace			(UVSpaceInfo* uvSpaceInfo) = 0; // Set an UV Space. The UV space will be added if it was not defined yet
	virtual MCCOMErr	MCCOMAPI GetUVSpace			(uint32 uvSpaceID, UVSpaceInfo* uvSpaceInfo) = 0; // Get UV Space info
	virtual uint32		MCCOMAPI GetUVSpaceCount	() = 0;
};

// ****************************************************************************
//								I3DShPolygonArray
// 
/// \deprecated
///
/// I3DShPolygonArray is a regular array of 3D points and normals.
/// Other interfaces supported: I3DShObject, I3DShPrimitive
/// 
struct I3DShPolygonArray: public IMCUnknown
{
	//-- Init calls
	virtual MCCOMErr MCCOMAPI Init			(uint32 uCount, uint32 vCount, boolean uClosed, boolean vClosed) = 0;
	//-- Geometry calls
	virtual MCCOMErr MCCOMAPI MeshSetVertex	(uint32 uIndex, uint32 vIndex, TVector3* vertex, TVector3* normal) = 0;		// normal can be NULL
	virtual MCCOMErr MCCOMAPI MeshGetVertex	(uint32 uIndex, uint32 vIndex, TVector3* vertex, TVector3* normal) = 0;		// normal can be NULL
	//-- (u,v) calls
	virtual MCCOMErr MCCOMAPI MeshSetU		(uint32  uIndex, real uValue) = 0;
	virtual MCCOMErr MCCOMAPI MeshSetV		(uint32  vIndex, real vValue) = 0;
	virtual MCCOMErr MCCOMAPI MeshGetU		(uint32  uIndex, real* uValue) = 0;
	virtual MCCOMErr MCCOMAPI MeshGetV		(uint32  vIndex, real* vValue) = 0;
	//-- Goodies
	virtual MCCOMErr MCCOMAPI MeshCalcUV	() = 0;							// Calculate for you all (u,v) values if you do not know how to make them
	virtual MCCOMErr MCCOMAPI MeshCalcNormals(boolean smooth) = 0;			// Calculate for you all normals if you do not know how to make them
	virtual MCCOMErr MCCOMAPI GetSize		(uint32& uCount, uint32& vCount, boolean& uClosed, boolean& vClosed) = 0;

};


// ****************************************************************************
//								I3DShPatchList
// 
/// \deprecated
///
/// I3DShPatchList is simply a bag of cubic 4 x 4 Bezier patches.
/// Other interfaces supported: I3DShObject, I3DShPrimitive
///
struct I3DShPatchList: public IMCUnknown
{
	//-- Init calls
	virtual MCCOMErr	MCCOMAPI Init				(boolean hasUV) = 0;

	//-- Patches handling
	virtual MCCOMErr	MCCOMAPI AddPatch			(TPatch3D* patch) = 0;
	virtual TPatch3D*	MCCOMAPI GetIndPatches		(uint32 index) = 0;			// (index is 1 based)
	virtual uint32		MCCOMAPI CountPatches		() = 0;

	virtual MCCOMErr	MCCOMAPI SetHasUVSpace		(boolean hasUV) = 0;	// If false, will remove all previous UV Space definitions
	virtual MCCOMErr	MCCOMAPI SetUVSpace			(UVSpaceInfo* uvSpaceInfo) = 0; // Set an UV Space. The UV space will be added if it was not defined yet
	virtual MCCOMErr	MCCOMAPI GetUVSpace			(uint32 uvSpaceID, UVSpaceInfo* uvSpaceInfo) = 0; // Get UV Space info
	virtual uint32		MCCOMAPI GetUVSpaceCount	() = 0;
	virtual MCCOMErr	MCCOMAPI BuildFacetMesh		(real lod, FacetMesh** outMesh) = 0;	// Low-level proc that always returns the facet mesh at the requested LOD (different than when using the I3DShPrimitive::GetFMesh system of sampling LODs values)
};

// ****************************************************************************
//								I3DShPatchArray
// 
/// \deprecated
///
/// I3DShPatchArray is an array of cubic 4 x 4 Bezier patches.
/// Other interfaces supported: I3DShObject, I3DShPrimitive
///
struct I3DShPatchArray: public IMCUnknown
{
	//-- Init calls
	virtual MCCOMErr MCCOMAPI Init			(uint32 uCount, uint32 vCount) = 0;

	//-- Geometry calls
	virtual MCCOMErr MCCOMAPI SetPatch		(uint32 uIndex, uint32 vIndex, TPatch3D* patch) = 0;
	virtual MCCOMErr MCCOMAPI GetPatch		(uint32 uIndex, uint32 vIndex, TPatch3D* patch) = 0;

	//-- (u,v) calls
	virtual MCCOMErr MCCOMAPI MeshSetU		(uint32 uIndex, real uValue) = 0;
	virtual MCCOMErr MCCOMAPI MeshSetV		(uint32 vIndex, real vValue) = 0;
	virtual MCCOMErr MCCOMAPI MeshGetU		(uint32 uIndex, real* uValue) = 0;
	virtual MCCOMErr MCCOMAPI MeshGetV		(uint32 vIndex, real* vValue) = 0;

	//-- Goodies
	virtual MCCOMErr MCCOMAPI MeshCalcUV	() = 0;				// Calculate for you all (u,v) values if you do not know how to make them
	virtual MCCOMErr MCCOMAPI GetSize		(uint32& uCount, uint32& vCount) = 0;
	virtual MCCOMErr MCCOMAPI BuildFacetMesh(real lod, FacetMesh** outMesh) = 0;	// Low-level proc that always returns the facet mesh at the requested LOD (different than when using the I3DShPrimitive::GetFMesh system of sampling LODs values)
};


/// \}

#endif