Пример #1
0
std::string gmshEdge::getAdditionalInfoString()
{
  if(List_Nbr(c->Control_Points) > 0){
    std::ostringstream sstream;
    sstream << "{";
    for(int i = 0; i < List_Nbr(c->Control_Points); i++){
      if(i) sstream << " ";
      Vertex *v;
      List_Read(c->Control_Points, i, &v);
      sstream << v->Num;
    }
    sstream << "}";

    if(meshAttributes.method == MESH_TRANSFINITE){
      sstream << " transfinite (" << meshAttributes.nbPointsTransfinite;
      int type = meshAttributes.typeTransfinite;
      if(std::abs(type) == 1)
        sstream << ", progression " << sign(type) * meshAttributes.coeffTransfinite;
      else if(std::abs(type) == 2)
        sstream << ", bump " << meshAttributes.coeffTransfinite;
      sstream << ")";
    }
    if(meshAttributes.extrude)
      sstream << " extruded";
    if(meshAttributes.reverseMesh)
      sstream << " reversed";

    return sstream.str();
  }
  else
    return GEdge::getAdditionalInfoString();
}
Пример #2
0
// Bezier
static Vertex InterpolateBezier(Curve *Curve, double u, int derivee)
{
  int NbCurves = (List_Nbr(Curve->Control_Points) - 1) / 3;
  int iCurve = (int)floor(u * (double)NbCurves);
  if(iCurve >= NbCurves) iCurve = NbCurves - 1; // u = 1
  if(iCurve <= 0) iCurve = 0;
  double t1 = (double)(iCurve) / (double)(NbCurves);
  double t2 = (double)(iCurve+1) / (double)(NbCurves);
  double t = (u - t1) / (t2 - t1);
  Vertex *v[4];
  for(int i = 0; i < 4; i++) {
    List_Read(Curve->Control_Points, iCurve * 3 + i , &v[i]);
  }

  if(Curve->geometry){
    SPoint2 pp = InterpolateCubicSpline(v, t, Curve->mat, t1, t2, Curve->geometry,derivee);
    SPoint3 pt = Curve->geometry->point(pp);
    Vertex V;
    V.Pos.X = pt.x();
    V.Pos.Y = pt.y();
    V.Pos.Z = pt.z();
    return V;
  }
  else
    return InterpolateCubicSpline(v, t, Curve->mat, derivee, t1, t2);
}
Пример #3
0
bool gmshFace::containsPoint(const SPoint3 &pt) const
{
  if(s->Typ == MSH_SURF_PLAN){
    // OK to use the normal from the mean plane here: we compensate
    // for the (possibly wrong) orientation at the end
    double n[3] = {meanPlane.a, meanPlane.b, meanPlane.c};
    norme(n);
    double angle = 0.;
    double v[3] = {pt.x(), pt.y(), pt.z()};
    for(int i = 0; i < List_Nbr(s->Generatrices); i++) {
      Curve *c;
      List_Read(s->Generatrices, i, &c);
      int N = (c->Typ == MSH_SEGM_LINE) ? 1 : 10;
      for(int j = 0; j < N; j++) {
        double u1 = (double)j / (double)N;
        double u2 = (double)(j + 1) / (double)N;
        Vertex p1 = InterpolateCurve(c, u1, 0);
        Vertex p2 = InterpolateCurve(c, u2, 0);
        double v1[3] = {p1.Pos.X, p1.Pos.Y, p1.Pos.Z};
        double v2[3] = {p2.Pos.X, p2.Pos.Y, p2.Pos.Z};
        angle += angle_plan(v, v1, v2, n);
      }
    }
    // we're inside if angle equals 2 * pi
    if(fabs(angle) > 2 * M_PI - 0.5 && fabs(angle) < 2 * M_PI + 0.5)
      return true;
    return false;
  }

  return false;
}
Пример #4
0
bool iSRuledSurfaceASphere(Surface *s, SPoint3 &center, double &radius)
{
  if(s->Typ != MSH_SURF_REGL && s->Typ != MSH_SURF_TRIC) return false;

  bool isSphere = true;
  Vertex *O = 0;
  Curve *C[4] = {0, 0, 0, 0};
  for(int i = 0; i < std::min(List_Nbr(s->Generatrices), 4); i++)
    List_Read(s->Generatrices, i, &C[i]);

  if(List_Nbr(s->InSphereCenter)) {
    // it's on a sphere: get the center
    List_Read(s->InSphereCenter, 0, &O);
  }
  else{
    // try to be intelligent (hum)
    for(int i = 0; i < std::min(List_Nbr(s->Generatrices), 4); i++) {
      if(C[i]->Typ != MSH_SEGM_CIRC && C[i]->Typ != MSH_SEGM_CIRC_INV){
        isSphere = false;
      }
      else if(isSphere){
        if(!i){
          List_Read(C[i]->Control_Points, 1, &O);
          ((double *)center)[0] = O->Pos.X;
          ((double *)center)[1] = O->Pos.Y;
          ((double *)center)[2] = O->Pos.Z;
        }
        else{
          Vertex *tmp;
          List_Read(C[i]->Control_Points, 1, &tmp);
          if(compareVertex(&O, &tmp))
            isSphere = false;
        }
      }
    }
  }
  if (isSphere && C[0]){
    Vertex *p = C[0]->beg;
    radius = sqrt ((p->Pos.X - center.x())+
                   (p->Pos.Y - center.y())+
                   (p->Pos.Z - center.z()));
  }

  return isSphere;
}
Пример #5
0
int gmshEdge::minimumDrawSegments () const
{
  int n = List_Nbr(c->Control_Points) - 1;
  if(!n) n = GEdge::minimumDrawSegments();

  if(geomType() == Line && !c->geometry)
    return n;
  else
    return CTX::instance()->geom.numSubEdges * n;
}
Пример #6
0
SVector3 gmshFace::normal(const SPoint2 &param) const
{
  if(s->Typ != MSH_SURF_PLAN){
    Vertex vu = InterpolateSurface(s, param[0], param[1], 1, 1);
    Vertex vv = InterpolateSurface(s, param[0], param[1], 1, 2);
    Vertex n = vu % vv;
    n.norme();
    return SVector3(n.Pos.X, n.Pos.Y, n.Pos.Z);
  }
  else{
    // We cannot use InterpolateSurface() for plane surfaces since it
    // relies on the mean plane, which does not respect the
    // orientation

    // FIXME: move this test at the end of the MeanPlane computation
    // routine--and store the correct normal, damn it!

    double n[3] = {meanPlane.a, meanPlane.b, meanPlane.c};
    norme(n);
    GPoint pt = point(param.x(), param.y());
    double v[3] = {pt.x(), pt.y(), pt.z()};
    int NP = 10, tries = 0;
    while(1){
      tries++;
      double angle = 0.;
      for(int i = 0; i < List_Nbr(s->Generatrices); i++) {
        Curve *c;
        List_Read(s->Generatrices, i, &c);
        int N = (c->Typ == MSH_SEGM_LINE) ? 1 : NP;
        for(int j = 0; j < N; j++) {
          double u1 = (double)j / (double)N;
          double u2 = (double)(j + 1) / (double)N;
          Vertex p1 = InterpolateCurve(c, u1, 0);
          Vertex p2 = InterpolateCurve(c, u2, 0);
          double v1[3] = {p1.Pos.X, p1.Pos.Y, p1.Pos.Z};
          double v2[3] = {p2.Pos.X, p2.Pos.Y, p2.Pos.Z};
          angle += angle_plan(v, v1, v2, n);
        }
      }
      if(fabs(angle) < 0.5){ // we're outside
        NP *= 2;
        Msg::Debug("Could not compute normal of surface %d - retrying with %d points",
                   tag(), NP);
        if(tries > 10){
          Msg::Warning("Could not orient normal of surface %d", tag());
          return SVector3(n[0], n[1], n[2]);
        }
      }
      else if(angle > 0)
        return SVector3(n[0], n[1], n[2]);
      else
        return SVector3(-n[0], -n[1], -n[2]);
    }
  }
}
Пример #7
0
gmshRegion::gmshRegion(GModel *m, ::Volume *volume)
  : GRegion(m, volume->Num), v(volume)
{
  for(int i = 0; i < List_Nbr(v->Surfaces); i++){
    Surface *s;
    List_Read(v->Surfaces, i, &s);
    int ori;
    List_Read(v->SurfacesOrientations, i, &ori);
    GFace *f = m->getFaceByTag(abs(s->Num));
    if(f){
      l_faces.push_back(f);
      l_dirs.push_back(ori);
      f->addRegion(this);
    }
    else
      Msg::Error("Unknown surface %d", s->Num);
  }
  for(int i = 0; i < List_Nbr(v->SurfacesByTag); i++){
    int is;
    List_Read(v->SurfacesByTag, i, &is);
    GFace *f = m->getFaceByTag(abs(is));
    if(f){
      l_faces.push_back(f);
      l_dirs.push_back(sign(is));
      f->addRegion(this);
    }
    else
      Msg::Error("Unknown surface %d", is);
  }
  if(v->EmbeddedSurfaces){
    for(int i = 0; i < List_Nbr(v->EmbeddedSurfaces); i++){
      Surface *s;
      List_Read(v->EmbeddedSurfaces, i, &s);
      GFace *gf = m->getFaceByTag(abs(s->Num));
      if(gf)
	addEmbeddedFace(gf);
      else
	Msg::Error("Unknown surface %d", s->Num);
    }
  }
  resetMeshAttributes();
}
Пример #8
0
static std::string list2string(List_T *list)
{
  std::ostringstream sstream;
  for(int i = 0; i < List_Nbr(list); i++){
    int num;
    List_Read(list, i, &num);
    if(i) sstream << ", ";
    sstream << num;
  }
  return sstream.str();
}
Пример #9
0
static Vertex InterpolateNurbs(Curve *Curve, double u, int derivee)
{
  double Nb[1000];
  int span = findSpan(u, Curve->degre, List_Nbr(Curve->Control_Points), Curve->k);
  basisFuns(u, span, Curve->degre, Curve->k, Nb);
  Vertex p;
  p.Pos.X = p.Pos.Y = p.Pos.Z = p.w = p.lc = 0.0;
  for(int i = Curve->degre; i >= 0; --i) {
    Vertex *v;
    List_Read(Curve->Control_Points, span - Curve->degre + i, &v);
    p.Pos.X += Nb[i] * v->Pos.X;
    p.Pos.Y += Nb[i] * v->Pos.Y;
    p.Pos.Z += Nb[i] * v->Pos.Z;
    p.w += Nb[i] * v->w;
    p.lc += Nb[i] * v->lc;
  }
  return p;
}
Пример #10
0
void gmshRegion::resetMeshAttributes()
{
  meshAttributes.recombine3D = v->Recombine3D;
  meshAttributes.method = v->Method;
  meshAttributes.QuadTri = v->QuadTri;
  meshAttributes.extrude = v->Extrude;
  if(meshAttributes.method == MESH_TRANSFINITE){
    meshAttributes.corners.clear();
    for(int i = 0; i < List_Nbr(v->TrsfPoints); i++){
      Vertex *corn;
      List_Read(v->TrsfPoints, i, &corn);
      GVertex *gv = model()->getVertexByTag(corn->Num);
      if(gv)
        meshAttributes.corners.push_back(gv);
      else
        Msg::Error("Unknown vertex %d in transfinite attributes", corn->Num);
    }
  }
}
Пример #11
0
void gmshFace::resetMeshAttributes()
{
  meshAttributes.recombine = s->Recombine;
  meshAttributes.recombineAngle = s->RecombineAngle;
  meshAttributes.method = s->Method;
  meshAttributes.extrude = s->Extrude;
  if(meshAttributes.method == MESH_TRANSFINITE){
    meshAttributes.transfiniteArrangement = s->Recombine_Dir;
    meshAttributes.transfiniteSmoothing = s->TransfiniteSmoothing;
    meshAttributes.corners.clear();
    for(int i = 0; i < List_Nbr(s->TrsfPoints); i++){
      Vertex *corn;
      List_Read(s->TrsfPoints, i, &corn);
      GVertex *gv = model()->getVertexByTag(corn->Num);
      if(gv)
        meshAttributes.corners.push_back(gv);
      else
        Msg::Error("Unknown vertex %d in transfinite attributes", corn->Num);
    }
  }
  meshAttributes.reverseMesh = s->ReverseMesh;
}
Пример #12
0
static Vertex InterpolateExtrudedSurface(Surface *s, double u, double v)
{
  Curve *c = FindCurve(s->Extrude->geo.Source);

  // find position of c in the list of generatrices
  int num = -1;
  for(int i = 0; i < List_Nbr(s->Generatrices); i++){
    if(c == *(Curve**)List_Pointer(s->Generatrices, i)){
      num = i;
      break;
    }
  }

  Vertex T;

  if(num < 0){
    Msg::Error("Unknown curve in extruded surface");
    return T;
  }

  switch(num){
  case 0:
    T = InterpolateCurve(c, c->ubeg + (c->uend - c->ubeg) * u, 0);
    s->Extrude->Extrude(v, T.Pos.X, T.Pos.Y, T.Pos.Z);
    return T;
  case 1:
    T = InterpolateCurve(c, c->ubeg + (c->uend - c->ubeg) * v, 0);
    s->Extrude->Extrude(1. - u, T.Pos.X, T.Pos.Y, T.Pos.Z);
    return T;
  case 2:
    T = InterpolateCurve(c, c->ubeg + (c->uend - c->ubeg) * (1. - u), 0);
    s->Extrude->Extrude(1. - v, T.Pos.X, T.Pos.Y, T.Pos.Z);
    return T;
  default:
    T = InterpolateCurve(c, c->ubeg + (c->uend - c->ubeg) * (1. - v), 0);
    s->Extrude->Extrude(u, T.Pos.X, T.Pos.Y, T.Pos.Z);
    return T;
  }
}
Пример #13
0
// Uniform BSplines
static Vertex InterpolateUBS(Curve *Curve, double u, int derivee)
{
  bool periodic = (Curve->end == Curve->beg);
  int NbControlPoints = List_Nbr(Curve->Control_Points);
  int NbCurves = NbControlPoints + (periodic ? -1 : 1);
  int iCurve = (int)floor(u * (double)NbCurves);
  if(iCurve == NbCurves) iCurve -= 1; // u = 1
  double t1 = (double)(iCurve) / (double)(NbCurves);
  double t2 = (double)(iCurve+1) / (double)(NbCurves);
  double t = (u - t1) / (t2 - t1);
  Vertex *v[4];
  for(int i = 0; i < 4; i++) {
    int k;
    if (periodic) {
      k = (iCurve - 1 + i) % (NbControlPoints - 1);
      if (k < 0)
        k += NbControlPoints - 1;
    }
    else {
      k = std::max(0, std::min(iCurve - 2 + i, NbControlPoints -1));
    }
    List_Read(Curve->Control_Points, k , &v[i]);
  }

  if(Curve->geometry){
    SPoint2 pp = InterpolateCubicSpline(v, t, Curve->mat, t1, t2, Curve->geometry,derivee);
    SPoint3 pt = Curve->geometry->point(pp);
    Vertex V;
    V.Pos.X = pt.x();
    V.Pos.Y = pt.y();
    V.Pos.Z = pt.z();
    return V;
  }
  else
    return InterpolateCubicSpline(v, t, Curve->mat, derivee, t1, t2);
}
Пример #14
0
int GModel::exportDiscreteGEOInternals()
{
  if(_geo_internals) delete _geo_internals;
  _geo_internals = new GEO_Internals;

  for(viter it = firstVertex(); it != lastVertex(); it++){
    Vertex *v = Create_Vertex((*it)->tag(), (*it)->x(), (*it)->y(), (*it)->z(),
                              (*it)->prescribedMeshSizeAtVertex(), 1.0);
    Tree_Add(this->getGEOInternals()->Points, &v);
  }

  for(eiter it = firstEdge(); it != lastEdge(); it++){
    if((*it)->geomType() == GEntity::DiscreteCurve){
      Curve *c = Create_Curve((*it)->tag(), MSH_SEGM_DISCRETE, 1,
                              NULL, NULL, -1, -1, 0., 1.);
      List_T *points = Tree2List(_geo_internals->Points);
      GVertex *gvb = (*it)->getBeginVertex();
      GVertex *gve = (*it)->getEndVertex();
      int nb = 2 ;
      c->Control_Points = List_Create(nb, 1, sizeof(Vertex *));
      for(int i = 0; i < List_Nbr(points); i++) {
        Vertex *v;
        List_Read(points, i, &v);
        if (v->Num == gvb->tag()) {
          List_Add(c->Control_Points, &v);
          c->beg = v;
        }
        if (v->Num == gve->tag()) {
          List_Add(c->Control_Points, &v);
          c->end = v;
        }
      }
      End_Curve(c);
      Tree_Add(this->getGEOInternals()->Curves, &c);
      CreateReversedCurve(c);
      List_Delete(points);
    }
  }

  for(fiter it = firstFace(); it != lastFace(); it++){
    if((*it)->geomType() == GEntity::DiscreteSurface){
      Surface *s = Create_Surface((*it)->tag(), MSH_SURF_DISCRETE);
      std::list<GEdge*> edges = (*it)->edges();
      s->Generatrices = List_Create(edges.size(), 1, sizeof(Curve *));
      List_T *curves = Tree2List(_geo_internals->Curves);
      Curve *c;
      for(std::list<GEdge*>::iterator ite = edges.begin(); ite != edges.end(); ite++){
        for(int i = 0; i < List_Nbr(curves); i++) {
          List_Read(curves, i, &c);
          if (c->Num == (*ite)->tag()) {
            List_Add(s->Generatrices, &c);
          }
        }
      }
      Tree_Add(this->getGEOInternals()->Surfaces, &s);
      List_Delete(curves);
    }
  }

  // TODO: create Volumes from discreteRegions

  Msg::Debug("Geo internal model has:");
  Msg::Debug("%d Vertices", Tree_Nbr(_geo_internals->Points));
  Msg::Debug("%d Edges", Tree_Nbr(_geo_internals->Curves));
  Msg::Debug("%d Faces", Tree_Nbr(_geo_internals->Surfaces));

  return 1;
}
Пример #15
0
int GModel::importGEOInternals()
{
  if(Tree_Nbr(_geo_internals->Points)) {
    List_T *points = Tree2List(_geo_internals->Points);
    for(int i = 0; i < List_Nbr(points); i++){
      Vertex *p;
      List_Read(points, i, &p);
      GVertex *v = getVertexByTag(p->Num);
      if(!v){
        v = new gmshVertex(this, p);
        add(v);
      }
      if(!p->Visible) v->setVisibility(0);
    }
    List_Delete(points);
  }
  if(Tree_Nbr(_geo_internals->Curves)) {
    List_T *curves = Tree2List(_geo_internals->Curves);
    for(int i = 0; i < List_Nbr(curves); i++){
      Curve *c;
      List_Read(curves, i, &c);
      if(c->Num >= 0){
	GEdge *e = getEdgeByTag(c->Num);
        if(!e && c->Typ == MSH_SEGM_COMPOUND){
          std::vector<GEdge*> comp;
          for(unsigned int j = 0; j < c->compound.size(); j++){
            GEdge *ge = getEdgeByTag(c->compound[j]);
            if(ge) comp.push_back(ge);
          }
          e = new GEdgeCompound(this, c->Num, comp);
	  e->meshAttributes.method = c->Method;
	  e->meshAttributes.nbPointsTransfinite = c->nbPointsTransfinite;
	  e->meshAttributes.typeTransfinite = c->typeTransfinite;
	  e->meshAttributes.coeffTransfinite = c->coeffTransfinite;
	  e->meshAttributes.extrude = c->Extrude;
	  e->meshAttributes.reverseMesh = c->ReverseMesh;
          add(e);
        }
        else if(!e && c->beg && c->end){
          e = new gmshEdge(this, c,
                           getVertexByTag(c->beg->Num),
                           getVertexByTag(c->end->Num));
          add(e);
        }
        else if(!e){
          e = new gmshEdge(this, c, 0, 0);
          add(e);
        }


        if(!c->Visible) e->setVisibility(0);
        if(c->Color.type) e->setColor(c->Color.mesh);
        if(c->degenerated) {
          e->setTooSmall(true);
        }
      }
    }
    List_Delete(curves);
  }
  if(Tree_Nbr(_geo_internals->Surfaces)) {
    List_T *surfaces = Tree2List(_geo_internals->Surfaces);
    for(int i = 0; i < List_Nbr(surfaces); i++){
      Surface *s;
      List_Read(surfaces, i, &s);
      GFace *f = getFaceByTag(s->Num);
      if(!f && s->Typ == MSH_SURF_COMPOUND){
        std::list<GFace*> comp;
        for(unsigned int j = 0; j < s->compound.size(); j++){
          GFace *gf = getFaceByTag(s->compound[j]);
          if(gf)
            comp.push_back(gf);
        }
	std::list<GEdge*> b[4];
        for(int j = 0; j < 4; j++){
	  for(unsigned int k = 0; k < s->compoundBoundary[j].size(); k++){
	    GEdge *ge = getEdgeByTag(s->compoundBoundary[j][k]);
	    if(ge) b[j].push_back(ge);
	  }
	}
        int param = CTX::instance()->mesh.remeshParam;

	GFaceCompound::typeOfCompound typ = GFaceCompound::HARMONIC_CIRCLE;
	if (param == 1) typ =  GFaceCompound::CONFORMAL_SPECTRAL;
	if (param == 2) typ =  GFaceCompound::RADIAL_BASIS;
	if (param == 3) typ =  GFaceCompound::HARMONIC_PLANE;
	if (param == 4) typ =  GFaceCompound::CONVEX_CIRCLE;
	if (param == 5) typ =  GFaceCompound::CONVEX_PLANE;
	if (param == 6) typ =  GFaceCompound::HARMONIC_SQUARE;
	if (param == 7) typ =  GFaceCompound::CONFORMAL_FE;

        int algo = CTX::instance()->mesh.remeshAlgo;
	f = new GFaceCompound(this, s->Num, comp, b[0], b[1], b[2], b[3], typ, algo);

        f->meshAttributes.recombine = s->Recombine;
        f->meshAttributes.recombineAngle = s->RecombineAngle;
        f->meshAttributes.method = s->Method;
        f->meshAttributes.extrude = s->Extrude;
        // transfinite import Added by Trevor Strickler.  This helps when experimenting
        // to create compounds from transfinite surfs. Not having it does not break
        // anything Gmsh *officially* does right now, but maybe it was left out by mistake??? and could
        // cause problems later?
        f->meshAttributes.transfiniteArrangement = s->Recombine_Dir;
        f->meshAttributes.corners.clear();
        for(int i = 0; i < List_Nbr(s->TrsfPoints); i++){
          Vertex *corn;
          List_Read(s->TrsfPoints, i, &corn);
          GVertex *gv = f->model()->getVertexByTag(corn->Num);
          if(gv)
            f->meshAttributes.corners.push_back(gv);
          else
            Msg::Error("Unknown vertex %d in transfinite attributes", corn->Num);
        }
        
        add(f);
        if(s->EmbeddedCurves){
          for(int i = 0; i < List_Nbr(s->EmbeddedCurves); i++){
            Curve *c;
            List_Read(s->EmbeddedCurves, i, &c);
            GEdge *e = getEdgeByTag(abs(c->Num));
            if(e)
              f->addEmbeddedEdge(e);
            else
              Msg::Error("Unknown curve %d", c->Num);
          }
        }
        if(s->EmbeddedPoints){
          for(int i = 0; i < List_Nbr(s->EmbeddedPoints); i++){
            Vertex *v;
            List_Read(s->EmbeddedPoints, i, &v);
            GVertex *gv = getVertexByTag(v->Num);
            if(gv)
              f->addEmbeddedVertex(gv);
            else
              Msg::Error("Unknown point %d", v->Num);
          }
        }
      }
      else if(!f){
        f = new gmshFace(this, s);
        add(f);
      }
      else
        f->resetMeshAttributes();
      if(!s->Visible) f->setVisibility(0);
      if(s->Color.type) f->setColor(s->Color.mesh);
    }
    List_Delete(surfaces);
  }
  if(Tree_Nbr(_geo_internals->Volumes)) {
    List_T *volumes = Tree2List(_geo_internals->Volumes);
    for(int i = 0; i < List_Nbr(volumes); i++){
      Volume *v;
      List_Read(volumes, i, &v);
      GRegion *r = getRegionByTag(v->Num);
      if(!r && v->Typ == MSH_VOLUME_COMPOUND){
        std::vector<GRegion*> comp;
        for(unsigned int j = 0; j < v->compound.size(); j++){
          GRegion *gr = getRegionByTag(v->compound[j]);
          if(gr) comp.push_back(gr);
        }
        r = new GRegionCompound(this, v->Num, comp);
        if(v->EmbeddedSurfaces){
          for(int i = 0; i < List_Nbr(v->EmbeddedSurfaces); i++){
            Surface *s;
            List_Read(v->EmbeddedSurfaces, i, &s);
            GFace *gf = getFaceByTag(abs(s->Num));
            if(gf)
              r->addEmbeddedFace(gf);
            else
              Msg::Error("Unknown surface %d", s->Num);
          }
        }
        add(r);
      }
      else if(!r){
        r = new gmshRegion(this, v);
        add(r);
      }
      else
        r->resetMeshAttributes();
      if(!v->Visible) r->setVisibility(0);
      if(v->Color.type) r->setColor(v->Color.mesh);
    }
    List_Delete(volumes);
  }
  for(int i = 0; i < List_Nbr(_geo_internals->PhysicalGroups); i++){
    PhysicalGroup *p;
    List_Read(_geo_internals->PhysicalGroups, i, &p);
    for(int j = 0; j < List_Nbr(p->Entities); j++){
      int num;
      List_Read(p->Entities, j, &num);
      GEntity *ge = 0;
      int tag = CTX::instance()->geom.orientedPhysicals ? abs(num) : num;
      switch(p->Typ){
      case MSH_PHYSICAL_POINT:   ge = getVertexByTag(tag); break;
      case MSH_PHYSICAL_LINE:    ge = getEdgeByTag(tag); break;
      case MSH_PHYSICAL_SURFACE: ge = getFaceByTag(tag); break;
      case MSH_PHYSICAL_VOLUME:  ge = getRegionByTag(tag); break;
      }
      int pnum = CTX::instance()->geom.orientedPhysicals ? (sign(num) * p->Num) : p->Num;
      if(ge && std::find(ge->physicals.begin(), ge->physicals.end(), pnum) ==
         ge->physicals.end())
        ge->physicals.push_back(pnum);
    }
  }

  // create periodic mesh relationships

  for (std::map<int,int>::iterator it = _geo_internals->periodicEdges.begin();
       it != _geo_internals->periodicEdges.end(); ++it){
    GEdge *ge = getEdgeByTag(abs(it->first));
    if (ge){
      int MASTER = it->second * (it->first > 0 ? 1 : -1);
      ge->setMeshMaster(MASTER);
    }
  }
  for (std::map<int,int>::iterator it = _geo_internals->periodicFaces.begin();
       it != _geo_internals->periodicFaces.end(); ++it){
    GFace *gf = getFaceByTag(abs(it->first));
    if (gf)gf->setMeshMaster(it->second * (it->first > 0 ? 1 : -1));
  }

  for (eiter it = firstEdge() ; it != lastEdge() ; ++it){
    int meshMaster = (*it)->meshMaster();
    if (meshMaster != (*it)->tag()){
      GEdge *ge_master = getEdgeByTag(abs(meshMaster));
      if(ge_master)(*it)->getBeginVertex()->setMeshMaster ( (meshMaster > 0)  ? ge_master->getBeginVertex()->tag() : ge_master->getEndVertex()->tag());
      if(ge_master)(*it)->getEndVertex()->setMeshMaster ( (meshMaster < 0)  ? ge_master->getBeginVertex()->tag() : ge_master->getEndVertex()->tag());
    }
  }

  Msg::Debug("Gmsh model (GModel) imported:");
  Msg::Debug("%d Vertices", vertices.size());
  Msg::Debug("%d Edges", edges.size());
  Msg::Debug("%d Faces", faces.size());
  Msg::Debug("%d Regions", regions.size());

  return 1;
}
Пример #16
0
gmshFace::gmshFace(GModel *m, Surface *face)
  : GFace(m, face->Num), s(face), isSphere(false), radius(0.)
{
  resetMeshAttributes();

  // edgeCounterparts = s->edgeCounterparts;
  // affineTransform = s->affineTransform;

  std::vector<GEdge*> eds;
  std::vector<int> nums;
  for(int i = 0; i < List_Nbr(s->Generatrices); i++){
    Curve *c;
    List_Read(s->Generatrices, i, &c);
    GEdge *e = m->getEdgeByTag(abs(c->Num));
    if(e){
      eds.push_back(e);
      nums.push_back(c->Num);
    }
    else
      Msg::Error("Unknown curve %d", c->Num);
  }
  for(int i = 0; i < List_Nbr(s->GeneratricesByTag); i++){
    int j;
    List_Read(s->GeneratricesByTag, i, &j);
    GEdge *e = m->getEdgeByTag(abs(j));
    if(e){
      eds.push_back(e);
      nums.push_back(j);
    }
    else
      Msg::Error("Unknown curve %d", j);
  }

  std::list<GEdge*> l_wire;
  GVertex *first = 0;
  for(unsigned int i = 0; i < eds.size(); i++){
    GEdge *e = eds[i];
    int num = nums[i];
    GVertex *start = (num > 0) ? e->getBeginVertex() : e->getEndVertex();
    GVertex *next  = (num > 0) ? e->getEndVertex() : e->getBeginVertex();
    if (!first) first = start;
    l_wire.push_back(e);
    if (next == first){
      edgeLoops.push_back(GEdgeLoop(l_wire));
      l_wire.clear();
      first = 0;
    }
    l_edges.push_back(e);
    e->addFace(this);
    l_dirs.push_back((num > 0) ? 1 : -1);
    if (List_Nbr(s->Generatrices) == 2){
      e->meshAttributes.minimumMeshSegments =
        std::max(e->meshAttributes.minimumMeshSegments, 2);
    }
  }

  // always compute and store the mean plane for plane surfaces (using
  // the bounding vertices)
  if(s->Typ == MSH_SURF_PLAN) computeMeanPlane();

  if(s->EmbeddedCurves){
    for(int i = 0; i < List_Nbr(s->EmbeddedCurves); i++){
      Curve *c;
      List_Read(s->EmbeddedCurves, i, &c);
      GEdge *e = m->getEdgeByTag(abs(c->Num));
      if(e)
        addEmbeddedEdge(e);
      else
        Msg::Error("Unknown curve %d", c->Num);
    }
  }
  if(s->EmbeddedPoints){
    for(int i = 0; i < List_Nbr(s->EmbeddedPoints); i++){
      Vertex *v;
      List_Read(s->EmbeddedPoints, i, &v);
      GVertex *gv = m->getVertexByTag(v->Num);
      if(gv)
        embedded_vertices.push_back(gv);
      else
        Msg::Error("Unknown point %d", v->Num);
    }
  }
  isSphere = iSRuledSurfaceASphere(s, center, radius);
}
Пример #17
0
void gmshEdge::discretize(double tol, std::vector<SPoint3> &pts, std::vector<double> &ts)
{
  switch(c->Typ) {
    case MSH_SEGM_LINE :
      {
        int NPt = List_Nbr(c->Control_Points);
        pts.resize(NPt);
        ts.resize(NPt);
        for (int i = 0; i < NPt; ++i) {
          pts[i]= curveGetPoint(c, i);
          ts[i] = i / (double) (NPt - 1);
        }
        return;
      }
    case MSH_SEGM_BEZIER :
      {
        int NbCurves = (List_Nbr(c->Control_Points) - 1) / 3;
        for (int iCurve = 0; iCurve < NbCurves; ++iCurve) {
          double t1 = (iCurve) / (double)(NbCurves);
          double t2 = (iCurve+1) / (double)(NbCurves);
          SPoint3 pt[4];
          for(int i = 0; i < 4; i++) {
            pt[i] = curveGetPoint(c, iCurve * 3 + i);
          }
          std::vector<double> lts;
          std::vector<SPoint3> lpts;
          decasteljau(tol, pt[0], pt[1], pt[2], pt[3], lpts, lts);
          for (size_t i = (iCurve == 0 ? 0 : 1); i < lpts.size(); ++i) {
            pts.push_back(lpts[i]);
            ts.push_back(t1 + lts[i] * (t2 - t1));
          }
        }
        break;
      }
    case MSH_SEGM_BSPLN:
      {
        bool periodic = (c->end == c->beg);
        int NbControlPoints = List_Nbr(c->Control_Points);
        int NbCurves = NbControlPoints + (periodic ? -1 : 1);
        SPoint3 pt[4];
        for (int iCurve = 0; iCurve < NbCurves; ++iCurve) {
          double t1 = (iCurve) / (double)(NbCurves);
          double t2 = (iCurve+1) / (double)(NbCurves);
          for(int i = 0; i < 4; i++) {
            int k;
            if (periodic) {
              k = (iCurve - 1 + i) % (NbControlPoints - 1);
              if (k < 0)
                k += NbControlPoints - 1;
            }
            else {
              k = std::max(0, std::min(iCurve - 2 + i, NbControlPoints -1));
            }
            pt[i] = curveGetPoint(c, k);
          }
          SPoint3 bpt[4] = {
            (pt[0] + pt[1] * 4 + pt[2]) * (1./6.),
            (pt[1] * 2 + pt[2]) * (1./3.),
            (pt[1] + pt[2] * 2) * (1./3.),
            (pt[1] + pt[2] * 4 + pt[3]) * (1./6.)
          };
          std::vector<double> lts;
          std::vector<SPoint3> lpts;
          decasteljau(tol, bpt[0], bpt[1], bpt[2], bpt[3], lpts, lts);
          for (size_t i = (iCurve == 0 ? 0 : 1); i < lpts.size(); ++i) {
            pts.push_back(lpts[i]);
            ts.push_back(t1 + lts[i] * (t2 - t1));
          }
        }
        break;
      }
    case MSH_SEGM_SPLN:
      {
        int NbCurves = List_Nbr(c->Control_Points) - 1;
        SPoint3 pt[4];
        for (int iCurve = 0; iCurve < NbCurves; ++iCurve) {
          double t1 = (iCurve) / (double)(NbCurves);
          double t2 = (iCurve+1) / (double)(NbCurves);
          pt[1] = curveGetPoint(c, iCurve);
          pt[2] = curveGetPoint(c, iCurve + 1);
          if(iCurve == 0) {
            if(c->beg == c->end)
              pt[0] = curveGetPoint(c, NbCurves - 1);
            else
              pt[0] = SPoint3(pt[1] * 2 - pt[2]);
          }
          else
            pt[0] = curveGetPoint(c, iCurve - 1);
          if(iCurve == NbCurves - 1) {
            if(c->beg == c->end)
              pt[3] = curveGetPoint(c, 1);
            else
              pt[3] = SPoint3(2 * pt[2] - pt[1]);
          }
          else
            pt[3] = curveGetPoint(c, iCurve + 2);
          SPoint3 bpt[4] = {
            pt[1],
            (pt[1] * 6 + pt[2] - pt[0]) * (1./6.),
            (pt[2] * 6 - pt[3] + pt[1]) * (1./6.),
            pt[2]
          };
          std::vector<double> lts;
          std::vector<SPoint3> lpts;
          decasteljau(tol, bpt[0], bpt[1], bpt[2], bpt[3], lpts, lts);
          for (size_t i = (iCurve == 0 ? 0 : 1); i < lpts.size(); ++i) {
            pts.push_back(lpts[i]);
            ts.push_back(t1 + lts[i] * (t2 - t1));
          }
        }
        break;
      }
    default :
      GEdge::discretize(tol, pts, ts);
  }
}
Пример #18
0
void gmshEdge::writeGEO(FILE *fp)
{
  if(!c || c->Num < 0 || c->Typ == MSH_SEGM_DISCRETE) return;
  switch (c->Typ) {
  case MSH_SEGM_LINE:
    fprintf(fp, "Line(%d) = ", c->Num);
    break;
  case MSH_SEGM_CIRC:
  case MSH_SEGM_CIRC_INV:
    fprintf(fp, "Circle(%d) = ", c->Num);
    break;
  case MSH_SEGM_ELLI:
  case MSH_SEGM_ELLI_INV:
    fprintf(fp, "Ellipse(%d) = ", c->Num);
    break;
  case MSH_SEGM_NURBS:
    fprintf(fp, "Nurbs(%d) = {", c->Num);
    for(int i = 0; i < List_Nbr(c->Control_Points); i++) {
      Vertex *v;
      List_Read(c->Control_Points, i, &v);
      if(!i)
        fprintf(fp, "%d", v->Num);
      else
        fprintf(fp, ", %d", v->Num);
      if(i % 8 == 7 && i != List_Nbr(c->Control_Points) - 1)
        fprintf(fp, "\n");
    }
    fprintf(fp, "}\n");
    fprintf(fp, "  Knots {");
    for(int j = 0; j < List_Nbr(c->Control_Points) + c->degre + 1; j++) {
      if(!j)
        fprintf(fp, "%.16g", c->k[j]);
      else
        fprintf(fp, ", %.16g", c->k[j]);
      if(j % 5 == 4 && j != List_Nbr(c->Control_Points) + c->degre)
        fprintf(fp, "\n        ");
    }
    fprintf(fp, "}\n");
    fprintf(fp, "  Order %d;\n", c->degre);
    return;
  case MSH_SEGM_SPLN:
    fprintf(fp, "Spline(%d) = ", c->Num);
    break;
  case MSH_SEGM_BSPLN:
    fprintf(fp, "BSpline(%d) = ", c->Num);
    break;
  case MSH_SEGM_BEZIER:
    fprintf(fp, "Bezier(%d) = ", c->Num);
    break;
  default:
    Msg::Error("Unknown curve type %d", c->Typ);
    return;
  }
  for(int i = 0; i < List_Nbr(c->Control_Points); i++) {
    Vertex *v;
    List_Read(c->Control_Points, i, &v);
    if(i)
      fprintf(fp, ", %d", v->Num);
    else
      fprintf(fp, "{%d", v->Num);
    if(i % 6 == 7)
      fprintf(fp, "\n");
  }
  fprintf(fp, "};\n");

  if(meshAttributes.method == MESH_TRANSFINITE){
    fprintf(fp, "Transfinite Line {%d} = %d",
            tag() * (meshAttributes.typeTransfinite > 0 ? 1 : -1),
            meshAttributes.nbPointsTransfinite);
    if(meshAttributes.typeTransfinite){
      if(std::abs(meshAttributes.typeTransfinite) == 1)
        fprintf(fp, "Using Progression ");
      else if(std::abs(meshAttributes.typeTransfinite) == 2)
        fprintf(fp, "Using Bump ");
      fprintf(fp, "%g", meshAttributes.coeffTransfinite);
    }
    fprintf(fp, ";\n");
  }

  if(meshAttributes.reverseMesh)
    fprintf(fp, "Reverse Line {%d};\n", tag());
}
Пример #19
0
SPoint2 gmshEdge::reparamOnFace(const GFace *face, double epar,int dir) const
{
  Surface *s = (Surface*) face->getNativePtr();

  bool periodic = (c->end == c->beg);
  if(s->geometry){
    switch (c->Typ) {
    case MSH_SEGM_LINE:
      {
        Vertex *v[3];
        List_Read(c->Control_Points, 0, &v[1]);
        List_Read(c->Control_Points, 1, &v[2]);
        SPoint2 p = v[1]->pntOnGeometry +
          (v[2]->pntOnGeometry - v[1]->pntOnGeometry) * epar;
        return p;
      }
    case MSH_SEGM_BSPLN:
    case MSH_SEGM_BEZIER:
      {
        int NbControlPoints = List_Nbr(c->Control_Points);
        int NbCurves = NbControlPoints + (periodic ? -1 : 1);
        int iCurve = (int)floor(epar * (double)NbCurves);
        if(iCurve >= NbCurves)
          iCurve = NbCurves - 1;
        else if (iCurve < 0) // ? does it happen ?
          iCurve = 0;
        double t1 = (double)(iCurve) / (double)(NbCurves);
        double t2 = (double)(iCurve+1) / (double)(NbCurves);
        double t = (epar - t1) / (t2 - t1);
        Vertex *v[4];
        for(int j = 0; j < 4; j ++ ){
          int k = iCurve - (periodic ? 1 : 2) + j;
          if(k < 0)
            k = periodic ? k + NbControlPoints - 1 : 0;
          if(k >= NbControlPoints)
            k = periodic ? k - NbControlPoints + 1: NbControlPoints - 1;
          List_Read(c->Control_Points, k, &v[j]);
        }
        return InterpolateCubicSpline(v, t, c->mat, t1, t2, c->geometry,0);
      }
    case MSH_SEGM_SPLN :
      {
        Vertex temp1, temp2;
        int N = List_Nbr(c->Control_Points);
        int i = (int)((double)(N - 1) * epar);
        if(i < 0)
          i = 0;
        if(i >= N - 1)
          i = N - 2;
        double t1 = (double)(i) / (double)(N - 1);
        double t2 = (double)(i + 1) / (double)(N - 1);
        double t = (epar - t1) / (t2 - t1);
        Vertex *v[4];
        List_Read(c->Control_Points, i, &v[1]);
        List_Read(c->Control_Points, i + 1, &v[2]);
        if(!i) {
          if(c->beg == c->end){
            List_Read(c->Control_Points,N-2,&v[0]);
          }
          else{
            v[0] = &temp1;
            v[0]->pntOnGeometry = v[1]->pntOnGeometry * 2. - v[2]->pntOnGeometry;
          }
        }
        else{
          List_Read(c->Control_Points, i - 1, &v[0]);
        }
        if(i == N - 2) {
          if(c->beg == c->end){
            List_Read(c->Control_Points,1,&v[3]);
          }
          else{
            v[3] = &temp2;
            v[3]->pntOnGeometry = v[2]->pntOnGeometry * 2. - v[1]->pntOnGeometry;
          }
        }
        else{
          List_Read(c->Control_Points, i + 2, &v[3]);
        }
        return InterpolateCubicSpline(v, t, c->mat, t1, t2, c->geometry,0);
      }
    default:
      Msg::Error("Unknown edge type in reparamOnFace");
      return SPoint2();
    }
  }


  if(s->Typ ==  MSH_SURF_REGL){
    Curve *C[4];
    for(int i = 0; i < 4; i++)
      List_Read(s->Generatrices, i, &C[i]);

    double U, V;
    if (C[0]->Num == c->Num) {
      U = (epar - C[0]->ubeg) / (C[0]->uend - C[0]->ubeg) ;
      V = 0;
    }
    else if (C[0]->Num == -c->Num) {
      U = (C[0]->uend - epar - C[0]->ubeg) / (C[0]->uend - C[0]->ubeg) ;
      V = 0;
    }
    else if (C[1]->Num == c->Num) {
      V = (epar - C[1]->ubeg) / (C[1]->uend - C[1]->ubeg) ;
      U = 1;
    }
    else if (C[1]->Num == -c->Num) {
      V = (C[1]->uend - epar - C[1]->ubeg) / (C[1]->uend - C[1]->ubeg) ;
      U = 1;
    }
    else if (C[2]->Num == c->Num) {
      U =  1 - (epar - C[2]->ubeg) / (C[2]->uend - C[2]->ubeg) ;
      V = 1;
    }
    else if (C[2]->Num == -c->Num) {
      U =  1 - ( C[2]->uend -epar - C[2]->ubeg) / (C[2]->uend - C[2]->ubeg) ;
      V = 1;
    }
    else if (C[3]->Num == c->Num) {
      V = 1-(epar - C[3]->ubeg) / (C[3]->uend - C[3]->ubeg) ;
      U = 0;
    }
    else if (C[3]->Num == -c->Num) {
      V = 1-(C[3]->uend - epar - C[3]->ubeg) / (C[3]->uend - C[3]->ubeg) ;
      U = 0;
    }
    else{
      Msg::Info("Reparameterizing edge %d on face %d", c->Num, s->Num);
      return GEdge::reparamOnFace(face, epar, dir);
    }
    return SPoint2(U, V);
  }
  else if (s->Typ == MSH_SURF_TRIC){
    Curve *C[3];
    for(int i = 0; i < 3; i++)
      List_Read(s->Generatrices, i, &C[i]);
    double U, V;
    if(CTX::instance()->geom.oldRuledSurface){
      if (C[0]->Num == c->Num) {
        U = (epar - C[0]->ubeg) / (C[0]->uend - C[0]->ubeg) ;
        V = 0;
      }
      else if (C[0]->Num == -c->Num) {
        U = (C[0]->uend - epar - C[0]->ubeg) / (C[0]->uend - C[0]->ubeg) ;
        V = 0;
      }
      else if (C[1]->Num == c->Num) {
        V = (epar - C[1]->ubeg) / (C[1]->uend - C[1]->ubeg) ;
        U = 1;
      }
      else if (C[1]->Num == -c->Num) {
        V = (C[1]->uend - epar - C[1]->ubeg) / (C[1]->uend - C[1]->ubeg) ;
        U = 1;
      }
      else if (C[2]->Num == c->Num) {
        U = 1-(epar - C[2]->ubeg) / (C[2]->uend - C[2]->ubeg) ;
        V = 1;
      }
      else if (C[2]->Num == -c->Num) {
        U = 1-(C[2]->uend - epar - C[2]->ubeg) / (C[2]->uend - C[2]->ubeg) ;
        V = 1;
      }
      else{
        Msg::Info("Reparameterizing edge %d on face %d", c->Num, s->Num);
        return GEdge::reparamOnFace(face, epar, dir);
      }

    }
    else{
      // FIXME: workaround for exact extrusions
      bool hack = false;
      if(CTX::instance()->geom.exactExtrusion && s->Extrude &&
         s->Extrude->geo.Mode == EXTRUDED_ENTITY && s->Typ != MSH_SURF_PLAN)
        hack = true;
      if (C[0]->Num == c->Num) {
        U = (epar - C[0]->ubeg) / (C[0]->uend - C[0]->ubeg) ;
        V = 0;
      }
      else if (C[0]->Num == -c->Num) {
        U = (C[0]->uend - epar - C[0]->ubeg) / (C[0]->uend - C[0]->ubeg) ;
        V = 0;
      }
      else if (C[1]->Num == c->Num) {
        V = (epar - C[1]->ubeg) / (C[1]->uend - C[1]->ubeg) ;
        U = 1;
      }
      else if (C[1]->Num == -c->Num) {
        V = (C[1]->uend - epar - C[1]->ubeg) / (C[1]->uend - C[1]->ubeg) ;
        U = 1;
      }
      else if (C[2]->Num == c->Num) {
        U = 1-(epar - C[2]->ubeg) / (C[2]->uend - C[2]->ubeg) ;
        V = hack ? 1 : U;
      }
      else if (C[2]->Num == -c->Num) {
        U = 1-(C[2]->uend - epar - C[2]->ubeg) / (C[2]->uend - C[2]->ubeg) ;
        V = hack ? 1 : U;
      }
      else{
        Msg::Info("Reparameterizing edge %d on face %d", c->Num, s->Num);
        return GEdge::reparamOnFace(face, epar, dir);
      }
    }
    return SPoint2(U, V);
  }
  else{
    return GEdge::reparamOnFace(face, epar, dir);
  }
}
Пример #20
0
static Vertex InterpolateRuledSurface(Surface *s, double u, double v)
{
  Curve *C[4] = {0, 0, 0, 0};

  for(int i = 0; i < std::min(List_Nbr(s->Generatrices), 4); i++)
    List_Read(s->Generatrices, i, &C[i]);

  Vertex *O = 0;
  bool isSphere = true;

  // Ugly hack: "fix" transfinite interpolation if we have a sphere
  // patch
  if(List_Nbr(s->InSphereCenter)) {
    // it's on a sphere: get the center
    List_Read(s->InSphereCenter, 0, &O);
  }
  else{
    // try to be intelligent (hum)
    for(int i = 0; i < std::min(List_Nbr(s->Generatrices), 4); i++) {
      if(C[i]->Typ != MSH_SEGM_CIRC && C[i]->Typ != MSH_SEGM_CIRC_INV){
        isSphere = false;
      }
      else if(isSphere){
        if(!i){
          List_Read(C[i]->Control_Points, 1, &O);
        }
        else{
          Vertex *tmp;
          List_Read(C[i]->Control_Points, 1, &tmp);
          if(compareVertex(&O, &tmp))
            isSphere = false;
        }
      }
    }
    if(isSphere){
      double n[3] = {C[0]->Circle.invmat[0][2],
                     C[0]->Circle.invmat[1][2],
                     C[0]->Circle.invmat[2][2]};
      bool isPlane = true;
      for(int i = 1; i < std::min(List_Nbr(s->Generatrices), 4); i++)
        isPlane &= (n[0] == C[i]->Circle.invmat[0][2] &&
                    n[1] == C[i]->Circle.invmat[1][2] &&
                    n[2] == C[i]->Circle.invmat[2][2]);
      if(isPlane)
        isSphere = false;
    }
  }

  Vertex *S[4], V[4],VB[3], T;
  if(s->Typ == MSH_SURF_REGL && List_Nbr(s->Generatrices) >= 4){
    S[0] = C[0]->beg;
    S[1] = C[1]->beg;
    S[2] = C[2]->beg;
    S[3] = C[3]->beg;
    V[0] = InterpolateCurve(C[0], C[0]->ubeg + (C[0]->uend - C[0]->ubeg) * u, 0);
    V[1] = InterpolateCurve(C[1], C[1]->ubeg + (C[1]->uend - C[1]->ubeg) * v, 0);
    V[2] = InterpolateCurve(C[2], C[2]->ubeg + (C[2]->uend - C[2]->ubeg) * (1. - u), 0);
    V[3] = InterpolateCurve(C[3], C[3]->ubeg + (C[3]->uend - C[3]->ubeg) * (1. - v), 0);
    /*
#if defined(HAVE_BFGS)
    printf("----- u %f v %f %g %g\n", u, v,C[1]->ubeg,C[1]->uend);
    printf("S[0] %f %f %f\n", S[0]->Pos.X, S[0]->Pos.Y,S[0]->Pos.Z);
    printf("S[1] %f %f %f\n", S[1]->Pos.X, S[1]->Pos.Y,S[1]->Pos.Z);
    printf("S[2] %f %f %f\n", S[2]->Pos.X, S[2]->Pos.Y,S[2]->Pos.Z);
    printf("S[3] %f %f %f\n", S[3]->Pos.X, S[3]->Pos.Y,S[3]->Pos.Z);
    printf("V[0] %f %f %f\n", V[0].Pos.X, V[0].Pos.Y,V[0].Pos.Z);
    printf("V[1] %f %f %f\n", V[1].Pos.X, V[1].Pos.Y,V[1].Pos.Z);
    printf("V[2] %f %f %f\n", V[2].Pos.X, V[2].Pos.Y,V[2].Pos.Z);
    printf("V[3] %f %f %f\n", V[3].Pos.X, V[3].Pos.Y,V[3].Pos.Z);
#endif
    */
    T = TransfiniteQua(V[0], V[1], V[2], V[3], *S[0], *S[1], *S[2], *S[3], u, v);
    if(isSphere) TransfiniteSph(*S[0], *O, &T);
  }
  else if(List_Nbr(s->Generatrices) >= 3){
    S[0] = C[0]->beg;
    S[1] = C[1]->beg;
    S[2] = C[2]->beg;
    if(CTX::instance()->geom.oldRuledSurface){
      V[0] = InterpolateCurve(C[0], C[0]->ubeg + (C[0]->uend - C[0]->ubeg) * u, 0);
      V[1] = InterpolateCurve(C[1], C[1]->ubeg + (C[1]->uend - C[1]->ubeg) * v, 0);
      V[2] = InterpolateCurve(C[2], C[2]->ubeg + (C[2]->uend - C[2]->ubeg) * (1. - u), 0);
      T = TransfiniteTri(V[0], V[1], V[2], *S[0], *S[1], *S[2], u, v);
    }
    else{
      V[0] = InterpolateCurve(C[0], C[0]->ubeg + (C[0]->uend - C[0]->ubeg) * (u-v), 0);
      V[1] = InterpolateCurve(C[1], C[1]->ubeg + (C[1]->uend - C[1]->ubeg) * v, 0);
      V[2] = InterpolateCurve(C[2], C[2]->ubeg + (C[2]->uend - C[2]->ubeg) * (1. - u), 0);
      VB[0] = InterpolateCurve(C[0], C[0]->ubeg + (C[0]->uend - C[0]->ubeg) * u, 0);
      VB[1] = InterpolateCurve(C[1], C[1]->ubeg + (C[1]->uend - C[1]->ubeg) * (1-u+v), 0);
      VB[2] = InterpolateCurve(C[2], C[2]->ubeg + (C[2]->uend - C[2]->ubeg) * (1. - v), 0);
      T = TransfiniteTriB(V[0],VB[0], V[1],VB[1], V[2],VB[2], *S[0], *S[1], *S[2], u, v);
    }
    if(isSphere) {
      TransfiniteSph(*S[0], *O, &T);
    }
  }

  return T;
}
Пример #21
0
Vertex InterpolateCurve(Curve *c, double u, int derivee)
{
  if(c->Num < 0) {
    Curve *C0 = FindCurve(-c->Num);
    if(!C0){
      Msg::Error("Unknown curve %d", -c->Num);
      return Vertex(0., 0., 0.);
    }
    return InterpolateCurve(C0, C0->ubeg + (C0->uend - C0->ubeg) * (1. - u), derivee);
  }

  Vertex V;

  if(derivee==1) {
    // switch (c->Typ) {
    // case MSH_SEGM_BSPLN:
    // case MSH_SEGM_BEZIER:
    //   V = InterpolateUBS(c, u, 1);
    //   V.u = u;
    //   break;
    // default :
      double eps1 = (u == 0) ? 0 : 1.e-5;
      double eps2 = (u == 1) ? 0 : 1.e-5;
      Vertex D[2];
      D[0] = InterpolateCurve(c, u - eps1, 0);
      D[1] = InterpolateCurve(c, u + eps2, 0);
      V.Pos.X = (D[1].Pos.X - D[0].Pos.X) / (eps1 + eps2);
      V.Pos.Y = (D[1].Pos.Y - D[0].Pos.Y) / (eps1 + eps2);
      V.Pos.Z = (D[1].Pos.Z - D[0].Pos.Z) / (eps1 + eps2);
      V.u = u;
    //   break;
    // }
    return V;
  }

  if(derivee==2) {
    switch (c->Typ) {
    case MSH_SEGM_BSPLN:
      V = InterpolateUBS(c, u, 2);
      V.u = u;
      break;
    case MSH_SEGM_BEZIER:
      V = InterpolateBezier(c, u, 2);
      V.u = u;
      break;
    default :
      double eps1 = (u == 0) ? 0 : 1.e-5;
      double eps2 = (u == 1) ? 0 : 1.e-5;
      Vertex D[2];
      D[0] = InterpolateCurve(c, u - eps1, 1);
      D[1] = InterpolateCurve(c, u + eps2, 1);
      V.Pos.X = (D[1].Pos.X - D[0].Pos.X) / (eps1 + eps2);
      V.Pos.Y = (D[1].Pos.Y - D[0].Pos.Y) / (eps1 + eps2);
      V.Pos.Z = (D[1].Pos.Z - D[0].Pos.Z) / (eps1 + eps2);
      V.u = u;
      break;
    }
    return V;
  }

  int N, i;
  Vertex *v[5];
  double theta, t1, t2, t;
  Vertex temp1, temp2;

  switch (c->Typ) {

  case MSH_SEGM_LINE:
#if defined(HAVE_BFGS)
    //    printf("MSH_SEGM_LINE\n");
#endif
    N = List_Nbr(c->Control_Points);
    i = (int)((double)(N - 1) * u);
    while(i >= N - 1)
      i--;
    while(i < 0)
      i++;
    t1 = (double)(i) / (double)(N - 1);
    t2 = (double)(i + 1) / (double)(N - 1);
    t = (u - t1) / (t2 - t1);
    List_Read(c->Control_Points, i, &v[1]);
    List_Read(c->Control_Points, i + 1, &v[2]);
    if(!c->geometry){
      V.Pos.X = v[1]->Pos.X + t * (v[2]->Pos.X - v[1]->Pos.X);
      V.Pos.Y = v[1]->Pos.Y + t * (v[2]->Pos.Y - v[1]->Pos.Y);
      V.Pos.Z = v[1]->Pos.Z + t * (v[2]->Pos.Z - v[1]->Pos.Z);
      V.w = (1. - t) * v[1]->w + t * v[2]->w;
      V.lc = (1. - t) * v[1]->lc + t * v[2]->lc;
    }
    else{
      SPoint2 p = v[1]->pntOnGeometry +  (v[2]->pntOnGeometry - v[1]->pntOnGeometry) * t;
      SPoint3 pp = c->geometry->point(p);
      V.Pos.X = pp.x();
      V.Pos.Y = pp.y();
      V.Pos.Z = pp.z();
    }
    break;

  case MSH_SEGM_CIRC:
  case MSH_SEGM_CIRC_INV:
  case MSH_SEGM_ELLI:
  case MSH_SEGM_ELLI_INV:
    if(c->Typ == MSH_SEGM_CIRC_INV || c->Typ == MSH_SEGM_ELLI_INV) {
      V.u = 1. - u;
      u = V.u;
    }
    theta = c->Circle.t1 - (c->Circle.t1 - c->Circle.t2) * u;
    theta -= c->Circle.incl; // for ellipses
    V.Pos.X =
      c->Circle.f1 * cos(theta) * cos(c->Circle.incl) -
      c->Circle.f2 * sin(theta) * sin(c->Circle.incl);
    V.Pos.Y =
      c->Circle.f1 * cos(theta) * sin(c->Circle.incl) +
      c->Circle.f2 * sin(theta) * cos(c->Circle.incl);
    V.Pos.Z = 0.0;
    Projette(&V, c->Circle.invmat);
    List_Read(c->Control_Points, 1, &v[0]);
    V.Pos.X += v[0]->Pos.X;
    V.Pos.Y += v[0]->Pos.Y;
    V.Pos.Z += v[0]->Pos.Z;
    V.w = (1. - u) * c->beg->w + u * c->end->w;
    V.lc = (1. - u) * c->beg->lc + u * c->end->lc;
    break;

  case MSH_SEGM_BSPLN:
    V = InterpolateUBS(c, u, 0);
    break;
  case MSH_SEGM_BEZIER:
    V = InterpolateBezier(c, u, 0);
    break;

  case MSH_SEGM_NURBS:
    V = InterpolateNurbs(c, u, 0);
    break;

  case MSH_SEGM_SPLN:
    N = List_Nbr(c->Control_Points);
    i = (int)((double)(N - 1) * u);
    if(i < 0)
      i = 0;
    if(i >= N - 1)
      i = N - 2;
    t1 = (double)(i) / (double)(N - 1);
    t2 = (double)(i + 1) / (double)(N - 1);
    t = (u - t1) / (t2 - t1);
    List_Read(c->Control_Points, i, &v[1]);
    List_Read(c->Control_Points, i + 1, &v[2]);
    if(!i) {
      if(c->beg == c->end){
        List_Read(c->Control_Points, N - 2, &v[0]);
      }
      else{
        v[0] = &temp1;
        v[0]->Pos.X = 2. * v[1]->Pos.X - v[2]->Pos.X;
        v[0]->Pos.Y = 2. * v[1]->Pos.Y - v[2]->Pos.Y;
        v[0]->Pos.Z = 2. * v[1]->Pos.Z - v[2]->Pos.Z;
        v[0]->pntOnGeometry = v[1]->pntOnGeometry * 2. - v[2]->pntOnGeometry;
      }
    }
    else {
      List_Read(c->Control_Points, i - 1, &v[0]);
    }
    if(i == N - 2) {
      if(c->beg == c->end){
        List_Read(c->Control_Points, 1, &v[3]);
      }
      else{
        v[3] = &temp2;
        v[3]->Pos.X = 2. * v[2]->Pos.X - v[1]->Pos.X;
        v[3]->Pos.Y = 2. * v[2]->Pos.Y - v[1]->Pos.Y;
        v[3]->Pos.Z = 2. * v[2]->Pos.Z - v[1]->Pos.Z;
        v[3]->pntOnGeometry = v[2]->pntOnGeometry * 2. - v[1]->pntOnGeometry;
      }
    }
    else {
      List_Read(c->Control_Points, i + 2, &v[3]);
    }
    if(c->geometry){
      SPoint2 pp = InterpolateCubicSpline(v, t, c->mat, t1, t2,c->geometry,0);
      SPoint3 pt = c->geometry->point(pp);
      V.Pos.X = pt.x();
      V.Pos.Y = pt.y();
      V.Pos.Z = pt.z();
    }
    else
      V = InterpolateCubicSpline(v, t, c->mat, 0, t1, t2);
    break;

  case MSH_SEGM_BND_LAYER:
    Msg::Debug("Cannot interpolate boundary layer curve");
    break;

  case MSH_SEGM_DISCRETE:
    Msg::Debug("Cannot interpolate discrete curve");
    break;

  case MSH_SEGM_COMPOUND:
    Msg::Debug("Cannot interpolate compound curve");
    break;

  default:
    Msg::Error("Unknown curve type in interpolation");
    break;
  }
  V.u = u;
  return V;
}