//
//
//
// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
void Geometry3D::fn_vGetPoint(ACP_tdxIndex xNumPoint,MTH3D_tdstVector *p_stPoint)
{
    GEO_vGetPointOfObject(GetStruct(),p_stPoint,xNumPoint);
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
void Geometry3D::fn_vSetPoint(ACP_tdxIndex xNumPoint,MTH3D_tdstVector *p_stPoint)
{
    switch ( GetSaveStatus() )
    {
    case E_ss_Responsible:
        if( !M_bHasPTModification() )
            fn_vOwnerSetPoint( xNumPoint, p_stPoint );
        break;
    case E_ss_Modify:
        if( fn_bIsOnInitialState(C_szFormModif) )
        {
            MTH3D_tdstVector st3D;
            // on passe en etat modifie
            fn_vClearModificationsList();
            // on sauve la valeur initiale
            fn_vGetPoint( xNumPoint, &st3D );
            // BEGIN CPA2 Cristi Petrescu 98-02-
			fn_vAddModification( xNumPoint/*, &st3D */);
			// END CPA2 Cristi Petrescu 98-02-
            //
            fn_vSetCurrentState( C_szFormModif, FALSE) ;
        }
        else
        {
            // on sauve la valeur initiale si ce n'est pas déjà fait
            if( !fn_p_stGetModification( xNumPoint ) )
            {
                MTH3D_tdstVector st3D;
                fn_vGetPoint( xNumPoint, &st3D );
                // BEGIN CPA2 Cristi Petrescu 98-02-
				fn_vAddModification( xNumPoint/*, &st3D */);
				// END CPA2 Cristi Petrescu 98-02-
            }
        }
        fn_vOwnerSetPoint( xNumPoint, p_stPoint );
        break;
    case E_ss_NoSave:
        fn_vOwnerSetPoint( xNumPoint, p_stPoint );
        break;
    case E_ss_NoModif:
        break;
    }
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
CPA_BaseObject *Geometry3D::fn_p_oGetGameMaterial(ACP_tdxHandleOfElement _hElement, ACP_tdxIndex _xIndexInElement /*=0*/)
{
  GMT_tdxHandleToGameMaterial hGameMaterial;

  hGameMaterial = fn_hGetGameMaterial(_hElement, _xIndexInElement);
	if ( GMT_fn_b_ulIsValid(hGameMaterial) )
	{
		CPA_BaseObject *p_oEditorGameMaterial = GetMainWorld()->fn_p_oFindObjectWithEngine(hGameMaterial, C_szGameMaterialTypeName);
		if ( p_oEditorGameMaterial )
			return p_oEditorGameMaterial;
		else if ( ( GetSaveStatus() != E_ss_NoSave ) //this is an error: the  handle is valid but no editor game material exists for it
				  && ((Geometry3D_Interface*)GetEditor()) -> fn_bShowWarnings() )
		{
			((Geometry3D_Interface*)GetEditor()) -> fn_vStopWarnings();

			SCR_tdst_Link_Table *p_stGameMaterialLinkTable = GMT_fn_p_stGetLinkTable();
			SCR_tdst_Link_Value *p_stMaterialEntry = SCR_fnp_st_Link_SearchValue(p_stGameMaterialLinkTable, (unsigned long) hGameMaterial);
			CString csMessage1 = "Error referencing GameMaterial";
			CString csMessage2 = "Geometry3D::fn_p_oGetGameMaterial";
			CString csMessage3 = "The game material referenced by " + GetReferencedSectionName();

			if ( p_stMaterialEntry )
				csMessage3 += CString(" and named ") + (SCR_M_p_sz_Link_GetKey(p_stMaterialEntry) + SCR_M_ul_Link_GetAdditionalLong(p_stMaterialEntry, 1));
			
			csMessage3 += " has no equivalent editor game material. Check what is wrong with this...";

			ERROR_PREPARE_M( C_szOGDModuleNameEro, csMessage1, csMessage2, E_ERROR_GRAVITY_WARNING, csMessage3 );
		//	ERROR_ASSERT(0);

			return NULL;
		}
		else //we did not find the editor game material, but this is not an object that will be saved, so we dont care
			return NULL;
	}
	else
		return NULL;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
void Geometry3D::fn_vSetGameMaterial(ACP_tdxHandleOfElement _hElement, ACP_tdxIndex _xIndexInElement,CPA_BaseObject *_p_oGMT)
{
	GMT_tdxHandleToGameMaterial hMaterialToSet;
	if ( _p_oGMT )
		hMaterialToSet = (GMT_tdxHandleToGameMaterial)_p_oGMT -> GetData();
	else
		GMT_fn_vInvalidate(&hMaterialToSet);
   fn_vSetEngineGameMaterial( _hElement, _xIndexInElement, hMaterialToSet);
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
void Geometry3D::fn_vSetEngineGameMaterial(ACP_tdxHandleOfElement _hElement, ACP_tdxIndex _xIndexInElement,
                                           GMT_tdxHandleToGameMaterial _hGameMaterial)
{
    switch ( GetSaveStatus() )
    {
    case E_ss_Responsible:
        if( !M_bHasGMTModification() )
            fn_vOwnerSetMaterial( _hElement, _xIndexInElement, _hGameMaterial);
        break;
    case E_ss_Modify:
        if( fn_bIsOnInitialState(C_szMaterialModif) )
        {
            // on passe en etat modifie
            fn_vClearGMTModificationsList();
            // on sauve la valeur initiale
            // BEGIN CPA2 Cristi Petrescu 98-02-
            fn_vAddGMTModification( _hElement, _xIndexInElement, fn_hGetGameMaterial( _hElement, _xIndexInElement ) );
			// END CPA2 Cristi Petrescu 98-02-
            //
            fn_vSetCurrentState( C_szMaterialModif, FALSE) ;
        }
        else
        {
            // on sauve la valeur initiale si ce n'est pas déjà fait
            if( !fn_p_stGetGMTModification( _hElement, _xIndexInElement ) )
                // BEGIN CPA2 Cristi Petrescu 98-02-
                fn_vAddGMTModification( _hElement, _xIndexInElement, fn_hGetGameMaterial( _hElement, _xIndexInElement ) );
				// END CPA2 Cristi Petrescu 98-02-
        }
        fn_vOwnerSetMaterial( _hElement, _xIndexInElement, _hGameMaterial );
        break;
    case E_ss_NoSave:
        fn_vOwnerSetMaterial( _hElement, _xIndexInElement, _hGameMaterial );
        break;
    case E_ss_NoModif:
        break;
    }
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
ACP_tdxIndex Geometry3D::fn_xGetNbIndexedElements(ACP_tdxHandleOfElement _hElement)
{
    ACP_tdxIndex                        _xElementType   = GEO_xGetElementType(GetStruct(), _hElement);
    ACP_tdxIndex                        xResult         = 0;
    GEO_tdstElementFaceMapDescriptors   *p_stEFMD;
	GEO_tdstElementAltimap				*p_stAltimap;

    switch( _xElementType )
    {
		case GEO_C_xElementIndexedTriangles:
            xResult = GEO_lGetIndexedTriangleNbFaces(GetStruct(), _hElement);
            break;
		// BEGIN CPA2 Cristi Petrescu 98-03-
		case GEO_C_xElementAltimap:
            p_stAltimap = (GEO_tdstElementAltimap *) GetStruct() -> d_stListOfElements[ _hElement ];
            xResult = p_stAltimap -> xNbFaces;
            break;
		// END CPA2 Cristi Petrescu 98-03-
		case GEO_C_xElementFaceMapDescriptors:
            p_stEFMD = (GEO_tdstElementFaceMapDescriptors*) GetStruct() -> d_stListOfElements[ _hElement ];
            xResult = p_stEFMD -> xNbFaces;
            break;
		case GEO_C_xElementSprites:
		case GEO_C_xElementTMeshes:
			break;
		case GEO_C_xElementPoints:
            xResult = GEO_lGetElementPointsNbPoints(GetStruct(), _hElement);
			break;
		case GEO_C_xElementLines:
            xResult = GEO_lGetElementLinesNbLines(GetStruct(), _hElement);
			break;
		case GEO_C_xElementSpheres:
            xResult = GEO_lGetIndexedSphereNbSpheres(GetStruct(), _hElement);
			break;
		case GEO_C_xElementAlignedBoxes:
            xResult = GEO_lGetAlignedBoxNbBoxes(GetStruct(), _hElement);
			break;
		case GEO_C_xElementCones:
            xResult = GEO_lGetConeNbCones(GetStruct(), _hElement);
			break;
    }
    return xResult;
}

/*-----------------------------------------------------------------------------
 *  Description : return BoundingVolume, and compute it if not exists
 *---------------------------------------------------------------------------*/
ACP_tdxHandleOfObject Geometry3D::fn_hGetBoundingVolume()
{
    if( m_hBoundingVolume == NULL )
        fn_vComputeBoundingVolume( FALSE );
    return m_hBoundingVolume;
}

/*-----------------------------------------------------------------------------
 *  Description :
 *---------------------------------------------------------------------------*/
void Geometry3D::fn_vComputeBoundingVolume(BOOL _bRecompute /*=FALSE*/)
{

	MTH3D_tdstVector		stCenter = {0,0,0};
	MTH_tdxReal				xRadius = 0.0;
    // Bounding volume already allocated ????
    if( m_hBoundingVolume == NULL )
    {
//ANNECY TQ 22/06/98{
        m_hBoundingVolume = GEO_fn_hCreateGeometricSphere();
//ENDANNECY TQ}

        _bRecompute = TRUE;
    }
    // recompute if necessary
    if( _bRecompute || m_bMustRecomputeBdV )
	{
//ANNECY TQ 22/06/98{
		GEO_fn_vAddObjectToSphere(GetStruct(), &stCenter, &xRadius);
		GEO_fn_vSetGeometricSphere(&stCenter, xRadius, m_hBoundingVolume);
//ENDANNECY TQ}

	}

    m_bMustRecomputeBdV = FALSE;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
void Geometry3D::fn_vTranslatePoint(ACP_tdxIndex _xPoint, MTH3D_tdstVector *_p_st3DTranslation)
{
    MTH3D_tdstVector x3DPoint;
    // translate point
    fn_vGetPoint(_xPoint,&x3DPoint);
    MTH3D_M_vAddVector(&x3DPoint,&x3DPoint,_p_st3DTranslation);
    fn_vSetPoint(_xPoint,&x3DPoint );
    m_bMustRecomputeBdV = TRUE;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
void Geometry3D::fn_vAllocAndComputeListOfPointsMaterial(void)
{
	if( GetStruct() -> d_hListOfPointsMaterial == NULL )
	{
		GEO_vCreateObjectListOfPointsMaterial ( GetStruct() );
		GEO_vComputeObjectListOfPointsMaterial( GetStruct() );
	}
}

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Object Creation
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_vSetListOfPoints(ACP_tdxIndex xNbPoints, MTH3D_tdstVector *p_stPoint)
{
    if(xNbPoints > GEO_xGetGeometricObjectNumberOfPoints( GetStruct() ) )
        xNbPoints = GEO_xGetGeometricObjectNumberOfPoints( GetStruct() );

    GEO_vSetListOfPointsOfObject ( GetStruct(), p_stPoint , xNbPoints , 0 );

    m_bMustRecomputeBdV = TRUE;

    return C_Ok;
}


// ----------------------------------------------------------------------------
// Description : allocate and compute internal informations
// ----------------------------------------------------------------------------
void Geometry3D::fn_vEndCreation()
{
    if( ! m_bEndCreated )
       GEO_vEndCreateObject ( GetStruct() );
    m_bEndCreated = TRUE;
}


// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Element Creation
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
ACP_tdxHandleOfElement Geometry3D::fn_hCreateElementSpheres(ACP_tdxIndex xNbSpheres)
{
    ACP_tdxHandleOfElement hElement;

    GEO_vCreateElementSpheres( GetStruct(), &hElement, xNbSpheres);
    fn_vInitElementSection( hElement );
    return hElement;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eSetIndexedSphere(ACP_tdxHandleOfElement hElementSphere, ACP_tdxIndex xIndexOfSphere,
                                               ACP_tdxIndex xCenter, MTH_tdxReal xRadius)
{
    tdeGeomResult eResult = C_BadElement;

    if ( fn_bIsSphere( hElementSphere, xIndexOfSphere ) )
    {
        GEO_vSetCenterPointOfIndexedSphere( GetStruct(), hElementSphere, xIndexOfSphere, xCenter );
        GEO_vSetRadiusOfIndexedSphere( GetStruct(), hElementSphere, xIndexOfSphere, xRadius );
        // default matérial
        fn_vSetEngineGameMaterial(hElementSphere, xIndexOfSphere, fn_hGetDefaultGameMaterial() );

        eResult = C_Ok;
    }
    return eResult;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
ACP_tdxHandleOfElement Geometry3D::fn_hCreateElementAlignedBox(ACP_tdxIndex xNbAlignedBoxes)
{
    ACP_tdxHandleOfElement hElement;

    GEO_vCreateElementAlignedBoxes( GetStruct(), &hElement, xNbAlignedBoxes );
    fn_vInitElementSection( hElement );
    return hElement;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eSetAlignedBox(ACP_tdxHandleOfElement hElementAlignedBox, ACP_tdxIndex xNumberOfAlignedBox,
                                            ACP_tdxIndex xMinPoint, ACP_tdxIndex xMaxPoint)
{
    tdeGeomResult eResult = C_BadElement;

    if ( fn_bIsAlignedBox( hElementAlignedBox, xNumberOfAlignedBox ) )
    {
        GEO_vSetMinMaxPointOfIndexedAlignedBox( GetStruct(), hElementAlignedBox, xNumberOfAlignedBox, xMinPoint, xMaxPoint );
        // default matérial
        fn_vSetEngineGameMaterial(hElementAlignedBox, xNumberOfAlignedBox, fn_hGetDefaultGameMaterial() );

        eResult = C_Ok;
    }
    return eResult;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
ACP_tdxHandleOfElement Geometry3D::fn_hCreateElementCone(ACP_tdxIndex xNbCones)
{
    ACP_tdxHandleOfElement hElement;

    GEO_vCreateElementCones( GetStruct(), &hElement, xNbCones );
    fn_vInitElementSection( hElement );
    return hElement;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eSetCone(ACP_tdxHandleOfElement hElementCone, ACP_tdxIndex xNumberOfCone,
                                      ACP_tdxIndex xTopPoint, ACP_tdxIndex xBasePoint, MTH_tdxReal xBaseRadius)
{
    tdeGeomResult eResult = C_BadElement;

    if ( fn_bIsCone( hElementCone, xNumberOfCone ) )
    {
        GEO_vSetPointsOfIndexedCone( GetStruct(), hElementCone, xNumberOfCone, xTopPoint, xBasePoint);
        GEO_vSetRadiusOfIndexedCone( GetStruct(), hElementCone, xNumberOfCone, xBaseRadius);
        // default matérial
        fn_vSetEngineGameMaterial(hElementCone, xNumberOfCone, fn_hGetDefaultGameMaterial() );

        eResult = C_Ok;
    }
    return eResult;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
ACP_tdxHandleOfElement Geometry3D::fn_hCreateElementIndexedTriangle(ACP_tdxIndex xNbFaces, ACP_tdxIndex xNbElementUV)
{
    ACP_tdxHandleOfElement hElement;

    GEO_vCreateElementIndexedTriangles( GetStruct(), &hElement, xNbFaces, xNbElementUV );
    fn_vInitElementSection( hElement );

    // default matérial
    fn_vSetEngineGameMaterial(hElement,0, fn_hGetDefaultGameMaterial() );

    return hElement;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eSetIndexedTriangle(ACP_tdxHandleOfElement hElementIT, ACP_tdxIndex xNumberOfFace,
                                                 ACP_tdxIndex xPoint1, ACP_tdxIndex xPoint2, ACP_tdxIndex xPoint3)
{
    tdeGeomResult eResult = C_BadElement;

    if ( fn_bIsIndexedTriangle( hElementIT, xNumberOfFace ) )
    {
        GEO_vSetFaceOfIndexedTriangles( GetStruct(), hElementIT, xNumberOfFace, xPoint1, xPoint2, xPoint3 );

        eResult = C_Ok;
    }
    return eResult;
}

// BEGIN CPA2 Cristi Petrescu 98-03-
// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
ACP_tdxHandleOfElement Geometry3D::fn_hCreateElementAltimap(ACP_tdxIndex xNbVertices, ACP_tdxIndex xNbSquares, ACP_tdxIndex	xNbVisibleTriangles, ACP_tdxIndex xNbUVValues, ACP_tdxIndex xNbMaterials)
{
    ACP_tdxHandleOfElement hElement;

	GEO_vCreateElementAltimap (GetStruct(), &hElement, xNbVertices, xNbSquares, xNbVisibleTriangles, xNbUVValues, xNbMaterials);
    fn_vInitElementSection (hElement);

    // default matérial
    fn_vSetEngineGameMaterial (hElement,0, fn_hGetDefaultGameMaterial());

    return hElement;
}

// ----------------------------------------------------------------------------
// Description : fill the atimap with std values
// ----------------------------------------------------------------------------
/*
void Geometry3D::fn_vStandardAltimap (ACP_tdxHandleOfElement hElement)
{
	ACP_tdxIndex xWidthCount, xDepthCount;
	GEO_tdstElementAltimap *p_stAltimap = (GEO_tdstElementAltimap *) GetStruct () -> d_stListOfElements [hElement];

	for (xWidthCount = 0; xWidthCount < p_stAltimap -> xWidth; xWidthCount ++)
	{
		for (xDepthCount = 0; xDepthCount < p_stAltimap -> xDepth; xDepthCount ++)
		{
			ACP_tdxIndex xNumSquare = xWidthCount + xDepthCount * p_stAltimap -> xWidth;
			// set the squares
			GEO_vSetAltimapSquare (GetStruct (), hElement, xNumSquare, GEO_C_xAltiSquareBothTRBL, xNumSquare * 2);
			// set the faces
			// uvs
			GEO_vSetAltimapFaceUVIndex (GetStruct (), hElement, xNumSquare * 2, 0, 1, 3);
			GEO_vSetAltimapFaceUVIndex (GetStruct (), hElement, xNumSquare * 2 + 1, 0, 2, 3);
			// materials
			// ############
			//GEO_vSetAltimapFaceGameMaterial (GetStruct (), hElement, xNumSquare * 2, fn_hGetDefaultGameMaterial ());
			//GEO_vSetAltimapFaceGameMaterial (GetStruct (), hElement, xNumSquare * 2 + 1, fn_hGetDefaultGameMaterial ());
			// and a normals ?!
		}
	}

	GEO_vSetAltimapNbFaces (GetStruct (), hElement, p_stAltimap -> xWidth * p_stAltimap -> xDepth * 2);

	// set the uv values
	ACP_tdst2DUVValues stUV0 = {0.0, 0.0};
	GEO_vSetAltimapUVValue (GetStruct (), hElement, 0, stUV0);
	ACP_tdst2DUVValues stUV1 = {1.0, 0.0};
	GEO_vSetAltimapUVValue (GetStruct (), hElement, 1, stUV1);
	ACP_tdst2DUVValues stUV2 = {0.0, 1.0};
	GEO_vSetAltimapUVValue (GetStruct (), hElement, 2, stUV2);
	ACP_tdst2DUVValues stUV3 = {1.0, 1.0};
	GEO_vSetAltimapUVValue (GetStruct (), hElement, 3, stUV3);

	GEO_vSetAltimapNbUVValues (GetStruct (), hElement, 4);
	
	// set the normals
	if(GetStruct()->d_stListOfPointsNormals) 
		GEO_M_CPAFree(GetStruct()->d_stListOfPointsNormals);
	if(GetStruct()->d_hListOfPointsMaterial) 
		GEO_M_CPAFree(GetStruct()->d_hListOfPointsMaterial);
	if(GetStruct()->d_stListOfEdges) 
		GEO_M_CPAFree(GetStruct()->d_stListOfEdges);
	if(GetStruct()->d_stListOfPointsReceivedLightIntensity) 
		GEO_M_CPAFree(GetStruct()->d_stListOfPointsReceivedLightIntensity);

    GEO_xCreateObjectPointNormals (GetStruct());
	GEO_vCreateObjectListOfPointsMaterial(GetStruct());
	GEO_xCreateObjectListOfEdges(GetStruct());

    GEO_xComputeObjectNormals (GetStruct());
    GEO_vComputeObjectListOfPointsMaterial(GetStruct());
    GEO_xComputeObjectListOfEdges(GetStruct());
}
*/
// END CPA2 Cristi Petrescu 98-03-

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
ACP_tdxHandleOfElement Geometry3D::fn_hCreateElementPoints(ACP_tdxIndex xNumberOfPoints)
{
    ACP_tdxHandleOfElement hElement;

    GEO_xCreateElementPoints( GetStruct(), &hElement, xNumberOfPoints );
    fn_vInitElementSection( hElement );

    // default matérial
    fn_vSetEngineGameMaterial(hElement, 0, fn_hGetDefaultGameMaterial() );

    return hElement;

}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eSetIndexedPoint(ACP_tdxHandleOfElement hElementPoint, ACP_tdxIndex xNumberOfPoint,
                                              ACP_tdxIndex xIndexOfPoint)
{
    tdeGeomResult eResult = C_BadElement;

    if ( fn_bIsPoint( hElementPoint, xNumberOfPoint ) )
    {
        GEO_xSetIndexOfElementPoints( GetStruct(), hElementPoint, xNumberOfPoint, xIndexOfPoint );

        eResult = C_Ok;
    }
    return eResult;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eSetFatnessOfElementPoint(ACP_tdxHandleOfElement hElementPoint,
                                                       MTH_tdxReal xFatness)
{
    tdeGeomResult eResult = C_BadElement;

    if ( fn_bIsPoint( hElementPoint, 0 ) )
    {
        GEO_xSetFatnessOfElementPoints( GetStruct(), hElementPoint, xFatness );

        eResult = C_Ok;
    }
    return eResult;
}

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Element Modification
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eSetConePoints(ACP_tdxHandleOfElement hElementCone, ACP_tdxIndex xNumberOfCone,
                                            ACP_tdxIndex xTopPoint, ACP_tdxIndex xBasePoint)
{
    tdeGeomResult eResult = C_BadElement;

    if ( fn_bIsCone( hElementCone, xNumberOfCone ) )
    {
        GEO_vSetPointsOfIndexedCone( GetStruct(), hElementCone, xNumberOfCone, xTopPoint, xBasePoint);
        eResult = C_Ok;
    }
    return eResult;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eSetConeBaseRadius(ACP_tdxHandleOfElement hElementCone, ACP_tdxIndex xNumberOfCone,
                                                MTH_tdxReal xBaseRadius)
{
    tdeGeomResult eResult = C_BadElement;

    if ( fn_bIsCone( hElementCone, xNumberOfCone ) )
    {
        GEO_vSetRadiusOfIndexedCone( GetStruct(), hElementCone, xNumberOfCone, xBaseRadius);
        eResult = C_Ok;
    }
    return eResult;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eGetConePoints(ACP_tdxHandleOfElement hElementCone, ACP_tdxIndex xNumberOfCone,
                                            ACP_tdxIndex *_p_xTopPoint, ACP_tdxIndex *_p_xBasePoint)
{
    tdeGeomResult eResult = C_BadElement;

    if ( fn_bIsCone( hElementCone, xNumberOfCone ) )
    {
        GEO_vGetPointsOfIndexedCone( GetStruct(), hElementCone, xNumberOfCone, _p_xTopPoint, _p_xBasePoint);
        eResult = C_Ok;
    }
    return eResult;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
MTH_tdxReal Geometry3D::fn_xGetConeBaseRadius(ACP_tdxHandleOfElement hElementCone, ACP_tdxIndex xNumberOfCone)
{
    MTH_tdxReal xResult = 0;

    if ( fn_bIsCone( hElementCone, xNumberOfCone ) )
    {
        xResult = GEO_xGetRadiusOfIndexedCone( GetStruct(), hElementCone, xNumberOfCone);
    }
    return xResult;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eGetIndexedTrianglePoints(ACP_tdxHandleOfElement hElementIT, ACP_tdxIndex xNumberOfFace,
                                                       ACP_tdxIndex *_p_xPt1, ACP_tdxIndex *_p_xPt2, ACP_tdxIndex *_p_xPt3)
{
    tdeGeomResult eResult = C_BadElement;

    if ( fn_bIsIndexedTriangle( hElementIT, xNumberOfFace ) )
    {
        GEO_vGetFaceOfIndexedTriangles( GetStruct(), hElementIT, xNumberOfFace, _p_xPt1, _p_xPt2, _p_xPt3 );
        eResult = C_Ok;
    }
    return eResult;
}

// BEGIN CPA2 Cristi Petrescu 98-03-
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// altimaps
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
/*
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : Geometry3D::fn_eGetOrigin 
// Date   : 98.03
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description : gets the altimap origin
// Author      : Cristi Petrescu
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
tdeGeomResult Geometry3D::fn_eGetOrigin (MTH3D_tdstVector *p_st3DPoint, ACP_tdxHandleOfElement hElement)
{
	tdeGeomResult eResult = C_BadElement;

    if (fn_bIsAltimap (hElement))
    {
        GEO_vGetAltimapOrigin (GetStruct (), hElement, p_st3DPoint);
        eResult = C_Ok;
    }

    return eResult;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : Geometry3D::fn_eSetOrigin 
// Date   : 98.03
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description : sets the altimap origin
// Author      : Cristi Petrescu
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
tdeGeomResult Geometry3D::fn_eSetOrigin (MTH3D_tdstVector st3DPoint, ACP_tdxHandleOfElement hElement)
{
	tdeGeomResult eResult = C_BadElement;

    if (fn_bIsAltimap (hElement))
    {
        GEO_vSetAltimapOrigin (GetStruct (), hElement, st3DPoint);
        eResult = C_Ok;
    }

    return eResult;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : Geometry3D::fn_eGetSquarePattern 
// Date   : 98.03
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description : gets the altimap square parameters
// Author      : Cristi Petrescu
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
tdeGeomResult Geometry3D::fn_eGetSquarePattern (ACP_tdxIndex *p_xWidth, MTH_tdxReal *p_xSquareDimX, ACP_tdxIndex *p_xDepth, MTH_tdxReal *p_xSquareDimY, ACP_tdxHandleOfElement hElement)
{
	tdeGeomResult eResult = C_BadElement;

    if (fn_bIsAltimap (hElement))
    {
        GEO_vGetAltimapSquarePattern (GetStruct (), hElement, p_xWidth, p_xSquareDimX, p_xDepth, p_xSquareDimY);
        eResult = C_Ok;
    }

    return eResult;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : Geometry3D::fn_eSetSquarePattern 
// Date   : 98.03
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description : sets the altimap square parameters
// Author      : Cristi Petrescu
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
tdeGeomResult Geometry3D::fn_eSetSquarePattern (ACP_tdxIndex xWidth, MTH_tdxReal xSquareDimX, ACP_tdxIndex xDepth, MTH_tdxReal xSquareDimY, ACP_tdxHandleOfElement hElement)
{
	tdeGeomResult eResult = C_BadElement;

    if (fn_bIsAltimap (hElement))
    {
		GEO_tdstElementAltimap *p_stAltimap = (GEO_tdstElementAltimap *) GetStruct () -> d_stListOfElements[hElement];

		ACP_tdxIndex xOldWidth = p_stAltimap -> xWidth;
		ACP_tdxIndex xOldDepth = p_stAltimap -> xDepth;
		MTH_tdxReal xOldSquareDimX = p_stAltimap -> xDeltaX;
		MTH_tdxReal xOldSquareDimY = p_stAltimap -> xDeltaY;
		
        GEO_vSetAltimapSquarePattern (GetStruct (), hElement, xWidth, xSquareDimX, xDepth, xSquareDimY);

		// coherence matter
		if (xOldWidth != xWidth || xOldDepth != xDepth)
		{
			// array of heights
			MTH_tdxReal *d_xOldHeight = p_stAltimap -> d_xHeight;
			GEO_M_CPAMalloc (p_stAltimap -> d_xHeight,
						     MTH_tdxReal *,
							 (xWidth + 1) * (xDepth + 1) * sizeof (MTH_tdxReal),
							 E_uwGEONotEnoughtMemory);
			for (ACP_tdxIndex xWidthCount = 0; xWidthCount < xWidth + 1; xWidthCount ++)
			{
				for (ACP_tdxIndex xDepthCount = 0; xDepthCount < xDepth + 1; xDepthCount ++)
				{
					// linear interpolate the old values
					ACP_tdxIndex xMinWidth = xWidthCount * xOldWidth / xWidth;
					ACP_tdxIndex xMinDepth = xDepthCount * xOldDepth / xDepth ;
					ACP_tdxIndex xMaxWidth = xMinWidth < xOldWidth ? xMinWidth + 1 : xOldWidth;
					ACP_tdxIndex xMaxDepth = xMinDepth < xOldDepth ? xMinDepth + 1: xOldDepth;
					// the corner values
					MTH_tdxReal xHwd = d_xOldHeight [xMinWidth + (xOldWidth + 1) * xMinDepth];
					MTH_tdxReal xHWd = d_xOldHeight [xMaxWidth + (xOldWidth + 1) * xMinDepth];
					MTH_tdxReal xHWD = d_xOldHeight [xMaxWidth + (xOldWidth + 1) * xMaxDepth];
					MTH_tdxReal xHwD = d_xOldHeight [xMinWidth + (xOldWidth + 1) * xMaxDepth];
					// the interpolation values (fractionary part)
					MTH_tdxReal xS = ((MTH_tdxReal) xWidthCount) * xOldWidth / xWidth - xMinWidth;
					MTH_tdxReal xT = ((MTH_tdxReal) xDepthCount) * xOldDepth / xDepth - xMinDepth;
					// the medium value
					MTH_tdxReal xInterpolatedHeight = (xT * (xS * xHwd + (1 - xS) * xHWd) + (1 - xT) * (xS * xHwD + (1 - xS) * xHWD) +
													   xS * (xT * xHwd + (1 - xT) * xHwD) + (1 - xS) * (xT * xHWd + (1 - xT) * xHWD)) / 2;
					//MTH_tdxReal xInterpolatedHeight = -0.4;
					p_stAltimap -> d_xHeight [xWidthCount + (xWidth + 1) * xDepthCount] = xInterpolatedHeight;
				}
			}
		
			GEO_M_CPAFree (d_xOldHeight);
		
			// reallocs
			// BECAUSE SOMEBODY SETS THIS TO WRONG VALUES IN RENDER FUNCTIONS
			// WHY ????????????
			// the Object points
			GetStruct () -> xNbPoints += (xWidth + 1) * (xDepth + 1);
			GetStruct () -> xNbPoints -= (xOldWidth + 1) * (xOldDepth + 1);
			GEO_M_CPAFree (GetStruct () -> d_stListOfPoints);
			GEO_M_CPAMalloc( GetStruct () -> d_stListOfPoints,
							 MTH3D_tdstVector *,
							(xWidth + 1) * (xDepth + 1) * sizeof( MTH3D_tdstVector ),
							E_uwGEONotEnoughtMemory );
			//--- Array of Point Normals ---
			GEO_M_CPAFree  ( p_stAltimap->d_stPointNormals);
			GEO_M_CPAMalloc( p_stAltimap->d_stPointNormals,
							 MTH3D_tdstVector *,
							 (xWidth + 1) * (xDepth + 1) * sizeof( MTH3D_tdstVector ),
							 E_uwGEONotEnoughtMemory );
			
			//--- Array of Square Descriptors ---
			GEO_M_CPAFree  ( p_stAltimap->d_stSquare);
			GEO_M_CPAMalloc( p_stAltimap->d_stSquare,
							 GEO_tdstAltimapSquare *,
							 xWidth * xDepth * sizeof( GEO_tdstAltimapSquare ),
						     E_uwGEONotEnoughtMemory );

			//--- Array of Face descriptors ---
			GEO_M_CPAFree  ( p_stAltimap->d_stFaces);
			GEO_M_CPAMalloc( p_stAltimap->d_stFaces,
							 GEO_tdstAltimapFace *,
							 2 * xWidth * xDepth * sizeof( GEO_tdstAltimapFace ),
							 E_uwGEONotEnoughtMemory );

			GEO_M_CPAFree  ( p_stAltimap->d_stUVValues);
			GEO_M_CPAMalloc( p_stAltimap->d_stUVValues,
							 ACP_tdst2DUVValues *,
							 4 * sizeof( ACP_tdst2DUVValues ), // the Editor std. value
							 E_uwGEONotEnoughtMemory );
			// standard inits
			fn_vStandardAltimap (hElement);
		}
    }

    return eResult;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : Geometry3D::fn_eSetNbFaces
// Date   : 98.03
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description : computes the nuber of visible triangles
// Author      : Cristi Petrescu
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
tdeGeomResult Geometry3D::fn_eSetNbFaces (ACP_tdxIndex xNbSquares, ACP_tdxHandleOfElement hElement)
{
	tdeGeomResult eResult = C_BadElement;

    if (fn_bIsAltimap (hElement))
    {
        // count the number of visible faces
		ACP_tdxIndex xNbFaces = 0;
		for (ACP_tdxIndex xCount = 0; xCount < xNbSquares; xCount ++)
		{
			unsigned char ucType;
			ACP_tdxIndex xDummy;
			GEO_vGetAltimapSquare (GetStruct (), hElement, xCount, & ucType, & xDummy);
			switch (ucType)
			{
			case GEO_C_xAltiSquareVoid:
				break;
			case GEO_C_xAltiSquareTopRight:
			case GEO_C_xAltiSquareBottomLeft:
			case GEO_C_xAltiSquareTopLeft:
			case GEO_C_xAltiSquareBottomRight:
				xNbFaces ++;
				break;
			case GEO_C_xAltiSquareBothTRBL:
			case GEO_C_xAltiSquareBothTLBR:
				xNbFaces += 2;
				break;
			default:
				ASSERT (FALSE);
			}
		}
		GEO_vSetAltimapNbFaces (GetStruct (), hElement, xNbFaces);
    }

    return eResult;
}
*/
// END CPA2 Cristi Petrescu 98-03-

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// spheres
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------

/* -----------------09/01/97 11:03-------------------
   Description : get the center of the sphere
 --------------------------------------------------*/
tdeGeomResult Geometry3D::fn_eGetCenter(MTH3D_tdstVector *p_st3DCenter, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumSphere /*=0*/)
{
    tdeGeomResult eResult = C_BadElement;

    if ( fn_bIsSphere(hElement,xNumSphere) )
    {
        ACP_tdxIndex xCenter = GEO_xGetCenterPointOfIndexedSphere(GetStruct(),hElement,xNumSphere);
        fn_vGetPoint(xCenter,p_st3DCenter);
        eResult = C_Ok;
    }

    return eResult;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eGetCenterX(MTH_tdxReal *p_xValue, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumSphere /*=0*/)
{
    MTH3D_tdstVector st3DCenter;
    tdeGeomResult eResult = fn_eGetCenter(&st3DCenter,hElement,xNumSphere);

    if( eResult == C_Ok )
        *p_xValue = MTH3D_M_xGetXofVector(&st3DCenter);

    return eResult;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eGetCenterY(MTH_tdxReal *p_xValue, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumSphere /*=0*/)
{
    MTH3D_tdstVector st3DCenter;
    tdeGeomResult eResult = fn_eGetCenter(&st3DCenter,hElement,xNumSphere);

    if( eResult == C_Ok )
        *p_xValue = MTH3D_M_xGetYofVector(&st3DCenter);

    return eResult;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eGetCenterZ(MTH_tdxReal *p_xValue, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumSphere /*=0*/)
{
    MTH3D_tdstVector st3DCenter;
    tdeGeomResult eResult = fn_eGetCenter(&st3DCenter,hElement,xNumSphere);

    if( eResult == C_Ok )
        *p_xValue = MTH3D_M_xGetZofVector(&st3DCenter);

    return eResult;
}

/* -----------------09/01/97 11:14-------------------
   Description : set the center of a sphere
 --------------------------------------------------*/
tdeGeomResult Geometry3D::fn_eSetCenter(MTH3D_tdstVector *p_stPoint, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumSphere /*=0*/)
{
    tdeGeomResult eResult = C_BadElement;

    if ( fn_bIsSphere(hElement,xNumSphere) )
    {
        ACP_tdxIndex xCenter = GEO_xGetCenterPointOfIndexedSphere(GetStruct(),hElement,xNumSphere);
        fn_vSetPoint(xCenter,p_stPoint);
        eResult = C_Ok;
    }

    return eResult;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eSetCenterX(MTH_tdxReal *p_xValue, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumSphere /*=0*/)
{
    tdeGeomResult eResult = C_BadElement;

    if ( fn_bIsSphere(hElement,xNumSphere) )
    {
        ACP_tdxIndex xCenter = GEO_xGetCenterPointOfIndexedSphere(GetStruct(),hElement,xNumSphere);
        MTH3D_tdstVector st3DCenter;

        fn_vGetPoint(xCenter,&st3DCenter);
        MTH3D_M_vSetXofVector(&st3DCenter,*p_xValue);
        fn_vSetPoint(xCenter,&st3DCenter);
        eResult = C_Ok;
    }

    return eResult;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eSetCenterY(MTH_tdxReal *p_xValue, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumSphere /*=0*/)
{
    tdeGeomResult eResult = C_BadElement;

    if ( fn_bIsSphere(hElement,xNumSphere) )
    {
        ACP_tdxIndex xCenter = GEO_xGetCenterPointOfIndexedSphere(GetStruct(),hElement,xNumSphere);
        MTH3D_tdstVector st3DCenter;

        fn_vGetPoint(xCenter,&st3DCenter);
        MTH3D_M_vSetYofVector(&st3DCenter,*p_xValue);
        fn_vSetPoint(xCenter,&st3DCenter);
        eResult = C_Ok;
    }

    return eResult;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eSetCenterZ(MTH_tdxReal *p_xValue, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumSphere /*=0*/)
{
    tdeGeomResult eResult = C_BadElement;

    if ( fn_bIsSphere(hElement,xNumSphere) )
    {
        ACP_tdxIndex xCenter = GEO_xGetCenterPointOfIndexedSphere(GetStruct(),hElement,xNumSphere);
        MTH3D_tdstVector st3DCenter;

        fn_vGetPoint(xCenter,&st3DCenter);
        MTH3D_M_vSetZofVector(&st3DCenter,*p_xValue);
        fn_vSetPoint(xCenter,&st3DCenter);
        eResult = C_Ok;
    }

    return eResult;
}

/* -----------------09/01/97 11:22-------------------
   Description : get radius of sphere
 --------------------------------------------------*/
tdeGeomResult Geometry3D::fn_eGetRadius(MTH_tdxReal *p_xValue, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumSphere /*=0*/)
{
    tdeGeomResult eResult = C_BadElement;

    if ( fn_bIsSphere(hElement,xNumSphere) )
    {
        *p_xValue = GEO_xGetRadiusOfIndexedSphere(GetStruct(),hElement,xNumSphere);
        eResult = C_Ok;
    }

    return eResult;
}

/* -----------------09/01/97 11:23-------------------
   Description : Set radius of sphere
 --------------------------------------------------*/
tdeGeomResult Geometry3D::fn_eSetRadius(MTH_tdxReal *p_xValue, ACP_tdxHandleOfElement hElement /*=0*/,
                                        ACP_tdxIndex xNumSphere /*=0*/)
{
    tdeGeomResult eResult = C_BadElement;

    if ( fn_bIsSphere(hElement,xNumSphere) )
    {
        if( MTH_M_bLessZero(*p_xValue) )
        {
            eResult = C_BadValue;
            *p_xValue = MTH_C_ZERO ;
        }
        else
            eResult = C_Ok ;
        // update radius
        GEO_vSetRadiusOfIndexedSphere(GetStruct(),hElement,xNumSphere,*p_xValue);
    }

    return eResult;
}

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Aligned box
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------

/* -----------------09/01/97 11:50-------------------
   Description : get MinPoint of AlignedBox
 --------------------------------------------------*/
tdeGeomResult Geometry3D::fn_eGetMinPoint(MTH3D_tdstVector *p_st3DPoint, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumBox /*=0*/)
{
    tdeGeomResult eResult = C_BadElement;

    if ( fn_bIsAlignedBox(hElement,xNumBox) )
    {
        ACP_tdxIndex xMinPoint,xMaxPoint;

        GEO_vGetMinMaxPointOfIndexedAlignedBox(GetStruct(),hElement,xNumBox,&xMinPoint,&xMaxPoint);
        fn_vGetPoint(xMinPoint,p_st3DPoint);
        eResult = C_Ok;
    }

    return eResult;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eSetMinPoint(MTH3D_tdstVector *p_st3DPoint, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumBox /*=0*/)
{
    MTH_tdxReal   xValueX  = MTH3D_M_xGetXofVector(p_st3DPoint);
    tdeGeomResult eResultX = fn_eSetMinPointX( &xValueX, hElement, xNumBox);

    MTH_tdxReal   xValueY  = MTH3D_M_xGetYofVector(p_st3DPoint);
    tdeGeomResult eResultY = fn_eSetMinPointY( &xValueY, hElement, xNumBox);

    MTH_tdxReal   xValueZ  = MTH3D_M_xGetZofVector(p_st3DPoint);
    tdeGeomResult eResultZ = fn_eSetMinPointZ( &xValueZ, hElement, xNumBox);

    if( (eResultX != C_Ok) || (eResultY != C_Ok) || (eResultZ != C_Ok) )
    {
        MTH3D_M_vSetVectorElements(p_st3DPoint,xValueX,xValueY,xValueZ);
        return C_BadValue;
    }
    return C_Ok;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eSetMinPointX(MTH_tdxReal *p_xValue, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumBox /*=0*/)
{
    return fn_eModifyMinPoint(C_Set,C_X,p_xValue,hElement,xNumBox);
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eSetMinPointY(MTH_tdxReal *p_xValue, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumBox /*=0*/)
{
    return fn_eModifyMinPoint(C_Set,C_Y,p_xValue,hElement,xNumBox);
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eSetMinPointZ(MTH_tdxReal *p_xValue, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumBox /*=0*/)
{
    return fn_eModifyMinPoint(C_Set,C_Z,p_xValue,hElement,xNumBox);
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eIncMinPointX(MTH_tdxReal *p_xValue, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumBox /*=0*/)
{
    return fn_eModifyMinPoint(C_Inc,C_X,p_xValue,hElement,xNumBox);
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eIncMinPointY(MTH_tdxReal *p_xValue, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumBox /*=0*/)
{
    return fn_eModifyMinPoint(C_Inc,C_Y,p_xValue,hElement,xNumBox);
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eIncMinPointZ(MTH_tdxReal *p_xValue, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumBox /*=0*/)
{
    return fn_eModifyMinPoint(C_Inc,C_Z,p_xValue,hElement,xNumBox);
}


// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eModifyMinPoint(tdeModifType eModif,tdeCompoType eCompo,MTH_tdxReal *p_xValue, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumBox /*=0*/)
{
    tdeGeomResult eResult = C_BadElement;

    if ( fn_bIsAlignedBox(hElement,xNumBox) )
    {
        ACP_tdxIndex xMinPoint,xMaxPoint;
        MTH3D_tdstVector stMinPoint;
        MTH3D_tdstVector stMaxPoint;

        GEO_vGetMinMaxPointOfIndexedAlignedBox(GetStruct(),hElement,xNumBox,&xMinPoint,&xMaxPoint);
        fn_vGetPoint(xMinPoint,&stMinPoint);
        fn_vGetPoint(xMaxPoint,&stMaxPoint);

        // change value
        switch ( eCompo )
        {
            case C_X:
                // update
                if( eModif == C_Set)
                {
                    MTH3D_M_vSetXofVector(&stMinPoint,*p_xValue);
                }
                else if ( eModif == C_Inc )
                {
                    MTH3D_M_vSetXofVector(&stMinPoint,MTH_M_xAdd(*p_xValue,MTH3D_M_xGetXofVector(&stMinPoint)));
                }
                // verify
                if(MTH_M_bLessEqual(MTH3D_M_xGetXofVector(&stMinPoint),MTH3D_M_xGetXofVector(&stMaxPoint)))
                    eResult = C_Ok;
                else
                {
                    eResult = C_BadValue;
                    MTH3D_M_vSetXofVector(&stMinPoint,MTH3D_M_xGetXofVector(&stMaxPoint));
                }
                break;
            case C_Y:
                // update
                if( eModif == C_Set)
                {
                    MTH3D_M_vSetYofVector(&stMinPoint,*p_xValue);
                }
                else if ( eModif == C_Inc )
                {
                    MTH3D_M_vSetYofVector(&stMinPoint,MTH_M_xAdd(*p_xValue,MTH3D_M_xGetYofVector(&stMinPoint)));
                }
                // verify
                if(MTH_M_bLessEqual(MTH3D_M_xGetYofVector(&stMinPoint),MTH3D_M_xGetYofVector(&stMaxPoint)))
                    eResult = C_Ok;
                else
                {
                    eResult = C_BadValue;
                    MTH3D_M_vSetYofVector(&stMinPoint,MTH3D_M_xGetYofVector(&stMaxPoint));
                }
                break;
            case C_Z:
                // update
                if( eModif == C_Set)
                {
                    MTH3D_M_vSetZofVector(&stMinPoint,*p_xValue);
                }
                else if ( eModif == C_Inc )
                {
                    MTH3D_M_vSetZofVector(&stMinPoint,MTH_M_xAdd(*p_xValue,MTH3D_M_xGetZofVector(&stMinPoint)));
                }
                // verify
                if( MTH_M_bLessEqual(MTH3D_M_xGetZofVector(&stMinPoint),MTH3D_M_xGetZofVector(&stMaxPoint)) )
                    eResult = C_Ok ;
                else
                {
                    eResult = C_BadValue ;
                    MTH3D_M_vSetZofVector(&stMinPoint,MTH3D_M_xGetZofVector(&stMaxPoint));
                }
                break;
        }
        fn_vSetPoint(xMinPoint,&stMinPoint);
    }

    return eResult;
}

/* -----------------09/01/97 11:51-------------------
   Description : Get MAxPoint of AlignedBox
 --------------------------------------------------*/
tdeGeomResult Geometry3D::fn_eGetMaxPoint(MTH3D_tdstVector *p_st3DPoint, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumBox /*=0*/)
{
    tdeGeomResult eResult = C_BadElement;

    if ( fn_bIsAlignedBox(hElement,xNumBox) )
    {
        ACP_tdxIndex xMinPoint,xMaxPoint;

        GEO_vGetMinMaxPointOfIndexedAlignedBox(GetStruct(),hElement,xNumBox,&xMinPoint,&xMaxPoint);
        fn_vGetPoint(xMaxPoint,p_st3DPoint);
        eResult = C_Ok;
    }

    return eResult;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eSetMaxPoint(MTH3D_tdstVector *p_st3DPoint, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumBox /*=0*/)
{
    MTH_tdxReal   xValueX  = MTH3D_M_xGetXofVector(p_st3DPoint);
    tdeGeomResult eResultX = fn_eSetMaxPointX( &xValueX, hElement, xNumBox);

    MTH_tdxReal   xValueY  = MTH3D_M_xGetYofVector(p_st3DPoint);
    tdeGeomResult eResultY = fn_eSetMaxPointY( &xValueY, hElement, xNumBox);

    MTH_tdxReal   xValueZ  = MTH3D_M_xGetZofVector(p_st3DPoint);
    tdeGeomResult eResultZ = fn_eSetMaxPointZ( &xValueZ, hElement, xNumBox);

    if( (eResultX != C_Ok) || (eResultY != C_Ok) || (eResultZ != C_Ok) )
    {
        MTH3D_M_vSetVectorElements(p_st3DPoint,xValueX,xValueY,xValueZ);
        return C_BadValue;
    }
    return C_Ok;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eSetMaxPointX(MTH_tdxReal *p_xValue, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumBox /*=0*/)
{
    return fn_eModifyMaxPoint(C_Set,C_X,p_xValue,hElement,xNumBox);
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eSetMaxPointY(MTH_tdxReal *p_xValue, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumBox /*=0*/)
{
    return fn_eModifyMaxPoint(C_Set,C_Y,p_xValue,hElement,xNumBox);
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eSetMaxPointZ(MTH_tdxReal *p_xValue, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumBox /*=0*/)
{
    return fn_eModifyMaxPoint(C_Set,C_Z,p_xValue,hElement,xNumBox);
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eIncMaxPointX(MTH_tdxReal *p_xValue, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumBox /*=0*/)
{
    return fn_eModifyMaxPoint(C_Inc,C_X,p_xValue,hElement,xNumBox);
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eIncMaxPointY(MTH_tdxReal *p_xValue, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumBox /*=0*/)
{
    return fn_eModifyMaxPoint(C_Inc,C_Y,p_xValue,hElement,xNumBox);
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eIncMaxPointZ(MTH_tdxReal *p_xValue, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumBox /*=0*/)
{
    return fn_eModifyMaxPoint(C_Inc,C_Z,p_xValue,hElement,xNumBox);
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
tdeGeomResult Geometry3D::fn_eModifyMaxPoint(tdeModifType eModif,tdeCompoType eCompo,MTH_tdxReal *p_xValue, ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumBox /*=0*/)
{
    tdeGeomResult eResult = C_BadElement;

    if ( fn_bIsAlignedBox(hElement,xNumBox) )
    {
        ACP_tdxIndex xMinPoint,xMaxPoint;
        MTH3D_tdstVector stMinPoint;
        MTH3D_tdstVector stMaxPoint;

        GEO_vGetMinMaxPointOfIndexedAlignedBox(GetStruct(),hElement,xNumBox,&xMinPoint,&xMaxPoint);
        fn_vGetPoint(xMinPoint,&stMinPoint);
        fn_vGetPoint(xMaxPoint,&stMaxPoint);

        // change value
        switch ( eCompo )
        {
            case C_X:
                // update
                if( eModif == C_Set)
                {
                    MTH3D_M_vSetXofVector(&stMaxPoint,*p_xValue);
                }
                else if ( eModif == C_Inc )
                {
                    MTH3D_M_vSetXofVector(&stMaxPoint,MTH_M_xAdd(*p_xValue,MTH3D_M_xGetXofVector(&stMaxPoint)));
                }
                // verify
                if(MTH_M_bLessEqual(MTH3D_M_xGetXofVector(&stMinPoint),MTH3D_M_xGetXofVector(&stMaxPoint)))
                    eResult = C_Ok;
                else
                {
                    eResult = C_BadValue ;
                    MTH3D_M_vSetXofVector(&stMaxPoint,MTH3D_M_xGetXofVector(&stMinPoint));
                }
                break;
            case C_Y:
                // update
                if( eModif == C_Set)
                {
                    MTH3D_M_vSetYofVector(&stMaxPoint,*p_xValue);
                }
                else if ( eModif == C_Inc )
                {
                    MTH3D_M_vSetYofVector(&stMaxPoint,MTH_M_xAdd(*p_xValue,MTH3D_M_xGetYofVector(&stMaxPoint)));
                }
                // verify
                if(MTH_M_bLessEqual(MTH3D_M_xGetYofVector(&stMinPoint),MTH3D_M_xGetYofVector(&stMaxPoint)))
                    eResult = C_Ok;
                else
                {
                    eResult = C_BadValue ;
                    MTH3D_M_vSetYofVector(&stMaxPoint,MTH3D_M_xGetYofVector(&stMinPoint));
                }
                break;
            case C_Z:
                // update
                if( eModif == C_Set)
                {
                    MTH3D_M_vSetZofVector(&stMaxPoint,*p_xValue);
                }
                else if ( eModif == C_Inc )
                {
                    MTH3D_M_vSetZofVector(&stMaxPoint,MTH_M_xAdd(*p_xValue,MTH3D_M_xGetZofVector(&stMaxPoint)));
                }
                // verify
                if(MTH_M_bLessEqual(MTH3D_M_xGetZofVector(&stMinPoint),MTH3D_M_xGetZofVector(&stMaxPoint)))
                    eResult = C_Ok;
                else
                {
                    eResult = C_BadValue ;
                    MTH3D_M_vSetZofVector(&stMaxPoint,MTH3D_M_xGetZofVector(&stMinPoint));
                }
                break;
        }
        fn_vSetPoint(xMaxPoint,&stMaxPoint);
    }

    return eResult;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
void Geometry3D::fn_vMoveFaceToFaceDescriptors(ACP_tdxIndex xElementIT, ACP_tdxIndex xFaceIT, ACP_tdxIndex *p_xElementFMD, ACP_tdxIndex *p_xFaceFMD)
{
// ANNECY MT - 15/09/98 {
// END ANNECY MT }
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
void Geometry3D::fn_vMoveFaceDescriptorsToFace(ACP_tdxIndex xElementFMD, ACP_tdxIndex xFaceFMD, ACP_tdxIndex xElementIT, ACP_tdxIndex xFaceIT)
{
// ANNECY MT - 15/09/98 {
// END ANNECY MT }
}

//
// protected methods
//

/* -----------------09/01/97 10:48-------------------
   Description : TRUE if (hElement,xNumSphere) references a sphere
 --------------------------------------------------*/
BOOL Geometry3D::fn_bIsSphere(ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumSphere /*=0*/)
{
    ACP_tdxIndex xNumElement = (ACP_tdxIndex)hElement;

    return ( (xNumElement < GEO_xGetGeometricObjectNumberOfElements(GetStruct())) &&
             (GEO_xGetElementType(GetStruct(),hElement) == GEO_C_xElementSpheres) &&
             (xNumSphere < GEO_lGetIndexedSphereNbSpheres(GetStruct(),xNumElement)) );
}

/* -----------------09/01/97 11:44-------------------
   Description : TRUE if (hElement,xNumBox) references a box
 --------------------------------------------------*/
BOOL Geometry3D::fn_bIsAlignedBox(ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumBox /*=0*/)
{
    ACP_tdxIndex xNumElement = (ACP_tdxIndex)hElement;

    return ( (xNumElement < GEO_xGetGeometricObjectNumberOfElements(GetStruct())) &&
             (GEO_xGetElementType(GetStruct(),hElement) == GEO_C_xElementAlignedBoxes) &&
             (xNumBox < GEO_lGetAlignedBoxNbBoxes(GetStruct(),xNumElement)) );
}

/* -------------------------------------------------
   Description : TRUE if (hElement,xNumCone) references a cone
 --------------------------------------------------*/
BOOL Geometry3D::fn_bIsCone(ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumCone /*=0*/)
{
    ACP_tdxIndex xNumElement = (ACP_tdxIndex)hElement;

    return ( (xNumElement < GEO_xGetGeometricObjectNumberOfElements(GetStruct())) &&
             (GEO_xGetElementType(GetStruct(),hElement) == GEO_C_xElementCones) &&
             (xNumCone < GEO_lGetConeNbCones(GetStruct(),xNumElement)) );
}

/* -------------------------------------------------
   Description : TRUE if (hElement,xNumFace) references a face of an IndexedTriangle
 --------------------------------------------------*/
BOOL Geometry3D::fn_bIsIndexedTriangle(ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumFace /*=0*/)
{
    ACP_tdxIndex xNumElement = (ACP_tdxIndex)hElement;

    return ( (xNumElement < GEO_xGetGeometricObjectNumberOfElements(GetStruct())) &&
             (GEO_xGetElementType(GetStruct(),hElement) == GEO_C_xElementIndexedTriangles) /*&&
             (xNumFace < GEO_lGetITNbFaces(GetStruct(),xNumElement))*/ );
}

/* -------------------------------------------------
   Description : TRUE if (hElement,xNumPoint) references a Point
 --------------------------------------------------*/
BOOL Geometry3D::fn_bIsPoint(ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumPoint /*=0*/)
{
    ACP_tdxIndex xNumElement = (ACP_tdxIndex)hElement;

    return ( (xNumElement < GEO_xGetGeometricObjectNumberOfElements(GetStruct())) &&
             (GEO_xGetElementType(GetStruct(),hElement) == GEO_C_xElementPoints) &&
             (xNumPoint < GEO_lGetElementPointsNbPoints(GetStruct(),xNumElement)) );
}

/* -------------------------------------------------
   Description : TRUE if (hElement,xNumLine) references a Line
 --------------------------------------------------*/
BOOL Geometry3D::fn_bIsLine(ACP_tdxHandleOfElement hElement /*=0*/, ACP_tdxIndex xNumLine /*=0*/)
{
    ACP_tdxIndex xNumElement = (ACP_tdxIndex)hElement;

    return ( (xNumElement < GEO_xGetGeometricObjectNumberOfElements(GetStruct())) &&
             (GEO_xGetElementType(GetStruct(),hElement) == GEO_C_xElementLines) &&
             (xNumLine < GEO_lGetElementLinesNbLines(GetStruct(),xNumElement)) );
}

// BEGIN CPA2 Cristi Petrescu 98-03-
/* -------------------------------------------------
   Description : TRUE if (hElement,xNumLine) references an Altimap
 --------------------------------------------------*/
BOOL Geometry3D::fn_bIsAltimap(ACP_tdxHandleOfElement hElement)
{
    ACP_tdxIndex xNumElement = (ACP_tdxIndex)hElement;

    return ( (xNumElement < GEO_xGetGeometricObjectNumberOfElements(GetStruct())) &&
             (GEO_xGetElementType(GetStruct(),hElement) == GEO_C_xElementAltimap) );
}
// END CPA2 Cristi Petrescu 98-03-

BOOL Geometry3D::fn_bIsFMD(ACP_tdxHandleOfElement hElement, ACP_tdxIndex xNumFace /*=0*/)
{
    ACP_tdxIndex xNumElement = (ACP_tdxIndex)hElement;
    GEO_tdstElementFaceMapDescriptors *p_stEFMD = (GEO_tdstElementFaceMapDescriptors*) GetStruct() -> d_stListOfElements[ hElement ];

    return ( (xNumElement < GEO_xGetGeometricObjectNumberOfElements(GetStruct())) &&
             (GEO_xGetElementType(GetStruct(),hElement) == GEO_C_xElementFaceMapDescriptors) &&
             (xNumFace < p_stEFMD -> xNbFaces) );

}
// ----------------------------------------------------------------------------
// Description : Compute referenced section name of given element
// ----------------------------------------------------------------------------
void Geometry3D::fn_vComputeElementReferencedSectionName(char *_szSectionName, ACP_tdxHandleOfElement _hElement)
{
    char    szFileName   [ SCR_CV_ui_Cfg_MaxLenName ];
    char    szElementName[ SCR_CV_ui_Cfg_MaxLenName ];
    char    szElementType[ SCR_CV_ui_Cfg_MaxLenName ];

    // get file name
    SCR_fn_v_RdL0_SplitSectionName( (char*)(LPCTSTR)GetReferencedSectionName(), szFileName, NULL, NULL );
    // get action name
    sprintf( szElementType, "Element%s", g_szElementTypeName[ GEO_xGetElementType( GetStruct(), _hElement ) ] );
    // get Id name
    sprintf( szElementName, "%s_element%02d", (char*)(LPCTSTR) GetName(), _hElement );
    // compute section name
    SCR_fn_v_RdL0_ComputeSectionName( _szSectionName, szFileName, szElementType, szElementName );
    //
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
void Geometry3D::fn_vInitElementSection(ACP_tdxHandleOfElement _hElement)
{
    if( fn_bCanBeNotified() )
    {
        char szSectionName[ SCR_CV_ui_Cfg_MaxLenName ];
        // find CPA_Section
        POSITION xPos = m_oListOfElementSections . FindIndex( _hElement );
        if( xPos )
        {
            SectionElement *p_oSection = m_oListOfElementSections . GetAt( xPos );
            //compute referenced section name
            fn_vComputeElementReferencedSectionName( szSectionName, _hElement );
            p_oSection -> SetReferencedSectionName(szSectionName);
            p_oSection -> SetElement( (void*) GetStruct() -> d_stListOfElements[ _hElement ] );
        }
    }
}