From b9de5da49fcb9b66da0bd9e716347779cdba30fd Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Sat, 16 Feb 2008 22:25:13 +0000 Subject: [PATCH] consistent surf display options and defaults --- Common/DefaultOptions.h | 4 +- Common/Options.cpp | 4 +- Fltk/GUI.cpp | 5 +- Geo/GFace.cpp | 75 ++++++++++++- Geo/GFace.h | 3 + Graphics/Geom.cpp | 240 ++++++++++++++++------------------------ 6 files changed, 181 insertions(+), 150 deletions(-) diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h index be1f5cc07c..e04889cc3d 100644 --- a/Common/DefaultOptions.h +++ b/Common/DefaultOptions.h @@ -861,8 +861,8 @@ StringXNumber GeometryOptions_Number[] = { "Display geometry surfaces?" }, { F|O, "SurfaceNumbers" , opt_geometry_surfaces_num , 0. , "Display surface numbers?" }, - { F|O, "SurfaceType" , opt_geometry_surface_type , 1. , - "Display surfaces as wireframe (0) or solid (1)" }, + { F|O, "SurfaceType" , opt_geometry_surface_type , 2. , + "Surface display type (0=cross, 1=wireframe, 2=solid" }, { F|O, "Tangents" , opt_geometry_tangents , 0. , "Display size of tangent vectors (in pixels)" }, diff --git a/Common/Options.cpp b/Common/Options.cpp index d67e17c82f..e28e864409 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -1,4 +1,4 @@ -// $Id: Options.cpp,v 1.380 2008-01-30 15:27:40 remacle Exp $ +// $Id: Options.cpp,v 1.381 2008-02-16 22:25:12 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -4077,6 +4077,8 @@ double opt_geometry_surface_type(OPT_ARGS_NUM) { if(action & GMSH_SET) { CTX.geom.surface_type = (int)val; + if(CTX.geom.surface_type < 0 || CTX.geom.surface_type > 2) + CTX.geom.surface_type = 0; } #if defined(HAVE_FLTK) if(WID && (action & GMSH_GUI)) { diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp index beaeca6b10..bb2ae978f0 100644 --- a/Fltk/GUI.cpp +++ b/Fltk/GUI.cpp @@ -1,4 +1,4 @@ -// $Id: GUI.cpp,v 1.652 2008-02-05 21:03:13 geuzaine Exp $ +// $Id: GUI.cpp,v 1.653 2008-02-16 22:25:12 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -367,6 +367,7 @@ static Fl_Menu_Item menu_line_display_post[] = { }; static Fl_Menu_Item menu_surface_display[] = { + {"Cross", 0, 0, 0}, {"Wireframe", 0, 0, 0}, {"Solid", 0, 0, 0}, {0} @@ -745,7 +746,7 @@ int GUI::global_shortcuts(int event) } else if(Fl::test_shortcut(FL_ALT + 'd')){ opt_geometry_surface_type(0, GMSH_SET | GMSH_GUI, - !opt_geometry_surface_type(0, GMSH_GET, 0)); + opt_geometry_surface_type(0, GMSH_GET, 0) + 1); redraw_opengl(); return 1; } diff --git a/Geo/GFace.cpp b/Geo/GFace.cpp index 07b1fa982f..593f7e6f0e 100644 --- a/Geo/GFace.cpp +++ b/Geo/GFace.cpp @@ -1,4 +1,4 @@ -// $Id: GFace.cpp,v 1.48 2008-02-07 13:17:18 geuzaine Exp $ +// $Id: GFace.cpp,v 1.49 2008-02-16 22:25:13 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -542,6 +542,79 @@ SPoint2 GFace::parFromPoint(const SPoint3 &p) const return SPoint2(U,V); } +bool GFace::buildRepresentationCross() +{ + if(geomType() != Plane){ + // don't try again + cross.clear(); + cross.push_back(SPoint3(0., 0., 0.)); + return false; + } + + std::list<GEdge*> ed = edges(); + SBoundingBox3d bb; + for(std::list<GEdge*>::iterator it = ed.begin(); it != ed.end(); it++){ + GEdge *ge = *it; + if(ge->geomType() == GEntity::DiscreteCurve || + ge->geomType() == GEntity::BoundaryLayerCurve){ + // don't try again + cross.clear(); + cross.push_back(SPoint3(0., 0., 0.)); + return false; + } + else{ + Range<double> t_bounds = ge->parBounds(0); + GPoint p[3] = {ge->point(t_bounds.low()), + ge->point(0.5 * (t_bounds.low() + t_bounds.high())), + ge->point(t_bounds.high())}; + for(int i = 0; i < 3; i++){ + SPoint2 uv = parFromPoint(SPoint3(p[i].x(), p[i].y(), p[i].z())); + bb += SPoint3(uv.x(), uv.y(), 0.); + } + } + } + bb *= 1.1; + GPoint v0 = point(bb.min().x(), bb.min().y()); + GPoint v1 = point(bb.max().x(), bb.min().y()); + GPoint v2 = point(bb.max().x(), bb.max().y()); + GPoint v3 = point(bb.min().x(), bb.max().y()); + const int N = 100; + for(int dir = 0; dir < 2; dir++) { + int end_line = 0; + SPoint3 pt, pt_last_inside; + for(int i = 0; i < N; i++) { + double t = (double)i / (double)(N - 1); + double x, y, z; + if(!dir){ + x = 0.5 * (t * (v0.x() + v1.x()) + (1. - t) * (v2.x() + v3.x())); + y = 0.5 * (t * (v0.y() + v1.y()) + (1. - t) * (v2.y() + v3.y())); + z = 0.5 * (t * (v0.z() + v1.z()) + (1. - t) * (v2.z() + v3.z())); + } + else{ + x = 0.5 * (t * (v0.x() + v3.x()) + (1. - t) * (v2.x() + v1.x())); + y = 0.5 * (t * (v0.y() + v3.y()) + (1. - t) * (v2.y() + v1.y())); + z = 0.5 * (t * (v0.z() + v3.z()) + (1. - t) * (v2.z() + v1.z())); + } + pt.setPosition(x, y, z); + if(containsPoint(pt)){ + pt_last_inside.setPosition(x, y, z); + if(!end_line) { cross.push_back(pt); end_line = 1; } + } + else { + if(end_line) { cross.push_back(pt_last_inside); end_line = 0; } + } + } + if(end_line) cross.push_back(pt_last_inside); + } + // if we couldn't determine a cross, add a dummy point so that + // we won't try again + if(!cross.size()){ + cross.push_back(SPoint3(0., 0., 0.)); + return false; + } + return true; +} + struct graphics_point{ double xyz[3]; SVector3 n; diff --git a/Geo/GFace.h b/Geo/GFace.h index d5cd90d7c9..e8ff468a15 100644 --- a/Geo/GFace.h +++ b/Geo/GFace.h @@ -136,6 +136,9 @@ class GFace : public GEntity // Returns a type-specific additional information string virtual std::string getAdditionalInfoString(); + // Fills the crude representation cross + bool GFace::buildRepresentationCross(); + // Builds a STL triangulation and fills the vertex array // va_geom_triangles virtual bool buildSTLTriangulation(); diff --git a/Graphics/Geom.cpp b/Graphics/Geom.cpp index 430a84fce3..4f89fe3b41 100644 --- a/Graphics/Geom.cpp +++ b/Graphics/Geom.cpp @@ -1,4 +1,4 @@ -// $Id: Geom.cpp,v 1.149 2008-02-05 23:16:44 geuzaine Exp $ +// $Id: Geom.cpp,v 1.150 2008-02-16 22:25:13 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -203,35 +203,78 @@ class drawGEdge { class drawGFace { private: + void _drawVertexArray(VertexArray *va, bool useNormalArray, int forceColor=0, + unsigned int color=0) + { + if(!va) return; + glVertexPointer(3, GL_FLOAT, 0, va->getVertexArray()); + glNormalPointer(GL_BYTE, 0, va->getNormalArray()); + glColorPointer(4, GL_UNSIGNED_BYTE, 0, va->getColorArray()); + glEnableClientState(GL_VERTEX_ARRAY); + if(useNormalArray){ + glEnable(GL_LIGHTING); + glEnableClientState(GL_NORMAL_ARRAY); + } + else + glDisableClientState(GL_NORMAL_ARRAY); + if(forceColor){ + glDisableClientState(GL_COLOR_ARRAY); + glColor4ubv((GLubyte *) & color); + } + else{ + glEnableClientState(GL_COLOR_ARRAY); + } + if(CTX.polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL); + if(CTX.geom.surface_type > 1) + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + else + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glDrawArrays(GL_TRIANGLES, 0, va->getNumVertices()); + glDisable(GL_POLYGON_OFFSET_FILL); + glDisable(GL_LIGHTING); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + } void _drawParametricGFace(GFace *f) { - if(CTX.geom.surfaces && !f->va_geom_triangles) { - glEnable(GL_LINE_STIPPLE); - glLineStipple(1, 0x1F1F); - gl2psEnable(GL2PS_LINE_STIPPLE); - int N = 20; - Range<double> ubounds = f->parBounds(0); - Range<double> vbounds = f->parBounds(1); - const double uav = 0.5 * (ubounds.high() + ubounds.low()); - const double vav = 0.5 * (vbounds.high() + vbounds.low()); - const double ud = (ubounds.high() - ubounds.low()); - const double vd = (vbounds.high() - vbounds.low()); - glBegin(GL_LINE_STRIP); - for(int i = 0; i < N; i++) { - GPoint p = f->point(ubounds.low() + ud * (double)i / (double)(N - 1), vav); - glVertex3d(p.x(), p.y(), p.z()); + if(CTX.geom.surfaces){ + if(CTX.geom.surface_type > 0 && f->va_geom_triangles){ + _drawVertexArray + (f->va_geom_triangles, CTX.geom.light, + (f->geomType() == GEntity::ProjectionFace) ? true : f->getSelection(), + (f->geomType() == GEntity::ProjectionFace) ? CTX.color.geom.projection : + CTX.color.geom.selection); } - glEnd(); - glBegin(GL_LINE_STRIP); - for(int i = 0; i < N; i++) { - GPoint p = f->point(uav, vbounds.low() + vd * (double)i / (double)(N - 1)); - glVertex3d(p.x(), p.y(), p.z()); + else{ + glEnable(GL_LINE_STIPPLE); + glLineStipple(1, 0x1F1F); + gl2psEnable(GL2PS_LINE_STIPPLE); + int N = 20; + Range<double> ubounds = f->parBounds(0); + Range<double> vbounds = f->parBounds(1); + const double uav = 0.5 * (ubounds.high() + ubounds.low()); + const double vav = 0.5 * (vbounds.high() + vbounds.low()); + const double ud = (ubounds.high() - ubounds.low()); + const double vd = (vbounds.high() - vbounds.low()); + glBegin(GL_LINE_STRIP); + for(int i = 0; i < N; i++) { + GPoint p = f->point(ubounds.low() + ud * (double)i / (double)(N - 1), vav); + glVertex3d(p.x(), p.y(), p.z()); + } + glEnd(); + glBegin(GL_LINE_STRIP); + for(int i = 0; i < N; i++) { + GPoint p = f->point(uav, vbounds.low() + vd * (double)i / (double)(N - 1)); + glVertex3d(p.x(), p.y(), p.z()); + } + glEnd(); + glDisable(GL_LINE_STIPPLE); + gl2psDisable(GL2PS_LINE_STIPPLE); } - glEnd(); - glDisable(GL_LINE_STIPPLE); - gl2psDisable(GL2PS_LINE_STIPPLE); } - + if(CTX.geom.surfaces_num) { GPoint p = f->point(0.5, 0.5); char Num[100]; @@ -256,88 +299,39 @@ class drawGFace { } void _drawPlaneGFace(GFace *f) { - // We create data here and the routine is not designed to be - // reentrant, so we must lock it to avoid race conditions when - // redraw events are fired in rapid succession - static bool busy = false; - if(!f->cross.size() && !busy) { - busy = true; - std::list<GEdge*> edges = f->edges(); - SBoundingBox3d bb; - for(std::list<GEdge*>::iterator it = edges.begin(); it != edges.end(); it++){ - GEdge *ge = *it; - if(ge->geomType() == GEntity::DiscreteCurve || - ge->geomType() == GEntity::BoundaryLayerCurve){ - // don't try again - f->cross.clear(); - f->cross.push_back(SPoint3(0., 0., 0.)); - busy = false; - return; - } - else{ - Range<double> t_bounds = ge->parBounds(0); - GPoint p[3] = {ge->point(t_bounds.low()), - ge->point(0.5 * (t_bounds.low() + t_bounds.high())), - ge->point(t_bounds.high())}; - for(int i = 0; i < 3; i++){ - SPoint2 uv = f->parFromPoint(SPoint3(p[i].x(), p[i].y(), p[i].z())); - bb += SPoint3(uv.x(), uv.y(), 0.); - } - } - } - bb *= 1.1; - GPoint v0 = f->point(bb.min().x(), bb.min().y()); - GPoint v1 = f->point(bb.max().x(), bb.min().y()); - GPoint v2 = f->point(bb.max().x(), bb.max().y()); - GPoint v3 = f->point(bb.min().x(), bb.max().y()); - const int N = 100; - for(int dir = 0; dir < 2; dir++) { - int end_line = 0; - SPoint3 pt, pt_last_inside; - for(int i = 0; i < N; i++) { - double t = (double)i / (double)(N - 1); - double x, y, z; - if(!dir){ - x = 0.5 * (t * (v0.x() + v1.x()) + (1. - t) * (v2.x() + v3.x())); - y = 0.5 * (t * (v0.y() + v1.y()) + (1. - t) * (v2.y() + v3.y())); - z = 0.5 * (t * (v0.z() + v1.z()) + (1. - t) * (v2.z() + v3.z())); - } - else{ - x = 0.5 * (t * (v0.x() + v3.x()) + (1. - t) * (v2.x() + v1.x())); - y = 0.5 * (t * (v0.y() + v3.y()) + (1. - t) * (v2.y() + v1.y())); - z = 0.5 * (t * (v0.z() + v3.z()) + (1. - t) * (v2.z() + v1.z())); - } - pt.setPosition(x, y, z); - if(f->containsPoint(pt)){ - pt_last_inside.setPosition(x, y, z); - if(!end_line) { f->cross.push_back(pt); end_line = 1; } - } - else { - if(end_line) { f->cross.push_back(pt_last_inside); end_line = 0; } - } - } - if(end_line) f->cross.push_back(pt_last_inside); + if(!CTX.geom.surface_type || !f->va_geom_triangles || + CTX.geom.surfaces_num || CTX.geom.normals){ + // We create data here and the routine is not designed to be + // reentrant, so we must lock it to avoid race conditions when + // redraw events are fired in rapid succession + static bool busy = false; + if(!f->cross.size() && !busy) { + busy = true; + f->buildRepresentationCross(); + busy = false; } - // if we couldn't determine a cross, add a dummy point so that - // we won't try again - if(!f->cross.size()) f->cross.push_back(SPoint3(0., 0., 0.)); - busy = false; } - if(f->cross.size() < 2) return; - - if(CTX.geom.surfaces && !f->va_geom_triangles) { - glEnable(GL_LINE_STIPPLE); - glLineStipple(1, 0x1F1F); - gl2psEnable(GL2PS_LINE_STIPPLE); - glBegin(GL_LINES); - for(unsigned int i = 0; i < f->cross.size(); i++) - glVertex3d(f->cross[i].x(), f->cross[i].y(), f->cross[i].z()); - glEnd(); - glDisable(GL_LINE_STIPPLE); - gl2psDisable(GL2PS_LINE_STIPPLE); + if(CTX.geom.surfaces) { + if(CTX.geom.surface_type > 0 && f->va_geom_triangles){ + _drawVertexArray(f->va_geom_triangles, CTX.geom.light, + f->getSelection(), CTX.color.geom.selection); + } + else{ + glEnable(GL_LINE_STIPPLE); + glLineStipple(1, 0x1F1F); + gl2psEnable(GL2PS_LINE_STIPPLE); + glBegin(GL_LINES); + for(unsigned int i = 0; i < f->cross.size(); i++) + glVertex3d(f->cross[i].x(), f->cross[i].y(), f->cross[i].z()); + glEnd(); + glDisable(GL_LINE_STIPPLE); + gl2psDisable(GL2PS_LINE_STIPPLE); + } } + if(f->cross.size() < 2) return; + if(CTX.geom.surfaces_num) { char Num[100]; sprintf(Num, "%d", f->tag()); @@ -362,40 +356,6 @@ class drawGFace { p.x(), p.y(), p.z(), n[0], n[1], n[2], CTX.geom.light); } } - void _drawVertexArray(VertexArray *va, bool useNormalArray, int forceColor=0, - unsigned int color=0) - { - if(!va) return; - glVertexPointer(3, GL_FLOAT, 0, va->getVertexArray()); - glNormalPointer(GL_BYTE, 0, va->getNormalArray()); - glColorPointer(4, GL_UNSIGNED_BYTE, 0, va->getColorArray()); - glEnableClientState(GL_VERTEX_ARRAY); - if(useNormalArray){ - glEnable(GL_LIGHTING); - glEnableClientState(GL_NORMAL_ARRAY); - } - else - glDisableClientState(GL_NORMAL_ARRAY); - if(forceColor){ - glDisableClientState(GL_COLOR_ARRAY); - glColor4ubv((GLubyte *) & color); - } - else{ - glEnableClientState(GL_COLOR_ARRAY); - } - if(CTX.polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL); - if(CTX.geom.surface_type > 0) - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - else - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - glDrawArrays(GL_TRIANGLES, 0, va->getNumVertices()); - glDisable(GL_POLYGON_OFFSET_FILL); - glDisable(GL_LIGHTING); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - } public : void operator () (GFace *f) @@ -421,13 +381,6 @@ public : glColor4ubv((GLubyte *) & CTX.color.geom.surface); } - if(CTX.geom.surfaces && f->va_geom_triangles) - _drawVertexArray - (f->va_geom_triangles, CTX.geom.light, - (f->geomType() == GEntity::ProjectionFace) ? true : f->getSelection(), - (f->geomType() == GEntity::ProjectionFace) ? CTX.color.geom.projection : - CTX.color.geom.selection); - if(f->geomType() == GEntity::Plane) _drawPlaneGFace(f); else @@ -442,7 +395,6 @@ public : } }; - class drawGRegion { public : void operator () (GRegion *r) -- GitLab