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
| class vtkImplicitFairing
{
public:
void SetInput(vtkSurface *Input) {this->Input=Input;};
double X[3];
double** TableLaplacian;
double** TablePoints;
double** Accumulate;
void AllocateTable()
{
TablePoints = new double* [this->Input->GetNumberOfPoints()];
Accumulate=new double* [this->Input->GetNumberOfPoints()];
TableLaplacian = new double* [this->Input->GetNumberOfPoints()];
for (int i=0;i<this->Input->GetNumberOfPoints();i++)
{
TablePoints[i]=new double[3] ;
TableLaplacian[i]=new double[3] ;
Accumulate[i]=new double[3] ;
}
}
void TableCoordinates()
{
//déclaration + allocation d'un tableau de 2 dimensaions et de i chaines
for (int i=0;i<this->Input->GetNumberOfPoints();i++ )
{
this->Input->GetPointCoordinates(i,X);//Xi
TablePoints[i][0]=X[0];
TablePoints[i][1]=X[1];//j'ai mit une copie des mes sommets dans un tableau
TablePoints[i][2]=X[2];
}
}
void ComputeLaplacian()
{
int m=6;
double** TableLaplacian = new double* [this->Input->GetNumberOfPoints()] ;
double Y[3],A[3],L[3];
vtkIdList *MyList=vtkIdList::New();
for (int i=0; i<this->Input->GetNumberOfPoints(); i++)
{
this->Input->GetVertexNeighbours(i,MyList);//elle me passe les sommets qui ont des voisinages avec le sommet choisi
TablePoints[i][0]=X[0];
TablePoints[i][1]=X[1];
TablePoints[i][2]=X[2];
double somme[3];
somme[0]=0; somme[1]=0;somme[2]=0;
for (int j=0;j<MyList->GetNumberOfIds();j++) //le nbre d'ID correspond au nombre des points de voisinage
{
this->Input->GetPointCoordinates(MyList->GetId(j),Y);//prendre les voisins Y(j) de i
TablePoints[j][0]=Y[0];
TablePoints[j][1]=Y[1];
TablePoints[j][2]=Y[2];
A[0]=TablePoints[j][0]-TablePoints[i][0];
A[1]=TablePoints[j][1]-TablePoints[i][1];//on soustraire Y(j) de X(i) pour chaque axe
A[2]=TablePoints[j][2]-TablePoints[i][2];
somme[0]=somme[0]+A[0];
somme[1]=somme[1]+A[1];//pour le calcul de Laplacian Discret= somme (y(j)-X(i))
somme[2]=somme[2]+A[2];
L[0]=1/m*somme[0];
L[1]=1/m*somme[1];//Laplacian d'ordre 1 L(X)=1/6*somme(Y(j)-X(i))
L[2]=1/m*somme[2];
}
TableLaplacian[i][0]=L[0];
TableLaplacian[i][1]=L[1];//j'ai mit une copie des mes sommets dans un tableau
TableLaplacian[i][2]=L[2];
}
MyList->Delete();
}
void AccumulateLaplacian()//X+Lambdadt*Laplacian
{
double X[3],Lambdadt=10;
for (int i=0; i<this->Input->GetNumberOfPoints(); i++)
{
X[0]=TablePoints[i][0];
X[1]=TablePoints[i][1];
X[2]=TablePoints[i][2];
this->ComputeLaplacian();
}
Accumulate[i][0]=X[0]+Lambdadt*TableLaplacian[i][0];
Accumulate[i][1]=X[1]+Lambdadt*TableLaplacian[i][1];
Accumulate[i][2]=X[2]+Lambdadt*TableLaplacian[i][2];
}
void ApplyImplicitFilter(double Lambdadt, int n)
{
this->AllocateTable();
for (int n=0;n<4;n++)
{
double Lambdadt=0, nombre=10;
Lambdadt=pow(nombre,n);//lambdadt=10^n;
this->ComputeLaplacian();
this->AccumulateLaplacian();
}
for (int i=0;i<this->Input->GetNumberOfPoints();i++)
{
this->Input->SetPointCoordinates(i, Accumulate[i]);//je fais réagir les nouveaux positions de mes sommets
}
}
int vtkImplicitFairing::free(double **TablePoints,double **Accumulate,double **TableLaplacian);
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 *Create=vtkSurface::New();
Create->CreateFromFile(argv[1]);
RenderWindow *Window=RenderWindow::New();
Window->SetInput(Create);
//Filtrage
vtkImplicitFairing *Fairing=new (vtkImplicitFairing);
Fairing->SetInput(Create);
Fairing->ApplyImplicitFilter(atof(argv[2]),atoi(argv[3]));
Window->Render();
Window->Interact();
//sauvgarde de maillage
vtkPolyDataWriter *Data=vtkPolyDataWriter::New();
Data->SetInput(Create);
Data->SetFileName("Implicit.vtk");
Data->Write();
return(0);
} |
Partager