Forked from
gmsh / gmsh
9515 commits behind the upstream repository.
-
Christophe Geuzaine authoredChristophe Geuzaine authored
GenericFace.cpp 8.85 KiB
// Gmsh - Copyright (C) 1997-2014 C. Geuzaine, J.-F. Remacle
//
// See the LICENSE.txt file for license information. Please report all
// bugs and problems to the public mailing list <gmsh@geuz.org>.
#include "GmshConfig.h"
#include "GmshMessage.h"
#include "GModel.h"
#include "GEdgeLoop.h"
#include "GenericVertex.h"
#include "GenericEdge.h"
#include "GenericFace.h"
#include "Numeric.h"
#include "Context.h"
#include <math.h>
GenericFace::ptrfunction_int_refstring GenericFace::FaceGeomType = NULL;
GenericFace::ptrfunction_int_refvector_refvector GenericFace::FaceUVFromXYZ = NULL;
GenericFace::ptrfunction_int_refvector_refvector_refvector GenericFace::FaceClosestPoint = NULL;
GenericFace::ptrfunction_int_refvector_refbool GenericFace::FaceContainsPointFromXYZ = NULL;
GenericFace::ptrfunction_int_refvector_refbool GenericFace::FaceContainsPointFromUV = NULL;
GenericFace::ptrfunction_int_refvector_refvector GenericFace::FaceXYZFromUV = NULL;
GenericFace::ptrfunction_int_int_refdouble_refdouble GenericFace::FaceParBounds = NULL;
GenericFace::ptrfunction_int_refvector_refvector_refvector_refdouble_refdouble GenericFace::FaceCurvatures = NULL;
GenericFace::ptrfunction_int_refvector_refvector GenericFace::FaceEvalNormal = NULL;
GenericFace::ptrfunction_int_refvector_refvector_refvector GenericFace::FaceFirstDer = NULL;
GenericFace::ptrfunction_int_refvector_refvector_refvector_refvector GenericFace::FaceSecondDer = NULL;
GenericFace::GenericFace(GModel *m, int num, int _native_id):GFace(m, num), id(_native_id)
{
if (!FaceParBounds) Msg::Fatal("Genericface::ERROR: Callback FaceParBounds not set");
Range<double> rangeu = parBounds(0);
Range<double> rangev = parBounds(1);
umin = rangeu.low();
umax = rangeu.high();
vmin = rangev.low();
vmax = rangev.high();
// TODO: set periodic or not !!!
//bool _periodic[2];// is periodic in u, v
// throw;
}
GenericFace::~GenericFace()
{
}
Range<double> GenericFace::parBounds(int i) const
{
if(i == 0) return Range<double>(umin, umax);
return Range<double>(vmin, vmax);
}
SVector3 GenericFace::normal(const SPoint2 ¶m) const
{
vector<double> res(3,0.);
vector<double> par(2,0.);
for (int i=0;i<2;i++) par[i] = param[i];
if (!FaceEvalNormal) Msg::Fatal("Genericface::ERROR: Callback FaceEvalNormal not set");
bool ok = FaceEvalNormal(id,par,res);
if (!ok) Msg::Error("GenericFace::ERROR from FaceEvalNormal ! " );
return SVector3(res[0],res[1],res[2]);
}
Pair<SVector3,SVector3> GenericFace::firstDer(const SPoint2 ¶m) const
{
if (!FaceFirstDer) Msg::Fatal("Genericface::ERROR: Callback FaceFirstDer not set");
vector<double> deru(3,0.);
vector<double> derv(3,0.);
vector<double> par(2,0.);
for (int i=0;i<2;i++) par[i] = param[i];
bool ok = FaceFirstDer(id,par,deru,derv);
if (!ok) Msg::Error("GenericFace::ERROR from FaceFirstDer ! " );
return Pair<SVector3,SVector3>(SVector3(deru[0],deru[1],deru[2]),
SVector3(derv[0],derv[1],derv[2]));
}
void GenericFace::secondDer(const SPoint2 ¶m,SVector3 *dudu, SVector3 *dvdv, SVector3 *dudv) const
{
vector<double> deruu(3,0.);
vector<double> dervv(3,0.);
vector<double> deruv(3,0.);
vector<double> par(2,0.);
for (int i=0;i<2;i++) par[i] = param[i];
if (!FaceSecondDer) Msg::Fatal("Genericface::ERROR: Callback FaceSecondDer not set");
bool ok = FaceSecondDer(id,par,deruu,dervv,deruv);
if (!ok) Msg::Error("GenericFace::ERROR from FaceSecondDer ! " );
*dudu = SVector3(deruu[0],deruu[1],deruu[2]);
*dvdv = SVector3(dervv[0],dervv[1],dervv[2]);
*dudv = SVector3(deruv[0],deruv[1],deruv[2]);
return;
}
GPoint GenericFace::point(double par1, double par2) const
{
vector<double> uv(2,0.);
uv[0] = par1;
uv[1] = par2;
vector<double> xyz(3,0.);
if (!FaceXYZFromUV) Msg::Fatal("Genericface::ERROR: Callback FaceXYZFromUV not set");
bool ok = FaceXYZFromUV(id,uv,xyz);
if (!ok) Msg::Error("GenericFace::ERROR from FaceXYZFromUV ! " );
double pp[2] = {par1, par2};
return GPoint(xyz[0], xyz[1], xyz[2], this, pp);
}
GPoint GenericFace::closestPoint(const SPoint3 &qp, const double initialGuess[2]) const
{
vector<double> uvres(2,0.);
vector<double> xyzres(3,0.);
vector<double> queryPoint(3,0.);
for (int i=0;i<3;i++) queryPoint[i] = qp[i];
if (!FaceClosestPoint) Msg::Fatal("Genericface::ERROR: Callback FaceClosestPoint not set");
bool ok = FaceClosestPoint(id,queryPoint,xyzres,uvres);// orthogonal projection
if (!ok) Msg::Error("GenericFace::ERROR from FaceClosestPoint ! " );
// check if the projected point lies on the face...
bool on_the_face;
// ok = FaceContainsPointFromXYZ(id,xyzres,on_the_face);// check if the projected point lies on the face...
// if (!ok) cout << "ERROR from FaceContainsPointFromXYZ ! " << endl;
// if (!on_the_face) cout << "GenericFace::closestPoint::WARNING (using XYZ) !!!! The returned point does not lies on the face ! " << endl;
if (!FaceContainsPointFromUV) Msg::Fatal("Genericface::ERROR: Callback FaceContainsPointFromUV not set");
ok = FaceContainsPointFromUV(id,uvres,on_the_face);
if (!ok) Msg::Error("GenericFace::ERROR from FaceContainsPointFromUV ! " );
if (!on_the_face) Msg::Warning("GenericFace::closestPoint::Warning (using UV) !!!! The returned point does not lies on the face ! " );
double pp[2] = {uvres[0], uvres[1]};
return GPoint(xyzres[0], xyzres[1], xyzres[2], this, pp);
}
SPoint2 GenericFace::parFromPoint(const SPoint3 &qp, bool onSurface) const
{
vector<double> uvres(2,0.);
vector<double> xyzres(3,0.);
vector<double> queryPoint(3,0.);
for (int i=0;i<3;i++) queryPoint[i] = qp[i];
bool ok=true;
if (onSurface){
if (!FaceUVFromXYZ) Msg::Fatal("Genericface::ERROR: Callback FaceUVFromXYZ not set");
ok = FaceUVFromXYZ(id,queryPoint,uvres);// assuming point is on surface
if (!ok) Msg::Error("GenericFace::ERROR from FaceUVFromXYZ ! " );
}
if ((!onSurface)||(!ok)){// if not on surface
if (!FaceClosestPoint) Msg::Fatal("Genericface::ERROR: Callback FaceClosestPoint not set");
ok = FaceClosestPoint(id,queryPoint,xyzres,uvres);// orthogonal projection
if (!ok) Msg::Error("GenericFace::ERROR from FaceClosestPoint ! " );
bool on_the_face;
if (!FaceContainsPointFromXYZ) Msg::Fatal("Genericface::ERROR: Callback FaceContainsPointFromXYZ not set");
ok = FaceContainsPointFromXYZ(id,xyzres,on_the_face);// check if the projected point lies on the face...
if (!ok) Msg::Error("GenericFace::ERROR from FaceContainsPointFromXYZ ! " );
if (!on_the_face) Msg::Warning("GenericFace::parFromPoint::Warning !!!! The returned point does not lies on the face ! " );
}
return SPoint2(uvres[0],uvres[1]);
}
GEntity::GeomType GenericFace::geomType() const
{
string s;
if (!FaceGeomType) Msg::Fatal("Genericface::ERROR: Callback FaceGeomType not set");
bool ok = FaceGeomType(id,s);
if (!ok){
Msg::Error("GenericFace::ERROR from FaceGeomType ! " );
return Unknown;
}
if(s.compare("Plane")==0)
return Plane;
else if(s.compare("Cylinder")==0)
return Cylinder;
else if(s.compare("Cone")==0)
return Cone;
else if(s.compare("Sphere")==0)
return Sphere;
else if(s.compare("Torus")==0)
return Torus;
else if(s.compare("BezierSurface")==0)
return BezierSurface;
else if(s.compare("BSplineSurface")==0)
return BSplineSurface;
else if(s.compare("SurfaceOfRevolution")==0)
return SurfaceOfRevolution;
return Unknown;
}
double GenericFace::curvatureMax(const SPoint2 ¶m) const
{
vector<double> dirMax(3,0.);
vector<double> dirMin(3,0.);
double curvMax,curvMin;
vector<double> par(2,0.);
for (int i=0;i<2;i++) par[i] = param[i];
if (!FaceCurvatures) Msg::Fatal("Genericface::ERROR: Callback FaceCurvatures not set");
bool ok = FaceCurvatures(id,par,dirMax,dirMin,curvMax,curvMin);
if (!ok) Msg::Error("GenericFace::ERROR from FaceCurvatures ! " );
return std::max(fabs(curvMax), fabs(curvMin));
}
double GenericFace::curvatures(const SPoint2 &_param,SVector3 *_dirMax,SVector3 *_dirMin,
double *curvMax,double *curvMin) const
{
vector<double> param(2,0.);
for (int i=0;i<2;i++) param[i] = _param[i];
vector<double> dirMax(3,0.);
vector<double> dirMin(3,0.);
if (!FaceCurvatures) Msg::Fatal("Genericface::ERROR: Callback FaceCurvatures not set");
bool ok = FaceCurvatures(id,param,dirMax,dirMin,*curvMax,*curvMin);
if (!ok) Msg::Error("GenericFace::ERROR from FaceCurvatures ! " );
*_dirMax = SVector3(dirMax[0],dirMax[1],dirMax[2]);
*_dirMin = SVector3(dirMin[0],dirMin[1],dirMin[2]);
return *curvMax;
}
bool GenericFace::containsPoint(const SPoint3 &pt) const
{
bool res;
vector<double> queryPoint(3,0.);
for (int i=0;i<3;i++) queryPoint[i] = pt[i];
if (!FaceContainsPointFromXYZ) Msg::Fatal("Genericface::ERROR: Callback FaceContainsPointFromXYZ not set");
bool ok = FaceContainsPointFromXYZ(id,queryPoint,res);
if (!ok) Msg::Error("GenericFace::ERROR from FaceContainsPointFromXYZ ! " );
return res;
}