/////////////////////////////////////////////////////////////
// CINEMA SDK : OBJECT PLUGINS														 //
/////////////////////////////////////////////////////////////
// VERSION    : CINEMA 4D																	 //
/////////////////////////////////////////////////////////////
// (c) 1989-2002 MAXON Computer GmbH, all rights reserved	 //
/////////////////////////////////////////////////////////////

// generator object example (with input objects)

#include "c4d.h"
#include "c4d_symbols.h"

class TriangulateData : public ObjectData
{
	private:
		LineObject *PrepareSingleSpline(PluginObject *generator, BaseObject *op, Matrix *ml, HierarchyHelp *hh, Bool *dirty);
		void Transform(PointObject *op, const Matrix &m);

	public:
		virtual BaseObject* GetVirtualObjects(PluginObject *op, HierarchyHelp *hh);

		static NodeData *Alloc(void) { return gNew TriangulateData; }
};

LineObject *TriangulateData::PrepareSingleSpline(PluginObject *generator, BaseObject *op, Matrix *ml, HierarchyHelp *hh, Bool *dirty)
{
	LineObject *lp  = (LineObject*)GetVirtualLineObject(op,hh,op->GetMl(),FALSE,FALSE,ml,dirty);
	if (!lp || lp->GetPointCount()<1 || !lp->GetLine()) return NULL;
	lp->Touch(); 
	generator->AddDependence(hh,lp);
	return lp;
}

void TriangulateData::Transform(PointObject *op, const Matrix &m)
{
	Vector	*padr=op->GetPoint();
	LONG		pcnt=op->GetPointCount(),i;
	
	for (i=0; i<pcnt; i++)
		padr[i]*=m;
	
	op->Message(MSG_UPDATE);
}

BaseObject *TriangulateData::GetVirtualObjects(PluginObject *op, HierarchyHelp *hh)
{
	if (!op->GetDown()) return NULL;

	LineObject		*contour=NULL;	
	PolygonObject *pp=NULL;
	Bool					dirty=FALSE;
	Matrix				ml;

	op->NewDependenceList();
	contour=PrepareSingleSpline(op,op->GetDown(),&ml,hh,&dirty);
	if (!dirty) dirty = op->CheckCache(hh);					
	if (!dirty) dirty = op->IsDirty(DIRTY_DATA);		
	if (!dirty) dirty = !op->CompareDependenceList();
	if (!dirty) return op->GetCache(hh);

	if (!contour) return NULL;

	if (hh->GetVFlags()&VFLAG_POLYGONAL)
		pp = contour->Triangulate(0.0,hh->GetThread());
	else
		pp = PolygonObject::Alloc(0,0);

	if (!pp) return NULL;

	pp->SetPhong(TRUE,FALSE,0.0);
	Transform(pp,ml);
	pp->SetName(op->GetName());
	
	if (hh->GetVFlags()&VFLAG_ISOPARM)
	{
		pp->SetIsoparm((LineObject*)contour->GetClone(COPY_NO_HIERARCHY,NULL));
		Transform(pp->GetIsoparm(),ml);
	}

	return pp;
}

// be sure to use a unique ID obtained from www.plugincafe.com
#define ID_TRIANGULATEOBJECT 1001159

Bool RegisterTriangulate(void)
{
	// decide by name if the plugin shall be registered - just for user convenience
	String name=GeLoadString(IDS_TRIANGULATE); if (!name.Content()) return TRUE;
	return RegisterObjectPlugin(ID_TRIANGULATEOBJECT,name,OBJECT_GENERATOR|OBJECT_INPUT,TriangulateData::Alloc,"","triangulate.tif","triangulate_small.tif",0);
}
