Example #1
0
static double LC_MVertex_CURV(GEntity *ge, double U, double V)
{
  double Crv = 0;
  switch(ge->dim()){
  case 0:
    Crv = max_edge_curvature((const GVertex *)ge);
    //Crv = std::max(max_surf_curvature_vertex((const GVertex *)ge), Crv);
    // Crv = max_surf_curvature((const GVertex *)ge);
    break;
  case 1:
    {
      GEdge *ged = (GEdge *)ge;
      Crv = ged->curvature(U);
      Crv = std::max(Crv, max_surf_curvature(ged, U));
      // Crv = max_surf_curvature(ged, U);
    }
    break;
  case 2:
    {
      GFace *gf = (GFace *)ge;
      Crv = gf->curvature(SPoint2(U, V));
    }
    break;
  }
  double lc = Crv > 0 ? 2 * M_PI / Crv / CTX::instance()->mesh.minCircPoints : MAX_LC;
  return lc;
}
Example #2
0
SMetric3 metric_based_on_surface_curvature(const GFace *gf, double u, double v,
					   bool surface_isotropic,
					   double d_normal ,
					   double d_tangent_max)
{
  if (gf->geomType() == GEntity::Plane)return SMetric3(1.e-12);
  double cmax, cmin;
  SVector3 dirMax,dirMin;
  cmax = gf->curvatures(SPoint2(u, v),&dirMax, &dirMin, &cmax,&cmin);
  if (cmin == 0)cmin =1.e-12;
  if (cmax == 0)cmax =1.e-12;
  double lambda1 =  ((2 * M_PI) /( fabs(cmin) *  CTX::instance()->mesh.minCircPoints ) );
  double lambda2 =  ((2 * M_PI) /( fabs(cmax) *  CTX::instance()->mesh.minCircPoints ) );
  SVector3 Z = crossprod(dirMax,dirMin);
  if (surface_isotropic)  lambda2 = lambda1 = std::min(lambda2,lambda1);
  dirMin.normalize();
  dirMax.normalize();
  Z.normalize();
  lambda1 = std::max(lambda1, CTX::instance()->mesh.lcMin);
  lambda2 = std::max(lambda2, CTX::instance()->mesh.lcMin);
  lambda1 = std::min(lambda1, CTX::instance()->mesh.lcMax);
  lambda2 = std::min(lambda2, CTX::instance()->mesh.lcMax);
  double lambda3 = std::min(d_normal, CTX::instance()->mesh.lcMax);
  lambda3 = std::max(lambda3, CTX::instance()->mesh.lcMin);
  lambda1 = std::min(lambda1, d_tangent_max);
  lambda2 = std::min(lambda2, d_tangent_max);

  SMetric3 curvMetric (1./(lambda1*lambda1),1./(lambda2*lambda2),
		       1./(lambda3*lambda3),
                       dirMin, dirMax, Z );
  return curvMetric;
}
Example #3
0
inline double computeEdgeLinearLength(BDS_Point *p1, BDS_Point *p2, GFace *f,
                                      double SCALINGU, double SCALINGV)
{
  // FIXME SUPER HACK
   // if (CTX::instance()->mesh.recombineAll || f->meshAttributes.recombine || 1){
   //   double quadAngle  = backgroundMesh::current()->getAngle (0.5 * (p1->u + p2->u) * SCALINGU, 0.5 * (p1->v + p2->v) * SCALINGV,0);
   //   const double a [2] = {p1->u,p1->v};
   //   const double b [2] = {p2->u,p2->v};
   //   return lengthInfniteNorm(a,b, quadAngle);
   // }

  GPoint GP = f->point(SPoint2(0.5 * (p1->u + p2->u) * SCALINGU,
                               0.5 * (p1->v + p2->v) * SCALINGV));

  if (!GP.succeeded())
    return computeEdgeLinearLength(p1,p2);

  const double dx1 = p1->X - GP.x();
  const double dy1 = p1->Y - GP.y();
  const double dz1 = p1->Z - GP.z();
  const double l1 = sqrt(dx1 * dx1 + dy1 * dy1 + dz1 * dz1);
  const double dx2 = p2->X - GP.x();
  const double dy2 = p2->Y - GP.y();
  const double dz2 = p2->Z - GP.z();
  const double l2 = sqrt(dx2 * dx2 + dy2 * dy2 + dz2 * dz2);
  return l1 + l2;
}
Example #4
0
// returns the cross field as a pair of othogonal vectors (NOT in parametric coordinates, but real 3D coordinates)
Pair<SVector3, SVector3> frameFieldBackgroundMesh2D::compute_crossfield_directions(double u, double v,
        double angle_current)
{
    // get the unit normal at that point
    GFace *face = dynamic_cast<GFace*>(gf);
    if(!face) {
        Msg::Error("Entity is not a face in background mesh");
        return Pair<SVector3,SVector3>(SVector3(), SVector3());
    }

    Pair<SVector3, SVector3> der = face->firstDer(SPoint2(u,v));
    SVector3 s1 = der.first();
    SVector3 s2 = der.second();
    SVector3 n = crossprod(s1,s2);
    n.normalize();

    SVector3 basis_u = s1;
    basis_u.normalize();
    SVector3 basis_v = crossprod(n,basis_u);

    // normalize vector t1 that is tangent to gf at uv
    SVector3 t1 = basis_u * cos(angle_current) + basis_v * sin(angle_current) ;
    t1.normalize();

    // compute the second direction t2 and normalize (t1,t2,n) is the tangent frame
    SVector3 t2 = crossprod(n,t1);
    t2.normalize();

    return Pair<SVector3,SVector3>(SVector3(t1[0],t1[1],t1[2]),
                                   SVector3(t2[0],t2[1],t2[2]));
}
Example #5
0
SPoint2 fourierFace::parFromPoint(const SPoint3 &p, bool onSurface) const
{
  double u, v, x, y, z;
  x = p.x(); y = p.y(); z = p.z();
  face->Inverse(x,y,z,u,v);

  return SPoint2(u, v);
}
Example #6
0
GPoint backgroundMesh2D::get_GPoint_from_MVertex(const MVertex *v)const
{
    GFace *face = dynamic_cast<GFace*>(gf);
    if(!face) {
        Msg::Error("Entity is not a face in background mesh");
        return GPoint();
    }
    return face->point(SPoint2(v->x(),v->y()));
}
Example #7
0
bool reparamMeshVertexOnFace(MVertex *v, const GFace *gf, SPoint2 &param,
                             bool onSurface)
{

  if (gf->geomType() == GEntity::CompoundSurface ){
    GFaceCompound *gfc = (GFaceCompound*) gf;
    param = gfc->parFromVertex(v);
    return true;
  }

  if(v->onWhat()->geomType() == GEntity::DiscreteCurve ||
     v->onWhat()->geomType() == GEntity::BoundaryLayerCurve){
     param = gf->parFromPoint(SPoint3(v->x(), v->y(), v->z()), onSurface);
    return true;
  }

  if(v->onWhat()->dim() == 0){
    GVertex *gv = (GVertex*)v->onWhat();
    // hack for bug in periodic curves
    if (gv->getNativeType() == GEntity::GmshModel && gf->geomType() == GEntity::Plane)
      param = gf->parFromPoint(SPoint3(v->x(), v->y(), v->z()), onSurface);
    else
      param = gv->reparamOnFace(gf, 1);
    // shout, we could be on a seam
    std::list<GEdge*> ed = gv->edges();
    for(std::list<GEdge*>::iterator it = ed.begin(); it != ed.end(); it++)
      if((*it)->isSeam(gf)) return false;
  }
  else if(v->onWhat()->dim() == 1){
    GEdge *ge = (GEdge*)v->onWhat();
    double t;
    v->getParameter(0, t);
    param = ge->reparamOnFace(gf, t, 1);
    if(!v->getParameter(0,t)) {
      Msg::Error("Vertex %p not MEdgeVertex", v);
      return false;
      //param = gf->parFromPoint(SPoint3(v->x(), v->y(), v->z()), onSurface);
    }

    // shout, we are on a seam
    if(ge->isSeam(gf))
      return false;
  }
  else{
    double uu, vv;
    if(v->onWhat() == gf && v->getParameter(0, uu) && v->getParameter(1, vv)){
       param = SPoint2(uu, vv);
    }
    else {
      // brute force!
      param = gf->parFromPoint(SPoint3(v->x(), v->y(), v->z()), onSurface);
    }
  }
  return true;
}
Example #8
0
SPoint2 OCCEdge::reparamOnFace(const GFace *face, double epar, int dir) const
{

  if (face->getNativeType() != GEntity::OpenCascadeModel){
    const GPoint pt = point(epar);
    SPoint3 sp(pt.x(), pt.y(), pt.z());
    return face->parFromPoint(sp);
  }
  else{
    const TopoDS_Face *s = (TopoDS_Face*) face->getNativePtr();
    double t0, t1;
    Handle(Geom2d_Curve) c2d;

    if(dir == 1){
      c2d = BRep_Tool::CurveOnSurface(c, *s, t0, t1);
    }
    else{
      c2d = BRep_Tool::CurveOnSurface(c_rev, *s, t0, t1);
    }

    if(c2d.IsNull()){
      Msg::Error("Reparam on face failed: curve %d is not on surface %d",
		 tag(), face->tag());
      const GPoint pt = point(epar);
      SPoint3 sp(pt.x(), pt.y(), pt.z());
      return face->parFromPoint(sp);
    }

    double u, v;
    gp_Pnt2d pnt = c2d->Value(epar);
    pnt.Coord(u, v);

    // sometimes OCC miserably fails ...
    if (0){
      GPoint p1 = point(epar);
      GPoint p2 = face->point(u, v);
      const double dx = p1.x()-p2.x();
      const double dy = p1.y()-p2.y();
      const double dz = p1.z()-p2.z();
      if(sqrt(dx * dx + dy * dy + dz * dz) > 1.e-2 * CTX::instance()->lc){
	Msg::Warning("Reparam on face was inaccurate for curve %d on surface %d at point %g",
		     tag(), face->tag(), epar);
	Msg::Warning("On the face %d local (%g %g) global (%g %g %g)",
		     face->tag(), u, v, p2.x(), p2.y(), p2.z());
	Msg::Warning("On the edge %d local (%g) global (%g %g %g)",
		     tag(), epar, p1.x(), p1.y(), p1.z());
      }
    }
    return SPoint2(u, v);
  }

}
Example #9
0
static void getAllParameters(MVertex *v, GFace *gf, std::vector<SPoint2> &params)
{
  params.clear();

  if (gf->geomType() == GEntity::CompoundSurface ){
    GFaceCompound *gfc = (GFaceCompound*) gf;
    params.push_back(gfc->parFromVertex(v));
    return;
  }

  if(v->onWhat()->dim() == 0){
    GVertex *gv = (GVertex*)v->onWhat();
    std::list<GEdge*> ed = gv->edges();
    bool seam = false;
    for(std::list<GEdge*>::iterator it = ed.begin(); it != ed.end(); it++){
      if((*it)->isSeam(gf)) {
        Range<double> range = (*it)->parBounds(0);
        if (gv == (*it)->getBeginVertex()){
          params.push_back((*it)->reparamOnFace(gf, range.low(),-1));
          params.push_back((*it)->reparamOnFace(gf, range.low(), 1));
        }
        if (gv == (*it)->getEndVertex()){
          params.push_back((*it)->reparamOnFace(gf, range.high(),-1));
          params.push_back((*it)->reparamOnFace(gf, range.high(), 1));
        }
        if (gv != (*it)->getBeginVertex() && gv != (*it)->getEndVertex()){
          Msg::Warning("Strange!");
        }
        seam = true;
      }
    }
    if (!seam)
      params.push_back(gv->reparamOnFace(gf, 1));
  }
  else if(v->onWhat()->dim() == 1){
    GEdge *ge = (GEdge*)v->onWhat();
    if(!ge->haveParametrization()) return;
    double UU;
    v->getParameter(0, UU);
    if (UU == 0.0)
      UU = ge->parFromPoint(v->point());
    params.push_back(ge->reparamOnFace(gf, UU, 1));
    if(ge->isSeam(gf))
      params.push_back(ge->reparamOnFace(gf, UU, -1));
  }
  else{
    double UU, VV;
    if(v->onWhat() == gf && v->getParameter(0, UU) && v->getParameter(1, VV))
      params.push_back(SPoint2(UU, VV));
  }
}
Example #10
0
SPoint2 gmshFace::parFromPoint(const SPoint3 &qp, bool onSurface) const
{
  if(s->Typ == MSH_SURF_PLAN){
    double x, y, z, VX[3], VY[3];
    getMeanPlaneData(VX, VY, x, y, z);
    double u, v, vec[3] = {qp.x() - x, qp.y() - y, qp.z() - z};
    prosca(vec, VX, &u);
    prosca(vec, VY, &v);
    return SPoint2(u, v);
  }
  else{
    return GFace::parFromPoint(qp, onSurface);
  }
}
Example #11
0
inline double computeEdgeMiddleCoord(BDS_Point *p1, BDS_Point *p2, GFace *f,
                                     double SCALINGU, double SCALINGV)
{
  if (f->geomType() == GEntity::Plane)
    return 0.5;

  GPoint GP = f->point(SPoint2(0.5 * (p1->u + p2->u) * SCALINGU,
                               0.5 * (p1->v + p2->v) * SCALINGV));

  const double dx1 = p1->X - GP.x();
  const double dy1 = p1->Y - GP.y();
  const double dz1 = p1->Z - GP.z();
  const double l1 = sqrt(dx1 * dx1 + dy1 * dy1 + dz1 * dz1);
  const double dx2 = p2->X - GP.x();
  const double dy2 = p2->Y - GP.y();
  const double dz2 = p2->Z - GP.z();
  const double l2 = sqrt(dx2 * dx2 + dy2 * dy2 + dz2 * dz2);

  if (l1 > l2)
    return 0.25 * (l1 + l2) / l1;
  else
    return 0.25 * (3 * l2 - l1) / l2;
}
Example #12
0
void Mesh::calcScaledNormalEl2D(const std::map<MElement*,GEntity*> &element2entity, int iEl)
{
  const JacobianBasis *jac = _el[iEl]->getJacobianFuncSpace();

  fullMatrix<double> primNodesXYZ(jac->getNumPrimMapNodes(),3);
  SVector3 geoNorm(0.,0.,0.);
  std::map<MElement*,GEntity*>::const_iterator itEl2ent = element2entity.find(_el[iEl]);
  GEntity *ge = (itEl2ent == element2entity.end()) ? 0 : itEl2ent->second;
  const bool hasGeoNorm = ge && (ge->dim() == 2) && ge->haveParametrization();
  for (int i=0; i<jac->getNumPrimMapNodes(); i++) {
    const int &iV = _el2V[iEl][i];
    primNodesXYZ(i,0) = _xyz[iV].x();
    primNodesXYZ(i,1) = _xyz[iV].y();
    primNodesXYZ(i,2) = _xyz[iV].z();
    if (hasGeoNorm && (_vert[iV]->onWhat() == ge)) {
      double u, v;
      _vert[iV]->getParameter(0,u);
      _vert[iV]->getParameter(1,v);
      geoNorm += ((GFace*)ge)->normal(SPoint2(u,v));
    }
  }
  if (hasGeoNorm && (geoNorm.normSq() == 0.)) {
    SPoint2 param = ((GFace*)ge)->parFromPoint(_el[iEl]->barycenter(true),false);
    geoNorm = ((GFace*)ge)->normal(param);
  }

  fullMatrix<double> &elNorm = _scaledNormEl[iEl];
  elNorm.resize(1,3);
  const double norm = jac->getPrimNormal2D(primNodesXYZ,elNorm);
  double factor = 1./norm;
  if (hasGeoNorm) {
    const double scal = geoNorm(0)*elNorm(0,0)+geoNorm(1)*elNorm(0,1)+geoNorm(2)*elNorm(0,2);
    if (scal < 0.) factor = -factor;
  }
  elNorm.scale(factor);   // Re-scaling normal here is faster than an extra scaling operation on the Jacobian

}
Example #13
0
inline double computeEdgeLinearLength_new(BDS_Point *p1, BDS_Point *p2,  GFace *f,
                                          double SCALINGU, double SCALINGV)
{
  const int nbSb = 10;
  GPoint GP[nbSb];

  for (int i = 1; i < nbSb; i++){
    double xi = (double)i / nbSb;
    GP[i-1] = f->point(SPoint2(((1-xi) * p1->u + xi * p2->u) * SCALINGU,
                               ((1-xi) * p1->v + xi * p2->v) * SCALINGV));
    if (!GP[i-1].succeeded())
      return computeEdgeLinearLength(p1,p2);
  }
  double l = 0;
  for (int i = 0; i < nbSb; i++){
    if (i == 0){
      const double dx1 = p1->X - GP[0].x();
      const double dy1 = p1->Y - GP[0].y();
      const double dz1 = p1->Z - GP[0].z();
      l+= sqrt(dx1 * dx1 + dy1 * dy1 + dz1 * dz1);
    }
    else if (i == nbSb-1){
      const double dx1 = p2->X - GP[nbSb-1].x();
      const double dy1 = p2->Y - GP[nbSb-1].y();
      const double dz1 = p2->Z - GP[nbSb-1].z();
      l+= sqrt(dx1 * dx1 + dy1 * dy1 + dz1 * dz1);
    }
    else{
      const double dx1 = GP[i].x() - GP[i-1].x();
      const double dy1 = GP[i].y() - GP[i-1].y();
      const double dz1 = GP[i].z() - GP[i-1].z();
      l+= sqrt(dx1 * dx1 + dy1 * dy1 + dz1 * dz1);
    }
  }
  return l;
}
Example #14
0
SPoint2 gmshSurface::parFromPoint(double x, double y, double z)
{
  Msg::Error("Parametric coordinate computation not implemented for this type of surface");
  return SPoint2();
}
Example #15
0
bool frameFieldBackgroundMesh2D::compute_RK_infos(double u,double v, double x, double y, double z, RK_form &infos)
{
    // check if point is in domain
    if (!inDomain(u,v)) return false;

    // get stored angle

    double angle_current = angle(u,v);

    // compute t1,t2: cross field directions

    // get the unit normal at that point
    GFace *face = dynamic_cast<GFace*>(gf);
    if(!face) {
        Msg::Error("Entity is not a face in background mesh");
        return false;
    }

    Pair<SVector3, SVector3> der = face->firstDer(SPoint2(u,v));
    SVector3 s1 = der.first();
    SVector3 s2 = der.second();
    SVector3 n = crossprod(s1,s2);
    n.normalize();
    SVector3 basis_u = s1;
    basis_u.normalize();
    SVector3 basis_v = crossprod(n,basis_u);
    // normalize vector t1 that is tangent to gf at uv
    SVector3 t1 = basis_u * cos(angle_current) + basis_v * sin(angle_current) ;
    t1.normalize();
    // compute the second direction t2 and normalize (t1,t2,n) is the tangent frame
    SVector3 t2 = crossprod(n,t1);
    t2.normalize();

    // get metric

    double L = size(u,v);
    infos.metricField = SMetric3(1./(L*L));
    FieldManager *fields = gf->model()->getFields();
    if(fields->getBackgroundField() > 0) {
        Field *f = fields->get(fields->getBackgroundField());
        if (!f->isotropic()) {
            (*f)(x,y,z, infos.metricField,gf);
        }
        else {
            L = (*f)(x,y,z,gf);
            infos.metricField = SMetric3(1./(L*L));
        }
    }
    double M = dot(s1,s1);
    double N = dot(s2,s2);
    double E = dot(s1,s2);
    // compute the first fundamental form i.e. the metric tensor at the point
    // M_{ij} = s_i \cdot s_j
    double metric[2][2] = {{M,E},{E,N}};

    // get sizes

    double size_1 = sqrt(1. / dot(t1,infos.metricField,t1));
    double size_2 = sqrt(1. / dot(t2,infos.metricField,t2));

    // compute covariant coordinates of t1 and t2 - cross field directions in parametric domain
    double covar1[2],covar2[2];
    // t1 = a s1 + b s2 -->
    // t1 . s1 = a M + b E
    // t1 . s2 = a E + b N --> solve the 2 x 2 system
    // and get covariant coordinates a and b
    double rhs1[2] = {dot(t1,s1),dot(t1,s2)};
    bool singular = false;
    if (!sys2x2(metric,rhs1,covar1)) {
        Msg::Info("Argh surface %d %g %g %g -- %g %g %g -- %g %g",gf->tag(),s1.x(),s1.y(),s1.z(),s2.x(),s2.y(),s2.z(),size_1,size_2);
        covar1[1] = 1.0;
        covar1[0] = 0.0;
        singular = true;
    }
    double rhs2[2] = {dot(t2,s1),dot(t2,s2)};
    if (!sys2x2(metric,rhs2,covar2)) {
        Msg::Info("Argh surface %d %g %g %g -- %g %g %g",gf->tag(),s1.x(),s1.y(),s1.z(),s2.x(),s2.y(),s2.z());
        covar2[0] = 1.0;
        covar2[1] = 0.0;
        singular = true;
    }

    // transform the sizes with respect to the metric
    // consider a vector v of size 1 in the parameter plane
    // its length is sqrt (v^T M v) --> if I want a real size
    // of size1 in direction v, it should be sqrt(v^T M v) * size1
    double l1 = sqrt(covar1[0]*covar1[0]+covar1[1]*covar1[1]);
    double l2 = sqrt(covar2[0]*covar2[0]+covar2[1]*covar2[1]);

    covar1[0] /= l1;
    covar1[1] /= l1;
    covar2[0] /= l2;
    covar2[1] /= l2;

    double size_param_1  = size_1 / sqrt (  M*covar1[0]*covar1[0]+
                                            2*E*covar1[1]*covar1[0]+
                                            N*covar1[1]*covar1[1]);
    double size_param_2  = size_2 / sqrt (  M*covar2[0]*covar2[0]+
                                            2*E*covar2[1]*covar2[0]+
                                            N*covar2[1]*covar2[1]);
    if (singular) {
        size_param_1 = size_param_2 = std::min (size_param_1,size_param_2);
    }


    // filling form...

    infos.t1 = t1;
    infos.h.first  = size_1;
    infos.h.second = size_2;
    infos.paramh.first  = size_param_1;
    infos.paramh.second = size_param_2;
    infos.paramt1 = SPoint2(covar1[0],covar1[1]);
    infos.paramt2 = SPoint2(covar2[0],covar2[1]);
    infos.angle = angle_current;
    infos.localsize = L;
    infos.normal = n;

    return true;
}
Example #16
0
SPoint2 gmshVertex::reparamOnFace(const GFace *face, int dir) const
{

  Surface *s = (Surface*)face->getNativePtr();

  if(s->geometry){
    // It is not always right if it is periodic.
    if(l_edges.size() == 1 &&
       (*l_edges.begin())->getBeginVertex() ==
       (*l_edges.begin())->getEndVertex()){
      Range<double> bb = (*l_edges.begin())->parBounds(0);
      return (*l_edges.begin())->reparamOnFace(face, bb.low(), dir);
    }
    return v->pntOnGeometry;
  }

  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]->beg == v && C[3]->beg == v) ||
        (C[0]->end == v && C[3]->beg == v) ||
        (C[0]->beg == v && C[3]->end == v) ||
        (C[0]->end == v && C[3]->end == v)){
      U = V = 0;
    }
    else if ((C[0]->beg == v && C[1]->beg == v) ||
             (C[0]->end == v && C[1]->beg == v) ||
             (C[0]->beg == v && C[1]->end == v) ||
             (C[0]->end == v && C[1]->end == v)){
      U = 1;
      V = 0;
    }
    else if ((C[2]->beg == v && C[1]->beg == v) ||
             (C[2]->end == v && C[1]->beg == v) ||
             (C[2]->beg == v && C[1]->end == v) ||
             (C[2]->end == v && C[1]->end == v)){
      U = 1;
      V = 1;
    }
    else if ((C[2]->beg == v && C[3]->beg == v) ||
             (C[2]->end == v && C[3]->beg == v) ||
             (C[2]->beg == v && C[3]->end == v) ||
             (C[2]->end == v && C[3]->end == v)){
      U = 0;
      V = 1;
    }
    else{
      Msg::Info("Reparameterizing point %d on face %d", v->Num, s->Num);
      return GVertex::reparamOnFace(face, 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 ((C[0]->beg == v && C[2]->beg == v) ||
        (C[0]->end == v && C[2]->beg == v) ||
        (C[0]->beg == v && C[2]->end == v) ||
        (C[0]->end == v && C[2]->end == v)){
      U = V = 0;
    }
    else if ((C[0]->beg == v && C[1]->beg == v) ||
             (C[0]->end == v && C[1]->beg == v) ||
             (C[0]->beg == v && C[1]->end == v) ||
             (C[0]->end == v && C[1]->end == v)){
      U = 1;
      V = 0;
    }
    else if ((C[2]->beg == v && C[1]->beg == v) ||
             (C[2]->end == v && C[1]->beg == v) ||
             (C[2]->beg == v && C[1]->end == v) ||
             (C[2]->end == v && C[1]->end == v)){
      U = 1;
      V = 1;
    }
    else{
      Msg::Info("Reparameterizing point %d on face %d", v->Num, s->Num);
      return GVertex::reparamOnFace(face, dir);
    }
    return SPoint2(U, V);
  }
  else{
    return GVertex::reparamOnFace(face, dir);
  }
}
Example #17
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);
  }
}
SPoint2 fourierProjectionFace::parFromPoint(const SPoint3 &p, bool onSurface) const
{  
  double u,v;
  ps_->Inverse(p[0], p[1], p[2], u, v);
  return SPoint2(u, v);
}
Example #19
0
bool computeFourNeighbors(frameFieldBackgroundMesh2D *bgm,
                          MVertex *v_center, // the vertex for which we want to
                                             // generate 4 neighbors (real
                                             // vertex (xyz), not parametric!)
                          SPoint2 &midpoint,
                          bool goNonLinear, // do we compute the position in
                                            // the real surface which is
                                            // nonlinear
                          SPoint2 newP[4][NUMDIR], // look into other directions
                          SMetric3 &metricField) // the mesh metric
{
  // we assume that v is on surface gf, and backgroundMesh2D has been created
  // based on gf

  // get BGM and GFace
  GFace *gf = dynamic_cast<GFace *>(bgm->getBackgroundGEntity());

  // get the parametric coordinates of the point on the surface
  reparamMeshVertexOnFace(v_center, gf, midpoint);

  // get RK info on midpoint (infos in two directions...)
  RK_form infos;
  bgm->compute_RK_infos(midpoint[0], midpoint[1], v_center->x(), v_center->y(),
                        v_center->z(), infos);
  metricField = infos.metricField;

  // shoot in four directions
  SPoint2 param_vec;
  double h;
  for(int i = 0; i < 4; i++) { // in four directions
    switch(i) {
    case 0:
      param_vec = infos.paramt1;
      h = infos.paramh.first;
      break;
    case 1:
      param_vec = infos.paramt2;
      h = infos.paramh.second;
      break;
    case 2:
      param_vec = infos.paramt1 * -1.;
      h = infos.paramh.first;
      break;
    case 3:
      param_vec = infos.paramt2 * -1.;
      h = infos.paramh.second;
      break;
    }
    shoot(midpoint, param_vec, h, newP[i][0]);
    //    std::cout << "(" << midpoint[0] << "," <<midpoint[1] << ") -> (" <<
    //    newP[i][0][0] << "," << newP[i][0][1] << ") " << std::endl;
  }

  // the following comes from surfaceFiller.cpp...
  const double EPS = 1.e-7;
  for(int j = 0; j < 2; j++) {
    for(int i = 0; i < 4; i++) {
      newP[i][0][j] += (EPS * (double)rand() / RAND_MAX);
    }
  }

  // We could stop here. Yet, if the metric varies a lot, we can solve a
  // nonlinear problem in order to find a better approximation in the real
  // surface
  if(1 && goNonLinear) {
    double L = infos.localsize;
    double newPoint[4][2];
    for(int j = 0; j < 2; j++) {
      for(int i = 0; i < 4; i++) {
        newPoint[i][j] = newP[i][0][j];
      }
    }
    double ERR[4];
    for(int i = 0; i < 4; i++) { //
      //      if (newPoint[i][0] < rangeU.low())newPoint[i][0] = rangeU.low();
      //      if (newPoint[i][0] > rangeU.high())newPoint[i][0] = rangeU.high();
      //      if (newPoint[i][1] < rangeV.low())newPoint[i][1] = rangeV.low();
      //      if (newPoint[i][1] > rangeV.high())newPoint[i][1] = rangeV.high();
      GPoint pp = gf->point(newP[i][0]);
      double D = sqrt((pp.x() - v_center->x()) * (pp.x() - v_center->x()) +
                      (pp.y() - v_center->y()) * (pp.y() - v_center->y()) +
                      (pp.z() - v_center->z()) * (pp.z() - v_center->z()));
      ERR[i] = 100 * fabs(D - L) / (D + L);
      //      printf("L = %12.5E D = %12.5E ERR =
      //      %12.5E\n",L,D,100*fabs(D-L)/(D+L));
    }

    surfaceFunctorGFace ss(gf);
    SVector3 dirs[4] = {infos.t1 * (-1.0), infos.t2 * (-1.0), infos.t1 * (1.0),
                        infos.t2 * (1.0)};
    for(int i = 0; i < 4; i++) {
      if(ERR[i] > 12) {
        double uvt[3] = {newPoint[i][0], newPoint[i][1], 0.0};
        // printf("Intersecting with circle N = %g %g %g dir = %g %g %g R
        //	  = %g p = %g %g
        //	  %g\n",n.x(),n.y(),n.z(),dirs[i].x(),dirs[i].y(),dirs[i].z(),L,
        //        v_center->x(),v_center->y(),v_center->z());
        curveFunctorCircle cf(
          dirs[i], infos.normal,
          SVector3(v_center->x(), v_center->y(), v_center->z()), L);
        if(intersectCurveSurface(cf, ss, uvt, infos.paramh.first * 1.e-3)) {
          GPoint pp = gf->point(SPoint2(uvt[0], uvt[1]));
          double D = sqrt((pp.x() - v_center->x()) * (pp.x() - v_center->x()) +
                          (pp.y() - v_center->y()) * (pp.y() - v_center->y()) +
                          (pp.z() - v_center->z()) * (pp.z() - v_center->z()));
          double DP =
            sqrt((newPoint[i][0] - uvt[0]) * (newPoint[i][0] - uvt[0]) +
                 (newPoint[i][1] - uvt[1]) * (newPoint[i][1] - uvt[1]));
          double newErr = 100 * fabs(D - L) / (D + L);
          //	    if (v_center->onWhat() != gf && gf->tag() == 3){
          //	      crossField2d::normalizeAngle (uvt[2]);
          //	      printf("INTERSECT angle = %g DP %g\n",uvt[2],DP);
          //	    }
          if(newErr < 1 && DP < .1) {
            //	      printf("%12.5E vs %12.5E : %12.5E %12.5E vs %12.5E %12.5E
            //	      \n",ERR[i],newErr,newPoint[i][0],newPoint[i][1],uvt[0],uvt[1]);
            newPoint[i][0] = uvt[0];
            newPoint[i][1] = uvt[1];
          }
          //	    printf("OK\n");
        }
        else {
          Msg::Debug("Cannot put a new point on Surface %d", gf->tag());
          // printf("NOT OK\n");
        }
      }
    }

    // return the four new vertices
    for(int i = 0; i < 4; i++) {
      newP[i][0] = SPoint2(newPoint[i][0], newPoint[i][1]);
    }
  }

  return true;
}