LCOV - code coverage report
Current view: top level - ugbase/lib_grid/algorithms/extrusion - extrude.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 84 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 8 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 "extrude.h"
      34              : #include "common/util/hash.h"
      35              : #include "lib_grid/algorithms/orientation_util.h"
      36              : #include "lib_grid/algorithms/geom_obj_util/face_util.h"
      37              : #include "lib_grid/algorithms/geom_obj_util/volume_util.h"
      38              : 
      39              : using namespace std;
      40              : 
      41              : namespace ug
      42              : {
      43              : 
      44            0 : static bool ExtrusionHelper_CheckOrientation(Volume* v, Grid::VertexAttachmentAccessor<Attachment<vector1> >& aaPos)
      45              : {
      46            0 :     UG_THROW("Can't check orientation of a degenerated volume element!");
      47              :     return false;
      48              : }
      49              : 
      50            0 : static bool ExtrusionHelper_CheckOrientation(Volume* v, Grid::VertexAttachmentAccessor<Attachment<vector2> >& aaPos)
      51              : {
      52            0 :     UG_THROW("Can't check orientation of a degenerated volume element!");
      53              :     return false;
      54              : }
      55              : 
      56              : static bool ExtrusionHelper_CheckOrientation(Volume* v, Grid::VertexAttachmentAccessor<Attachment<vector3> >& aaPos)
      57              : {
      58            0 :     return CheckOrientation(v, aaPos);
      59              : }
      60              : 
      61              : ////////////////////////////////////////////////////////////////////////
      62              : //      Extrude
      63              : template <class vector_t>
      64            0 : void Extrude(Grid& grid,
      65              :                         std::vector<Vertex*>* pvVerticesInOut,
      66              :                         std::vector<Edge*>* pvEdgesInOut,
      67              :                         std::vector<Face*>* pvFacesInOut,
      68              :                         const vector_t& direction,
      69              :                         uint extrusionOptions,
      70              :                         Attachment<vector_t>& aPos,
      71              :                         std::vector<Volume*>* pvVolsOut)
      72              : {
      73              :         UG_DLOG(LIB_GRID, 0, "extruding...\n");
      74              :         
      75            0 :         if(!grid.has_vertex_attachment(aPos))
      76            0 :                 grid.attach_to_vertices(aPos);
      77              : 
      78              :         Grid::VertexAttachmentAccessor<Attachment<vector_t> > aaPos(grid, aPos);
      79              : 
      80            0 :         Extrude(grid, pvVerticesInOut, pvEdgesInOut, pvFacesInOut,
      81              :                         direction, aaPos, extrusionOptions, pvVolsOut);
      82            0 : }
      83              : 
      84              : template <class TAAPos>
      85            0 : void Extrude(Grid& grid,
      86              :                         std::vector<Vertex*>* pvVerticesInOut,
      87              :                         std::vector<Edge*>* pvEdgesInOut,
      88              :                         std::vector<Face*>* pvFacesInOut,
      89              :                         const typename TAAPos::ValueType& direction,
      90              :                         TAAPos aaPos,
      91              :                         uint extrusionOptions,
      92              :                         std::vector<Volume*>* pvVolsOut)
      93              : {
      94            0 :         if(pvVolsOut)
      95              :                 pvVolsOut->clear();
      96              : 
      97              : //TODO: find a better guess.
      98              : //      first we'll determine the rough size of the hash.
      99              : //      we'll simply add all vertices, edges and faces.
     100              :         uint hashSize = 10;
     101              :         uint numNewFaces = 0;// the number of faces that are generated directly in this method (autogeneration during volume-extrude is not regarded).
     102            0 :         if(pvVerticesInOut)
     103            0 :                 hashSize += pvVerticesInOut->size();
     104            0 :         if(pvEdgesInOut){
     105            0 :                 hashSize += pvEdgesInOut->size();
     106              :                 numNewFaces += pvEdgesInOut->size();
     107              :         }
     108            0 :         if(pvFacesInOut){
     109            0 :                 hashSize += pvFacesInOut->size();
     110            0 :                 numNewFaces += pvFacesInOut->size();
     111              :         }
     112              : 
     113            0 :         if(hashSize == 0)
     114            0 :                 return;
     115              : 
     116              : //      the hash:
     117              :         typedef Hash<uint, Vertex*> VertexHash;
     118            0 :         VertexHash vrtHash(hashSize);
     119              :         vrtHash.reserve(hashSize);
     120              : 
     121              : //      we'll record created faces in this vector, since we have to fix the
     122              : //      orientation later on (only if pvEdgesInOut has been specified).
     123              :         vector<Face*> vNewFaces;
     124              :         bool bRecordNewFaces = false;
     125            0 :         if((pvEdgesInOut != NULL) && (extrusionOptions & EO_CREATE_FACES))
     126              :         {
     127            0 :                 if(!pvEdgesInOut->empty()){
     128              :                         bRecordNewFaces = true;
     129            0 :                         vNewFaces.resize(numNewFaces);
     130              :                 }
     131              :         }
     132              :         
     133              :         size_t newFaceCount = 0;
     134              : //      if faces are extruded we want them in the first section of vNewFaces (they shall define the orientation).
     135              : //      Thats why we start in the second section in this case.
     136            0 :         if(pvFacesInOut)
     137              :                 newFaceCount = pvFacesInOut->size();
     138              : 
     139              : //      first we'll extrude all vertices. For each a new edge will be created.
     140            0 :         if(pvVerticesInOut)
     141              :         {
     142              :                 UG_DLOG(LIB_GRID, 1, "  extruding vertices: " << pvVerticesInOut->size() << endl);
     143              :                 vector<Vertex*>& vVertices = *pvVerticesInOut;
     144            0 :                 for(uint i = 0; i < vVertices.size(); ++i)
     145              :                 {
     146            0 :                         Vertex* vOld = vVertices[i];
     147              :                 //      create a new vertex and store it in the hash.
     148              :                 //      use the attachment_data_index of the old one as key.
     149              :                 //      WARNING: this is only secure as long as nobody calls defragment while the hash is active!
     150            0 :                         Vertex* v = *grid.create<RegularVertex>(vOld);
     151            0 :                         vrtHash.insert(grid.get_attachment_data_index(vOld), v);
     152              : 
     153              :                 //      calculate new position
     154              :                         aaPos[v] = aaPos[vOld];
     155              :                         VecAdd(aaPos[v], aaPos[v], direction);
     156              : 
     157              :                 //      create an edge between both vertices.
     158            0 :                         grid.create<RegularEdge>(EdgeDescriptor(vOld, v), vOld);
     159              : 
     160              :                 //      overwrite the vertex in pvVerticesInOut
     161            0 :                         vVertices[i] = v;
     162              :                 }
     163              :                 UG_DLOG(LIB_GRID, 1, "  extruding vertices done.\n");
     164              :         }
     165              : 
     166              : //      now extrude edges.
     167            0 :         if(pvEdgesInOut)
     168              :         {
     169              :                 UG_DLOG(LIB_GRID, 1, "  extruding edges: " << pvEdgesInOut->size() << endl);
     170              :                 vector<Edge*>& vEdges = *pvEdgesInOut;
     171            0 :                 for(uint i = 0; i < vEdges.size(); ++i)
     172              :                 {
     173            0 :                         Edge* e = vEdges[i];
     174              : 
     175              :                 //      check for both boundary points whether the new vertices have already been created.
     176              :                 //      if not then create them here and store them.
     177              :                         Vertex* v[2];
     178              : 
     179            0 :                         for(uint j = 0; j < 2; ++j)
     180              :                         {
     181            0 :                                 if(!vrtHash.get_entry(v[j], grid.get_attachment_data_index(e->vertex(j))))
     182              :                                 {
     183            0 :                                         v[j] = *grid.create<RegularVertex>(e->vertex(j));
     184            0 :                                         vrtHash.insert(grid.get_attachment_data_index(e->vertex(j)), v[j]);
     185              :                                 //      calculate new position
     186            0 :                                         aaPos[v[j]] = aaPos[e->vertex(j)];
     187              :                                         VecAdd(aaPos[v[j]], aaPos[v[j]], direction);
     188              :                                 }
     189              :                         }
     190              : 
     191              :                 //      both new vertices exist now.
     192              :                 //      create the new edge
     193            0 :                         RegularEdge* eNew = *grid.create<RegularEdge>(EdgeDescriptor(v[0], v[1]), e);
     194              : 
     195              :                 //      overwrite the edge in pvEdgesInOut
     196            0 :                         vEdges[i] = eNew;
     197              : 
     198              :                 //      finally create the face.
     199            0 :                         if(extrusionOptions & EO_CREATE_FACES)
     200              :                         {
     201              :                         //      create a quadrilateral from the four points.
     202              :                         //      the orientation will be done later on.
     203            0 :                                 Face* f = *grid.create<Quadrilateral>(QuadrilateralDescriptor(v[0], v[1], e->vertex(1), e->vertex(0)), e);
     204            0 :                                 vNewFaces[newFaceCount++] = f;
     205              :                         }
     206              :                 }
     207              :                 UG_DLOG(LIB_GRID, 1, "  extrunding edges done.\n");
     208              :         }
     209              : 
     210              : //      now extrude faces.
     211            0 :         if(pvFacesInOut)
     212              :         {
     213              :                 UG_DLOG(LIB_GRID, 1, "  extruding faces: " << pvFacesInOut->size() << endl);
     214              :         //      fill the first section of vNewFaces
     215              :                 newFaceCount = 0;
     216              : 
     217              :                 vector<Face*>& vFaces = *pvFacesInOut;
     218            0 :                 for(uint i = 0; i < vFaces.size(); ++i)
     219              :                 {
     220            0 :                         Face* f = vFaces[i];
     221              :                         assert(f->num_vertices() < 5 && "can't deal with faces that have more than 4 vertices!");
     222              : 
     223              :                 //      check for all points whether the new vertices have already been created.
     224              :                 //      if not then create them here and store them.
     225              :                         Vertex* v[4];
     226              : 
     227            0 :                         uint numVrts = f->num_vertices();
     228              : 
     229            0 :                         for(uint j = 0; j < numVrts; ++j)
     230              :                         {
     231            0 :                                 uint oldVrtInd = grid.get_attachment_data_index(f->vertex(j));
     232            0 :                                 if(!vrtHash.get_entry(v[j], oldVrtInd)){
     233            0 :                                         v[j] = *grid.create<RegularVertex>(f->vertex(j));
     234            0 :                                         vrtHash.insert(oldVrtInd, v[j]);
     235              :                                 //      calculate new position
     236            0 :                                         aaPos[v[j]] = aaPos[f->vertex(j)];
     237              :                                         VecAdd(aaPos[v[j]], aaPos[v[j]], direction);
     238              :                                 }
     239              :                         }
     240              : 
     241              :                 //      all new vertices exist now.
     242              :                 //      create the new face
     243              :                         Face* fNew = NULL;
     244            0 :                         Volume* vol = NULL;
     245            0 :                         if(numVrts == 3)
     246              :                         {
     247              :                                 UG_DLOG(LIB_GRID, 2, "    " << i << ": creating tri...\n");
     248            0 :                                 fNew = *grid.create<Triangle>(TriangleDescriptor(v[0], v[1], v[2]), f);
     249              : 
     250              :                         //      create the volume
     251            0 :                                 if(extrusionOptions & EO_CREATE_VOLUMES)
     252              :                                 {
     253            0 :                                         Prism prism(f->vertex(0), f->vertex(1), f->vertex(2),
     254            0 :                                                                 fNew->vertex(0), fNew->vertex(1), fNew->vertex(2));
     255              :                                         
     256              :                                 //      check the orientation and create the prism
     257            0 :                                         if (!ExtrusionHelper_CheckOrientation(&prism, aaPos)){
     258            0 :                                                 VolumeDescriptor vd;
     259            0 :                                                 prism.get_flipped_orientation(vd);
     260            0 :                                                 vol = *grid.create_by_cloning(&prism, vd, f);       
     261              :                                         }
     262              :                                         else
     263            0 :                                                 vol = *grid.create_by_cloning(&prism, prism, f);                                    
     264              : 
     265              :                                 }
     266              :                         }
     267            0 :                         else if(numVrts == 4)
     268              :                         {
     269              :                                 UG_DLOG(LIB_GRID, 2, "    " << i << ": creating quad...\n");
     270            0 :                                 fNew = *grid.create<Quadrilateral>(QuadrilateralDescriptor(v[0], v[1], v[2], v[3]), f);
     271              : 
     272              :                         //      create the volume
     273            0 :                                 if(extrusionOptions & EO_CREATE_VOLUMES)
     274              :                                 {
     275            0 :                                         Hexahedron hex(f->vertex(0), f->vertex(1), f->vertex(2), f->vertex(3),
     276            0 :                                                                    fNew->vertex(0), fNew->vertex(1), fNew->vertex(2), fNew->vertex(3));
     277              :                                         
     278              :                                 //      check the orientation and create the hexahedron
     279            0 :                                         if(!ExtrusionHelper_CheckOrientation(&hex, aaPos)){
     280            0 :                                                 VolumeDescriptor vd;
     281            0 :                                                 hex.get_flipped_orientation(vd);
     282            0 :                                                 vol = *grid.create_by_cloning(&hex, vd, f); 
     283              :                                         }
     284              :                                         else
     285            0 :                                                 vol = *grid.create_by_cloning(&hex, hex, f);                                        
     286              :                                 }
     287              :                         }
     288              :                         else{
     289              :                                 assert(!"face has bad number of vertices!");
     290              :                         }
     291              : 
     292            0 :                         if(fNew){
     293              :                         //      overwrite the face in pvFacesInOut
     294            0 :                                 vFaces[i] = fNew;
     295              :                         //      store the face in vNewFaces - but only if we have
     296              :                         //      to re-orientate them later on.
     297            0 :                                 if(bRecordNewFaces){
     298              :                                         UG_DLOG(LIB_GRID, 2, "    storing face for reordering...\n");
     299            0 :                                         vNewFaces[newFaceCount++] = fNew;
     300              :                                 }
     301              :                         }
     302              : 
     303            0 :                         if(pvVolsOut && vol)
     304            0 :                                 pvVolsOut->push_back(vol);
     305              :                 }
     306              :                 UG_DLOG(LIB_GRID, 1, "  extruding faces done.\n");
     307              :         }
     308              : 
     309              : //      if faces were extruded from edges, we have to fix the orientation now
     310              :         // if(bRecordNewFaces){
     311              :         //      UG_DLOG(LIB_GRID, 1, "  reordering faces...\n");
     312              :         //      FixFaceOrientation(grid, vNewFaces.begin(), vNewFaces.end());
     313              :         //      UG_DLOG(LIB_GRID, 1, "  reordering faces done.\n");
     314              :         // }
     315            0 : }
     316              : 
     317              : template void Extrude<vector1>(Grid&,
     318              :                                                                 std::vector<Vertex*>*,
     319              :                                                                 std::vector<Edge*>*,
     320              :                                                                 std::vector<Face*>*,
     321              :                                                                 const vector1&,
     322              :                                                                 uint,
     323              :                                                                 Attachment<vector1>&,
     324              :                                                                 std::vector<Volume*>*);
     325              : 
     326              : template void Extrude<vector2>(Grid&,
     327              :                                                                 std::vector<Vertex*>*,
     328              :                                                                 std::vector<Edge*>*,
     329              :                                                                 std::vector<Face*>*,
     330              :                                                                 const vector2&,
     331              :                                                                 uint,
     332              :                                                                 Attachment<vector2>&,
     333              :                                                                 std::vector<Volume*>*);
     334              : 
     335              : template void Extrude<vector3>(Grid&,
     336              :                                                                 std::vector<Vertex*>*,
     337              :                                                                 std::vector<Edge*>*,
     338              :                                                                 std::vector<Face*>*,
     339              :                                                                 const vector3&,
     340              :                                                                 uint,
     341              :                                                                 Attachment<vector3>&,
     342              :                                                                 std::vector<Volume*>*);
     343              : 
     344              : template void Extrude<Grid::VertexAttachmentAccessor<Attachment<vector1> > >(
     345              :                                                                 Grid&,
     346              :                                                                 std::vector<Vertex*>*,
     347              :                                                                 std::vector<Edge*>*,
     348              :                                                                 std::vector<Face*>*,
     349              :                                                                 const vector1&,
     350              :                                                                 Grid::VertexAttachmentAccessor<Attachment<vector1> >,
     351              :                                                                 uint,
     352              :                                                                 std::vector<Volume*>*);
     353              : 
     354              : template void Extrude<Grid::VertexAttachmentAccessor<Attachment<vector2> > >(
     355              :                                                                 Grid&,
     356              :                                                                 std::vector<Vertex*>*,
     357              :                                                                 std::vector<Edge*>*,
     358              :                                                                 std::vector<Face*>*,
     359              :                                                                 const vector2&,
     360              :                                                                 Grid::VertexAttachmentAccessor<Attachment<vector2> >,
     361              :                                                                 uint,
     362              :                                                                 std::vector<Volume*>*);
     363              : 
     364              : template void Extrude<Grid::VertexAttachmentAccessor<Attachment<vector3> > >(
     365              :                                                                 Grid&,
     366              :                                                                 std::vector<Vertex*>*,
     367              :                                                                 std::vector<Edge*>*,
     368              :                                                                 std::vector<Face*>*,
     369              :                                                                 const vector3&,
     370              :                                                                 Grid::VertexAttachmentAccessor<Attachment<vector3> >,
     371              :                                                                 uint,
     372              :                                                                 std::vector<Volume*>*);
     373              : }//     end of namespace
        

Generated by: LCOV version 2.0-1