1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
| #include <vtkCommand.h>
#include <sstream>
#include <vtkCell.h>
#include "vtkSurface.h"
#include "RenderWindow.h"
#include <vtkIntArray.h>
#include <vtkIdTypeArray.h>
#include <vtkBitArray.h>
#include <vtkDoubleArray.h>
#include <vtkIdListCollection.h>
#include "vtkPolyDataWriter.h"
#include <vtkPolyDataReader.h>
#include "vtkSurfaceBase.h"
#include <vtkPolyData.h>
#include <vtkCellArray.h>
#include <vtkMath.h>
#include <math.h>
class vtkAnisotropicFilter
{
public :
//déclaration + allocation d'un tableau de 2 dimensaions et de i chaines
void SetInput(vtkSurface *Input) {this->Input=Input;};
double* TableAreaStar;
double** TableDeltaLambda;
double** TableVertex;
//calcul du vecteur H(e)=He*Ne (vecteur du courbure moyenne) tel que Ne=N1+N2/||N1+N2|| He=2|e|cosOe/2
void ApplyAnisotropicSmoothing(double Lambda,double s,int n,double r)//M(maillage), Lambda(paramétre de détection de dispositif)
{
//s(facteur de gradutaion qui détermine la quantité de lissage faite dans un seul étape),n(nombre des étapes de lissages explicites)
TableDeltaLambda=new double* [Input->GetNumberOfPoints()];
TableAreaStar=new double [Input->GetNumberOfPoints()];
TableVertex=new double* [Input->GetNumberOfPoints()];
double vi[3];
for (int i =0;i<Input->GetNumberOfPoints();i++)
{
TableDeltaLambda[i]=new double[3];
TableVertex[i]= new double[3];
TableDeltaLambda[i][0]=0;
TableDeltaLambda[i][1]=0;
TableDeltaLambda[i][2]=0;
TableAreaStar[i]=0;
Input->GetPointCoordinates(i,vi);
TableVertex[i][0]=vi[0];
TableVertex[i][1]=vi[1];
TableVertex[i][2]=vi[2];
}
for(int s=0;s<n;s++)//n nombre d'étape
{
double Vi[3],Vj[3],Vii[3],Vjj[3],Vkk[3],Ne[3],He,W;
vtkIdType i,j,fi, fj,ii,jj,kk;//je les déclare comme des vtkIdType
for (int e=0; e<this->Input->GetNumberOfEdges(); e++)
{
Input->GetEdgeFaces(e,fi,fj);// Returns i and j as the faces adjacent to the edge.
Input->GetTriangleNormal(fi,Vi);
Input->GetTriangleNormal(fj,Vj);
Input->GetEdgeVertices(e,i,j);
Ne[0]=Vi[0]+Vj[0];
Ne[1]=Vi[1]+Vj[1];
Ne[2]=Vi[2]+Vj[2];//additionner les 2 vecteurs Vi et Vj
vtkMath::Normalize(Ne);
double Z=vtkMath::Dot(Vi,Ne);//produit entre 2 vecteurs[3] le résultat dans Z cosOe/2=<Ne,Vi>/||Ne||
double Edge=Input->GetDistanceBetweenVertices(i,j);//calcul de l'arret Eij
He=2*fabs(Edge)*Z;//He=2|e|cosOe/2
double a=He;
double LambdaSquare=pow(Lambda,2.0);
if (fabs(a)>Lambda)
W=LambdaSquare/(r*pow((Lambda-fabs(a)),2.0)+LambdaSquare);
else
W=1;
TableDeltaLambda[i][0]-=W*He*Ne[0];
TableDeltaLambda[i][1]-=W*He*Ne[1];
TableDeltaLambda[i][2]-=W*He*Ne[2];
TableDeltaLambda[j][0]-=W*He*Ne[0];
TableDeltaLambda[j][1]-=W*He*Ne[1];
TableDeltaLambda[j][2]-=W*He*Ne[2];
}
for (int h=0; h<Input->GetNumberOfCells(); h++)
{
Input->GetFaceVertices(h,ii,jj,kk);//donne moi tous les sommets des triangles h=triangle ii,jj,kk les 3 sommets
Input->GetPointCoordinates(ii,Vii);//je donnes le coordonnées du ii et jj
Input->GetPointCoordinates(jj,Vjj);
Input->GetPointCoordinates(kk,Vkk);
double areat=Input->GetFaceArea(h);//calcul d'aires du triangles
TableAreaStar[ii]+=areat;
TableAreaStar[jj]+=areat;
TableAreaStar[kk]+=areat;
}
for(int i=0;i<this->Input->GetNumberOfPoints();i++)
{
double Calculate[3];
Calculate[0]=(2*TableAreaStar[i]);
Calculate[1]=(2*TableAreaStar[i]);
Calculate[2]=(2*TableAreaStar[i]);
TableVertex[i][0]+=((3*s/Calculate[0])*TableDeltaLambda[i][0]);
TableVertex[i][1]+=((3*s/Calculate[1])*TableDeltaLambda[i][1]);
TableVertex[i][2]+=((3*s/Calculate[2])*TableDeltaLambda[i][2]);
Input->SetPointCoordinates(i, TableVertex[i]);//je fais réagir les nouveaux positions de mes sommets
Input->GetPoints()->Modified();
}
/* //calcul de S(p) pour lisser les surfaces/ s(p)=1/2somme WeHeTe*Tetransposer t
//We=<Np,Ne>
*/
}
}
protected:
vtkSurface *Input;
};
int main( int argc, char* argv[] )//argc contient le nombre de parametre passé au programme +1
//argv est un tableau contenant les chaines de caractere transmises
{
int i;
for(i=0;i<argc;i++)
{
printf("Argument %1i : %s \n", i+1, argv[i]);
}
//Lire le fichier
vtkSurface *Build=vtkSurface::New();
Build->CreateFromFile(argv[1]);
RenderWindow *Window=RenderWindow::New();
Window->SetInput(Build);
Window->Render();
Window->Interact();
//Filtrage
vtkAnisotropicFilter *Smoothing=new (vtkAnisotropicFilter);
Smoothing->SetInput(Build);
Smoothing->ApplyAnisotropicSmoothing(atof(argv[2]),atof(argv[3]),atoi(argv[4]),atof(argv[5]));
Window->Render();
Window->Interact();
//sauvgarde de maillage
vtkPolyDataWriter *Data=vtkPolyDataWriter::New();
Data->SetInput(Build);
Data->SetFileName("AnisotropicFilter.vtk");
Data->Write();
return (0);
} |
Partager