Forked from
gmsh / gmsh
20321 commits behind the upstream repository.
-
Christophe Geuzaine authoredChristophe Geuzaine authored
3D_Extrude_Old.cpp 15.72 KiB
// $Id: 3D_Extrude_Old.cpp,v 1.18 2001-12-06 08:10:31 geuzaine Exp $
// This is the old extrusion mesh generator -> only available through
// the command line option -extrude (w/o -recombine). This mesh
// generator pre-supposes a definition of surfaces in the XY plane,
// and will extrude everything along the Z axis, taking parameters
// interactively from standard input, e.g.
//
// gmsh test -extrude -recombine < params.ext
//
// The progression ratio defines a geometric progression for the
// definition of the elements heights: a factor of 2 means that the
// next element will be twice as high than the preceding one.
//
// All geometrical entities are automatically numbered:
//
// volumes: 3 * K1 + layer * K2 + surf->num
// New XY surfaces: 2 * K1 + layer * K2 + surf->num
// perp. surfaces: 1 * K1 + layer * K2 + curve->num
// perp. lines: 4 * K1 + layer * K2 + point->Num
// New XY lines: 5 * K1 + layer * K2 + curve->Num
//
#define MAXLAYERS 100
#define K1 100.e6
#define K2 1.e6 // to store MAXLAYERS
#include "Gmsh.h"
#include "Numeric.h"
#include "Geo.h"
#include "CAD.h"
#include "Mesh.h"
#include "Context.h"
#include "Create.h"
extern Context_T CTX ;
extern Mesh *LOCAL, *THEM;
static Tree_T *Tree_Ares, *Tree_Swaps;
Surface *THES;
Volume *THEV;
int TEST_IS_ALL_OK, NbLayer;
int NbElmLayer [MAXLAYERS];
int ZonLayer [MAXLAYERS];
int LineLayer [MAXLAYERS+1];
int SurfLayer [MAXLAYERS+1];
double hLayer [MAXLAYERS];
double parLayer [MAXLAYERS];
typedef struct {
int a,b;
}nxn;
static int compnxn(const void *a, const void *b){
nxn *q,*w;
q = (nxn*)a;
w = (nxn*)b;
if(q->a > w->a)return 1;
if(q->a < w->a)return -1;
if(q->b > w->b)return 1;
if(q->b < w->b)return -1;
return 0;
}
static void InitExtrudeParams (void){
FILE *file;
int i;
printf("Number of layers: ");
scanf("%d",&NbLayer);
if(NbLayer>MAXLAYERS) Msg(FATAL, "Max number of layer (%d) exceeded", MAXLAYERS);
file = fopen("xtrude","w");
if(file) fprintf(file, "%d\n", NbLayer);
for(i=0;i<NbLayer;i++){
printf("Number of elements in layer %d: ",i+1);
scanf("%d",&NbElmLayer[i]);
if(file) fprintf(file, "%d\n", NbElmLayer[i]);
printf("Depth of layer %d: ",i+1);
scanf("%lf",&hLayer[i]);
if(file) fprintf(file, "%g\n", hLayer[i]);
printf("Progresion ratio for layer %d: ",i+1);
scanf("%lf",&parLayer[i]);
if(file) fprintf(file, "%g\n", parLayer[i]);
}
if(file){
fflush(file);
fclose(file);
}
Tree_Ares = Tree_Create(sizeof(nxn),compnxn);
Tree_Swaps = Tree_Create(sizeof(nxn),compnxn);
}
static int are_exist(Vertex *v1,Vertex *v2, Tree_T *t){
nxn n;
n.a = IMAX(v1->Num,v2->Num);
n.b = IMIN(v1->Num,v2->Num);
return Tree_Search(t,&n);
}
static void are_cree(Vertex *v1,Vertex *v2, Tree_T *t){
nxn n;
n.a = IMAX(v1->Num,v2->Num);
n.b = IMIN(v1->Num,v2->Num);
Tree_Replace(t,&n);
}
static void are_del(Vertex *v1,Vertex *v2, Tree_T *t){
nxn n;
n.a = IMAX(v1->Num,v2->Num);
n.b = IMIN(v1->Num,v2->Num);
Tree_Suppress(t,&n);
}
static void Extrude_Simplex_Phase1 (void *data , void *dum){
Simplex **pS , *s;
int i,j,k;
Vertex *v1,*v2,*v3,*v4,*v5,*v6;
pS = (Simplex**)data;
s = *pS;
k = 0;
for(i=0;i<NbLayer;i++){
for(j=0;j<NbElmLayer[i];j++){
List_Read(s->V[0]->Extruded_Points,k,&v1);
List_Read(s->V[1]->Extruded_Points,k,&v2);
List_Read(s->V[2]->Extruded_Points,k,&v3);
List_Read(s->V[0]->Extruded_Points,k+1,&v4);
List_Read(s->V[1]->Extruded_Points,k+1,&v5);
List_Read(s->V[2]->Extruded_Points,k+1,&v6);
k++;
if(!are_exist(v1,v5,Tree_Ares))are_cree(v2,v4,Tree_Ares);
if(!are_exist(v5,v3,Tree_Ares))are_cree(v2,v6,Tree_Ares);
if(!are_exist(v4,v3,Tree_Ares))are_cree(v1,v6,Tree_Ares);
}
}
}
static void Extrude_Simplex_Phase3 (void *data , void *dum){
Simplex **pS , *s, *news;
Prism *newp;
Hexahedron *newh;
int i,j,k;
Vertex *v1,*v2,*v3,*v4,*v5,*v6,*v7,*v8;
pS = (Simplex**)data;
s = *pS;
if(s->V[3] && !CTX.mesh.oldxtrude_recombine){
Msg(GERROR, "Non recombined extrusion impossible with quadrangles (use -recombine)");
}
k = 0;
for(i=0;i<=NbLayer;i++){
if(SurfLayer[i]){
List_Read(s->V[0]->Extruded_Points,k,&v1);
List_Read(s->V[1]->Extruded_Points,k,&v2);
List_Read(s->V[2]->Extruded_Points,k,&v3);
news = Create_Simplex(v1,v2,v3,NULL);
if(s->V[3]){
List_Read(s->V[3]->Extruded_Points,k,&v4);
news->V[3] = v4;
}
news->iEnt = SurfLayer[i];
Tree_Add(THEV->Simp_Surf,&news);
}
for(j=0;j<NbElmLayer[i];j++){
k++;
}
}
k = 0;
for(i=0;i<NbLayer;i++){
for(j=0;j<NbElmLayer[i];j++){
if(s->V[3]){
List_Read(s->V[0]->Extruded_Points,k,&v1);
List_Read(s->V[1]->Extruded_Points,k,&v2);
List_Read(s->V[2]->Extruded_Points,k,&v3);
List_Read(s->V[3]->Extruded_Points,k,&v4);
List_Read(s->V[0]->Extruded_Points,k+1,&v5);
List_Read(s->V[1]->Extruded_Points,k+1,&v6);
List_Read(s->V[2]->Extruded_Points,k+1,&v7);
List_Read(s->V[3]->Extruded_Points,k+1,&v8);
}
else{
List_Read(s->V[0]->Extruded_Points,k,&v1);
List_Read(s->V[1]->Extruded_Points,k,&v2);
List_Read(s->V[2]->Extruded_Points,k,&v3);
List_Read(s->V[0]->Extruded_Points,k+1,&v4);
List_Read(s->V[1]->Extruded_Points,k+1,&v5);
List_Read(s->V[2]->Extruded_Points,k+1,&v6);
}
k++;
if(ZonLayer[i]){
if(CTX.mesh.oldxtrude_recombine){
if(s->V[3]){
newh = Create_Hexahedron(v1,v2,v3,v4,v5,v6,v7,v8);
newh->iEnt = ZonLayer[i];
Tree_Add(THEV->Hexahedra,&newh);
}
else{
newp = Create_Prism(v1,v2,v3,v4,v5,v6);
newp->iEnt = ZonLayer[i];
Tree_Add(THEV->Prisms,&newp);
}
}
else{
if(are_exist(v4,v2,Tree_Ares) &&
are_exist(v5,v3,Tree_Ares) &&
are_exist(v4,v3,Tree_Ares) ){
news = Create_Simplex(v1,v2,v3,v4);
news->iEnt = ZonLayer[i];
Tree_Add(THEV->Simplexes,&news);
news = Create_Simplex(v4,v5,v6,v3);
news->iEnt = ZonLayer[i];
Tree_Add(THEV->Simplexes,&news);
news = Create_Simplex(v2,v4,v5,v3);
news->iEnt = ZonLayer[i];
Tree_Add(THEV->Simplexes,&news);
}
if(are_exist(v4,v2,Tree_Ares) &&
are_exist(v2,v6,Tree_Ares) &&
are_exist(v4,v3,Tree_Ares) ){
news = Create_Simplex(v1,v2,v3,v4);
news->iEnt = ZonLayer[i];
Tree_Add(THEV->Simplexes,&news);
news = Create_Simplex(v4,v5,v6,v2);
news->iEnt = ZonLayer[i];
Tree_Add(THEV->Simplexes,&news);
news = Create_Simplex(v4,v2,v6,v3);
news->iEnt = ZonLayer[i];
Tree_Add(THEV->Simplexes,&news);
}
if(are_exist(v4,v2,Tree_Ares) &&
are_exist(v2,v6,Tree_Ares) &&
are_exist(v6,v1,Tree_Ares) ){
news = Create_Simplex(v1,v2,v3,v6);
news->iEnt = ZonLayer[i];
Tree_Add(THEV->Simplexes,&news);
news = Create_Simplex(v4,v5,v6,v2);
news->iEnt = ZonLayer[i];
Tree_Add(THEV->Simplexes,&news);
news = Create_Simplex(v2,v4,v6,v1);
news->iEnt = ZonLayer[i];
Tree_Add(THEV->Simplexes,&news);
}
if(are_exist(v5,v1,Tree_Ares) &&
are_exist(v5,v3,Tree_Ares) &&
are_exist(v4,v3,Tree_Ares) ){
news = Create_Simplex(v1,v2,v3,v5);
news->iEnt = ZonLayer[i];
Tree_Add(THEV->Simplexes,&news);
news = Create_Simplex(v4,v5,v6,v3);
news->iEnt = ZonLayer[i];
Tree_Add(THEV->Simplexes,&news);
news = Create_Simplex(v1,v4,v5,v3);
news->iEnt = ZonLayer[i];
Tree_Add(THEV->Simplexes,&news);
}
if(are_exist(v5,v1,Tree_Ares) &&
are_exist(v5,v3,Tree_Ares) &&
are_exist(v6,v1,Tree_Ares) ){
news = Create_Simplex(v1,v2,v3,v5);
news->iEnt = ZonLayer[i];
Tree_Add(THEV->Simplexes,&news);
news = Create_Simplex(v4,v5,v6,v1);
news->iEnt = ZonLayer[i];
Tree_Add(THEV->Simplexes,&news);
news = Create_Simplex(v1,v3,v5,v6);
news->iEnt = ZonLayer[i];
Tree_Add(THEV->Simplexes,&news);
}
if(are_exist(v5,v1,Tree_Ares) &&
are_exist(v2,v6,Tree_Ares) &&
are_exist(v6,v1,Tree_Ares) ){
news = Create_Simplex(v1,v2,v3,v6);
news->iEnt = ZonLayer[i];
Tree_Add(THEV->Simplexes,&news);
news = Create_Simplex(v4,v5,v6,v1);
news->iEnt = ZonLayer[i];
Tree_Add(THEV->Simplexes,&news);
news = Create_Simplex(v1,v2,v5,v6);
news->iEnt = ZonLayer[i];
Tree_Add(THEV->Simplexes,&news);
}
}
}
}
}
}
static void Extrude_Simplex_Phase2 (void *data , void *dum){
Simplex **pS , *s;
int i,j,k;
Vertex *v1,*v2,*v3,*v4,*v5,*v6;
pS = (Simplex**)data;
s = *pS;
k = 0;
for(i=0;i<NbLayer;i++){
for(j=0;j<NbElmLayer[i];j++){
List_Read(s->V[0]->Extruded_Points,k,&v1);
List_Read(s->V[1]->Extruded_Points,k,&v2);
List_Read(s->V[2]->Extruded_Points,k,&v3);
List_Read(s->V[0]->Extruded_Points,k+1,&v4);
List_Read(s->V[1]->Extruded_Points,k+1,&v5);
List_Read(s->V[2]->Extruded_Points,k+1,&v6);
k++;
if(are_exist(v4,v2,Tree_Ares) &&
are_exist(v5,v3,Tree_Ares) &&
are_exist(v1,v6,Tree_Ares)){
TEST_IS_ALL_OK++;
if(!are_exist(v4,v2,Tree_Swaps)){
are_del(v4,v2,Tree_Ares);
are_cree(v1,v5,Tree_Ares);
are_cree(v1,v5,Tree_Swaps);
are_cree(v4,v2,Tree_Swaps);
}
else if(!are_exist(v5,v3,Tree_Swaps)){
are_del(v5,v3,Tree_Ares);
are_cree(v2,v6,Tree_Ares);
are_cree(v5,v3,Tree_Swaps);
are_cree(v2,v6,Tree_Swaps);
}
else if(!are_exist(v1,v6,Tree_Swaps)){
are_del(v1,v6,Tree_Ares);
are_cree(v4,v3,Tree_Ares);
are_cree(v1,v6,Tree_Swaps);
are_cree(v4,v3,Tree_Swaps);
}
}
else if(are_exist(v1,v5,Tree_Ares) &&
are_exist(v2,v6,Tree_Ares) &&
are_exist(v4,v3,Tree_Ares)){
TEST_IS_ALL_OK++;
if(!are_exist(v1,v5,Tree_Swaps)){
are_del(v1,v5,Tree_Ares);
are_cree(v4,v2,Tree_Ares);
are_cree(v1,v5,Tree_Swaps);
are_cree(v4,v2,Tree_Swaps);
}
else if(!are_exist(v2,v6,Tree_Swaps)){
are_del(v2,v6,Tree_Ares);
are_cree(v5,v3,Tree_Ares);
are_cree(v5,v3,Tree_Swaps);
are_cree(v2,v6,Tree_Swaps);
}
else if(!are_exist(v4,v3,Tree_Swaps)){
are_del(v4,v3,Tree_Ares);
are_cree(v1,v6,Tree_Ares);
are_cree(v1,v6,Tree_Swaps);
are_cree(v4,v3,Tree_Swaps);
}
}
}
}
}
static void Extrude_Vertex (void *data , void *dum){
Vertex **pV , *v, *newv;
int i,j;
double h,a;
pV = (Vertex**)data;
v = *pV;
if(v->Extruded_Points)return;
v->Extruded_Points = List_Create(NbLayer,1,sizeof(Vertex*));
List_Add(v->Extruded_Points,&v);
h = 0.0;
//printf("-extruding vertex %d %p\n", v->Num, v);
for(i=0;i<NbLayer;i++){
// Geometric progression ar^i
// Sum of n (=NbElmLayer[i]) terms = hLayer[i] = a (r^n-1)/(r-1)
if(parLayer[i] == 1.)
a = hLayer[i]/(double)NbElmLayer[i];
else
a = hLayer[i] * (parLayer[i]-1.)/(pow(parLayer[i],NbElmLayer[i])-1.) ;
for(j=0;j<NbElmLayer[i];j++){
//h += hLayer[i]/(double)NbElmLayer[i];
h += a*pow(parLayer[i],j);
newv = Create_Vertex(++THEM->MaxPointNum,v->Pos.X,v->Pos.Y,v->Pos.Z + h, v->lc , v->u );
Tree_Add(THEM->Vertices,&newv);
List_Add(v->Extruded_Points,&newv);
}
}
}
static void Extrude_Surface1 (void *data , void *dum){
Surface **pS , *s;
if(!NbLayer)return;
pS = (Surface**)data;
s = THES = *pS;
Tree_Action(s->Vertices,Extrude_Vertex);
if(!CTX.mesh.oldxtrude_recombine) Tree_Action(s->Simplexes,Extrude_Simplex_Phase1);
}
static void Extrude_Surface2 (void *data , void *dum){
Surface **pS , *s;
if(!NbLayer)return;
pS = (Surface**)data;
s = THES = *pS;
Tree_Action(s->Simplexes,Extrude_Simplex_Phase2);
}
static void Extrude_Surface3 (void *data , void *dum){
Surface **pS , *s;
int i;
if(!NbLayer)return;
pS = (Surface**)data;
s = THES = *pS;
/* Numerotation automatique des entites physiques */
Msg(INFO, "Extruding Surface %d", s->Num);
for(i=0;i<NbLayer;i++){
ZonLayer[i] = (int)(3 * K1) + (int) ((i+1) * K2) + s->Num ;
}
SurfLayer[0] = s->Num ;
for(i=0;i<NbLayer;i++){
SurfLayer[i+1] = (int)(2 * K1) + (int)((i+1) * K2) + s->Num ;
}
Tree_Action(s->Simplexes,Extrude_Simplex_Phase3);
}
static void Extrude_Seg(Vertex *V1, Vertex *V2){
int i,j,k;
Vertex *v1,*v2,*v3,*v4;
Simplex *s;
//printf("-curve vertex %d %p %d %p\n", V1->Num, V1, V2->Num, V2);
k = 0;
for(i=0;i<=NbLayer;i++){
if(LineLayer[i]){
List_Read(V1->Extruded_Points,k,&v1);
List_Read(V2->Extruded_Points,k,&v2);
s = Create_Simplex(v1,v2,NULL,NULL);
s->iEnt = LineLayer[i];
Tree_Add(THEV->Simp_Surf,&s);
}
for(j=0;j<NbElmLayer[i];j++){
k++;
}
}
k = 0;
for(i=0;i<NbLayer;i++){
for(j=0;j<NbElmLayer[i];j++){
List_Read(V1->Extruded_Points,k,&v1);
List_Read(V2->Extruded_Points,k,&v2);
List_Read(V1->Extruded_Points,k+1,&v3);
List_Read(V2->Extruded_Points,k+1,&v4);
if(SurfLayer[i]){
if(CTX.mesh.oldxtrude_recombine){
s = Create_Simplex(v1,v2,v4,NULL);
s->V[3] = v3;
s->iEnt = SurfLayer[i];
Tree_Add(THEV->Simp_Surf,&s);
}
else{
if(are_exist(v3,v2,Tree_Ares)){
s = Create_Simplex(v3,v2,v1,NULL);
s->iEnt = SurfLayer[i];
Tree_Add(THEV->Simp_Surf,&s);
s = Create_Simplex(v3,v4,v2,NULL);
s->iEnt = SurfLayer[i];
Tree_Add(THEV->Simp_Surf,&s);
}
else{
s = Create_Simplex(v3,v4,v1,NULL);
s->iEnt = SurfLayer[i];
Tree_Add(THEV->Simp_Surf,&s);
s = Create_Simplex(v1,v4,v2,NULL);
s->iEnt = SurfLayer[i];
Tree_Add(THEV->Simp_Surf,&s);
}
}
}
k++;
}
}
}
static void Extrude_Curve (void *data , void *dum){
Curve **pC , *c;
Vertex *v1,*v2;
int i;
if(!NbLayer)return;
pC = (Curve**)data;
c = *pC;
if (c->Num < 0) return;
/* Numerotation automatique des entites physiques */
Msg(INFO, "Extruding Curve %d", c->Num);
LineLayer[0] = c->Num ;
for(i=0;i<NbLayer;i++){
SurfLayer[i] = (int)(1 * K1) + (int)((i+1) * K2) + c->Num ;
LineLayer[i+1] = (int)(5 * K1) + (int)((i+1) * K2) + c->Num ;
}
for(i=0;i<List_Nbr(c->Vertices)-1;i++){
List_Read(c->Vertices,i,&v1);
List_Read(c->Vertices,i+1,&v2);
Extrude_Seg(v1,v2);
}
}
static void Extrude_Pnt(Vertex *V1){
int i,j,k;
Vertex *v1,*v2;
Simplex *s;
k = 0;
for(i=0;i<NbLayer;i++){
for(j=0;j<NbElmLayer[i];j++){
List_Read(V1->Extruded_Points,k,&v1);
List_Read(V1->Extruded_Points,k+1,&v2);
if(LineLayer[i]){
s = Create_Simplex(v1,v2,NULL,NULL);
s->iEnt = LineLayer[i];
Tree_Add(THEV->Simp_Surf,&s);
}
k++;
}
}
}
static void Extrude_Point (void *data , void *dum){
Vertex **pV, *v, **pV2;
int i;
if(!NbLayer)return;
pV = (Vertex**)data;
v = *pV;
/* Numerotation automatique des entites physiques */
Msg(INFO, "Extruding Vertex %d", v->Num);
for(i=0;i<NbLayer;i++){
LineLayer[i] = (int)(4 * K1) + (int)((i+1) * K2) + v->Num ;
}
if((pV2 = (Vertex**)Tree_PQuery(THEM->Vertices, pV))){
Extrude_Vertex(pV2, NULL);
Extrude_Pnt(*pV2);
}
}
void FreeEP(void *a, void *b){
Vertex *v = *((Vertex**)a);
Free_ExtrudedPoints(v->Extruded_Points);
v->Extruded_Points = NULL;
}
void Extrude_Mesh_Old(Mesh *M){
int j;
Mesh MM;
InitExtrudeParams();
LOCAL = &MM;
THEM = M;
//clean up Extruded_Points stuff (in case another extrusion was
//performed before)
Tree_Action(THEM->Vertices,FreeEP);
Create_BgMesh (WITHPOINTS, .2, LOCAL);
Tree_Left(M->Volumes,&THEV);
Tree_Action(M->Surfaces, Extrude_Surface1);
if(!CTX.mesh.oldxtrude_recombine){
j = 0;
do{
TEST_IS_ALL_OK=0;
Tree_Action ( M->Surfaces , Extrude_Surface2 );
Msg(INFO, "%d swaps", TEST_IS_ALL_OK);
if(TEST_IS_ALL_OK == j)break;
j = TEST_IS_ALL_OK;
}while(TEST_IS_ALL_OK);
}
Tree_Action ( M->Surfaces , Extrude_Surface3 );
Tree_Action ( M->Curves , Extrude_Curve );
Tree_Action ( M->Points , Extrude_Point );
}