Forked from
gmsh / gmsh
20314 commits behind the upstream repository.
-
Christophe Geuzaine authoredChristophe Geuzaine authored
2D_SMesh.cpp 8.01 KiB
// $Id: 2D_SMesh.cpp,v 1.8 2001-10-29 08:52:20 geuzaine Exp $
/*
Maillage transfini surfacique
*s2
s3 c2 s2 /|
*-----------* / |
| | c2/ |c1
c3| |c1 / |
| | / |
v *-----------* *-----*
| s0 c0 s1 s0 c0 s1
*--u
Decoupages : |
*--*
|\ |
| \|
*--*--
s0 -> s1
*/
#include "Gmsh.h"
#include "Geo.h"
#include "Mesh.h"
#include "Numeric.h"
#include "Interpolation.h"
extern Mesh *THEM;
int index1d (int flag, int N, int n){
switch(flag){
case 0 : return(n);
case 1 : return(N-n-1);
default : return -1;
}
}
int MeshTransfiniteSurface (Surface *sur) {
int i,j,k,flag,nb,N1,N2,issphere;
int nbquad=0,nbtri=0;
Curve *G[4],*GG[4];
Vertex V,**vexist,*pV,*c1,*c2,**list,*CP[2];
Simplex *simp;
double u,v;
int C_flag[4];
Vertex *C[4],*S[4];
static int tab1qua[] = {0,1, 1,2, 3,2, 0,3};
static int tab1tri[] = {0,1, 1,2, 0,2};
static int tab2[] = {0,1, 1,0};
if (sur->Method != TRANSFINI) return(0);
switch(sur->Typ){
case MSH_SURF_REGL:
case MSH_SURF_PLAN:
case MSH_SURF_TRIC:
case MSH_SURF_NURBS:
nb = List_Nbr(sur->Generatrices);
if(nb != 3 && nb != 4) return(0);
for(i=0;i<4;i++) G[i] = NULL ;
for(i=0;i<nb;i++){
V.Num = sur->ipar[i];
pV = &V;
if((vexist = (Vertex**)Tree_PQuery(THEM->Vertices,&pV)) == NULL) {
Msg(WARNING, "Unknown Control Point %d in Transfinite Surface %d",
V.Num,sur->Num);
return(0);
}
else{
S[i]=*vexist;
}
}
for(i=0;i<nb;i++) List_Read(sur->Generatrices,i,&GG[i]);
for(i=0;i<nb;i++){
List_Read(GG[i]->Control_Points,0,&CP[0]);
List_Read(GG[i]->Control_Points,List_Nbr(GG[i]->Control_Points)-1,&CP[1]);
for(flag=0;flag<2;flag++){
for(k=0;k<nb;k++){
if(nb == 4){
if(S[tab1qua[2*k ]]->Num == CP[tab2[2*flag ]]->Num &&
S[tab1qua[2*k+1]]->Num == CP[tab2[2*flag+1]]->Num){
G[k]=GG[i];
C_flag[k]=flag;
}
}
else{
if(S[tab1tri[2*k ]]->Num == CP[tab2[2*flag ]]->Num &&
S[tab1tri[2*k+1]]->Num == CP[tab2[2*flag+1]]->Num){
G[k]=GG[i];
C_flag[k]=flag;
}
}
}
}
}
for(i=0;i<nb;i++)
if(G[i] == NULL) {
Msg(WARNING, "Wrong definition of Transfinite Surface %d",
sur->Num);
return(0);
}
if(nb == 4) {
if((N1 = List_Nbr(G[0]->Vertices)) != List_Nbr(G[2]->Vertices)) return(0);
if((N2 = List_Nbr(G[1]->Vertices)) != List_Nbr(G[3]->Vertices)) return(0);
}
else {
if((N1 = List_Nbr(G[0]->Vertices)) != List_Nbr(G[2]->Vertices)) return(0);
N2 = List_Nbr(G[1]->Vertices);
}
sur->Nu = N1;
sur->Nv = N2;
list = (Vertex**)Malloc(N1*N2*sizeof(Vertex*));
issphere = 1;
for(i=0;i<nb;i++){
if(G[i]->Typ != MSH_SEGM_CIRC && G[i]->Typ != MSH_SEGM_CIRC_INV){
issphere = 0;
}
else if (issphere){
if(!i){
List_Read(G[i]->Control_Points, 1, &c1);
}
else{
List_Read(G[i]->Control_Points, 1, &c2);
if(compareVertex(&c1,&c2))issphere = 0;
}
}
}
for(i=0;i<N1;i++){
List_Read(G[0]->Vertices, index1d(C_flag[0],N1,i), &C[0]);
List_Read(G[2]->Vertices, index1d(C_flag[2],N1,i), &C[2]);
if( (G[0]->Num>0 && C_flag[0]) || (G[0]->Num<0 && !C_flag[0]) )
u = 1.-C[0]->u;
else
u = C[0]->u;
for(j=0;j<N2;j++){
List_Read(G[1]->Vertices, index1d(C_flag[1],N2,j), &C[1]);
if(nb == 4)
List_Read(G[3]->Vertices, index1d(C_flag[3],N2,j), &C[3]);
if( (G[1]->Num>0 && C_flag[1]) || (G[1]->Num<0 && !C_flag[1]) )
v = 1.-C[1]->u;
else
v = C[1]->u;
if(i && j && i != N1-1 && j != N2-1){
if (sur->Typ == MSH_SURF_NURBS)
V = InterpolateSurface (sur, u, v, 0, 0);
else if(nb == 4)
V = TransfiniteQua(*C[0],*C[1],*C[2],*C[3],*S[0],*S[1],*S[2],*S[3],u,v);
else
V = TransfiniteTri(*C[0],*C[1],*C[2],*S[0],*S[1],*S[2],u,v);
if(issphere)
TransfiniteSph(*C[0],*c1,&V);
list[i+N1*j] = Create_Vertex(++THEM->MaxPointNum,V.Pos.X,V.Pos.Y,V.Pos.Z,V.lc,0.0);
}
else if(!i)
list[i+N1*j] = (nb == 4)?C[3]:C[2];
else if(!j)
list[i+N1*j] = C[0];
else if(i == N1-1)
list[i+N1*j] = C[1];
else if(j == N2-1)
list[i+N1*j] = C[2];
list[i + N1 * j]->us[0] = u;
list[i + N1 * j]->us[1] = v;
}
}
for(i=0;i<N1;i++){
for(j=0;j<N2;j++){
List_Add(sur->TrsfVertices,&list[i+N1*j]);
}
}
if(nb == 4){
for(i=0;i<N1;i++){
for(j=0;j<N2;j++){
Tree_Replace(sur->Vertices,&list[i+N1*j]);
}
}
for(i=0;i<N1-1;i++){
for(j=0;j<N2-1;j++){
if(sur->Recombine){
simp = Create_Quadrangle(list[(i) + N1*(j)], list[(i+1)+ N1*(j)],
list[(i+1)+ N1*(j+1)], list[(i)+ N1*(j+1)]);
simp->iEnt = sur->Num;
Tree_Add(sur->Simplexes,&simp);
List_Add(sur->TrsfSimplexes,&simp);
nbquad++;
}
else{
simp = Create_Simplex(list[(i) + N1*(j)], list[(i+1) + N1*(j)],
list[(i) + N1*(j+1)], NULL);
simp->iEnt = sur->Num;
Tree_Add(sur->Simplexes,&simp);
List_Add(sur->TrsfSimplexes,&simp);
simp = Create_Simplex(list[(i+1) + N1*(j+1)], list[(i) + N1*(j+1)],
list[(i+1) + N1*(j)], NULL);
simp->iEnt = sur->Num;
Tree_Add(sur->Simplexes,&simp);
List_Add(sur->TrsfSimplexes,&simp);
nbtri += 2;
}
}
}
}
else if(nb == 3) {
Tree_Replace(sur->Vertices,&list[0]);
for(i=1;i<N1;i++){
for(j=0;j<N2;j++){
Tree_Replace(sur->Vertices,&list[i+N1*j]);
}
}
for(j=0;j<N2-1;j++){
simp = Create_Simplex(list[1 + N1*(j+1)], list[N1*(j+1)],list[1 + N1*(j)],NULL);
simp->iEnt = sur->Num;
Tree_Add(sur->Simplexes,&simp);
List_Add(sur->TrsfSimplexes,&simp);
nbtri++;
}
for(i=1;i<N1-1;i++){
for(j=0;j<N2-1;j++){
if(sur->Recombine){
simp = Create_Quadrangle(list[(i) + N1*(j)],list[(i+1) + N1*(j)],
list[(i+1) + N1*(j+1)],list[i+N1*(j+1)]);
simp->iEnt = sur->Num;
Tree_Add(sur->Simplexes,&simp);
List_Add(sur->TrsfSimplexes,&simp);
nbquad++;
}
else{
simp = Create_Simplex(list[(i) + N1*(j)], list[(i+1) + N1*(j)],
list[(i) + N1*(j+1)],NULL);
simp->iEnt = sur->Num;
Tree_Add(sur->Simplexes,&simp);
List_Add(sur->TrsfSimplexes,&simp);
simp = Create_Simplex(list[(i+1) + N1*(j+1)], list[(i) + N1*(j+1)],
list[(i+1) + N1*(j)], NULL);
simp->iEnt = sur->Num;
Tree_Add(sur->Simplexes,&simp);
List_Add(sur->TrsfSimplexes,&simp);
nbtri += 2;
}
}
}
}
break;
default:
return(0);
}
Free(list);
// We count this here, to be able to distinguish very quickly
// between triangles and quadrangles later
THEM->Statistics[8] += nbquad;
return(1);
}