From 9ce73bf345f1a810fe82d80cf0379b2a0f4fa838 Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Sun, 5 Oct 2008 12:06:58 +0000 Subject: [PATCH] attractors on surfaces (not fully satisfactory, but useful nonetheless) --- Mesh/Field.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++++------ doc/TODO.txt | 13 ++++++----- 2 files changed, 57 insertions(+), 14 deletions(-) diff --git a/Mesh/Field.cpp b/Mesh/Field.cpp index 2d6535275a..fa4f1515ea 100644 --- a/Mesh/Field.cpp +++ b/Mesh/Field.cpp @@ -1117,8 +1117,7 @@ class AttractorField : public Field ANNpointArray zeronodes; ANNidxArray index; ANNdistArray dist; - std::list<int> nodes_id; - std::list<int> edges_id; + std::list<int> nodes_id, edges_id, faces_id; int n_nodes_by_edge; public: AttractorField() : kdtree(0), zeronodes(0) @@ -1135,6 +1134,11 @@ class AttractorField : public Field options["NNodesByEdge"] = new FieldOptionInt(n_nodes_by_edge, "Number of nodes " "used to discetized each curve", &update_needed); + options["FacesList"] = new FieldOptionList(faces_id, "Indices of " + "surfaces in the geometric model " + "(Warning: might give strange " + "results for complex surfaces)", + &update_needed); } ~AttractorField() { @@ -1163,7 +1167,8 @@ class AttractorField : public Field annDeallocPts(zeronodes); delete kdtree; } - int totpoints = nodes_id.size() + n_nodes_by_edge * edges_id.size(); + int totpoints = nodes_id.size() + n_nodes_by_edge * edges_id.size() + + n_nodes_by_edge * n_nodes_by_edge * faces_id.size(); if(totpoints) zeronodes = annAllocPts(totpoints, 4); int k = 0; @@ -1197,13 +1202,13 @@ class AttractorField : public Field } } else { - GEdge *ge = GModel::current()->getEdgeByTag(*it); - if(ge) { + GEdge *e = GModel::current()->getEdgeByTag(*it); + if(e) { for(int i = 0; i < n_nodes_by_edge; i++) { double u = (double)i / (n_nodes_by_edge - 1); - Range<double> b = ge->parBounds(0); + Range<double> b = e->parBounds(0); double t = b.low() + u * (b.high() - b.low()); - GPoint gp = ge->point(t); + GPoint gp = e->point(t); zeronodes[k][0] = gp.x(); zeronodes[k][1] = gp.y(); zeronodes[k++][2] = gp.z(); @@ -1211,6 +1216,45 @@ class AttractorField : public Field } } } + // This can lead to weird results as we generate attractors over + // the whole parametric plane (We should really use a + // mesh... but none is available before 1D & 2D meshing. Or we + // should provide a better containsParam() implementation.) + for(std::list<int>::iterator it = faces_id.begin(); + it != faces_id.end(); ++it) { + Surface *s = FindSurface(*it); + if(s) { + for(int i = 0; i < n_nodes_by_edge; i++) { + for(int j = 0; j < n_nodes_by_edge; j++) { + double u = (double)i / (n_nodes_by_edge - 1); + double v = (double)j / (n_nodes_by_edge - 1); + Vertex V = InterpolateSurface(s, u, v, 0, 0); + zeronodes[k][0] = V.Pos.X; + zeronodes[k][1] = V.Pos.Y; + zeronodes[k++][2] = V.Pos.Z; + } + } + } + else { + GFace *f = GModel::current()->getFaceByTag(*it); + if(f) { + for(int i = 0; i < n_nodes_by_edge; i++) { + for(int j = 0; j < n_nodes_by_edge; j++) { + double u = (double)i / (n_nodes_by_edge - 1); + double v = (double)j / (n_nodes_by_edge - 1); + Range<double> b1 = ge->parBounds(0); + Range<double> b2 = ge->parBounds(1); + double t1 = b1.low() + u * (b1.high() - b1.low()); + double t2 = b2.low() + v * (b2.high() - b2.low()); + GPoint gp = f->point(t1, t2); + zeronodes[k][0] = gp.x(); + zeronodes[k][1] = gp.y(); + zeronodes[k++][2] = gp.z(); + } + } + } + } + } kdtree = new ANNkd_tree(zeronodes, totpoints, 3); update_needed = false; } diff --git a/doc/TODO.txt b/doc/TODO.txt index f178815b82..61da5b491d 100644 --- a/doc/TODO.txt +++ b/doc/TODO.txt @@ -1,9 +1,4 @@ -$Id: TODO.txt,v 1.6 2008-10-01 19:18:14 geuzaine Exp $ - -******************************************************************** - -Add Attractor field on surfaces (use the surface mesh points as point -attractors?) +$Id: TODO.txt,v 1.7 2008-10-05 12:06:58 geuzaine Exp $ ******************************************************************** @@ -39,7 +34,8 @@ entity, and sort like in post-processing. fix tetgen for non manifold geometries: with a single surface connected to a volume and tetgen modifies the volume boundary mesh, we get hanging nodes -Plus we need to fix the 1D mesh in all cases + +Also: we need to fix the 1D mesh in all cases! ******************************************************************** @@ -72,6 +68,9 @@ interface GModel in surface creation in the parser add linear lc progression in 1D transfinite generator +Also: implement easier to understand "bump" function (double +progression?) + ******************************************************************** add parameter to geo transforms to copy the meshes--this would allow -- GitLab