//================================================================
// E3D
//
// PolyGroups and Polygons
//
// AUTHOR:  Gabor Nagy
// DATE:    2016-Nov-23 04:49:40
//
// Copyright (C) 1996-2026 by Gabor Nagy. All rights reserved.
//================================================================
#ifndef _E3D_PolygonEditing_h
#define _E3D_PolygonEditing_h


#ifndef _E3D_Polygon_h
#include <E3D/Polygon.h>
#endif



//========================================================================================
// Allocate VertexNodes for a Polygon
//
// Arguments
//  PPolygon    Pointer to the Polygon structure
//  PCount      The number of VertexNodes to allocate
//
// Description
//  Allocates VertexNodes for the given Polygon and initializes these fields:<PRE>
// PPolygon->NumOfVertices = 0;                    // Number of VertexNodes minus contour separators
// PPolygon->NumOfExteriorVertices = 0;            // Number of Vertices in the exterior contour
// PPolygon->NumOfVertexNodes = PCount;            // Total number of VertexNodes</PRE>
//
// Return value
//  A pointer to the allocated array of VertexNodes or NULL in case of an error
//
// See also
//  E3dPolygon_AddVertexNode
//========================================================================================
static inline E3dVertexNode* E3dPolygon_VertexNodesNew(E3dPolygon* PPolygon, const E3dVertexNodeSize PVertexNodeSize, const EIndex PCount)
{
	E3dVertexNode*  LVertexNodes;EMallocT(E3dVertexNode*, PVertexNodeSize * PCount, LVertexNodes);if(LVertexNodes)
	{
		PPolygon->NumOfVertices = 0;
		PPolygon->NumOfExteriorVertices = 0;
		PPolygon->NumOfVertexNodes = PCount;
	}
	PPolygon->VertexNodes = LVertexNodes;

	return(LVertexNodes);
}


static inline void E3dPolygon_CopyCore(const E3dPolygon* PSPolygon, E3dPolygon* PDPolygon)
{
#define _CopyField(m) PDPolygon->m = PSPolygon->m
	_CopyField(Normal);
	_CopyField(Center);
	_CopyField(Flags);
#undef _CopyField
}


//========================================================================================
// Copy a Polygon
//
// Arguments
//  PSPolygon          Pointer to the source Polygon
//  PVertexNodeSize    Size of Polygon VertexNode in bytes
//  PDPolygon          Pointer to the destination Polygon
//
// Description
//  Deep-copies a Polygon. This function must be used for copying Polygons (rather than just memcpy()),
//  as Polygons may have dynamically allocated arrays, such as VertexNodes or ITriangles.
//========================================================================================
static inline void E3d_PolygonCopy(const E3dPolygon* PSPolygon, const E3dVertexNodeSize PVertexNodeSize, E3dPolygon* PDPolygon)
{
	E3dPolygon_CopyCore(PSPolygon, PDPolygon);

#define _CopyField(m) PDPolygon->m = PSPolygon->m
	_CopyField(ITriangles_Count);

	const EIndex  LVNum = PSPolygon->NumOfVertexNodes;if(LVNum > 0)
	{
		EMallocT(E3dVertexNode*, PVertexNodeSize * LVNum, PDPolygon->VertexNodes);if(PDPolygon->VertexNodes)
		{
			memcpy(PDPolygon->VertexNodes, PSPolygon->VertexNodes, PVertexNodeSize * LVNum);_CopyField(NumOfVertexNodes);
			_CopyField(NumOfVertices);
			_CopyField(NumOfExteriorVertices);

			if(PSPolygon->ITriangles)
			{
				const EIndex  LN = PSPolygon->ITriangles_Count;ENewN(LN, PDPolygon->ITriangles);

				EIndex  LC = 0;const E3dITriangle*  LSITriangle = PSPolygon->ITriangles;E3dITriangle*  LDITriangle = PDPolygon->ITriangles;for(;LC < LN;LC++)
				{
					LDITriangle->VertexNodes[0] = LSITriangle->VertexNodes[0];
					LDITriangle->VertexNodes[1] = LSITriangle->VertexNodes[1];
					LDITriangle->VertexNodes[2] = LSITriangle->VertexNodes[2];
					LSITriangle++;LDITriangle++;
				}
			}
			else PDPolygon->ITriangles = NULL;
		}
		else
		{
			PDPolygon->VertexNodes = NULL;
			PDPolygon->ITriangles  = NULL;
		}
	}
	else
	{
		PDPolygon->VertexNodes = NULL;
		PDPolygon->ITriangles  = NULL;
	}
#undef _CopyField
}


#if defined (__cplusplus) && (!(defined (__CPLUSLIBS)))
}	// Close scope of 'extern "C"' declaration
#endif

#endif	// _E3D_PolygonEditing_h
