diff --git a/Common/Context.h b/Common/Context.h index ef1e961fd9ae528159e15d3cad48c883d10ee8fc..0cde4d0bfb3db673780e36fb57533e01a5d84ae8 100644 --- a/Common/Context.h +++ b/Common/Context.h @@ -153,6 +153,7 @@ public : int auto_coherence; double tolerance; double snap[3]; + int occ_fix_small_edges, occ_fix_small_faces, occ_sew_faces; } geom; // mesh options diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h index d22a6522c0bea83e3d1bc9b5d6dcc8e5afe47635..214b50480e4c098d33cd31ec8fd0687d781b18a0 100644 --- a/Common/DefaultOptions.h +++ b/Common/DefaultOptions.h @@ -797,6 +797,12 @@ StringXNumber GeometryOptions_Number[] = { { F|O, "Normals" , opt_geometry_normals , 0. , "Display size of normal vectors (in pixels)" }, + { F|O, "OCCFixSmallEdges" , opt_geometry_occ_fix_small_edges , 1. , + "Fix small edges in OpenCascade models" }, + { F|O, "OCCFixSmallFaces" , opt_geometry_occ_fix_small_faces , 1. , + "Fix small faces in OpenCascade models" }, + { F|O, "OCCSewFaces" , opt_geometry_occ_sew_faces , 0. , + "Sew faces in OpenCascade models" }, { F|O, "OldCircle" , opt_geometry_old_circle , 0. , "Use old circle description (compatibility option for old Gmsh geometries)" }, { F|O, "OldNewReg" , opt_geometry_old_newreg , 1. , diff --git a/Common/Options.cpp b/Common/Options.cpp index 19cf2ff1dcf45700051184467d1ab421a5a88c79..625e9ab12cc8498b40df65f5236c7852c885fb12 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -1,4 +1,4 @@ -// $Id: Options.cpp,v 1.328 2007-01-18 09:12:44 geuzaine Exp $ +// $Id: Options.cpp,v 1.329 2007-01-18 13:18:42 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -3978,6 +3978,27 @@ double opt_geometry_light(OPT_ARGS_NUM) return CTX.geom.light; } +double opt_geometry_occ_fix_small_edges(OPT_ARGS_NUM) +{ + if(action & GMSH_SET) + CTX.geom.occ_fix_small_edges = val ? 1 : 0; + return CTX.geom.occ_fix_small_edges; +} + +double opt_geometry_occ_fix_small_faces(OPT_ARGS_NUM) +{ + if(action & GMSH_SET) + CTX.geom.occ_fix_small_faces = val ? 1 : 0; + return CTX.geom.occ_fix_small_faces; +} + +double opt_geometry_occ_sew_faces(OPT_ARGS_NUM) +{ + if(action & GMSH_SET) + CTX.geom.occ_sew_faces = val ? 1 : 0; + return CTX.geom.occ_sew_faces; +} + double opt_geometry_old_circle(OPT_ARGS_NUM) { if(action & GMSH_SET) diff --git a/Common/Options.h b/Common/Options.h index 850b6562d48c035f2ebae2ba5e11b3fa4421e4a7..8a82b7902e0905879af50a5a3011f6d794e91b6d 100644 --- a/Common/Options.h +++ b/Common/Options.h @@ -398,6 +398,9 @@ double opt_mesh_label_frequency(OPT_ARGS_NUM); double opt_geometry_line_sel_width(OPT_ARGS_NUM); double opt_geometry_line_type(OPT_ARGS_NUM); double opt_geometry_light(OPT_ARGS_NUM); +double opt_geometry_occ_fix_small_edges(OPT_ARGS_NUM); +double opt_geometry_occ_fix_small_faces(OPT_ARGS_NUM); +double opt_geometry_occ_sew_faces(OPT_ARGS_NUM); double opt_geometry_old_circle(OPT_ARGS_NUM); double opt_geometry_old_newreg(OPT_ARGS_NUM); double opt_geometry_circle_points(OPT_ARGS_NUM); diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp index 0d3f234024717052afe07aea505308f4de8c91a0..ba3225263939303a5cf75bd6765c7caf87319993 100644 --- a/Geo/GModel.cpp +++ b/Geo/GModel.cpp @@ -1,4 +1,4 @@ -// $Id: GModel.cpp,v 1.27 2007-01-12 13:16:59 remacle Exp $ +// $Id: GModel.cpp,v 1.28 2007-01-18 13:18:42 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -296,13 +296,3 @@ void GModel::deleteMeshPartitions() meshPartitions.clear(); } -double GModel::getMeshSize () -{ - if(meshSize < 0){ - SBoundingBox3d b = bounds(); - return 0.1 * norm(SVector3(b.max(), b.min())); - - } - else - return meshSize; -} diff --git a/Geo/GModel.h b/Geo/GModel.h index 1e9042ee9b6d49d9811bcf56ec7550d7caf952d0..20365702e15c1d36c8d9727ea4de5b5bd7e5ee38 100644 --- a/Geo/GModel.h +++ b/Geo/GModel.h @@ -39,7 +39,6 @@ class GModel private: void deleteOCCInternals(); OCC_Internals *occ_internals; - double meshSize; protected: std::string modelName; @@ -51,8 +50,8 @@ class GModel std::map<int, std::string> physicalNames; public: - GModel() : meshSize(-1.), modelName("Untitled"), normals(0) {} - GModel(const std::string &name) : meshSize(-1.), modelName(name), normals(0) {} + GModel() : modelName("Untitled"), normals(0) {} + GModel(const std::string &name) : modelName(name), normals(0) {} virtual ~GModel(){ deleteOCCInternals(); destroy(); } typedef std::set<GRegion*, GEntityLessThan>::iterator riter; @@ -146,11 +145,6 @@ class GModel // Deletes all the partitions virtual void deleteMeshPartitions(); - // Get or set the global mesh size for the model (default value is a - // tenth of the size of the domain) - double getMeshSize(); - void setMeshSize(const double s) { meshSize = s; } - // A container for smooth normals smooth_normals *normals; diff --git a/Geo/GModelIO_Fourier.cpp b/Geo/GModelIO_Fourier.cpp index 5aa3bccd4771fa340becf4610b8517ea1e9390fb..0592ebe2c296bb73c4114932e6a58fb290c49d09 100644 --- a/Geo/GModelIO_Fourier.cpp +++ b/Geo/GModelIO_Fourier.cpp @@ -835,7 +835,6 @@ int GModel::readFourier(const std::string &name) //return 1; // mesh each face using the standard gmsh algorithms - setMeshSize(0.05); std::for_each(firstFace(), lastFace(), meshGmsh()); return 1; diff --git a/Geo/GModelIO_Geo.cpp b/Geo/GModelIO_Geo.cpp index c4d4cfcd23c966e4309d83b220697fc7f3bb03b9..4bc86625ef51bbfa3e0d087009cfe6230f9f65ac 100644 --- a/Geo/GModelIO_Geo.cpp +++ b/Geo/GModelIO_Geo.cpp @@ -1,4 +1,4 @@ -// $Id: GModelIO_Geo.cpp,v 1.6 2007-01-12 13:16:59 remacle Exp $ +// $Id: GModelIO_Geo.cpp,v 1.7 2007-01-18 13:18:42 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -129,8 +129,6 @@ int GModel::importTHEM() } } - meshSize = 1.e22; - Msg(DEBUG, "Gmsh model imported:"); Msg(DEBUG, "%d Vertices", vertices.size()); Msg(DEBUG, "%d Edges", edges.size()); diff --git a/Geo/GModelIO_OCC.cpp b/Geo/GModelIO_OCC.cpp index 918eebd7a4d70e383b1d16d59924a605b3eedabb..9c2caaaed2e5b638670e2d7db23e49edfa6c3479 100644 --- a/Geo/GModelIO_OCC.cpp +++ b/Geo/GModelIO_OCC.cpp @@ -1,4 +1,4 @@ -// $Id: GModelIO_OCC.cpp,v 1.16 2007-01-17 08:14:23 geuzaine Exp $ +// $Id: GModelIO_OCC.cpp,v 1.17 2007-01-18 13:18:42 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -46,7 +46,6 @@ extern Context_T CTX; class OCC_Internals { TopoDS_Shape shape; TopTools_IndexedMapOfShape fmap, emap, vmap, somap, shmap, wmap; - double tolerance; public: OCC_Internals() { @@ -56,10 +55,10 @@ public: wmap.Clear(); emap.Clear(); vmap.Clear(); - tolerance = CTX.geom.tolerance; } - void HealGeometry(bool fixsmalledges = true, bool fixspotstripfaces = true, - bool sewfaces = false, bool makesolids = false); + void HealGeometry(double tolerance, bool fixsmalledges, + bool fixspotstripfaces, bool sewfaces, + bool makesolids=false); void loadSTEP(const char *); void loadIGES(const char *); void loadBREP(const char *); @@ -225,8 +224,9 @@ void OCC_Internals::buildLists() } -void OCC_Internals::HealGeometry(bool fixsmalledges, bool fixspotstripfaces, - bool sewfaces, bool makesolids) +void OCC_Internals::HealGeometry(double tolerance, bool fixsmalledges, + bool fixspotstripfaces, bool sewfaces, + bool makesolids) { int nrc = 0, nrcs = 0; TopExp_Explorer e; @@ -392,7 +392,10 @@ void OCC_Internals::loadBREP(const char *fn) BRepTools::Read(shape, (char*)fn, aBuilder); BRepTools::Clean(shape); buildLists(); - HealGeometry(); + HealGeometry(CTX.geom.tolerance, + CTX.geom.occ_fix_small_edges, + CTX.geom.occ_fix_small_faces, + CTX.geom.occ_sew_faces); BRepTools::Clean(shape); } @@ -405,7 +408,10 @@ void OCC_Internals::loadSTEP(const char *fn) shape = reader.OneShape(); BRepTools::Clean(shape); buildLists(); - HealGeometry(); + HealGeometry(CTX.geom.tolerance, + CTX.geom.occ_fix_small_edges, + CTX.geom.occ_fix_small_faces, + CTX.geom.occ_sew_faces); BRepTools::Clean(shape); } @@ -418,10 +424,10 @@ void OCC_Internals::loadIGES(const char *fn) shape = reader.OneShape(); BRepTools::Clean(shape); buildLists(); - HealGeometry(); - BRepTools::Clean(shape); - buildLists(); - HealGeometry(); + HealGeometry(CTX.geom.tolerance, + CTX.geom.occ_fix_small_edges, + CTX.geom.occ_fix_small_faces, + CTX.geom.occ_sew_faces); BRepTools::Clean(shape); } diff --git a/Geo/GVertex.cpp b/Geo/GVertex.cpp index bb617f40beb64690f834d50c9f3cea1a43802fb6..a915d4a1b9edeb38ef947b736e82ed510b848eb1 100644 --- a/Geo/GVertex.cpp +++ b/Geo/GVertex.cpp @@ -1,4 +1,4 @@ -// $Id: GVertex.cpp,v 1.11 2006-12-16 14:37:20 geuzaine Exp $ +// $Id: GVertex.cpp,v 1.12 2007-01-18 13:18:42 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -45,7 +45,7 @@ void GVertex::delEdge(GEdge *e) SPoint2 GVertex::reparamOnFace ( GFace *gf , int) const { - return gf->parFromPoint ( SPoint3(x(),y(),z() )); + return gf->parFromPoint(SPoint3(x(), y(), z())); } std::string GVertex::getAdditionalInfoString() diff --git a/Mesh/BackgroundMesh.cpp b/Mesh/BackgroundMesh.cpp index 8d91a2707b70610414808696bd01c5b93633fb53..e4a0e685e1b422610173f2ea14d63b1e305f197d 100644 --- a/Mesh/BackgroundMesh.cpp +++ b/Mesh/BackgroundMesh.cpp @@ -1,4 +1,4 @@ -// $Id: BackgroundMesh.cpp,v 1.12 2007-01-16 11:31:41 geuzaine Exp $ +// $Id: BackgroundMesh.cpp,v 1.13 2007-01-18 13:18:42 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -35,156 +35,8 @@ extern Context_T CTX; static OctreePost *BGM_OCTREE = NULL; static double BGM_MAX = 0.; -// computes the characteristic length of the -// mesh at a vertex in order to have the geometry -// captured with accuracy. A parameter called -// CTX.mesh.min_circ_points tells the minimum -// number of points per radius of curvature - -static double max_surf_curvature ( const GVertex *gv ) -{ - double max_curvature = 0; - std::list<GEdge*> l_edges = gv->edges(); - for (std::list<GEdge*> :: const_iterator ite = l_edges.begin() ; ite != l_edges.end() ; ++ite ) - { - GEdge *_myGEdge = *ite; - std::list<GFace *> faces = _myGEdge->faces(); - std::list<GFace *>::iterator it = faces.begin(); - while (it != faces.end()) - { - SPoint2 par = gv->reparamOnFace((*it),1); - double cc = (*it)->curvature ( par ); - max_curvature = std::max ( cc , max_curvature); - ++it; - } - } - return max_curvature; -} - -static double max_surf_curvature ( const GEdge *ge , double u) -{ - double max_curvature = 0; - std::list<GFace *> faces = ge->faces(); - std::list<GFace *>::iterator it = faces.begin(); - while (it != faces.end()) - { - SPoint2 par = ge->reparamOnFace((*it),u,1); - double cc = (*it)->curvature ( par ); - max_curvature = std::max ( cc , max_curvature); - ++it; - } - return max_curvature; -} - - -// the mesh vertex is classified on a model vertex. -// we compute the maximum of the curvature -// of model faces surrounding this point -// if it is classified on a model edge, -// we do the same for all model faces surrounding it -// if it is on a model face, we compute the curvature -// at this location - const double MAX_LC = 1.e22; -double LC_MVertex_CURV ( GEntity *ge, double U, double V ) -{ - double Crv=0; - switch (ge->dim ()) - { - case 0: - Crv = max_surf_curvature ( (const GVertex *)ge); - break; - case 1: - { - GEdge *ged = (GEdge *)ge; - //Crv = ged->curvature( U ); - Crv = max_surf_curvature ( ged, U); - } - break; - case 2: - { - GFace *gf = (GFace *)ge; - Crv = gf->curvature( SPoint2( U, V) ); - } - break; - } - - if (Crv > 0) return 2*M_PI/Crv/CTX.mesh.min_circ_points; - else return MAX_LC; -} - - -// compute the mesh size at a given -// vertex due to prescribed sizes at mesh vertices -double LC_MVertex_BGM ( GEntity *ge, double X, double Y, double Z ) -{ -// if (X > CTX.min[0] + 0.5 * (CTX.max[0] -CTX.min[0])) -// return 0.3*ge->model()->getMeshSize(); -// else -// return 1.e22; - if (BGMExists()) - { - return BGMXYZ(X,Y,Z); - } - else - return 1.e22; -} - -// compute the mesh size at a given -// vertex due to prescribed sizes at mesh vertices -double LC_MVertex_PNTS ( GEntity *ge, double U, double V ) -{ - double a; - switch (ge->dim ()) - { - case 0: - { - GVertex *gv = (GVertex *)ge; - return gv->prescribedMeshSizeAtVertex(); - } - case 1: - { - GEdge *ged = (GEdge *)ge; - GVertex *v1 = ged->getBeginVertex(); - GVertex *v2 = ged->getEndVertex(); - Range<double> range = ged->parBounds(0); - a = (U - range.low())/(range.high() - range.low()); - return (1-a) * v1->prescribedMeshSizeAtVertex() + (a) * v2->prescribedMeshSizeAtVertex() ; - } - default: - return 1.e22; - } -} - - - -double BGM_MeshSize ( GEntity *ge, double U, double V , double X, double Y, double Z) -{ - // FIXME - // This should be controlled by the interface - - if(CTX.mesh.bgmesh_type == ONFILE && !CTX.mesh.constrained_bgmesh){ - // unconstrained background mesh - return CTX.mesh.lc_factor * BGMXYZ(X,Y,Z) ; - } - - double l2 = 1.e22; - double l3 = ge->model()->getMeshSize(); - double l4 = LC_MVertex_BGM ( ge, X, Y , Z ); - if (ge->dim() < 2) l2 = LC_MVertex_PNTS ( ge, U, V ); - // printf("ge->dim() %d l2 = %g l4 = %g l3 = %g\n",ge->dim(),l2,l3,l4); - double l = std::min(std::min(l2,l4),l3); - - l *= CTX.mesh.lc_factor ; - double l1 = 1.e22; - - if(CTX.mesh.lc_from_curvature && ge->dim() < 3) - l1 = std::max(l3/100,LC_MVertex_CURV ( ge, U, V )); - - return std::min(l,l1) ; -} - int BGMWithView(Post_View * ErrView) { Msg(INFO, "Applying '%s' as background mesh", ErrView->Name); @@ -236,3 +88,131 @@ double BGMXYZ(double X, double Y, double Z) return l; } +// computes the characteristic length of the mesh at a vertex in order +// to have the geometry captured with accuracy. A parameter called +// CTX.mesh.min_circ_points tells the minimum number of points per +// radius of curvature + +static double max_surf_curvature(const GVertex *gv) +{ + double max_curvature = 0; + std::list<GEdge*> l_edges = gv->edges(); + for (std::list<GEdge*>::const_iterator ite = l_edges.begin(); + ite != l_edges.end(); ++ite){ + GEdge *_myGEdge = *ite; + std::list<GFace *> faces = _myGEdge->faces(); + std::list<GFace *>::iterator it = faces.begin(); + while (it != faces.end()){ + SPoint2 par = gv->reparamOnFace((*it),1); + double cc = (*it)->curvature ( par ); + max_curvature = std::max ( cc , max_curvature); + ++it; + } + } + return max_curvature; +} + +static double max_surf_curvature(const GEdge *ge, double u) +{ + double max_curvature = 0; + std::list<GFace *> faces = ge->faces(); + std::list<GFace *>::iterator it = faces.begin(); + while(it != faces.end()){ + SPoint2 par = ge->reparamOnFace((*it),u,1); + double cc = (*it)->curvature(par); + max_curvature = std::max(cc, max_curvature); + ++it; + } + return max_curvature; +} + +// the mesh vertex is classified on a model vertex. we compute the +// maximum of the curvature of model faces surrounding this point if +// it is classified on a model edge, we do the same for all model +// faces surrounding it if it is on a model face, we compute the +// curvature at this location + +double LC_MVertex_CURV(GEntity *ge, double U, double V) +{ + double Crv = 0; + switch(ge->dim()){ + case 0: + Crv = max_surf_curvature ( (const GVertex *)ge); + break; + case 1: + { + GEdge *ged = (GEdge *)ge; + //Crv = ged->curvature(U); + Crv = max_surf_curvature(ged, U); + } + break; + case 2: + { + GFace *gf = (GFace *)ge; + Crv = gf->curvature(SPoint2(U, V)); + } + break; + } + + if(Crv > 0) return 2*M_PI / Crv / CTX.mesh.min_circ_points; + else return MAX_LC; +} + +// compute the mesh size at a given vertex due to prescribed sizes at +// mesh vertices + +double LC_MVertex_BGM(GEntity *ge, double X, double Y, double Z) +{ + if(BGMExists()) + return BGMXYZ(X,Y,Z); + else + return MAX_LC; +} + +// compute the mesh size at a given vertex due to prescribed sizes at +// mesh vertices +double LC_MVertex_PNTS(GEntity *ge, double U, double V) +{ + double a; + switch(ge->dim()){ + case 0: + { + GVertex *gv = (GVertex *)ge; + return gv->prescribedMeshSizeAtVertex(); + } + case 1: + { + GEdge *ged = (GEdge *)ge; + GVertex *v1 = ged->getBeginVertex(); + GVertex *v2 = ged->getEndVertex(); + Range<double> range = ged->parBounds(0); + a = (U - range.low())/(range.high() - range.low()); + return (1-a) * v1->prescribedMeshSizeAtVertex() + + (a) * v2->prescribedMeshSizeAtVertex() ; + } + default: + return MAX_LC; + } +} + +double BGM_MeshSize(GEntity *ge, double U, double V, double X, double Y, double Z) +{ + // unconstrained background mesh + if(CTX.mesh.bgmesh_type == ONFILE && !CTX.mesh.constrained_bgmesh){ + return CTX.mesh.lc_factor * BGMXYZ(X, Y, Z); + } + + double l2 = MAX_LC; + double l3 = CTX.lc / 10.; + double l4 = LC_MVertex_BGM(ge, X, Y, Z); + if(ge->dim() < 2) l2 = LC_MVertex_PNTS(ge, U, V); + double l = std::min(std::min(l2, l4), l3); + + l *= CTX.mesh.lc_factor ; + double l1 = MAX_LC; + + if(CTX.mesh.lc_from_curvature && ge->dim() < 3) + l1 = std::max(l3/100, LC_MVertex_CURV(ge, U, V)); + + return std::min(l, l1) ; +} diff --git a/Mesh/BackgroundMesh.h b/Mesh/BackgroundMesh.h index 421bd82fc485b4504e3a8572b2995832f7427a70..7be7861bff0901dbf96ac6332021f86d2a3834f3 100644 --- a/Mesh/BackgroundMesh.h +++ b/Mesh/BackgroundMesh.h @@ -20,11 +20,11 @@ // // Please report all bugs and problems to <gmsh@geuz.org>. - #define ONFILE 2 #define WITHPOINTS 3 + class GEntity; -double BGMXYZ(double X, double Y, double Z); +double BGM_MeshSize(GEntity *ge, double U, double V, double X, double Y, double Z); int BGMExists(); -double BGM_MeshSize (GEntity *ge, double U, double V, double X, double Y, double Z); + #endif diff --git a/Parser/OpenFile.cpp b/Parser/OpenFile.cpp index ea629b52bff11035e0f1f3e5e21af418395518ed..845e4a7a27552e3dc5ecf47901a1b9d203214dd3 100644 --- a/Parser/OpenFile.cpp +++ b/Parser/OpenFile.cpp @@ -1,4 +1,4 @@ -// $Id: OpenFile.cpp,v 1.139 2007-01-17 08:14:24 geuzaine Exp $ +// $Id: OpenFile.cpp,v 1.140 2007-01-18 13:18:42 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -384,11 +384,6 @@ int MergeFile(char *name, int warn_if_missing) SetBoundingBox(); - SBoundingBox3d bb; - bb = GMODEL->bounds(); - if (GMODEL->getMeshSize() < 0) - GMODEL->setMeshSize(0.1 * norm( SVector3 ( bb.max() , bb.min() ))); - CTX.geom.draw = 1; CTX.mesh.changed = ENT_ALL;