Exemple #1
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;
}
Exemple #2
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]);
    }
  }
}
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;
  }
}
Exemple #4
0
SVector3 gmshEdge::secondDer(double par) const
{
  Vertex a = InterpolateCurve(c, par, 2);
  return SVector3(a.Pos.X, a.Pos.Y, a.Pos.Z);
}
Exemple #5
0
GPoint gmshEdge::point(double par) const
{
  Vertex a = InterpolateCurve(c, par, 0);
  return GPoint(a.Pos.X, a.Pos.Y, a.Pos.Z, this, par);
}
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;
}
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;
}