936 lines
33 KiB
C
936 lines
33 KiB
C
/*=========================================================================
|
|
*
|
|
* Altimap.h - Altimap functions
|
|
*
|
|
* Version 1.0
|
|
* Revision date
|
|
*
|
|
*=======================================================================*/
|
|
#include "Altimaps.h"
|
|
|
|
#include "sprobj.h"
|
|
|
|
#include "SpoSave.h"
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
* Description: Test if an element is altimap or not
|
|
*
|
|
* Parameters: p_fX : elements to test
|
|
* p_iEqualX : returns the equal elements
|
|
* p_stGeometric : geometric object
|
|
* k : returns number of equal elements
|
|
*---------------------------------------------------------------------------
|
|
* Revision date: Author:
|
|
*****************************************************************************/
|
|
BOOL MLT_bIsAltimap(float **p_fX, int **p_iEqualX, MLT_tdstGeometricObject *p_stGeometric, int *k)
|
|
{
|
|
int i=0;
|
|
BOOL bTrue;
|
|
float x1;
|
|
|
|
(*p_iEqualX)[0]=1;
|
|
*k=0;
|
|
|
|
// get the elements from the array with x coordinates which
|
|
// are closed till a limit fLimit with the first element of the sorted array
|
|
// continue with completing the arrays with equal elements
|
|
while (i<=p_stGeometric->xNbPoints)
|
|
{
|
|
x1=(*p_fX)[i];
|
|
// when all the values are equal, get that number
|
|
while ( (*p_fX)[i+1] == x1)
|
|
{
|
|
i++;
|
|
(*p_iEqualX)[*k]++;
|
|
}
|
|
i++;
|
|
(*k)++;
|
|
(*p_iEqualX)[(*k)]=1;
|
|
}
|
|
bTrue=TRUE;
|
|
|
|
//test if the number of equal elements is exactly the same for all the pars
|
|
for (i=0;i<*k-2; i++)
|
|
if ((*p_iEqualX)[i]!=(*p_iEqualX)[i+1])
|
|
bTrue = FALSE;
|
|
return bTrue;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Description: complete the structure of the altimap element
|
|
*
|
|
* Parameters: p_stGeometric : geometric object
|
|
* p_stAltimap : altimap element
|
|
*---------------------------------------------------------------------------
|
|
* Revision date: Author:
|
|
*****************************************************************************/
|
|
void MLT_vCompleteAltimapStructure(MLT_tdstGeometricObject *p_stGeometric, MLT_tdstElementAltimap* p_stAltimap)
|
|
{
|
|
MLT_tdstElementIndexedTriangles *p_stGeom, *p_stGeomNext;
|
|
MLT_tdstTripledIndex *d_stVertexIndexes;
|
|
BOOL bIsAltimap, bIsFirstTriangle;
|
|
float *d_fX, *d_fY;
|
|
int m, i, k, j, l, iNew, iIndexSquare;
|
|
int *d_iInd, *d_iXIndex, *d_iXIndexFinal, *d_iEqualX;
|
|
int iLin, iCol;
|
|
int iFirst;
|
|
int iLast;
|
|
|
|
//allocate the intermediare vectors for vertexes
|
|
d_fX = (float *)malloc(p_stGeometric->xNbPoints*sizeof(float));
|
|
if (d_fX==NULL) //test if it could be allocated
|
|
{
|
|
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
|
|
return ;
|
|
}
|
|
d_fY = (float *)malloc(p_stGeometric->xNbPoints*sizeof(float));
|
|
//test if it could be allocated
|
|
if (d_fY==NULL)
|
|
{
|
|
free(d_fX);
|
|
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
|
|
return ;
|
|
}
|
|
p_stAltimap->d_stPointNormals = (MTH3D_tdstVector *)malloc(sizeof(MTH3D_tdstVector)*p_stGeometric->xNbPoints);
|
|
//test if it could be allocated
|
|
if (p_stAltimap->d_stPointNormals==NULL)
|
|
{
|
|
free(d_fX);
|
|
free(d_fY);
|
|
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
|
|
return ;
|
|
}
|
|
p_stAltimap->d_xHeight = (MTH_tdxReal *)malloc(sizeof(MTH_tdxReal)*p_stGeometric->xNbPoints);
|
|
//test if it could be allocated
|
|
if (p_stAltimap->d_xHeight==NULL)
|
|
{
|
|
free(d_fX);
|
|
free(d_fY);
|
|
free(p_stAltimap->d_stPointNormals);
|
|
free(p_stAltimap);
|
|
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
|
|
return ;
|
|
}
|
|
d_iXIndex = (int *)malloc(p_stGeometric->xNbPoints*sizeof(int));
|
|
//test if it could be allocated
|
|
if (d_iXIndex==NULL)
|
|
{
|
|
free(d_fX);
|
|
free(d_fY);
|
|
MLT_vFree(p_stAltimap);
|
|
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
|
|
return ;
|
|
}
|
|
|
|
//determine the number of faces and the number of UVs for the element altimap
|
|
p_stGeom = (MLT_tdstElementIndexedTriangles*)(p_stGeometric->d_stListOfElements[0]);
|
|
p_stAltimap->xNbElementUV=0;
|
|
p_stAltimap->xNbFaces = 0;
|
|
for(i=0; i<p_stGeometric->xNbElements; i++)
|
|
{ p_stGeom = (MLT_tdstElementIndexedTriangles*)(p_stGeometric->d_stListOfElements[i]);
|
|
//get the number of Faces and maximum number of elementUV for the altimap
|
|
p_stAltimap->xNbFaces += p_stGeom->xNbFaces;
|
|
p_stAltimap->xNbElementUV += p_stGeom->xNbElementUV;
|
|
}
|
|
|
|
d_stVertexIndexes = (MLT_tdstTripledIndex *)malloc((p_stAltimap->xNbFaces)*sizeof(MLT_tdstTripledIndex));
|
|
if (d_stVertexIndexes==NULL)//test if it could be allocated
|
|
{
|
|
free(d_fX);
|
|
free(d_fY);
|
|
MLT_vFree(p_stAltimap);
|
|
free(d_iXIndex);
|
|
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
|
|
return ;
|
|
}
|
|
//get the initial values for the X, Y coordinates, the height, and the normals in X, Y, Z
|
|
for (i=0; i< p_stGeometric->xNbPoints; i++)
|
|
{ d_fX[i] = p_stGeometric->d_stListOfPoints[i].xX;
|
|
d_fY[i] = p_stGeometric->d_stListOfPoints[i].xY;
|
|
p_stAltimap->d_xHeight[i] = p_stGeometric->d_stListOfPoints[i].xZ;
|
|
MTH3D_M_vSetVectorElements(&p_stAltimap->d_stPointNormals[i],
|
|
p_stGeometric->d_stListOfPointsNormals[i].xX,
|
|
p_stGeometric->d_stListOfPointsNormals[i].xY,
|
|
p_stGeometric->d_stListOfPointsNormals[i].xZ);
|
|
d_iXIndex[i] = i;
|
|
}
|
|
|
|
//get also the indexes of the vertexes which creates a face
|
|
k=0;
|
|
for(j=0; j<p_stGeometric->xNbElements; j++)
|
|
{ p_stGeom = (MLT_tdstElementIndexedTriangles*)(p_stGeometric->d_stListOfElements[j]);
|
|
for (i=0; i<p_stGeom->xNbFaces; i++)
|
|
{ d_stVertexIndexes[k+i].a3_xIndex[0] = p_stGeom->d_stListOfFacesTripled[i].a3_xIndex[0];
|
|
d_stVertexIndexes[k+i].a3_xIndex[1] = p_stGeom->d_stListOfFacesTripled[i].a3_xIndex[1];
|
|
d_stVertexIndexes[k+i].a3_xIndex[2] = p_stGeom->d_stListOfFacesTripled[i].a3_xIndex[2];
|
|
}
|
|
k += p_stGeom->xNbFaces;
|
|
}
|
|
|
|
//sort the array with x coordinates
|
|
MLT_vBubbleSort(&d_fX, &d_iXIndex, p_stGeometric->xNbPoints);
|
|
//update all the vectors (y, z and normalx, normaly, normalz vor the vertexes after the sorted x array
|
|
MLT_vExchange(&d_fY, d_iXIndex, p_stGeometric->xNbPoints);
|
|
MLT_vExchange(&p_stAltimap->d_xHeight, d_iXIndex, p_stGeometric->xNbPoints);
|
|
MLT_vExchangeNormals(&p_stAltimap->d_stPointNormals, d_iXIndex, p_stGeometric->xNbPoints);
|
|
MLT_vExchangeIndexes(&d_stVertexIndexes, d_iXIndex, p_stAltimap->xNbFaces, p_stGeometric->xNbPoints);
|
|
|
|
d_iEqualX= (int *)malloc(1000*sizeof(int));
|
|
if (d_iEqualX==NULL)//test if it could be allocated
|
|
{
|
|
MLT_vFreeAlloc(d_fX, d_fY, d_stVertexIndexes);
|
|
MLT_vFree(p_stAltimap);
|
|
free(d_iXIndex);
|
|
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
|
|
return ;
|
|
}
|
|
if (bIsAltimap=MLT_bIsAltimap(&d_fX, &d_iEqualX, p_stGeometric, &k)) //if the object is an altimap
|
|
{ for (i=0; i< p_stGeometric->xNbPoints; i++)
|
|
d_iXIndex[i] = i;
|
|
MLT_vBubbleSort(&d_fY, &d_iXIndex, p_stGeometric->xNbPoints); //sort the array with the y coordinates
|
|
//update all the vectors (x, z and normalx, normaly, normalz vor the vertexes after the sorted x array
|
|
MLT_vExchange(&d_fX, d_iXIndex, p_stGeometric->xNbPoints);
|
|
MLT_vExchange(&p_stAltimap->d_xHeight, d_iXIndex, p_stGeometric->xNbPoints);
|
|
MLT_vExchangeNormals(&p_stAltimap->d_stPointNormals, d_iXIndex, p_stGeometric->xNbPoints);
|
|
MLT_vExchangeIndexes(&d_stVertexIndexes, d_iXIndex, p_stAltimap->xNbFaces, p_stGeometric->xNbPoints);
|
|
|
|
iFirst = 0;
|
|
iLast = k-2;
|
|
//sort the array of X coordinates between the indexes: 0:k-2,k-1:...
|
|
for (i=0; i< p_stGeometric->xNbPoints; i++)
|
|
d_iXIndex[i] = i;
|
|
while (iLast<p_stGeometric->xNbPoints-1)
|
|
{
|
|
MLT_vFinalSort(&d_fX, &d_iXIndex, iFirst, iLast);
|
|
iFirst += k-1;
|
|
iLast += k-1;
|
|
}
|
|
MLT_vExchange(&d_fY, d_iXIndex, p_stGeometric->xNbPoints);
|
|
MLT_vExchange(&p_stAltimap->d_xHeight, d_iXIndex, p_stGeometric->xNbPoints);
|
|
MLT_vExchangeNormals(&p_stAltimap->d_stPointNormals, d_iXIndex, p_stGeometric->xNbPoints);
|
|
MLT_vExchangeIndexes(&d_stVertexIndexes, d_iXIndex, p_stAltimap->xNbFaces, p_stGeometric->xNbPoints);
|
|
|
|
}
|
|
free(d_iXIndex);
|
|
//if it was not an altimap return, after deallocated all
|
|
if (!bIsAltimap)
|
|
{
|
|
MLT_vFreeAlloc(d_fX, d_fY, d_stVertexIndexes);
|
|
if (d_iEqualX) free(d_iEqualX);
|
|
MLT_vFree(p_stAltimap);
|
|
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
|
|
return;
|
|
}
|
|
//set the components of the altimap
|
|
//set the origin
|
|
MTH3D_M_vSetVectorElements(&p_stAltimap->stOrigin, d_fX[0], d_fY[0], p_stAltimap->d_xHeight[0]);
|
|
//set the square pattern
|
|
p_stAltimap->xDeltaX = (d_fX[k-2]-d_fX[0])/(k-2);
|
|
p_stAltimap->xDeltaY = (d_fY[p_stGeometric->xNbPoints-k+1]-d_fY[0])/(d_iEqualX[0]-1); //d_fY[p_stGeometric->xNbPoints/d_iEqualX[0]]-d_fY[0];
|
|
p_stAltimap->xWidth = k-2;
|
|
p_stAltimap->xDepth = d_iEqualX[0]-1;
|
|
free(d_iEqualX);
|
|
|
|
//see if the values are good in a precision of fLimit=0.001
|
|
bIsAltimap=TRUE;
|
|
for (i=0; i<p_stGeometric->xNbPoints; i++)
|
|
{
|
|
//get the column and line for the index i
|
|
iCol = i % ( p_stAltimap->xWidth+1);
|
|
iLin = (i-iCol)/(p_stAltimap->xWidth+1);
|
|
//if the data is in the precision, arange the values, if not is not an altimap
|
|
if (fabs(d_fX[i]-d_fX[0]-iCol*p_stAltimap->xDeltaX)<=g_fLimit1)
|
|
d_fX[i] = d_fX[0]+iCol*p_stAltimap->xDeltaX;
|
|
else
|
|
bIsAltimap=FALSE;
|
|
if (fabs(d_fY[i]-d_fY[0]-iLin*p_stAltimap->xDeltaY)<=g_fLimit1)
|
|
d_fY[i] = d_fY[0]+iLin*p_stAltimap->xDeltaY;
|
|
else
|
|
bIsAltimap=FALSE;
|
|
}
|
|
//if it was not an altimap return, after deallocated all
|
|
if (!bIsAltimap)
|
|
{
|
|
MLT_vFreeAlloc(d_fX, d_fY, d_stVertexIndexes);
|
|
MLT_vFree(p_stAltimap);
|
|
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
|
|
return;
|
|
}
|
|
|
|
//set the number of squares and vertexes
|
|
p_stAltimap->xNbSquares = p_stAltimap->xWidth*p_stAltimap->xDepth; //k-2;
|
|
p_stAltimap->xNbVertexes = p_stGeometric->xNbPoints;
|
|
p_stAltimap->d_stSquare = (MLT_tdstAltimapSquare *)malloc(sizeof(MLT_tdstAltimapSquare)*p_stAltimap->xNbSquares);
|
|
//alloc all the structure needed by the altimap
|
|
//test if it could be allocated
|
|
if (p_stAltimap->d_stSquare==NULL)
|
|
{
|
|
MLT_vFree(p_stAltimap);
|
|
MLT_vFreeAlloc(d_fX, d_fY, d_stVertexIndexes);
|
|
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
|
|
return ;
|
|
}
|
|
p_stAltimap->d_stFaceNormals = (MTH3D_tdstVector *)malloc(sizeof(MTH3D_tdstVector)*p_stAltimap->xNbFaces);
|
|
//test if it could be allocated
|
|
if (p_stAltimap->d_stFaceNormals==NULL)
|
|
{
|
|
free(p_stAltimap->d_stSquare);
|
|
MLT_vFree(p_stAltimap);
|
|
MLT_vFreeAlloc(d_fX, d_fY, d_stVertexIndexes);
|
|
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
|
|
return ;
|
|
}
|
|
p_stAltimap->d_hFMD = (MLT_tdxHandleOfFMD *)malloc(sizeof(MLT_tdxHandleOfFMD)*p_stAltimap->xNbFaces);
|
|
//test if it could be allocated
|
|
if (p_stAltimap->d_hFMD==NULL)
|
|
{
|
|
free(p_stAltimap->d_stSquare);
|
|
free(p_stAltimap->d_stFaceNormals);
|
|
MLT_vFree(p_stAltimap);
|
|
MLT_vFreeAlloc(d_fX, d_fY, d_stVertexIndexes);
|
|
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
|
|
return ;
|
|
}
|
|
for (i=0; i<p_stAltimap->xNbFaces; i++)
|
|
{ p_stAltimap->d_hFMD[i] = (MLT_tdstHandleOfFMD *)malloc(sizeof(MLT_tdstHandleOfFMD));
|
|
if (p_stAltimap->d_hFMD[i]==NULL)//test if it could be allocated
|
|
{
|
|
free(p_stAltimap->d_stSquare);
|
|
free(p_stAltimap->d_stFaceNormals);
|
|
free(p_stAltimap->d_hFMD);
|
|
MLT_vFree(p_stAltimap);
|
|
MLT_vFreeAlloc(d_fX, d_fY, d_stVertexIndexes);
|
|
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
|
|
return ;
|
|
}
|
|
}
|
|
p_stAltimap->d_stUVValues = (ACP_tdst2DUVValues *)malloc(sizeof(ACP_tdst2DUVValues)*p_stAltimap->xNbElementUV);
|
|
if (p_stAltimap->d_stUVValues==NULL)//test if it could be allocated
|
|
{
|
|
free(p_stAltimap->d_stSquare);
|
|
free(p_stAltimap->d_stFaceNormals);
|
|
for (i=0; i<p_stAltimap->xNbFaces; i++)
|
|
free(p_stAltimap->d_hFMD[i]);
|
|
free(p_stAltimap->d_hFMD);
|
|
MLT_vFree(p_stAltimap);
|
|
MLT_vFreeAlloc(d_fX, d_fY, d_stVertexIndexes);
|
|
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
|
|
return ;
|
|
}
|
|
|
|
//set the types, number of faces and the index of the first triangle for every square
|
|
for (i=0;i<p_stAltimap->xNbSquares;i++)
|
|
{ p_stAltimap->d_stSquare[i].ucType = 0;
|
|
p_stAltimap->d_stSquare[i].sNbFacesForSquare = 0;
|
|
p_stAltimap->d_stSquare[i].xFaceIndex = -1;
|
|
}
|
|
d_iXIndex = (int *)malloc(2*p_stAltimap->xNbSquares*sizeof(int));
|
|
if (d_iXIndex==NULL)
|
|
{
|
|
MLT_vFreeAltimap(p_stAltimap);
|
|
MLT_vFreeAlloc(d_fX, d_fY, d_stVertexIndexes);
|
|
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
|
|
return ;
|
|
}
|
|
|
|
d_iXIndexFinal = (int *)malloc(p_stAltimap->xNbFaces*sizeof(int));
|
|
//test if it could be allocated
|
|
if (d_iXIndexFinal==NULL)
|
|
{
|
|
MLT_vFreeAltimap(p_stAltimap);
|
|
MLT_vFreeAlloc(d_fX, d_fY, d_stVertexIndexes);
|
|
free(d_iXIndex);
|
|
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
|
|
return ;
|
|
}
|
|
for (i=0; i<2*p_stAltimap->xNbSquares; i++)
|
|
d_iXIndex[i]=-1;
|
|
//for every square get the indexes for the triangles associated with a square
|
|
for (i=0; i<p_stAltimap->xNbFaces; i++)
|
|
{ iIndexSquare = MLT_iIndexSquare(&d_stVertexIndexes[i], p_stAltimap, &bIsFirstTriangle);
|
|
if (iIndexSquare==-1)
|
|
{
|
|
if (d_iXIndex) free(d_iXIndex);
|
|
if (d_iXIndexFinal) free(d_iXIndexFinal);
|
|
MLT_vFreeAlloc(d_fX, d_fY, d_stVertexIndexes);
|
|
MLT_vFreeAltimap(p_stAltimap);
|
|
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
|
|
return;
|
|
}
|
|
if (d_iXIndex[2*iIndexSquare] == -1)
|
|
d_iXIndex[2*iIndexSquare] = i;
|
|
else
|
|
if (bIsFirstTriangle)
|
|
{ d_iXIndex[2*iIndexSquare+1] = d_iXIndex[2*iIndexSquare];
|
|
d_iXIndex[2*iIndexSquare] = i;
|
|
}
|
|
else
|
|
d_iXIndex[2*iIndexSquare+1] = i;
|
|
}
|
|
j=0;
|
|
for (i=0; i<2*p_stAltimap->xNbSquares; i++)
|
|
{ if (d_iXIndex[i] != -1)
|
|
{ d_iXIndexFinal[j] = d_iXIndex[i];
|
|
j++;
|
|
}
|
|
}
|
|
free(d_iXIndex);
|
|
|
|
//get the UVs for the altimap element
|
|
p_stGeom=(MLT_tdstElementIndexedTriangles*)(p_stGeometric->d_stListOfElements[0]);
|
|
for (i=0; i<p_stGeom->xNbElementUV; i++)
|
|
{ p_stAltimap->d_stUVValues[i].xU = p_stGeom->d_stListOfElementUV[i].xU;
|
|
p_stAltimap->d_stUVValues[i].xV = p_stGeom->d_stListOfElementUV[i].xV;
|
|
}
|
|
p_stAltimap->xNbElementUV = p_stGeom->xNbElementUV;
|
|
|
|
//get also the material for a face
|
|
for (i=0; i<p_stAltimap->xNbFaces; i++)
|
|
if (d_iXIndexFinal[i] < p_stGeom->xNbFaces)
|
|
strcpy(p_stAltimap->d_hFMD[i]->sMaterial, p_stGeom->sMaterial);
|
|
//for every element indexed triangle, of the geometric object
|
|
for (l=1; l<p_stGeometric->xNbElements; l++)
|
|
{ p_stGeomNext=(MLT_tdstElementIndexedTriangles*)(p_stGeometric->d_stListOfElements[l]);
|
|
j=p_stGeom->xNbFaces;
|
|
m=p_stGeom->xNbElementUV;
|
|
p_stGeom->d_stListOfFacesNormals=(MTH3D_tdstVector *)realloc(p_stGeom->d_stListOfFacesNormals,
|
|
(p_stGeomNext->xNbFaces+j)*sizeof(MTH3D_tdstVector));
|
|
p_stGeom->d_stListOfElementUV=(ACP_tdst2DUVValues *)realloc(p_stGeom->d_stListOfElementUV,
|
|
(p_stGeomNext->xNbElementUV+m)*sizeof(ACP_tdst2DUVValues));
|
|
p_stGeom->d_stListOfFacesTripledIndexUV=(MLT_tdstTripledIndex *)realloc(p_stGeom->d_stListOfFacesTripledIndexUV,
|
|
(p_stGeomNext->xNbFaces+j)*sizeof(MLT_tdstTripledIndex));
|
|
for (i=0; i<p_stGeomNext->xNbFaces; i++)
|
|
{ //set the normals
|
|
MTH3D_M_vSetVectorElements(&p_stGeom->d_stListOfFacesNormals[i+j], p_stGeomNext->d_stListOfFacesNormals[i].xX, p_stGeomNext->d_stListOfFacesNormals[i].xY, p_stGeomNext->d_stListOfFacesNormals[i].xZ);
|
|
for (k=0; k<3; k++)
|
|
//add or not the new UV at the list of UVs for the indexed triangle which will contain a concatanation of indexed traingles
|
|
//and set also the list with tripled indexes for them
|
|
if(!MLT_bExist(p_stAltimap->d_stUVValues, p_stGeomNext->d_stListOfElementUV[p_stGeomNext->d_stListOfFacesTripledIndexUV[i].a3_xIndex[k]], &iNew, p_stAltimap->xNbElementUV))
|
|
{ p_stGeom->d_stListOfFacesTripledIndexUV[i+j].a3_xIndex[k] = m;
|
|
p_stAltimap->xNbElementUV++;
|
|
p_stGeom->d_stListOfElementUV[m].xU=p_stGeomNext->d_stListOfElementUV[p_stGeomNext->d_stListOfFacesTripledIndexUV[i].a3_xIndex[k]].xU;
|
|
p_stGeom->d_stListOfElementUV[m].xV=p_stGeomNext->d_stListOfElementUV[p_stGeomNext->d_stListOfFacesTripledIndexUV[i].a3_xIndex[k]].xV;
|
|
p_stAltimap->d_stUVValues[m].xU=p_stGeomNext->d_stListOfElementUV[p_stGeomNext->d_stListOfFacesTripledIndexUV[i].a3_xIndex[k]].xU;
|
|
p_stAltimap->d_stUVValues[m].xV=p_stGeomNext->d_stListOfElementUV[p_stGeomNext->d_stListOfFacesTripledIndexUV[i].a3_xIndex[k]].xV;
|
|
m++;
|
|
}
|
|
else
|
|
p_stGeom->d_stListOfFacesTripledIndexUV[i+j].a3_xIndex[k] = iNew;
|
|
}
|
|
p_stGeom->xNbFaces += p_stGeomNext->xNbFaces;
|
|
p_stGeom->xNbElementUV = m;
|
|
//set the materials for the faces which are own by the processed element indexed triangle
|
|
for (k=0; k<p_stAltimap->xNbFaces; k++)
|
|
if ((d_iXIndexFinal[k] < p_stGeomNext->xNbFaces+j) &&(d_iXIndexFinal[k] >= j))
|
|
strcpy(p_stAltimap->d_hFMD[k]->sMaterial, p_stGeomNext->sMaterial);
|
|
}
|
|
d_iInd = (int *)malloc(3*sizeof(int));
|
|
//test if it could be allocated
|
|
if (d_iInd==NULL)
|
|
{
|
|
MLT_vFreeAltimap(p_stAltimap);
|
|
MLT_vFreeAlloc(d_fX, d_fY, d_stVertexIndexes);
|
|
free(d_iXIndexFinal);
|
|
p_stGeometric->iFlags |= IS_NOT_ALTIMAP;
|
|
return ;
|
|
}
|
|
|
|
for (i=0; i<p_stAltimap->xNbFaces; i++)
|
|
{
|
|
//get the normals to the faces for tthe altimap element
|
|
MTH3D_M_vSetVectorElements(&p_stAltimap->d_stFaceNormals[i],
|
|
p_stGeom->d_stListOfFacesNormals[d_iXIndexFinal[i]].xX,
|
|
p_stGeom->d_stListOfFacesNormals[d_iXIndexFinal[i]].xY,
|
|
p_stGeom->d_stListOfFacesNormals[d_iXIndexFinal[i]].xZ);
|
|
MLT_vSortIndex(&d_stVertexIndexes[d_iXIndexFinal[i]], p_stAltimap,/* d_fX, d_fY,*/ &d_iInd);
|
|
//and the UVs
|
|
for (j=0; j<3; j++)
|
|
p_stAltimap->d_hFMD[i]->stTrianglesIndexUVValues.a3_xIndex[j]=
|
|
p_stGeom->d_stListOfFacesTripledIndexUV[d_iXIndexFinal[i]].a3_xIndex[d_iInd[j]];
|
|
}
|
|
//set also the index to start for every square, for every triangle
|
|
if (p_stAltimap->d_stSquare[0].sNbFacesForSquare)
|
|
p_stAltimap->d_stSquare[0].xFaceIndex = 0;
|
|
for (i=1; i<p_stAltimap->xNbSquares; i++)
|
|
p_stAltimap->d_stSquare[i].xFaceIndex += p_stAltimap->d_stSquare[i-1].xFaceIndex + p_stAltimap->d_stSquare[i-1].sNbFacesForSquare+1;
|
|
//deallocate all it used
|
|
free(d_stVertexIndexes);
|
|
free(d_iXIndexFinal);
|
|
free(d_iInd);
|
|
free(d_fX);
|
|
free(d_fY);
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
* Description: free some parts of the altimap
|
|
*
|
|
* Parameters: p_stAltimap : altimap element
|
|
*---------------------------------------------------------------------------
|
|
* Revision date: Author:
|
|
*****************************************************************************/
|
|
void MLT_vFreeAltimap(MLT_tdstElementAltimap* p_stAltimap)
|
|
{
|
|
int i;
|
|
|
|
free(p_stAltimap->d_stFaceNormals);
|
|
free(p_stAltimap->d_stSquare);
|
|
for (i=0; i<p_stAltimap->xNbFaces; i++)
|
|
free(p_stAltimap->d_hFMD[i]);
|
|
free(p_stAltimap->d_hFMD);
|
|
free(p_stAltimap->d_stUVValues);
|
|
MLT_vFree(p_stAltimap);
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
* Description: free the altimap
|
|
*
|
|
* Parameters: p_stAltimap : altimap element
|
|
*---------------------------------------------------------------------------
|
|
* Revision date: Author:
|
|
*****************************************************************************/
|
|
void MLT_vFree(MLT_tdstElementAltimap* p_stAltimap)
|
|
{
|
|
free(p_stAltimap->d_xHeight);
|
|
free(p_stAltimap->d_stPointNormals);
|
|
free(p_stAltimap);
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
* Description: free some allocated structures
|
|
*
|
|
* Parameters: d_fX : array of x coordinates
|
|
* d_fY : array of y coordinates
|
|
* d_stVertexIndexes : array of indexes
|
|
*---------------------------------------------------------------------------
|
|
* Revision date: Author:
|
|
*****************************************************************************/
|
|
void MLT_vFreeAlloc(float *d_fX, float *d_fY, MLT_tdstTripledIndex *d_stVertexIndexes)
|
|
{
|
|
free(d_fX);
|
|
free(d_fY);
|
|
free(d_stVertexIndexes);
|
|
}
|
|
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
* Description: sort an array using the bubble sort method
|
|
*
|
|
* Parameters: p_fX : array of cooridnates to sort
|
|
* p_iXIndex : array of indexes
|
|
* lNbPoints : nb of points in the array
|
|
*---------------------------------------------------------------------------
|
|
* Revision date: Author:
|
|
*****************************************************************************/
|
|
void MLT_vBubbleSort (float **p_fX, int **p_iXIndex, long lNbPoints)
|
|
{
|
|
BOOL bSwapped;
|
|
float fTemp;
|
|
int i, iTemp;
|
|
|
|
// sort the array using the bubble sort method,
|
|
// and also update the p_iXIndex array using the same method
|
|
// in p_iXIndex are the indices for the modified array
|
|
do
|
|
{
|
|
bSwapped=FALSE;
|
|
for(i = 0; i < lNbPoints-1; i++)
|
|
{
|
|
if ((*p_fX)[i+1]<(*p_fX)[i])
|
|
{ if (fabs((*p_fX)[i+1]-(*p_fX)[i])<=g_fLimit1)
|
|
(*p_fX)[i+1] = (*p_fX)[i];
|
|
else
|
|
{ // perform the swap
|
|
fTemp=(*p_fX)[i];
|
|
(*p_fX)[i]=(*p_fX)[i+1];
|
|
//change the values of array to sort
|
|
(*p_fX)[i+1]=fTemp;
|
|
iTemp=(*p_iXIndex)[i];
|
|
(*p_iXIndex)[i]=(*p_iXIndex)[i+1];
|
|
//change the ordered array
|
|
(*p_iXIndex)[i+1]=iTemp;
|
|
//according to the array to sort, for saving the indexes
|
|
bSwapped = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{ if (fabs((*p_fX)[i+1]-(*p_fX)[i])<=g_fLimit1)
|
|
(*p_fX)[i+1] = (*p_fX)[i];
|
|
}
|
|
}
|
|
} while (bSwapped);
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
* Description: sort an array using the bubble sort method
|
|
*
|
|
* Parameters: p_fX : array of cooridnates to sort
|
|
* p_iXIndex : array of indexes
|
|
* iFirst : first index
|
|
* iLast : last index
|
|
*---------------------------------------------------------------------------
|
|
* Revision date: Author:
|
|
*****************************************************************************/
|
|
void MLT_vFinalSort(float **p_fX, int **p_iXIndex, int iFirst, int iLast)
|
|
{
|
|
BOOL bSwapped;
|
|
float fTemp;
|
|
int i, iTemp;
|
|
|
|
do
|
|
{
|
|
bSwapped=FALSE;
|
|
for(i = iFirst; i < iLast-1; i++)
|
|
{
|
|
if ((*p_fX)[i+1]<(*p_fX)[i])
|
|
{ // perform the swap
|
|
fTemp=(*p_fX)[i];
|
|
(*p_fX)[i]=(*p_fX)[i+1];
|
|
//change the values of array to sort
|
|
(*p_fX)[i+1]=fTemp;
|
|
iTemp=(*p_iXIndex)[i];
|
|
(*p_iXIndex)[i]=(*p_iXIndex)[i+1];
|
|
//change the ordered array
|
|
(*p_iXIndex)[i+1]=iTemp;
|
|
//according to the array to sort, for saving the indexes
|
|
bSwapped = TRUE;
|
|
}
|
|
}
|
|
} while (bSwapped);
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
* Description: Sort the arrays with indexes of columns and lines
|
|
*
|
|
* Parameters: p_stListOfFaces : list of faces
|
|
* p_stAltimap : altimap element
|
|
* p_iInd : array of indexes
|
|
*---------------------------------------------------------------------------
|
|
* Revision date: Author:
|
|
*****************************************************************************/
|
|
void MLT_vSortIndex(MLT_tdstTripledIndex *p_stListOfFaces, MLT_tdstElementAltimap* p_stAltimap, int **p_iInd)
|
|
{
|
|
int i, *d_iCol, *d_iLin;
|
|
d_iCol = (int *)malloc(sizeof(int)*3);
|
|
d_iLin = (int *)malloc(sizeof(int)*3);
|
|
for (i=0; i<3; i++)
|
|
{
|
|
(*p_iInd)[i] = i;
|
|
//get the column and the line of every triangle
|
|
d_iCol[i] = p_stListOfFaces->a3_xIndex[i] % (p_stAltimap->xWidth+1);
|
|
d_iLin[i] = (p_stListOfFaces->a3_xIndex[i] -d_iCol[i]) / (p_stAltimap->xWidth+1);
|
|
}
|
|
MLT_vOrder(&d_iCol, p_iInd);
|
|
MLT_vArrangeArray(&d_iLin, *p_iInd);
|
|
MLT_vOrder(&d_iLin, p_iInd);
|
|
free(d_iCol);
|
|
free(d_iLin);
|
|
}
|
|
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
* Description: Change an array according with an array of indexes
|
|
*
|
|
* Parameters: p_fX : array to change
|
|
* p_iXIndex : array of indexes
|
|
* lNbPoints : nb of points
|
|
*---------------------------------------------------------------------------
|
|
* Revision date: Author:
|
|
*****************************************************************************/
|
|
void MLT_vExchange(float **p_fX, int *p_iXIndex, long lNbPoints)
|
|
{
|
|
int i;
|
|
float *d_fTemp;
|
|
|
|
d_fTemp = (float *)malloc(lNbPoints*sizeof(float));
|
|
//set the x, y, and z arrays with coordinates after the positions from the p_iXIndex array
|
|
for (i=0; i<lNbPoints; i++)
|
|
d_fTemp[i] = (*p_fX)[p_iXIndex[i]];
|
|
for (i=0; i<lNbPoints; i++)
|
|
(*p_fX)[i] = d_fTemp[i];
|
|
free(d_fTemp);
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
* Description: Change the Tripled Indexes according with an given index
|
|
*
|
|
* Parameters: p_fX : array to change
|
|
* p_iXIndex : array of indexes
|
|
* lNbPoints : nb of points
|
|
* lGeomPoints : nb of points in geometry
|
|
*---------------------------------------------------------------------------
|
|
* Revision date: Author:
|
|
*****************************************************************************/
|
|
void MLT_vExchangeIndexes(MLT_tdstTripledIndex **p_fX, int *p_iXIndex, long lNbPoints, long lGeomPoints)
|
|
{
|
|
int i=0;
|
|
MLT_tdstTripledIndex *d_stTemp;
|
|
|
|
d_stTemp = (MLT_tdstTripledIndex *)malloc(lNbPoints*sizeof(MLT_tdstTripledIndex));
|
|
//set the tripled indexes according to the indexes
|
|
for (i=0; i<lNbPoints; i++)
|
|
{
|
|
d_stTemp[i].a3_xIndex[0] = MLT_iGetIndex(p_iXIndex, (*p_fX)[i].a3_xIndex[0],lGeomPoints);
|
|
d_stTemp[i].a3_xIndex[1] = MLT_iGetIndex(p_iXIndex, (*p_fX)[i].a3_xIndex[1],lGeomPoints);
|
|
d_stTemp[i].a3_xIndex[2] = MLT_iGetIndex(p_iXIndex, (*p_fX)[i].a3_xIndex[2],lGeomPoints);
|
|
}
|
|
for (i=0; i<lNbPoints; i++)
|
|
{ (*p_fX)[i].a3_xIndex[0] = d_stTemp[i].a3_xIndex[0];
|
|
(*p_fX)[i].a3_xIndex[1] = d_stTemp[i].a3_xIndex[1];
|
|
(*p_fX)[i].a3_xIndex[2] = d_stTemp[i].a3_xIndex[2];
|
|
}
|
|
free(d_stTemp);
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
* Description: Change the normals according with an given index
|
|
*
|
|
* Parameters: p_fX : array to change
|
|
* p_iXIndex : array of indexes
|
|
* lNbPoints : nb of points
|
|
*---------------------------------------------------------------------------
|
|
* Revision date: Author:
|
|
*****************************************************************************/
|
|
void MLT_vExchangeNormals(MTH3D_tdstVector **p_fX, int *p_iXIndex, long lNbPoints)
|
|
{
|
|
int i;
|
|
MTH3D_tdstVector *d_stTemp;
|
|
|
|
d_stTemp = (MTH3D_tdstVector *)malloc(lNbPoints*sizeof(MTH3D_tdstVector));
|
|
//set the x, y, and z arrays with coordinates after the positions from the p_iXIndex array
|
|
for (i=0; i<lNbPoints; i++)
|
|
MTH3D_M_vSetVectorElements(&d_stTemp[i],
|
|
(*p_fX)[p_iXIndex[i]].xX,
|
|
(*p_fX)[p_iXIndex[i]].xY,
|
|
(*p_fX)[p_iXIndex[i]].xZ);
|
|
for (i=0; i<lNbPoints; i++)
|
|
MTH3D_M_vSetVectorElements(&(*p_fX)[i],
|
|
d_stTemp[i].xX,
|
|
d_stTemp[i].xY,
|
|
d_stTemp[i].xZ);
|
|
|
|
free(d_stTemp);
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
* Description: order an array according with a given index
|
|
*
|
|
* Parameters: p_iValues : array to order
|
|
* p_iInd : array of indexes
|
|
*---------------------------------------------------------------------------
|
|
* Revision date: Author:
|
|
*****************************************************************************/
|
|
void MLT_vOrder (int **p_iValues, int ** p_iInd)
|
|
{
|
|
BOOL bSwapped;
|
|
int i, iTemp;
|
|
|
|
do
|
|
{
|
|
bSwapped=FALSE;
|
|
for(i = 0; i < 2; i++)
|
|
{
|
|
//arrange an array with integers
|
|
if ((*p_iValues)[i+1] < (*p_iValues)[i])
|
|
{
|
|
iTemp=(*p_iValues)[i];
|
|
(*p_iValues)[i]=(*p_iValues)[i+1];
|
|
(*p_iValues)[i+1]=iTemp;
|
|
//arrange the array with indexes for showing how the first array is update
|
|
iTemp=(*p_iInd)[i];
|
|
(*p_iInd)[i]=(*p_iInd)[i+1];
|
|
(*p_iInd)[i+1]=iTemp;
|
|
bSwapped = TRUE;
|
|
}
|
|
}
|
|
} while (bSwapped);
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
* Description: Arrange an array with integers after an array with indexes
|
|
*
|
|
* Parameters: p_iCol : array to order
|
|
* p_iInd : array of indexes
|
|
*---------------------------------------------------------------------------
|
|
* Revision date: Author:
|
|
*****************************************************************************/
|
|
void MLT_vArrangeArray(int **p_iCol, int *p_iInd)
|
|
{
|
|
int i, iTemp[3];
|
|
for (i=0; i<3; i++)
|
|
iTemp[i] = (*p_iCol)[p_iInd[i]];
|
|
for (i=0; i<3; i++)
|
|
(*p_iCol)[i] = iTemp[i];
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
* Description: Get the minumum value from an array
|
|
*
|
|
* Parameters: p_iValues : array to search
|
|
*---------------------------------------------------------------------------
|
|
* Revision date: Author:
|
|
*****************************************************************************/
|
|
int MLT_iMin (int *p_iValues)
|
|
{
|
|
int i, iMin=p_iValues[0];
|
|
//get the minimum value of an array
|
|
for (i=1; i<3; i++)
|
|
if (p_iValues[i]<iMin)
|
|
iMin=p_iValues[i];
|
|
return iMin;
|
|
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Description: Get the index of value in an array
|
|
*
|
|
* Parameters: p_iXIndex : array to search
|
|
* iValue : value to search for
|
|
* lNbPoints : number of points
|
|
*---------------------------------------------------------------------------
|
|
* Revision date: Author:
|
|
*****************************************************************************/
|
|
int MLT_iGetIndex (int *p_iXIndex, int iValue, long lNbPoints)
|
|
{
|
|
int i;
|
|
|
|
for (i=0; i<lNbPoints;i++)
|
|
{
|
|
//return the index of the element which have a value equal to the searched one
|
|
if (p_iXIndex[i]==iValue)
|
|
return i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
* Description: Get the index of a square which contains the triangle
|
|
*
|
|
* Parameters: p_stListOfFaces : list of faces
|
|
* p_stAltimap : altimap element
|
|
* bIsFirst : flag for the search
|
|
*---------------------------------------------------------------------------
|
|
* Revision date: Author:
|
|
*****************************************************************************/
|
|
int MLT_iIndexSquare(MLT_tdstTripledIndex *p_stListOfFaces, MLT_tdstElementAltimap* p_stAltimap, BOOL *bIsFirst)
|
|
{
|
|
int i, *d_iCol, *d_iLin, *d_iInd;
|
|
|
|
d_iCol = (int *)malloc(sizeof(int)*3);
|
|
d_iLin = (int *)malloc(sizeof(int)*3);
|
|
d_iInd = (int *)malloc(sizeof(int)*3);
|
|
|
|
//get the indexes of the columns and lines for the three points which forms a triangle
|
|
for (i=0; i<3; i++)
|
|
{ d_iInd[i] = i;
|
|
d_iCol[i] = p_stListOfFaces->a3_xIndex[i] % (p_stAltimap->xWidth+1);
|
|
d_iLin[i] = (p_stListOfFaces->a3_xIndex[i] -d_iCol[i]) / (p_stAltimap->xWidth+1);
|
|
}
|
|
|
|
//get the sorted array with the column indexes
|
|
MLT_vOrder(&d_iCol, &d_iInd);
|
|
MLT_vArrangeArray(&d_iLin, d_iInd);
|
|
for (i=0; i<3; i++)
|
|
d_iInd[i] = i;
|
|
MLT_vOrder(&d_iLin, &d_iInd);
|
|
MLT_vArrangeArray(&d_iCol, d_iInd);
|
|
|
|
//determine the index of the square
|
|
if (((d_iCol[0]==d_iCol[1]) || (d_iCol[2]==d_iCol[1]) || (d_iCol[0]==d_iCol[2]))&&
|
|
((d_iLin[0]==d_iLin[1]) || (d_iLin[2]==d_iLin[1]) || (d_iLin[0]==d_iLin[2])))
|
|
i=MLT_iMin(d_iLin)*p_stAltimap->xWidth + MLT_iMin(d_iCol);
|
|
else return i=-1;
|
|
|
|
//determine also the type of the square (how many triangles are in it, and how are they located in the square)
|
|
if ((d_iCol[0]==d_iCol[2])&&(d_iCol[0]==d_iCol[1]+1))
|
|
{ if (!p_stAltimap->d_stSquare[i].ucType || (p_stAltimap->d_stSquare[i].ucType==2))
|
|
p_stAltimap->d_stSquare[i].ucType += 1;
|
|
else return i=-1;
|
|
*bIsFirst = TRUE;
|
|
p_stAltimap->d_stSquare[i].sNbFacesForSquare++;
|
|
}
|
|
if ((d_iCol[0]==d_iCol[2]) && (d_iCol[0]==d_iCol[1]-1))
|
|
{ if (!p_stAltimap->d_stSquare[i].ucType || (p_stAltimap->d_stSquare[i].ucType==1))
|
|
p_stAltimap->d_stSquare[i].ucType+=2;
|
|
else return i=-1;
|
|
*bIsFirst = FALSE; //it is not the first triangle (with index 0)
|
|
p_stAltimap->d_stSquare[i].sNbFacesForSquare++;
|
|
}
|
|
if ((d_iCol[0]==d_iCol[1])&&(d_iCol[0]==d_iCol[2]-1))
|
|
{ if (!p_stAltimap->d_stSquare[i].ucType || (p_stAltimap->d_stSquare[i].ucType==8))
|
|
p_stAltimap->d_stSquare[i].ucType+=4;
|
|
else return i=-1;
|
|
*bIsFirst = TRUE;
|
|
p_stAltimap->d_stSquare[i].sNbFacesForSquare++;
|
|
}
|
|
if ((d_iCol[0]==d_iCol[1]-1) && (d_iCol[1]==d_iCol[2]))
|
|
{ if (!p_stAltimap->d_stSquare[i].ucType || (p_stAltimap->d_stSquare[i].ucType==4))
|
|
p_stAltimap->d_stSquare[i].ucType+=8;
|
|
else return i=-1;
|
|
*bIsFirst = FALSE;//it is not the first triangle (with index 0)
|
|
p_stAltimap->d_stSquare[i].sNbFacesForSquare++;
|
|
}
|
|
free(d_iCol);
|
|
free(d_iLin);
|
|
free(d_iInd);
|
|
return i;
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
* Description: Test if an UV exist in the array of UVs
|
|
*
|
|
* Parameters: p_stUV : array to search
|
|
* stUVi : value to search for
|
|
* iNew : returns the index of the found element
|
|
* lNumber : rnb of elements
|
|
*---------------------------------------------------------------------------
|
|
* Revision date: Author:
|
|
*****************************************************************************/
|
|
BOOL MLT_bExist (ACP_tdst2DUVValues *p_stUV, ACP_tdst2DUVValues stUVi, int *iNew, long lNumber)
|
|
{
|
|
int i;
|
|
|
|
for (i=0; i<lNumber; i++)
|
|
{
|
|
//if it exist return the index of it
|
|
if ((stUVi.xU == p_stUV[i].xU)&&(stUVi.xV == p_stUV[i].xV))
|
|
{ *iNew = i;
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|