From b1ee3b8a3b23214615a9b1621ae0d7d918299090 Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Wed, 5 Oct 2011 06:27:58 +0000 Subject: [PATCH] don't try to remove degenerated edges by default: it fails on some geometries --- Common/Context.h | 3 +- Common/DefaultOptions.h | 2 + Common/Options.cpp | 13 ++++ Common/Options.h | 1 + Fltk/onelabWindow.cpp | 2 +- Fltk/optionWindow.cpp | 16 +++-- Fltk/optionWindow.h | 2 - Geo/GModelIO_OCC.cpp | 132 +++++++++++++++++++++------------------- Geo/GModelIO_OCC.h | 7 ++- 9 files changed, 104 insertions(+), 74 deletions(-) diff --git a/Common/Context.h b/Common/Context.h index ed2f660b18..e21dfda744 100644 --- a/Common/Context.h +++ b/Common/Context.h @@ -49,7 +49,8 @@ struct contextGeometryOptions { double normals, tangents, scalingFactor; int autoCoherence, highlightOrphans, clip, useTransform; double tolerance, snap[3], transform[3][3], offset[3]; - int occFixSmallEdges, occFixSmallFaces, occSewFaces, occConnectFaces; + int occFixDegenerated, occFixSmallEdges, occFixSmallFaces; + int occSewFaces, occConnectFaces; int copyMeshingMethod, exactExtrusion; int matchGeomAndMesh; }; diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h index f7d827326d..caf185bfb3 100644 --- a/Common/DefaultOptions.h +++ b/Common/DefaultOptions.h @@ -920,6 +920,8 @@ StringXNumber GeometryOptions_Number[] = { { F|O, "NumSubEdges" , opt_geometry_num_sub_edges , 20. , "Number of edge subdivisions between control points when displaying curves" }, + { F|O, "OCCFixDegenerated" , opt_geometry_occ_fix_degenerated , 0. , + "Fix degenerated edges/faces in STEP, IGES and BRep models" }, { F|O, "OCCFixSmallEdges" , opt_geometry_occ_fix_small_edges , 0. , "Fix small edges in STEP, IGES and BRep models" }, { F|O, "OCCFixSmallFaces" , opt_geometry_occ_fix_small_faces , 0. , diff --git a/Common/Options.cpp b/Common/Options.cpp index 877d39fbac..257af24d08 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -4680,6 +4680,19 @@ double opt_geometry_light_two_side(OPT_ARGS_NUM) return CTX::instance()->geom.lightTwoSide; } +double opt_geometry_occ_fix_degenerated(OPT_ARGS_NUM) +{ + if(action & GMSH_SET) + CTX::instance()->geom.occFixDegenerated = val ? 1 : 0; +#if defined(HAVE_FLTK) + if(FlGui::available() && (action & GMSH_GUI)) { + FlGui::instance()->options->geo.butt[16]->value + (CTX::instance()->geom.occFixDegenerated); + } +#endif + return CTX::instance()->geom.occFixSmallEdges; +} + double opt_geometry_occ_fix_small_edges(OPT_ARGS_NUM) { if(action & GMSH_SET) diff --git a/Common/Options.h b/Common/Options.h index e80389fc05..fe5cb6cfd6 100644 --- a/Common/Options.h +++ b/Common/Options.h @@ -443,6 +443,7 @@ double opt_geometry_line_type(OPT_ARGS_NUM); double opt_geometry_surface_type(OPT_ARGS_NUM); double opt_geometry_light(OPT_ARGS_NUM); double opt_geometry_light_two_side(OPT_ARGS_NUM); +double opt_geometry_occ_fix_degenerated(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); diff --git a/Fltk/onelabWindow.cpp b/Fltk/onelabWindow.cpp index a610052754..ac5c15f860 100644 --- a/Fltk/onelabWindow.cpp +++ b/Fltk/onelabWindow.cpp @@ -187,7 +187,7 @@ bool onelab::localNetworkClient::run(const std::string &what) default: Msg::Warning("Received unknown message type (%d)", type); break; - } + } FlGui::instance()->check(); } diff --git a/Fltk/optionWindow.cpp b/Fltk/optionWindow.cpp index 93c1111885..d224d43ad2 100644 --- a/Fltk/optionWindow.cpp +++ b/Fltk/optionWindow.cpp @@ -378,7 +378,7 @@ static void geometry_options_ok_cb(Fl_Widget *w, void *data) opt_geometry_auto_coherence(0, GMSH_SET, o->geo.butt[8]->value()); opt_geometry_light(0, GMSH_SET, o->geo.butt[9]->value()); opt_geometry_highlight_orphans(0, GMSH_SET, o->geo.butt[10]->value()); - opt_geometry_occ_fix_small_edges(0, GMSH_SET, o->geo.butt[11]->value()); + opt_geometry_occ_fix_degenerated(0, GMSH_SET, o->geo.butt[16]->value()); opt_geometry_occ_fix_small_faces(0, GMSH_SET, o->geo.butt[12]->value()); opt_geometry_occ_sew_faces(0, GMSH_SET, o->geo.butt[13]->value()); opt_geometry_light_two_side(0, GMSH_SET, o->geo.butt[14]->value()); @@ -1796,28 +1796,34 @@ optionWindow::optionWindow(int deltaFontSize) (FL_NO_BOX, L + 2 * WB, 2 * WB + 3 * BH + 1, IW, BH, "Open CASCADE model healing options (experimental):"); b2->align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT); + geo.butt[16] = new Fl_Check_Button + (L + 2 * WB, 2 * WB + 4 * BH, BW, BH, "Remove degenerated edges and faces"); + geo.butt[16]->type(FL_TOGGLE_BUTTON); + geo.butt[16]->callback(geometry_options_ok_cb); + geo.butt[11] = new Fl_Check_Button - (L + 2 * WB, 2 * WB + 4 * BH, BW, BH, "Remove small edges"); + (L + 2 * WB, 2 * WB + 5 * BH, BW, BH, "Remove small edges"); geo.butt[11]->type(FL_TOGGLE_BUTTON); geo.butt[11]->callback(geometry_options_ok_cb); geo.butt[12] = new Fl_Check_Button - (L + 2 * WB, 2 * WB + 5 * BH, BW, BH, "Remove small faces"); + (L + 2 * WB, 2 * WB + 6 * BH, BW, BH, "Remove small faces"); geo.butt[12]->type(FL_TOGGLE_BUTTON); geo.butt[12]->callback(geometry_options_ok_cb); geo.butt[13] = new Fl_Check_Button - (L + 2 * WB, 2 * WB + 6 * BH, BW, BH, "Sew faces"); + (L + 2 * WB, 2 * WB + 7 * BH, BW, BH, "Sew faces"); geo.butt[13]->type(FL_TOGGLE_BUTTON); geo.butt[13]->callback(geometry_options_ok_cb); geo.butt[15] = new Fl_Check_Button - (L + 2 * WB, 2 * WB + 7 * BH, BW, BH, "Cut and merge faces"); + (L + 2 * WB, 2 * WB + 8 * BH, BW, BH, "Cut and merge faces"); geo.butt[15]->type(FL_TOGGLE_BUTTON); geo.butt[15]->callback(geometry_options_ok_cb); #if !defined(HAVE_OCC) b2->deactivate(); + geo.butt[16]->deactivate(); geo.butt[11]->deactivate(); geo.butt[12]->deactivate(); geo.butt[13]->deactivate(); diff --git a/Fltk/optionWindow.h b/Fltk/optionWindow.h index ddf67bde7e..048fc8ac61 100644 --- a/Fltk/optionWindow.h +++ b/Fltk/optionWindow.h @@ -21,8 +21,6 @@ #include "spherePositionWidget.h" #include "colorbarWindow.h" - - #define NUM_FONTS 14 extern Fl_Menu_Item menu_font_names[]; diff --git a/Geo/GModelIO_OCC.cpp b/Geo/GModelIO_OCC.cpp index 88969c506e..4d80c00183 100644 --- a/Geo/GModelIO_OCC.cpp +++ b/Geo/GModelIO_OCC.cpp @@ -207,10 +207,15 @@ void OCC_Internals::addShapeToLists(TopoDS_Shape _shape) } -void OCC_Internals::healGeometry(double tolerance, bool fixsmalledges, - bool fixspotstripfaces, bool sewfaces, - bool makesolids, bool connect) +void OCC_Internals::healGeometry(double tolerance, bool fixdegenerated, + bool fixsmalledges, bool fixspotstripfaces, + bool sewfaces, bool makesolids, bool connect) { + if(!fixdegenerated && !fixsmalledges && !fixspotstripfaces && + !sewfaces && !makesolids && !connect) return; + + Msg::Info("Starting geometry healing procedure (tolerance: %g)", tolerance); + buildLists(); TopExp_Explorer exp0, exp1; int nrc = 0, nrcs = 0; @@ -218,21 +223,7 @@ void OCC_Internals::healGeometry(double tolerance, bool fixsmalledges, int nrw = wmap.Extent(), nre = emap.Extent(), nrv = vmap.Extent(); for (exp0.Init(shape, TopAbs_COMPOUND); exp0.More(); exp0.Next()) nrc++; for (exp0.Init(shape, TopAbs_COMPSOLID); exp0.More(); exp0.Next()) nrcs++; - - Msg::Info("Starting geometry healing procedure (tolerance: %g)", tolerance); - - { - Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; - rebuild->Apply(shape); - for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()){ - TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); - if(BRep_Tool::Degenerated(edge)) - rebuild->Remove(edge, false); - } - shape = rebuild->Apply(shape); - } - buildLists(); - + double surfacecont = 0; for (exp0.Init(shape, TopAbs_FACE); exp0.More(); exp0.Next()){ TopoDS_Face face = TopoDS::Face(exp0.Current()); @@ -241,55 +232,69 @@ void OCC_Internals::healGeometry(double tolerance, bool fixsmalledges, surfacecont += system.Mass(); } - { - Msg::Info("- repairing faces"); - - Handle(ShapeFix_Face) sff; - Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; - rebuild->Apply(shape); + if (fixdegenerated){ + Msg::Info("- fix degenerated edges and faces"); - for (exp0.Init (shape, TopAbs_FACE); exp0.More(); exp0.Next()){ - TopoDS_Face face = TopoDS::Face(exp0.Current()); + { + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Apply(shape); + for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()){ + TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); + if(BRep_Tool::Degenerated(edge)) + rebuild->Remove(edge, false); + } + shape = rebuild->Apply(shape); + } + buildLists(); - sff = new ShapeFix_Face (face); - sff->FixAddNaturalBoundMode() = Standard_True; - sff->FixSmallAreaWireMode() = Standard_True; - sff->Perform(); + { + Handle(ShapeFix_Face) sff; + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Apply(shape); - if(sff->Status(ShapeExtend_DONE1) || - sff->Status(ShapeExtend_DONE2) || - sff->Status(ShapeExtend_DONE3) || - sff->Status(ShapeExtend_DONE4) || - sff->Status(ShapeExtend_DONE5)) - { - Msg::Info(" repaired face %d", fmap.FindIndex(face)); - if(sff->Status(ShapeExtend_DONE1)) - Msg::Info(" (some wires are fixed)"); - else if(sff->Status(ShapeExtend_DONE2)) - Msg::Info(" (orientation of wires fixed)"); - else if(sff->Status(ShapeExtend_DONE3)) - Msg::Info(" (missing seam added)"); - else if(sff->Status(ShapeExtend_DONE4)) - Msg::Info(" (small area wire removed)"); - else if(sff->Status(ShapeExtend_DONE5)) - Msg::Info(" (natural bounds added)"); - TopoDS_Face newface = sff->Face(); - - rebuild->Replace(face, newface, Standard_False); - } + for (exp0.Init (shape, TopAbs_FACE); exp0.More(); exp0.Next()){ + TopoDS_Face face = TopoDS::Face(exp0.Current()); + + sff = new ShapeFix_Face (face); + sff->FixAddNaturalBoundMode() = Standard_True; + sff->FixSmallAreaWireMode() = Standard_True; + sff->Perform(); + + if(sff->Status(ShapeExtend_DONE1) || + sff->Status(ShapeExtend_DONE2) || + sff->Status(ShapeExtend_DONE3) || + sff->Status(ShapeExtend_DONE4) || + sff->Status(ShapeExtend_DONE5)) + { + Msg::Info(" repaired face %d", fmap.FindIndex(face)); + if(sff->Status(ShapeExtend_DONE1)) + Msg::Info(" (some wires are fixed)"); + else if(sff->Status(ShapeExtend_DONE2)) + Msg::Info(" (orientation of wires fixed)"); + else if(sff->Status(ShapeExtend_DONE3)) + Msg::Info(" (missing seam added)"); + else if(sff->Status(ShapeExtend_DONE4)) + Msg::Info(" (small area wire removed)"); + else if(sff->Status(ShapeExtend_DONE5)) + Msg::Info(" (natural bounds added)"); + TopoDS_Face newface = sff->Face(); + + rebuild->Replace(face, newface, Standard_False); + } + } + shape = rebuild->Apply(shape); } - shape = rebuild->Apply(shape); - } - - { - Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; - rebuild->Apply(shape); - for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()){ - TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); - if ( BRep_Tool::Degenerated(edge) ) - rebuild->Remove(edge, false); + + { + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Apply(shape); + for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()){ + TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); + if (BRep_Tool::Degenerated(edge)) + rebuild->Remove(edge, false); + } + shape = rebuild->Apply(shape); } - shape = rebuild->Apply(shape); } if (fixsmalledges){ @@ -549,6 +554,7 @@ void OCC_Internals::loadBREP(const char *fn) BRepTools::Read(shape, (char*)fn, aBuilder); BRepTools::Clean(shape); healGeometry(CTX::instance()->geom.tolerance, + CTX::instance()->geom.occFixDegenerated, CTX::instance()->geom.occFixSmallEdges, CTX::instance()->geom.occFixSmallFaces, CTX::instance()->geom.occSewFaces, @@ -580,6 +586,7 @@ void OCC_Internals::loadSTEP(const char *fn) shape = reader.OneShape(); BRepTools::Clean(shape); healGeometry(CTX::instance()->geom.tolerance, + CTX::instance()->geom.occFixDegenerated, CTX::instance()->geom.occFixSmallEdges, CTX::instance()->geom.occFixSmallFaces, CTX::instance()->geom.occSewFaces, @@ -606,6 +613,7 @@ void OCC_Internals::loadIGES(const char *fn) shape = reader.OneShape(); BRepTools::Clean(shape); healGeometry(CTX::instance()->geom.tolerance, + CTX::instance()->geom.occFixDegenerated, CTX::instance()->geom.occFixSmallEdges, CTX::instance()->geom.occFixSmallFaces, CTX::instance()->geom.occSewFaces, diff --git a/Geo/GModelIO_OCC.h b/Geo/GModelIO_OCC.h index 487d0a061e..f3142057eb 100644 --- a/Geo/GModelIO_OCC.h +++ b/Geo/GModelIO_OCC.h @@ -32,9 +32,10 @@ class OCC_Internals { void buildLists(); void buildShapeFromLists(TopoDS_Shape _shape); void addShapeToLists(TopoDS_Shape shape); - void healGeometry(double tolerance, bool fixsmalledges, - bool fixspotstripfaces, bool sewfaces, - bool makesolids=false, bool connect=false); + void healGeometry(double tolerance, bool fixdegenerated, + bool fixsmalledges, bool fixspotstripfaces, + bool sewfaces, bool makesolids=false, + bool connect=false); void loadBREP(const char *); void writeBREP(const char *); void loadSTEP(const char *); -- GitLab