示例#1
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]);
    }
  }
}
示例#2
0
Pair<SVector3, SVector3> gmshFace::firstDer(const SPoint2 &param) const
{
  if(s->Typ == MSH_SURF_PLAN && !s->geometry){
    double x, y, z, VX[3], VY[3];
    getMeanPlaneData(VX, VY, x, y, z);
    return Pair<SVector3, SVector3>(SVector3(VX[0], VX[1], VX[2]),
                                    SVector3(VY[0], VY[1], VY[2]));
  }
  else{
    Vertex vu = InterpolateSurface(s, param[0], param[1], 1, 1);
    Vertex vv = InterpolateSurface(s, param[0], param[1], 1, 2);
    return Pair<SVector3, SVector3>(SVector3(vu.Pos.X, vu.Pos.Y, vu.Pos.Z),
                                    SVector3(vv.Pos.X, vv.Pos.Y, vv.Pos.Z));
  }
}
示例#3
0
void gmshFace::secondDer(const SPoint2 &param,
                         SVector3 *dudu, SVector3 *dvdv, SVector3 *dudv) const
{
  if(s->Typ == MSH_SURF_PLAN && !s->geometry){
    *dudu = SVector3(0., 0., 0.);
    *dvdv = SVector3(0., 0., 0.);
    *dudv = SVector3(0., 0., 0.);
  }
  else{
    Vertex vuu = InterpolateSurface(s, param[0], param[1], 2, 1);
    Vertex vvv = InterpolateSurface(s, param[0], param[1], 2, 2);
    Vertex vuv = InterpolateSurface(s, param[0], param[1], 2, 3);
    *dudu = SVector3(vuu.Pos.X,vuu.Pos.Y,vuu.Pos.Z);
    *dvdv = SVector3(vvv.Pos.X,vvv.Pos.Y,vvv.Pos.Z);
    *dudv = SVector3(vuv.Pos.X,vuv.Pos.Y,vuv.Pos.Z);
  }
}
示例#4
0
GPoint gmshFace::point(double par1, double par2) const
{
  double pp[2] = {par1, par2};
  if(s->Typ == MSH_SURF_PLAN && !s->geometry){
    double x, y, z, VX[3], VY[3];
    getMeanPlaneData(VX, VY, x, y, z);
    return GPoint(x + VX[0] * par1 + VY[0] * par2,
                  y + VX[1] * par1 + VY[1] * par2,
                  z + VX[2] * par1 + VY[2] * par2, this, pp);
  }
  else{
    Vertex v = InterpolateSurface(s, par1, par2, 0, 0);
    return GPoint(v.Pos.X, v.Pos.Y, v.Pos.Z, this, pp);
  }
}
示例#5
0
Vertex InterpolateSurface(Surface *s, double u, double v, int derivee, int u_v)
{
  if(derivee == 1) {
    double eps = 1.e-8;
    Vertex D[4];
    if(u_v == 1) {
      if(u - eps < 0.0) {
        D[0] = InterpolateSurface(s, u, v, 0, 0);
        D[1] = InterpolateSurface(s, u + eps, v, 0, 0);
      }
      else {
        D[0] = InterpolateSurface(s, u - eps, v, 0, 0);
        D[1] = InterpolateSurface(s, u, v, 0, 0);
      }
    }
    else {
      if(v - eps < 0.0) {
        D[0] = InterpolateSurface(s, u, v, 0, 0);
        D[1] = InterpolateSurface(s, u, v + eps, 0, 0);
      }
      else {
        D[0] = InterpolateSurface(s, u, v - eps, 0, 0);
        D[1] = InterpolateSurface(s, u, v, 0, 0);
      }
    }
    return Vertex((D[1].Pos.X - D[0].Pos.X) / eps,
                  (D[1].Pos.Y - D[0].Pos.Y) / eps,
                  (D[1].Pos.Z - D[0].Pos.Z) / eps);
  }
  else if (derivee == 2) {
    double eps = 1.e-6;
    Vertex D[2];
    if(u_v == 1) { // dudu
      if(u - eps < 0.0) {
        D[0] = InterpolateSurface(s, u, v, 1, 1);
        D[1] = InterpolateSurface(s, u + eps, v, 1, 1);
      }
      else {
        D[0] = InterpolateSurface(s, u - eps, v, 1, 1);
        D[1] = InterpolateSurface(s, u, v, 1, 1);
      }
    }
    else if(u_v == 2) { // dvdv
      if(v - eps < 0.0) {
        D[0] = InterpolateSurface(s, u, v, 1, 2);
        D[1] = InterpolateSurface(s, u, v + eps, 1, 2);
      }
      else {
        D[0] = InterpolateSurface(s, u, v - eps, 1, 2);
        D[1] = InterpolateSurface(s, u, v, 1, 2);
      }
    }
    else { // dudv
      if(v - eps < 0.0) {
        D[0] = InterpolateSurface(s, u, v, 1, 1);
        D[1] = InterpolateSurface(s, u, v + eps, 1, 1);
      }
      else {
        D[0] = InterpolateSurface(s, u, v - eps, 1, 1);
        D[1] = InterpolateSurface(s, u, v, 1, 1);
      }
    }
    return Vertex((D[1].Pos.X - D[0].Pos.X) / eps,
                  (D[1].Pos.Y - D[0].Pos.Y) / eps,
                  (D[1].Pos.Z - D[0].Pos.Z) / eps);
  }

  if(s->geometry){
    SPoint3 p = s->geometry->point(u, v);
    return Vertex(p.x(), p.y(), p.z());
  }

  // Warning: we use the exact extrusion formula so we can create
  // exact surfaces of revolution. This WILL fail if the surface is
  // transformed after the extrusion: in that case set the
  // exactExtrusion option to 0 to use the normal code path
  if(CTX::instance()->geom.exactExtrusion && s->Extrude &&
     s->Extrude->geo.Mode == EXTRUDED_ENTITY && s->Typ != MSH_SURF_PLAN)
    return InterpolateExtrudedSurface(s, u, v);

  switch (s->Typ) {
  case MSH_SURF_REGL:
  case MSH_SURF_TRIC:
    return InterpolateRuledSurface(s, u, v);
  case MSH_SURF_PLAN:
    Msg::Error("Should never interpolate plane surface in InterpolateSurface()");
    return Vertex(0., 0., 0.);
  case MSH_SURF_BND_LAYER:
    Msg::Error("Cannot interpolate boundary layer surface");
    return Vertex(0., 0., 0.);
  case MSH_SURF_DISCRETE:
    Msg::Error("Cannot interpolate discrete surface");
    return Vertex(0., 0., 0.);
  default:
    Msg::Error("Unknown surface type in interpolation");
    return Vertex(0., 0., 0.);
  }
}