Forked from
gmsh / gmsh
21345 commits behind the upstream repository.
-
Christophe Geuzaine authoredChristophe Geuzaine authored
Create.cpp 14.85 KiB
// $Id: Create.cpp,v 1.8 2001-01-12 13:29:00 geuzaine Exp $
#include "Gmsh.h"
#include "Const.h"
#include "Geo.h"
#include "CAD.h"
#include "Mesh.h"
#include "Numeric.h"
#include "Context.h"
extern Mesh *THEM;
extern Context_T CTX;
extern int CurrentSimplexNumber;
//static double CIRC_GRAN = 2.2;
int compareNXE (const void *a, const void *b){
NXE *q, *w;
q = (NXE *) a;
w = (NXE *) b;
return (compareVertex (&q->v, &w->v));
}
int compareFxE (const void *a, const void *b){
FxE *q, *w;
q = (FxE *) a;
w = (FxE *) b;
return (compareFace (&q->Sorted, &w->Sorted));
}
int compareHexahedron (const void *a, const void *b){
Hexahedron **q, **w;
q = (Hexahedron **) a;
w = (Hexahedron **) b;
return ((*q)->Num - (*w)->Num);
}
int compareSurfaceLoop (const void *a, const void *b){
SurfaceLoop **q, **w;
q = (SurfaceLoop **) a;
w = (SurfaceLoop **) b;
return ((*q)->Num - (*w)->Num);
}
int compareEdgeLoop (const void *a, const void *b){
EdgeLoop **q, **w;
q = (EdgeLoop **) a;
w = (EdgeLoop **) b;
return ((*q)->Num - (*w)->Num);
}
int comparePrism (const void *a, const void *b){
Prism **q, **w;
q = (Prism **) a;
w = (Prism **) b;
return ((*q)->Num - (*w)->Num);
}
int compareQuality (const void *a, const void *b){
double d;
Simplex **q, **w;
q = (Simplex **) a;
w = (Simplex **) b;
d = (*q)->Quality - (*w)->Quality;
if (d > 0)
return (1);
if (d < 0)
return (-1);
return ((*q)->Num - (*w)->Num);
}
int compareCurve (const void *a, const void *b){
Curve **q, **w;
q = (Curve **) a;
w = (Curve **) b;
return ((*q)->Num - (*w)->Num);
}
int compareAttractor (const void *a, const void *b){
Attractor **q, **w;
q = (Attractor **) a;
w = (Attractor **) b;
return ((*q)->Num - (*w)->Num);
}
int compareSurface (const void *a, const void *b){
Surface **q, **w;
q = (Surface **) a;
w = (Surface **) b;
return ((*q)->Num - (*w)->Num);
}
int compareVolume (const void *a, const void *b){
Volume **q, **w;
q = (Volume **) a;
w = (Volume **) b;
return ((*q)->Num - (*w)->Num);
}
int compareSxF (const void *a, const void *b){
SxF *q, *w;
q = (SxF *) a;
w = (SxF *) b;
return compareFace (&q->F, &w->F);
}
Attractor * Create_Attractor (int Num, double lc1, double lc2, double Radius,
Vertex * v, Curve * c, Surface * s){
Attractor *pA;
pA = (Attractor *) Malloc (sizeof (Attractor));
pA->v = v;
pA->c = c;
pA->s = s;
pA->lc1 = lc1;
pA->lc2 = lc2;
pA->Radius = Radius;
return pA;
}
void Add_SurfaceLoop (int Num, List_T * intlist, Mesh * M){
SurfaceLoop *pSL;
int i, j;
pSL = (SurfaceLoop *) Malloc (sizeof (SurfaceLoop));
pSL->Surfaces = List_Create (List_Nbr (intlist), 1, sizeof (int));
pSL->Num = Num;
for (i = 0; i < List_Nbr (intlist); i++){
List_Read (intlist, i, &j);
List_Add (pSL->Surfaces, &j);
}
Tree_Add (M->SurfaceLoops, &pSL);
}
void Add_PhysicalGroup (int Num, int typ, List_T * intlist, Mesh * M){
PhysicalGroup *pSL;
int i, j;
pSL = (PhysicalGroup *) Malloc (sizeof (PhysicalGroup));
pSL->Entities = List_Create (List_Nbr (intlist), 1, sizeof (int));
pSL->Num = Num;
pSL->Typ = typ;
for (i = 0; i < List_Nbr (intlist); i++){
List_Read (intlist, i, &j);
List_Add (pSL->Entities, &j);
}
List_Add (M->PhysicalGroups, &pSL);
}
void Add_EdgeLoop (int Num, List_T * intlist, Mesh * M){
EdgeLoop *pEL;
int i, j;
pEL = (EdgeLoop *) Malloc (sizeof (EdgeLoop));
pEL->Curves = List_Create (List_Nbr (intlist), 1, sizeof (int));
pEL->Num = Num;
for (i = 0; i < List_Nbr (intlist); i++){
List_Read (intlist, i, &j);
List_Add (pEL->Curves, &j);
}
Tree_Add (M->EdgeLoops, &pEL);
}
void End_Curve (Curve * c){
double det, R2, mat[3][3], R, A3, A1, A4;
Vertex *v[5], v1, v3, v4;
double dd[3], qq[3], AX, f1, f2, DP, dir32[3], dir12[3], n[3], m[3], dir42[3];
double rhs[2], sys[2][2], sol[2];
int i;
Curve *Curve;
if (c->Typ == MSH_SEGM_CIRC ||
c->Typ == MSH_SEGM_CIRC_INV ||
c->Typ == MSH_SEGM_ELLI ||
c->Typ == MSH_SEGM_ELLI_INV){
Curve = c;
if (List_Nbr (Curve->Control_Points) == 4)
List_Read (Curve->Control_Points, 2, &v[4]);
else
v[4] = NULL;
if (Curve->Typ == MSH_SEGM_CIRC_INV ||
Curve->Typ == MSH_SEGM_ELLI_INV){
List_Read (Curve->Control_Points, 0, &v[3]);
List_Read (Curve->Control_Points, 1, &v[2]);
if (!v[4])
List_Read (Curve->Control_Points, 2, &v[1]);
else
List_Read (Curve->Control_Points, 3, &v[1]);
}
else{
List_Read (Curve->Control_Points, 0, &v[1]);
List_Read (Curve->Control_Points, 1, &v[2]);
if (!v[4])
List_Read (Curve->Control_Points, 2, &v[3]);
else
List_Read (Curve->Control_Points, 3, &v[3]);
}
direction (v[2], v[3], dir32);
direction (v[2], v[1], dir12);
if (v[4])
direction (v[2], v[4], dir42);
/*
norme(dir32);
norme(dir12);
norme(dir42);
*/
//prodve(dir12,dir32,n);
dd[0] = dir12[0];
dd[1] = dir12[1];
dd[2] = dir12[2];
qq[0] = dir32[0];
qq[1] = dir32[1];
qq[2] = dir32[2];
norme (dd);
norme (qq);
prodve (dd, qq, n);
if (fabs (n[0]) < 1.e-5 && fabs (n[1]) < 1.e-5 && fabs (n[2]) < 1.e-5){
n[0] = Curve->Circle.n[0];
n[1] = Curve->Circle.n[1];
n[2] = Curve->Circle.n[2];
}
/* BOF BOF BOF */
prodve (n, dir12, m);
v1.Pos.X = dir12[0];
v1.Pos.Y = dir12[1];
v1.Pos.Z = dir12[2];
v3.Pos.X = dir32[0];
v3.Pos.Y = dir32[1];
v3.Pos.Z = dir32[2];
if (v[4]){
v4.Pos.X = dir42[0];
v4.Pos.Y = dir42[1];
v4.Pos.Z = dir42[2];
}
norme (dir12);
norme (n);
norme (m);
mat[2][0] = Curve->Circle.invmat[0][2] = n[0];
mat[2][1] = Curve->Circle.invmat[1][2] = n[1];
mat[2][2] = Curve->Circle.invmat[2][2] = n[2];
mat[1][0] = Curve->Circle.invmat[0][1] = m[0];
mat[1][1] = Curve->Circle.invmat[1][1] = m[1];
mat[1][2] = Curve->Circle.invmat[2][1] = m[2];
mat[0][0] = Curve->Circle.invmat[0][0] = dir12[0];
mat[0][1] = Curve->Circle.invmat[1][0] = dir12[1];
mat[0][2] = Curve->Circle.invmat[2][0] = dir12[2];
if(CTX.geom.old_circle){
if(n[0] == 0.0 && n[1] == 0.0){
mat[2][0] = Curve->Circle.invmat[0][2] = 0;
mat[2][1] = Curve->Circle.invmat[1][2] = 0;
mat[2][2] = Curve->Circle.invmat[2][2] = 1;
mat[1][0] = Curve->Circle.invmat[0][1] = 0;
mat[1][1] = Curve->Circle.invmat[1][1] = 1;
mat[1][2] = Curve->Circle.invmat[2][1] = 0;
mat[0][0] = Curve->Circle.invmat[0][0] = 1;
mat[0][1] = Curve->Circle.invmat[1][0] = 0;
mat[0][2] = Curve->Circle.invmat[2][0] = 0;
}
}
Projette (&v1, mat);
Projette (&v3, mat);
if (v[4])
Projette (&v4, mat);
R = sqrt (v1.Pos.X * v1.Pos.X + v1.Pos.Y * v1.Pos.Y);
R2 = sqrt (v3.Pos.X * v3.Pos.X + v3.Pos.Y * v3.Pos.Y);
A3 = myatan2 (v3.Pos.Y, v3.Pos.X);
if (v[4])
A4 = myatan2 (v4.Pos.Y, v4.Pos.X);
else
A4 = 0.0;
A1 = myatan2 (v1.Pos.Y, v1.Pos.X);
DP = 2 * Pi;
A3 = angle_02pi (A3);
A1 = angle_02pi (A1);
if (v[4])
A4 = angle_02pi (A4);
if (A1 >= A3)
A3 += DP;
if (A4 > A1)
A4 -= DP;
if (v[4]){
AX = (A1 - A4);
sys[0][0] = cos (AX) * cos (A4);
sys[0][1] = -sin (AX) * sin (A4);
sys[1][0] = cos (AX) * sin (A4);
sys[1][1] = sin (AX) * cos (A4);
rhs[0] = v1.Pos.X;
rhs[1] = v1.Pos.Y;
det = sys[0][0] * sys[1][1] - sys[1][0] * sys[0][1];
if (det < 1.e-12){
AX = (A3 - A4);
sys[0][0] = cos (AX) * cos (A4);
sys[0][1] = -sin (AX) * sin (A4);
sys[1][0] = cos (AX) * sin (A4);
sys[1][1] = sin (AX) * cos (A4);
rhs[0] = v3.Pos.X;
rhs[1] = v3.Pos.Y;
det = sys[0][0] * sys[1][1] - sys[1][0] * sys[0][1];
}
if (det < 1.e-12){
f1 = DMAX (R, R2);
f2 = DMIN (R, R2);
}
else{
sys2x2 (sys, rhs, sol);
f1 = sol[0];
f2 = sol[1];
}
}
else{
f1 = f2 = R;
}
Curve->Circle.t1 = A1;
Curve->Circle.t2 = A3;
Curve->Circle.f1 = f1;
Curve->Circle.f2 = f2;
Curve->Circle.incl = A4;
for (i = 0; i < 4; i++)
Curve->Circle.v[i] = v[i];
/*
if (!c->Circle.done){
float proj[4][4];
for (i = 0; i < 4; i++){
for (int j = 0; j < 4; j++){
if (i != 3 && j != 3)
proj[i][j] = Curve->Circle.f1 * Curve->Circle.invmat[i][j];
else
proj[i][j] = 0.0;
}
}
proj[0][3] = Curve->Circle.v[2]->Pos.X;
proj[1][3] = Curve->Circle.v[2]->Pos.Y;
proj[2][3] = Curve->Circle.v[2]->Pos.Z;
proj[3][3] = 1.0;
c->Circle.done = 1;
}
*/
// Un cercle a au moins 16 pts par pi radiants
// c->beg->lc = DMIN (R*Pi/(fabs(c->Circle.t1-c->Circle.t2)*CIRC_GRAN),c->beg->lc);
// c->end->lc = DMIN (R*Pi/(fabs(c->Circle.t1-c->Circle.t2)*CIRC_GRAN),c->end->lc);
}
c->cp = (float *) malloc (4 * List_Nbr (c->Control_Points) * sizeof (float));
for (i = 0; i < List_Nbr (c->Control_Points); i++){
List_Read (c->Control_Points, i, &v[0]);
c->cp[4 * i] = v[0]->Pos.X;
c->cp[4 * i + 1] = v[0]->Pos.Y;
c->cp[4 * i + 2] = v[0]->Pos.Z;
c->cp[4 * i + 3] = v[0]->w;
}
}
void End_Surface (Surface * s){
int i;
Vertex *v;
if (!s->Control_Points || !List_Nbr(s->Control_Points))
return;
s->cp = (float *) Malloc (4 * List_Nbr (s->Control_Points) * sizeof (float));
for (i = 0; i < List_Nbr (s->Control_Points); i++){
List_Read (s->Control_Points, i, &v);
s->cp[4 * i] = v->Pos.X;
s->cp[4 * i + 1] = v->Pos.Y;
s->cp[4 * i + 2] = v->Pos.Z;
s->cp[4 * i + 3] = v->w;
}
}
Curve *Create_Curve (int Num, int Typ, int Order, List_T * Liste,
List_T * Knots, int p1, int p2, double u1, double u2){
Curve *pC;
Vertex *v;
int i, j, iPnt;
double d;
double matcr[4][4] = { {-0.5, 1.5, -1.5, 0.5},
{1.0, -2.5, 2.0, -0.5},
{-0.5, 0.0, 0.5, 0.0},
{0.0, 1.0, 0.0, 0.0} };
double matbs[4][4] = { {-1.0, 3, -3, 1},
{3, -6, 3.0, 0},
{-3, 0.0, 3, 0.0},
{1, 4, 1, 0.0} };
double matbez[4][4] = { {-1.0, 3, -3, 1},
{3, -6, 3.0, 0},
{-3, 3.0, 0, 0.0},
{1, 0, 0, 0.0} };
pC = (Curve *) Malloc (sizeof (Curve));
pC->Vertices = NULL;
pC->Typ = Typ;
pC->Num = Num;
pC->Simplexes = Tree_Create (sizeof (Simplex *), compareSimplex);
pC->TrsfSimplexes = List_Create (1, 10, sizeof (Simplex *));
pC->ConnectedSurfaces = NULL;
pC->Circle.done = 0;
pC->Method = LIBRE;
pC->degre = Order;
pC->Circle.n[0] = 1.0;
pC->Circle.n[1] = 0.0;
pC->Circle.n[2] = 0.0;
if (Typ == MSH_SEGM_SPLN){
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
pC->mat[i][j] = matcr[i][j];
}
else if (Typ == MSH_SEGM_BSPLN){
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
pC->mat[i][j] = matbs[i][j] / 6.0;
}
else if (Typ == MSH_SEGM_BEZIER){
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
pC->mat[i][j] = matbez[i][j];
}
pC->ubeg = u1;
pC->uend = u2;
if (Knots){
pC->k = (float *) malloc (List_Nbr (Knots) * sizeof (float));
double kmin = .0, kmax = 1.;
List_Read (Knots, 0, &kmin);
List_Read (Knots, List_Nbr (Knots) - 1, &kmax);
pC->ubeg = kmin;
pC->uend = kmax;
for (i = 0; i < List_Nbr (Knots); i++){
List_Read (Knots, i, &d);
pC->k[i] = (float) d;
}
}
else
pC->k = NULL;
if (Liste){
pC->Control_Points = List_Create (List_Nbr (Liste), 1, sizeof (Vertex *));
for (j = 0; j < List_Nbr (Liste); j++){
List_Read (Liste, j, &iPnt);
if ((v = FindVertex (iPnt, THEM)))
List_Add (pC->Control_Points, &v);
else
Msg(FATAL, "Unknown Control Point %d in Curve %d", iPnt, pC->Num);
}
}
else {
//End_Curve(pC);
return pC;
}
if (p1 < 0){
List_Read (pC->Control_Points, 0, &pC->beg);
List_Read (pC->Control_Points, List_Nbr (pC->Control_Points) - 1, &pC->end);
}
else {
if ((v = FindVertex (p1, THEM))){
pC->beg = v;
Msg(INFO, "Curve %d First Control Point %d ", pC->Num, v->Num);
}
else{
List_Read (pC->Control_Points, 0, &pC->beg);
Msg(FATAL, "Unknown Control Point %d in Curve %d", p1, pC->Num);
}
if ((v = FindVertex (p2, THEM))){
pC->end = v;
Msg(INFO, "Curve %d First Control Point %d ", pC->Num, v->Num);
}
else{
List_Read (pC->Control_Points, List_Nbr (pC->Control_Points) - 1, &pC->end);
Msg(FATAL, "Unknown Control Point %d in Curve %d", p2, pC->Num);
}
}
End_Curve (pC);
pC->Extrude = NULL;
return (pC);
}
Surface * Create_Surface (int Num, int Typ, int Mat){
Surface *pS;
pS = (Surface *) Malloc (sizeof (Surface));
pS->Num = Num;
pS->Typ = Typ;
pS->Mat = Mat;
pS->Method = LIBRE;
pS->Recombine = 0;
pS->RecombineAngle = 30;
pS->Simplexes = Tree_Create (sizeof (Simplex *), compareQuality);
pS->TrsfSimplexes = List_Create (1, 10, sizeof (Simplex *));
pS->Vertices = Tree_Create (sizeof (Vertex *), compareVertex);
pS->TrsfVertices = List_Create (1, 10, sizeof (Vertex *));
pS->Contours = List_Create (1, 1, sizeof (List_T *));
pS->Orientations = NULL;
pS->Support = pS;
pS->Control_Points = List_Create (1, 10, sizeof (Vertex *));
pS->Extrude = NULL;
pS->STL = NULL;
return (pS);
}
Volume * Create_Volume (int Num, int Typ, int Mat){
Volume *pV;
pV = (Volume *) Malloc (sizeof (Volume));
pV->Num = Num;
pV->Typ = Typ;
pV->Mat = Mat;
pV->Method = LIBRE;
pV->Surfaces = List_Create (1, 2, sizeof (Surface *));
pV->Simplexes = Tree_Create (sizeof (Simplex *), compareQuality);
pV->Vertices = Tree_Create (sizeof (Vertex *), compareVertex);
pV->Hexahedra = Tree_Create (sizeof (Hexahedron *), compareHexahedron);
pV->Prisms = Tree_Create (sizeof (Prism *), comparePrism);
pV->Extrude = NULL;
return pV;
}
Hexahedron * Create_Hexahedron (Vertex * v1, Vertex * v2, Vertex * v3, Vertex * v4,
Vertex * v5, Vertex * v6, Vertex * v7, Vertex * v8){
Hexahedron *h;
h = (Hexahedron *) Malloc (sizeof (Hexahedron));
h->iEnt = -1;
h->Num = ++CurrentSimplexNumber;
h->V[0] = v1;
h->V[1] = v2;
h->V[2] = v3;
h->V[3] = v4;
h->V[4] = v5;
h->V[5] = v6;
h->V[6] = v7;
h->V[7] = v8;
h->VSUP = NULL;
return (h);
}
Prism * Create_Prism (Vertex * v1, Vertex * v2, Vertex * v3,
Vertex * v4, Vertex * v5, Vertex * v6){
Prism *p;
p = (Prism *) Malloc (sizeof (Prism));
p->iEnt = -1;
p->Num = ++CurrentSimplexNumber;
p->V[0] = v1;
p->V[1] = v2;
p->V[2] = v3;
p->V[3] = v4;
p->V[4] = v5;
p->V[5] = v6;
p->VSUP = NULL;
return (p);
}