
/**********************************************************
 *                                                        *
 *                   Morphing                             *
 *                                                        *
 * This file contains the function to deal with           *
 * geometric and physical objects                         *
 *                                                        *
 * Author : Ubi China - Alexis Vaisse                     *
 *                                                        *
 **********************************************************/

//XB
#define D_3dData_StructureDefine
#define	D_ObjsTbls_Define
#define PO_FRIEND
#include "ACP_base.h"
#include "GAM/ToolsCPA.h"
#include "gam.h"

#include "GMT.h"
#include "GEO.h"
#include "GLI.h"
#include "PCS.h"
#include "COL.h"

#include "PO.h"

#define HieFriend
#include "SPO.h"

#include "mec.h"
#include "prt.h"
#include "fil.h"
#include "snd.h"
//#include "fon.h"
#include "ipt.h"
#define ENV_FRIEND
//#include "env.h"
//#include "srf.h"
#include "sct.h"
// ANNECY - MT 08/05/98 {
#include "TMP.h"
// END ANNECY MT }

#include "x:/cpa/tempgrp/gliglou/multidrv/inc/visus_st.h"


#include "mor.h"

/* Macro */

// ANNECY - MT 08/05/98 {
#define GEO_M_DuplicateElement( Elem )                                                                                 \
	 MMG_fn_vAddMemoryInfo (MMG_C_lTypeMOR , MMG_C_lSubTypeElement , 0);											   \
     MOR_M_pvMalloc (hObject2 -> d_stListOfElements [hElement] , void * , sizeof( Elem ) );							   \
     if (hObject2 -> d_stListOfElements [hElement] == NULL)  return(NULL);                                             \
     hObject2 -> d_xListOfElementsTypes [hElement] = hObject1 -> d_xListOfElementsTypes [hElement];                    \
     memcpy (hObject2 -> d_stListOfElements [hElement] , hObject1 -> d_stListOfElements [hElement] , sizeof (Elem));
// END ANNECY MT }


/*====================================================================================
Name: MOR_fn_xCopyGeometricObjectForMorph
Goal: Make a copy of an existing geometric object. This copy will be used as morphed object
Code: Qi Zeyu 
=====================================================================================*/
ACP_tdxHandleOfObject MOR_fn_xCopyGeometricObjectForMorph (GEO_tdstGeometricObject * hObject1)
{
	ACP_tdxIndex           xNbPoints;
	ACP_tdxIndex           xNbElements;
	ACP_tdxHandleOfObject  hObject2;
	ACP_tdxHandleOfElement hElement;

	xNbPoints   = hObject1 -> xNbPoints;
	xNbElements = hObject1 -> xNbElements;
// ANNECY - MT 08/05/98 {
	GEO_vCreateTMPGeometricObject (& hObject2 , xNbPoints , xNbElements);
// END ANNECY MT }
	
	if (hObject2 == NULL) return hObject2;

	// copy the list of the points.
	memcpy(hObject2->d_stListOfPoints, hObject1->d_stListOfPoints, sizeof(MTH3D_tdstVector)*xNbPoints);

	// copy the list of the normals.
	memcpy(hObject2->d_stListOfPointsNormals, hObject1->d_stListOfPointsNormals, sizeof(MTH3D_tdstVector)*xNbPoints);

	// copy the list of element types
	memcpy(hObject2->d_xListOfElementsTypes, hObject1->d_xListOfElementsTypes, sizeof(ACP_tdxIndex)* xNbElements);

    // copy the elements
	for(hElement=0 ; hElement<xNbElements ; hElement++)
    {
		switch (hObject1 -> d_xListOfElementsTypes [hElement])
        {
			case GEO_C_xElementNULL:                                                                            break;
			case GEO_C_xElementPoints:              GEO_M_DuplicateElement( GEO_tdstElementPoints ) ;           break;
			case GEO_C_xElementLines:               GEO_M_DuplicateElement( GEO_tdstElementLines ) ;            break;
			case GEO_C_xElementFaceMapDescriptors : GEO_M_DuplicateElement( GEO_tdstElementFaceMapDescriptors); break;
			case GEO_C_xElementSprites:             GEO_M_DuplicateElement( GEO_tdstElementSprite ) ;           break;
			case GEO_C_xElementSpheres:             GEO_M_DuplicateElement( GEO_tdstElementSpheres ) ;          break;
			case GEO_C_xElementAlignedBoxes:        GEO_M_DuplicateElement( GEO_tdstElementAlignedBoxes ) ;     break;
			case GEO_C_xElementCones:               GEO_M_DuplicateElement( GEO_tdstIndexedCone ) ;             break;
			case GEO_C_xElementTMeshes:             GEO_M_DuplicateElement( GEO_tdstElementTMeshes ) ;          break;
			case GEO_C_xElementIndexedTriangles :   GEO_M_DuplicateElement( GEO_tdstElementIndexedTriangles ) ; break;
		}
	}

	return hObject2;
}

/*====================================================================================
Name: MOR_fn_vDeleteGeometricObject
Goal: Delete a geometric object
=====================================================================================*/
void MOR_fn_vDeleteGeometricObject (ACP_tdxHandleOfObject *p_hObj )
{
	long                      lElementCounter;
	GEO_tdstGeometricObject * p_hObject ;

    p_hObject= *(GEO_tdstGeometricObject **)p_hObj ;

    for (lElementCounter = 0 ; lElementCounter < p_hObject -> xNbElements; lElementCounter ++ )
        switch (p_hObject -> d_xListOfElementsTypes [lElementCounter ] )
        {
// ANNECY - MT 08/05/98 {
             case GEO_C_xElementNULL:
				         break;
             case GEO_C_xElementPoints:
		         //MOR_M_Free( ((GEO_tdstElementPoints * )(p_hObject -> d_stListOfElements[lElementCounter ])) -> d_xListOfPointIndex);
		         MOR_M_Free( p_hObject -> d_stListOfElements[lElementCounter ] );
				         break;
             case GEO_C_xElementLines:
		         //MOR_M_Free( ((GEO_tdstElementLines * )(p_hObject -> d_stListOfElements[lElementCounter ]))  -> d_stListOfLineIndex);
		         //MOR_M_Free( ((GEO_tdstElementLines * )(p_hObject -> d_stListOfElements[lElementCounter ]))  -> d_hListOfLinesMaterial);
		         //MOR_M_Free( ((GEO_tdstElementLines * )(p_hObject -> d_stListOfElements[lElementCounter ]))  -> d_stListOfLinesReceivedLightIntensity);
		         MOR_M_Free( ((GEO_tdstElementLines * )(p_hObject -> d_stListOfElements[lElementCounter ])) );
		                 break;
             case GEO_C_xElementFaceMapDescriptors :
		         //MOR_M_Free( ((GEO_tdstElementFaceMapDescriptors * )(p_hObject -> d_stListOfElements[lElementCounter ]))  -> d_stListOfFacesNormals);
		         //MOR_M_Free( ((GEO_tdstElementFaceMapDescriptors * )(p_hObject -> d_stListOfElements[lElementCounter ]))  -> d_stListOfFacesReceivedLightIntensity);
		         //MOR_M_Free( ((GEO_tdstElementFaceMapDescriptors * )(p_hObject -> d_stListOfElements[lElementCounter ]))  -> d_stListOfFacesQuadrupled);
		         MOR_M_Free( ((GEO_tdstElementFaceMapDescriptors * )(p_hObject -> d_stListOfElements[lElementCounter ]))  );
                         break;
             case GEO_C_xElementSprites:
		         //MOR_M_Free( ((GEO_tdstElementSprite * )(p_hObject -> d_stListOfElements[lElementCounter ]))  -> d_stListOfSprites);
		         MOR_M_Free( ((GEO_tdstElementSprite * )(p_hObject -> d_stListOfElements[lElementCounter ]))  );
                         break;
             case GEO_C_xElementSpheres: 
		         //MOR_M_Free( ((GEO_tdstElementSpheres * )(p_hObject -> d_stListOfElements[lElementCounter ])) -> d_stListOfSpheres );
		         MOR_M_Free( ((GEO_tdstElementSpheres * )(p_hObject -> d_stListOfElements[lElementCounter ])) );
                         break;
             case GEO_C_xElementAlignedBoxes: 
		         //MOR_M_Free( ((GEO_tdstElementAlignedBoxes * )(p_hObject -> d_stListOfElements[lElementCounter ])) -> d_stListOfAlignedBoxes);
		         MOR_M_Free( ((GEO_tdstElementAlignedBoxes * )(p_hObject -> d_stListOfElements[lElementCounter ])) );
                         break;
             case GEO_C_xElementCones: 
		         //MOR_M_Free( ((GEO_tdstElementCones * )(p_hObject -> d_stListOfElements[lElementCounter ])) -> d_stListOfCones);
		         MOR_M_Free( ((GEO_tdstElementCones * )(p_hObject -> d_stListOfElements[lElementCounter ])) );
                         break;
             case GEO_C_xElementTMeshes:
		         //MOR_M_Free( ((GEO_tdstElementTMeshes * )(p_hObject -> d_stListOfElements[lElementCounter ])) -> d_stListOfMeshAtoms);
		         //MOR_M_Free( ((GEO_tdstElementTMeshes * )(p_hObject -> d_stListOfElements[lElementCounter ])) -> d_stListOfFacesNormals);
		         //MOR_M_Free( ((GEO_tdstElementTMeshes * )(p_hObject -> d_stListOfElements[lElementCounter ])) -> d_stListOfFacesReceivedLightIntensity);
		         //MOR_M_Free( ((GEO_tdstElementTMeshes * )(p_hObject -> d_stListOfElements[lElementCounter ])) -> d_stListOfElementUV);
		         MOR_M_Free( ((GEO_tdstElementTMeshes * )(p_hObject -> d_stListOfElements[lElementCounter ])) );
                         break;
             case GEO_C_xElementIndexedTriangles :
		         //MOR_M_Free( ((GEO_tdstElementIndexedTriangles * )(p_hObject -> d_stListOfElements[lElementCounter ])) -> d_stListOfFacesTripled);
		         //MOR_M_Free( ((GEO_tdstElementIndexedTriangles * )(p_hObject -> d_stListOfElements[lElementCounter ])) -> d_stListOfFacesTripledIndexUV);
		         //MOR_M_Free( ((GEO_tdstElementIndexedTriangles * )(p_hObject -> d_stListOfElements[lElementCounter ])) -> d_stListOfFacesNormals);
		         //MOR_M_Free( ((GEO_tdstElementIndexedTriangles * )(p_hObject -> d_stListOfElements[lElementCounter ])) -> d_stListOfFacesReceivedLightIntensity);
		         //MOR_M_Free( ((GEO_tdstElementIndexedTriangles * )(p_hObject -> d_stListOfElements[lElementCounter ])) -> d_stListOfElementUV);
		         MOR_M_Free( ((GEO_tdstElementIndexedTriangles * )(p_hObject -> d_stListOfElements[lElementCounter ])) );
                         break;
         }

	MOR_M_Free( p_hObject -> d_stListOfPoints);
	MOR_M_Free( p_hObject -> d_stListOfPointsNormals);
   // if (p_hObject -> d_stListOfPointsReceivedLightIntensity != NULL) 
	 // MOR_M_Free( p_hObject -> d_stListOfPointsReceivedLightIntensity);
//	MOR_M_Free( p_hObject -> d_hListOfPointsMaterial);
//	MOR_M_Free( p_hObject -> d_stListOfEdges);
//	MOR_M_Free( p_hObject -> d_hListOfEdgesMaterial);
	MOR_M_Free( p_hObject -> d_xListOfElementsTypes);
	MOR_M_Free( p_hObject -> d_stListOfElements);

    MOR_M_Free( p_hObject );
    * p_hObj = NULL;
// END ANNECY MT }
}

/*====================================================================================
Name: MOR_fn_vDeletePhysicalObject
Goal: Delete a physical object
=====================================================================================*/
void MOR_fn_vDeletePhysicalObject (PO_tdstPhysicalObject * _pPhysicalObject)
{
	ACP_tdxIndex i;

	for(i=0 ; i<_pPhysicalObject->_hVisualSet->xNbLodDefinitions ; i++)
	{
		MOR_fn_vDeleteGeometricObject (& (_pPhysicalObject->_hVisualSet->d_p_stLodDefinitions [i]));
	};

// ANNECY - MT 08/05/98 {
	GEO_M_TMPFree(_pPhysicalObject->_hVisualSet->d_xThresholdsTable);
	GEO_M_TMPFree(_pPhysicalObject->_hVisualSet->d_p_stLodDefinitions);
	GEO_M_TMPFree(_pPhysicalObject->_hVisualSet);
	MOR_M_Free(_pPhysicalObject);
// END ANNECY MT }
}
