From 629fd5fb76f7455a3fe6ee9071351ab4399f0e2a Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Wed, 15 Feb 2012 19:58:11 +0000 Subject: [PATCH] fix drawing of 3-sided ruled surfaces (due to change in param space) --- Geo/GeoInterpolation.cpp | 53 +++++++++--------- Graphics/drawGeom.cpp | 112 ++++++++++++++++++++++----------------- 2 files changed, 88 insertions(+), 77 deletions(-) diff --git a/Geo/GeoInterpolation.cpp b/Geo/GeoInterpolation.cpp index 45ba40fb94..c93a312a8b 100644 --- a/Geo/GeoInterpolation.cpp +++ b/Geo/GeoInterpolation.cpp @@ -17,7 +17,7 @@ static Vertex InterpolateCubicSpline(Vertex *v[4], double t, double mat[4][4], { Vertex V; int i, j; - double vec[4], T[4]; + double vec[4], T[4]; V.Pos.X = V.Pos.Y = V.Pos.Z = 0.0; V.lc = (1 - t) * v[1]->lc + t * v[2]->lc; @@ -137,7 +137,7 @@ SPoint2 InterpolateCubicSpline(Vertex *v[4], double t, double mat[4][4], } // Uniform BSplines -static Vertex InterpolateUBS(Curve *Curve, double u, int derivee) +static Vertex InterpolateUBS(Curve *Curve, double u, int derivee) { bool periodic = (Curve->end == Curve->beg); int NbControlPoints = List_Nbr(Curve->Control_Points); @@ -163,7 +163,7 @@ static Vertex InterpolateUBS(Curve *Curve, double u, int derivee) V.Pos.Y = pt.y(); V.Pos.Z = pt.z(); return V; - } + } else return InterpolateCubicSpline(v, t, Curve->mat, derivee, t1, t2); } @@ -240,7 +240,7 @@ Vertex InterpolateCurve(Curve *c, double u, int derivee) } return InterpolateCurve(C0, C0->ubeg + (C0->uend - C0->ubeg) * (1. - u), derivee); } - + Vertex V; if(derivee==1) { @@ -262,7 +262,7 @@ Vertex InterpolateCurve(Curve *c, double u, int derivee) V.u = u; break; } - return V; + return V; } if(derivee==2) { @@ -284,7 +284,7 @@ Vertex InterpolateCurve(Curve *c, double u, int derivee) V.u = u; break; } - return V; + return V; } int N, i; @@ -421,7 +421,6 @@ Vertex InterpolateCurve(Curve *c, double u, int derivee) #if defined(HAVE_BFGS) // printf("MSH_SEGM_DISCRETE\n"); #endif - Msg::Debug("Cannot interpolate discrete curve"); break; @@ -463,20 +462,20 @@ static Vertex TransfiniteQua(Vertex c1, Vertex c2, Vertex c3, Vertex c4, // Interpolation transfinie sur un triangle : TRAN_QUA avec s1=s4=c4 // f(u,v) = u c2 (v) + (1-v) c1(u) + v c3(u) - u(1-v) s2 - uv s3 -// +// // s3(1,1) // + // / | -// c3 / | +// c3 / | // / | c2 // / | // / c1 | // +----------+ // s1(0,0) s2(1,0) -// u = v = 0 -----> x = c1(0) = s1 --> OK -// u = 1 ; v = 0 -----> x = c2(0) + c1(1) - s2 = s2 --> OK -// u = 1 ; v = 1 -----> x = c2(1) + c3(1) - s3 = s3 --> OK +// u = v = 0 -----> x = c1(0) = s1 --> OK +// u = 1 ; v = 0 -----> x = c2(0) + c1(1) - s2 = s2 --> OK +// u = 1 ; v = 1 -----> x = c2(1) + c3(1) - s3 = s3 --> OK // v = 0 --> u s2 + c1(u) - u s2 --> x = c1(u) --> OK // u = 1 --> c2(v) + (1-v) s2 + v s3 -(1-v) s2 - v s3 --> x = c2(v) --> OK // u = 0 --> (1-v) s1 + v s1 = s1 !!! not terrible (singular) @@ -485,19 +484,17 @@ static Vertex TransfiniteQua(Vertex c1, Vertex c2, Vertex c3, Vertex c4, // f(u,v) = (1-u) (c1(u-v) + c3(1-v) - s1) + // (u-v) (c2(v) + c1(u) - s2) + -// v (c3(1-u) + c2(1-u+v) - s3) -// -// u = v = 0 --> f(0,0) = s1 + s1 - s1 = s1 -// u = v = 1 --> f(1,1) = s3 + s3 - s3 = s3 -// u = 1 ; v = 0 --> f(1,1) = s2 + s2 - s2 = s2 +// v (c3(1-u) + c2(1-u+v) - s3) +// +// u = v = 0 --> f(0,0) = s1 + s1 - s1 = s1 +// u = v = 1 --> f(1,1) = s3 + s3 - s3 = s3 +// u = 1 ; v = 0 --> f(1,1) = s2 + s2 - s2 = s2 // v = 0 --> (1-u)c1(u) + u c1(u) = c1(u) --> COOL - #define TRAN_TRI(c1,c2,c3,s1,s2,s3,u,v) u*c2+(1.-v)*c1+v*c3-(u*(1.-v)*s2+u*v*s3); #define TRAN_TRIB(c1,c1b,c2,c2b,c3,c3b,s1,s2,s3,u,v) (1.-u)*(c1+c3b-s1)+(u-v)*(c2+c1b-s2)+v*(c3+c2b-s3); - static Vertex TransfiniteTri(Vertex c1, Vertex c2, Vertex c3, Vertex s1, Vertex s2, Vertex s3, double u, double v) { @@ -512,9 +509,10 @@ static Vertex TransfiniteTri(Vertex c1, Vertex c2, Vertex c3, s1.Pos.Z, s2.Pos.Z, s3.Pos.Z, u, v); return V; } + static Vertex TransfiniteTriB(Vertex c1, Vertex c1b, Vertex c2, Vertex c2b, Vertex c3, Vertex c3b, - Vertex s1, Vertex s2, Vertex s3, + Vertex s1, Vertex s2, Vertex s3, double u, double v) { Vertex V; @@ -529,7 +527,6 @@ static Vertex TransfiniteTriB(Vertex c1, Vertex c1b, Vertex c2, return V; } - static void TransfiniteSph(Vertex S, Vertex center, Vertex *T) { double r = sqrt(SQU(S.Pos.X - center.Pos.X) + SQU(S.Pos.Y - center.Pos.Y) @@ -599,7 +596,7 @@ static Vertex InterpolateRuledSurface(Surface *s, double u, double v) for(int i = 0; i < std::min(List_Nbr(s->Generatrices), 4); i++) List_Read(s->Generatrices, i, &C[i]); - + Vertex *O = 0; bool isSphere = true; @@ -640,7 +637,7 @@ static Vertex InterpolateRuledSurface(Surface *s, double u, double v) isSphere = false; } } - + Vertex *S[4], V[4],VB[3], T; if(s->Typ == MSH_SURF_REGL && List_Nbr(s->Generatrices) >= 4){ S[0] = C[0]->beg; @@ -684,7 +681,7 @@ static Vertex InterpolateRuledSurface(Surface *s, double u, double v) VB[1] = InterpolateCurve(C[1], C[1]->ubeg + (C[1]->uend - C[1]->ubeg) * (1-u+v), 0); VB[2] = InterpolateCurve(C[2], C[2]->ubeg + (C[2]->uend - C[2]->ubeg) * (1. - v), 0); T = TransfiniteTriB(V[0],VB[0], V[1],VB[1], V[2],VB[2], *S[0], *S[1], *S[2], u, v); - + if(isSphere) { TransfiniteSph(*S[0], *O, &T); } @@ -712,9 +709,9 @@ static Vertex InterpolateExtrudedSurface(Surface *s, double u, double v) Msg::Error("Unknown curve in extruded surface"); return T; } - + switch(num){ - case 0: + case 0: T = InterpolateCurve(c, c->ubeg + (c->uend - c->ubeg) * u, 0); s->Extrude->Extrude(v, T.Pos.X, T.Pos.Y, T.Pos.Z); return T; @@ -809,13 +806,13 @@ Vertex InterpolateSurface(Surface *s, double u, double v, int derivee, int u_v) // exact surfaces of revolution. This WILL fail if the surface is // transformed after the extrusion: in that case set the // exactExtrusion option to 0 to use the normal code path - if(CTX::instance()->geom.exactExtrusion && s->Extrude && + if(CTX::instance()->geom.exactExtrusion && s->Extrude && s->Extrude->geo.Mode == EXTRUDED_ENTITY && s->Typ != MSH_SURF_PLAN) return InterpolateExtrudedSurface(s, u, v); switch (s->Typ) { case MSH_SURF_REGL: - case MSH_SURF_TRIC: + case MSH_SURF_TRIC: return InterpolateRuledSurface(s, u, v); case MSH_SURF_PLAN: Msg::Error("Should never interpolate plane surface in InterpolateSurface()"); diff --git a/Graphics/drawGeom.cpp b/Graphics/drawGeom.cpp index a2cdc096fe..3ba0674a93 100644 --- a/Graphics/drawGeom.cpp +++ b/Graphics/drawGeom.cpp @@ -23,16 +23,16 @@ class drawGVertex { if(!v->getVisibility()) return; if(v->geomType() == GEntity::BoundaryLayerPoint) return; - bool select = (_ctx->render_mode == drawContext::GMSH_SELECT && + bool select = (_ctx->render_mode == drawContext::GMSH_SELECT && v->model() == GModel::current()); if(select) { glPushName(0); glPushName(v->tag()); } - + if(v->getSelection()) { glPointSize((float)CTX::instance()->geom.selectedPointSize); - gl2psPointSize((float)(CTX::instance()->geom.selectedPointSize * + gl2psPointSize((float)(CTX::instance()->geom.selectedPointSize * CTX::instance()->print.epsPointSizeFactor)); glColor4ubv((GLubyte *) & CTX::instance()->color.geom.selection); } @@ -42,7 +42,7 @@ class drawGVertex { CTX::instance()->print.epsPointSizeFactor)); glColor4ubv((GLubyte *) & CTX::instance()->color.geom.point); } - + if(CTX::instance()->geom.highlightOrphans){ std::list<GEdge*> edges = v->edges(); if(edges.size() == 0) @@ -57,10 +57,10 @@ class drawGVertex { if(CTX::instance()->geom.points) { if(CTX::instance()->geom.pointType > 0) { if(v->getSelection()) - _ctx->drawSphere(CTX::instance()->geom.selectedPointSize, x, y, z, + _ctx->drawSphere(CTX::instance()->geom.selectedPointSize, x, y, z, CTX::instance()->geom.light); else - _ctx->drawSphere(CTX::instance()->geom.pointSize, x, y, z, + _ctx->drawSphere(CTX::instance()->geom.pointSize, x, y, z, CTX::instance()->geom.light); } else { @@ -73,14 +73,14 @@ class drawGVertex { if(CTX::instance()->geom.pointsNum) { char Num[100]; sprintf(Num, "%d", v->tag()); - double offset = (0.5 * CTX::instance()->geom.pointSize + + double offset = (0.5 * CTX::instance()->geom.pointSize + 0.1 * CTX::instance()->glFontSize) * _ctx->pixel_equiv_x; glRasterPos3d(x + offset / _ctx->s[0], y + offset / _ctx->s[1], z + offset / _ctx->s[2]); _ctx->drawString(Num); } - + if(select) { glPopName(); glPopName(); @@ -99,28 +99,28 @@ class drawGEdge { if(e->geomType() == GEntity::DiscreteCurve) return; if(e->geomType() == GEntity::PartitionCurve) return; if(e->geomType() == GEntity::BoundaryLayerCurve) return; - // if(e->geomType() == GEntity::CompoundCurve) return; - - bool select = (_ctx->render_mode == drawContext::GMSH_SELECT && + // if(e->geomType() == GEntity::CompoundCurve) return; + + bool select = (_ctx->render_mode == drawContext::GMSH_SELECT && e->model() == GModel::current()); if(select) { glPushName(1); glPushName(e->tag()); } - + if(e->getSelection()) { glLineWidth((float)CTX::instance()->geom.selectedLineWidth); - gl2psLineWidth((float)(CTX::instance()->geom.selectedLineWidth * + gl2psLineWidth((float)(CTX::instance()->geom.selectedLineWidth * CTX::instance()->print.epsLineWidthFactor)); glColor4ubv((GLubyte *) & CTX::instance()->color.geom.selection); } else { glLineWidth((float)CTX::instance()->geom.lineWidth); - gl2psLineWidth((float)(CTX::instance()->geom.lineWidth * + gl2psLineWidth((float)(CTX::instance()->geom.lineWidth * CTX::instance()->print.epsLineWidthFactor)); glColor4ubv((GLubyte *) & CTX::instance()->color.geom.line); } - + if(CTX::instance()->geom.highlightOrphans){ std::list<GFace*> faces = e->faces(); if(faces.size() == 0) @@ -132,7 +132,7 @@ class drawGEdge { Range<double> t_bounds = e->parBounds(0); double t_min = t_bounds.low(); double t_max = t_bounds.high(); - + if(CTX::instance()->geom.lines) { int N = e->minimumDrawSegments() + 1; if(CTX::instance()->geom.lineType > 0) { @@ -146,8 +146,8 @@ class drawGEdge { double z[2] = {p1.z(), p2.z()}; _ctx->transform(x[0], y[0], z[0]); _ctx->transform(x[1], y[1], z[1]); - _ctx->drawCylinder(e->getSelection() ? CTX::instance()->geom.selectedLineWidth : - CTX::instance()->geom.lineWidth, x, y, z, + _ctx->drawCylinder(e->getSelection() ? CTX::instance()->geom.selectedLineWidth : + CTX::instance()->geom.lineWidth, x, y, z, CTX::instance()->geom.light); } } @@ -163,12 +163,12 @@ class drawGEdge { glEnd(); } } - + if(CTX::instance()->geom.linesNum) { GPoint p = e->point(t_min + 0.5 * (t_max - t_min)); char Num[100]; sprintf(Num, "%d", e->tag()); - double offset = (0.5 * CTX::instance()->geom.lineWidth + + double offset = (0.5 * CTX::instance()->geom.lineWidth + 0.1 * CTX::instance()->glFontSize) * _ctx->pixel_equiv_x; double x = p.x(), y = p.y(), z = p.z(); _ctx->transform(x, y, z); @@ -177,7 +177,7 @@ class drawGEdge { z + offset / _ctx->s[2]); _ctx->drawString(Num); } - + if(CTX::instance()->geom.tangents) { double t = t_min + 0.5 * (t_max - t_min); GPoint p = e->point(t); @@ -203,7 +203,7 @@ class drawGEdge { class drawGFace { private: drawContext *_ctx; - void _drawVertexArray(VertexArray *va, bool useNormalArray, int forceColor=0, + void _drawVertexArray(VertexArray *va, bool useNormalArray, int forceColor=0, unsigned int color=0) { if(!va || !va->getNumVertices()) return; @@ -244,8 +244,12 @@ class drawGFace { 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()); + bool tri = (f->geomType() == GEntity::RuledSurface && f->edges().size() == 3); + double c = tri ? 0.75 : 0.5; + double uav = c * (ubounds.high() + ubounds.low()); + double vav = (1-c) * (vbounds.high() + vbounds.low()); + double u2 = 0.5 * (ubounds.high() + ubounds.low()); + double v2 = 0.5 * (vbounds.high() + vbounds.low()); if(CTX::instance()->geom.surfaces){ if(CTX::instance()->geom.surfaceType > 0 && f->va_geom_triangles){ @@ -253,22 +257,27 @@ class drawGFace { if (f->getSelection() || (f->getCompound() && f->getCompound()->getSelection())) selected = true; _drawVertexArray - (f->va_geom_triangles, CTX::instance()->geom.light, - (f->geomType() == GEntity::ProjectionFace) ? true : selected, - (f->geomType() == GEntity::ProjectionFace) ? - CTX::instance()->color.geom.projection : + (f->va_geom_triangles, CTX::instance()->geom.light, + (f->geomType() == GEntity::ProjectionFace) ? true : selected, + (f->geomType() == GEntity::ProjectionFace) ? + CTX::instance()->color.geom.projection : CTX::instance()->color.geom.selection); } else{ glEnable(GL_LINE_STIPPLE); glLineStipple(1, 0x1F1F); gl2psEnable(GL2PS_LINE_STIPPLE); - int N = 20; const double ud = (ubounds.high() - ubounds.low()); const double vd = (vbounds.high() - vbounds.low()); + int N = 20; + GPoint p; glBegin(GL_LINE_STRIP); for(int i = 0; i < N; i++) { - GPoint p = f->point(ubounds.low() + ud * (double)i / (double)(N - 1), vav); + if(tri) + p = f->point(u2 + u2 * (double)i / (double)(N - 1), + vbounds.low() + v2 * (double)i / (double)(N - 1)); + else + p = f->point(ubounds.low() + ud * (double)i / (double)(N - 1), vav); double x = p.x(), y = p.y(), z = p.z(); _ctx->transform(x, y, z); glVertex3d(x, y, z); @@ -276,12 +285,17 @@ class drawGFace { 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)); + if(tri) + p = f->point(u2 + u2 * (double)i / (double)(N - 1), + v2 - v2 * (double)i / (double)(N - 1)); + else + p = f->point(uav, vbounds.low() + vd * (double)i / (double)(N - 1)); double x = p.x(), y = p.y(), z = p.z(); _ctx->transform(x, y, z); glVertex3d(x, y, z); } glEnd(); + glDisable(GL_LINE_STIPPLE); gl2psDisable(GL2PS_LINE_STIPPLE); } @@ -299,7 +313,7 @@ class drawGFace { z + offset / _ctx->s[2]); _ctx->drawString(Num); } - + if(CTX::instance()->geom.normals) { GPoint p = f->point(uav, vav); SVector3 n = f->normal(SPoint2(uav, vav)); @@ -327,7 +341,7 @@ class drawGFace { if (f->getSelection() || (f->getCompound() && f->getCompound()->getSelection())) selected = true; if(CTX::instance()->geom.surfaceType > 0 && f->va_geom_triangles){ - _drawVertexArray(f->va_geom_triangles, CTX::instance()->geom.light, + _drawVertexArray(f->va_geom_triangles, CTX::instance()->geom.light, f->getSelection(), CTX::instance()->color.geom.selection); } else{ @@ -347,7 +361,7 @@ class drawGFace { } if(f->cross.size() < 2) return; - + if(CTX::instance()->geom.surfacesNum) { char Num[100]; sprintf(Num, "%d", f->tag()); @@ -378,7 +392,7 @@ class drawGFace { CTX::instance()->geom.light); } } - + void _drawCompoundGFace(GFace *f, bool visible = false, bool selected = false) { GFaceCompound *fc = (GFaceCompound*) f; @@ -387,7 +401,7 @@ class drawGFace { if ((*it)->geomType() == GEntity::DiscreteSurface) continue; if ((*it)->geomType() == GEntity::PartitionSurface) continue; if ((*it)->geomType() == GEntity::BoundaryLayerSurface) continue; - + if((*it)->geomType() == GEntity::CompoundSurface) _drawCompoundGFace((*it)); else if ((*it)->geomType() == GEntity::Plane) @@ -396,7 +410,7 @@ class drawGFace { _drawParametricGFace((*it)); } } - + public : drawGFace(drawContext *ctx) : _ctx(ctx) {} void operator () (GFace *f) @@ -406,13 +420,13 @@ class drawGFace { if(f->geomType() == GEntity::PartitionSurface) return; if(f->geomType() == GEntity::BoundaryLayerSurface) return; - bool select = (_ctx->render_mode == drawContext::GMSH_SELECT && + bool select = (_ctx->render_mode == drawContext::GMSH_SELECT && f->model() == GModel::current()); if(select) { glPushName(2); glPushName(f->tag()); } - + if(f->getSelection()) { glLineWidth((float)(CTX::instance()->geom.selectedLineWidth / 2.)); gl2psLineWidth((float)(CTX::instance()->geom.selectedLineWidth / 2. * @@ -421,7 +435,7 @@ class drawGFace { } else { glLineWidth((float)(CTX::instance()->geom.lineWidth / 2.)); - gl2psLineWidth((float)(CTX::instance()->geom.lineWidth / 2. * + gl2psLineWidth((float)(CTX::instance()->geom.lineWidth / 2. * CTX::instance()->print.epsLineWidthFactor)); glColor4ubv((GLubyte *) & CTX::instance()->color.geom.surface); } @@ -449,19 +463,19 @@ class drawGRegion { { if(!r->getVisibility()) return; // if(r->geomType() == GEntity::DiscreteVolume) return; - - bool select = (_ctx->render_mode == drawContext::GMSH_SELECT && + + bool select = (_ctx->render_mode == drawContext::GMSH_SELECT && r->model() == GModel::current()); if(select) { glPushName(3); glPushName(r->tag()); } - + if(r->getSelection()) glColor4ubv((GLubyte *) & CTX::instance()->color.geom.selection); else glColor4ubv((GLubyte *) & CTX::instance()->color.geom.volume); - + SPoint3 p = r->bounds().center(); const double size = 8.; @@ -481,7 +495,7 @@ class drawGRegion { z + offset / _ctx->s[2]); _ctx->drawString(Num); } - + if(select) { glPopName(); glPopName(); @@ -497,9 +511,9 @@ void drawContext::drawGeom() glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); else glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); - + for(int i = 0; i < 6; i++) - if(CTX::instance()->geom.clip & (1 << i)) + if(CTX::instance()->geom.clip & (1 << i)) glEnable((GLenum)(GL_CLIP_PLANE0 + i)); else glDisable((GLenum)(GL_CLIP_PLANE0 + i)); @@ -509,7 +523,7 @@ void drawContext::drawGeom() if(m->getVisibility() && isVisible(m)){ if(CTX::instance()->geom.points || CTX::instance()->geom.pointsNum) std::for_each(m->firstVertex(), m->lastVertex(), drawGVertex(this)); - if(CTX::instance()->geom.lines || CTX::instance()->geom.linesNum || + if(CTX::instance()->geom.lines || CTX::instance()->geom.linesNum || CTX::instance()->geom.tangents) std::for_each(m->firstEdge(), m->lastEdge(), drawGEdge(this)); if(CTX::instance()->geom.surfaces || CTX::instance()->geom.surfacesNum || @@ -520,7 +534,7 @@ void drawContext::drawGeom() std::for_each(m->firstRegion(), m->lastRegion(), drawGRegion(this)); } } - + for(int i = 0; i < 6; i++) glDisable((GLenum)(GL_CLIP_PLANE0 + i)); } -- GitLab