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

		I3DShTreeElement.h

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

		I3DShTreeElement definition

		Author:	Ray Dream
		Date:	3/2/98

		Revision History

		when		who			what & why
		==========	==========	======================================================
		12/08/99	Yann		Added ClearInstanceCache
		11/24/99	Yann		Added the I3DShTreeElementMember interface
		10/25/99	Yann		Added invalidateDeformedGeometry parameter to EndMove and PostMoveChange
		09/14/99	Guillaume	Changed pointer parameters to reference parameters
		09/09/99	Guillaume	Changed the name of I3DShMotionLink to I3DShConstraint
		8/22/99		Greg		Added SetDataComponentByID (changed spelling on Get: byID to ByID)
		6/7/99		Greg		Added GetNotDeformedBBox and CanBeDistorted
		5/25/99		Greg		Added support for IsShown (in the 3DView)
		4/14/99		Alec		Added GetStandardLight call, TLightAndTfm and array
		3/16/99		Joshua		Added CLSID_StandardHelperObject
		3/16/99		Joshua		Added IsPickable
		3/4/99		Joshua		Added SetModifiers
		2/26/99		Joshua		Multiple wireframe support
		2/8/99		Joshua		Added ECloneMode param to ComClone		
								Added GetTopIfConstrained to API (renamed from GetFatherIfLinked)
								Added GetUndoInfo/SetFromUndoInfo to API
		1/25/99		Greg		GetCanonicalCameraType() and SetCanonicalCameraType now API calls
		01/06/99    Charles     Removed ExportFMesh call
		01/04/99	Joshua		Made GetAnimationMethod const
		12/14/98	EricB		Moved enum ETreeShadingLevel from TTree to I3DShTreeElement
		12/11/98	Alec		removed the renderer caching structs to I3DShRenderable.h
		12/10/98	Greg		GetEditor() is now an API call
		12/10/98	Joshua		Added GetFatherGlobalTransform3D
		11/24/98	Joshua		Added ECanonicalCameraType
		11/18/98	Joshua		Added CloneSubTree call
		11/3/98		Joshua		Unlink takes a RelinkTreeElementInfo, added Relink
		10/30/98	Eml			Master Shaders
		10/21/98	Alec		Did first pass at revising the cameras
		9/29/98		Joshua		Change to Modifier system

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

#ifndef __I3DSHTREEELEMENT__
#define __I3DSHTREEELEMENT__

#if CP_PRAGMA_ONCE
#pragma once
#endif


#include "APITypes.h"
#include "MCBasicDefines.h"
#include "MCCountedPtr.h"
#include "TreeTypes.h"
#include "WireFrameState.h"
#include "ComTypes.h"
#include "Id.h"
#include "Transforms.h"
#include "Vector3Fwd.h"
#include "Matrix33Fwd.h"


struct I3DExReflectionFeature;
struct I3DShReflectionFeature;
struct I3DExRefractionFeature;
struct I3DShRefractionFeature;
struct I3DExShadowFeature;
struct I3DShShadowFeature;
struct I3DExDataComponent;
struct I3DShDataComponent;
struct I3DShMasterGroup;
struct I3DImportData;

struct I3DShScene;
struct I3DShConstraint;
struct I3DShModifier;
struct I3DShLightsourceGel;
struct I3DShAnimationMethod;
struct I3DShMasterShader;
struct ISelectableObject;
struct TWireFrameInfo;
struct TConformingInfo;
struct IActorDataComponent;
struct IFigureDataComponent;

class  TTreeUndoInfo;
class  TBBox3D;
class  TRenderableAndTfmArray;
template <class T> class TMCArray;
template <class T> class TMCClassArray;
template <class T> class TMCCountedPtrArray;


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

MCDEFINE_GUID_SAFELIB(IID_I3DShTreeElement, 0xD68FEB00L, 0x3A02, 0x101C, 0x88, 0x5F, 0x04, 0x02, 0x1C, 0x00, 0x70, 0x02);
MCDEFINE_GUID_SAFELIB(IID_I3DShExtension, 0xE9F9B4A1L, 0x3A02, 0x101C, 0x88, 0x5F, 0x04, 0x02, 0x1C, 0x00, 0x70, 0x02);
MCDEFINE_GUID_SAFELIB(IID_I3DShTreeElementMember, 0xE37B67B3, 0x1768, 0x11d3, 0xba, 0xb4, 0x0, 0x0, 0xe8, 0xdd, 0x86, 0xd4);

// Classes always available
MCDEFINE_GUID_SAFELIB(CLSID_StandardSceneInstance, 0x7aaf6f4c, 0xde5a, 0x11d2, 0x8e, 0xe7, 0x0, 0x60, 0x97, 0xb, 0xc5, 0x21);
MCDEFINE_GUID_SAFELIB(CLSID_StandardHelperObject, 0xb3872731, 0xdbfd, 0x11d2, 0x88, 0x85, 0x0, 0x60, 0x97, 0x14, 0x85, 0x21);
MCDEFINE_GUID_SAFELIB(CLSID_StandardHelperJointObject, 0xdcab71ad, 0xfd41, 0x499a, 0x8a, 0xe1, 0xf0, 0x3a, 0xf2, 0x4, 0xcc, 0xe0);



/*****************************************************************************\
*  I3DShTreeElement                                                           *
*                                                                             *
*    I3DShTreeElement is the abstract class of all elements in a tree.        *
*                                                                             *
*    You can always get this interface from a I3DShGroup, I3DShInstance, etc. *
*                                                                             *
\*****************************************************************************/

// For SetGlobalTreeTransform mode
enum ETreeTransformMode
{
	kXTreeBehaviorDefault= 0,
	kXTreeBehaviorTrackT = 1,
	kXTreeBehaviorTrackR = 2,

	kInvalidTransformMode= 0xFFFFFFFF
};

//For SetLocalTreeTransform and SetGlobalTreeTransform
#define kApplyConstraint	true
#define kIgnoreConstraint	false

/* Behavior Message Flags */
#define kBMUpdatePhysics 1

#define kPathNameSeparator  '.'


struct RelinkTreeElementInfo;


//ETreeOperation's constants are used as arguments to I3DShTreeElement::IsOperationAllowed
enum ETreeOperation
{
	kNoOperation= 0,
	kCopyTreeOperation,				
	kDuplicateTreeOperation,		//includes duplicate with symetry
	kDeleteTreeOperation,
	kChangeTransformOperation,
	kChangeParentTreeOperation,
	kAddChildTreeOperation,
	kPromoteToMasterOperation,
	kCutTreeOperation,

	kInvalidOperation = 0xFFFFFFFF
};

enum ETreeType
{
	kGroup=1,
	kInstance=2,
	kHelperObject=3,
	kJoint=4,
	kInvisibleTree=5,
	kWorkingBox=16
};

#define	kOpAllowed				0x00
#define	kOpAlwaysForbidden		0x01
#define	kOpShouldDettachFirst	0x02
#define	kOpForbiddenUnkown		0x04


/// \addtogroup ShellInterface
/// \{

/// A tree element is a node in the hierarchy of the scene. It can be a group,
/// or a primitive instance or a scene instance...
///
/// <P>A tree element stores the transform of the object</P>
///
struct I3DShTreeElement: public IMCUnknown
{
	// ****************************************************************************
	//								GetScene
	// 
	/// Returns a pointer to the scene that contains this tree element.
	/// 
	/// \param scene  Pointer to the scene pointer should be returned.
	/// 
	virtual MCCOMErr	MCCOMAPI GetScene				(I3DShScene** scene) = 0;

	// ****************************************************************************
	//								GetSceneNoAddRef
	// 
	/// Returns a pointer to the scene that contains this tree
	/// 
	virtual I3DShScene* MCCOMAPI GetSceneNoAddRef		() =0;

	// ****************************************************************************
	//								SetName
	// 
	/// Sets the name of the tree element.
	/// 
	/// \param name  The new name of the tree.
	/// 
	virtual MCCOMErr MCCOMAPI SetName					(const TMCString& name) = 0;
	
	// ****************************************************************************
	//								GetName
	// 
	/// Returns the name of the tree element.
	/// 
	/// \param name  
	/// 
	virtual MCCOMErr MCCOMAPI GetName					(TMCString& name) = 0;
	
	// ****************************************************************************
	//								GetFirst
	// 
	/// Returns the first son of the tree element.
	/// 
	/// \param result A pointer to the first son of the tree element.  
	/// 
	virtual void     MCCOMAPI GetFirst					(I3DShTreeElement** result) = 0;	// Gives first son
	
	// ****************************************************************************
	//								GetLast
	// 
	/// Returns the last son of the tree element.
	/// 
	/// \param result  A pointer to the last son of the tree element.
	/// 
	virtual void     MCCOMAPI GetLast					(I3DShTreeElement** result) = 0;	// Gives last son
	
	// ****************************************************************************
	//								GetLeft
	// 
	/// Returns the tree element that is on the left of this tree element (previous son of the parent).
	/// 
	/// \param result  The previous tree element.
	/// 
	virtual void     MCCOMAPI GetLeft					(I3DShTreeElement** result) = 0;	// Gives left brother
	
	// ****************************************************************************
	//								GetRight
	// 
	/// Returns the tree element that is on the right of this tree element (next son of the parent).
	/// 
	/// \param result  The next tree element.
	/// 
	virtual void     MCCOMAPI GetRight					(I3DShTreeElement** result) = 0;	// Gives right brother
	
	// ****************************************************************************
	//								GetTop
	// 
	/// Returns the parent of the tree element.
	/// 
	/// \param result  A pointer to the parent of the tree element.
	/// 
	virtual void     MCCOMAPI GetTop					(I3DShTreeElement** result) = 0;	// Gives father

	// ****************************************************************************
	//								GetTop
	// 
	/// Returns the parent of the tree element.
	/// 
	virtual I3DShTreeElement*	MCCOMAPI	GetTop		() const = 0;

	// ****************************************************************************
	//								GetIndexInTop
	// 
	/// Returns the index of this tree in its parent.
	/// 
	virtual int32	 MCCOMAPI GetIndexInTop				() = 0;

	// ****************************************************************************
	//								IsAncestorOf
	// 
	/// Returns true if this tree is a parent of the given tree (is same trees returns false).
	/// 
	/// \param wouldBeHeir  A pointer to a tree who could be a child of this tree.
	/// 
	virtual boolean  MCCOMAPI IsAncestorOf				(const I3DShTreeElement* wouldBeHeir) const = 0;

	// ****************************************************************************
	//								Unlink
	// 
	/// Unhook tree element from father, and returns old father 
	/// 
	/// \param treeElement  The old father.
	/// \param outRelink    Data to relink the tree element.
	/// 
	virtual MCCOMErr MCCOMAPI Unlink					(I3DShTreeElement** treeElement, RelinkTreeElementInfo* outRelink=NULL) = 0;
	
	// ****************************************************************************
	//								Relink
	// 
	/// Rehook tree element based upon Unlink() 
	/// 
	/// \param inRelink  The info coming from Unlink()
	/// 
	virtual	MCCOMErr MCCOMAPI Relink					(RelinkTreeElementInfo* inRelink) = 0;
	
	// ****************************************************************************
	//								InsertFirst
	// 
	/// Inserts as the first son
	/// 
	/// \param newSon  The tree element to insert.
	/// 
	virtual MCCOMErr MCCOMAPI InsertFirst				(I3DShTreeElement* newSon) = 0;
	
	// ****************************************************************************
	//								InsertLast
	// 
	/// Inserts as the last son.
	/// 
	/// \param newSon  The tree element to insert.
	/// 
	virtual MCCOMErr MCCOMAPI InsertLast				(I3DShTreeElement* newSon) = 0;
	
	// ****************************************************************************
	//								InsertLeft
	// 
	/// Inserts as the first left brother
	/// 
	/// \param newBrother  The tree element to insert.
	/// 
	virtual MCCOMErr MCCOMAPI InsertLeft				(I3DShTreeElement* newBrother) = 0;
	
	// ****************************************************************************
	//								InsertRight
	// 
	/// Insert as the first right brother
	/// 
	/// \param newBrother  The tree element to insert.
	/// 
	virtual MCCOMErr MCCOMAPI InsertRight				(I3DShTreeElement* newBrother) = 0;		

	// ****************************************************************************
	//								GetPrimScalingFactor
	// 
	/// Returns the scaling factor associated with the local object (primitive, etc)
	/// 
	virtual real32	 MCCOMAPI GetPrimScalingFactor		() const = 0;

	// ****************************************************************************
	//								SetScalingFactor
	// 
	/// Sets the scaling factor for this tree element. Note that this should only
	/// be used on helper objects since it will have no effect on primitives.
	/// 
	virtual void MCCOMAPI SetScalingFactor(real scalingFactor) =0;

	// ****************************************************************************
	//								GetHotPoint
	// 
	/// Returns the hot point of the tree element. The hot point is the center of
	/// rotation.
	/// 
	/// \param hotPoint  The position of the hot point.
	/// 
	virtual MCCOMErr MCCOMAPI GetHotPoint				(TVector3& hotPoint) = 0;				// In local coordinates
	
	// ****************************************************************************
	//								SetHotPoint
	// 
	/// Sets the hot point of the tree element. The hot point is the center of
	/// rotation.
	/// 
	/// \param hotPoint  The position of the hot point.
	/// 
	virtual MCCOMErr MCCOMAPI SetHotPoint				(const TVector3& hotPoint) = 0;			// In local coordinates
	
	// ****************************************************************************
	//								CenterElementOnHotPoint
	// 
	/// Moves the tree element so that its center matches the hotpoint.
	/// 
	virtual MCCOMErr MCCOMAPI CenterElementOnHotPoint	() = 0;
	
	// ****************************************************************************
	//								CenterHotPointOnElement
	// 
	/// Moves the hot point so that its center matches the hotpoint.
	/// 
	virtual MCCOMErr MCCOMAPI CenterHotPointOnElement	() = 0;
	
	// ****************************************************************************
	//								TranslateHotPoint
	// 
	/// Translates hotpoint of delta (In local coordinates)
	/// 
	/// \param delta The translation in local coordinates. 
	/// 
	virtual MCCOMErr MCCOMAPI TranslateHotPoint			(TVector3& delta) = 0;

	// ****************************************************************************
	//								ComClone
	// 
	/// Creates a copy of the tree element.
	/// 
	/// \param treeElement  The copy that is created.
	/// \param cloneMode    The clone mode (see ECloneMode).
	/// \param cloneAll     True if the whole subtree should be copied.
	/// 
	virtual MCCOMErr MCCOMAPI ComClone					(I3DShTreeElement** treeElement, ECloneMode cloneMode, boolean cloneAll) = 0;

	// ****************************************************************************
	//								InvalidateBoundingBox
	// 
	/// Invalidates the bounding box of the tree.
	/// 
	virtual void	 MCCOMAPI InvalidateBoundingBox		() = 0;
	
	// ****************************************************************************
	//								GetBoundingBoxWithoutLightsAndCameras
	// 
	/// Returns the (deformed) bounding box of the tree and its children without taking into
	/// account the lights and cameras.
	/// 
	/// \param bbox  The bounding box that is returned.
	/// \param rendering   True if you want a bounding box for rendering or just for previewing
	/// 
	virtual void	 MCCOMAPI GetBoundingBoxWithoutLightsAndCameras(TBBox3D& bbox, boolean rendering=true, boolean onlyVisible=false) = 0;
	
	// ****************************************************************************
	//								GetBoundingBox
	// 
	/// Returns the bounding box of the tree element.
	/// 
	/// \param bbox        The bounding box of the tree element.
	/// \param deformMode  The deformation mode (see ETreeDeformBBoxModes).
	/// \param rendering   True if you want a bounding box for rendering or just for previewing
	/// 
	virtual void	 MCCOMAPI GetBoundingBox			(TBBox3D& bbox, ETreeDeformBBoxModes deformMode, boolean rendering=true) = 0;
	
	// ****************************************************************************
	//								GetSubtreeBoundingBox
	// 
	/// Returns the bounding box of the entire subtree
	/// 
	/// \param bbox        The bounding box.
	/// \param deformMode  The deformation mode (see ETreeDeformBBoxModes).
	/// \param rendering   True if you want a bounding box for rendering or just for previewing
	/// 
	virtual void	 MCCOMAPI GetSubtreeBoundingBox		(TBBox3D& bbox, ETreeDeformBBoxModes deformMode, boolean rendering=true) = 0; 

	// ****************************************************************************
	//								CanBeDistorted
	// 
	/// Returns true if a non uniform scaling can be applied to this tree element.
	/// 
	virtual boolean	 MCCOMAPI CanBeDistorted			() = 0;
	
	// ****************************************************************************
	//								BeginMove
	// 
	/// Called when a tree starts moving.
	/// 
	virtual MCCOMErr MCCOMAPI BeginMove					() = 0;
	
	// ****************************************************************************
	//								PostMoveChange
	// 
	/// Called to notify the scene that a tree has moved.
	/// 
	/// \param invalidateDeformedGeometry True if the deformer should be invalidated.  
	/// 
	virtual void	 MCCOMAPI PostMoveChange			(boolean invalidateDeformedGeometry = false) = 0;
	
	// ****************************************************************************
	//								EndMove
	// 
	/// Called when a tree has been moved or modified.
	/// 
	/// \param invalidateDeformedGeometry  True if the deformer should be invalidated.
	/// 
	virtual MCCOMErr MCCOMAPI EndMove					(boolean invalidateDeformedGeometry = false) = 0;
	
	// ****************************************************************************
	//								GetXYZScaling
	// 
	/// Returns the non uniform scaling.
	/// 
	/// \param xyzScaling  The non uniform scaling.
	/// 
	virtual MCCOMErr MCCOMAPI GetXYZScaling				(TVector3& xyzScaling) = 0;
	
	// ****************************************************************************
	//								SetXYZScaling
	// 
	/// Sets the non uniform scaling.
	/// 
	/// \param xyzScaling  The non uniform scaling.
	/// 
	virtual MCCOMErr MCCOMAPI SetXYZScaling				(TVector3& xyzScaling) = 0;

	/// Sets whether the uniform scaling is applied to the children
	virtual void	 MCCOMAPI SetPropagateUniformScaling	(boolean inPropagateUniformScaling) = 0;

	/// Returns true when the uniform scaling is applied to the children
	/// Returns false then the uniform scaling is only applied to the tree
	virtual boolean	 MCCOMAPI GetPropagateUniformScaling	() const = 0;

	/// Returns true when the XYZ scaling is applied to the children
	/// Returns false then the XYZ scaling is only applied to the tree
	virtual boolean	 MCCOMAPI GetPropagateXYZScaling		() const = 0;

	/// Returns true when the XYZ and uniform scaling when not propagated scale
	/// the children offset (ie. the children are translated)
	virtual boolean	 MCCOMAPI ApplyScalingToChildrenOffsets	() const = 0;
	
	/// Sets the XYZ and uniform scaling policy regarding children offset scaling
	virtual void	 MCCOMAPI SetApplyScalingToChildrenOffsets(boolean enable) = 0;

	// ****************************************************************************
	//								GetNbrFreedom
	// 
	/// Returns the number of degree of freedom of this tree element and its parents.
	/// Note that it is not the same as the number of degree of freedom of the
	/// constraint applied to the tree element. It is the sum of the degree of
	/// freedom of this tree element and its parents.
	/// 
	virtual int16	 MCCOMAPI GetNbrFreedom				() = 0;
	
	// ****************************************************************************
	//								GetFreedomRange
	// 
	/// Returns the limits of the variations of a given degree of freedom.
	/// 
	/// \param index  The index (1-based) of the degree of freedom of tree element. (see GetNbrFreedom()).
	/// \param min    The minimum value.
	/// \param max    The maximum value.
	/// 
	virtual MCCOMErr MCCOMAPI GetFreedomRange			(int16 index,real* min,real* max) = 0;
	
	// ****************************************************************************
	//								GetFreedomTransform
	// 
	/// Returns the rotation matrix and translation vector due to the freedom values.
	/// When the freedom values are initialized the function GetTransform must return
	/// the identity matrix for the rotation and a null vector for the translation.
	/// 
	/// \param RR     The rotation matrix
	/// \param TT     The transation
	///
	virtual MCCOMErr MCCOMAPI GetFreedomTransform		(TMatrix33& RR,TVector3& TT) = 0;
	
	// ****************************************************************************
	//								GetFreedomDerivative
	// 
	/// Returns the derivatives of the transform relative to a degree of freedom.
	/// A partial derivative transformation is a transformation where each element
	/// is derived by a freedom degree.
	/// 
	/// \param index  The index (1-based) of the degree of freedom of tree element (see GetNbrFreedom()).
	/// \param RR     The rotation matrix derivative
	/// \param TT     The transation derivative
	/// 
	virtual MCCOMErr MCCOMAPI GetFreedomDerivative		(int16 index,TMatrix33& RR,TVector3& TT) = 0;
	
	// ****************************************************************************
	//								GetFreedomSecondDerivative
	// 
	/// Returns the second order partial derivative of the transform. A partial derivative
	/// transformation is a transformation where each element is derived by a freedom degree.
	/// 
	/// \param index1  The index (1-based) of the first degree of freedom used to derivate the transform (see GetNbrFreedom()).
	/// \param index2  The index (1-based) of the second degree of freedom used to derivate the transform (see GetNbrFreedom()).
	/// \param RR      The rotation matrix derivative
	/// \param TT      The transation derivative
	/// 
	virtual MCCOMErr MCCOMAPI GetFreedomSecondDerivative(int16 index1, int16 index2, TMatrix33& RR,TVector3& TT) = 0;
	
	// ****************************************************************************
	//								IncrementFreedomValue
	// 
	/// Modify the value of a degree of freedom by adding an increment
	///
	/// \param index The index (1-based) of the degree of freedom of tree element (see GetNbrFreedom()).
	/// \param value The increment value
	/// 
	virtual MCCOMErr MCCOMAPI IncrementFreedomValue		(int16 index,real* value) = 0;
	
	// ****************************************************************************
	//								MarkFreedomAsModified
	// 
	/// Mark a freedom degree as modified.
	/// 
	/// \param index  The index (1-based) of the degree of freedom of tree element (see GetNbrFreedom()).
	/// 
	virtual void	 MCCOMAPI MarkFreedomAsModified		(int16 index) = 0;
	
	// ****************************************************************************
	//								GetGlobalHotPoint
	// 
	/// Returns the hot point in global coordinates.
	/// 
	/// \param index        The index (1-based) of the degree of freedom of tree element (see GetNbrFreedom()).
	/// \param outGlobalHP  The hotpoint.
	/// 
	virtual void	 MCCOMAPI GetGlobalHotPoint			(int16 index, TVector3& outGlobalHP) = 0;

	// ****************************************************************************
	//								AddDependentIKeffector
	// 
	/// When this tree is an IK target, the effectors can register themselves to get movement notification
	/// 
	/// \param inUniqueID  The unique ID of the tree.
	/// 
	virtual void 	 MCCOMAPI AddDependentIKeffector	(TTreeId inUniqueID) = 0;
	
	// ****************************************************************************
	//								RemoveDependentIKeffector
	// 
	/// When this tree is an IK target, the effectors can register themselves to get movement notification
	/// 
	/// \param inUniqueID  The unique ID of the tree.
	/// 
	virtual void 	 MCCOMAPI RemoveDependentIKeffector	(TTreeId inUniqueID) = 0;
	
	// ****************************************************************************
	//								GetDependentIKeffectors
	// 
	/// Returns an array of the unique ID of the effects that influence the motion
	/// of the tree.
	/// 
	virtual const TMCArray<TTreeId>& MCCOMAPI GetDependentIKeffectors() = 0;

	// ****************************************************************************
	//								GetFullName
	// 
	/// Returns the "path name" of the tree element (nodes separated by kPathNameSeparator)
	/// 
	/// \param fullName  The full path name of the tree.
	/// 
	virtual MCCOMErr MCCOMAPI GetFullName				(TMCString& fullName) = 0;

	// ****************************************************************************
	//								InsertModifier
	// 
	/// Inserts a modifier in the modifier list of the tree.
	/// 
	/// \param modifier   The modifier that should be inserted.
	/// \param index      The index in the modifier list.
	/// \param cloneMode  The clone mode (see ECloneMode).
	/// 
	virtual MCCOMErr MCCOMAPI InsertModifier			(I3DShModifier* modifier, uint32 index, ECloneMode cloneMode) = 0;
	
	// ****************************************************************************
	//								RemoveModifier
	// 
	/// Removes a modifier from the modifier list.
	/// 
	/// \param index  The index of the modifier to remove.
	/// 
	virtual MCCOMErr MCCOMAPI RemoveModifier			(uint32 index) = 0;
	
	// ****************************************************************************
	//								GetModifiersCount
	// 
	/// Returns the number of modifiers in the modifier list.
	/// 
	virtual uint32   MCCOMAPI GetModifiersCount			() = 0;
	
	// ****************************************************************************
	//								GetModifierByIndex
	// 
	/// Gets a modifier by index.
	/// 
	/// \param modifier  A pointer to the modifier.
	/// \param index     The index in the list of modifiers.
	/// 
	virtual MCCOMErr MCCOMAPI GetModifierByIndex		(I3DShModifier** modifier, uint32 index) = 0;
	
	// ****************************************************************************
	//								SetModifiers
	// 
	/// Sets the list of modifiers.
	/// 
	/// \param modifiers  The list of modifiers.
	/// \param cloneMode  The clone mode (see ECloneMode).
	/// 
	virtual MCCOMErr MCCOMAPI SetModifiers				(const TMCCountedPtrArray<I3DShModifier>* modifiers, ECloneMode cloneMode)=0;

	// ****************************************************************************
	//								LinksChanged
	// 
	/// Called when a constraint has been changed..
	/// \param updateIK   when true, updates the ik chains of the sons
	virtual MCCOMErr MCCOMAPI LinksChanged				(boolean updateIK) = 0;
	
	// ****************************************************************************
	//								BeginGetRenderables
	// 
	/// Called to get all the renderable of this tree element and its children.
	/// 
	/// \param instances    The list of renderables when the new renderable should be append.
	/// \param inOnlyShown  True if only the renderable that are visible in the 3DView should be appended.     
	/// 
	virtual MCCOMErr MCCOMAPI BeginGetRenderables		(const TRenderableAndTfmArray*& instances, boolean inOnlyShown = false) = 0;
	
	// ****************************************************************************
	//								EndGetRenderables
	// 
	/// Called after BeginGetRenderables,
	/// 
	virtual MCCOMErr MCCOMAPI EndGetRenderables			() = 0;
		
	// ****************************************************************************
	//								GetConstraint
	// 
	/// Returns the constraint applied to this tree element.
	/// 
	/// \param link  A pointer to the constraint.
	/// 
	virtual MCCOMErr MCCOMAPI GetConstraint				(I3DShConstraint** link) const = 0;
	
	// ****************************************************************************
	//								SetConstraint
	// 
	/// Sets the constraint applied to this tree element.
	/// 
	/// \param link       A pointer to the constraint.
	/// \param cloneMode  The clone mode (see ECloneMode).
	/// 
	virtual MCCOMErr MCCOMAPI SetConstraint				(I3DShConstraint* link, ECloneMode cloneMode) = 0;
	
	// ****************************************************************************
	//								SetConstraintByID
	// 
	/// Sets a contraint by class ID.
	/// 
	/// \param kindID  The class ID of the constraint.
	/// 
	virtual MCCOMErr MCCOMAPI SetConstraintByID			(int32 kindID) = 0;
	

	// ****************************************************************************
	//                             IsContraintEnabled
	//
	// Returns bool indicating if the contraints are enabled for the element
	virtual boolean MCCOMAPI IsConstraintEnabled() = 0;
	
	// ****************************************************************************
	//                             SetConstraintProtected
	//
	// Set the ProtectedConstraint flag to onOff value
	virtual void	MCCOMAPI SetConstraintProtected(boolean onOff) = 0;

	// ****************************************************************************
	//                             GetConstraintProtected
	//
	// Get the ProtectedConstraint flag value
	virtual boolean	MCCOMAPI GetConstraintProtected() = 0;

	// ****************************************************************************
	//								GetDataComponentsCount
	// 
	/// Returns the number of data components applied to this tree element.
	/// 
	virtual uint32   MCCOMAPI GetDataComponentsCount	() = 0;
	
	// ****************************************************************************
	//								GetDataComponentByIndex
	// 
	/// Gets a data component by index.
	/// 
	/// \param dataComp  A pointer to the data component that is returned.
	/// \param index     The index in the list of data components.
	/// 
	virtual MCCOMErr MCCOMAPI GetDataComponentByIndex	(I3DShDataComponent** dataComp, uint32 index) = 0;
	
	// ****************************************************************************
	//								SetDataComponentByID
	// 
	/// Sets a data component.
	/// 
	/// \param dataComp   A pointer to the data component.
	/// \param cloneMode  The clone mode (see ECloneMode).
	/// 
	virtual MCCOMErr MCCOMAPI SetDataComponentByID		(I3DShDataComponent* dataComp, ECloneMode cloneMode) = 0;
	
	// ****************************************************************************
	//								GetDataComponentByID
	// 
	/// Returns the data component of a given type.
	/// 
	/// \param dataComp  A pointer to the data component.
	/// \param kindID    The class ID of the data component.
	/// 
	virtual MCCOMErr MCCOMAPI GetDataComponentByID		(I3DShDataComponent** dataComp, IDType kindID) = 0;
	
	// ****************************************************************************
	//								InsertDataComponent
	// 
	/// Inserts a data component.
	/// 
	/// \param dataComp  A data component to insert.
	/// 
	virtual MCCOMErr MCCOMAPI InsertDataComponent		(I3DShDataComponent* dataComp)=0;
	
	// ****************************************************************************
	//								InsertDataComponentByID
	// 
	/// Inserts a data component.
	/// 
	/// \param kindID  The class ID of the data component.
	/// \param index   The index in the list of data component.
	/// 
	virtual MCCOMErr MCCOMAPI InsertDataComponentByID	(int32 kindID, int32 index) = 0;
	
	// ****************************************************************************
	//								RemoveDataComponent
	// 
	/// Removes a data component.
	/// 
	/// \param index  The index of the data component.
	/// 
	virtual MCCOMErr MCCOMAPI RemoveDataComponent		(uint32 index) = 0;

	///Returns the actor data component of the tree (if any)
	virtual IActorDataComponent*	MCCOMAPI GetActorDataComponent	() = 0;

	///Returns the figure data component of the tree (if any)
	virtual IFigureDataComponent*	MCCOMAPI GetFigureDataComponent	() = 0;


	virtual void	 MCCOMAPI SetData					(TDataKey dataKey, IMCUnknown* data)=0;
	virtual MCCOMErr MCCOMAPI GetData					(TDataKey dataKey, IMCUnknown** data)=0;
	virtual void	 MCCOMAPI ReleaseData				(TDataKey dataKey)=0;
	virtual void	 MCCOMAPI ReleaseData				()=0;

	// ****************************************************************************
	//								IsOpen
	// 
	/// Returns true if its children can be edited.
	/// 
	virtual boolean	 MCCOMAPI IsOpen					()=0;

	// ****************************************************************************
	//								GetEditor
	// 
	/// Returns the classID of the module that can edit this tree element.
	/// 
	virtual	int32	 MCCOMAPI GetEditor					() const = 0;

	// ****************************************************************************
	//								GetAnimationMethod
	// 
	/// Returns the animation method that is associated with this tree element.
	/// 
	/// \param animationMethod  A pointer to the animation method.
	/// 
	virtual MCCOMErr MCCOMAPI GetAnimationMethod		(I3DShAnimationMethod** animationMethod) const = 0;

	// ****************************************************************************
	//								SetAnimationMethod
	// 
	// -Description: 
	//		Set a new animation method on the tree or convert the data from the previous animation
	//		method into the new one
	// -Parameters:
	//		usePreviousAnimationData: set to true to convert the data from the previous animation method 
	//		to the new one
	//		conversionQuality: used only if usePreviousAnimationData is set to true.
	// ****************************************************************************
	//								SetAnimationMethod
	// 
	/// Set a new animation method on the tree or convert the data from the previous animation
	///	method into the new one.
	/// 
	/// \param animationMethod           The new animation method.
	/// \param cloneMode                 The clone mode (see ECloneMode).
	/// \param conversionQuality         used only if usePreviousAnimationData is set to true.
	/// \param usePreviousAnimationData  Set to true to convert the data from the previous animation method 
	///	                                 to the new one.
	/// 
	virtual void	 MCCOMAPI SetAnimationMethod		(I3DShAnimationMethod* animationMethod, ECloneMode cloneMode, real conversionQuality=0.0f, boolean usePreviousAnimationData=false) = 0;

	// ****************************************************************************
	//								GetLocalTreeTransform
	// 
	/// Returns the local transform of the tree element.
	/// 
	virtual	const TTreeTransform&	MCCOMAPI GetLocalTreeTransform			() const = 0;

	// ****************************************************************************
	//								GetGlobalTransform3D
	// 
	/// Returns the global transform of the tree element.
	/// 
	/// \param frameType  This parameter allows you to get the transform at the previous frame
	///                   or next frame if it was stored using I3DShScene::StoreCurrentState.
	/// 
	virtual	const TTransform3D&		MCCOMAPI GetGlobalTransform3D			(EFrameType frameType = kCurrentFrame) const = 0;
	
	// ****************************************************************************
	//								GetInverseGlobalTransform3D
	// 
	/// Returns the inverse of the global transform of the tree element.
	/// 
	virtual	const TTransform3D& 	MCCOMAPI GetInverseGlobalTransform3D	() const = 0;

	// ****************************************************************************
	//								GetLocalTreeTransform
	// 
	/// Returns the local transform of the tree element (takes conforming into account)
	/// 
	/// \param mat  The local transform.
	/// 
	virtual void	 MCCOMAPI GetLocalTreeTransform		(TTreeTransform& mat)=0;

	// ****************************************************************************
	//								SetLocalTreeTransform
	// 
	/// Sets the local tree transform 
	/// 
	/// \param mat              The new local transform.
	/// \param applyConstraint  use kApplyConstraint and kIgnoreConstraint
	/// \param lockChildren		If true the position of the children of this tree element will be
	///							corrected to lock their positions in global space (WARNING: setting
	///							this flags on will modified the transform of the children, you need
	///							to be carefull (with the undo for instance).
	/// \param moveAnimation    If true, the whole animation is moved not only the transform at this time.
	/// \param mode             If kXTreeBehaviorTrackT the current rotation will be kept
	/// \param ignoreObjScaling	If true, will ignore the instance's own scaling factor. If false, the transform
	///							matrix will be divided by this factor. In practice, this parameter should be false 
	///							if the matrix has originally been obtained by a call to a GetXXXXTransform method and
	///							it should be true otherwise
	/// \param removeConstraint If true, the transform of the constraint will be removed from mat
	/// 
	virtual void	 MCCOMAPI SetLocalTreeTransform		(const TTreeTransform& mat,
														 boolean	applyConstraint	= kApplyConstraint,
														 boolean	lockChildren	= false,
														 boolean	moveAnimation	= false,
														 ETreeTransformMode mode	= kXTreeBehaviorDefault,
														 boolean	ignoreObjScaling  = false,
														 boolean	removeConstraint= true)=0;
	
	// ****************************************************************************
	//								GetGlobalTreeTransform
	// 
	/// Returns the global transform of the object. Note that this method only
	/// works if the local transform of the parents do not have non uniform
	/// scaling. It is recommended to use GetGlobalTransform3D() instead whenever
	/// it is possible.
	/// 
	/// \param mat  The global transform.
	/// 
	virtual	void	 MCCOMAPI GetGlobalTreeTransform	(TTreeTransform& mat) = 0;

	// ****************************************************************************
	//								GetGlobalTreeTransform2
	// 
	/// Returns the global transform of the object.
	/// 
	/// \param mat  The global transform.
	/// 
	virtual	void	 MCCOMAPI GetGlobalTreeTransform2	(TGlobalTreeTransform& mat) = 0;

	// ****************************************************************************
	//								SetGlobalTreeTransform
	// 
	/// Sets the global transform of the tree
	/// NOTE: this function should be avoided as much as possible as it cannot work in some cases 
	///		  (non uniform scaling on parents, or a transform build from the local transforms of an uncompatible hierarchy
	/// 
	/// \param mat                   The global transform.
	/// \param mode                  If kXTreeBehaviorTrackT the current rotation will be kept
	/// \param applyConstraint       when false, the constraint on the tree (if any) will be ignored.
	///					             you should use kApplyConstraint (true) and kIgnoreConstraint(false)
	/// \param lockChildren			 If true the position of the children of this tree element will be
	///								 corrected to lock their positions in global space (WARNING: setting
	///								 this flags on will modified the transform of the children, you need
	///								 to be carefull (with the undo for instance).
	/// \param moveAnimation         If true, the whole animation is moved not only the transform at this time
	/// \param ignoreObjScaling		 If true, will ignore the instance's own scaling factor. If false, the transform
	///								 matrix will be divided by this factor. In practice, this parameter should be false if
	///								 the matrix has originally been obtained by a call to a GetXXXXTransform method and
	///								 it should be true otherwise
	/// 
	virtual	void	 MCCOMAPI SetGlobalTreeTransform	(	const TTreeTransform&	mat, 
															ETreeTransformMode		mode			= kXTreeBehaviorDefault,
															boolean					applyConstraint	= kApplyConstraint,
															boolean					lockChildren	= false,
															boolean					moveAnimation	= false,
															boolean					ignoreObjScaling = false) = 0;

	// ****************************************************************************
	//								SetGlobalTreeTransform2
	// 
	/// Sets the global transform of the tree
	/// NOTE: this function should be avoided as much as possible as it cannot work in some cases 
	///		  (non uniform scaling on parents, or a transform build from the local transforms of an uncompatible hierarchy
	/// 
	/// \param mat                   The global transform.
	/// \param ignoreObjScaling		 If true, will ignore the instance's own scaling factor. If false, the transform
	///								 mat will be divided by this factor. In practice, this parameter should be false if
	///								 the matrix has originally been obtained by a call to a GetXXXXTransform method and
	///								 it should be true otherwise
	/// \param mode                  If kXTreeBehaviorTrackT the current rotation will be kept
	/// \param applyConstraint       when false, the constraint on the tree (if any) will be ignored.
	///					             you should use kApplyConstraint (true) and kIgnoreConstraint(false)
	/// \param lockChildren			 If true the position of the children of this tree element will be
	///								 corrected to lock their positions in global space (WARNING: setting
	///								 this flags on will modified the transform of the children, you need
	///								 to be carefull (with the undo for instance).
	/// \param moveAnimation         If true, the whole animation is moved not only the transform at this time
	/// \param ignoreObjScaling		 If true, will ignore the instance's own scaling factor. If false, the transform
	///								 matrix will be divided by this factor. In practice, this parameter should be false if
	///								 the matrix has originally been obtained by a call to a GetXXXXTransform method and
	///								 it should be true otherwise
	/// 
	virtual	void	 MCCOMAPI SetGlobalTreeTransform2	(	const TGlobalTreeTransform&	mat,
															ETreeTransformMode			mode			= kXTreeBehaviorDefault,
															boolean						applyConstraint	= kApplyConstraint,
															boolean						lockChildren	= false,
															boolean						moveAnimation	= false,
															boolean					  ignoreObjScaling  = false) = 0;

	// ****************************************************************************
	//								GetGlobalTransform3D
	// 
	/// Returns the global transform of the tree.
	/// 
	/// \param mat  The global transform of the tree element.
	/// 
	virtual	void	 MCCOMAPI GetGlobalTransform3D		(TTransform3D& mat) const = 0;
	
	// ****************************************************************************
	//								GetInverseGlobalTransform3D
	// 
	/// Returns the inverse of the global transform of this tree element.
	/// 
	/// \param mat  The inverse of the global transform.
	/// 
	virtual void	 MCCOMAPI GetInverseGlobalTransform3D(TTransform3D& mat) const = 0; 
	
	// ****************************************************************************
	//								SetGlobalTransform3D
	// 
	/// Sets the global transform of the tree element.
	/// 
	/// \param mat   The global transform of the tree element.
	/// \param mode  See ETreeTransformMode.
	/// 
	virtual	void	 MCCOMAPI SetGlobalTransform3D		(const TTransform3D& mat, ETreeTransformMode mode = kXTreeBehaviorDefault) = 0;

	// ****************************************************************************
	//								GetFatherGlobalTransform
	// 
	/// Returns the global transform of the parent.
	/// 
	/// \param mat  The global transform of the parent.
	/// 
	virtual	void 	 MCCOMAPI GetFatherGlobalTransform(TFatherTransform& mat) const = 0;

	// ****************************************************************************
	//								GetUnconstrainedLocalTreeTransform
	// 
	/// Returns the local transform of the tree that doesn't take into account the tree's constraint.
	/// When there is a constraint GetLocalTreeTransform == GetUnconstrainedLocalTreeTransform() * constraintTransform
	/// 
	virtual	const TTreeTransform&	MCCOMAPI GetUnconstrainedLocalTreeTransform() const = 0;


	// ****************************************************************************
	//								GetUnconformedLocalTreeTransform
	// 
	/// Returns the local transform of the tree that doesn't take into account the tree's conforming, 
	/// but takes into account the constraint
	virtual	void	MCCOMAPI GetUnconformedLocalTreeTransform(TTreeTransform& outLocalT) const = 0;

	// ****************************************************************************
	//								CloneSubTree
	// 
	/// Creates a copy of the sub tree.
	/// 
	/// \param cloneMode  The clone mode (see ECloneMode).
	/// \param clone      The copy of the sub tree.
	/// 
	virtual MCCOMErr MCCOMAPI CloneSubTree				(ECloneMode cloneMode, I3DShTreeElement** clone)=0;

	// ****************************************************************************
	//								GetUndoInfo
	// 
	/// Returns the undo info.
	/// 
	/// \param undoInfo  the undo info.
	/// 
	virtual void	 MCCOMAPI GetUndoInfo				(TTreeUndoInfo& undoInfo) const=0;
	
	virtual void	 MCCOMAPI SetFromUndoInfo			(const TTreeUndoInfo& toInfo, const TTreeUndoInfo* fromInfo)=0;

	// ****************************************************************************
	//								GetTopIfConstrained
	// 
	/// \deprecated
	/// 
	virtual MCCOMErr MCCOMAPI GetTopIfConstrained		(I3DShTreeElement** treeElement) const { MCNotify("Deprecated function"); return MC_S_FALSE;} //Arnaud: was used too stupidly.

	// ****************************************************************************
	//								GetWireFrameArray
	// 
	/// Returns the list of all component anim attached to the tree that implement the I3DExWF interface
	/// 
	/// \param wireFrameArray  the array to fill with the wireframes
	/// 
	virtual MCCOMErr MCCOMAPI GetWireFrameArray			(TMCClassArray<TWireFrameInfo>& wireFrameArray) = 0;

	// ****************************************************************************
	//								SetWireFramesState
	// 
	/// Changes the state of all the wireframes attached to the tree.
	/// 
	/// \param wfState  The new state
	/// 
	virtual void	 MCCOMAPI SetWireFramesState		(EWireFrameState wfState) = 0;


	// ****************************************************************************
	//								IsPickable
	// 
	/// Returns true if the tree element can be picked in the 3D view.
	/// 
	virtual boolean	 MCCOMAPI IsPickable				() const=0;

	// ****************************************************************************
	//								IsBBoxPickable
	// 
	/// Returns true if the tree element can be selected by its bounding box
	/// (primitive instances usually reply no to allow accurate picking)
	/// 
	virtual boolean	 MCCOMAPI IsBBoxPickable			() const=0;

	// ****************************************************************************
	//							IsControllingAtmosphere
	// 
	/// Should return true iff the tree element is linked to the atmosphere and can
	/// be used to control some of the atmosphere's parameters (e.g. Sun lights).
	/// 
	virtual boolean	 MCCOMAPI IsControllingAtmosphere			() const=0;

	// ****************************************************************************
	//							UpdateAtmosphere
	// 
	/// This function is called each time this tree element (or one of its wireframes) 
	/// is tracked if IsControllingAtmosphere() returned true, to update the current
	///	scene's atmosphere according to the tree element
	/// 
	virtual MCCOMErr MCCOMAPI UpdateAtmosphere			() = 0;

	// ****************************************************************************
	//								RemoveConstraint
	// 
	/// Removes the constraint from the tree element.
	/// 
	/// \param outLink  A pointer to the constraint that was removed.
	/// 
	virtual void	 MCCOMAPI RemoveConstraint			(I3DShConstraint** outLink)=0;
	
	// ****************************************************************************
	//								RestoreConstraint
	// 
	/// Restore a constraint (see RemoveConstraint())
	/// 
	/// \param inLink  A pointer to the constraint
	/// 
	virtual void	 MCCOMAPI RestoreConstraint			(I3DShConstraint*  inLink)=0;	

	// ****************************************************************************
	//								GetExists
	// 
	/// Returns true if the tree element is marked as visible. Note that this function
	/// does not take into account the groups that could contains this tree element. To
	/// determine the visibility of a tree element you should use Exists() instead.
	/// 
	virtual boolean  MCCOMAPI GetVisibilityFlag() const = 0;

	// ****************************************************************************
	//								SetVisibilityFlag
	// 
	/// Sets whether the tree element is visible. (this parameter is animated)
	/// 
	/// \param inVisible  True if the tree element is visible.
	/// 
	virtual void 	 MCCOMAPI SetVisibilityFlag(boolean inVisible) = 0;

	// ****************************************************************************
	//								Exists
	// 
	/// Returns true if the tree element is visible in the rendering. This function
	/// checks the visibility status of the groups containing this tree element.
	/// 
	virtual boolean MCCOMAPI Exists() const = 0;
	

	// ****************************************************************************
	//								GetIsShown
	// 
	/// Returns true if the tree element is visible in the 3D view.
	/// 
	virtual boolean	 MCCOMAPI GetIsShown				() const = 0;
	
	// ****************************************************************************
	//								SetIsShown
	// 
	/// Sets whether the tree element is visible in the 3D view.
	/// 
	/// \param inIsShown  True if the tree element is visible in the 3D view.
	/// 
	virtual void	 MCCOMAPI SetIsShown				(boolean inIsShown) = 0;

	// ****************************************************************************
	//								GetShadowCasting
	// 
	/// Returns true if this tree element can cast shadows.
	/// 
	virtual	boolean	 MCCOMAPI GetShadowCasting			() = 0;

	// ****************************************************************************
	//								SetShadowCasting
	// 
	/// Sets whether this tree element can cast shadows.
	/// 
	/// \param shadowCasting  True if this tree element can cast shadows.
	/// 
	virtual	MCCOMErr MCCOMAPI SetShadowCasting			(boolean shadowCasting) = 0;

	// ****************************************************************************
	//								GetReceiveShadow
	// 
	/// Returns true if this tree element can receive shadows.
	/// 
	virtual	boolean	 MCCOMAPI GetReceiveShadow			() = 0;
	
	// ****************************************************************************
	//								SetReceiveShadow
	// 
	/// Sets whether this tree element can receive shadows.
	/// 
	/// \param receiveShadow  True if this tree element can receive shadows.
	/// 
	virtual	void	 MCCOMAPI SetReceiveShadow			(boolean receiveShadow) = 0;

	// ****************************************************************************
	//								GetAnimateTree
	// 
	/// True if the tree element can be animated.
	/// 
	virtual boolean	 MCCOMAPI GetAnimateTree			() const = 0;
	
	// ****************************************************************************
	//								SetAnimateTree
	// 
	/// Sets whether a tree element can be animated.
	/// 
	/// \param animateTree  True if this tree element can be animated.
	///
	virtual void	 MCCOMAPI SetAnimateTree			(boolean animateTree) = 0;

	// ****************************************************************************
	//								ClearInstanceCache
	// 
	/// Clears the renderable cache that is stored at the Tree Element level
	/// 
	virtual void	 MCCOMAPI ClearInstanceCache		() = 0;

	// ****************************************************************************
	//								IsExcludedFromTripleBuffer
	// 
	/// Returns true if the tree is to be excluded from the triple buffer 
	/// (because it is in the selection or because of side effects like IK or Skinning)
	/// If lookAtParents is true, this call will return true if one of the tree's parents is excluded from the TBuf.
	/// 
	/// \param lookAtParents  
	/// 
	virtual boolean	 MCCOMAPI IsExcludedFromTripleBuffer(boolean lookAtParents)= 0;

	// ****************************************************************************
	//								IsConstrained
	// 
	/// Returns true if the tree has a constraint.
	/// 
	virtual boolean  MCCOMAPI IsConstrained				() const = 0;

	// ****************************************************************************
	//								IsOperationAllowed
	// 
	/// Return kOpAllowed if the given operation is allowed
	/// otherwise return the reason why it is not allowed or after which operation it could be allowed
	/// Some operations are blocked in certain states and should not be performed if this methods says so 
	/// (or you could get weird results).
	/// 
	/// \param operation  The operation you plan on doing on the tree.
	/// 
	virtual uint32  MCCOMAPI IsOperationAllowed(const ETreeOperation operation) = 0;

	// ****************************************************************************
	//								GetSelectableInterface
	// 
	/// Returns the selectable interface supported by the tree.	
	/// 
	virtual ISelectableObject* MCCOMAPI GetSelectableInterface() = 0;


	// ****************************************************************************
	//								DoOpenClose
	// 
	/// Use this call to open or close a tree that has children
	/// 
	/// \param openIt  True if the tree should be open.
	/// 
	virtual MCCOMErr MCCOMAPI DoOpenClose(boolean openIt) = 0;
	
	// ****************************************************************************
	//								OpenClose
	// 
	/// Low level call. Use DoOpenClose() instead.
	/// 
	virtual MCCOMErr MCCOMAPI OpenClose(boolean openIt) = 0;

	// ****************************************************************************
	//								GetIKModifierIndex
	// 
	/// Returns the index of the (first) IK modifier on the tree, or kUnusedIndex if there is none
	/// 
	virtual uint32	 MCCOMAPI GetIKModifierIndex() const = 0;

	// ****************************************************************************
	//								GetIKTerminatorIndex
	// 
	/// \param outExcludeFromChain	When there is a terminator, tells if the tree should be excluded from the chain
	/// Returns the index of the (first) IK terminator on the tree, or kUnusedIndex if there is none
	/// 
	virtual uint32	 MCCOMAPI GetIKTerminatorIndex(boolean* outExcludeFromChain) const = 0;

	// ****************************************************************************
	//								GetTreePermanentID
	// 
	/// Returns the tree PermanentID ( 0 == no ID )
	/// 
	virtual	TTreeId	MCCOMAPI GetTreePermanentID()=0;

	// ****************************************************************************
	//								SetTreePermanentID
	// 
	/// Sets the tree PermanentID ( if tree has no ID )
	/// 
	virtual	void	MCCOMAPI SetTreePermanentID( TTreeId )=0;

	// ****************************************************************************
	//								GetTreeIDPath
	// 
	/// Returns the tree absolute Path
	/// 
	virtual	TTreeIdPath	MCCOMAPI GetTreeIDPath() const=0;

	// ****************************************************************************
	//								ResetTreePermanentID
	// 
	/// Reset the tree PermanentID to 0.
	/// <P><B>Warning</B>: the tree permanentID will be lost. This method should be used causiously.</P>
	/// 
	virtual	void	MCCOMAPI ResetTreePermanentID()=0;

	// ****************************************************************************
	//								SetMasterGroup
	// 
	/// Sets the master groups that contains the tree, must be called each time a
	/// tree is inserted in a scene.
	/// 
	/// \param masterGroup  A pointer to the masterGroup containing the tree, NULL if the tree is outside a scene
	/// \param invalidateCache  If True will invalidate all the caches.
	/// 
	virtual void MCCOMAPI SetMasterGroup(I3DShMasterGroup* masterGroup, boolean invalidateCache=true)=0;

	// ****************************************************************************
	//								GetMasterGroup
	// 
	/// Returns a pointer to the masterGroup that contains this tree
	/// 
	virtual I3DShMasterGroup* MCCOMAPI GetMasterGroup()=0;

	// ****************************************************************************
	//								GetName
	// 
	/// Returns a reference to the tree's name.
	/// 
	virtual const TMCString& MCCOMAPI GetName() const  = 0;

	// ****************************************************************************
	//								GetThisSelectable
	// 
	/// Trees are selectable objects.
	/// 
	virtual ISelectableObject* MCCOMAPI GetThisSelectable() = 0;

	// ****************************************************************************
	//								PostSelectionChange
	// 
	/// Called to notify the scene that a tree has been added or removed from the
	/// selection..
	/// 
	/// \param invalidateDeformedGeometry True if the deformer should be invalidated.  
	/// 
	virtual void	 MCCOMAPI PostSelectionChange			(boolean invalidateDeformedGeometry = false) = 0;

	/// Returns true if the tree can import the given data on the given instance
	virtual boolean	 MCCOMAPI CanImportData			(I3DImportData*	inImportData) = 0;

	/// Imports the given data on the tree, returns false if the import was aborted
	virtual boolean	 MCCOMAPI ImportData			(I3DImportData* inImportData) = 0;

	///Sets the prefered scalingLockmode on the tree
	virtual void				MCCOMAPI SetScalingLockMode	(const EScalingLockMode&	inMode) = 0;

	///Gets the prefered scalingLockmode for this tree
	virtual EScalingLockMode	MCCOMAPI GetScalingLockMode	() const = 0;


	//******************************* Conforming *********************************************

	///Conforms a tree to another
	/// \param target relative path to the object this tree will be conformed to (both are in the same mastergroup)
	virtual void		MCCOMAPI ConformTo				( const TConformingInfo& inInfo) = 0;

	///returns invalid path when object is not comformed
	virtual void		MCCOMAPI GetConformingInfo		( TConformingInfo& outInfo) const = 0;

	virtual boolean		MCCOMAPI IsConformed			() const = 0;

	///Removes the conforming link
	virtual void		MCCOMAPI UnConform				() = 0;

	virtual I3DShTreeElement* MCCOMAPI GetConformTarget () const = 0;


	///Call only when you REALLY changed the transform as this will invalidate the skining, conforming...
	virtual void		MCCOMAPI CallTransformHasChanged() const = 0;

			// ****************************************************************************
	//								GetSubtreeBoundingBox2
	// 
	/// Returns the bounding box of the entire subtree
	/// 
	/// \param bbox        The bounding box.
	/// \param transform   local transform to apply to subtrees.
	/// \param deformMode  The deformation mode (see ETreeDeformBBoxModes).
	/// \param rendering   True if you want a bounding box for rendering or just for previewing
	/// \param withAllHelperObject  False if you want a bounding box without all helper objects (without Magnets for example)
	/// 
	virtual void	 MCCOMAPI GetSubtreeBoundingBox2		(TBBox3D& bbox, TTransform3D& transform, ETreeDeformBBoxModes deformMode, boolean rendering=true, boolean withAllHelperObject=true) = 0; 

	virtual int16	 MCCOMAPI WhatIAm() const = 0;

};

/// \}

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

struct RelinkTreeElementInfo : public TMCObject
{
	TMCCountedPtr<I3DShTreeElement> fTreeElement;		// the I3DShTreeElement to be relinked
	TMCCountedPtr<I3DShTreeElement> fOldTop;			// fTreeElement's old fTop
	TMCCountedPtr<I3DShTreeElement> fOldRight;			// fTreeElement's old fRight
	TGlobalTreeTransform			fGlobalTransform;	// fTreeElement's old global transform
};


/// \addtogroup ShellInterface
/// \{

// ****************************************************************************
//								GetTreeElement
// 
/// This interface can be used to get to the Tree Element for extensions that
/// are attached to a Tree Element, but are not a Tree Element. For example,
/// a Light Source may need to get to its Tree Element, or even just to its
/// I3DShLightsource shell interface. Unfortunately, its "Controlling Unknown"
/// is NOT the Tree Element, it is a IComponentAnim that is a member of the
/// I3DShLightsource / I3DShTreeElement object. So it will never reply to a
/// QueryInterface(IID_I3DShTreeElement).
///
///	Use this interface in this situation.
///
/// This interface is supported by :
///
///			- Cameras (I3DExCamera)
///			- Light Sources (I3DExLightsource)
///			- Gels (I3DExLightsourceGel)
///			- Modifiers (I3DExModifier)
///			- Contraints (I3DExConstraint)
///			- Data Components (I3DExDataComponent)
///			- Shadow Features (I3DExShadowFeature)
///			- Reflection Features (I3DExReflectionFeature)
///			- Refraction Features (I3DExRefractionFeature)
///
struct I3DShTreeElementMember : public IMCUnknown
{
	// ****************************************************************************
	//								GetTreeElement
	// 
	/// Returns a pointer to the tree element that owns this object.
	/// 
	/// \param outTree  A pointer to the tree element that owns this object.
	/// 
	virtual void	 MCCOMAPI GetTreeElement(I3DShTreeElement** outTree)=0;

	// ****************************************************************************
	//								SetTreeElement
	// 
	/// Set the tree element that owns this object. WARNING: this function should
	/// not be used. The tree element is set by the application.
	/// 
	/// \param inTree	A pointer to the tree element that owns this object.
	/// 
	virtual void	 MCCOMAPI SetTreeElement(I3DShTreeElement* inTree)=0;
};

/// \}

#endif