LCOV - code coverage report
Current view: top level - ugbase/lib_grid/algorithms/geom_obj_util - vertex_util.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 225 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 24 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2009-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Sebastian Reiter
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : #include "vertex_util.h"
      34              : #include "edge_util.h"
      35              : #include "../trees/kd_tree_static.h"
      36              : #include "misc_util.h"
      37              : 
      38              : using namespace std;
      39              : 
      40              : namespace ug
      41              : {
      42              : 
      43              : ////////////////////////////////////////////////////////////////////////
      44            0 : int GetVertexIndex(EdgeVertices* e, Vertex* v)
      45              : {
      46            0 :         if(e->vertex(0) == v)
      47              :                 return 0;
      48            0 :         else if(e->vertex(1) == v)
      49            0 :                 return 1;
      50              :         return -1;
      51              : }
      52              : 
      53              : ////////////////////////////////////////////////////////////////////////
      54            0 : int GetVertexIndex(FaceVertices* f, Vertex* v)
      55              : {
      56            0 :         uint numVrts = f->num_vertices();
      57            0 :         for(uint i = 0; i < numVrts; ++i)
      58              :         {
      59            0 :                 if(f->vertex(i) == v)
      60            0 :                         return i;
      61              :         }
      62              :         return -1;
      63              : }
      64              : 
      65              : ////////////////////////////////////////////////////////////////////////
      66            0 : int GetVertexIndex(VolumeVertices* vol, Vertex* v)
      67              : {
      68            0 :         uint numVrts = vol->num_vertices();
      69            0 :         for(uint i = 0; i < numVrts; ++i)
      70              :         {
      71            0 :                 if(vol->vertex(i) == v)
      72            0 :                         return i;
      73              :         }
      74              :         return -1;
      75              : }
      76              : 
      77              : ////////////////////////////////////////////////////////////////////////
      78            0 : Vertex* GetConnectedVertex(Edge* e, Vertex* v)
      79              : {
      80            0 :         if(e->vertex(0) == v)
      81            0 :                 return e->vertex(1);
      82            0 :         else if(e->vertex(1) == v)
      83            0 :                 return e->vertex(0);
      84              :         return NULL;
      85              : }
      86              : 
      87              : ////////////////////////////////////////////////////////////////////////
      88              : //      GetConnectedVertex
      89            0 : Vertex* GetConnectedVertex(EdgeVertices* e, Face* f)
      90              : {
      91            0 :         uint numVrts = f->num_vertices();
      92            0 :         for(uint i = 0; i < numVrts; ++i){
      93            0 :                 if((f->vertex(i) != e->vertex(0)) &&
      94            0 :                         (f->vertex(i) != e->vertex(1)))
      95            0 :                         return f->vertex(i);
      96              :         }
      97              :         return NULL;
      98              : }
      99              : 
     100              : ////////////////////////////////////////////////////////////////////////
     101            0 : int GetConnectedVertexIndex(Face* f, const EdgeDescriptor& ed)
     102              : {
     103            0 :         return GetConnectedVertexIndex(f, &ed);
     104              : }
     105              : 
     106            0 : int GetConnectedVertexIndex(Face* f, const EdgeVertices* e)
     107              : {
     108            0 :         uint numVrts = f->num_vertices();
     109            0 :         for(uint i = 0; i < numVrts; ++i)
     110              :         {
     111            0 :                 if((f->vertex(i) != e->vertex(0)) &&
     112            0 :                         (f->vertex(i) != e->vertex(1)))
     113              :                 {
     114            0 :                         return i;
     115              :                 }
     116              :         }
     117              :         return -1;
     118              : }
     119              : 
     120              : ////////////////////////////////////////////////////////////////////////
     121            0 : Edge* GetConnectedEdge(Grid& g, Vertex* vrt, Face* tri)
     122              : {
     123              :         size_t numEdges = tri->num_edges();
     124            0 :         EdgeDescriptor ed;
     125            0 :         for(size_t i = 0; i < numEdges; ++i){
     126            0 :                 tri->edge_desc(i, ed);
     127            0 :                 if(!EdgeContains(&ed, vrt))
     128            0 :                         return g.get_edge(ed);
     129              :         }
     130              :         return NULL;
     131              : }
     132              : 
     133              : ////////////////////////////////////////////////////////////////////////
     134            0 : Vertex* GetSharedVertex(IVertexGroup* vrts0, IVertexGroup* vrts1)
     135              : {
     136              :         const size_t num0 = vrts0->size();
     137              :         const size_t num1 = vrts1->size();
     138              : 
     139            0 :         IVertexGroup::ConstVertexArray v0 = vrts0->vertices();
     140            0 :         IVertexGroup::ConstVertexArray v1 = vrts1->vertices();
     141              : 
     142            0 :         for(size_t i0 = 0; i0 < num0; ++i0){
     143            0 :                 Vertex* v = v0[i0];
     144            0 :                 for(size_t i1 = 0; i1 < num1; ++i1){
     145            0 :                         if(v == v1[i1])
     146            0 :                                 return v;
     147              :                 }
     148              :         }
     149              : 
     150              :         return 0;
     151              : }
     152              : 
     153              : ////////////////////////////////////////////////////////////////////////
     154            0 : size_t GetSharedVertices(
     155              :                         std::vector<Vertex*>& vrtsOut,
     156              :                         IVertexGroup* vrts0,
     157              :                         IVertexGroup* vrts1)
     158              : {
     159              :         vrtsOut.clear();
     160              : 
     161              :         const size_t num0 = vrts0->size();
     162              :         const size_t num1 = vrts1->size();
     163              : 
     164            0 :         IVertexGroup::ConstVertexArray v0 = vrts0->vertices();
     165            0 :         IVertexGroup::ConstVertexArray v1 = vrts1->vertices();
     166              : 
     167            0 :         for(size_t i0 = 0; i0 < num0; ++i0){
     168            0 :                 Vertex* v = v0[i0];
     169            0 :                 for(size_t i1 = 0; i1 < num1; ++i1){
     170            0 :                         if(v == v1[i1])
     171            0 :                                 vrtsOut.push_back(v);
     172              :                 }
     173              :         }
     174              : 
     175            0 :         return vrtsOut.size();
     176              : }
     177              : 
     178              : ////////////////////////////////////////////////////////////////////////
     179            0 : size_t NumSharedVertices(IVertexGroup* vrts0, IVertexGroup* vrts1)
     180              : {
     181              :         const size_t num0 = vrts0->size();
     182              :         const size_t num1 = vrts1->size();
     183              : 
     184            0 :         IVertexGroup::ConstVertexArray v0 = vrts0->vertices();
     185            0 :         IVertexGroup::ConstVertexArray v1 = vrts1->vertices();
     186              : 
     187              :         size_t numShared = 0;
     188            0 :         for(size_t i0 = 0; i0 < num0; ++i0){
     189            0 :                 Vertex* v = v0[i0];
     190            0 :                 for(size_t i1 = 0; i1 < num1; ++i1){
     191            0 :                         if(v == v1[i1])
     192            0 :                                 ++numShared;
     193              :                 }
     194              :         }
     195              : 
     196            0 :         return numShared;
     197              : }
     198              : 
     199              : ////////////////////////////////////////////////////////////////////////
     200            0 : int NumAssociatedEdges(Grid& grid, Vertex* v)
     201              : {
     202              :         Grid::edge_traits::secure_container edges;
     203              :         grid.associated_elements(edges, v);
     204            0 :         return (int)edges.size();
     205              : }
     206              : 
     207              : ////////////////////////////////////////////////////////////////////////
     208            0 : int NumAssociatedFaces(Grid& grid, Vertex* v)
     209              : {
     210              :         Grid::face_traits::secure_container faces;
     211              :         grid.associated_elements(faces, v);
     212            0 :         return (int)faces.size();
     213              : }
     214              : 
     215              : ////////////////////////////////////////////////////////////////////////
     216              : //      CollectSurfaceNeighborsSorted
     217            0 : bool CollectSurfaceNeighborsSorted(std::vector<Vertex*>& vNeighborsOut,
     218              :                                                                    Grid& grid, Vertex* v)
     219              : {
     220              :         vNeighborsOut.clear();
     221              :         
     222              : //      the algorithm won't work if volumes are connected
     223            0 :         if(grid.num_volumes() > 0){
     224            0 :                 if(grid.associated_volumes_begin(v) != grid.associated_volumes_end(v))
     225              :                         return false;
     226              :         }
     227              :                 
     228              : //      the algorithm won't work if no faces are connected
     229            0 :         if(grid.associated_faces_begin(v) == grid.associated_faces_end(v))
     230              :                 return false;
     231              :         
     232            0 :         grid.begin_marking();
     233              :         
     234            0 :         if(grid.option_is_enabled(FACEOPT_AUTOGENERATE_EDGES)
     235            0 :            && grid.option_is_enabled(EDGEOPT_STORE_ASSOCIATED_FACES)){
     236              :         //      collect edges in this vector
     237              :                 vector<Edge*> edges;
     238              :         //      start with an arbitrary edge
     239            0 :                 Edge* curEdge = *grid.associated_edges_begin(v);
     240              :                 
     241            0 :                 while(curEdge){
     242            0 :                         vNeighborsOut.push_back(GetConnectedVertex(curEdge, v));
     243              :                         grid.mark(curEdge);
     244              :                         
     245              :                 //      get associated faces
     246              :                         Face* f[2];
     247            0 :                         if(GetAssociatedFaces(f, grid, curEdge, 2) != 2)
     248            0 :                                 return false;
     249              :                         
     250              :                         curEdge = NULL;
     251            0 :                         for(int i = 0; i < 2; ++i){
     252            0 :                                 if(!grid.is_marked(f[i])){
     253            0 :                                         CollectEdges(edges, grid, f[i]);
     254            0 :                                         for(size_t j = 0; j < edges.size(); ++j){
     255            0 :                                                 if(!grid.is_marked(edges[j])){
     256            0 :                                                         if(EdgeContains(edges[j], v)){
     257            0 :                                                                 curEdge = edges[j];
     258            0 :                                                                 break;
     259              :                                                         }
     260              :                                                 }
     261              :                                         }
     262              :                                 }
     263              :                         }
     264              :                 }
     265            0 :         }
     266              :         else{
     267              :         //      we can't use GetAssociatedFaces here, since it uses Grid::mark itself if
     268              :         //      EDGEOPT_STORE_ASSOCIATED_FACES is not enabled.
     269              :         //      Start with an arbitrary face
     270            0 :                 Face* f = *grid.associated_faces_begin(v);
     271              :                 grid.mark(v);
     272              : 
     273            0 :                 while(f){
     274              :                         grid.mark(f);
     275              :                         
     276              :                 //      mark one of the edges that is connected to v by marking
     277              :                 //      the edges endpoints. Make sure that it was not already marked.
     278            0 :                         size_t numVrts = f->num_vertices();
     279            0 :                         int vind = GetVertexIndex(f, v);
     280            0 :                         Vertex* tvrt = f->vertex((vind + 1)%numVrts);
     281            0 :                         if(grid.is_marked(tvrt))
     282            0 :                                 tvrt = f->vertex((vind + numVrts - 1)%numVrts);
     283            0 :                         if(grid.is_marked(tvrt))
     284            0 :                                 throw(UGError("CollectSurfaceNeighborsSorted: unexpected exit."));
     285              :                                 
     286            0 :                         vNeighborsOut.push_back(tvrt);
     287              :                         grid.mark(tvrt);
     288              : 
     289              :                 //      iterate through the faces associated with v and find an unmarked one that
     290              :                 //      contains two marked vertices
     291              :                         f = NULL;
     292            0 :                         Grid::AssociatedFaceIterator iterEnd = grid.associated_faces_end(v);
     293            0 :                         for(Grid::AssociatedFaceIterator iter = grid.associated_faces_begin(v);
     294            0 :                                 iter != iterEnd; ++iter)
     295              :                         {
     296            0 :                                 if(!grid.is_marked(*iter)){
     297              :                                         f = *iter;
     298              :                                         size_t numMarked = 0;
     299            0 :                                         for(size_t i = 0; i < f->num_vertices(); ++i){
     300            0 :                                                 if(grid.is_marked(f->vertex(i)))
     301            0 :                                                         ++numMarked;
     302              :                                         }
     303            0 :                                         if(numMarked == 2)
     304              :                                                 break;
     305              :                                         else
     306              :                                                 f = NULL;
     307              :                                 }
     308              :                         }
     309              :                 }
     310              :         }
     311              : 
     312            0 :         grid.end_marking();
     313            0 :         return true;
     314              : }
     315              : 
     316              : ////////////////////////////////////////////////////////////////////////
     317            0 : Vertex* FindVertexByCoordiante(vector3& coord, VertexIterator iterBegin, VertexIterator iterEnd,
     318              :                                                                         Grid::VertexAttachmentAccessor<APosition>& aaPos)
     319              : {
     320            0 :         if(iterBegin == iterEnd)
     321              :                 return NULL;
     322              : 
     323              :         Vertex* bestVrt = *iterBegin;
     324            0 :         number bestDistSq = VecDistanceSq(coord, aaPos[bestVrt]);
     325              : 
     326              :         VertexIterator iter = iterBegin;
     327              :         iter++;
     328            0 :         while(iter != iterEnd)
     329              :         {
     330            0 :                 number distSq = VecDistanceSq(coord, aaPos[*iter]);
     331            0 :                 if(distSq < bestDistSq)
     332              :                 {
     333              :                         bestDistSq = distSq;
     334              :                         bestVrt = *iter;
     335              :                 }
     336              : 
     337              :                 ++iter;
     338              :         }
     339              : 
     340              :         return bestVrt;
     341              : }
     342              : 
     343              : ////////////////////////////////////////////////////////////////////////
     344              : //      CalculateVertexNormals
     345            0 : bool CalculateVertexNormals(Grid& grid,
     346              :                                                         Grid::AttachmentAccessor<Vertex, APosition>& aaPos,
     347              :                                                         Grid::AttachmentAccessor<Vertex, ANormal>& aaNorm)
     348              : {
     349              : //      set all normals to zero
     350              :         {
     351              :                 for(VertexIterator iter = grid.begin<Vertex>();
     352            0 :                         iter != grid.end<Vertex>(); iter++)
     353              :                         aaNorm[*iter] = vector3(0, 0, 0);
     354              :         }
     355              : //      loop through all the faces, calculate their normal and add them to their connected points
     356              :         {
     357            0 :                 for(FaceIterator iter = grid.begin<Face>(); iter != grid.end<Face>(); iter++)
     358              :                 {
     359              :                         Face* f = *iter;
     360              :                         vector3 vN;
     361              : 
     362            0 :                         CalculateNormal(vN, f, aaPos);
     363              : 
     364            0 :                         for(size_t i = 0; i < f->num_vertices(); ++i)
     365            0 :                                 VecAdd(aaNorm[f->vertex(i)], aaNorm[f->vertex(i)], vN);
     366              :                 }
     367              :         }
     368              : //      loop through all the points and normalize their normals
     369              :         {
     370              :                 for(VertexIterator iter = grid.begin<Vertex>();
     371            0 :                         iter != grid.end<Vertex>(); iter++)
     372            0 :                         VecNormalize(aaNorm[*iter], aaNorm[*iter]);
     373              :         }
     374              : //      done
     375            0 :         return true;
     376              : }
     377              : 
     378            0 : bool CalculateVertexNormals(Grid& grid, APosition& aPos, ANormal& aNorm)
     379              : {
     380            0 :         if(!grid.has_attachment<Vertex>(aPos))
     381              :                 return false;
     382            0 :         if(!grid.has_attachment<Vertex>(aNorm))
     383            0 :                 grid.attach_to<Vertex>(aNorm);
     384              : 
     385              :         Grid::VertexAttachmentAccessor<APosition> aaPos(grid, aPos);
     386              :         Grid::VertexAttachmentAccessor<ANormal> aaNorm(grid, aNorm);
     387              : 
     388            0 :         return CalculateVertexNormals(grid, aaPos, aaNorm);
     389              : }
     390              : 
     391              : 
     392              : ////////////////////////////////////////////////////////////////////////
     393              : //      MergeVertices
     394              : ///     merges two vertices and restructures the adjacent elements.
     395            0 : void MergeVertices(Grid& grid, Vertex* v1, Vertex* v2)
     396              : {
     397              : //      make sure that GRIDOPT_VERTEXCENTRIC_INTERCONNECTION is enabled
     398            0 :         if(grid.num_edges() && (!grid.option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES))){
     399              :                 LOG("  WARNING in MergeVertices: autoenabling VRTOPT_STORE_ASSOCIATED_EDGES\n");
     400            0 :                 grid.enable_options(VRTOPT_STORE_ASSOCIATED_EDGES);
     401              :         }
     402            0 :         if(grid.num_faces() && (!grid.option_is_enabled(VRTOPT_STORE_ASSOCIATED_FACES))){
     403              :                 LOG("  WARNING in MergeVertices: autoenabling VRTOPT_STORE_ASSOCIATED_FACES\n");
     404            0 :                 grid.enable_options(VRTOPT_STORE_ASSOCIATED_FACES);
     405              :         }
     406            0 :         if(grid.num_volumes() && (!grid.option_is_enabled(VRTOPT_STORE_ASSOCIATED_VOLUMES))){
     407              :                 LOG("  WARNING in MergeVertices: autoenabling VRTOPT_STORE_ASSOCIATED_VOLUMES\n");
     408            0 :                 grid.enable_options(VRTOPT_STORE_ASSOCIATED_VOLUMES);
     409              :         }
     410              : 
     411              : 
     412            0 :         Edge* conEdge = grid.get_edge(v1, v2);
     413            0 :         if(conEdge){
     414              :         //      perform an edge-collapse on conEdge
     415            0 :                 CollapseEdge(grid, conEdge, v1);
     416              :         }
     417              :         else{
     418              :         //      notify the grid, that the two vertices will be merged
     419              :                 grid.objects_will_be_merged(v1, v1, v2);
     420              :                 
     421              :         //      we have to check if there are elements that connect the vertices.
     422              :         //      We have to delete those.
     423            0 :                 EraseConnectingElements(grid, v1, v2);
     424              : 
     425              :         //      create new edges for each edge that is connected with v2.
     426              :         //      avoid double edges
     427            0 :                 if(grid.num_edges() > 0)
     428              :                 {
     429            0 :                         EdgeDescriptor ed;
     430            0 :                         Grid::AssociatedEdgeIterator iterEnd = grid.associated_edges_end(v2);
     431            0 :                         for(Grid::AssociatedEdgeIterator iter = grid.associated_edges_begin(v2); iter != iterEnd; ++iter)
     432              :                         {
     433            0 :                                 Edge* e = *iter;
     434            0 :                                 if(e->vertex(0) == v2)
     435            0 :                                         ed.set_vertices(v1, e->vertex(1));
     436              :                                 else
     437            0 :                                         ed.set_vertices(e->vertex(0), v1);
     438              : 
     439            0 :                                 Edge* existingEdge = grid.get_edge(ed);
     440            0 :                                 if(!existingEdge)
     441            0 :                                         grid.create_by_cloning(e, ed, e);
     442              :                                 else
     443              :                                         grid.objects_will_be_merged(existingEdge, existingEdge, e);
     444              :                         }
     445              :                 }
     446              : 
     447              :         //      create new faces for each face that is connected to v2
     448              :         //      avoid double faces.
     449            0 :                 if(grid.num_faces() > 0)
     450              :                 {
     451            0 :                         FaceDescriptor fd;
     452            0 :                         Grid::AssociatedFaceIterator iterEnd = grid.associated_faces_end(v2);
     453            0 :                         for(Grid::AssociatedFaceIterator iter = grid.associated_faces_begin(v2); iter != iterEnd; ++iter)
     454              :                         {
     455            0 :                                 Face* f = *iter;
     456            0 :                                 uint numVrts = f->num_vertices();
     457              :                                 fd.set_num_vertices(numVrts);
     458            0 :                                 for(uint i = 0; i < numVrts; ++i)
     459              :                                 {
     460            0 :                                         if(f->vertex(i) == v2)
     461              :                                                 fd.set_vertex(i, v1);
     462              :                                         else
     463            0 :                                                 fd.set_vertex(i, f->vertex(i));
     464              :                                 }
     465              : 
     466            0 :                                 Face* existingFace = grid.get_face(fd);
     467            0 :                                 if(!existingFace)
     468            0 :                                         grid.create_by_cloning(f, fd, f);
     469              :                                 else
     470              :                                         grid.objects_will_be_merged(existingFace, existingFace, f);
     471              :                         }
     472              :                 }
     473              : 
     474              :         //      create new volumes for each volume that is connected to v2
     475            0 :                 if(grid.num_volumes() > 0)
     476              :                 {
     477            0 :                         VolumeDescriptor vd;
     478            0 :                         Grid::AssociatedVolumeIterator iterEnd = grid.associated_volumes_end(v2);
     479            0 :                         for(Grid::AssociatedVolumeIterator iter = grid.associated_volumes_begin(v2); iter != iterEnd; ++iter)
     480              :                         {
     481            0 :                                 Volume* v = *iter;
     482            0 :                                 uint numVrts = v->num_vertices();
     483              :                                 vd.set_num_vertices(numVrts);
     484            0 :                                 for(uint i = 0; i < numVrts; ++i)
     485              :                                 {
     486            0 :                                         if(v->vertex(i) == v2)
     487              :                                                 vd.set_vertex(i, v1);
     488              :                                         else
     489            0 :                                                 vd.set_vertex(i, v->vertex(i));
     490              :                                 }
     491              : 
     492              :                                 //assert(!"avoid double volumes! implement FindVolume and use it here.");
     493            0 :                                 grid.create_by_cloning(v, vd, v);
     494              :                         }
     495              :                 }
     496              : 
     497              :         //      new elements have been created. remove the old ones.
     498              :         //      it is sufficient to simply erase v2.
     499            0 :                 grid.erase(v2);
     500              :         }
     501            0 : }
     502              : 
     503              : ////////////////////////////////////////////////////////////////////////
     504            0 : bool IsBoundaryVertex1D(Grid& grid, Vertex* v,
     505              :                                                 Grid::edge_traits::callback cbConsiderEdge)
     506              : {
     507            0 :         if(!grid.option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES))
     508              :         {
     509              :         //      we have to enable this option, since nothing works without it in reasonable time.
     510              :                 LOG("WARNING in IsBoundaryVertex1D(...): auto-enabling VRTOPT_STORE_ASSOCIATED_EDGES.\n");
     511            0 :                 grid.enable_options(VRTOPT_STORE_ASSOCIATED_EDGES);
     512              :         }
     513              : 
     514              : //      iterate over associated edges and return true if only one of them
     515              : //      should be considered for the polygonal chain
     516              :         size_t counter = 0;
     517            0 :         for(Grid::AssociatedEdgeIterator iter = grid.associated_edges_begin(v);
     518            0 :                 iter != grid.associated_edges_end(v); ++iter)
     519              :         {
     520            0 :                 if(cbConsiderEdge(*iter)){
     521            0 :                         ++counter;
     522            0 :                         if(counter > 1)
     523              :                                 return false;
     524              :                 }
     525              :         }
     526              :         
     527              :         return true;
     528              : }
     529              :                                                 
     530              : ////////////////////////////////////////////////////////////////////////
     531            0 : bool IsBoundaryVertex2D(Grid& grid, Vertex* v)
     532              : {
     533              : //      check whether one of the associated edges is a boundary edge.
     534              : //      if so return true.
     535            0 :         if(!grid.option_is_enabled(FACEOPT_AUTOGENERATE_EDGES))
     536              :         {
     537              :         //      we have to enable this option, since we need edges in order to detect boundary vertices.
     538              :                 LOG("WARNING in IsBoundaryVertex2D(...): auto-enabling FACEOPT_AUTOGENERATE_EDGES.\n");
     539            0 :                 grid.enable_options(FACEOPT_AUTOGENERATE_EDGES);
     540              :         }
     541            0 :         if(!grid.option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES))
     542              :         {
     543              :         //      we have to enable this option, since nothing works without it in reasonable time.
     544              :                 LOG("WARNING in IsBoundaryVertex2D(...): auto-enabling VRTOPT_STORE_ASSOCIATED_EDGES.\n");
     545            0 :                 grid.enable_options(VRTOPT_STORE_ASSOCIATED_EDGES);
     546              :         }
     547              : 
     548            0 :         for(Grid::AssociatedEdgeIterator iter = grid.associated_edges_begin(v);
     549            0 :                 iter != grid.associated_edges_end(v); ++iter)
     550              :         {
     551            0 :                 if(IsBoundaryEdge2D(grid, *iter))
     552              :                         return true;
     553              :         }
     554              : 
     555              :         return false;
     556              : }
     557              : 
     558            0 : bool IsBoundaryVertex3D(Grid& grid, Vertex* v)
     559              : {
     560              : //      check whether one of the associated edges is a boundary edge.
     561              : //      if so return true.
     562            0 :         if(!grid.option_is_enabled(VOLOPT_AUTOGENERATE_FACES))
     563              :         {
     564              :         //      we have to enable this option, since we need edges in order to detect boundary vertices.
     565              :                 LOG("  WARNING in IsBoundaryVertex2D(...): auto-enabling VOLOPT_AUTOGENERATE_FACES.\n");
     566            0 :                 grid.enable_options(VOLOPT_AUTOGENERATE_FACES);
     567              :         }
     568            0 :         if(!grid.option_is_enabled(VRTOPT_STORE_ASSOCIATED_FACES))
     569              :         {
     570              :         //      we have to enable this option, since nothing works without it in reasonable time.
     571              :                 LOG("  WARNING in IsBoundaryVertex2D(...): auto-enabling VRTOPT_STORE_ASSOCIATED_FACES.\n");
     572            0 :                 grid.enable_options(VRTOPT_STORE_ASSOCIATED_FACES);
     573              :         }
     574              : 
     575            0 :         for(Grid::AssociatedFaceIterator iter = grid.associated_faces_begin(v);
     576            0 :                 iter != grid.associated_faces_end(v); ++iter)
     577              :         {
     578            0 :                 if(IsVolumeBoundaryFace(grid, *iter))
     579              :                         return true;
     580              :         }
     581              : 
     582              :         return false;
     583              : }
     584              : 
     585            0 : bool LiesOnBoundary(Grid& grid, Vertex* v)
     586              : {
     587            0 :         if(IsBoundaryVertex1D(grid, v))
     588              :                 return true;
     589              : 
     590            0 :         if((grid.num<Face>() > 0) && IsBoundaryVertex2D(grid, v))
     591              :                 return true;
     592              : 
     593            0 :         if((grid.num<Volume>() > 0) && IsBoundaryVertex3D(grid, v))
     594              :                 return true;
     595              : 
     596              :         return false;
     597              : }
     598              : 
     599              : 
     600              : ////////////////////////////////////////////////////////////////////////
     601            0 : bool IsRegularSurfaceVertex(Grid& grid, Vertex* v)
     602              : {
     603              : //      check how many faces each associated edge has
     604            0 :         Grid::AssociatedEdgeIterator edgesEnd = grid.associated_edges_end(v);
     605            0 :         for(Grid::AssociatedEdgeIterator iter = grid.associated_edges_begin(v);
     606            0 :                 iter != edgesEnd; ++iter)
     607              :         {
     608            0 :                 if(NumAssociatedFaces(grid, *iter) != 2)
     609              :                         return false;
     610              :         }
     611              :         return true;
     612              : }
     613              : 
     614              : ////////////////////////////////////////////////////////////////////////
     615            0 : void MarkFixedCreaseVertices(Grid& grid, SubsetHandler& sh,
     616              :                                                         int creaseSI, int fixedSI)
     617              : {
     618              : //      if there are no crease-edges then there is nothing to do.
     619            0 :         if((int)sh.num_subsets() <= creaseSI)
     620              :                 return;
     621            0 :         if(sh.num<Edge>(creaseSI) == 0)
     622              :                 return;
     623              : 
     624              : //      begin marking
     625            0 :         grid.begin_marking();
     626              : //      iterate over all crease-edges
     627              :         for(EdgeIterator iter = sh.begin<Edge>(creaseSI);
     628            0 :                 iter != sh.end<Edge>(creaseSI); ++iter)
     629              :         {
     630              :         //      check for both vertices whether they are fixed-vertices
     631            0 :                 for(int i = 0; i < 2; ++i)
     632              :                 {
     633            0 :                         Vertex* v = (*iter)->vertex(i);
     634              :                 //      if the vertex is not marked (has not been checked yet)
     635            0 :                         if(!grid.is_marked(v))
     636              :                         {
     637              :                         //      mark it
     638              :                                 grid.mark(v);
     639              :                         //      count associated crease edges
     640              :                                 int counter = 0;
     641            0 :                                 Grid::AssociatedEdgeIterator aeIterEnd = grid.associated_edges_end(v);
     642            0 :                                 for(Grid::AssociatedEdgeIterator aeIter = grid.associated_edges_begin(v);
     643            0 :                                         aeIter != aeIterEnd; ++aeIter)
     644              :                                 {
     645            0 :                                         if(sh.get_subset_index(*aeIter) == creaseSI)
     646              :                                         {
     647              :                                         //      the edge is a crease-edge. Increase the counter.
     648            0 :                                                 ++counter;
     649              :                                         //      if the counter is higher than 2, the vertex is a fixed vertex.
     650            0 :                                                 if(counter > 2)
     651              :                                                 {
     652            0 :                                                         sh.assign_subset(v, fixedSI);
     653              :                                                         break;
     654              :                                                 }
     655              :                                         }
     656              :                                 }
     657              :                         }
     658              :                 }
     659              :         }
     660              : 
     661              : //      end marking
     662            0 :         grid.end_marking();
     663              : }
     664              : 
     665              : }//     end of namespace
        

Generated by: LCOV version 2.0-1