diff --git a/CMakeLists.txt b/CMakeLists.txt index b4b01bdf2af890a977bafc39a94399f84ae38b93..cb478406c11f61f9d6a1cb0d78591d908c9da4a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -125,6 +125,7 @@ set(GMSH_API Geo/SPoint2.h Geo/SPoint3.h Geo/SVector3.h Geo/STensor3.h Geo/SBoundingBox3d.h Geo/Pair.h Geo/Range.h Geo/SOrientedBoundingBox.h Geo/CellComplex.h Geo/ChainComplex.h Geo/Cell.h Geo/Homology.h Geo/Chain.h + Geo/GenericVertex.h Geo/GenericEdge.h Geo/GenericFace.h Geo/GenericRegion.h Geo/partitionEdge.h Geo/CGNSOptions.h Geo/gmshLevelset.h Geo/boundaryLayersData.h Mesh/meshGEdge.h Mesh/meshGFace.h Mesh/meshGFaceOptimize.h Mesh/meshGFaceElliptic.h Mesh/meshPartition.h Mesh/meshGFaceDelaunayInsertion.h diff --git a/Geo/CMakeLists.txt b/Geo/CMakeLists.txt index ed90152c76c7a16f9211fc93c3f62f4a3ae822ed..78bae5b48cf5cbde67f700cbff8a66fc419726dc 100644 --- a/Geo/CMakeLists.txt +++ b/Geo/CMakeLists.txt @@ -14,6 +14,7 @@ set(SRC gmshVertex.cpp gmshEdge.cpp gmshFace.cpp gmshRegion.cpp gmshSurface.cpp OCCVertex.cpp OCCEdge.cpp OCCFace.cpp OCCRegion.cpp + GenericVertex.cpp GenericEdge.cpp GenericFace.cpp GenericRegion.cpp discreteEdge.cpp discreteFace.cpp discreteRegion.cpp fourierEdge.cpp fourierFace.cpp fourierProjectionFace.cpp ACISVertex.cpp diff --git a/Geo/GEntity.h b/Geo/GEntity.h index b120b83799c8864166b947ece032e4780409649d..4ec679f7605cad11efef20b3592b9ed75f5f26fa 100644 --- a/Geo/GEntity.h +++ b/Geo/GEntity.h @@ -65,6 +65,7 @@ class GEntity { GmshModel, FourierModel, OpenCascadeModel, + GenericModel, AcisModel }; @@ -239,6 +240,9 @@ class GEntity { // get the native pointer of the particular representation virtual void *getNativePtr() const { return 0; } + + // get the native id (int) of the particular representation + virtual int getNativeInt() const { return 0; } // the model owning this entity GModel *model() const { return _model; } diff --git a/Geo/GenericEdge.cpp b/Geo/GenericEdge.cpp new file mode 100644 index 0000000000000000000000000000000000000000..53af6e71a781ede4985fd67e755f695b9fad1d8f --- /dev/null +++ b/Geo/GenericEdge.cpp @@ -0,0 +1,162 @@ +// 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 <limits> +#include "GmshConfig.h" +#include "GmshMessage.h" +#include "GModel.h" +#include "GenericEdge.h" +#include "GenericFace.h" +#include "Context.h" + +//------------------------------------------------------------------------ + +GenericEdge::ptrfunction_int_double_refvector GenericEdge::EdgeEvalXYZFromT = NULL; +GenericEdge::ptrfunction_int_refdouble_refdouble GenericEdge::EdgeEvalParBounds = NULL; +GenericEdge::ptrfunction_int_refstring GenericEdge::EdgeGeomType = NULL; +GenericEdge::ptrfunction_int_refbool GenericEdge::EdgeDegenerated = NULL; +GenericEdge::ptrfunction_int_double_refvector GenericEdge::EdgeEvalFirstDer = NULL; +GenericEdge::ptrfunction_int_double_refdouble GenericEdge::EdgeEvalCurvature = NULL; +GenericEdge::ptrfunction_int_refvector_refdouble_refvector_refbool GenericEdge::EdgeClosestPoint = NULL; +GenericEdge::ptrfunction_int_refbool GenericEdge::EdgeIs3D = NULL; +GenericEdge::ptrfunction_int_int_double_int_refvector GenericEdge::EdgeReparamOnFace = NULL; + +//------------------------------------------------------------------------ + +GenericEdge::GenericEdge(GModel *m, int num, int _native_id, GVertex *v1, GVertex *v2):GEdge(m, num, v1, v2), id(_native_id){ + if ((!EdgeEvalParBounds)||(!EdgeEvalXYZFromT)) Msg::Error("GenericEdge::ERROR: Callback not set"); + bool ok = EdgeEvalParBounds(id,s0,s1); + if (!ok) Msg::Error("GenericEdge::ERROR from EdgeEvalParBounds ! " ); +} + +//------------------------------------------------------------------------ + +GenericEdge::~GenericEdge(){ +} + +//------------------------------------------------------------------------ + +Range<double> GenericEdge::parBounds(int i) const{ + return Range<double>(s0, s1); +} + +//------------------------------------------------------------------------ + +SPoint2 GenericEdge::reparamOnFace(const GFace *face, double par, int dir) const{ + vector<double> res(2,0.); + if (!EdgeReparamOnFace) Msg::Error("GenericEdge::ERROR: Callback EdgeReparamOnFace not set"); + bool ok = EdgeReparamOnFace(id,face->getNativeInt(),par, dir,res); + if (!ok) Msg::Error("GenericEdge::ERROR from EdgeReparamOnFace ! " ); + return SPoint2(res[0],res[1]);; +} + +//------------------------------------------------------------------------ + +GPoint GenericEdge::closestPoint(const SPoint3 &qp, double ¶m) const{ + vector<double> queryPoint(3,0.); + for (int i=0;i<3;i++) queryPoint[i] = qp[i]; + vector<double> res(3,0.); + bool is_on_edge; + if (!EdgeClosestPoint) Msg::Error("GenericEdge::ERROR: Callback EdgeClosestPoint not set"); + bool ok = EdgeClosestPoint(id,queryPoint,param,res,is_on_edge); + if (!ok) Msg::Error("GenericEdge::ERROR from EdgeClosestPoint ! " ); + if (!is_on_edge) Msg::Warning("WARNING:GenericEdge::closestPoint closest point NOT on edge, out of bounds ! " ); + return GPoint(res[0], res[1], res[2], this, param); +} + +//------------------------------------------------------------------------ + +// True if the edge is a seam for the given face +bool GenericEdge::isSeam(const GFace *face) const{ + Msg::Error("GenericEdge::isSeam: not implemented yet ! "); + return false; +} + +//------------------------------------------------------------------------ + +GPoint GenericEdge::point(double par) const{ + vector<double> res(3,0.); + if (!EdgeEvalXYZFromT) Msg::Error("GenericEdge::ERROR: Callback EdgeEvalXYZFromT not set"); + bool ok = EdgeEvalXYZFromT(id,par,res); + if (!ok) Msg::Error("GenericEdge::ERROR from EdgeEvalXYZFromT ! " ); + return GPoint(res[0], res[1], res[2], this, par); +} + +//------------------------------------------------------------------------ + +SVector3 GenericEdge::firstDer(double par) const{ + vector<double> res(3,0.); + if (!EdgeEvalFirstDer) Msg::Error("GenericEdge::ERROR: Callback EdgeEvalFirstDer not set"); + bool ok = EdgeEvalFirstDer(id,par,res); + if (!ok) Msg::Error("GenericEdge::ERROR from EdgeEvalFirstDer ! " ); + return SVector3(res[0],res[1],res[2]); +} + +//------------------------------------------------------------------------ + +GEntity::GeomType GenericEdge::geomType() const{ + string s; + if (!EdgeGeomType) Msg::Error("GenericEdge::ERROR: Callback EdgeGeomType not set"); + bool ok = EdgeGeomType(id,s); + if (!ok){ + Msg::Error("GenericEdge::ERROR from EdgeGeomType ! " ); + return Unknown; + } + + if(s.compare("Line")==0) + return Line; + else if(s.compare("Circle")==0) + return Circle; + else if(s.compare("Ellipse")==0) + return Ellipse; + else if(s.compare("Parabola")==0) + return Parabola; + else if(s.compare("Hyperbola")==0) + return Hyperbola; + else if(s.compare("Bezier")==0) + return Bezier; + else if(s.compare("BSpline")==0) + return BSpline; + else if(s.compare("TrimmedCurve")==0) + return TrimmedCurve; + + Msg::Warning("GenericEdge::geomType:: unknown type from callback: ", s.c_str()); + + return Unknown; +} + +//------------------------------------------------------------------------ + +double GenericEdge::curvature(double par) const{ + double res; + if (!EdgeEvalCurvature) Msg::Error("GenericEdge::ERROR: Callback EdgeEvalCurvature not set"); + bool ok = EdgeEvalCurvature(id,par,res); + if (!ok) Msg::Error("GenericEdge::ERROR from EdgeEvalCurvature ! " ); + return res; +} + +//------------------------------------------------------------------------ + +bool GenericEdge::is3D() const{ + bool res; + if (!EdgeIs3D) Msg::Error("GenericEdge::ERROR: Callback EdgeIs3D not set"); + bool ok = EdgeIs3D(id,res); + if (!ok) Msg::Error("GenericEdge::ERROR from EdgeIs3D ! " ); + return res; +} + +//------------------------------------------------------------------------ + +bool GenericEdge::degenerate(int) const{ + bool res; + if (!EdgeDegenerated) Msg::Error("GenericEdge::ERROR: Callback EdgeDegenerated not set"); + bool ok = EdgeDegenerated(id,res); + if (!ok) Msg::Error("GenericEdge::ERROR from EdgeDegenerated ! " ); + return res; +} + +//------------------------------------------------------------------------ + + diff --git a/Geo/GenericEdge.h b/Geo/GenericEdge.h new file mode 100644 index 0000000000000000000000000000000000000000..cd29aadadb2ce4e99e7d298bc3d496c72aa96a30 --- /dev/null +++ b/Geo/GenericEdge.h @@ -0,0 +1,85 @@ +// 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>. + +#ifndef _GENERIC_EDGE_H +#define _GENERIC_EDGE_H + +#include "GmshConfig.h" +#include "GEdge.h" +#include "GModel.h" +#include "GenericVertex.h" +#include "Range.h" +#include <vector> + +using namespace std; + +class GenericFace; + +/*The set of Generic Entities is a generic interface to any other modeler. + Callbacks (function pointers) are given, sending requests, enquiries, to the native modeler. */ + +class GenericEdge : public GEdge { + protected: + double s0, s1; + int id; + public: + // callbacks typedef + typedef bool (*ptrfunction_int_double_refvector)(int, double, vector<double>&); + typedef bool (*ptrfunction_int_refdouble_refdouble)(int, double&, double&); + typedef bool (*ptrfunction_int_double_refdouble)(int, double, double&); + typedef bool (*ptrfunction_int_refstring)(int, string&); + typedef bool (*ptrfunction_int_refbool)(int, bool&); + typedef bool (*ptrfunction_int_refvector_refdouble_refvector_refbool)(int, const vector<double> &, double &, vector<double>&, bool &); + typedef bool (*ptrfunction_int_int_double_int_refvector)(int, int, double, int, vector<double> &); + + GenericEdge(GModel *model, int num,int _native_id, GVertex *v1, GVertex *v2); + virtual ~GenericEdge(); + + virtual Range<double> parBounds(int i) const; + virtual GeomType geomType() const; + virtual bool degenerate(int) const; + virtual GPoint point(double p) const; + virtual SVector3 firstDer(double par) const; + virtual double curvature (double par) const; + virtual SPoint2 reparamOnFace(const GFace *face, double epar, int dir) const; + virtual GPoint closestPoint(const SPoint3 &queryPoint, double ¶m) const; + + ModelType getNativeType() const { return GenericModel; } + virtual int getNativeInt()const{return id;}; + + bool is3D() const; + bool isSeam(const GFace *) const; + + // sets the callbacks, to be given by the user + static void setEdgeEvalXYZFromT(ptrfunction_int_double_refvector fct){EdgeEvalXYZFromT = fct;}; + static void setEdgeEvalParBounds(ptrfunction_int_refdouble_refdouble fct){EdgeEvalParBounds = fct;}; + static void setEdgeGeomType(ptrfunction_int_refstring fct){EdgeGeomType = fct;}; + static void setEdgeDegenerated(ptrfunction_int_refbool fct){EdgeDegenerated = fct;}; + static void setEdgeEvalFirstDer(ptrfunction_int_double_refvector fct){EdgeEvalFirstDer = fct;}; + static void setEdgeEvalCurvature(ptrfunction_int_double_refdouble fct){EdgeEvalCurvature = fct;}; + static void setEdgeClosestPoint(ptrfunction_int_refvector_refdouble_refvector_refbool fct){EdgeClosestPoint = fct;}; + static void setEdgeIs3D(ptrfunction_int_refbool fct){EdgeIs3D = fct;}; + static void setEdgeReparamOnFace(ptrfunction_int_int_double_int_refvector fct){EdgeReparamOnFace = fct;}; + + private: + // the callbacks: + // -------------- + static ptrfunction_int_double_refvector EdgeEvalXYZFromT; + static ptrfunction_int_refdouble_refdouble EdgeEvalParBounds; + static ptrfunction_int_refstring EdgeGeomType; + static ptrfunction_int_refbool EdgeDegenerated; + static ptrfunction_int_double_refvector EdgeEvalFirstDer; + static ptrfunction_int_double_refdouble EdgeEvalCurvature; + // the first vector is a query point xyz, fills the second vector with closest point + // on edge using orthogonal projection. Fills double param with parametric coordinate of end point projection. + static ptrfunction_int_refvector_refdouble_refvector_refbool EdgeClosestPoint; + static ptrfunction_int_refbool EdgeIs3D; + static ptrfunction_int_int_double_int_refvector EdgeReparamOnFace; + + +}; + + +#endif diff --git a/Geo/GenericFace.cpp b/Geo/GenericFace.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3046436973158c188c6fea287e1e076e63347f51 --- /dev/null +++ b/Geo/GenericFace.cpp @@ -0,0 +1,244 @@ +// 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<3;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<3;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<3;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<3;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<3;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; +} + +//------------------------------------------------------------------------ + diff --git a/Geo/GenericFace.h b/Geo/GenericFace.h new file mode 100644 index 0000000000000000000000000000000000000000..76c5e55de9c997c209c1b3764812ffb0f0f1db04 --- /dev/null +++ b/Geo/GenericFace.h @@ -0,0 +1,92 @@ +// 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>. + +#ifndef _GENERIC_FACE_H_ +#define _GENERIC_FACE_H_ + +#include "GmshConfig.h" +#include "GFace.h" +#include "GModel.h" +#include "GenericVertex.h" +#include "GenericEdge.h" +#include "Range.h" +#include <vector> + +using namespace std; + +/*The set of Generic Entities is a generic interface to any other modeler. + Callbacks (function pointers) are given, sending requests, enquiries, to the native modeler. */ + +class GenericFace : public GFace { + protected: + int id; + double umin, umax, vmin, vmax;// face uv bounds + bool _periodic[2];// is periodic in u, v + + public: + // callbacks typedef + typedef bool (*ptrfunction_int_refstring)(int, string&); + typedef bool (*ptrfunction_int_refvector_refvector)(const int , const vector<double> &, vector<double> &); + typedef bool (*ptrfunction_int_refvector_refvector_refvector)(const int , const vector<double> &, vector<double> &, vector<double> &); + typedef bool (*ptrfunction_int_refvector_refbool)(const int , const vector<double> &, bool &); + typedef bool (*ptrfunction_int_int_refdouble_refdouble)(const int, const int, double &, double &); + typedef bool (*ptrfunction_int_refvector_refvector_refvector_refdouble_refdouble)(const int, const vector<double> &, vector<double> &, vector<double> &, double &, double &); + typedef bool (*ptrfunction_int_refvector_refvector_refvector_refvector)(const int , const vector<double> &, vector<double> &, vector<double> &, vector<double> &); + + GenericFace(GModel *m, int num, int _native_id); + virtual ~GenericFace(); + + Range<double> parBounds(int i) const; + virtual GPoint point(double par1, double par2) const; + virtual GPoint closestPoint(const SPoint3 & queryPoint, + const double initialGuess[2]) const; + virtual bool containsPoint(const SPoint3 &pt) const; + virtual SVector3 normal(const SPoint2 ¶m) const; + virtual Pair<SVector3,SVector3> firstDer(const SPoint2 ¶m) const; + virtual void secondDer(const SPoint2 &, SVector3 *, SVector3 *, SVector3 *) const; + virtual GEntity::GeomType geomType() const; + virtual SPoint2 parFromPoint(const SPoint3 &, bool onSurface=true) const; + virtual double curvatureMax(const SPoint2 ¶m) const; + virtual double curvatures(const SPoint2 ¶m, SVector3 *dirMax, SVector3 *dirMin, + double *curvMax, double *curvMin) const; + + ModelType getNativeType() const { return GenericModel; } + virtual int getNativeInt()const{return id;}; + + void addBndInfo(int loop, GEdge *ptr, int sign){ + bnd.insert(make_pair(loop, make_pair(ptr,sign))); + l_dirs.push_back(sign); + l_edges.push_back(ptr); + ptr->addFace(this); + }; + + // sets callbacks + static void setFaceGeomType(ptrfunction_int_refstring fct){FaceGeomType = fct;}; + static void setFaceUVFromXYZ(ptrfunction_int_refvector_refvector fct){FaceUVFromXYZ = fct;}; + static void setFaceClosestPoint(ptrfunction_int_refvector_refvector_refvector fct){FaceClosestPoint = fct;}; + static void setFaceContainsPointFromXYZ(ptrfunction_int_refvector_refbool fct){FaceContainsPointFromXYZ = fct;}; + static void setFaceContainsPointFromUV(ptrfunction_int_refvector_refbool fct){FaceContainsPointFromUV = fct;}; + static void setFaceXYZFromUV(ptrfunction_int_refvector_refvector fct){FaceXYZFromUV = fct;}; + static void setFaceParBounds(ptrfunction_int_int_refdouble_refdouble fct){FaceParBounds = fct;}; + static void setFaceCurvatures(ptrfunction_int_refvector_refvector_refvector_refdouble_refdouble fct){FaceCurvatures = fct;}; + static void setFaceEvalNormal(ptrfunction_int_refvector_refvector fct){FaceEvalNormal = fct;}; + static void setFaceFirstDer(ptrfunction_int_refvector_refvector_refvector fct){FaceFirstDer = fct;}; + static void setFaceSecondDer(ptrfunction_int_refvector_refvector_refvector_refvector fct){FaceSecondDer = fct;}; + + private: + multimap<int, pair<GEdge*,int> > bnd; + + // the callbacks: + static ptrfunction_int_refstring FaceGeomType; + static ptrfunction_int_refvector_refvector FaceUVFromXYZ,FaceXYZFromUV,FaceEvalNormal; + static ptrfunction_int_refvector_refvector_refvector FaceClosestPoint,FaceFirstDer; + static ptrfunction_int_refvector_refbool FaceContainsPointFromXYZ,FaceContainsPointFromUV; + static ptrfunction_int_int_refdouble_refdouble FaceParBounds; + static ptrfunction_int_refvector_refvector_refvector_refdouble_refdouble FaceCurvatures; + static ptrfunction_int_refvector_refvector_refvector_refvector FaceSecondDer; + +}; + +#endif diff --git a/Geo/GenericRegion.cpp b/Geo/GenericRegion.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a6b8f1a408777c553d70eddad8ebeb541a48d391 --- /dev/null +++ b/Geo/GenericRegion.cpp @@ -0,0 +1,34 @@ +// 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 "GenericVertex.h" +#include "GenericEdge.h" +#include "GenericFace.h" +#include "GenericRegion.h" + +//------------------------------------------------------------------------ + +GenericRegion::GenericRegion(GModel *m, int num, int _native_id):GRegion(m, num), id(_native_id) +{ +} + +//------------------------------------------------------------------------ + +GenericRegion::~GenericRegion() +{ +} + +//------------------------------------------------------------------------ + +GEntity::GeomType GenericRegion::geomType() const +{ + return Unknown; +} + +//------------------------------------------------------------------------ + diff --git a/Geo/GenericRegion.h b/Geo/GenericRegion.h new file mode 100644 index 0000000000000000000000000000000000000000..74850cc8b2e7cb3535f48a167b283391adc97e48 --- /dev/null +++ b/Geo/GenericRegion.h @@ -0,0 +1,37 @@ +// 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>. + +#ifndef _GENERIC_REGION_H_ +#define _GENERIC_REGION_H_ + +#include "GmshConfig.h" +#include "GRegion.h" + +/*The set of Generic Entities is a generic interface to any other modeler. + Callbacks (function pointers) are given, sending requests, enquiries, to the native modeler. */ + +class GenericRegion : public GRegion { + public: + GenericRegion(GModel *m, int num, int _native_id); + virtual ~GenericRegion(); + + virtual GeomType geomType() const; + + ModelType getNativeType() const { return GenericModel; } + virtual int getNativeInt()const{return id;}; + + // TODO: When using GRegion->l_dirs and l_faces, what is the convention for l_dirs ? For now, assuming positive value for normals pointing inside the region. + void addFace(GenericFace *ptr, int sign){ + l_dirs.push_back(sign); + l_faces.push_back(ptr); + ptr->addRegion(this); + }; + + + private: + int id; +}; + +#endif diff --git a/Geo/GenericVertex.cpp b/Geo/GenericVertex.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a80e787cf8c51a8eb43d9c8e14ae6b87b1d546de --- /dev/null +++ b/Geo/GenericVertex.cpp @@ -0,0 +1,92 @@ +// 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 "GModel.h" +#include "MVertex.h" +#include "MPoint.h" +#include "GenericVertex.h" +#include "GenericEdge.h" +#include "GenericFace.h" +#include<algorithm> + +//------------------------------------------------------------------------ + +GenericVertex::ptrfunction_int_vector GenericVertex::VertexXYZ = NULL; + +//------------------------------------------------------------------------ + +GenericVertex::GenericVertex(GModel *m, int num, int _native_id):GVertex(m, num), id(_native_id){ + if (!VertexXYZ) + Msg::Fatal("GenericVertex::ERROR: Callback not set"); + + vector<double> vec(3,0.); + bool ok = VertexXYZ(id,vec); + if (!ok) Msg::Error("GenericVertex::ERROR from callback VertexXYZ "); + _x=vec[0]; + _y=vec[1]; + _z=vec[2]; +} + +//------------------------------------------------------------------------ + +GenericVertex::~GenericVertex(){ +} + +//------------------------------------------------------------------------ + +SPoint2 GenericVertex::reparamOnFace(const GFace *gf, int dir) const +{ + std::list<GEdge*>::const_iterator it = l_edges.begin(); + // // TODO: isSeam not ready yet !!! + // while(it != l_edges.end()){ + // std::list<GEdge*> l = gf->edges(); + // if(std::find(l.begin(), l.end(), *it) != l.end()){ + // if((*it)->isSeam(gf)){ + // const TopoDS_Face *s = (TopoDS_Face*)gf->getNativePtr(); + // const TopoDS_Edge *c = (TopoDS_Edge*)(*it)->getNativePtr(); + // double s1,s0; + // Handle(Geom2d_Curve) curve2d = BRep_Tool::CurveOnSurface(*c, *s, s0, s1); + // if((*it)->getBeginVertex() == this) + // return (*it)->reparamOnFace(gf, s0, dir); + // else if((*it)->getEndVertex() == this) + // return (*it)->reparamOnFace(gf, s1, dir); + // } + // } + // ++it; + // } + it = l_edges.begin(); + while(it != l_edges.end()){ + std::list<GEdge*> l = gf->edges(); + if(std::find(l.begin(), l.end(), *it) != l.end()){ + // the vertex belongs to an edge, which belongs to a face -> just find if begin or end vertex and edge->reparamOnFace(begin or end param) + Range<double> vec = (*it)->parBounds(0); + if((*it)->getBeginVertex() == this) + return (*it)->reparamOnFace(gf, vec.low(), dir); + else if((*it)->getEndVertex() == this) + return (*it)->reparamOnFace(gf, vec.high(), dir); + } + ++it; + } + + // normally never here + return GVertex::reparamOnFace(gf, dir); +} + +//------------------------------------------------------------------------ + +void GenericVertex::setPosition(GPoint &p) +{ + _x = p.x(); + _y = p.y(); + _z = p.z(); + if(mesh_vertices.size()){ + mesh_vertices[0]->x() = p.x(); + mesh_vertices[0]->y() = p.y(); + mesh_vertices[0]->z() = p.z(); + } +} + +//------------------------------------------------------------------------ diff --git a/Geo/GenericVertex.h b/Geo/GenericVertex.h new file mode 100644 index 0000000000000000000000000000000000000000..fb34abceb81105f35f8a38d9512952738044547c --- /dev/null +++ b/Geo/GenericVertex.h @@ -0,0 +1,51 @@ +// 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>. + +#ifndef _GENERIC_VERTEX_H_ +#define _GENERIC_VERTEX_H_ + +#include "GmshConfig.h" +#include "GModel.h" +#include "GVertex.h" +#include <vector> + +using namespace std; + +/*The set of Generic Entities is a generic interface to any other modeler. + Callbacks (function pointers) are given, sending requests, enquiries, to the native modeler. */ + +class GenericVertex : public GVertex { + protected: + int id; + double _x, _y, _z; + public: + // callbacks typedef + typedef bool (*ptrfunction_int_vector)(int, vector<double>&); + + GenericVertex(GModel *m, int num, int _native_id); + virtual ~GenericVertex(); + + virtual GPoint point() const { return GPoint(x(), y(), z()); } + virtual double x() const { return _x; } + virtual double y() const { return _y; } + virtual double z() const { return _z; } + + virtual void setPosition(GPoint &p); + virtual SPoint2 reparamOnFace(const GFace *gf, int) const; + + ModelType getNativeType() const { return GenericModel; } + virtual int getNativeInt()const{return id;}; + + // sets the callbacks + static void setVertexXYZ(ptrfunction_int_vector fct){VertexXYZ = fct;}; + + private: + // the callbacks: + // -------------- + // fills vector xyz for vertex of int id + static ptrfunction_int_vector VertexXYZ; +}; + +#endif