//*****************************************************************************
/*!
   \file xsi_triangle.h
   \brief Triangle and CTriangleRefArray class declarations.

   © Copyright 1998-2002 Avid Technology, Inc. and its licensors. All rights
   reserved. This file contains confidential and proprietary information of
   Avid Technology, Inc., and is subject to the terms of the SOFTIMAGE|XSI
   end user license agreement (or EULA).
*/
//*****************************************************************************

#if (_MSC_VER > 1000) || defined(SGI_COMPILER)
#pragma once
#endif

#ifndef __XSITRIANGLE_H__
#define __XSITRIANGLE_H__

#include <xsi_siobject.h>
#include <xsi_math.h>
#include <xsi_vertexcolor.h>
#include <xsi_uv.h>
#include <xsi_longarray.h>

namespace XSI {

class CTriangleRefArray;
class CTriangleVertexRefArray;

//*****************************************************************************
/*! \class Triangle xsi_triangle.h
	\brief Represents a triangle generated by a surface tesselation.

	\sa CTriangleRefArray, Triangle, Geometry

	\eg This example shows how to print out the point positions and the triangle
		data for a polygon mesh.

	\code
		using namespace XSI;
		using namespace MATH;

		Application app;
		Model root = app.GetActiveSceneRoot();

		X3DObject myCube;
		root.AddGeometry( L"Cube", L"MeshSurface", L"", myCube );

		Geometry geom(myCube.GetActivePrimitive().GetGeometry());
		CPointRefArray points(geom.GetPoints());
		CVector3Array positions( geom.GetPoints().GetPositionArray() );

		LONG ulCount = positions.GetCount();
		app.LogMessage( L"Object: " + myCube.GetName() );
		app.LogMessage( L"Points: " + CValue((LONG)ulCount).GetAsText() );

		// Print out the x,y,z positions of each point
		for (LONG i=0; i<ulCount; ++i )
		{
			app.LogMessage(
				CValue(positions[i].GetX()).GetAsText() + L"," +
				CValue(positions[i].GetY()).GetAsText() + L"," +
				CValue(positions[i].GetZ()).GetAsText() );
		}

		// Print out the point indices for each triangle
		CTriangleRefArray triangles(geom.GetTriangles());
		CLongArray indices( triangles.GetIndexArray() );

		app.LogMessage( L"Triangles: " + CValue(triangles.GetCount()).GetAsText());

		ulCount = indices.GetCount();
		for (i=0; i<ulCount; i += 3 )
		{
			app.LogMessage( CValue(indices[i]).GetAsText() + L"," +
				CValue(indices[i+1]).GetAsText() + L"," +
				CValue(indices[i+2]).GetAsText() );
		}
	\endcode
*/
//*****************************************************************************

class SICPPSDKDECL Triangle : public SIObject
{
public:
	/*! Default constructor. */
	Triangle();

	/*! Default destructor. */
	~Triangle();

	/*! Constructor.
	\param in_ref constant reference object.
	*/
	Triangle(const CRef& in_ref);

	/*! Copy constructor.
	\param in_obj constant class object.
	*/
	Triangle(const Triangle& in_obj);

	/*! Returns true if a given class type is compatible with this API class.
	\param in_ClassID class type.
	\return true if the class is compatible, false otherwise.
	*/
	bool IsA( siClassID in_ClassID) const;

	/*! Returns the type of the API class.
	\return The class type.
	*/
	siClassID GetClassID() const;

	/*! Creates an object from another object. The newly created object is set to
	empty if the input object is not compatible.
	\param in_obj constant class object.
	\return The new Triangle object.
	*/
	Triangle& operator=(const Triangle& in_obj);

	/*! Creates an object from a reference object. The newly created object is
	set to empty if the input reference object is not compatible.
	\param in_ref constant class object.
	\return The new Triangle object.
	*/
	Triangle& operator=(const CRef& in_ref);

	/*! Returns an array of neighbor Triangle objects for this triangle. The array may
	contain empty objects whose represent the unexisting neighbour triangles.
	\return Array of neighbor Triangle objects.
	*/
	CTriangleRefArray GetNeighborTriangles() const;

	/*! Returns an array of TriangleVertex objects for this triangle.
	\return Array of TriangleVertex objects.
	*/
	CTriangleVertexRefArray GetPoints() const;

	/*! Returns the index of this Triangle object in its geometry.
	\return The Triangle index.
	*/
	LONG GetIndex() const;

	/*! Returns the index of the polygon from which this Triangle comes.
	\return The Polygon index.
	*/
	LONG GetPolygonIndex() const;

	/*! Returns an array of CVector3 objects representing the position of all
	TriangleVertex objects of this Triangle object.
	\return Array of CVector3 objects.
	*/
	MATH::CVector3Array GetPositionArray() const;

	/*! Returns the TriangleVertex normals for this Triangle as an array of CVector3 objects.
	Triangle objects that belong to the same polygon will have the same normal values.
	\return Array of CVector3 objects.
	*/
	MATH::CVector3Array GetPolygonNodeNormalArray() const;

	/*! Returns the TriangleVertex colors for this Triangle as an array of VertexColor objects.
	\return Array of CVertexColor objects.
	*/
	CVertexColorArray GetColorArray() const;

	/*! Returns the TriangleVertex UV coordinates for this Triangle as an array of CUV objects.
	\return Array of CUV objects.
	*/
	CUVArray GetUVArray() const;

	/*! Returns the TriangleVertex indices for this Triangle.
	\return Array of indices.
	*/
	CLongArray GetIndexArray() const;

	private:
	Triangle * operator&() const;
	Triangle * operator&();
};

//*****************************************************************************
/*! \class CTriangleRefArray xsi_triangle.h
	\brief An array of Triangle objects that represents all the triangles in the Geometry.

	\warning This specialized array is returned by Geometry::GetTriangles, it is not meant
		to be created and modified in user-defined functions. If you want to add and remove
		arbitrary items to a collection, you must use a CRefArray instead.

	\sa Geometry::GetTriangles, Triangle

	\eg
	\code
		using namespace XSI;
		using namespace MATH;

		Application app;
		Model root = app.GetActiveSceneRoot();

		X3DObject myCube;
		root.AddGeometry( L"Cube", L"MeshSurface", L"", myCube );

		CTriangleRefArray triangles(myCube.GetActivePrimitive().GetGeometry().GetTriangles());
		CVector3Array normals( triangles.GetPolygonNodeNormalArray() );

		for (LONG i=0; i<normals.GetCount(); ++i )
		{
			app.LogMessage( CValue(normals[i].GetX()).GetAsText() + L"," +
				CValue(normals[i].GetY()).GetAsText() + L"," +
				CValue(normals[i].GetZ()).GetAsText() );
		}
	\endcode
 */
//*****************************************************************************
class SICPPSDKDECL CTriangleRefArray : public CRefArray
{
	public:
	CTriangleRefArray();

	/*! Copy constructor.
	\param in_array constant CTriangleRefArray reference object.
	*/
	CTriangleRefArray( const CTriangleRefArray& in_array );

	/*! Returns a Triangle object at a specified index in the array.
	\param in_index The index of the Triangle.
	\return The Triangle object.
	*/
	CRef GetItem( LONG in_index ) const;

	/*! Returns the Triangle object in the array matching the specified name.
	\param in_name The name of the Triangle.
	\return The Triangle object.
	*/
	CRef GetItem( const CString& in_name ) const;

	/*! Returns the number of Triangle objects in the array.
	\return The number of Triangle objects.
	*/
	LONG GetCount() const;

	/*! Returns true if this array is a valid object or false otherwise.
	\return true if valid, false otherwise.
	*/
	bool IsValid() const;

	/*! Returns the TriangleVertex positions for all triangles of this array.
	\return Array of CVector3 objects.
	*/
	MATH::CVector3Array GetPositionArray() const;

	/*! Returns the TriangleVertex normals for all triangles of this array.
	\return Array of CVector3 objects.
	*/
	MATH::CVector3Array GetPolygonNodeNormalArray() const;

	/*! Returns the TriangleVertex colors for all triangles of this array.
	\return Array of CVertexColor objects.
	*/
	CVertexColorArray GetColorArray() const;

	/*! Returns the TriangleVertex UV coordinates for all triangles of this array.
	\return Array of CUV objects.
	*/
	CUVArray GetUVArray() const;

	/*! Returns the TriangleVertex indices for each triangle of this array.
	\return Array of indices.
	*/
	CLongArray GetIndexArray() const;

	private:
	void* m_ptr;
};


};

#endif // __XSITRIANGLE_H__
