Skip to content
Snippets Groups Projects
Forked from gmsh / gmsh
21345 commits behind the upstream repository.
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);
}