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

            Line data    Source code
       1              : /*
       2              :  * expand_layers_arte.cpp
       3              :  *
       4              :  *  Created on: 5.8.2024
       5              :  *      Author: Markus M. Knodel
       6              :   * This file is part of UG4.
       7              :  * 
       8              :  * UG4 is free software: you can redistribute it and/or modify it under the
       9              :  * terms of the GNU Lesser General Public License version 3 (as published by the
      10              :  * Free Software Foundation) with the following additional attribution
      11              :  * requirements (according to LGPL/GPL v3 §7):
      12              :  * 
      13              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      14              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      15              :  * 
      16              :  * (2) The following notice must be displayed at a prominent place in the
      17              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      18              :  * 
      19              :  * (3) The following bibliography is recommended for citation and must be
      20              :  * preserved in all covered files:
      21              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      22              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      23              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      24              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      25              :  *   flexible software system for simulating pde based models on high performance
      26              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      27              :  * 
      28              :  * This program is distributed in the hope that it will be useful,
      29              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      30              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      31              :  * GNU Lesser General Public License for more details.
      32              :  */
      33              : 
      34              : #include <boost/function.hpp>
      35              : 
      36              : #include "expand_layers.h"
      37              : #include "expand_layers_arte.h"
      38              : #include "lib_grid/algorithms/geom_obj_util/geom_obj_util.h"
      39              : #include "lib_grid/callbacks/callbacks.h"
      40              : #include "lib_grid/grid/grid_util.h"
      41              : 
      42              : #include <stack>
      43              : #include <utility>
      44              : #include <vector>
      45              : #include <type_traits>
      46              : #include <limits>
      47              : #include <atomic>
      48              : #include <cstddef>
      49              : #include <bitset>
      50              : #include <string>
      51              : #include <cmath>
      52              : 
      53              : #include "support.h"
      54              : 
      55              : 
      56              : using namespace std;
      57              : 
      58              : namespace ug{
      59              : 
      60              : //using namespace ug::support;
      61              : 
      62              : using VertFracTrip = VertexFractureTriple<Edge*, Face*, vector3>;
      63              : 
      64              : //using VecVertFracTrip = std::vector<VertFracTrip>;
      65              : 
      66              : //using VvftIterator = VecVertFracTrip::iterator;
      67              : 
      68              : using AttVrtVec = Attachment<std::vector<Vertex*> >;
      69              : 
      70              : //using VertexOfFaceInfo = VertexFractureTriple< std::pair<Edge*, Edge*>, Face*, std::pair<vector3,vector3> >;
      71              : //
      72              : //using SegmentsFractExtrus = std::vector<VecVertexOfFaceInfo>;
      73              : 
      74              : using IndexType = unsigned short;
      75              : 
      76              : //using ShiftInfoBasis = std::pair<Edge*, vector3>;
      77              : //
      78              : //using ShiftInfoSegment = std::pair<ShiftInfoBasis,ShiftInfoBasis>;
      79              : 
      80              : //using CrossVertInf = CrossingVertexInfo<Vertex*, IndexType, Edge*, Face* >;
      81              : //using CrossVertInf = CrossingVertexInfo<Vertex*, IndexType, Edge*, ShiftInfoSegment  >;
      82              : using CrossVertInf = CrossingVertexInfo<Vertex*, IndexType >; //, Edge* >;
      83              : 
      84              : 
      85              : 
      86              : 
      87              : // for cases with one fracture and no crossing points
      88              : template <typename ASOF >
      89              : bool expandSingleFractureAtGivenSide( vector3 const & nOne, vector3 const & nTwo,
      90              :                                                                           Edge * edgeOne, Edge * edgeTwo,
      91              :                                                                           Face * facOne, Face * facTwo,
      92              :                                                                           vector<FractureInfo> const & fracInfosBySubset,
      93              :                                                                           vector3 const & posOldVrt,
      94              :                                                                           Grid::VertexAttachmentAccessor<APosition> & aaPos,
      95              :                                                                           Grid & grid, SubsetHandler & sh,
      96              :                                                                           ASOF const & assoFaces,
      97              :                                                                           std::vector<Vertex *> const & nextFracVrt,
      98              :                                                                           Grid::FaceAttachmentAccessor<AttVrtVec> & aaVrtVecFace,
      99              :                                                                           int & dbg_flachen_passiert,
     100              :                                                                           Vertex * iterV                                                                          )
     101              : {
     102              : 
     103              :         CrossVertInf cvi( nullptr, 0 );
     104              : 
     105              :         return expandSingleFractureAtGivenSide( nOne, nTwo,
     106              :                           edgeOne, edgeTwo,
     107              :                           facOne, facTwo,
     108              :                           fracInfosBySubset,
     109              :                           posOldVrt,
     110              :                           aaPos,
     111              :                           grid, sh,
     112              :                           assoFaces,
     113              :                           nextFracVrt,
     114              :                           aaVrtVecFace,
     115              :                           dbg_flachen_passiert,
     116              :                           iterV,
     117              :                           cvi,
     118              :                           false
     119              :                           );
     120              : }
     121              : 
     122              : // for the case of crossing points
     123              : template <typename ASOF >
     124              : bool expandSingleFractureAtGivenSide( vector3 const & nOne, vector3 const & nTwo,
     125              :                                                                           Edge * edgeOne, Edge * edgeTwo,
     126              :                                                                           Face * facOne, Face * facTwo,
     127              :                                                                           vector<FractureInfo> const & fracInfosBySubset,
     128              :                                                                           vector3 const & posOldVrt,
     129              :                                                                           Grid::VertexAttachmentAccessor<APosition> & aaPos,
     130              :                                                                           Grid & grid, SubsetHandler & sh,
     131              :                                                                           ASOF const & assoFaces,
     132              :                                                                           std::vector<Vertex *> const & nextFracVrt,
     133              :                                                                           Grid::FaceAttachmentAccessor<AttVrtVec> & aaVrtVecFace,
     134              :                                                                           int & dbg_flachen_passiert,
     135              :                                                                           Vertex * iterV,
     136              :                                                                           CrossVertInf & crossVrtInf,
     137              :                                                                           bool insertCrossVrtInf = true
     138              :                                                                           )
     139              : {
     140              : 
     141              : #if 1
     142              :         // gleiche Seite vermutet oder gegeben
     143              : 
     144              :         // average the normals -- das wird wohl der Fehler sein, wenn n1 und n2 nicht fast parallel sind, wenn man davon ausgehend
     145              :         // bestimmt, auf welcher Seite benachbarte Dreiecke liegen, zur Berechnung des Verschiebevektors ist es aber gut
     146              : 
     147              :         vector3 normSum;
     148              : 
     149              :         VecAdd( normSum, nOne, nTwo );
     150              : 
     151              :         vector3 normSumNormed;
     152              : 
     153              :         VecNormalize(normSumNormed, normSum);
     154              : 
     155              :         UG_LOG("averaged normal " << normSumNormed << std::endl);
     156              : 
     157              :         std::vector<Edge * > attEdg;
     158              :         std::vector<Face * > attFac;
     159              : 
     160              :         attEdg.push_back( edgeOne );
     161              :         attEdg.push_back( edgeTwo );
     162              : 
     163              :         attFac.push_back( facOne );
     164              :         attFac.push_back( facTwo );
     165              : 
     166              :         // jetzt neuen Vertex erzeugen in Richtung der Normalen
     167              :         // sonst ist das attachment Schwachsinn!
     168              : 
     169              :         vector3 posNewVrt;
     170              : 
     171              :         vector3 moveVrt;
     172              : 
     173              :         auto subsIndEdgOne = sh.get_subset_index(edgeOne);
     174              : 
     175              :         auto subsIndEdgTwo = sh.get_subset_index(edgeTwo);
     176              : 
     177              :         if( subsIndEdgOne != subsIndEdgTwo )
     178              :         {
     179              :                 UG_THROW("subsets passen nicht Vereinheitlichung" << std::endl );
     180              :         }
     181              : 
     182              :         number width = fracInfosBySubset.at(subsIndEdgOne).width;
     183              : 
     184              :         // FALSCH
     185              :         // der Faktor ist Käse und muss noch aus den Eingaben übernommen werden
     186              :         VecScale(moveVrt, normSumNormed, width/2. );
     187              : 
     188              :         VecAdd(posNewVrt, posOldVrt, moveVrt );
     189              : 
     190              :         UG_LOG("neuer Vertex " << posNewVrt << std::endl );
     191              : 
     192              :         // TODO FIXME hier ist das PROBLEM, SEGFAULT durch create regular vertex
     193              : 
     194              :         Vertex * newShiftVrtx = *grid.create<RegularVertex>();
     195              :         aaPos[newShiftVrtx] = posNewVrt;
     196              : 
     197              :         sh.assign_subset(newShiftVrtx, subsIndEdgOne );
     198              : 
     199              :         if( insertCrossVrtInf )
     200              :         {
     201              :                 crossVrtInf.addShiftVrtx(newShiftVrtx, true);
     202              :         }
     203              :         // only needed in case of crossing vertices
     204              : 
     205              : 
     206              : 
     207              :         // alle anhängenden faces müssen noch zu wissen bekommen
     208              :         // dass es diesen neuen Vertex gibt, nicht nur die
     209              :         // an den edges anhängenden
     210              :         // vielleicht gibt es einen Loop über attached faces des
     211              :         // Vertex, für die schon bekannten direkt angehängten klar
     212              :         // wenn auch dort vermerkt werden muss im Attachment von Seb
     213              :         // bei den anderen, die keine Edge haben von der Kluft
     214              :         // da muss man die Normale ins Zentrum bestimmen
     215              :         // um heraus zu finden, ob sie auf dieser seite sind
     216              :         // am besten dann das Attachment der faces für vertizes
     217              :         // von Seb recyclen
     218              : 
     219              :         // loop über assosciated faces des vertex am besten
     220              :         // vermutlich auch noch assosciated edges, um
     221              :         // zu markieren, welche weg fallen sollen, wenn
     222              :         // nicht von Kluft selber, sondern quasi verschoben
     223              :         // und neu erzeugt
     224              : 
     225              :         int dbg_FaceIterator = 0;
     226              : 
     227              :         for( auto const & ifac : assoFaces )
     228              :         {
     229              : 
     230              :                 bool isFromFrac = false;
     231              : 
     232              :                 int dbg_innterFacFracIt = 0;
     233              : 
     234              :                 for( auto const & facFrac : attFac )
     235              :                 {
     236              : 
     237              :                         // DEBUG ASSERT TEST static_assert( std::is_same<  decltype( (facFrac) ), decltype ( ifac ) >::value );
     238              : 
     239              :                         if( ifac == facFrac )
     240              :                         {
     241              :                                 isFromFrac = true;
     242              : 
     243              :                                 // DEBUG ASSERT TEST static_assert( std::is_same< decltype( (facFrac) ), Face * const & >::value  );
     244              :                                 // DEBUG ASSERT TEST static_assert( std::is_same< decltype( (facFrac) ), decltype( ifac ) >::value  );
     245              : 
     246              :                         }
     247              :                 }
     248              : 
     249              : //              if( ifac == facOne || ifac == facTwo )
     250              : //                      isFromFrac = true;
     251              : 
     252              : //              if( FaceContains(facOne,edgeOne) || FaceContains(facTwo,edgeTwo) )
     253              : //                      isFromFrac = true;
     254              : 
     255              : 
     256              :                 bool atRightSide = false;
     257              : 
     258              :                 if( isFromFrac )
     259              :                         atRightSide = true;
     260              : 
     261              :                 if( !isFromFrac )
     262              :                 {
     263              :                         // check if on same side of edge where the normal points to: compute cosinus between vector of face center
     264              :                         //  perpendicular to the edge
     265              :                         // hier liegt wohl aber ein Fehler vor, wenn die beiden Ecken in einem Winkel zueinander stehen, der nicht fast parallel ist
     266              : 
     267              :                         vector3 facCenter = CalculateCenter( ifac, aaPos );
     268              : 
     269              :                         vector3 perpendicu;
     270              : 
     271              :                         constexpr bool decideSideBasedOnAveragedEdges = false;
     272              : 
     273              :                         if( nextFracVrt.size() != 2 )
     274              :                         {
     275              :                                 UG_THROW("komische Groesse" << std::endl);
     276              :                         }
     277              : 
     278              :                         if( decideSideBasedOnAveragedEdges )
     279              :                         {
     280              :                                 DropAPerpendicular(perpendicu, facCenter, aaPos[nextFracVrt[0]], aaPos[nextFracVrt[1]]);
     281              : 
     282              :                                 vector3 tmpN;
     283              : 
     284              :                                 VecSubtract(tmpN, facCenter, perpendicu );
     285              : 
     286              :                                 VecNormalize(tmpN, tmpN);
     287              : 
     288              :                                 UG_LOG("Normale zum Face ist " << tmpN << std::endl);
     289              : 
     290              :                                 number cosBetwFracEdgAndDirection2Face = VecDot(tmpN, normSumNormed );
     291              : 
     292              :                                 UG_LOG("Cosinus zur Normalen ist " << cosBetwFracEdgAndDirection2Face << std::endl);
     293              : 
     294              :                                 if( cosBetwFracEdgAndDirection2Face > 0 )
     295              :                                 {
     296              :                                         UG_LOG("assuming face to be on richt side" << std::endl);
     297              : 
     298              :                                         atRightSide = true;
     299              : 
     300              : 
     301              : #if ESTABLISH_DEBUG_SUDOS
     302              : 
     303              :                                         Vertex * otherFacCent = *grid.create<RegularVertex>();
     304              :                                         aaPos[otherFacCent] = facCenter;
     305              :         //                              sh.assign_subset(otherFacCent, 5 );
     306              :                                         sh.assign_subset(otherFacCent, sh.num_subsets() );
     307              : 
     308              :                                         Vertex * pp = *grid.create<RegularVertex>();
     309              :                                         aaPos[pp] = perpendicu;
     310              :                                         sh.assign_subset(pp, sh.num_subsets() );
     311              :         //                              sh.assign_subset(pp, 6 );
     312              : 
     313              :         //                              sh.assign_subset(*iterFac,7);
     314              :                                         sh.assign_subset( *iterFac, sh.num_subsets() );
     315              : #endif
     316              : 
     317              :                                 }
     318              :                                 else
     319              :                                 {
     320              :                                         UG_LOG("assuming face to be on wrong side" << std::endl);
     321              :                                 }
     322              :                         }
     323              :                         else // vielleicht besser so?
     324              :                         {
     325              : 
     326              :                                 // dicide first to which of the edges the center is more close
     327              : 
     328              :                                 vector3 perpendOne, perpendTwo;
     329              : 
     330              :                                 DropAPerpendicular(perpendOne, facCenter, aaPos[edgeOne->vertex(0)], aaPos[edgeOne->vertex(1)] );
     331              :                                 DropAPerpendicular(perpendTwo, facCenter, aaPos[edgeTwo->vertex(0)], aaPos[edgeTwo->vertex(1)] );
     332              : 
     333              :                                 vector3 distOne, distTwo;
     334              : 
     335              :                                 VecSubtract(distOne, facCenter, perpendOne );
     336              :                                 VecSubtract(distOne, facCenter, perpendTwo );
     337              : 
     338              :                                 auto lengthOne = VecLength(distOne);
     339              :                                 auto lengthTwo = VecLength(distTwo);
     340              : 
     341              :                                 // hier umgedreht, bewirkt Verbewwerung, wieso das?
     342              :                                 bool oneSmallerThanTwo = ( lengthOne < lengthTwo );
     343              :                                 // correct assumption?
     344              :                                 //Edge * closerEdge = ( lengthOne > lengthTwo ) ? edgeTwo : edgeOne;
     345              :                                 vector3 distMin = oneSmallerThanTwo ? distTwo : distOne;
     346              :                                 vector3 distNorm;
     347              :                                 VecNormalize(distNorm, distMin);
     348              : 
     349              :                                 UG_LOG("Normale zum Face ist " << distNorm << std::endl);
     350              : 
     351              :                                 vector3 normMin = oneSmallerThanTwo ? nTwo : nOne;
     352              :                                 number cosBetwFracEdgAndDirection2Face = VecDot(distNorm, normMin );
     353              : 
     354              :                                 UG_LOG("Cosinus zur Normalen ist " << cosBetwFracEdgAndDirection2Face << std::endl);
     355              : 
     356              :                                 if( cosBetwFracEdgAndDirection2Face > 0 )
     357              :                                 {
     358              :                                         UG_LOG("assuming face to be on richt side" << std::endl);
     359              : 
     360              :                                         atRightSide = true;
     361              : 
     362              : 
     363              : #if ESTABLISH_DEBUG_SUDOS
     364              : 
     365              :                                         Vertex * otherFacCent = *grid.create<RegularVertex>();
     366              :                                         aaPos[otherFacCent] = facCenter;
     367              :         //                              sh.assign_subset(otherFacCent, 5 );
     368              :                                         sh.assign_subset(otherFacCent, sh.num_subsets() );
     369              : 
     370              :                                         Vertex * pp = *grid.create<RegularVertex>();
     371              :                                         aaPos[pp] = perpendicu;
     372              :                                         sh.assign_subset(pp, sh.num_subsets() );
     373              :         //                              sh.assign_subset(pp, 6 );
     374              : 
     375              :         //                              sh.assign_subset(*iterFac,7);
     376              :                                         sh.assign_subset( *iterFac, sh.num_subsets() );
     377              : #endif
     378              :                                 }
     379              : 
     380              :                         }
     381              : 
     382              :                         dbg_flachen_passiert++;
     383              :                 }
     384              : 
     385              :                 if( atRightSide ) // atRightSide ) NOCH FALSCH TODO FIXME muss nur auf richtiger Seite sein
     386              :                 {
     387              : 
     388              :                         // ACHTUNG neue Variable Face klein geschrieben im Gegensatz zu Prof. Reiter! nicht später falsche verwenden!
     389              :                         vector<Vertex*>& newVrts4Fac = aaVrtVecFace[ ifac ];
     390              : 
     391              :                         IndexType vrtxFnd = 0;
     392              : 
     393              :                         for(size_t indVrt = 0; indVrt < (ifac)->num_vertices();  indVrt++ )
     394              :                         {
     395              :                                 Vertex* facVrt = (ifac)->vertex(indVrt);
     396              : 
     397              :                                 if(  facVrt == iterV )
     398              :                                 {
     399              :                                         newVrts4Fac[ indVrt ] = newShiftVrtx;
     400              :                                         vrtxFnd++;
     401              :                                 }
     402              :                         }
     403              : 
     404              : //                      if( insertCrossVrtInf )
     405              : //                      {
     406              : ////                            crossVrtInf.setShiftVrtx(newVrts4Fac);
     407              : //                              crossVrtInf.addShiftVrtx(newVrts4Fac, true);
     408              : //                      }
     409              : //                      // only needed in case of crossing vertices
     410              : 
     411              :                         if( vrtxFnd <= 0 )
     412              :                         {
     413              :                                 UG_THROW("vertex not found!" << std::endl);
     414              :                                                                                                 }
     415              :                         else if( vrtxFnd > 1 )
     416              :                         {
     417              :                                 UG_THROW("vertex zu oft gefunden " << vrtxFnd << std::endl );
     418              :                         }
     419              :                         else if ( vrtxFnd == 1 )
     420              :                         {
     421              :                         }
     422              :                         else
     423              :                         {
     424              :                                 UG_THROW("vertex finden komisch " << std::endl);
     425              :                         }
     426              : 
     427              : 
     428              :                 }
     429              : 
     430              :                 dbg_innterFacFracIt++;
     431              : 
     432              : 
     433              : 
     434              :                 dbg_FaceIterator++;
     435              : 
     436              :         }
     437              : #endif
     438              : 
     439              :         return true;
     440              : 
     441              : }
     442              : 
     443              : #if 0
     444              : void createShiftVertexPassingClefts( vector3 const & nOne, vector3 const nTwo, Vertex * & newShiftVrtx, SubsetHandler & sh,
     445              :                 vector3 const & posOldVrt, bool subsEqual = true )
     446              : {
     447              : 
     448              :         auto subsIndEdgOne = sh.get_subset_index(edgeOne);
     449              : 
     450              :         auto subsIndEdgTwo = sh.get_subset_index(edgeTwo);
     451              : 
     452              :         if( subsIndEdgOne != subsIndEdgTwo && subsEqual )
     453              :         {
     454              :                 UG_THROW("subsets passen nicht Vereinheitlichung" << std::endl );
     455              :         }
     456              : 
     457              :         vector3 moveVrt;
     458              : 
     459              :         number cosinus = VecDot(nOne,nTwo);
     460              : 
     461              :         number pi = 3.1415926535897932385;
     462              : 
     463              :         number cosinusLim = std::cos( pi/8. );
     464              : 
     465              :         if( cosinus > cosinusLim )
     466              :         {
     467              :                 vector3 normSum;
     468              : 
     469              :                 VecAdd( normSum, nOne, nTwo );
     470              : 
     471              :                 vector3 normSumNormed;
     472              : 
     473              :                 VecNormalize(normSumNormed, normSum);
     474              : 
     475              :                 UG_LOG("averaged normal " << normSumNormed << std::endl);
     476              : 
     477              :                 std::vector<Edge * > attEdg;
     478              :                 std::vector<Face * > attFac;
     479              : 
     480              :                 attEdg.push_back( edgeOne );
     481              :                 attEdg.push_back( edgeTwo );
     482              : 
     483              :                 attFac.push_back( facOne );
     484              :                 attFac.push_back( facTwo );
     485              : 
     486              :                 // jetzt neuen Vertex erzeugen in Richtung der Normalen
     487              :                 // sonst ist das attachment Schwachsinn!
     488              : 
     489              :                 number widthOne = fracInfosBySubset.at(subsIndEdgOne).width;
     490              :                 number widthTwo = fracInfosBySubset.at(subsIndEdgTwo).width;
     491              : 
     492              :                 number width = ( widthOne + widthTwo ) /2.;
     493              : 
     494              :                 // FALSCH
     495              :                 // der Faktor ist Käse und muss noch aus den Eingaben übernommen werden
     496              :                 VecScale(moveVrt, normSumNormed, width/2. );
     497              : 
     498              :         }
     499              :         else // abknickende Fractures
     500              :         {
     501              : 
     502              :         }
     503              : 
     504              :         vector3 posNewVrt;
     505              : 
     506              :         VecAdd(posNewVrt, posOldVrt, moveVrt );
     507              : 
     508              :         UG_LOG("neuer Vertex " << posNewVrt << std::endl );
     509              : 
     510              :         // TODO FIXME hier ist das PROBLEM, SEGFAULT durch create regular vertex
     511              : 
     512              :         newShiftVrtx = *grid.create<RegularVertex>();
     513              :         aaPos[newShiftVrtx] = posNewVrt;
     514              : 
     515              :         sh.assign_subset(newShiftVrtx, subsIndEdgOne );
     516              : }
     517              : #endif
     518              : 
     519              : using VecVertFracTrip = std::vector<VertFracTrip>;
     520              : 
     521              : // needed for crossing points
     522              : using VertexOfFaceInfo = VertexFractureTriple< std::pair<Edge*, Edge*>, Face*, std::pair<vector3,vector3> >;
     523              : // all edges of the attached face - must always be two, the face itself, and the normal vectors of the face in direction of the two edges
     524              : // the size of the normal vector vector also must be two
     525              : // however, if an edge of the face is not a fracture edge, we do not compute the normal, but assign zero as norm
     526              : // for those edges and faces which are Kluft edges, we assign the normal known from the info computed before, vertex fracture triple
     527              : 
     528              : using VecVertexOfFaceInfo = std::vector<VertexOfFaceInfo>;
     529              : 
     530              : using SegmentsFractExtrus = std::vector<VecVertexOfFaceInfo>;
     531              : 
     532              : 
     533              : 
     534              : 
     535              : template <>
     536              : // for the case of crossing points
     537            0 : bool expandSingleFractureAtGivenSide<VecVertexOfFaceInfo>
     538              :                                                                         ( vector3 const & nOne, vector3 const & nTwo,
     539              :                                                                           Edge * edgeOne, Edge * edgeTwo,
     540              :                                                                           Face * facOne, Face * facTwo,
     541              :                                                                           vector<FractureInfo> const & fracInfosBySubset,
     542              :                                                                           vector3 const & posOldVrt,
     543              :                                                                           Grid::VertexAttachmentAccessor<APosition> & aaPos,
     544              :                                                                           Grid & grid, SubsetHandler & sh,
     545              :                                                                           VecVertexOfFaceInfo const & segPart,
     546              :                                                                           std::vector<Vertex *> const & nextFracVrt,
     547              :                                                                           Grid::FaceAttachmentAccessor<AttVrtVec> & aaVrtVecFace,
     548              :                                                                           int & dbg_flachen_passiert,
     549              :                                                                           Vertex * crossPt,
     550              :                                                                           CrossVertInf & crossVrtInf,
     551              :                                                                           bool insertCrossVrtInf
     552              :                                                                           )
     553              : //
     554              : //                                                                      ( vector3 const & nOne, vector3 const & nTwo,
     555              : //                                                                        Edge * edgeOne, Edge * edgeTwo,
     556              : //                                                                        Face * facOne, Face * facTwo,
     557              : //                                                                        vector<FractureInfo> const & fracInfosBySubset,
     558              : //                                                                        vector3 const & posOldVrt,
     559              : //                                                                        Grid::VertexAttachmentAccessor<APosition> & aaPos,
     560              : //                                                                        Grid & grid, SubsetHandler & sh,
     561              : //                                                                        VecVertexOfFaceInfo const & segPart,
     562              : //                                                                        std::vector<Vertex *> const & nextFracVrt,
     563              : //                                                                        Grid::FaceAttachmentAccessor<AttVrtVec> & aaVrtVecFace,
     564              : //                                                                        int & dbg_flachen_passiert,
     565              : //                                                                        Vertex const * & crossPt,
     566              : //                                                                        CrossVertInf & crossVrtInf,
     567              : //                                                                        bool insertCrossVrtInf // = true
     568              : //                                                                        )
     569              : {
     570              : 
     571              :         // gleiche Seite gegeben
     572              : 
     573              :         // average the normals -- das wird wohl der Fehler sein, wenn n1 und n2 nicht fast parallel sind, wenn man davon ausgehend
     574              :         // bestimmt, auf welcher Seite benachbarte Dreiecke liegen, zur Berechnung des Verschiebevektors ist es aber gut
     575              : 
     576              :         // TODO FIXME fuer grossere Winkel die Methode von XCross Projektionen übernehmen!!!
     577              : 
     578              :         vector3 normSum;
     579              : 
     580              :         VecAdd( normSum, nOne, nTwo );
     581              : 
     582              :         vector3 normSumNormed;
     583              : 
     584            0 :         VecNormalize(normSumNormed, normSum);
     585              : 
     586            0 :         UG_LOG("averaged normal " << normSumNormed << std::endl);
     587              : 
     588              :         std::vector<Edge * > attEdg;
     589              :         std::vector<Face * > attFac;
     590              : 
     591            0 :         attEdg.push_back( edgeOne );
     592            0 :         attEdg.push_back( edgeTwo );
     593              : 
     594            0 :         attFac.push_back( facOne );
     595            0 :         attFac.push_back( facTwo );
     596              : 
     597              :         // jetzt neuen Vertex erzeugen in Richtung der Normalen
     598              :         // sonst ist das attachment Schwachsinn!
     599              : 
     600              :         vector3 posNewVrt;
     601              : 
     602              :         vector3 moveVrt;
     603              : 
     604            0 :         auto subsIndEdgOne = sh.get_subset_index(edgeOne);
     605              : 
     606            0 :         auto subsIndEdgTwo = sh.get_subset_index(edgeTwo);
     607              : 
     608            0 :         if( subsIndEdgOne != subsIndEdgTwo )
     609              :         {
     610            0 :                 UG_THROW("subsets passen nicht Vereinheitlichung" << std::endl );
     611              :         }
     612              : 
     613            0 :         number width = fracInfosBySubset.at(subsIndEdgOne).width;
     614              : 
     615              :         // FALSCH
     616              :         // der Faktor ist Käse und muss noch aus den Eingaben übernommen werden
     617            0 :         VecScale(moveVrt, normSumNormed, width/2. );
     618              : 
     619              :         VecAdd(posNewVrt, posOldVrt, moveVrt );
     620              : 
     621            0 :         UG_LOG("neuer Vertex " << posNewVrt << std::endl );
     622              : 
     623              :         // TODO FIXME hier ist das PROBLEM, SEGFAULT durch create regular vertex
     624              : 
     625            0 :         Vertex * newShiftVrtx = *grid.create<RegularVertex>();
     626              :         aaPos[newShiftVrtx] = posNewVrt;
     627              : 
     628            0 :         sh.assign_subset(newShiftVrtx, subsIndEdgOne );
     629              : 
     630            0 :         if( insertCrossVrtInf )
     631              :         {
     632            0 :                 crossVrtInf.addShiftVrtx(newShiftVrtx, true);
     633              :         }
     634              :         // only needed in case of crossing vertices
     635              : 
     636              : 
     637              : 
     638              :         // alle anhängenden faces müssen noch zu wissen bekommen
     639              :         // dass es diesen neuen Vertex gibt, nicht nur die
     640              :         // an den edges anhängenden
     641              :         // vielleicht gibt es einen Loop über attached faces des
     642              :         // Vertex, für die schon bekannten direkt angehängten klar
     643              :         // wenn auch dort vermerkt werden muss im Attachment von Seb
     644              :         // bei den anderen, die keine Edge haben von der Kluft
     645              :         // da muss man die Normale ins Zentrum bestimmen
     646              :         // um heraus zu finden, ob sie auf dieser seite sind
     647              :         // am besten dann das Attachment der faces für vertizes
     648              :         // von Seb recyclen
     649              : 
     650              :         // loop über assosciated faces des vertex am besten
     651              :         // vermutlich auch noch assosciated edges, um
     652              :         // zu markieren, welche weg fallen sollen, wenn
     653              :         // nicht von Kluft selber, sondern quasi verschoben
     654              :         // und neu erzeugt
     655              : 
     656              :         // TODO FIXME in eigene Funktion stecken, taucht exakt gleich bei XCross auf am Ende!
     657              : 
     658            0 :         for( VertexOfFaceInfo const & vertFracInfoSeg : segPart )
     659              :         {
     660              :                 Face * fac = vertFracInfoSeg.getFace();
     661              : 
     662              : //                                              sh.assign_subset(fa,newSubsToAdd);
     663              : 
     664              : 
     665              :                 // ACHTUNG neue Variable Face klein geschrieben im Gegensatz zu Prof. Reiter! nicht später falsche verwenden!
     666              :                 vector<Vertex*>& newVrts4Fac = aaVrtVecFace[ fac ];
     667              : 
     668              :                 IndexType vrtxFnd = 0;
     669              : 
     670            0 :                 for(size_t indVrt = 0; indVrt < (fac)->num_vertices();  indVrt++ )
     671              :                 {
     672            0 :                         Vertex* facVrt = (fac)->vertex(indVrt);
     673              : 
     674            0 :                         if(  facVrt == crossPt )
     675              :                         {
     676            0 :                                 newVrts4Fac[ indVrt ] = newShiftVrtx;
     677            0 :                                 vrtxFnd++;
     678              : 
     679              : 
     680              :                         }
     681              :                 }
     682              : 
     683            0 :                 if( vrtxFnd <= 0 )
     684              :                 {
     685            0 :                         UG_THROW("vertex not found !" << std::endl);
     686              :                                                                                         }
     687            0 :                 else if( vrtxFnd > 1 )
     688              :                 {
     689            0 :                         UG_THROW("vertex zu oft gefunden  " << vrtxFnd << std::endl );
     690              :                 }
     691              :                 else if ( vrtxFnd == 1 )
     692              :                 {
     693              :                 }
     694              :                 else
     695              :                 {
     696              :                         UG_THROW("vertex finden komisch  " << std::endl);
     697              :                 }
     698              : 
     699              :         }
     700              : 
     701            0 :         return true;
     702              : 
     703            0 : }
     704              : 
     705              : 
     706              : template <>
     707              : // for cases with one fracture and no crossing points
     708            0 : bool expandSingleFractureAtGivenSide<VecVertexOfFaceInfo>
     709              :                                                                         ( vector3 const & nOne, vector3 const & nTwo,
     710              :                                                                           Edge * edgeOne, Edge * edgeTwo,
     711              :                                                                           Face * facOne, Face * facTwo,
     712              :                                                                           vector<FractureInfo> const & fracInfosBySubset,
     713              :                                                                           vector3 const & posOldVrt,
     714              :                                                                           Grid::VertexAttachmentAccessor<APosition> & aaPos,
     715              :                                                                           Grid & grid, SubsetHandler & sh,
     716              :                                                                           VecVertexOfFaceInfo const & segPart,
     717              :                                                                           std::vector<Vertex *> const & nextFracVrt,
     718              :                                                                           Grid::FaceAttachmentAccessor<AttVrtVec> & aaVrtVecFace,
     719              :                                                                           int & dbg_flachen_passiert,
     720              :                                                                           Vertex * iterV
     721              :                                                                           )
     722              : {
     723              : 
     724            0 :         CrossVertInf cvi( nullptr, 0 );
     725              : 
     726            0 :         return expandSingleFractureAtGivenSide( nOne, nTwo,
     727              :                           edgeOne, edgeTwo,
     728              :                           facOne, facTwo,
     729              :                           fracInfosBySubset,
     730              :                           posOldVrt,
     731              :                           aaPos,
     732              :                           grid, sh,
     733              :                           segPart,
     734              :                           nextFracVrt,
     735              :                           aaVrtVecFace,
     736              :                           dbg_flachen_passiert,
     737              :                           iterV,
     738              :                           cvi,
     739              :                           false
     740            0 :                           );
     741              : }
     742              : 
     743              : 
     744              : using VecEdge = std::vector<Edge*>;
     745              : using VecFace = std::vector<Face*>;
     746              : 
     747              : using ExpandCrossFracInfo = VertexFractureTriple< std::pair<Edge*, Edge*>, Face*, std::pair<Vertex*, Vertex*> >;
     748              : // Vertex nullptr wo original fracture, und shift vertex, wo Keilecke, die weg soll - Fall X Cross
     749              : 
     750              : using VecExpandCrossFracInfo = std::vector<ExpandCrossFracInfo>;
     751              : 
     752              : // leider erst ab 17er Standard möglich
     753              : //template <typename VRTCOMB >
     754              : //template < typename SHIVET > distinguish shiftVrtcs for TEnd and XCross, using static conxtexpr for isXCross in calling
     755              : // TODO FIXME change once std 17 available in UG4
     756            0 : bool SortFaces4DiamondCreation( SubsetHandler& sh, std::vector<Face *> & assoFacCrossCop, Edge * & firstEdgeFac, Edge * & secondEdgeFac,
     757              :                 Face * & assoFacConsider, VecEdge const & origFracEdg,
     758              :                 std::vector<Vertex * > const & shiftVrtcs,
     759              : //              std::vector<VRTCOMB > const & shiftVrtcs,
     760              :                 Vertex * const & crossPt, Edge * & assoFacEdgBeg2Fix, Edge * & assoFacEdgEnd2Fix, Grid& grid,
     761              :                 VecExpandCrossFracInfo & vecExpCrossFI,
     762              :                 bool isXCross = true // if false, then isTEnd, no other possibility
     763              :                 )
     764              : {
     765              : 
     766              :         // done noch die Abweichungen für den TEnd Fall einbauen
     767              : 
     768              :         bool atStartSort = true;
     769              : 
     770              :         bool boundAtShiftVrtEdg = isXCross; // false in case of TEnd at beginning
     771              : 
     772              : //                      auto shiftVrtcsCop = shiftVrtcs;
     773              : 
     774              : //                      UG_LOG("starting Rundlauf " << std::endl);
     775              : 
     776              :         IndexType dbg_rndl = 0;
     777              : 
     778            0 :         while( assoFacCrossCop.size() != 0 )
     779              :         {
     780              :                 //                              UG_LOG("Debug Rundlauf " << dbg_rndl << std::endl);
     781              : 
     782              :                 dbg_rndl++;
     783              : 
     784              :                 // Original X Cross ganz einfach
     785              : //              secondEdgeFac = nullptr;
     786              : 
     787              :                 // stattdessen bei T End
     788              : //              if( ! atStartSort )
     789              : //              {
     790              : //                      secondEdgeFac = nullptr;
     791              : //              }
     792              : 
     793              : //               zusammengefasst, hoffentlich richtig so:
     794            0 :                 if( isXCross || ( ! isXCross && ! atStartSort )  )
     795            0 :                         secondEdgeFac = nullptr;
     796              : 
     797              :                 // leider erst ab std 17, zu cool für älteren Standard
     798              : //              constexpr bool isXCross = std::is_same<Vertex*, VRTCOMB >::value;
     799              : //
     800              : //
     801              : //              if constexpr ( std::is_same<Vertex*, VRTCOMB >::value )
     802              : //              {
     803              : //                      secondEdgeFac = nullptr;
     804              : //              }
     805              : //
     806              : //              if constexpr ( std::is_same< VRTCOMB, std::pair<Vertex*, bool > )
     807              : //              {
     808              : //                      if( ! atStartSort )
     809              : //                              secondEdgeFac = nullptr;
     810              : //              }
     811              : 
     812              : 
     813              :                 Edge * fracEdge = nullptr;
     814              :                 Edge * shiftVrtxEdg = nullptr;
     815              : 
     816              :                 //                              IndexType fndEdgEnd = 0;
     817              : 
     818              :                 std::vector<Edge*> edgesThisFac;
     819              : 
     820              :                 edgesThisFac.clear();
     821              : 
     822              :                 //                              IndexType eoeo = edgesThisFac.size();
     823              :                 //
     824              :                 //                              auto eiei = eoeo;
     825              : 
     826              :                 //                              UG_LOG("Edges this fac Orig Orig " << eiei <<  " " << dbg_rndl << std::endl);
     827              : 
     828              : 
     829              :                 //                              UG_LOG("Debug Ecken " << std::endl);
     830              : 
     831              :                 IndexType dbg_itEd = 0;
     832              : 
     833            0 :                 for( std::vector<Edge *>::iterator iterEdgF = grid.associated_edges_begin(assoFacConsider);
     834            0 :                                 iterEdgF != grid.associated_edges_end(assoFacConsider); iterEdgF++ )
     835              :                 {
     836            0 :                         edgesThisFac.push_back(*iterEdgF);
     837              : 
     838              :                 //                                      UG_LOG("und noch eines dazu " << dbg_itEd << " " << dbg_rndl << std::endl);
     839              : 
     840              :                                                         //IndexType sudos = sh.num_subsets();
     841              : 
     842              :                                                         //sh.assign_subset(*iterEdgF,sudos);
     843              :                 }
     844              : 
     845              :                 //                              IndexType effsOrig = edgesThisFac.size();
     846              : 
     847              :                 //                              auto efeu = effsOrig;
     848              : 
     849              :                 //                              UG_LOG("Edges this fac Orig " << efeu <<  dbg_rndl << std::endl);
     850              : 
     851              : 
     852              :                                                 // figure out original fracture edge
     853              : 
     854              :                 IndexType fndFracEdg = 0;
     855              : 
     856            0 :                 for( auto const & etf : edgesThisFac )
     857              :                 {
     858            0 :                         for( auto const & ofe : origFracEdg )
     859              :                         {
     860            0 :                                 if( etf == ofe )
     861              :                                 {
     862            0 :                                         fndFracEdg++;
     863              :                                         fracEdge = etf;
     864              :                                 }
     865              :                         }
     866              :                 }
     867              : 
     868              :                 //                              UG_LOG("Debug Ofen  " << std::endl);
     869              : 
     870            0 :                 if( fracEdge == nullptr || fndFracEdg != 1 )
     871              :                 {
     872              :                         UG_LOG("Frac Orig Ecke nicht gefunden oder falsche Zahl " << fndFracEdg << " " << isXCross << std::endl );
     873              :                 //                                      return false;
     874            0 :                         UG_THROW("Frac Orig Ecke nicht gefunden oder falsche Zahl " << fndFracEdg << " " << isXCross << std::endl );
     875              :                 }
     876              : 
     877              : 
     878              :                                                 // find expanded shift vertex
     879              : 
     880              :                 Vertex * shiftVrtxFound = nullptr;
     881              :                 IndexType fndVrt = 0;
     882              : 
     883              :                 //                              IndexType suse = sh.num_subsets();
     884              : 
     885              :                                                 //sh.assign_subset(crossPt,suse);
     886              : 
     887              :                 //                              for( auto & sv : shiftVrtcsCop )
     888              :                 //                              {
     889              :                 //                                      IndexType suseV = sh.num_subsets();
     890              :                 //                                      //sh.assign_subset(sv,suseV);
     891              :                 //                              }
     892              : 
     893              :                 //                              return true;
     894              : 
     895              :                 //                              UG_LOG("Debug Entfernene    " << std::endl);
     896              : 
     897              :                 IndexType dbg_edgnum = 0;
     898              : 
     899              :                 IndexType helpVarEdges = 0;
     900              : 
     901              :                 //                              IndexType effs = edgesThisFac.size();
     902              :                 //                              IndexType shiffs = shiftVrtcs.size();
     903              : 
     904              :                 //                              UG_LOG("Edges this fac " <<  effs <<  dbg_rndl << std::endl);
     905              :                 //                              UG_LOG("Shift Vectors " <<  shiffs <<  dbg_rndl << std::endl);
     906              : 
     907              : 
     908            0 :                 for( auto const & etf : edgesThisFac )
     909              :                 {
     910              : 
     911            0 :                         if( helpVarEdges >= edgesThisFac.size() )
     912              :                         {
     913              :                                 UG_LOG("Indexueberschreitung Edges" << " " << isXCross <<  std::endl);
     914              :                                 break;
     915              :                         }
     916              : 
     917            0 :                         helpVarEdges++;
     918              : 
     919              :                         dbg_edgnum++;
     920              : 
     921              :                         IndexType helpShiVaNum = 0;
     922              : 
     923              :                         IndexType dbg_shiVe = 0;
     924              : 
     925              :                 //                                      for( Vertex * const & sv : shiftVrtcs )
     926            0 :                         for( auto const & sv : shiftVrtcs )
     927              :                         {
     928              : 
     929            0 :                                 if( helpShiVaNum >= shiftVrtcs.size() )
     930              :                                 {
     931              :                                         UG_LOG("Shift Vertex Index Verletzung " << " " << isXCross << std::endl);
     932              :                                         break;
     933              :                                 }
     934              : 
     935            0 :                                 helpShiVaNum++;
     936              : 
     937              :                                 dbg_shiVe++;
     938              : 
     939            0 :                                 if( EdgeContains(etf, crossPt ) && EdgeContains( etf, sv ) )
     940              :                                 {
     941            0 :                                         shiftVrtxFound = sv;
     942            0 :                                         fndVrt++;
     943            0 :                                         shiftVrtxEdg = etf;
     944              : 
     945              : //                                      UG_LOG("Shift Vertex " << aaPos[shiftVrtxFound] << " " << dbg_edgnum << " " << dbg_shiVe << " " << dbg_rndl << std::endl);
     946              : //                                      UG_LOG("Cross Vertex " << aaPos[crossPt] << " " << dbg_edgnum << " " << dbg_shiVe <<  " " << dbg_rndl <<  std::endl );
     947              : //
     948              : //                                      UG_LOG("dbg edgenu shive " << dbg_edgnum << " " << dbg_shiVe <<  " " << dbg_rndl <<  std::endl);
     949              : 
     950              : //                                      isAtFreeSideShiVe = svwi.second;
     951              :                                 }
     952              : 
     953              : 
     954              : //                              for( IndexType i = 0; i < 2; i++ )
     955              : //                              {
     956              : //
     957              : //                                      // done ersetzen durch ElementContains Funktion
     958              : //              //                                                      if( ( etf->vertex(i) == crossPt && etf->vertex((i+1)%2) == sv )  || (etf->vertex((i+1)%2) == crossPt && etf->vertex(i) == sv ))
     959              : //                                      if( etf->vertex(i) == crossPt && etf->vertex((i+1)%2) == sv )
     960              : //                                      {
     961              : //                                              shiftVrtxFound = sv;
     962              : //                                              fndVrt++;
     963              : //                                              shiftVrtxEdg = etf;
     964              : //
     965              : //              //                                                              UG_LOG("Shift Vertex " << aaPos[shiftVrtxFound] << " " << dbg_edgnum << " " << dbg_shiVe << " " << dbg_rndl << std::endl);
     966              : //              //                                                              UG_LOG("Cross Vertex " << aaPos[crossPt] << " " << dbg_edgnum << " " << dbg_shiVe <<  " " << dbg_rndl <<  std::endl );
     967              : //              //
     968              : //              //                                                              UG_LOG("dbg edgenu shive " << dbg_edgnum << " " << dbg_shiVe <<  " " << dbg_rndl <<  std::endl);
     969              : //                                      }
     970              : //                              }
     971              :                         }
     972              :                 }
     973              : 
     974              :                 //                              UG_LOG("Debug Entfert durch         " << std::endl);
     975              : 
     976              : 
     977            0 :                 if( fndVrt != 1 || shiftVrtxFound == nullptr || shiftVrtxEdg == nullptr )
     978              :                 {
     979              :                         UG_LOG("shift vertex komische Zahl oder null " << fndVrt << " " << isXCross << std::endl);
     980              :                 //                                      return false;
     981            0 :                         UG_THROW("shift vertex komische Zahl oder null " << fndVrt << " " << isXCross << std::endl);
     982              :                 }
     983              : 
     984              :                 //                              UG_LOG("Debug Entfert Text durch    " << std::endl);
     985              : 
     986              : 
     987              :                 //                              for( std::vector<Vertex*>::iterator itV = shiftVrtcsCop.begin(); itV != shiftVrtcsCop.end(); itV++ )
     988              :                 //                              {
     989              :                 //                                      Vertex * vrt = *itV;
     990              :                 //
     991              :                 //                                      if( vrt == shiftVrtxFound )
     992              :                 //                                      {
     993              :                 //                                              shiftVrtcsCop.erase(itV);
     994              :                 //                                              break;
     995              :                 //                                      }
     996              :                 //                              }
     997              :                 //
     998              :                 //                              UG_LOG("Debug Rasieren durch        " << std::endl);
     999              : 
    1000              : 
    1001              : //              if( atStartSort && isXCross )
    1002              : //              {
    1003              : //                      assoFacEdgBeg2Fix = fracEdge;
    1004              : //              }
    1005              : //
    1006              : //              if( atStartSort && ! isXCross )
    1007              : //              {
    1008              : //                      assoFacEdgBeg2Fix = fracEdge;
    1009              : //                      atStartSort = false;
    1010              : //              }
    1011              : 
    1012              : 
    1013            0 :                 if( atStartSort )
    1014              :                 {
    1015            0 :                         if( isXCross )
    1016              :                         {
    1017            0 :                                 assoFacEdgBeg2Fix = fracEdge;
    1018              :                         }
    1019              :                         else
    1020              :                         {
    1021            0 :                                 if( fracEdge != secondEdgeFac || shiftVrtxEdg != firstEdgeFac || assoFacEdgBeg2Fix != shiftVrtxEdg )
    1022            0 :                                         UG_THROW("ALler Anfang ist schwer TEnd " << std::endl);
    1023              :                         }
    1024              : 
    1025              :                         atStartSort = false;
    1026              :                 }
    1027              : 
    1028              : 
    1029              : 
    1030              :                 //                              Edge * firstEdgeFac = fracEdge;
    1031              :                 //                              Edge * secondEdgeFac = shiftEdge;
    1032            0 :                 firstEdgeFac = fracEdge;
    1033            0 :                 secondEdgeFac = shiftVrtxEdg;
    1034              : 
    1035              : 
    1036              :                 Vertex * firstVrt = nullptr;
    1037              :                 Vertex * secondVrt = shiftVrtxFound;
    1038              : 
    1039            0 :                 if( !boundAtShiftVrtEdg )
    1040              :                 {
    1041            0 :                         firstEdgeFac = shiftVrtxEdg;
    1042            0 :                         secondEdgeFac = fracEdge;
    1043              : 
    1044              :                         firstVrt = shiftVrtxFound;
    1045              :                         secondVrt = nullptr;
    1046              :                 }
    1047              : 
    1048              :                 //                              UG_LOG("Debug Paarbildung   " << std::endl);
    1049              : 
    1050              : 
    1051              :                 std::pair<Edge*, Edge*> edgesFac( firstEdgeFac, secondEdgeFac );
    1052              : 
    1053              :                 std::pair<Vertex*,Vertex*> vrtcsSF( firstVrt, secondVrt );
    1054              : 
    1055              :                 ExpandCrossFracInfo startFacInf( edgesFac, assoFacConsider, vrtcsSF );
    1056              : 
    1057            0 :                 vecExpCrossFI.push_back(startFacInf);
    1058              : 
    1059              : //              if( !isXCross )
    1060              : //              {
    1061              : //                      IndexType sui = sh.num_subsets();
    1062              : //
    1063              : //                      sh.assign_subset(assoFacConsider,sui);
    1064              : //              }
    1065              : 
    1066              :                 //                              UG_LOG("Debug Paarbildung  Rasieren " << std::endl);
    1067              : 
    1068              :                 IndexType dbg_it_er = 0;
    1069              : 
    1070            0 :                 for( std::vector<Face*>::iterator itFac = assoFacCrossCop.begin(); itFac != assoFacCrossCop.end(); itFac++ )
    1071              :                 {
    1072            0 :                         Face * iFa = *itFac;
    1073              : 
    1074              :                 //                                      UG_LOG("interieren " << dbg_it_er << std::endl );
    1075              : 
    1076              :                         dbg_it_er++;
    1077              : 
    1078              :                 //                                      UG_LOG("ifa " << iFa << std::endl );
    1079              :                 //                                      UG_LOG("assoFac " << assoFacConsider << std::endl );
    1080              : 
    1081              :                 //                                      bool enthaltung = FaceContains( iFa, firstEdgeFac );
    1082              :                 //
    1083              :                 ////                                    UG_LOG("Enthaltung " << std::endl);
    1084              :                 //
    1085              :                 //                                      bool entzwei = FaceContains(iFa, secondEdgeFac);
    1086              :                 //
    1087              :                 ////                                    UG_LOG("Entzweiung " << std::endl);
    1088              : 
    1089              : 
    1090            0 :                         if( iFa == assoFacConsider && FaceContains( iFa, firstEdgeFac ) && FaceContains(iFa, secondEdgeFac) )
    1091              :                         {
    1092              :                 //                                              UG_LOG("Erasieren " << std::endl);
    1093              :                                 assoFacCrossCop.erase(itFac);
    1094            0 :                                 break;
    1095              :                         }
    1096              :                 }
    1097              : 
    1098              :                 //                              UG_LOG("Debug Paarbildung  Rasieren durch " << std::endl);
    1099              : 
    1100              : 
    1101            0 :                 if( assoFacCrossCop.size() == 0 )
    1102              :                 {
    1103            0 :                         if( secondEdgeFac != assoFacEdgBeg2Fix )
    1104              :                         {
    1105              :                                 UG_LOG("Gesichter Diamant leer, aber keine Anfangsecke gefunden" << " " << isXCross << std::endl);
    1106              :                                 //return true;
    1107            0 :                                 UG_THROW("Gesichter Diamant leer, aber keine Anfangsecke gefunden" << " " << isXCross << std::endl);
    1108              :                         }
    1109              :                         else
    1110              :                         {
    1111            0 :                                 assoFacEdgEnd2Fix = secondEdgeFac;
    1112              : 
    1113              :                                 break; // while loop zu Ende, raus aus dem while loop, den Rest nicht mehr machen, würde schief gehen zwingendermassen
    1114              :                         }
    1115              : 
    1116              :                 }
    1117              : 
    1118              :                                                 // figure out the next face
    1119              : 
    1120            0 :                 firstEdgeFac = secondEdgeFac;
    1121            0 :                 secondEdgeFac = nullptr;
    1122              : 
    1123              :                 IndexType nextFaceFound = 0;
    1124              : 
    1125            0 :                 for( std::vector<Face*>::iterator itFac = assoFacCrossCop.begin(); itFac != assoFacCrossCop.end(); itFac++ )
    1126              :                 {
    1127            0 :                         Face * iFa = *itFac;
    1128              : 
    1129            0 :                         if( FaceContains(iFa, firstEdgeFac ) )
    1130              :                         {
    1131            0 :                                 nextFaceFound++;
    1132              :                         }
    1133              :                 }
    1134              : 
    1135            0 :                 if( nextFaceFound != 1 )
    1136              :                 {
    1137              :                         UG_LOG("folgendes Gesicht in falscher Anztahl gefunden Diamant " << nextFaceFound << " " << isXCross << std::endl);
    1138              :                 //                                      return false;
    1139            0 :                         UG_THROW("folgendes Gesicht in falscher Anztahl gefunden Diamant " << nextFaceFound << " " << isXCross << std::endl);
    1140              :                 }
    1141              : 
    1142            0 :                 for( std::vector<Face*>::iterator itFac = assoFacCrossCop.begin(); itFac != assoFacCrossCop.end(); itFac++ )
    1143              :                 {
    1144            0 :                         Face * iFa = *itFac;
    1145              : 
    1146            0 :                         if( FaceContains(iFa, firstEdgeFac ) )
    1147              :                         {
    1148            0 :                                 assoFacConsider = iFa;
    1149            0 :                                 break;
    1150              :                         }
    1151              :                 }
    1152              : 
    1153              : 
    1154            0 :                 boundAtShiftVrtEdg = ! boundAtShiftVrtEdg;
    1155              : 
    1156            0 :         }
    1157              : 
    1158            0 :         if( assoFacEdgEnd2Fix != assoFacEdgBeg2Fix || assoFacEdgEnd2Fix == nullptr || assoFacEdgBeg2Fix == nullptr )
    1159              :         {
    1160            0 :                 UG_THROW("Anfang und Ende stimmen nicht ueberein " << isXCross << std::endl);
    1161              : //                              return false;
    1162              :                 UG_THROW("Anfang und Ende stimmen nicht ueberein " << isXCross << std::endl);
    1163              :         }
    1164              : 
    1165              : //                      if( shiftVrtcsCop.size() != 0 )
    1166              : //                      {
    1167              : //                              UG_LOG("Shift vertizes nicht alle gefinden " << std::endl);
    1168              : //                              return false;
    1169              : //                              UG_THROW("Shift vertizes nicht alle gefinden " << std::endl);
    1170              : //                      }
    1171              : 
    1172            0 :         if( assoFacCrossCop.size() != 0 )
    1173              :         {
    1174              :                 UG_LOG("nicht alle asso facs gefunden " << isXCross << std::endl);
    1175              : //                              return false;
    1176            0 :                 UG_THROW("nicht alle asso facs gefunden " << isXCross << std::endl);
    1177              :         }
    1178              : 
    1179              : 
    1180            0 :         return true;
    1181              : }
    1182              : 
    1183            0 : void computeDiamondPointXCrossType( ExpandCrossFracInfo & expCFIBeforeFracEdg, ExpandCrossFracInfo & expCFIAfterFracEdg,
    1184              :                                                                         Vertex * const & crossPt, Grid::VertexAttachmentAccessor<APosition> & aaPos,
    1185              :                                                                         SubsetHandler & sh, Grid & grid, IndexType const & diamantSubsNum,
    1186              :                                                                         vector3 & distVecNewVrt2SCrossPt,
    1187              :                                                                         bool useTrianglesInDiamonds = false
    1188              : //                                                                      vector3 & distVecNewVrt2ShiVeBefore = vector3(), vector3 & distVecNewVrt2ShiVeAfter = vector3(),
    1189              : //                                                                      bool computeDistancesNewVrtsToOldShiVe = false
    1190              : )
    1191              : {
    1192              :         // compute cross point
    1193              : 
    1194              :         std::pair<Edge*, Edge*> edgesCrossSegBefore = expCFIBeforeFracEdg.getEdge();
    1195              :         std::pair<Edge*, Edge*> edgesCrossSegAfter = expCFIAfterFracEdg.getEdge();
    1196              : 
    1197              :         Edge * beforeShiftEdg = edgesCrossSegBefore.first;
    1198              :         Edge * beforeFracEdg = edgesCrossSegBefore.second;
    1199              :         Edge * afterFracEdg = edgesCrossSegAfter.first;
    1200              :         Edge * afterShiftEdg = edgesCrossSegAfter.second;
    1201              : 
    1202              :         std::pair<Vertex*,Vertex*> vrtcsCrossSegBefore = expCFIBeforeFracEdg.getNormal();
    1203              :         std::pair<Vertex*,Vertex*> vrtcsCrossSegAfter = expCFIAfterFracEdg.getNormal();
    1204              : 
    1205              :         Vertex * shiftBefore = vrtcsCrossSegBefore.first;
    1206              :         Vertex * shiftAfter = vrtcsCrossSegAfter.second;
    1207              : 
    1208              :         // zur Zielsetzung
    1209              : //                              Vertex * toBeEstablishedCutEdgeVrtBefore = vrtcsCrossSegBefore.second;
    1210              : //                              Vertex * toBeEstablishedCutEdgeVrtAfter = vrtcsCrossSegAfter.first;
    1211              : 
    1212            0 :         if(    vrtcsCrossSegBefore.second != nullptr ||  vrtcsCrossSegAfter.first != nullptr
    1213            0 :                 ||      shiftBefore == nullptr || shiftAfter == nullptr
    1214              : //                              if(    toBeEstablishedCutEdgeVrtBefore != nullptr ||  toBeEstablishedCutEdgeVrtAfter != nullptr
    1215              : //                                      ||      shiftBefore == nullptr || shiftAfter == nullptr
    1216              :           )
    1217            0 :                 UG_THROW("Nullpointer fehlen oder zu viel " << std::endl);
    1218              : 
    1219            0 :         if(    beforeFracEdg != afterFracEdg || beforeFracEdg == nullptr || afterFracEdg == nullptr
    1220            0 :                 || beforeShiftEdg == nullptr || afterShiftEdg == nullptr
    1221              :           )
    1222              :                 UG_LOG("Ecken Nullpunkter " << std::endl);
    1223              : 
    1224              :         // determin cut point of line between the shift vertices and the frac edge
    1225              : 
    1226              :         Edge * fracEdge = beforeFracEdg; // muss gleich sein offenkundig afterFracEdge, ist getestet auch
    1227              : 
    1228              :         // Gerade bestimmen, die durch fracEdge bestimmt wird, und Gerade, die durch Verbindungsvektor shift Verzices bestimmt wird
    1229              : 
    1230              :         // figure out frac vertex which is the cross point
    1231              : 
    1232              :         IndexType fracEdgInd = -1;
    1233              : 
    1234            0 :         for( IndexType fiv = 0; fiv < 2; fiv++ )
    1235              :         {
    1236            0 :                 if( fracEdge->vertex(fiv) == crossPt )
    1237              :                         fracEdgInd = fiv;
    1238              :         }
    1239              : 
    1240            0 :         if( fracEdgInd < 0 || fracEdgInd > 1 )
    1241            0 :                 UG_THROW("cross point nicht Teil von fracture edge" << std::endl );
    1242              : 
    1243            0 :         Vertex * fracEdgEnd = fracEdge->vertex( ( fracEdgInd + 1 ) % 2 );
    1244              : 
    1245            0 :         vector3 posCrossPt = aaPos[ crossPt ];
    1246              :         vector3 posFracEnd = aaPos[ fracEdgEnd ];
    1247              : 
    1248              :         vector3 posShiftBefore = aaPos[ shiftBefore ];
    1249              :         vector3 posShiftAfter = aaPos[ shiftAfter ];
    1250              : 
    1251              : //      vector3 directionFrac;
    1252              : //
    1253              : //      VecSubtract(directionFrac, posFracEnd, posCrossPt );
    1254              : 
    1255              :         vector3 directionShiftBefore;
    1256              : 
    1257              :         VecSubtract(directionShiftBefore, posShiftBefore, posCrossPt);
    1258              : 
    1259              :         vector3 directionShiftAfter;
    1260              : 
    1261              :         VecSubtract(directionShiftAfter, posShiftAfter, posCrossPt );
    1262              : 
    1263              :         vector3 sumShift;
    1264              : 
    1265              :         VecAdd(sumShift, directionShiftBefore, directionShiftAfter);
    1266              : 
    1267              :         vector3 halfSumShift;
    1268              : 
    1269            0 :         number scaFa = useTrianglesInDiamonds ? 1 : 0.5;
    1270              : 
    1271              : //      VecScale(halfSumShift, sumShift, 0.5);
    1272              :         VecScale( halfSumShift, sumShift, scaFa );
    1273              : 
    1274              :         vector3 posNewVrtOnEdg;
    1275              : 
    1276              :         VecAdd( posNewVrtOnEdg, posCrossPt, halfSumShift );
    1277              : 
    1278              :         // check if not shifting into the wrong direction TODO FIXME
    1279              :         // if length between posFracEnd and posNewVrtOnEdg bigger than length between posFracEnd and crossPt
    1280              :         // then shifted into the wrong direction, Kommando zurück dann!
    1281              : 
    1282              : //      if( useTrianglesInDiamonds )
    1283              : //      {
    1284              :         // always
    1285              : 
    1286              :         vector3 distVecOld;
    1287              :         VecSubtract(distVecOld, posFracEnd, posCrossPt );
    1288              :         vector3 distVecNew;
    1289              :         VecSubtract(distVecNew, posFracEnd, posNewVrtOnEdg);
    1290              :         number oldDistSq = VecLength(distVecOld);
    1291              :         number newDistSq = VecLength(distVecNew);
    1292              : 
    1293            0 :         if( oldDistSq < newDistSq )
    1294              :         {
    1295            0 :                 VecScale( halfSumShift, sumShift, - scaFa);
    1296              :                 VecAdd(posNewVrtOnEdg, posCrossPt, halfSumShift);
    1297              :         }
    1298            0 :         else if( oldDistSq == newDistSq ) // cross pt would equal new position
    1299              :         {
    1300            0 :                 if( posNewVrtOnEdg != posCrossPt || distVecNew != distVecOld )
    1301            0 :                         UG_THROW("Denkfehler, Implementation extemer Spezialfall checken" << std::endl);
    1302              : 
    1303              :                 vector3 distCorr;
    1304              :                 VecScale( distCorr, distVecOld, 0.05 );
    1305              :                 VecAdd( posNewVrtOnEdg, posCrossPt, distCorr );
    1306              :                 // Versuch, den Punkt ein wenig zu verschieben
    1307              :         }
    1308              : 
    1309              :         // TODO FIXME eventuell noch testen, ob die beiden Punkte in einem kleinen Radius liegen und korrigieren,
    1310              :         // eventuell schon vorher, statt zu werfen
    1311            0 :         if( posNewVrtOnEdg == posCrossPt )
    1312            0 :                 UG_THROW("Denkfehler Typ 2, Implementation extemer Spezialfall checken" << std::endl);
    1313              : 
    1314              : //      }
    1315              : 
    1316            0 :         Vertex * newEdgVrtx = *grid.create<RegularVertex>();
    1317              :         aaPos[newEdgVrtx] = posNewVrtOnEdg;
    1318              : 
    1319            0 :         IndexType sudoEdg = sh.get_subset_index(fracEdge);
    1320              : 
    1321              :         Face * faceBefore = expCFIBeforeFracEdg.getFace();
    1322              :         Face * faceAfter = expCFIAfterFracEdg.getFace();
    1323              : 
    1324            0 :         IndexType sudoBefore = sh.get_subset_index(faceBefore);
    1325            0 :         IndexType sudoAfter = sh.get_subset_index(faceAfter);
    1326              : 
    1327            0 :         if( sudoEdg != sudoBefore || sudoBefore != sudoAfter )
    1328            0 :                 UG_THROW("komische sudos vor Diamant " << std::endl);
    1329              : 
    1330              : //      sh.assign_subset(newEdgVrtx, sudoEdg);
    1331            0 :         sh.assign_subset(newEdgVrtx, diamantSubsNum );
    1332              : 
    1333              : 
    1334            0 :         UG_LOG("neuer Diamant Vorbereitungs Vertex " << posNewVrtOnEdg << std::endl);
    1335              : 
    1336              :         //                              Vertex * toBeEstablishedCutEdgeVrtBefore = vrtcsCrossSegBefore.second;
    1337              :         //                              Vertex * toBeEstablishedCutEdgeVrtAfter = vrtcsCrossSegAfter.first;
    1338              : 
    1339              : 
    1340              : 
    1341              :         // gleich neue Faces erzeugen?
    1342              : //                              std::pair<Vertex*,Vertex*> vrtcsCrossSegBefore = expCFIBeforeFracEdg.getNormal();
    1343              : //                              std::pair<Vertex*,Vertex*> vrtcsCrossSegAfter = expCFIAfterFracEdg.getNormal();
    1344              : 
    1345              :         // insert the newly established vertex into the vertex info of the ExpandCrossFracInfo of the face
    1346              : ////                            vrtcsCrossSegBefore.second = newEdgVrtx;
    1347              : ////                            vrtcsCrossSegAfter.first = newEdgVrtx;
    1348              : ////
    1349              : //                              std::pair<Vertex*,Vertex*> vrtcsCrossSegBeforeNew( vrtcsCrossSegBefore.first, newEdgVrtx );
    1350              : //                              std::pair<Vertex*,Vertex*> vrtcsCrossSegAfterNew( newEdgVrtx, vrtcsCrossSegAfter.second );
    1351              : //
    1352              : //
    1353              : //                              expCFIBeforeFracEdg.setNewNormal( vrtcsCrossSegBeforeNew );
    1354              : //                              expCFIAfterFracEdg.setNewNormal( vrtcsCrossSegAfterNew );
    1355              : 
    1356              :         vrtcsCrossSegBefore.second = newEdgVrtx;
    1357              :         vrtcsCrossSegAfter.first = newEdgVrtx;
    1358              :         expCFIBeforeFracEdg.setNewNormal( vrtcsCrossSegBefore );
    1359              :         expCFIAfterFracEdg.setNewNormal( vrtcsCrossSegAfter );
    1360              : 
    1361              :         VecSubtract(distVecNewVrt2SCrossPt, posCrossPt, posNewVrtOnEdg );
    1362              : 
    1363              :         // only needed for TEnd case
    1364              : //      if( computeDistancesNewVrtsToOldShiVe )
    1365              : //      {
    1366              : //              VecSubtract(distVecNewVrt2ShiVeBefore, posShiftBefore, posNewVrtOnEdg );
    1367              : //              VecSubtract(distVecNewVrt2ShiVeAfter, posShiftAfter, posNewVrtOnEdg );
    1368              : //      }
    1369            0 : }
    1370              : 
    1371              : // This function creates the new faces outside the diamond, directly attached to the diamond,
    1372              : // as part of post processing
    1373              : 
    1374            0 : void createNewFacesForExtXCrossFracs( ExpandCrossFracInfo const & ecf,  std::vector<Face*> & newFracFaceVec,
    1375              :                                                                           bool & boundAtShiftVrtEdg, //bool & atStartSort,
    1376              :                                                                           SubsetHandler & sh, Grid & grid, Vertex * const & crossPt,
    1377              :                                                                           std::vector<IndexType> const & subdomList
    1378              :                                                                         )
    1379              : {
    1380              :         // get new vertex at the original fracture edge
    1381              : 
    1382              :         // extract this functionality to own function
    1383              : 
    1384              : 
    1385              :         std::pair<Edge*, Edge*> edgesCrossSeg = ecf.getEdge();
    1386              : 
    1387              :         Face * facSeg = ecf.getFace();
    1388              : 
    1389              :         std::pair<Vertex*, Vertex*> vertcsCrossSeg = ecf.getNormal();
    1390              : 
    1391              :         std::pair<Vertex*, Vertex*> vertcsCrossSegWithNewV = ecf.getNewNormal();
    1392              : 
    1393              : 
    1394              : //      if( atStartSort || boundAtShiftVrtEdg )
    1395            0 :         if( boundAtShiftVrtEdg )
    1396              :         {
    1397            0 :                 if( vertcsCrossSeg.first != nullptr || vertcsCrossSeg.second == nullptr )
    1398            0 :                         UG_THROW("Verwechslung " << vertcsCrossSeg.first << " " << vertcsCrossSeg.second << std::endl);
    1399              :         }
    1400              : 
    1401              : //      atStartSort = false;
    1402              : 
    1403            0 :         Edge * fracEdge = boundAtShiftVrtEdg ? edgesCrossSeg.first : edgesCrossSeg.second;
    1404              :         Edge * shiftVrtEdge = boundAtShiftVrtEdg ?  edgesCrossSeg.second : edgesCrossSeg.first;
    1405              : 
    1406            0 :         Vertex * fracVrtNew =  boundAtShiftVrtEdg ? vertcsCrossSegWithNewV.first : vertcsCrossSegWithNewV.second; // should be nullptr at first segment, to be assigned afterwards / shifted
    1407            0 :         Vertex * shiftVrt = boundAtShiftVrtEdg ? vertcsCrossSeg.second : vertcsCrossSeg.first;
    1408            0 :         Vertex * shiftVrtTest = boundAtShiftVrtEdg ? vertcsCrossSegWithNewV.second : vertcsCrossSegWithNewV.first;
    1409              : 
    1410            0 :         if( shiftVrtTest != shiftVrt )
    1411            0 :                 UG_THROW("Shift Vertex verloren gegangen " << std::endl);
    1412              : 
    1413            0 :         IndexType sudoFac = sh.get_subset_index(facSeg);
    1414              : 
    1415            0 :         IndexType sudoFracEdge = sh.get_subset_index(fracEdge);
    1416              : 
    1417            0 :         if( sudoFac != sudoFracEdge )
    1418              :         {
    1419            0 :                 UG_THROW("subdoms frac edge und face nicht gleich " << std::endl);
    1420              :         }
    1421              : 
    1422              :         // get all vertices of face, check if both known ones are contained, delete the face, create
    1423              :         // the additional needed edge, and create new face with new vertex
    1424              : 
    1425              : 
    1426              :         std::vector<Vertex*> vrtcsFace;
    1427              :         // assign first old vertices, then replace
    1428              : //                              std::vector<Vertex*> vrtcsNewFaceFrac = vrtcsFace;
    1429              : //                              std::vector<Vertex*> vrtcsNewFaceDiam = vrtcsFace;
    1430              : 
    1431              :         //      all new vertices have been assigned to newVrts.
    1432              :         //      Note that if newVrts[i] == NULL, then we have to take the
    1433              :         //      old vertex sf->vertex(i).
    1434              :         //      now expand the fracture edges of sf to faces.
    1435            0 :         for(size_t iVrt = 0; iVrt < facSeg->num_vertices(); iVrt++ )
    1436              :         {
    1437              : 
    1438            0 :                 Vertex * vrt = facSeg->vertex(iVrt);
    1439            0 :                 vrtcsFace.push_back( vrt );
    1440              : //                                      vrtcsNewFaceFrac.push_back( vrt );
    1441              : //                                      vrtcsNewFaceDiam.push_back( vrt );
    1442              :         }
    1443              : 
    1444            0 :         std::vector<Vertex*> vrtcsNewFaceFrac = vrtcsFace;
    1445              : //                              std::vector<Vertex*> vrtcsNewFaceDiam = vrtcsFace;
    1446              : 
    1447              : 
    1448              :         // check if known vertices are contained
    1449              : 
    1450              :         IndexType fraVeNuInd = -1;
    1451              :         IndexType shiftVeNuInd = -1;
    1452              : 
    1453              :         IndexType cntr = 0;
    1454              : 
    1455            0 :         for( auto const & vf : vrtcsFace )
    1456              :         {
    1457            0 :                 if( vf == fracVrtNew )
    1458              :                 {
    1459              :                         fraVeNuInd = cntr;
    1460            0 :                         UG_THROW("wie kann man hierher kommen?" << std::endl);
    1461              :                 }
    1462              : 
    1463            0 :                 if( vf == crossPt )
    1464              :                 {
    1465              :                         fraVeNuInd = cntr;
    1466              :                 }
    1467              : 
    1468              : //
    1469            0 :                 if( vf == shiftVrt )
    1470              :                         shiftVeNuInd = cntr;
    1471              : 
    1472            0 :                 cntr++;
    1473              :         }
    1474              : 
    1475              :         if( fraVeNuInd < 0 || shiftVeNuInd < 0 )
    1476              :                 UG_THROW("frac vertex oder shift vertex not contained " << std::endl);
    1477              : 
    1478              :         UG_LOG("neuer frac vertex " << fraVeNuInd << " " << shiftVeNuInd << std::endl );
    1479              : 
    1480              :         // replace vrtcs
    1481            0 :         vrtcsNewFaceFrac[fraVeNuInd] = fracVrtNew;
    1482              : 
    1483              :         // compute shift of center vertex along frac edge
    1484              : 
    1485              :         // check subdom of frac vertex and check if in subdom List of X cross
    1486              : 
    1487              :         IndexType sudoOther = -1;
    1488              : 
    1489              :         IndexType foundSudoOther = 0;
    1490              :         IndexType foundSudoFac = 0;
    1491              : 
    1492            0 :         for( auto const & sd : subdomList )
    1493              :         {
    1494            0 :                 if( sd != sudoFac )
    1495              :                 {
    1496              :                         sudoOther = sd;
    1497            0 :                         foundSudoOther++;
    1498              :                 }
    1499              :                 else if( sd == sudoFac )
    1500              :                 {
    1501            0 :                         foundSudoFac++;
    1502              :                 }
    1503              :                 else
    1504              :                 {
    1505              :                         UG_THROW("Sudo not from frac and not from other?" << std::endl);
    1506              :                 }
    1507              :         }
    1508              : 
    1509            0 :         if( foundSudoFac != 1 && foundSudoOther != 1 )
    1510            0 :                 UG_THROW("sudo zu oft oder zu selten gefunden " << std::endl);
    1511              : 
    1512              :         // establish new edges and new faces
    1513              : 
    1514            0 :         if( vrtcsNewFaceFrac.size() != 4 )
    1515              :                 UG_LOG("komische Groesse Gesicht " << std::endl);
    1516              : 
    1517            0 :         for( IndexType i = 0; i < vrtcsNewFaceFrac.size(); i++ )
    1518              :         {
    1519            0 :                 if( vrtcsNewFaceFrac[i] == nullptr )
    1520              :                 {
    1521            0 :                         UG_THROW("null auf " << i << std::endl);
    1522              :                 }
    1523              : //                                      else
    1524              : //                                      {
    1525              : //                                              UG_LOG("kein null auf " << i << std::endl );
    1526              : //                                      }
    1527              :         }
    1528              : 
    1529              : 
    1530              :         UG_LOG("neue Gesichter ausserhalb Diamant Ziel " << std::endl);
    1531              : 
    1532              : //                              int a = 1 + 2;
    1533              : //
    1534            0 :         Face * newFracFace = nullptr;
    1535              : 
    1536            0 :         if(vrtcsNewFaceFrac.size() == 3 )
    1537              :         {
    1538            0 :                 newFracFace =
    1539            0 :                         *grid.create<Triangle>( TriangleDescriptor( vrtcsNewFaceFrac[0], vrtcsNewFaceFrac[1],
    1540              :                                                                                                                                   vrtcsNewFaceFrac[2]
    1541              :                                                                                 ) );
    1542              : 
    1543              :         }
    1544            0 :         else if( vrtcsNewFaceFrac.size() == 4 )
    1545              :         {
    1546            0 :                 newFracFace =
    1547            0 :                         *grid.create<Quadrilateral>( QuadrilateralDescriptor( vrtcsNewFaceFrac[0], vrtcsNewFaceFrac[1],
    1548              :                                                                                                                                   vrtcsNewFaceFrac[2], vrtcsNewFaceFrac[3]
    1549              :                                                                                 ) );
    1550              : 
    1551              :         }
    1552              :         else
    1553              :         {
    1554            0 :                 UG_THROW("komisches Gesicht " << std::endl);
    1555              :         }
    1556              : 
    1557            0 :         if( newFracFace != nullptr )
    1558              :         {
    1559            0 :                 sh.assign_subset(newFracFace, sh.get_subset_index(facSeg) );
    1560              :                 //                              sh.assign_subset(newFracFace, diamantSubsNum ); testweise
    1561              : 
    1562            0 :                 newFracFaceVec.push_back(newFracFace);
    1563              :         }
    1564              :         else
    1565              :         {
    1566            0 :                 UG_THROW("Gesicht ist nicht enstanden " << std::endl);
    1567              :         }
    1568              : 
    1569              : 
    1570            0 :         boundAtShiftVrtEdg = ! boundAtShiftVrtEdg;
    1571              : 
    1572              : 
    1573            0 : }
    1574              : 
    1575              : // this function creates the new faces of the diamond center, for XCross, but also for free TEnd type crossing fractures
    1576              : 
    1577            0 : void createDiamondFacesXCrossType( ExpandCrossFracInfo & expCFIBeforeFracEdg, ExpandCrossFracInfo & expCFIAfterFracEdg,
    1578              :                 std::vector<Face*> & newDiamFaceVec,  SubsetHandler & sh, Grid & grid, IndexType diamantSubsNum, Vertex * & crossPt,
    1579              :                 bool isFreeTEnd = false )
    1580              : {
    1581              : 
    1582              :         Face * facBefore = expCFIBeforeFracEdg.getFace();
    1583              :         Face * facAfter = expCFIAfterFracEdg.getFace();
    1584              : 
    1585              :         std::vector<Vertex*> vrtcsFaceBefore;
    1586              :         std::vector<Vertex*> vrtcsFaceAfter;
    1587              : 
    1588            0 :         for(size_t iVrt = 0; iVrt < facBefore->num_vertices(); iVrt++ )
    1589              :         {
    1590            0 :                 Vertex * vrt = facBefore->vertex(iVrt);
    1591            0 :                 vrtcsFaceBefore.push_back( vrt );
    1592              :         }
    1593              : 
    1594            0 :         for(size_t iVrt = 0; iVrt < facAfter->num_vertices(); iVrt++ )
    1595              :         {
    1596            0 :                 Vertex * vrt = facAfter->vertex(iVrt);
    1597            0 :                 vrtcsFaceAfter.push_back( vrt );
    1598              :         }
    1599              : 
    1600            0 :         Vertex * newVrtBefore = expCFIBeforeFracEdg.getNewNormal().first;
    1601            0 :         Vertex * shiftVrt = expCFIBeforeFracEdg.getNewNormal().second;
    1602            0 :         Vertex * newVrtAfter = expCFIAfterFracEdg.getNewNormal().second;
    1603              : 
    1604              :         if(    expCFIBeforeFracEdg.getNewNormal().second != expCFIBeforeFracEdg.getNormal().second
    1605            0 :                 || expCFIBeforeFracEdg.getNewNormal().second == nullptr
    1606            0 :                 || expCFIBeforeFracEdg.getNewNormal().second != expCFIAfterFracEdg.getNewNormal().first
    1607              :                 || expCFIAfterFracEdg.getNewNormal().first == nullptr
    1608            0 :                 || expCFIAfterFracEdg.getNewNormal().first != expCFIAfterFracEdg.getNormal().first
    1609              :         )
    1610              :         {
    1611              :                 UG_LOG("Vektoren " << expCFIBeforeFracEdg.getNewNormal().second << " != " <<  expCFIBeforeFracEdg.getNormal().second << std::endl
    1612              :                 << expCFIBeforeFracEdg.getNewNormal().second << std::endl
    1613              :                 << expCFIBeforeFracEdg.getNewNormal().second << " != " << expCFIAfterFracEdg.getNewNormal().first << std::endl
    1614              :                 << expCFIAfterFracEdg.getNewNormal().first << std::endl
    1615              :                 << expCFIAfterFracEdg.getNewNormal().first << " != " << expCFIAfterFracEdg.getNormal().first << std::endl );
    1616              : 
    1617              : #if 0
    1618              :                 Vektoren 0x591e03ec9c90 != 0x591e03ec9c90
    1619              :                 0x591e03ec9c90
    1620              :                 0x591e03ec9c90 != 0x591e03d00fa0
    1621              :                 0x591e03d00fa0
    1622              :                 0x591e03d00fa0 != 0x591e03d00fa0
    1623              :                 Execution of tool Expand Layers 2d Arte failed with the following message:
    1624              : #endif
    1625              : 
    1626            0 :                 UG_THROW("Vektorchaos " << std::endl);
    1627              :         }
    1628              : 
    1629            0 :         if( ! isFreeTEnd ) // standard XCross case, also applicable for TEnd apart from the free end
    1630              :         {
    1631              :                 std::vector<Vertex *> vrtxSmallDiam;
    1632              : 
    1633            0 :                 vrtxSmallDiam.push_back( crossPt );
    1634            0 :                 vrtxSmallDiam.push_back( newVrtBefore );
    1635            0 :                 vrtxSmallDiam.push_back( shiftVrt );
    1636            0 :                 vrtxSmallDiam.push_back( newVrtAfter );
    1637              : 
    1638              :                 Face * newFracFace =
    1639            0 :                         *grid.create<Quadrilateral>( QuadrilateralDescriptor( vrtxSmallDiam[0], vrtxSmallDiam[1],
    1640              :                                                                                                                                   vrtxSmallDiam[2], vrtxSmallDiam[3]
    1641            0 :                                                                                 ) );
    1642              : 
    1643            0 :                 sh.assign_subset(newFracFace, diamantSubsNum );
    1644              : 
    1645            0 :                 newDiamFaceVec.push_back(newFracFace);
    1646              : 
    1647            0 :         }
    1648              :         else
    1649              :         {
    1650              :                 std::vector<Vertex *> vrtxSmallDiamBefore;
    1651              :                 std::vector<Vertex *> vrtxSmallDiamAfter;
    1652              : 
    1653            0 :                 vrtxSmallDiamBefore.push_back( crossPt );
    1654            0 :                 vrtxSmallDiamBefore.push_back( newVrtBefore );
    1655            0 :                 vrtxSmallDiamBefore.push_back( shiftVrt );
    1656              : 
    1657            0 :                 vrtxSmallDiamAfter.push_back( crossPt );
    1658            0 :                 vrtxSmallDiamAfter.push_back( shiftVrt );
    1659            0 :                 vrtxSmallDiamAfter.push_back( newVrtAfter );
    1660              : 
    1661              :                 Face * newFracFaceBefore =
    1662            0 :                         *grid.create<Triangle>( TriangleDescriptor( vrtxSmallDiamBefore[0], vrtxSmallDiamBefore[1], vrtxSmallDiamBefore[2] ) );
    1663              : 
    1664              :                 Face * newFracFaceAfter =
    1665            0 :                         *grid.create<Triangle>( TriangleDescriptor( vrtxSmallDiamAfter[0], vrtxSmallDiamAfter[1], vrtxSmallDiamAfter[2] ) );
    1666              : 
    1667              : 
    1668            0 :                 sh.assign_subset(newFracFaceBefore, diamantSubsNum );
    1669            0 :                 sh.assign_subset(newFracFaceAfter, diamantSubsNum );
    1670              : 
    1671            0 :                 newDiamFaceVec.push_back(newFracFaceBefore);
    1672            0 :                 newDiamFaceVec.push_back(newFracFaceAfter);
    1673              : 
    1674            0 :         }
    1675              : 
    1676              : 
    1677            0 : }
    1678              : 
    1679            0 : void assignFaceSubsetToClosedFace( std::vector<Face*> & faceVec, Grid & grid, SubsetHandler & sh )
    1680              : {
    1681              : 
    1682            0 :         for( auto const & nF : faceVec )
    1683              :         {
    1684            0 :                 for(size_t iEdge = 0; iEdge < nF->num_edges(); iEdge++ )
    1685              :                 {
    1686            0 :                         Edge* edg = grid.get_edge(nF, iEdge);
    1687              : 
    1688            0 :                         sh.assign_subset( edg, sh.get_subset_index(nF) );
    1689              : 
    1690              :                 }
    1691              : 
    1692            0 :                 for( size_t iVrt = 0; iVrt < nF->num_vertices(); iVrt++ )
    1693              :                 {
    1694            0 :                         Vertex * vrt = nF->vertex(iVrt);
    1695              : 
    1696            0 :                         sh.assign_subset( vrt, sh.get_subset_index(nF) );
    1697              :                 }
    1698              : 
    1699              :         }
    1700              : 
    1701            0 : }
    1702              : 
    1703              : 
    1704              : //using VecVertFracTrip = std::vector<VertFracTrip>;
    1705              : //
    1706              : //// needed for crossing points
    1707              : //using VertexOfFaceInfo = VertexFractureTriple< std::pair<Edge*, Edge*>, Face*, std::pair<vector3,vector3> >;
    1708              : //// all edges of the attached face - must always be two, the face itself, and the normal vectors of the face in direction of the two edges
    1709              : //// the size of the normal vector vector also must be two
    1710              : //// however, if an edge of the face is not a fracture edge, we do not compute the normal, but assign zero as norm
    1711              : //// for those edges and faces which are Kluft edges, we assign the normal known from the info computed before, vertex fracture triple
    1712              : //
    1713              : //using VecVertexOfFaceInfo = std::vector<VertexOfFaceInfo>;
    1714              : //
    1715              : //using SegmentsFractExtrus = std::vector<VecVertexOfFaceInfo>;
    1716              : 
    1717              : 
    1718            0 : bool determineOrderOfFaces( //CrossVertInf & crossVrtInf,
    1719              :                                                         VecVertFracTrip const & vecVertFracTrip,
    1720              :                                                         VecFace const & assoFaces,  VecVertexOfFaceInfo & orderedFaces,
    1721              :                                                         SegmentsFractExtrus & segments,
    1722              :                                                         // single components always from one fracture edge to the next one
    1723              :                                                         //VecVertexOfFaceInfo & segmentPart,
    1724              :                                                         // note: we do not attach this info to the vertex, as we only need it local; in principle, in case of further need, it would
    1725              :                                                         // be usful to establish some sort of attachment,
    1726              :                                                         //VertFracTrip & startVertFracTrip,
    1727              :                                                         IndexType startIndex,
    1728              :                                                         std::vector<Edge*> const & allAssoEdges,
    1729              :                                                         SubsetHandler & sh,
    1730              :                                                         Grid::EdgeAttachmentAccessor<ABool> const & aaMarkEdgeB,
    1731              :                                                         std::vector<Edge* > const & adjBndEdgs = std::vector<Edge* >(), // to allow for boundary constrained regions
    1732              :                                                         Face * const & attFaceOf1stBndEdg = nullptr
    1733              :                                                 )
    1734              : {
    1735              :         IndexType countedCrossingFracEdgs = 0;
    1736              :         // copies of all faces and of fractured ones
    1737            0 :         auto aF = assoFaces; // caution: COPY, not reference!
    1738            0 :         auto vVFT = vecVertFracTrip; // caution: COPY, not reference!
    1739              : 
    1740              :         UG_LOG("Gesamtanzahl faces um Knoten " <<  aF.size() << std::endl );
    1741              : 
    1742              :         //  erstmal die ganzen anhaengenden Faces ordnen, dass wir wissen, in welcher Reihenfolge wir durchlaufen muessen
    1743              :         // jede Edge hat ein bool attachment schon, das weiss, ob sie Fracture edge ist oder nicht
    1744              :         // Reihenfolge der faces und die edges auch dazu, vielleicht neues Triple oder dergleiche, dabei zwei edges und zwei normals
    1745              :         // und wie gesagt, die edges wissen, ob sie fractures sind, dazu keine neuen Variablen notwendig
    1746              : 
    1747              :         //                              using VertexOfFaceInfo = VertexFractureTriple< std::pair<Edge*, Edge*>, Face*, std::pair<vector3,vector3> >;
    1748              : 
    1749              :         // all edges of the attached face - must always be two, the face itself, and the normal vectors of the face in direction of the two edges
    1750              :         // the size of the normal vector vector also must be two
    1751              :         // however, if an edge of the face is not a fracture edge, we do not compute the normal, but assign zero as norm
    1752              :         // for those edges and faces which are Kluft edges, we assign the normal known from the info computed before, vertex fracture triple
    1753              : 
    1754              : 
    1755            0 :         if( vVFT.size() == 0 )
    1756            0 :                 UG_THROW("vertex frac triple zu klein an Kreuzung " << std::endl);
    1757              : 
    1758            0 :         IndexType numbIncorpBnds = adjBndEdgs.size();
    1759              : 
    1760            0 :         if( numbIncorpBnds != 0 && numbIncorpBnds != 2 )
    1761            0 :                 UG_THROW("komische Grenzstruktur" << numbIncorpBnds << std::endl);
    1762              : 
    1763              :         bool isNormalNoBndCase = ( numbIncorpBnds != 2 );
    1764              : 
    1765              :         bool atFirstTriple = true;
    1766              : 
    1767              :         vector3 nuVe(0,0,0);
    1768              : 
    1769              :         Face* fracFac = nullptr;
    1770              :         Edge* fracEdg = nullptr;
    1771              :         vector3 fracNorm = nuVe;
    1772              : 
    1773              :         Edge * originalStartEdge = nullptr;
    1774              :         Edge * targetedEndEdge = nullptr;
    1775              : 
    1776            0 :         if( isNormalNoBndCase )
    1777              :         {
    1778              :                         // we start with the first fracture face edge stuff, copy it,  and delete this immidiately
    1779            0 :                 VertFracTrip startVertFracTrip = vVFT[startIndex];
    1780              : 
    1781              :                 vVFT.erase( vVFT.begin() + startIndex );
    1782              : 
    1783              :                 atFirstTriple = true;
    1784              : 
    1785              :                 fracFac = startVertFracTrip.getFace();
    1786              :                 fracEdg = startVertFracTrip.getEdge();
    1787              :                 fracNorm = startVertFracTrip.getNormal();
    1788              : 
    1789              :                 originalStartEdge = startVertFracTrip.getEdge();
    1790              :                 targetedEndEdge = originalStartEdge;
    1791              :         }
    1792              :         else // boundary edge start
    1793              :         {
    1794              :                 atFirstTriple = false;
    1795              : 
    1796              :                 // misleading names fracFac and fracEdg, as on boundary edge no fracture assumed, but to keep code overviewable
    1797            0 :                 fracFac = attFaceOf1stBndEdg;
    1798            0 :                 fracEdg = adjBndEdgs[0];
    1799              : //              fracNorm = startVertFracTrip.getNormal(); - assumed to be nullvector
    1800              : 
    1801              :                 originalStartEdge = adjBndEdgs[0];
    1802            0 :                 targetedEndEdge = adjBndEdgs[1];
    1803              : 
    1804              : 
    1805              :         }
    1806              : 
    1807              : 
    1808              :         if( fracEdg != nullptr )
    1809              :         {
    1810              :                 countedCrossingFracEdgs++;
    1811              :         }
    1812              : 
    1813              :         // do not change this pointer
    1814              :         Edge* startEdg = fracEdg;
    1815              :         Face* startFace = fracFac;
    1816              : 
    1817              :         vector3 startNormal = fracNorm;
    1818              : 
    1819              :         Face* nextFace = NULL;
    1820              : 
    1821              :         UG_LOG("Gesamtanzahl faces um Knoten vor while " <<  aF.size() << std::endl );
    1822              : 
    1823              :         VecVertexOfFaceInfo segmentPart;
    1824              : 
    1825            0 :         while( aF.size() != 0 )
    1826              :         {
    1827              : 
    1828              :                 UG_LOG("Gesamtanzahl faces um Knoten Anfang while " <<  aF.size() << std::endl );
    1829              : 
    1830              : 
    1831              :                 Face* face2Append = startFace;
    1832              :                 Edge* startEdg2Append = startEdg;
    1833              : 
    1834              : 
    1835              :                 IndexType fndCommEdg = 0;
    1836              : //              vector3 nuVe(0,0,0);
    1837              : 
    1838              :                 Edge* nextEdge = NULL;
    1839              : 
    1840              :                 std::pair<Edge*, Edge *> edge2Append( startEdg2Append, nextEdge );
    1841              :                 std::pair<vector3, vector3 > normal2Append( startNormal, nuVe );
    1842              : 
    1843              : 
    1844              :                 // if start face and start edge from a triple, then has to be erased this triple, exept for the entire start, as already erased
    1845            0 :                 if( ! atFirstTriple )
    1846              :                 {
    1847            0 :                         for( VecVertFracTrip::iterator itAttVFT = vVFT.begin(); itAttVFT !=  vVFT.end(); itAttVFT++ )
    1848              :                         {
    1849              :                                 auto vft = *itAttVFT;
    1850              : 
    1851              :                                 Edge * edgIt = vft.getEdge();
    1852              : 
    1853              :                                 Face * facIt = vft.getFace();
    1854              : 
    1855            0 :                                 if( edgIt == startEdg && facIt == startFace )
    1856              :                                 {
    1857              :                                         // the first edge if from a fracture and the face is connected to it
    1858              : 
    1859              :                                         vVFT.erase(itAttVFT);
    1860              : 
    1861              :                                         normal2Append.first = vft.getNormal();
    1862              : 
    1863            0 :                                         if( ! FaceContains( facIt, startEdg ))
    1864              :                                         {
    1865            0 :                                                 UG_THROW("Face does not contain start edge of its edge" << std::endl);
    1866              :                                         }
    1867              : 
    1868              :                                         break;
    1869              :                                 }
    1870              :                         }
    1871              : 
    1872              :                 }
    1873              :                 else // we can save the investigation if we have a triple, and we do not need to erase, as already erased.....
    1874              :                 {
    1875              :                         atFirstTriple = false;
    1876              :                 }
    1877              : 
    1878              : 
    1879            0 :                 for( auto const & iE : allAssoEdges ) // werden nicht gelöscht, deswegen Zugriff auf attachment direkt
    1880              :                 {
    1881            0 :                         if( FaceContains(face2Append, iE) )
    1882              :                         {
    1883            0 :                                 fndCommEdg++;
    1884              : 
    1885            0 :                                 if( iE != startEdg )
    1886              :                                 {
    1887              :                                         nextEdge = iE;
    1888              : 
    1889              :                                         edge2Append.second = iE;
    1890              : 
    1891              :                                 }
    1892              :                         }
    1893              : 
    1894              : 
    1895              :                 }
    1896              : 
    1897            0 :                 if( fndCommEdg != 2 )
    1898              :                 {
    1899            0 :                         UG_THROW("komische Anzahl gemeinsamer Ecke " << fndCommEdg << std::endl);
    1900              :                 }
    1901              : 
    1902            0 :                 if( nextEdge == NULL )
    1903              :                 {
    1904            0 :                         UG_THROW("wieso keine zweite Ecke gefunden???? " << std::endl);
    1905              :                 }
    1906              : 
    1907            0 :                         if( edge2Append.first == NULL || edge2Append.second == NULL )
    1908              :                 {
    1909            0 :                         UG_THROW("null immer noch?" << std::endl);
    1910              :                 }
    1911              : 
    1912              :                 // erase the face from the list
    1913              : 
    1914              :                 IndexType faceFound = 0;
    1915              : 
    1916            0 :                 for( std::vector<Face*>::iterator itFac = aF.begin(); itFac != aF.end(); itFac++ )
    1917              :                 {
    1918            0 :                         Face * iFa = *itFac;
    1919              : 
    1920            0 :                         if( iFa == startFace &&  FaceContains( iFa, nextEdge ) && FaceContains(iFa, startEdg))
    1921              :                         {
    1922            0 :                                 faceFound++;
    1923              :                         }
    1924              :                 }
    1925              : 
    1926              :                 int totalSubsNum = sh.num_subsets();
    1927              : 
    1928              :                 int newSubsToAdd = totalSubsNum;
    1929              : 
    1930            0 :                 if( faceFound != 1 )
    1931              :                 {
    1932              : 
    1933              : 
    1934            0 :                         sh.assign_subset(startFace,newSubsToAdd++);
    1935            0 :                         sh.assign_subset(startEdg,newSubsToAdd++);
    1936            0 :                         sh.assign_subset(nextEdge,newSubsToAdd++);
    1937              : 
    1938            0 :                         int faNum = aF.size();
    1939              : 
    1940            0 :                         UG_LOG("Gesamtzahl faces vor Absturz " << faNum << std::endl);
    1941              : 
    1942              :                         UG_LOG("Gesicht in falscher Anztahl gefunden " << faceFound << std::endl);
    1943              : 
    1944              :         //                                              return true;
    1945              : 
    1946            0 :                         UG_THROW("Gesicht in falscher Anztahl gefunden " << faceFound << std::endl);
    1947              : 
    1948              :                         return false;
    1949              : 
    1950              :                 }
    1951              :                 else
    1952              :                 {
    1953              :         //                                              sh.assign_subset(startFace,newSubsToAdd++);
    1954              :         //                                              sh.assign_subset(startEdg,newSubsToAdd++);
    1955              :         //                                              sh.assign_subset(nextEdge,newSubsToAdd++);
    1956              : 
    1957            0 :                         int faNum = aF.size();
    1958              : 
    1959            0 :                         UG_LOG("Gesamtzahl faces ohne Absturz " << faNum << std::endl);
    1960              : 
    1961              :                 }
    1962              : 
    1963            0 :                 for( std::vector<Face*>::iterator itFac = aF.begin(); itFac != aF.end(); itFac++ )
    1964              :                 {
    1965            0 :                         Face * iFa = *itFac;
    1966              : 
    1967            0 :                         if( iFa == startFace && FaceContains( iFa, nextEdge ) && FaceContains(iFa, startEdg) )
    1968              :                         {
    1969              :                                 aF.erase(itFac);
    1970            0 :                                 break;
    1971              :                         }
    1972              :                 }
    1973              : 
    1974              : 
    1975              :                 bool sndEdgIsFracEdge = aaMarkEdgeB[nextEdge];
    1976              : 
    1977              :                 bool tripFound = false;
    1978              : 
    1979            0 :                 if( sndEdgIsFracEdge )
    1980              :                 {
    1981              : 
    1982              :                         if( nextEdge != originalStartEdge || ! isNormalNoBndCase )
    1983              :                                 countedCrossingFracEdgs++;
    1984              : 
    1985              :                         // we need to have a look for the next triple
    1986              : 
    1987              :                         // check if the next normal is a frac normal which contains the face as well
    1988              : 
    1989            0 :                         for( VecVertFracTrip::iterator itAttVFT = vVFT.begin(); itAttVFT !=  vVFT.end(); itAttVFT++ )
    1990              :                         {
    1991              :                                 auto vft = *itAttVFT;
    1992              : 
    1993              :                                 Edge * edgIt = vft.getEdge();
    1994              : 
    1995              :                                 Face * facIt = vft.getFace();
    1996              : 
    1997            0 :                                 if( edgIt == nextEdge && facIt == face2Append )
    1998              :                                 {
    1999              :                                         // the second edge if from a fracture and the face is connected to it
    2000              : 
    2001              :                                         tripFound = true;
    2002              : 
    2003              :                                         vVFT.erase(itAttVFT);
    2004              : 
    2005              :                                         normal2Append.second = vft.getNormal();
    2006              : 
    2007            0 :                                         if( ! FaceContains( facIt, nextEdge ))
    2008              :                                         {
    2009            0 :                                                 UG_THROW("Face does not contain edge of its edge" << std::endl);
    2010              :                                         }
    2011              : 
    2012              :                                         break;
    2013              :                                 }
    2014              :                         }
    2015              : 
    2016              :                 }
    2017              : 
    2018            0 :                 if( ! tripFound && sndEdgIsFracEdge )
    2019              :                 {
    2020            0 :                         UG_THROW("Triple nicht gefunden trotz markierter Edge" << std::endl);
    2021              :                 }
    2022              : 
    2023              : 
    2024              :                 // check if aF or vVFT still contain the former or the next face - must not be the case!
    2025              : 
    2026              :                 VertexOfFaceInfo vOFI( edge2Append, face2Append, normal2Append );
    2027              : 
    2028            0 :                 orderedFaces.push_back( vOFI );
    2029              : 
    2030            0 :                 segmentPart.push_back( vOFI );
    2031              : 
    2032            0 :                 if( sndEdgIsFracEdge )
    2033              :                 {
    2034            0 :                         segments.push_back( segmentPart );
    2035              : 
    2036              :                         segmentPart.clear();
    2037              :                 }
    2038              : 
    2039              : 
    2040              :                 // what is next face, what is next edge?
    2041              :                 // wie kriegen wir es hin, auch das nächste Triple zu erasen, wenn es jetzt kommt als nächstes?
    2042              : 
    2043              : 
    2044              :                 startNormal = nuVe;
    2045              :                 startEdg = nextEdge;
    2046              : 
    2047            0 :                 if( aF.size() == 0 )
    2048              :                 {
    2049              : //                      if( nextEdge != originalStartEdge )
    2050            0 :                         if( nextEdge != targetedEndEdge )
    2051              :                         {
    2052            0 :                                 UG_THROW("Gesichter leer, aber keine Anfangsecke gefunden" << std::endl);
    2053              :                         }
    2054              :                         else
    2055              :                         {
    2056              : 
    2057            0 :                                 if( ! isNormalNoBndCase )
    2058              :                                 {
    2059            0 :                                         segments.push_back( segmentPart );
    2060              : 
    2061              :                                         segmentPart.clear();
    2062              :                                 }
    2063              : 
    2064            0 :                                 break; // while loop zu Ende, raus aus dem while loop, den Rest nicht mehr machen, würde schief gehen zwingendermassen
    2065              :                         }
    2066              : 
    2067              :                 }
    2068              : 
    2069              : 
    2070              :                 // bleibt noch das nächste Gesicht heraus zu finden, dafür kommt eigentlich nur noch eines in Frage, da das zweite Gesicht vom edge
    2071              :                 // geloescht sein muss in aF, es muss das einzig übrige face sein, das die jetzt start edge enthält, davon darf es nur eines geben, wir löschen aber noch nicht
    2072              : 
    2073              :                 IndexType nextFaceFound = 0;
    2074              : 
    2075            0 :                 for( std::vector<Face*>::iterator itFac = aF.begin(); itFac != aF.end(); itFac++ )
    2076              :                 {
    2077            0 :                         Face * iFa = *itFac;
    2078              : 
    2079            0 :                         if( FaceContains(iFa, startEdg ) )
    2080              :                         {
    2081            0 :                                 nextFaceFound++;
    2082              :                         }
    2083              :                 }
    2084              : 
    2085            0 :                 if( nextFaceFound != 1 )
    2086              :                 {
    2087            0 :                         UG_THROW("folgendes Gesicht in falscher Anztahl gefunden " << nextFaceFound << std::endl);
    2088              :                 }
    2089              : 
    2090            0 :                 for( std::vector<Face*>::iterator itFac = aF.begin(); itFac != aF.end(); itFac++ )
    2091              :                 {
    2092            0 :                         Face * iFa = *itFac;
    2093              : 
    2094            0 :                         if( FaceContains(iFa, startEdg ) )
    2095              :                         {
    2096              :                                 startFace = iFa;
    2097              :                                 break;
    2098              :                         }
    2099              :                 }
    2100              : 
    2101              : 
    2102              :         }
    2103              : 
    2104            0 :         if( vVFT.size() != 0 )
    2105              :         {
    2106            0 :                 UG_THROW("not all triples found! " << std::endl);
    2107              :         }
    2108              : 
    2109            0 :         if( aF.size() != 0 )
    2110            0 :                 UG_THROW("not all faces found " << std::endl);
    2111              : 
    2112              : //      if( startEdg != originalStartEdge )
    2113            0 :         if( startEdg != targetedEndEdge )
    2114              :         {
    2115            0 :                 UG_THROW("wir sind nicht am Anfang wieder angekommen" << std::endl);
    2116              :         }
    2117              : 
    2118              : 
    2119            0 :         if( segmentPart.size() != 0 )
    2120              :         {
    2121            0 :                 UG_THROW("die Segmentteile muessen alle verarbeitet sein"  << std::endl);
    2122              :         }
    2123              : 
    2124              :         UG_LOG("Kreislauf geschlossen" << std::endl);
    2125              : 
    2126              : 
    2127              :         return true;
    2128            0 : }
    2129              : 
    2130              : 
    2131            0 : void teachAssoFacesNewVrtx( VecVertexOfFaceInfo const & segPart, Grid::FaceAttachmentAccessor<AttVrtVec> & aaVrtVecFace,
    2132              :                                                         Vertex * const & crossPt, Vertex * const & newShiftVrtx )
    2133              : {
    2134            0 :         for( VertexOfFaceInfo const & vertFracInfoSeg : segPart )
    2135              :         {
    2136              :                 Face * fac = vertFracInfoSeg.getFace();
    2137              : 
    2138              : //                                              sh.assign_subset(fa,newSubsToAdd);
    2139              : 
    2140              :                 // ACHTUNG neue Variable Face klein geschrieben im Gegensatz zu SR! nicht später falsche verwenden!
    2141              :                 vector<Vertex*>& newVrts4Fac = aaVrtVecFace[ fac ];
    2142              : 
    2143              :                 IndexType vrtxFnd = 0;
    2144              : 
    2145            0 :                 for(size_t indVrt = 0; indVrt < (fac)->num_vertices();  indVrt++ )
    2146              :                 {
    2147            0 :                         Vertex* facVrt = (fac)->vertex(indVrt);
    2148              : 
    2149            0 :                         if(  facVrt == crossPt )
    2150              :                         {
    2151            0 :                                 newVrts4Fac[ indVrt ] = newShiftVrtx;
    2152            0 :                                 vrtxFnd++;
    2153              : 
    2154              :                         }
    2155              :                 }
    2156              : 
    2157            0 :                 if( vrtxFnd <= 0 )
    2158              :                 {
    2159            0 :                         UG_THROW("vertex not found kreuzung!" << std::endl);
    2160              :                                                                                         }
    2161            0 :                 else if( vrtxFnd > 1 )
    2162              :                 {
    2163            0 :                         UG_THROW("vertex zu oft gefunden kreuzung " << vrtxFnd << std::endl );
    2164              :                 }
    2165              :                 else if ( vrtxFnd == 1 )
    2166              :                 {
    2167              :                 }
    2168              :                 else
    2169              :                 {
    2170              :                         UG_THROW("vertex finden komisch kreuzung " << std::endl);
    2171              :                 }
    2172              : 
    2173              :         }
    2174              : 
    2175            0 : }
    2176              : 
    2177              : 
    2178              : 
    2179              : #ifndef WORKAROUND_ARTE_SEGFAULT
    2180              : #define WORKAROUND_ARTE_SEGFAULT 1
    2181              : #endif
    2182              : 
    2183              : #ifndef ESTABLISH_DEBUG_SUDOS
    2184              : #define ESTABLISH_DEBUG_SUDOS 0
    2185              : #endif
    2186              : 
    2187              : #ifndef FORMER_PROMESH_FINITE_CLEFT_TECHNIQUE
    2188              : #define FORMER_PROMESH_FINITE_CLEFT_TECHNIQUE 0
    2189              : #endif
    2190              : 
    2191            0 : bool ExpandFractures2dArte( Grid& grid, SubsetHandler& sh, vector<FractureInfo> const & fracInfos,
    2192              : //                                              bool expandInnerFracBnds, bool expandOuterFracBnds
    2193              :                                                 bool useTrianglesInDiamonds, bool establishDiamonds
    2194              : )
    2195              : {
    2196              : 
    2197              :         constexpr bool expandInnerFracBnds = false;
    2198              :         constexpr bool expandOuterFracBnds = true;
    2199              : 
    2200              : //      for(EdgeIterator iter = sh.begin<Edge>(1); iter != sh.end<Edge>(1); ++iter)
    2201              : //      {
    2202              : //              size_t sm = sh.num_subsets();
    2203              : //
    2204              : //              sh.assign_subset(*iter,sm);
    2205              : //
    2206              : //              SplitEdge<RegularVertex>(grid,*iter,true);
    2207              : //
    2208              : //              UG_LOG("vertex gesplittet" << std::endl);
    2209              : //
    2210              : //              return true;
    2211              : //
    2212              : //      }
    2213              : 
    2214              : 
    2215              : //      static constexpr bool dehneInnereKluftGrenzpunkteAus = false;
    2216              : 
    2217              : //      expandInnerFracBnds = false;
    2218              : 
    2219              : //      expandOuterFracBnds = true;
    2220              : 
    2221              : //      access position attachment
    2222            0 :         if(!grid.has_vertex_attachment(aPosition)){
    2223              :                 UG_LOG("Error in ExpandFractures 2D Arte: Missing position attachment");
    2224            0 :                 return false;
    2225              :         }
    2226              :         Grid::VertexAttachmentAccessor<APosition> aaPos(grid, aPosition);
    2227              : 
    2228            0 :         if(!grid.option_is_enabled(FACEOPT_AUTOGENERATE_EDGES)){
    2229              :                 UG_LOG("WARNING in Arte 2D CalculateCreaseNormal: grid option FACEOPT_AUTOGENERATE_EDGES autoenabled.\n");
    2230            0 :                 grid.enable_options(FACEOPT_AUTOGENERATE_EDGES);
    2231              :         }
    2232              : 
    2233              : 
    2234              : 
    2235              : //      objects for temporary results
    2236            0 :         FaceDescriptor fd;
    2237              :         vector<Edge*> edges; // used for temporary results.
    2238              :         vector<Face*> faces; // used for temporary results.
    2239              : 
    2240              : //      vectors that allow to access fracture properties by subset index
    2241            0 :         vector<FractureInfo> fracInfosBySubset(sh.num_subsets(), FractureInfo(-1, -1, 0));
    2242            0 :         for(size_t i = 0; i < fracInfos.size(); ++i){
    2243            0 :                 if(fracInfos[i].subsetIndex >= sh.num_subsets()){
    2244            0 :                         throw(UGError("Bad subsetIndex in given fracInfos."));
    2245              :                 }
    2246              : 
    2247            0 :                 fracInfosBySubset[fracInfos[i].subsetIndex] = fracInfos[i];
    2248              :         }
    2249              : 
    2250              : ////////////////////////////////
    2251              : //      Collect surrounding faces of all fractures in a selector
    2252              : //      and select edges and vertices too.
    2253            0 :         Selector sel(grid);
    2254            0 :         sel.enable_autoselection(false);
    2255            0 :         sel.enable_selection_inheritance(false);
    2256              : 
    2257              : #if FORMER_PROMESH_FINITE_CLEFT_TECHNIQUE
    2258              :         AInt aAdjMarker;        // used to mark how many adjacent fractures a vertex has.
    2259              :                                                 // 0: no frac, 1: frac-boundary, >1: inner frac vertex
    2260              :         // TODO FIXME das sieht komisch aus, ist das immer so, wenn z.B. an einer Grenze sich zwei fracs treffen?
    2261              :         grid.attach_to_vertices_dv(aAdjMarker, 0);
    2262              :         Grid::VertexAttachmentAccessor<AInt> aaMarkVRT(grid, aAdjMarker);
    2263              :         grid.attach_to_edges_dv(aAdjMarker, 0);
    2264              :         Grid::EdgeAttachmentAccessor<AInt> aaMarkEDGE(grid, aAdjMarker);
    2265              : #endif
    2266              : 
    2267              : //      using IndexType = unsigned short;
    2268              :         using AttVerFracProp = Attachment<VertexFractureProperties<IndexType> >;
    2269              :         // attachment pair boundary is fracture, number fractures crossing
    2270              : 
    2271              :         AttVerFracProp aAdjMarkerVFP;
    2272              : 
    2273              :         VertexFractureProperties<IndexType> vfp0( false, 0 );
    2274              :         // default value: no boundary fracture, no fractures crossing
    2275              : 
    2276              :         grid.attach_to_vertices_dv(aAdjMarkerVFP, vfp0 );
    2277              :         Grid::VertexAttachmentAccessor<AttVerFracProp> aaMarkVrtVFP(grid, aAdjMarkerVFP);
    2278              : 
    2279              :         ABool aAdjMarkerB; // used to know if an edge is frac edge
    2280            0 :         grid.attach_to_edges_dv(aAdjMarkerB, false);
    2281              :         Grid::EdgeAttachmentAccessor<ABool> aaMarkEdgeB(grid, aAdjMarkerB);
    2282              : 
    2283              : 
    2284              :         // die Vertizes, Faces und Edges, die mit einer Kluft zu tun haben
    2285              : 
    2286              : //      using VertFracTrip = VertexFractureTriple<Edge*, Face*, vector3>;
    2287              : //
    2288              : //      using VecVertFracTrip = std::vector<VertFracTrip>;
    2289              : 
    2290              :         VecVertFracTrip vertexNoInfo;
    2291              : 
    2292              :         using AttVecVertFracTrip = Attachment<VecVertFracTrip>;
    2293              : 
    2294              :         AttVecVertFracTrip aAdjInfoAVVFT;
    2295              : 
    2296              :         grid.attach_to_vertices_dv( aAdjInfoAVVFT, vertexNoInfo );
    2297              :         Grid::VertexAttachmentAccessor<AttVecVertFracTrip> aaVrtInfoFraTri(grid,  aAdjInfoAVVFT );
    2298              : 
    2299              : 
    2300              : //      using VecEdge = std::vector<Edge*>;
    2301              : //      using VecFace = std::vector<Face*>;
    2302              : 
    2303              :         using AttVecEdge = Attachment<VecEdge>;
    2304              :         using AttVecFace = Attachment<VecFace>;
    2305              : 
    2306              :         VecEdge noEdge;
    2307              :         VecFace noFace;
    2308              :         AttVecEdge aAdjInfoEdges;
    2309              :         AttVecFace aAdjInfoFaces;
    2310              : 
    2311              :         grid.attach_to_vertices_dv( aAdjInfoEdges, noEdge );
    2312              :         Grid::VertexAttachmentAccessor<AttVecEdge> aaVrtInfoAssoEdges( grid, aAdjInfoEdges );
    2313              : 
    2314              :         grid.attach_to_vertices_dv( aAdjInfoFaces, noFace );
    2315              :         Grid::VertexAttachmentAccessor<AttVecFace> aaVrtInfoAssoFaces( grid, aAdjInfoFaces );
    2316              : 
    2317              : 
    2318              :         // das ist Käse, ich brauche für jeden Vertex ein Attachment der Form
    2319              :         // class VertexTriple, bzw std vektoren von solchen vertex triplen
    2320              :         // da weiss dann jeder Vertex das triple
    2321              :         // Kante (damit subdom) - Face - normal (von Kante in Face rein)
    2322              :         // dann kann man nämlich anhand des Winkels von zwei Normalen
    2323              :         // von solchen Vertizes bestimmtn, ob sie auf die gleiche Seite der Kante zeigen
    2324              :         // und dann kann man sie mitteln, sofern die Vertizes keine Kreuzungs Vertizes sind
    2325              :         // oder keine äusseren Vertizes - ob sie dsa sind, dafür haben wir schon attachments!
    2326              : 
    2327              :         // TODO FIXME diese komischen accessoren sollen jetzt so zugewiesen
    2328              :         // werden, dass
    2329              :         /*
    2330              :          * jeder Kluftvertex soll wissen, welche Kluftedges ihm anliegen, und welche faces
    2331              :          * jede Kluftedge soll wissen, welche Vertizes ihr anliegen, und welche faces
    2332              :          * jedes Face, das an eine Kluft anliegt, soll wissen, welche Vertizes und Edges
    2333              :          * ihm anliegen
    2334              :          * letzteres muss man vielleicht noch ausdehnen, indem man subdomain indizes
    2335              :          * dazu bringt
    2336              :          * das kann auch notwendig sein fuer alle anderen - wirklich?
    2337              :          * die edges und faces kennen ihre subdomain
    2338              :          * nur beim Vertex kann in Kreuzungspunkten ein Problem sein
    2339              :          * zudem ist die subdomain der faces EGAL, im Zweifel entscheidet die subdomain
    2340              :          * der edges, die anliegen bzw der edge, die anliegt!
    2341              :          *
    2342              :          */
    2343              : 
    2344              : //      iterate over the given fracture infos and select all fracture edges
    2345              : //      and fracture vertices.
    2346            0 :         for(size_t i_fi = 0; i_fi < fracInfos.size(); ++i_fi)
    2347              :         {
    2348            0 :                 int fracInd = fracInfos[i_fi].subsetIndex;
    2349              : 
    2350            0 :                 for(EdgeIterator iter = sh.begin<Edge>(fracInd); iter != sh.end<Edge>(fracInd); ++iter)
    2351              :                 {
    2352              :                 //      mark edge and vertices
    2353              :                         sel.select(*iter);
    2354              : 
    2355              : #if FORMER_PROMESH_FINITE_CLEFT_TECHNIQUE
    2356              :                         aaMarkEDGE[*iter] = 1;
    2357              : #endif
    2358              : 
    2359              :                         aaMarkEdgeB[*iter] = true;
    2360              : 
    2361              :                 //      select associated vertices
    2362            0 :                         for(size_t i = 0; i < 2; ++i)
    2363              :                         {
    2364            0 :                                 Vertex* v = (*iter)->vertex(i);
    2365              :                                 sel.select(v);
    2366              : 
    2367              :                                 // wird in jedem Fall inkrimiert, da der Vertex auf jeden Fall mit einer Kante einer frac verbunden sein muss, sonst darf der loop gar nicht darüber gehen
    2368              :                                 aaMarkVrtVFP[v]++;
    2369              : 
    2370            0 :                                 if( IsBoundaryVertex2D(grid, v) )
    2371              :                                         aaMarkVrtVFP[v].setIsBndFracVertex();
    2372              : 
    2373              : 
    2374              : #if FORMER_PROMESH_FINITE_CLEFT_TECHNIQUE
    2375              :                                 // das ist Sebastians loop, den nicht mehr lassen lassen
    2376              :                                 //      if fracture boundaries are expanded, we'll regard all fracture vertices
    2377              :                                 //      as inner vertices
    2378              :                                 if(expandInnerFracBnds)
    2379              :                                 {
    2380              :                                         if(!expandOuterFracBnds)
    2381              :                                         {
    2382              :                                                 if(IsBoundaryVertex2D(grid, v))
    2383              :                                                         aaMarkVRT[v]++;
    2384              :                                                 else
    2385              :                                                         aaMarkVRT[v] = 2;
    2386              :                                         }
    2387              :                                         else
    2388              :                                                 aaMarkVRT[v] = 2;
    2389              :                                 }
    2390              :                                 else
    2391              :                                         aaMarkVRT[v]++;
    2392              : #endif
    2393              : 
    2394              :                         }
    2395              :                 }
    2396              :         }
    2397              : 
    2398              : 
    2399              : #if FORMER_PROMESH_FINITE_CLEFT_TECHNIQUE
    2400              : //      Make sure that selected vertices that lie on the boundary of the geometry
    2401              : //      are treated as inner fracture vertices.
    2402              : //      This is only required if frac-boundaries are not expanded anyways.
    2403              :         if(expandOuterFracBnds && !expandInnerFracBnds){
    2404              :                 for(VertexIterator iter = sel.vertices_begin();
    2405              :                         iter != sel.vertices_end(); ++iter)
    2406              :                 {
    2407              :                         Vertex* v = *iter;
    2408              :                         if(aaMarkVRT[v] == 1){
    2409              :                                 if(IsBoundaryVertex2D(grid, v))
    2410              :                                         aaMarkVRT[v] = 2;
    2411              :                         }
    2412              :                 }
    2413              :         }
    2414              :         // TODO FIXME was soll das fuer ein Kaese sein?
    2415              : #endif
    2416              : 
    2417              :         int dbg_flachen_passiert = 0;
    2418              : 
    2419            0 :         for(VertexIterator iter = sel.begin<Vertex>(); iter != sel.end<Vertex>(); ++iter)
    2420              :         {
    2421              : 
    2422              :                 bool wahl = true;
    2423              : 
    2424              : 
    2425              :                 // so stimmt es vielleicht, aber ist auch ein komischer Fall, innen expandieren und aussen nicht...... die Frage ist, ob es oonst Sinn macht.....
    2426              :                 if( expandInnerFracBnds && !expandOuterFracBnds && aaMarkVrtVFP[*iter].getIsBndFracVertex() )
    2427              :                         wahl = false;
    2428              : 
    2429              :                 // DEBUG ASSERT TEST static_assert( std::is_same< decltype(*iter), Vertex * >::value );
    2430              : 
    2431              :                 bool isBnd = aaMarkVrtVFP[ *iter ].getIsBndFracVertex();
    2432              :                 auto numCrosFrac = aaMarkVrtVFP[ *iter ].getNumberFracEdgesInVertex();
    2433              : 
    2434            0 :                 if( ! isBnd && numCrosFrac == 1 )
    2435              :                 {
    2436              :                         wahl = false;
    2437              :                 }
    2438              : 
    2439              : //              if( ! dehneInnereKluftGrenzpunkteAus )
    2440              : //              {
    2441              : //                      if( numCrosFrac == 1 ) // inner frac boundary vertex
    2442              : //                      {
    2443              : //                              wahl = false;
    2444              : //                      }
    2445              : //              }
    2446              : 
    2447              : 
    2448              :                 if( wahl )
    2449              :                 {
    2450            0 :                         sel.select(grid.associated_edges_begin(*iter),
    2451              :                                                 grid.associated_edges_end(*iter));
    2452            0 :                         sel.select(grid.associated_faces_begin(*iter),
    2453              :                                                 grid.associated_faces_end(*iter));
    2454              : 
    2455              :                         // TODO FIXME hier ein attachment der associated faces und vertizes, am besten als Klasse, die std vertizes davon frisst, an jeden Vertex anhängen
    2456              :                         // so muss man später nicht nochmal über alle Faces und Edges laufen, sondern hat die angehängten schon zur Hand
    2457              :                         // im Fall, dass eine Kreuzung vorliegt, das Ganze irgendwann ordnen, dass nebeneinander liegende Faces und edges in eine verkettete Liste kommen
    2458              :                         // vielleicht das aber nur bei den Schnittvertizes später
    2459              :                         // und vielleicht sollen die Faces Zeiger auf ihre Edges bekommen, und die edges auf die faces, aber wird irgendwann zu wild verzeigert.....
    2460              :                         // vielleicht einfach attachment von faces und edges unabhängig an jeden Fracture Vertex......
    2461              : 
    2462              :                         // testen, ob ein Schnittvertex vor liegt, indem die Anzahl der touches getestet wird, anhand einfacher Geometrien testen, was die Anzahl ist
    2463              : 
    2464              :                         // mit UG_LOG ausgeben, was die Koordinaten sind, und die Anzahl der hits
    2465              : 
    2466              :                         VecFace assFac;
    2467              :                         VecEdge assEdg;
    2468              : 
    2469              : //                      UG_LOG("----------" << std::endl);
    2470              : 
    2471            0 :                         for( std::vector<Face *>::iterator iterFac = grid.associated_faces_begin(*iter); iterFac != grid.associated_faces_end(*iter); iterFac++ )
    2472              :                         {
    2473            0 :                                 assFac.push_back(*iterFac);
    2474              : //                              vector3 facCenter = CalculateCenter( *iterFac, aaPos );
    2475              : //                              UG_LOG("fac center " << facCenter << std::endl);
    2476              : 
    2477              : //                              sh.assign_subset(*iterFac, 10);
    2478              :                         }
    2479              : 
    2480              : //                      UG_LOG("----------" << std::endl);
    2481              : 
    2482            0 :                         for( std::vector<Edge *>::iterator iterEdg = grid.associated_edges_begin(*iter); iterEdg != grid.associated_edges_end(*iter); iterEdg++ )
    2483              :                         {
    2484            0 :                                 assEdg.push_back(*iterEdg);
    2485              : //                              sh.assign_subset(*iterEdg,10);
    2486              :                         }
    2487              : 
    2488            0 :                         aaVrtInfoAssoFaces[*iter] = assFac;
    2489            0 :                         aaVrtInfoAssoEdges[*iter] = assEdg;
    2490              : 
    2491            0 :                         UG_LOG("marked vertex wahl: " << aaPos[*iter] << " is bnd " << isBnd << " number cross frac " << numCrosFrac << std::endl );
    2492              : 
    2493              :                         // fuer Nicht Boundary Vertizes muessen wir durch 2 teilen, damit wir richtige Anzahl der
    2494              :                         // Fracs haben, die durch den spezifischen Vertex durch geht
    2495              :                         // FALSCH war mal so, ist schon abgestellt, es wird angezeigt, wieviele Ecken von Kanten rein kommen
    2496              : 
    2497            0 :                 }
    2498              :                 else
    2499              :                 {
    2500            0 :                         UG_LOG("marked vertex unwahl: " << aaPos[*iter] << " is bnd " << isBnd << " number cross frac " << numCrosFrac << std::endl );
    2501              :                 }
    2502              : 
    2503              :         }
    2504              : 
    2505              : //      return true;
    2506              : 
    2507              :         using pairIndDbl = std::pair<IndexType,double>;
    2508              : 
    2509              :         std::vector< pairIndDbl > fracSubdom_facePerpendMinVal;
    2510              : 
    2511            0 :         for( auto const & pf: fracInfos )
    2512              :         {
    2513            0 :                 fracSubdom_facePerpendMinVal.push_back( pairIndDbl( pf.subsetIndex, std::numeric_limits<double>::max() ) );
    2514              :         }
    2515              : 
    2516              :         T_min<double> minDistPerpOverall( std::numeric_limits<double>::max() );
    2517              : 
    2518              : //      for( auto fI : fracInfos )
    2519              : //      for( size_t fraInfInd = 0; fraInfInd < fracInfos.size(); fraInfInd++ )
    2520            0 :         for( auto & fsfpmv : fracSubdom_facePerpendMinVal )
    2521              :         {
    2522              : //              int fracInd = fracInfos[fraInfInd].subsetIndex;
    2523              : //              int fracInd = fI.subsetIndex;
    2524              : 
    2525            0 :                 auto fracInd = fsfpmv.first;
    2526              : 
    2527            0 :                 T_min<double> minDistPerpThisFrac( fsfpmv.second );
    2528              : 
    2529            0 :                 for(EdgeIterator iterEdg = sh.begin<Edge>(fracInd); iterEdg != sh.end<Edge>(fracInd); iterEdg++ )
    2530              :                 {
    2531              : 
    2532              :                         // get subdomain of edge
    2533              : 
    2534            0 :                         auto sudoEdg = sh.get_subset_index(*iterEdg);
    2535              : 
    2536              :                         // sieht quasi doppelt gemoppelt aus
    2537            0 :                         if( sudoEdg != fracInd )
    2538            0 :                                 UG_THROW("Subdomain Index Fehler " << std::endl);
    2539              : 
    2540              :                         // DEBUG ASSERT TEST static_assert( std::is_same< decltype(sudoEdg), int >::value );
    2541              : 
    2542              :                         // get vertices of edge, always 2
    2543              : 
    2544              :                         std::vector<Vertex* > verticesEdg;
    2545              : 
    2546              :                         // DEBUG ASSERT TEST static_assert( std::is_same< Vertex*, decltype( (*iterEdg)->vertex(0) ) >::value );
    2547              : 
    2548            0 :                         for( size_t i = 0; i < 2; ++i )
    2549            0 :                                 verticesEdg.push_back( (*iterEdg)->vertex(i) );
    2550              : 
    2551              :                         // get attached faces
    2552              : 
    2553              : #if 0
    2554              :                         std::vector<Face* > assFace;
    2555              : 
    2556              :                         // TODO FIXME dieser loop kann vielleicht vereinfacht werden, wenn dieser ganze loop umgebaut wird
    2557              :                         // denn die Vertizes kennen dann die assosciated faces schon
    2558              :                         // der Name AssociatedFaceIterator ist sowieso verwirrend, hat mit assosciated nix zu tun, bezieht sich auf alle std Vektoren von Face *
    2559              :                         UG_LOG("XXXXXXXXXXXX" << std::endl);
    2560              :                         for(Grid::AssociatedFaceIterator iterAFI = grid.associated_faces_begin( verticesEdg[0] );
    2561              :                                 iterAFI != grid.associated_faces_end( verticesEdg[0] );
    2562              :                                 iterAFI++ )
    2563              :                         {
    2564              : 
    2565              :                                 if(FaceContains( *iterAFI, *iterEdg ))
    2566              :                                 {
    2567              :                                         assFace.push_back( *iterAFI );
    2568              : 
    2569              : 
    2570              :                                         vector3 facCenter = CalculateCenter( *iterAFI, aaPos );
    2571              :                                         UG_LOG("fac center " << facCenter << std::endl);
    2572              : 
    2573              : 
    2574              : 
    2575              : //                                      sh.assign_subset( *iterAFI, sh.get_subset_index(*iterEdg));
    2576              :                                 }
    2577              : 
    2578              :                         }
    2579              :                         UG_LOG("XXXXXXXXX" << std::endl);
    2580              : #else
    2581              : 
    2582            0 :                         std::vector<Face* > & assFaceVrt0 = aaVrtInfoAssoFaces[verticesEdg[0]];
    2583              : 
    2584              :                         std::vector<Face* > assFace;
    2585              : 
    2586              : //                      // DEBUG ASSERT TEST static_assert( std::is_same< decltype( aaVrtInfoAssoFaces[verticesEdg[0]] )[0], std::vector<Face *> >::value );
    2587              :                         //// DEBUG ASSERT TEST static_assert( std::is_same< decltype( *(aaVrtInfoAssoFaces[verticesEdg[0]]) ), Face * >::value );
    2588              : 
    2589              : //                      UG_LOG("XXXXXXXXXXXX" << std::endl);
    2590              : 
    2591            0 :                         for( auto const & ifa : assFaceVrt0 )
    2592              :                         {
    2593            0 :                                 if(FaceContains( ifa, *iterEdg ))
    2594              :                                 {
    2595            0 :                                         assFace.push_back( ifa );
    2596              : 
    2597              : //                                      vector3 facCenter = CalculateCenter( ifa, aaPos );
    2598              : //                                      UG_LOG("fac center " << facCenter << std::endl);
    2599              :                                 }
    2600              :                         }
    2601              : 
    2602            0 :                         std::vector<Face* > & assFaceVrt1 = aaVrtInfoAssoFaces[verticesEdg[1]];
    2603              : 
    2604            0 :                         for( auto const & ifa : assFaceVrt1 )
    2605              :                         {
    2606            0 :                                 if(FaceContains( ifa, *iterEdg ))
    2607              :                                 {
    2608              :                                         bool faceContained = false;
    2609              : 
    2610            0 :                                         for( auto const & afa : assFace )
    2611              :                                         {
    2612            0 :                                                 if( afa == ifa )
    2613              :                                                         faceContained = true;
    2614              :                                         }
    2615              : 
    2616            0 :                                         if( !faceContained )
    2617              :                                         {
    2618              :                                                 bool faceAlreadyIncluded = false;
    2619              : 
    2620            0 :                                                 for( auto const & af : assFace )
    2621              :                                                 {
    2622            0 :                                                         if( ifa == af )
    2623              :                                                                 faceAlreadyIncluded = true;
    2624              :                                                 }
    2625              : 
    2626            0 :                                                 if( ! faceAlreadyIncluded )
    2627            0 :                                                         assFace.push_back( ifa );
    2628              :                                         }
    2629              :                                 }
    2630              :                         }
    2631              : 
    2632              : 
    2633              : //                      UG_LOG("XXXXXXXXX" << std::endl);
    2634              : 
    2635              : #endif
    2636              :                         // von hier lernen:
    2637              :                         //      VecFace & assoFaces = aaVrtInfoAssoFaces[*iterV ist verticesEdg[0] ];
    2638              :                         //              for( auto const & ifac : assoFaces )
    2639              :                         //              {
    2640              :                         //                      // DEBUG ASSERT TEST static_assert( std::is_same< decltype( ifac ), Face * const & >::value );
    2641              :                         //              }
    2642              : 
    2643              : 
    2644              : 
    2645              :                         // compute normal of edge
    2646              : 
    2647              :                         std::vector< vector3 > edgeNormals;
    2648              : 
    2649              :                         std::vector<double> perpendDistances;
    2650              : 
    2651            0 :                         for( auto const & fac : assFace )
    2652              :                         {
    2653            0 :                                 vector3 facCenter = CalculateCenter( fac, aaPos );
    2654              : 
    2655              :                                 vector3 perpendicu;
    2656              : 
    2657            0 :                                 DropAPerpendicular(perpendicu, facCenter, aaPos[verticesEdg[0]], aaPos[verticesEdg[1]]);
    2658              : 
    2659            0 :                                 double perpendDist = VecLength( perpendicu ); // betrag perpendicu
    2660              : 
    2661            0 :                                 perpendDistances.push_back( perpendDist );
    2662              : 
    2663              :                                 minDistPerpThisFrac( perpendDist );
    2664              : 
    2665              : 
    2666              :                         //      vector from projection to center is the unnormalized normal
    2667              :                                 vector3 tmpN;
    2668              : 
    2669              :                                 VecSubtract(tmpN, facCenter, perpendicu );
    2670              : 
    2671            0 :                                 VecNormalize(tmpN, tmpN);
    2672              : 
    2673            0 :                                 edgeNormals.push_back( tmpN );
    2674              : 
    2675              :                                 // DEBUG ASSERT TEST static_assert( std::is_same< Edge*, decltype(*iterEdg) >::value );
    2676              : 
    2677              :                                 // DEBUG ASSERT TEST static_assert( std::is_same< Face * const &, decltype(fac) >::value );
    2678              :                                 // DEBUG ASSERT TEST static_assert( std::is_same< Face *, decltype( const_cast<Face*>(fac) ) >::value );
    2679              :                                 // DEBUG ASSERT TEST static_assert( std::is_same< vector3, decltype( tmpN ) >::value );
    2680              : 
    2681              :                                 VertFracTrip infoVertizesThisEdge( *iterEdg, fac, tmpN );
    2682              : 
    2683              : //                              UG_LOG("TypE Fac " << typeid(const_cast<Face*>(fac) ).name() << std::endl);
    2684              : //                              UG_LOG("TypE Edg " << typeid( *iterEdg ).name() << std::endl);
    2685              : //                              UG_LOG("TypE Vec " << typeid( tmpN ).name() << std::endl);
    2686              : 
    2687              : 
    2688            0 :                                 for( auto const & v : verticesEdg )
    2689              :                                 {
    2690              :                                         // DEBUG ASSERT TEST static_assert( std::is_same< decltype(v), Vertex * const & >::value );
    2691              :                                         // DEBUG ASSERT TEST static_assert( std::is_same< decltype(const_cast<Vertex*>(v)), Vertex *  >::value );
    2692            0 :                                         aaVrtInfoFraTri[v].push_back( infoVertizesThisEdge );
    2693              : 
    2694              : //                                      VecVertFracTrip allInfosVrtxThisEdg = aaVrtInfoFraTri[v];
    2695              : 
    2696              : //                                      // DEBUG ASSERT TEST static_assert( std::is_same< decltype(  aaVrtInfoFraTri[v] ),  VecVertFracTrip >::value );
    2697              : 
    2698              : //                                      UG_LOG("type Fac " << typeid( aaVrtInfoFraTri[v][ aaVrtInfoFraTri[v].size() - 1 ].getFace() ).name() << std::endl);
    2699              : //                                      UG_LOG("type Edg " << typeid( aaVrtInfoFraTri[v][ aaVrtInfoFraTri[v].size() - 1 ].getEdge() ).name() << std::endl);
    2700              : //                                      UG_LOG("type Vec " << typeid( aaVrtInfoFraTri[v][ aaVrtInfoFraTri[v].size() - 1 ].getNormal() ).name() << std::endl);
    2701              : 
    2702              :                                         // DEBUG ASSERT TEST static_assert( std::is_same< decltype( aaVrtInfoFraTri[v][ aaVrtInfoFraTri[v].size() - 1 ].getFace() ), Face * >::value );
    2703              :                                         // DEBUG ASSERT TEST static_assert( std::is_same< decltype( aaVrtInfoFraTri[v][ aaVrtInfoFraTri[v].size() - 1 ].getEdge() ), Edge * >::value );
    2704              :                                         // DEBUG ASSERT TEST static_assert( std::is_same< decltype( aaVrtInfoFraTri[v][ aaVrtInfoFraTri[v].size() - 1 ].getNormal() ), vector3 const >::value );
    2705              :                                 }
    2706              : 
    2707              :                         }
    2708              : 
    2709              :                         // damit speichern wir die plus und minus Normale, und das ist alles, und auch
    2710              :                         // gleich wieder weg
    2711              :                         // TODO FIXME besser, wir speichern die gemittelte Normale an den Vertizes
    2712              :                         // vielleihct als attachment pair, das die subdom kennt der frac und die Normale dazu?
    2713              :                         // ziemlich nutzlos, die Normale wie hier gemacht in einen kurzen Vektor zu speichern, der schnell
    2714              :                         // wieder weg ist......
    2715              :                         // wir brauchen alle Normalen zu jeder fracture an jedem fracture Vertex, also die Mittelung vermutlich
    2716              :                         // diese Mittelung kann aber erst stattfinden, wenn wir nachher über die vertizes loopen,
    2717              :                         // hier kennen wir nur die Vertizes, die an derselben Edge anliegen
    2718              : 
    2719            0 :                         UG_LOG("EDGE NORMALS: " << sh.get_subset_index(*iterEdg) << " -> ");
    2720              : 
    2721              :                         int j = 0;
    2722              : 
    2723            0 :                         for( auto const & en: edgeNormals )
    2724              :                         {
    2725              : 
    2726            0 :                                 for( size_t i = 0; i < 3; i++ )
    2727            0 :                                         UG_LOG( en[i] << ", "  );
    2728              : 
    2729              : 
    2730            0 :                                 UG_LOG(" --- " << perpendDistances[j] << " ///////// " );
    2731              : 
    2732            0 :                                 j++;
    2733              :                         }
    2734              : 
    2735              :                         UG_LOG(std::endl);
    2736              : 
    2737            0 :                 }
    2738              : 
    2739            0 :                 fsfpmv.second = minDistPerpThisFrac();
    2740              : 
    2741              :                 minDistPerpOverall( fsfpmv.second );
    2742              : 
    2743            0 :                 UG_LOG("first " << fsfpmv.first << " second " << fsfpmv.second << std::endl);
    2744              :         }
    2745              : 
    2746            0 :         for( auto const & fsfpmv : fracSubdom_facePerpendMinVal )
    2747              :         {
    2748            0 :                 UG_LOG("min dist sd " << fsfpmv.first << " -> " << fsfpmv.second << std::endl  );
    2749              :         }
    2750              : 
    2751              :         UG_LOG("overall min dist " << minDistPerpOverall() << std::endl);
    2752              : 
    2753              : 
    2754              : 
    2755              :         // von Sebastian teilweise das Prinzip übernommen, dass die Faces wissen können, was ihre neuen Vertizes sein sollen
    2756              :         //      create new vertices
    2757              : 
    2758              :         //      we have to associate a vector of vertices with each node in the fracture.
    2759              :         //      since an empty vector is quite small, we can associate one with each vertex in
    2760              :         //      the whole grid. This could be optimized if required, by using subset attachments.
    2761              : 
    2762              :         // es reicht vielleicht, hier statt einem Vektor einfach nur einen Vertex * zu storen
    2763              : //      using AttVrtVec = Attachment<vector<Vertex*> >;
    2764              :         AttVrtVec attVrtVec;
    2765              : 
    2766              :         //      we  associate a vector of vertices for each face adjacent to the frac.
    2767              :         //      it will store a set of vertices. An entry contains the new vertex, if the
    2768              :         //      corresponding vertex is an inner fracture vertex, and NULL if not.
    2769              :         grid.attach_to_faces(attVrtVec);
    2770              :         Grid::FaceAttachmentAccessor<AttVrtVec> aaVrtVecFace(grid, attVrtVec);
    2771              : 
    2772              : 
    2773              :         //      iterate over all surrounding faces to enable face changes, this loop taken from SR but shortened
    2774            0 :         for(FaceIterator iterSurrFac = sel.faces_begin(); iterSurrFac != sel.faces_end(); ++iterSurrFac )
    2775              :         {
    2776              :                 Face* sf = *iterSurrFac;
    2777              : 
    2778              :                 std::vector<Vertex*>& newVrts = aaVrtVecFace[sf];
    2779            0 :                 newVrts.resize(sf->num_vertices());
    2780              : 
    2781            0 :                 for(size_t i_vrt = 0; i_vrt < sf->num_vertices(); ++i_vrt)
    2782              :                 {
    2783            0 :                         newVrts[i_vrt] = nullptr;
    2784              :                 }
    2785              :                         // erstmal so tun, als ob keine neuen Vertizes erzeugt werden an den alten Vertizes
    2786              :         }
    2787              : 
    2788              : 
    2789              :         // attachment to allow fracture vertizes to know the newly created vertizes
    2790              :         // due to extrusion which are related to them, in connection with
    2791              :         // the normals which are an average of the related edges and the faces
    2792              :         // defining the original normal
    2793              : 
    2794              :         // usage: store edges and associated faces in SAME order in std vectors!
    2795              :         using ExpandVertexMultiplett = VertexFractureTriple< std::vector<Edge*>, std::vector<Face*>, vector3 >;
    2796              :         // holds the averaged normal of the related edges and their corresponding faces which give direction
    2797              : 
    2798              :         using VecExpandVertexMultiplett = std::vector<ExpandVertexMultiplett>;
    2799              : 
    2800              : 
    2801              :         VecExpandVertexMultiplett vertexMultiplettEmpty;
    2802              : 
    2803              :         using AttVecExpandVertexMultiplett = Attachment<VecExpandVertexMultiplett>;
    2804              : 
    2805              :         AttVecExpandVertexMultiplett aAdjInfoVVEVM;
    2806              : 
    2807              :         grid.attach_to_vertices_dv( aAdjInfoVVEVM, vertexMultiplettEmpty );
    2808              :         Grid::VertexAttachmentAccessor<AttVecExpandVertexMultiplett> aaVrtExpMP(grid, aAdjInfoVVEVM );
    2809              : 
    2810              : 
    2811              :         // am Ende dieser Prozedur sollten alle Vertizes wissen, welche Tripel vom Typ Edge - Face - Normal zum Face hin an ihnen angelagert sind
    2812              : 
    2813              :         // damit weiss, wenn es stimmt, jeder Vertex, der an einer Fracture ist, wieviele Schnittpunkte von Fractures er hat,
    2814              :         // ob er ein boundary vertex ist, und was für einen Vektor von Tripeln an ihm angehängt sind
    2815              :         // die subdomain der Fracture muss anhand der subdomain der edge bestimmt werden immer
    2816              : 
    2817              :         UG_LOG("loop over all marked vertizes " << std::endl);
    2818              : 
    2819              :         int dbg_vertizesPassiert = 0;
    2820              : 
    2821              : //      std::vector<Vertex *> crossVrts;
    2822              : //      std::vector<Vertex *> teeVrts;
    2823              : 
    2824              : //      using CrossVertInf = CrossingVertexInfo<Vertex*, IndexType, Edge*, Face* >;
    2825              : 
    2826              : //      std::vector<CrossingVertexInfo<Vertex*, IndexType> > vecCrossVrtInf;
    2827              :         std::vector<CrossVertInf > vecCrossVrtInf;
    2828              : 
    2829              : //      // needed for crossing points
    2830              : //      using VertexOfFaceInfo = VertexFractureTriple< std::pair<Edge*, Edge*>, Face*, std::pair<vector3,vector3> >;
    2831              : //      // all edges of the attached face - must always be two, the face itself, and the normal vectors of the face in direction of the two edges
    2832              : //      // the size of the normal vector vector also must be two
    2833              : //      // however, if an edge of the face is not a fracture edge, we do not compute the normal, but assign zero as norm
    2834              : //      // for those edges and faces which are Kluft edges, we assign the normal known from the info computed before, vertex fracture triple
    2835              : //
    2836              : //      using VecVertexOfFaceInfo = std::vector<VertexOfFaceInfo>;
    2837              : //
    2838              : //      using SegmentsFractExtrus = std::vector<VecVertexOfFaceInfo>;
    2839              : 
    2840              : 
    2841              :         // jetzt können wir alle Vertizes ablaufen und an ihnen neue Vertizes erzeugen, die anhand der gemittelten Normalen von den Vertizes weg gehen
    2842              :         // ob zwei anhängende Faces auf der gleichen Seite liegen, wenn es kein Schnittvertex von zwei oder mehr Klüften ist
    2843              :         // das kann man anhand des Winkels zwischen zwei face Normalen unterscheiden vermutlich
    2844              :         // dabei müssen die edges sowieso disjunkt sein, sonst ist man sowieso sicher auf verschiedenen Seiten
    2845              :         // wenn wir es mit einem boundary Vertex zu tun haben, müssen wir weiter überlegen, wie wir die Verschiebung auf die äussere Kante projizieren
    2846              :         // muss auch mit dem Winkel zu tun haben
    2847            0 :         for(VertexIterator iterV = sel.begin<Vertex>(); iterV != sel.end<Vertex>(); ++iterV)
    2848              :         {
    2849              : 
    2850              :                 // POsition dieses Vertex
    2851              :                 vector3 posOldVrt = aaPos[*iterV];
    2852              : 
    2853              :                 // vielleicht muss man, wenn die neuen Vertizes da sind, diese auch gleich mit den umliegenden Knoten per neuer Kanten verbinden
    2854              :                 // und die neuen faces erzeugen nach Löschen der alten?
    2855              :                 // oder alle neuen Vertizes wie bei Prof Reiter in einen std Vektor, der als attachment den bisherigen Face Vertizes angehängt wird
    2856              :                 // und Edge Vernichtung und Erzeugung neuer edges und faces wie bei Prof Reiter in Folgeschritten?
    2857              : 
    2858              :                 VecVertFracTrip & vecVertFracTrip = aaVrtInfoFraTri[*iterV];
    2859              : 
    2860              :                 std::vector<Edge*> & allAssoEdges = aaVrtInfoAssoEdges[*iterV];
    2861              : 
    2862              :                 // DEBUG ASSERT TEST static_assert( std::is_same< decltype( vecVertFracTrip[ vecVertFracTrip.size() - 1 ].getFace() ), Face * >::value );
    2863              :                 // DEBUG ASSERT TEST static_assert( std::is_same< decltype( vecVertFracTrip[ vecVertFracTrip.size() - 1 ].getEdge() ), Edge * >::value );
    2864              :                 // DEBUG ASSERT TEST static_assert( std::is_same< decltype( vecVertFracTrip[ vecVertFracTrip.size() - 1 ].getNormal() ), vector3 const >::value );
    2865              : 
    2866            0 :                 for( auto const & vft : vecVertFracTrip )
    2867              :                 {
    2868              :                         // DEBUG ASSERT TEST static_assert( std::is_same< decltype( vft.getFace() ), Face * >::value );
    2869              :                         // DEBUG ASSERT TEST static_assert( std::is_same< decltype( vft.getEdge() ), Edge * >::value );
    2870              :                         // DEBUG ASSERT TEST static_assert( std::is_same< decltype( vft.getNormal() ), vector3 const >::value );
    2871              : 
    2872              :                         Face * f = vft.getFace();
    2873              :                         Edge * e = vft.getEdge();
    2874              :                         vector3 n = vft.getNormal();
    2875              : 
    2876              :                 }
    2877              : 
    2878              :                 using VvftIterator = VecVertFracTrip::iterator;
    2879              : 
    2880              :                 VecFace & assoFaces = aaVrtInfoAssoFaces[*iterV];
    2881              :                 // TODO FIXME hier braucht man das nicht zu ordnen
    2882              :                 // aber bei Kreuzpunkten von Klueften muss es so geordnet werden, wie es nebeneinander liegt
    2883              :                 // bei den Edges gibt es auch die benachbarten, und die edges haben das attachment, ob sie Kluftedges sind
    2884              : 
    2885              : //              for( auto const & ifac : assoFaces )
    2886              : //              {
    2887              : //                      // DEBUG ASSERT TEST static_assert( std::is_same< decltype( ifac ), Face * const & >::value );
    2888              : //              }
    2889              : 
    2890              : 
    2891              : 
    2892              :                 // Anzahl der Kreuzungspunkte auslesen und danach unterscheiden, erstmal keine Kreuzung! TODO FIXME
    2893              : 
    2894              :                 // irgendwie muessen wir diese Infos jetzt verwerten, um als erstes neue Vertizes zu erzeugen, anfangs für eine Kluft nur
    2895              :                 // und danach die alten Edges und faces löschen und an neuer Stelle neu erzeugen, plus die sowieso neuen,
    2896              :                 // oder Edges verschieben, wenn es möglich ist, die Vertizes zu verschieben, und die Edges und in Folge faces passen sich an,
    2897              :                 // dann müssen nur die neuen edges und faces neu erzeugt werden
    2898              :                 // verschieben der Position des Vertex löst Kaskade aus, dass Edge und Face auch verschoben werden, kann also angewendet werden
    2899              :                 // allerdings Problem, dass die Vertizes dafür verdoppelt werden müssen und die Kanten, sonst kann man sie nicht nach aussen verschieben
    2900              :                 // also doch komplette Neuerzeugung vermutlich..... oder doppeltes Klonen, und das alte bleibt in der Mitte.....
    2901              : 
    2902              :                 vector3 posThisVrt =  aaPos[*iterV];
    2903              : 
    2904            0 :                 UG_LOG("vertex at " << posThisVrt << std::endl );
    2905              : 
    2906              :                 bool vrtxIsBndVrt = aaMarkVrtVFP[*iterV].getIsBndFracVertex();
    2907              :                 // alternativ wäre möglich: IsBoundaryVertex2D(grid, *iterV)
    2908              : 
    2909              :                 UG_LOG("is bndry " << vrtxIsBndVrt << std::endl);
    2910              : 
    2911              :                 IndexType numFracsCrossAtVrt = aaMarkVrtVFP[*iterV].getNumberFracEdgesInVertex();
    2912              : 
    2913              :                 UG_LOG("number crossing fracs " << numFracsCrossAtVrt << std::endl);
    2914              : 
    2915              :                 size_t numbAttTripl = vecVertFracTrip.size();
    2916              : 
    2917              :                 UG_LOG("sizes of vft " << numbAttTripl << std::endl );
    2918              : 
    2919            0 :                 if( ! vrtxIsBndVrt )
    2920              :                 {
    2921              : 
    2922              : #if 0
    2923              :                         CrossVertInf crossVrtInf( *iterV, numFracsCrossAtVrt );
    2924              : 
    2925              :                         //                              using VecVertexOfFaceInfo = std::vector<VertexOfFaceInfo>;
    2926              :                         VecVertexOfFaceInfo orderedFaces;
    2927              : 
    2928              : //                              using SegmentsFractExtrus = std::vector<VecVertexOfFaceInfo>;
    2929              : 
    2930              :                         SegmentsFractExtrus segments;
    2931              :                         // single components always from one fracture edge to the next one
    2932              : 
    2933              :                         VecVertexOfFaceInfo segmentPart;
    2934              : 
    2935              :                         // note: we do not attach this info to the vertex, as we only need it local; in principle, in case of further need, it would
    2936              :                         // be usful to establish some sort of attachment
    2937              : 
    2938              :                         // fixed: diesen Sortierungsalgorithmus bei allen inneren Knoten anwenden,
    2939              :                         // um zweifelsfrei alle anhängenden Faces der richtigen Seite zuordnen zu können!!!!
    2940              : 
    2941              :                         // VecVertFracTrip & vecVertFracTrip = aaVrtInfoFraTri[*iterV];
    2942              :                         // VecFace & assoFaces = aaVrtInfoAssoFaces[*iterV];
    2943              : 
    2944              :                         IndexType startIndex = 0;
    2945              : 
    2946              :                         if( numFracsCrossAtVrt > 1 )
    2947              :                         {
    2948              :                                 determineOrderOfFaces( // crossVrtInf,
    2949              :                                                                                 vecVertFracTrip, assoFaces,  orderedFaces,
    2950              :                                                                                 segments, segmentPart, startIndex, allAssoEdges,
    2951              :                                                                                 sh, aaMarkEdgeB
    2952              :                                                                         );
    2953              :                         }
    2954              : #endif
    2955            0 :                         if( numFracsCrossAtVrt < 1 )
    2956              :                         {
    2957            0 :                                 UG_THROW("no fracs crossing but marked vertex? << std::endl");
    2958              :                         }
    2959            0 :                         else if( numFracsCrossAtVrt == 1 )
    2960              :                         {
    2961              : 
    2962              :                                 // do nothing
    2963              : 
    2964              : //                              if( numbAttTripl != 0 )
    2965              : //                              {
    2966              : //                                      UG_THROW("Anzahl der angehaengten Triples kann nicht stimmen, Vertex einer Kluft ohne Schnittpunkte, nicht am Rand, Kluftende " << std::endl);
    2967              : //                              }
    2968              : 
    2969              : 
    2970              : 
    2971              :                                 UG_LOG("END THIS VERTEX NORMAL INNER ENDING CLEFT" << std::endl);
    2972              : 
    2973              : 
    2974              : //                              if( ! dehneInnereKluftGrenzpunkteAus )
    2975              : //                              {
    2976              : //                                      break;
    2977              : //                              }
    2978              :                                 // inner vertex where fracture ends
    2979              :                                 // TODO FIXME
    2980              : 
    2981              :                                 // in this case, we have two attached edges, and each of these edges has two attached faces
    2982              :                                 // the faces have a naormal, and based on the normal, we can decide which faces belong to the same side of the edges
    2983              : 
    2984              : #if 0
    2985              : 
    2986              :                                 if( numbAttTripl != 2 )
    2987              :                                 {
    2988              :                                         UG_THROW("Anzahl der angehaengten Triples kann nicht stimmen, Vertex einer Kluft ohne Schnittpunkte, nicht am Rand, Kluftende " << std::endl);
    2989              :                                 }
    2990              : 
    2991              :                                 // Zuordnung der Edges und Faces, die auf der gleichen Seite der fracture sind
    2992              : 
    2993              :                                 // und gleich auch Erzeugung der neuen Knoten, die dann
    2994              :                                 // in einem Doublett zusammen mit ihren Normalen an die alten Vertizes
    2995              :                                 // angehängt werden; der Winkel zur Normalen hilft später, die Seite
    2996              :                                 // heraus zu finden, Seite von den Edges
    2997              : 
    2998              :                                 int dbg_iteratorAblaufen = 0;
    2999              : 
    3000              : 
    3001              : #if WORKAROUND_ARTE_SEGFAULT
    3002              : 
    3003              :                                 int dbg_laenge = 0;
    3004              : 
    3005              :                                 for( auto const & vft : vecVertFracTrip )
    3006              :                                 {
    3007              :                                         dbg_laenge++;
    3008              : 
    3009              :                                         UG_LOG("VERTEXFRACTRIP" << std::endl);
    3010              : 
    3011              :                                         vector3 ve = vft.getNormal();
    3012              : 
    3013              :                                         UG_LOG("NORMAL " << ve << std::endl);
    3014              : 
    3015              :                                         UG_LOG("laenge " << dbg_laenge << std::endl );
    3016              :                                 }
    3017              : 
    3018              :                                 int dbg_laenge_eins = 0;
    3019              : 
    3020              : #endif
    3021              : 
    3022              : 
    3023              : 
    3024              :                                 for( VvftIterator vvftV = vecVertFracTrip.begin();
    3025              :                                                 vvftV != vecVertFracTrip.end();
    3026              :                                                 vvftV++
    3027              :                                 )
    3028              :                                 {
    3029              : 
    3030              : #if WORKAROUND_ARTE_SEGFAULT
    3031              :                                         dbg_laenge_eins++;
    3032              : 
    3033              :                                         if( dbg_laenge_eins > dbg_laenge )
    3034              :                                         {
    3035              :                                                 break;
    3036              :                                         }
    3037              : 
    3038              : #endif
    3039              : 
    3040              :                                         vector3 nV = vvftV->getNormal();
    3041              : 
    3042              :                                         Edge * edgeV = vvftV->getEdge();
    3043              : 
    3044              : 
    3045              : 
    3046              : #if WORKAROUND_ARTE_SEGFAULT
    3047              : 
    3048              :                                         UG_LOG("NORMAL " << vvftV->getNormal() << std::endl);
    3049              :                                         UG_LOG("LAENGE EINZ " << dbg_laenge_eins << std::endl );
    3050              : #endif
    3051              : 
    3052              :                                         Vertex * nextFracVrt;
    3053              : 
    3054              :                                         IndexType foundThisVrt = 0;
    3055              : 
    3056              :                                         for( size_t i = 0; i < 2; ++i )
    3057              :                                         {
    3058              :                                                 Vertex * vrtEdgEnd = edgeV->vertex(i);
    3059              : 
    3060              :                                                 if( vrtEdgEnd == *iterV )
    3061              :                                                 {
    3062              :                                                         foundThisVrt++;
    3063              :                                                 }
    3064              :                                                 else
    3065              :                                                 {
    3066              :                                                         nextFracVrt = vrtEdgEnd ;
    3067              :                                                 }
    3068              : 
    3069              :                                         }
    3070              : 
    3071              :                                         if( foundThisVrt != 1 )
    3072              :                                         {
    3073              :                                                 UG_THROW("zu viel zu wenig vertizex one " << std::endl);
    3074              :                                         }
    3075              : 
    3076              : 
    3077              : 
    3078              :                                         // Klasse schreiben, die als attachment an einen Fracture-Vertex
    3079              :                                         // die neuen Vertizes samt ihrer gemittelten Normalen speichert
    3080              :                                         // also std::vector von dieser neuen Klasse als Vertex attachment
    3081              : 
    3082              :                                         std::vector<Edge * > attEdg;
    3083              :                                         std::vector<Face * > attFac;
    3084              : 
    3085              :                                         attEdg.push_back( edgeV );
    3086              : 
    3087              :                                         Face * facV = vvftV->getFace();
    3088              : 
    3089              :                                         attFac.push_back( facV );
    3090              : 
    3091              :                                         // jetzt neuen Vertex erzeugen in Richtung der Normalen
    3092              :                                         // sonst ist das attachment Schwachsinn!
    3093              : 
    3094              :                                         vector3 posNewVrt;
    3095              : 
    3096              :                                         vector3 moveVrt;
    3097              : 
    3098              :                                         auto subsIndEdgV = sh.get_subset_index(edgeV);
    3099              : 
    3100              :                                         number width = fracInfosBySubset.at(subsIndEdgV).width;
    3101              : 
    3102              : //                                      if( expandInnerFracBnds )
    3103              : //                                      {
    3104              : //                                              // der Faktor ist Käse und muss noch aus den Eingaben übernommen werden
    3105              : //                                              VecScale(moveVrt, nV, width/2. );
    3106              : //                                      }
    3107              : //                                      else
    3108              : //                                      {
    3109              : //                                              // auf Annes Wunsch hin werden die Normalen innendrin an einer endenen Kluft zu Null gesetzt
    3110              : //
    3111              : //                                              VecScale(moveVrt, nV, 0. );
    3112              : //
    3113              : //                                      }
    3114              : 
    3115              :                                         VecScale(moveVrt, nV, width/2. );
    3116              : 
    3117              :                                         VecAdd(posNewVrt, posOldVrt, moveVrt );
    3118              : 
    3119              :                                         UG_LOG("neuer Vertex " << posNewVrt << std::endl );
    3120              : 
    3121              :                                         // TODO FIXME hier ist das PROBLEM, SEGFAULT durch create regular vertex
    3122              : 
    3123              : 
    3124              : 
    3125              :                                         Vertex * newShiftVrtx = *grid.create<RegularVertex>();
    3126              :                                         aaPos[newShiftVrtx] = posNewVrt;
    3127              : 
    3128              :                                         sh.assign_subset(newShiftVrtx, subsIndEdgV );
    3129              : 
    3130              : 
    3131              : 
    3132              :                                         // fuer was braucheh wir das eigentlich? selber schon vergessen.....
    3133              : 
    3134              :                                         ExpandVertexMultiplett vrtMtpl( attEdg, attFac, nV );
    3135              : 
    3136              :                                         aaVrtExpMP[ *iterV ].push_back( vrtMtpl );
    3137              : 
    3138              : 
    3139              : 
    3140              :                                         // alle anhängenden faces müssen noch zu wissen bekommen
    3141              :                                         // dass es diesen neuen Vertex gibt, nicht nur die
    3142              :                                         // an den edges anhängenden
    3143              :                                         // vielleicht gibt es einen Loop über attached faces des
    3144              :                                         // Vertex, für die schon bekannten direkt angehängten klar
    3145              :                                         // wenn auch dort vermerkt werden muss im Attachment von Seb
    3146              :                                         // bei den anderen, die keine Edge haben von der Kluft
    3147              :                                         // da muss man die Normale ins Zentrum bestimmen
    3148              :                                         // um heraus zu finden, ob sie auf dieser seite sind
    3149              :                                         // am besten dann das Attachment der faces für vertizes
    3150              :                                         // von Seb recyclen
    3151              : 
    3152              :                                         // loop über assosciated faces des vertex am besten
    3153              :                                         // vermutlich auch noch assosciated edges, um
    3154              :                                         // zu markieren, welche weg fallen sollen, wenn
    3155              :                                         // nicht von Kluft selber, sondern quasi verschoben
    3156              :                                         // und neu erzeugt
    3157              : 
    3158              :                                         int dbg_FaceIterator = 0;
    3159              : 
    3160              : 
    3161              : 
    3162              :                                         for( auto const & ifac : assoFaces )
    3163              :                                         {
    3164              :                                                 bool isFromFrac = false;
    3165              : 
    3166              :                                                 for( auto const & facFrac : attFac )
    3167              :                                                 {
    3168              : 
    3169              : //                                                                                      // DEBUG ASSERT TEST static_assert( std::is_same<  decltype( const_cast<Face* & >(facFrac) ), decltype ( ifac ) >::value );
    3170              :                                                         // DEBUG ASSERT TEST static_assert( std::is_same<  decltype( (facFrac) ), decltype ( ifac ) >::value );
    3171              : 
    3172              :                                                         if( ifac == facFrac )
    3173              :                                                         {
    3174              :                                                                 isFromFrac = true;
    3175              : 
    3176              : //                                                                                                      // DEBUG ASSERT TEST static_assert( std::is_same< decltype( const_cast<Face* & >(facFrac) ), Face * & >::value  );
    3177              :                                                                 // DEBUG ASSERT TEST static_assert( std::is_same< decltype( (facFrac) ), Face * const & >::value  );
    3178              : //                                                                                              // DEBUG ASSERT TEST static_assert( std::is_same< decltype( const_cast<Face* & >(facFrac) ), decltype( ifac ) >::value  );
    3179              :                                                                 // DEBUG ASSERT TEST static_assert( std::is_same< decltype( (facFrac) ), decltype( ifac ) >::value  );
    3180              : 
    3181              :                                                         }
    3182              :                                                 }
    3183              : 
    3184              : 
    3185              :                                                 bool atRightSide = false;
    3186              : 
    3187              :                                                 if( isFromFrac )
    3188              :                                                         atRightSide = true;
    3189              : 
    3190              :                                                 if( !isFromFrac )
    3191              :                                                 {
    3192              :                                                         // check if on same side of edge where the normal points to: compute cosinus between vector of face center
    3193              :                                                         //  perpendicular to the edge
    3194              : 
    3195              : 
    3196              : 
    3197              : 
    3198              :                                                         vector3 facCenter = CalculateCenter( ifac, aaPos );
    3199              : 
    3200              :                                                         vector3 perpendicu;
    3201              : 
    3202              : 
    3203              : //                                                      UG_LOG("pos 0 " << aaPos[nextFracVrt[0]] << std::endl);
    3204              : //                                                      UG_LOG("pos 1 " << aaPos[*iterV] << std::endl);
    3205              : //                                                      UG_LOG("fac ce " << facCenter << std::endl);
    3206              : 
    3207              :                                                         DropAPerpendicular(perpendicu, facCenter, aaPos[nextFracVrt], aaPos[*iterV]);
    3208              : 
    3209              : //                                                      if( dbg_FaceIterator == 1 )
    3210              : //                                                      {
    3211              : //                                                              UG_LOG("huhu a0" << std::endl);
    3212              : //                                                              return true;
    3213              : //                                                      }
    3214              : 
    3215              : 
    3216              :                                                         vector3 tmpN;
    3217              : 
    3218              :                                                         VecSubtract(tmpN, facCenter, perpendicu );
    3219              : 
    3220              :                                                         VecNormalize(tmpN, tmpN);
    3221              : 
    3222              :                                                         UG_LOG("Normale zum Face ist " << tmpN << std::endl);
    3223              : 
    3224              :                                                         number cosBetwFracEdgAndDirection2Face = VecDot(tmpN, nV );
    3225              : 
    3226              :                                                         UG_LOG("Cosinus zur Normalen ist " << cosBetwFracEdgAndDirection2Face << std::endl);
    3227              : 
    3228              : //                                                      if( dbg_FaceIterator == 1 )
    3229              : //                                                      {
    3230              : //                                                              UG_LOG("huhu a" << std::endl);
    3231              : ////                                                            return true;
    3232              : //                                                      }
    3233              : 
    3234              : 
    3235              :                                                         if( cosBetwFracEdgAndDirection2Face > 0 )
    3236              :                                                         {
    3237              :                                                                 UG_LOG("assuming face to be on richt side" << std::endl);
    3238              : 
    3239              :                                                                 atRightSide = true;
    3240              : 
    3241              : #if ESTABLISH_DEBUG_SUDOS
    3242              : 
    3243              :                                                                 Vertex * otherFacCent = *grid.create<RegularVertex>();
    3244              :                                                                 aaPos[otherFacCent] = facCenter;
    3245              :                                                                 sh.assign_subset(otherFacCent, 6 );
    3246              : 
    3247              :                                                                 Vertex * pp = *grid.create<RegularVertex>();
    3248              :                                                                 aaPos[pp] = perpendicu;
    3249              :                                                                 sh.assign_subset(pp, 7 );
    3250              : 
    3251              :                                                                 sh.assign_subset(ifac,8);
    3252              : 
    3253              : #endif
    3254              : 
    3255              :                                                         }
    3256              :                                                         else
    3257              :                                                         {
    3258              :                                                                 UG_LOG("assuming face to be on wrong side" << std::endl);
    3259              :                                                         }
    3260              : 
    3261              : 
    3262              :                                                         dbg_flachen_passiert++;
    3263              :                                                 }
    3264              : 
    3265              : 
    3266              : //                                              if( dbg_FaceIterator == 1 )
    3267              : //                                              {
    3268              : //                                                      UG_LOG("huhu b" << std::endl);
    3269              : ////                                                    return true;
    3270              : //                                              }
    3271              : 
    3272              : 
    3273              : 
    3274              :                                                 if( atRightSide ) // atRightSide ) NOCH FALSCH TODO FIXME muss nur auf richtiger Seite sein
    3275              :                                                 {
    3276              : 
    3277              :                                                         // ACHTUNG neue Variable Face klein geschrieben im Gegensatz zu Prof. Reiter! nicht später falsche verwenden!
    3278              :                                                         vector<Vertex*>& newVrts4Fac = aaVrtVecFace[ ifac ];
    3279              : 
    3280              :                                                         IndexType vrtxFnd = 0;
    3281              : 
    3282              :                                                         for(size_t indVrt = 0; indVrt < (ifac)->num_vertices();  indVrt++ )
    3283              :                                                         {
    3284              :                                                                 Vertex* facVrt = (ifac)->vertex(indVrt);
    3285              : 
    3286              :                                                                 if(  facVrt == *iterV )
    3287              :                                                                 {
    3288              :                                                                         newVrts4Fac[ indVrt ] = newShiftVrtx;
    3289              :                                                                         vrtxFnd++;
    3290              :                                                                 }
    3291              :                                                         }
    3292              : 
    3293              : 
    3294              :                                                         if( vrtxFnd <= 0 )
    3295              :                                                         {
    3296              :                                                                 UG_THROW("vertex not found!" << std::endl);
    3297              :                                                         }
    3298              :                                                         else if( vrtxFnd > 1 )
    3299              :                                                         {
    3300              :                                                                 UG_THROW("vertex zu oft gefunden " << vrtxFnd << std::endl );
    3301              :                                                         }
    3302              :                                                         else if ( vrtxFnd == 1 )
    3303              :                                                         {
    3304              :                                                         }
    3305              :                                                         else
    3306              :                                                         {
    3307              :                                                                 UG_THROW("vertex finden komisch " << std::endl);
    3308              :                                                         }
    3309              : 
    3310              : 
    3311              :                                                 }
    3312              : 
    3313              :                                                 dbg_FaceIterator++;
    3314              : 
    3315              :                                         }
    3316              : 
    3317              : 
    3318              : 
    3319              : 
    3320              : 
    3321              : 
    3322              : 
    3323              : 
    3324              :                                 }
    3325              : 
    3326              : 
    3327              : 
    3328              :                                 dbg_iteratorAblaufen++;
    3329              : 
    3330              : 
    3331              : 
    3332              : //                              // Ziel: die beiden parallelen Normalen mitteln, und in die jeweiligen beiden Richtungen je einen neuen Vertex erzeugen
    3333              : //                              // irgendwie muss der Vertex oder die Edge besser sogar wissen, dass sie einen neuen Verschiebevertex bekommen hat
    3334              : //                              // denn später müssen neue Edges und neue Faces basierend auf den neuen Vertizes erzeugt werden
    3335              : //                              // vielleicht braucht die edge und das face ein Attachment, das ihnen das sagt, ähnlihc wie VertexTrible std Vektoren?
    3336              : //
    3337              : //
    3338              : //
    3339              :                                 UG_LOG("END THIS VERTEX NORMAL INNER ENDING CLEFT" << std::endl);
    3340              : 
    3341              : #endif
    3342              : 
    3343              : 
    3344              : //                              return true;
    3345              : 
    3346              : 
    3347              :                         }
    3348              : //                      else if( numFracsCrossAtVrt == 2 ) // free line of fracture, no crossing point, not at boundary
    3349              :                         else if( false ) // free line of fracture, no crossing point, not at boundary
    3350              :                         {
    3351              :                                 // in this case, we have two attached edges, and each of these edges has two attached faces
    3352              :                                 // the faces have a naormal, and based on the normal, we can decide which faces belong to the same side of the edges
    3353              : 
    3354              : 
    3355              :                                 if( numbAttTripl != 4 )
    3356              :                                 {
    3357              : 
    3358              :                                         UG_LOG("NUMBER OF TRIPLETTS " << numbAttTripl << std::endl);
    3359              : 
    3360              : //                                      return true;
    3361              : 
    3362              :                                         UG_THROW("Anzahl der angehaengten Triples kann nicht stimmen, Vertex einer Kluft ohne Schnittpunkte, nicht am Rand " << std::endl);
    3363              :                                 }
    3364              : 
    3365              :                                 // Zuordnung der Edges und Faces, die auf der gleichen Seite der fracture sind
    3366              : 
    3367              :                                 // und gleich auch Erzeugung der neuen Knoten, die dann
    3368              :                                 // in einem Doublett zusammen mit ihren Normalen an die alten Vertizes
    3369              :                                 // angehängt werden; der Winkel zur Normalen hilft später, die Seite
    3370              :                                 // heraus zu finden, Seite von den Edges
    3371              : 
    3372              : 
    3373              : 
    3374              :                                 int dbg_iteratorAblaufen = 0;
    3375              : 
    3376              : #if WORKAROUND_ARTE_SEGFAULT
    3377              : 
    3378              :                                 int dbg_laenge = 0;
    3379              : 
    3380              :                                 for( auto const & vft : vecVertFracTrip )
    3381              :                                 {
    3382              :                                         dbg_laenge++;
    3383              : 
    3384              :                                         UG_LOG("VERTEXFRACTRIP" << std::endl);
    3385              : 
    3386              :                                         vector3 ve = vft.getNormal();
    3387              : 
    3388              :                                         UG_LOG("NORMAL " << ve << std::endl);
    3389              : 
    3390              :                                         UG_LOG("laenge " << dbg_laenge << std::endl );
    3391              :                                 }
    3392              : 
    3393              : 
    3394              :                                 UG_LOG("SINGLE" << std::endl);
    3395              : 
    3396              : 
    3397              :                                 for( VvftIterator vvftOne = vecVertFracTrip.begin();
    3398              :                                                 vvftOne != vecVertFracTrip.end() - 1;
    3399              :                                                 vvftOne++
    3400              :                                 )
    3401              :                                 {
    3402              : 
    3403              : 
    3404              :                                         Edge * edgeOne = vvftOne->getEdge();
    3405              :                                         vector3 nOne = vvftOne->getNormal();
    3406              : 
    3407              : 
    3408              :                                         for( VvftIterator vvftTwo = vvftOne + 1;
    3409              :                                                         vvftTwo != vecVertFracTrip.end();
    3410              :                                                         vvftTwo++
    3411              :                                         )
    3412              :                                         {
    3413              :                                                 Edge * edgeTwo = vvftTwo->getEdge();
    3414              :                                                 vector3 nTwo = vvftTwo->getNormal();
    3415              : 
    3416              :                                                 number cosinus = VecDot( nOne, nTwo );
    3417              : 
    3418              :                                                 if( edgeOne != edgeTwo )
    3419              :                                                 {
    3420              :                                                         UG_LOG("COSI  between " << nOne << " and " << nTwo << " -> " << cosinus << std::endl );
    3421              :                                                 }
    3422              : 
    3423              :                                         }
    3424              :                                 }
    3425              : 
    3426              :                                 UG_LOG("SINGLE END" << std::endl);
    3427              : 
    3428              :                                 int dbg_laenge_eins = 0;
    3429              : 
    3430              : #endif
    3431              : 
    3432              : 
    3433              :                                 for( VvftIterator vvftOne = vecVertFracTrip.begin();
    3434              :                                                 vvftOne != vecVertFracTrip.end() - 1;
    3435              :                                                 vvftOne++
    3436              :                                 )
    3437              :                                 {
    3438              : 
    3439              : #if WORKAROUND_ARTE_SEGFAULT
    3440              :                                         dbg_laenge_eins++;
    3441              : 
    3442              :                                         if( dbg_laenge_eins > dbg_laenge )
    3443              :                                         {
    3444              :                                                 break;
    3445              :                                         }
    3446              : 
    3447              :                                         int dbg_laenge_zwei = dbg_laenge_eins;
    3448              : #endif
    3449              :                                         int dbg_zweiterIteratorAblaufen = 0;
    3450              : 
    3451              :                                         vector3 nOne = vvftOne->getNormal();
    3452              : 
    3453              :                                         Edge * edgeOne = vvftOne->getEdge();
    3454              : 
    3455              : 
    3456              : 
    3457              :                                         for( VvftIterator vvftTwo = vvftOne + 1;
    3458              :                                                         vvftTwo != vecVertFracTrip.end();
    3459              :                                                         vvftTwo++
    3460              :                                         )
    3461              :                                         {
    3462              : 
    3463              : #if WORKAROUND_ARTE_SEGFAULT
    3464              :                                                 dbg_laenge_zwei++;
    3465              : 
    3466              :                                                 if( dbg_laenge_zwei > dbg_laenge )
    3467              :                                                 {
    3468              :                                                         break;
    3469              :                                                 }
    3470              : 
    3471              :                                                 UG_LOG("NORMAL ONE " << vvftOne->getNormal() << std::endl);
    3472              :                                                 UG_LOG("NORMAL TWO " << vvftTwo->getNormal() << std::endl);
    3473              :                                                 UG_LOG("LAENGE EINZ ZWO " << dbg_laenge_eins << " " << dbg_laenge_zwei << std::endl );
    3474              : #endif
    3475              : 
    3476              :                                                 // dieselben brauchen wir nicht vergleichen
    3477              :                                                 if( vvftOne == vvftTwo )
    3478              :                                                 {
    3479              :                                                         // sollte nie vorkommen!
    3480              :                                                         UG_THROW("Unsinn " << std::endl);
    3481              :                                                 }
    3482              :                                                 else
    3483              :                                                 {
    3484              : 
    3485              :                                                         Edge * edgeTwo = vvftTwo->getEdge();
    3486              : 
    3487              :                                                         // noch testen, ob nicht die Kante dieselbe ist, geht das?
    3488              :                                                         // bei der gleichen Ecke ist es unnötig, da es gegensätzlich sein muss
    3489              : 
    3490              : 
    3491              : 
    3492              :                                                         if( edgeOne != edgeTwo )
    3493              :                                                         {
    3494              : 
    3495              :                                                                 std::vector<Vertex *> nextFracVrt;
    3496              : 
    3497              :                                                                 IndexType foundThisVrtOne = 0;
    3498              : 
    3499              :                                                                 for( size_t i = 0; i < 2; ++i )
    3500              :                                                                 {
    3501              :                                                                         Vertex * vrtEdgEnd = edgeOne->vertex(i);
    3502              : 
    3503              :                                                                         if( vrtEdgEnd == *iterV )
    3504              :                                                                         {
    3505              :                                                                                 foundThisVrtOne++;
    3506              :                                                                         }
    3507              :                                                                         else
    3508              :                                                                         {
    3509              :                                                                                 nextFracVrt.push_back( vrtEdgEnd );
    3510              :                                                                         }
    3511              : 
    3512              :                                                                 }
    3513              : 
    3514              :                                                                 if( foundThisVrtOne != 1 )
    3515              :                                                                 {
    3516              :                                                                         UG_THROW("zu viel zu wenig vertizex one " << std::endl);
    3517              :                                                                 }
    3518              : 
    3519              : 
    3520              :                                                                 IndexType foundThisVrtTwo = 0;
    3521              : 
    3522              :                                                                 for( size_t i = 0; i < 2; ++i )
    3523              :                                                                 {
    3524              :                                                                         Vertex * vrtEdgEnd = edgeTwo->vertex(i);
    3525              : 
    3526              :                                                                         if( vrtEdgEnd == *iterV )
    3527              :                                                                         {
    3528              :                                                                                 foundThisVrtTwo++;
    3529              :                                                                         }
    3530              :                                                                         else
    3531              :                                                                         {
    3532              :                                                                                 nextFracVrt.push_back( vrtEdgEnd );
    3533              :                                                                         }
    3534              : 
    3535              :                                                                 }
    3536              : 
    3537              :                                                                 if( foundThisVrtTwo != 1 )
    3538              :                                                                 {
    3539              :                                                                         UG_THROW("zu viel zu wenig vertizex two " << std::endl);
    3540              :                                                                 }
    3541              : 
    3542              : 
    3543              : 
    3544              :                                                                 vector3 nTwo = vvftTwo->getNormal();
    3545              : 
    3546              :                                                                 number cosinus = VecDot( nOne, nTwo );
    3547              : 
    3548              : //                                                              bool vz = ! std::signbit(cosinus);
    3549              : 
    3550              :                                                                 UG_LOG("cosinus " << dbg_vertizesPassiert << " between " << nOne << " and " << nTwo << " -> " << cosinus << std::endl );
    3551              :                                                                 //UG_LOG("sign between " << nOne << " and " << nTwo << " -> " << vz << std::endl );
    3552              : 
    3553              : 
    3554              :                                                                 if( cosinus > 0 )
    3555              :                                                                 {
    3556              :                                                                         // gleiche Seite vermutet
    3557              : 
    3558              :                                                                         // sind die edges dieselben? pruefen! gleiche unnoetig - wird oben schon abgefragt
    3559              : 
    3560              :                                                                         // Klasse schreiben, die als attachment an einen Fracture-Vertex
    3561              :                                                                         // die neuen Vertizes samt ihrer gemittelten Normalen speichert
    3562              :                                                                         // also std::vector von dieser neuen Klasse als Vertex attachment
    3563              : 
    3564              : #if 1
    3565              : 
    3566              :                                                                         Face * facOne = vvftOne->getFace();
    3567              :                                                                         Face * facTwo = vvftTwo->getFace();
    3568              : 
    3569              :                                                                         expandSingleFractureAtGivenSide( nOne, nTwo,
    3570              :                                                                                                                                          edgeOne, edgeTwo,
    3571              :                                                                                                                                          facOne, facTwo,
    3572              :                                                                                                                                          fracInfosBySubset,
    3573              :                                                                                                                                          posOldVrt,
    3574              :                                                                                                                                          aaPos,
    3575              :                                                                                                                                          grid, sh,
    3576              :                                                                                                                                          assoFaces,
    3577              :                                                                                                                                          nextFracVrt,
    3578              :                                                                                                                                          aaVrtVecFace,
    3579              :                                                                                                                                          dbg_flachen_passiert,
    3580              :                                                                                                                                          *iterV
    3581              :                                                                                                                                         );
    3582              : 
    3583              : #else
    3584              : 
    3585              :                                                                         // average the normals
    3586              : 
    3587              :                                                                         vector3 normSum;
    3588              : 
    3589              :                                                                         VecAdd( normSum, nOne, nTwo );
    3590              : 
    3591              :                                                                         vector3 normSumNormed;
    3592              : 
    3593              :                                                                         VecNormalize(normSumNormed, normSum);
    3594              : 
    3595              :                                                                         UG_LOG("averaged normal " << normSumNormed << std::endl);
    3596              : 
    3597              :                                                                         std::vector<Edge * > attEdg;
    3598              :                                                                         std::vector<Face * > attFac;
    3599              : 
    3600              :                                                                         attEdg.push_back( edgeOne );
    3601              :                                                                         attEdg.push_back( edgeTwo );
    3602              : 
    3603              : //                                                                      Face * facOne = vvftOne->getFace();
    3604              : //                                                                      Face * facTwo = vvftTwo->getFace();
    3605              : 
    3606              :                                                                         attFac.push_back( facOne );
    3607              :                                                                         attFac.push_back( facTwo );
    3608              : 
    3609              :                                                                         // jetzt neuen Vertex erzeugen in Richtung der Normalen
    3610              :                                                                         // sonst ist das attachment Schwachsinn!
    3611              : 
    3612              :                                                                         vector3 posNewVrt;
    3613              : 
    3614              :                                                                         vector3 moveVrt;
    3615              : 
    3616              :                                                                         auto subsIndEdgOne = sh.get_subset_index(edgeOne);
    3617              : 
    3618              :                                                                         auto subsIndEdgTwo = sh.get_subset_index(edgeTwo);
    3619              : 
    3620              : 
    3621              :                                                                         if( subsIndEdgOne != subsIndEdgTwo )
    3622              :                                                                         {
    3623              :                                                                                 UG_THROW("subsets passen nicht" << std::endl );
    3624              :                                                                         }
    3625              : 
    3626              : 
    3627              : 
    3628              : 
    3629              :                                                                         number width = fracInfosBySubset.at(subsIndEdgOne).width;
    3630              : 
    3631              :                                                                         // der Faktor ist Käse und muss noch aus den Eingaben übernommen werden
    3632              :                                                                         VecScale(moveVrt, normSumNormed, width/2. );
    3633              : 
    3634              :                                                                         VecAdd(posNewVrt, posOldVrt, moveVrt );
    3635              : 
    3636              :                                                                         UG_LOG("neuer Vertex " << posNewVrt << std::endl );
    3637              : 
    3638              :                                                                         // TODO FIXME hier ist das PROBLEM, SEGFAULT durch create regular vertex
    3639              : 
    3640              :                                                                         Vertex * newShiftVrtx = *grid.create<RegularVertex>();
    3641              :                                                                         aaPos[newShiftVrtx] = posNewVrt;
    3642              : 
    3643              :                                                                         sh.assign_subset(newShiftVrtx, subsIndEdgOne );
    3644              : 
    3645              : 
    3646              : 
    3647              :                                                                         // fuer was braucheh wir das eigentlich? selber schon vergessen.....
    3648              : 
    3649              :                                                                         ExpandVertexMultiplett vrtMtpl( attEdg, attFac, normSumNormed );
    3650              : 
    3651              :                                                                         aaVrtExpMP[ *iterV ].push_back( vrtMtpl );
    3652              : 
    3653              : 
    3654              : 
    3655              :                                                                         // alle anhängenden faces müssen noch zu wissen bekommen
    3656              :                                                                         // dass es diesen neuen Vertex gibt, nicht nur die
    3657              :                                                                         // an den edges anhängenden
    3658              :                                                                         // vielleicht gibt es einen Loop über attached faces des
    3659              :                                                                         // Vertex, für die schon bekannten direkt angehängten klar
    3660              :                                                                         // wenn auch dort vermerkt werden muss im Attachment von Seb
    3661              :                                                                         // bei den anderen, die keine Edge haben von der Kluft
    3662              :                                                                         // da muss man die Normale ins Zentrum bestimmen
    3663              :                                                                         // um heraus zu finden, ob sie auf dieser seite sind
    3664              :                                                                         // am besten dann das Attachment der faces für vertizes
    3665              :                                                                         // von Seb recyclen
    3666              : 
    3667              :                                                                         // loop über assosciated faces des vertex am besten
    3668              :                                                                         // vermutlich auch noch assosciated edges, um
    3669              :                                                                         // zu markieren, welche weg fallen sollen, wenn
    3670              :                                                                         // nicht von Kluft selber, sondern quasi verschoben
    3671              :                                                                         // und neu erzeugt
    3672              : 
    3673              :                                                                         int dbg_FaceIterator = 0;
    3674              : 
    3675              : #if 0
    3676              : //                                                                      for( auto iterFac = grid.associated_faces_begin(*iterV); iterFac != grid.associated_faces_end(*iterV); iterFac++ )
    3677              :                                                                         for( std::vector<Face *>::iterator iterFac = grid.associated_faces_begin(*iterV); iterFac != grid.associated_faces_end(*iterV); iterFac++ )
    3678              :                                                                         {
    3679              :                                                                                 bool isFromFrac = false;
    3680              : 
    3681              : //                                                                              for( std::vector<Face *>::iterator iterF2 = attFac.begin(); iterF2 != attFac.end(); iterF2++ )
    3682              : //                                                                              {
    3683              : //                                                                                      // DEBUG ASSERT TEST static_assert( std::is_same< decltype( *iterF2 ), decltype ( *iterFac ) >::value );
    3684              : //
    3685              : //                                                                              }
    3686              : 
    3687              :                                                                                 int dbg_innterFacFracIt = 0;
    3688              : 
    3689              :                                                                                 for( auto const & facFrac : attFac )
    3690              :                                                                                 {
    3691              : 
    3692              : 
    3693              : //                                                                                      UG_LOG("type iter facFrac " << typeid( facFrac ).name() << std::endl);
    3694              : //
    3695              : //                                                                                      UG_LOG("type iter Fac " << typeid( *iterFac ).name() << std::endl);
    3696              : 
    3697              :                                                                                         // DEBUG ASSERT TEST static_assert( std::is_same<  decltype( const_cast<Face* & >(facFrac) ), decltype ( *iterFac ) >::value );
    3698              : 
    3699              : 
    3700              : 
    3701              : 
    3702              :                                                                                         if( *iterFac == facFrac )
    3703              :                                                                                         {
    3704              :                                                                                                 isFromFrac = true;
    3705              : 
    3706              :                                                                                                 // DEBUG ASSERT TEST static_assert( std::is_same< decltype( const_cast<Face* & >(facFrac) ), Face * & >::value  );
    3707              :                                                                                                 // DEBUG ASSERT TEST static_assert( std::is_same< decltype( const_cast<Face* & >(facFrac) ), decltype( * iterFac ) >::value  );
    3708              : 
    3709              :                                                                                         }
    3710              :                                                                                 }
    3711              : 
    3712              :                                                                                 bool atRightSide = false;
    3713              : 
    3714              :                                                                                 if( isFromFrac )
    3715              :                                                                                         atRightSide = true;
    3716              : 
    3717              :                                                                                 if( !isFromFrac )
    3718              :                                                                                 {
    3719              :                                                                                         // check if on same side of edge where the normal points to: compute cosinus between vector of face center
    3720              :                                                                                         //  perpendicular to the edge
    3721              :                                                                                         // TODO FIXME
    3722              :                                                                                         // KAESE!!!
    3723              : 
    3724              :                                                                                         vector3 facCenter = CalculateCenter( *iterFac, aaPos );
    3725              : 
    3726              :                                                                                         vector3 perpendicu;
    3727              : 
    3728              :                                                                                         if( nextFracVrt.size() != 2 )
    3729              :                                                                                         {
    3730              :                                                                                                 UG_THROW("komische Groesse" << std::endl);
    3731              :                                                                                         }
    3732              : 
    3733              :                                                                                         DropAPerpendicular(perpendicu, facCenter, aaPos[nextFracVrt[0]], aaPos[nextFracVrt[1]]);
    3734              : 
    3735              :                                                                                         vector3 tmpN;
    3736              : 
    3737              :                                                                                         VecSubtract(tmpN, facCenter, perpendicu );
    3738              : 
    3739              :                                                                                         VecNormalize(tmpN, tmpN);
    3740              : 
    3741              :                                                                                         UG_LOG("Normale zum Face ist " << tmpN << std::endl);
    3742              : 
    3743              :                                                                                         number cosBetwFracEdgAndDirection2Face = VecDot(tmpN, normSumNormed );
    3744              : 
    3745              :                                                                                         UG_LOG("Cosinus zur Normalen ist " << cosBetwFracEdgAndDirection2Face << std::endl);
    3746              : 
    3747              :                                                                                         if( cosBetwFracEdgAndDirection2Face > 0 )
    3748              :                                                                                         {
    3749              :                                                                                                 UG_LOG("assuming face to be on richt side" << std::endl);
    3750              : 
    3751              :                                                                                                 atRightSide = true;
    3752              : 
    3753              : #if ESTABLISH_DEBUG_SUDOS
    3754              : 
    3755              :                                                                                                 Vertex * otherFacCent = *grid.create<RegularVertex>();
    3756              :                                                                                                 aaPos[otherFacCent] = facCenter;
    3757              :                                                                                                 sh.assign_subset(otherFacCent, 5 );
    3758              : 
    3759              :                                                                                                 Vertex * pp = *grid.create<RegularVertex>();
    3760              :                                                                                                 aaPos[pp] = perpendicu;
    3761              :                                                                                                 sh.assign_subset(pp, 6 );
    3762              : 
    3763              :                                                                                                 sh.assign_subset(*iterFac,7);
    3764              : #endif
    3765              : 
    3766              :                                                                                         }
    3767              :                                                                                         else
    3768              :                                                                                         {
    3769              :                                                                                                 UG_LOG("assuming face to be on wrong side" << std::endl);
    3770              :                                                                                         }
    3771              : 
    3772              : //                                                                                      if( dbg_flachen_passiert == 0 )
    3773              : //                                                                                      {
    3774              : //                                                                                              UG_LOG("passiert " << dbg_flachen_passiert << std::endl);
    3775              : //
    3776              : //                                                                                              Vertex * otherFacCent = *grid.create<RegularVertex>();
    3777              : //                                                                                              aaPos[otherFacCent] = facCenter;
    3778              : //                                                                                              sh.assign_subset(otherFacCent, 5 );
    3779              : //
    3780              : //                                                                                              Vertex * pp = *grid.create<RegularVertex>();
    3781              : //                                                                                              aaPos[pp] = perpendicu;
    3782              : //                                                                                              sh.assign_subset(pp, 6 );
    3783              : //
    3784              : //                                                                                              sh.assign_subset(*iterFac,7);
    3785              : //
    3786              : //
    3787              : //                                                                                              sh.assign_subset(*iterFac,3);
    3788              : //
    3789              : //                                                                                              UG_LOG("is from frac " << isFromFrac << std::endl);
    3790              : //
    3791              : //                                                                                              return true;
    3792              : //                                                                                      }
    3793              : 
    3794              : 
    3795              :                                                                                         dbg_flachen_passiert++;
    3796              :                                                                                 }
    3797              : 
    3798              : 
    3799              :                                                                                 if( atRightSide ) // atRightSide ) NOCH FALSCH TODO FIXME muss nur auf richtiger Seite sein
    3800              :                                                                                 {
    3801              : 
    3802              : 
    3803              :                                                                                         // ACHTUNG neue Variable Face klein geschrieben im Gegensatz zu Prof. Reiter! nicht später falsche verwenden!
    3804              :                                                                                         vector<Vertex*>& newVrts4Fac = aaVrtVecFace[ * iterFac ];
    3805              : 
    3806              :                                                                                         IndexType vrtxFnd = 0;
    3807              : 
    3808              :                                                                                         for(size_t indVrt = 0; indVrt < (*iterFac)->num_vertices();  indVrt++ )
    3809              :                                                                                         {
    3810              :                                                                                                 Vertex* facVrt = (*iterFac)->vertex(indVrt);
    3811              : 
    3812              :                                                                                                 if(  facVrt == *iterV )
    3813              :                                                                                                 {
    3814              :                                                                                                         newVrts4Fac[ indVrt ] = newShiftVrtx;
    3815              :         //                                                                                                      UG_LOG("vertex found " <<  indVrt << std::endl );
    3816              :                                                                                                         vrtxFnd++;
    3817              :                                                                                                 }
    3818              :                                                                                         }
    3819              : 
    3820              : 
    3821              :                                                                                         if( vrtxFnd <= 0 )
    3822              :                                                                                         {
    3823              :                                                                                                 UG_THROW("vertex not found!" << std::endl);
    3824              :                                                                                         }
    3825              :                                                                                         else if( vrtxFnd > 1 )
    3826              :                                                                                         {
    3827              :                                                                                                 UG_THROW("vertex zu oft gefunden " << vrtxFnd << std::endl );
    3828              :                                                                                         }
    3829              :                                                                                         else if ( vrtxFnd == 1 )
    3830              :                                                                                         {
    3831              :         //                                                                                              UG_LOG("vertex found abgeschlossen" << std::endl);
    3832              :                                                                                         }
    3833              :                                                                                         else
    3834              :                                                                                         {
    3835              :                                                                                                 UG_THROW("vertex finden komisch " << std::endl);
    3836              :                                                                                         }
    3837              : 
    3838              : 
    3839              :                                                                                 }
    3840              : 
    3841              :                                                                                 dbg_innterFacFracIt++;
    3842              : 
    3843              : 
    3844              : 
    3845              : //
    3846              : //
    3847              : //                                                                              if( ! isFromFrac )
    3848              : //                                                                              {
    3849              : //                                                                                      // Vektor zum Zentrum von KNoten aus berechnen und Winkel zur Normalen bestimmen zur Unterscheidung der Seite
    3850              : //                                                                                      // wenn auf richtiger Seite, zuweisen
    3851              : //                                                                              }
    3852              : 
    3853              :                                                                                 dbg_FaceIterator++;
    3854              : 
    3855              :                                                                         }
    3856              : #else
    3857              : //                                                                      std::vector<Face* > & assFaceVrt = aaVrtInfoAssoFaces[*iterV];
    3858              : 
    3859              :                                                                         //                                                                      VecFace & assoFaces = aaVrtInfoAssoFaces[*iterV];
    3860              :                                                                                                                                                 // TODO FIXME hier braucht man das nicht zu ordnen
    3861              :                                                                                                                                                 // aber bei Kreuzpunkten von Klueften muss es so geordnet werden, wie es nebeneinander liegt
    3862              :                                                                                                                                                 // bei den Edges gibt es auch die benachbarten, und die edges haben das attachment, ob sie Kluftedges sind
    3863              : 
    3864              :                                                                         //                                                                      for( auto const & ifac : assoFaces )
    3865              :                                                                         //                                                                      {
    3866              :                                                                         //                                                                              // DEBUG ASSERT TEST static_assert( std::is_same< decltype( ifac ), Face * const & >::value );
    3867              :                                                                         //
    3868              :                                                                         //                                                                              // TODO FIXME folgenden loop durch diesen ersetzen
    3869              :                                                                         //                                                                              // Achtung: Zeigerproblematik, Referenzen, etc.....
    3870              :                                                                         //                                                                              // *iterFac ersetzen durch ifac vermutlich, aber wer weiss
    3871              :                                                                         //                                                                      }
    3872              : 
    3873              : 
    3874              :                                                                         //                                                                      for( auto iterFac = grid.associated_faces_begin(*iterV); iterFac != grid.associated_faces_end(*iterV); iterFac++ )
    3875              :                                                                         //for( std::vector<Face *>::iterator iterFac = grid.associated_faces_begin(*iterV); iterFac != grid.associated_faces_end(*iterV); iterFac++ )
    3876              :                                                                         for( auto const & ifac : assoFaces )
    3877              :                                                                         {
    3878              :                                                                                 bool isFromFrac = false;
    3879              : 
    3880              : 
    3881              :                                                                                 int dbg_innterFacFracIt = 0;
    3882              : 
    3883              :                                                                                 for( auto const & facFrac : attFac )
    3884              :                                                                                 {
    3885              : 
    3886              : //                                                                                      // DEBUG ASSERT TEST static_assert( std::is_same<  decltype( const_cast<Face* & >(facFrac) ), decltype ( ifac ) >::value );
    3887              :                                                                                         // DEBUG ASSERT TEST static_assert( std::is_same<  decltype( (facFrac) ), decltype ( ifac ) >::value );
    3888              : 
    3889              :                                                                                         if( ifac == facFrac )
    3890              :                                                                                         {
    3891              :                                                                                                 isFromFrac = true;
    3892              : 
    3893              : //                                                                                              // DEBUG ASSERT TEST static_assert( std::is_same< decltype( const_cast<Face* & >(facFrac) ), Face * & >::value  );
    3894              :                                                                                                 // DEBUG ASSERT TEST static_assert( std::is_same< decltype( (facFrac) ), Face * const & >::value  );
    3895              : //                                                                                              // DEBUG ASSERT TEST static_assert( std::is_same< decltype( const_cast<Face* & >(facFrac) ), decltype( ifac ) >::value  );
    3896              :                                                                                                 // DEBUG ASSERT TEST static_assert( std::is_same< decltype( (facFrac) ), decltype( ifac ) >::value  );
    3897              : 
    3898              :                                                                                         }
    3899              :                                                                                 }
    3900              : 
    3901              :                                                                                 bool atRightSide = false;
    3902              : 
    3903              :                                                                                 if( isFromFrac )
    3904              :                                                                                         atRightSide = true;
    3905              : 
    3906              :                                                                                 if( !isFromFrac )
    3907              :                                                                                 {
    3908              :                                                                                         // check if on same side of edge where the normal points to: compute cosinus between vector of face center
    3909              :                                                                                         //  perpendicular to the edge
    3910              : 
    3911              :                                                                                         vector3 facCenter = CalculateCenter( ifac, aaPos );
    3912              : 
    3913              :                                                                                         vector3 perpendicu;
    3914              : 
    3915              :                                                                                         if( nextFracVrt.size() != 2 )
    3916              :                                                                                         {
    3917              :                                                                                                 UG_THROW("komische Groesse" << std::endl);
    3918              :                                                                                         }
    3919              : 
    3920              :                                                                                         DropAPerpendicular(perpendicu, facCenter, aaPos[nextFracVrt[0]], aaPos[nextFracVrt[1]]);
    3921              : 
    3922              :                                                                                         vector3 tmpN;
    3923              : 
    3924              :                                                                                         VecSubtract(tmpN, facCenter, perpendicu );
    3925              : 
    3926              :                                                                                         VecNormalize(tmpN, tmpN);
    3927              : 
    3928              :                                                                                         UG_LOG("Normale zum Face ist " << tmpN << std::endl);
    3929              : 
    3930              :                                                                                         number cosBetwFracEdgAndDirection2Face = VecDot(tmpN, normSumNormed );
    3931              : 
    3932              :                                                                                         UG_LOG("Cosinus zur Normalen ist " << cosBetwFracEdgAndDirection2Face << std::endl);
    3933              : 
    3934              :                                                                                         if( cosBetwFracEdgAndDirection2Face > 0 )
    3935              :                                                                                         {
    3936              :                                                                                                 UG_LOG("assuming face to be on richt side" << std::endl);
    3937              : 
    3938              :                                                                                                 atRightSide = true;
    3939              : 
    3940              : #if ESTABLISH_DEBUG_SUDOS
    3941              : 
    3942              :                                                                                                 Vertex * otherFacCent = *grid.create<RegularVertex>();
    3943              :                                                                                                 aaPos[otherFacCent] = facCenter;
    3944              :                                                                                                 sh.assign_subset(otherFacCent, 5 );
    3945              : 
    3946              :                                                                                                 Vertex * pp = *grid.create<RegularVertex>();
    3947              :                                                                                                 aaPos[pp] = perpendicu;
    3948              :                                                                                                 sh.assign_subset(pp, 6 );
    3949              : 
    3950              :                                                                                                 sh.assign_subset(*iterFac,7);
    3951              : #endif
    3952              : 
    3953              :                                                                                         }
    3954              :                                                                                         else
    3955              :                                                                                         {
    3956              :                                                                                                 UG_LOG("assuming face to be on wrong side" << std::endl);
    3957              :                                                                                         }
    3958              : 
    3959              : 
    3960              :                                                                                         dbg_flachen_passiert++;
    3961              :                                                                                 }
    3962              : 
    3963              : 
    3964              :                                                                                 if( atRightSide ) // atRightSide ) NOCH FALSCH TODO FIXME muss nur auf richtiger Seite sein
    3965              :                                                                                 {
    3966              : 
    3967              :                                                                                         // ACHTUNG neue Variable Face klein geschrieben im Gegensatz zu Prof. Reiter! nicht später falsche verwenden!
    3968              :                                                                                         vector<Vertex*>& newVrts4Fac = aaVrtVecFace[ ifac ];
    3969              : 
    3970              :                                                                                         IndexType vrtxFnd = 0;
    3971              : 
    3972              :                                                                                         for(size_t indVrt = 0; indVrt < (ifac)->num_vertices();  indVrt++ )
    3973              :                                                                                         {
    3974              :                                                                                                 Vertex* facVrt = (ifac)->vertex(indVrt);
    3975              : 
    3976              :                                                                                                 if(  facVrt == *iterV )
    3977              :                                                                                                 {
    3978              :                                                                                                         newVrts4Fac[ indVrt ] = newShiftVrtx;
    3979              :                                                                                                         vrtxFnd++;
    3980              :                                                                                                 }
    3981              :                                                                                         }
    3982              : 
    3983              : 
    3984              :                                                                                         if( vrtxFnd <= 0 )
    3985              :                                                                                         {
    3986              :                                                                                                 UG_THROW("vertex not found!" << std::endl);
    3987              :                                                                                                                                                                 }
    3988              :                                                                                         else if( vrtxFnd > 1 )
    3989              :                                                                                         {
    3990              :                                                                                                 UG_THROW("vertex zu oft gefunden " << vrtxFnd << std::endl );
    3991              :                                                                                         }
    3992              :                                                                                         else if ( vrtxFnd == 1 )
    3993              :                                                                                         {
    3994              :                                                                                         }
    3995              :                                                                                         else
    3996              :                                                                                         {
    3997              :                                                                                                 UG_THROW("vertex finden komisch " << std::endl);
    3998              :                                                                                         }
    3999              : 
    4000              : 
    4001              :                                                                                 }
    4002              : 
    4003              :                                                                                 dbg_innterFacFracIt++;
    4004              : 
    4005              : 
    4006              : 
    4007              :                                                                                 dbg_FaceIterator++;
    4008              : 
    4009              :                                                                         }
    4010              : 
    4011              : #endif
    4012              : 
    4013              : #endif
    4014              : 
    4015              :                                                                 }
    4016              :                                                                 else
    4017              :                                                                 {
    4018              :                                                                         // andere Seite vermutet, nichts tun!
    4019              :                                                                 }
    4020              : 
    4021              : 
    4022              :                                                         }
    4023              : 
    4024              : 
    4025              :                                                 }
    4026              : 
    4027              :                                                 dbg_zweiterIteratorAblaufen++;
    4028              : 
    4029              :                                         }
    4030              : 
    4031              :                                         dbg_iteratorAblaufen++;
    4032              : 
    4033              :                                 }
    4034              : 
    4035              : 
    4036              : //                              // Ziel: die beiden parallelen Normalen mitteln, und in die jeweiligen beiden Richtungen je einen neuen Vertex erzeugen
    4037              : //                              // irgendwie muss der Vertex oder die Edge besser sogar wissen, dass sie einen neuen Verschiebevertex bekommen hat
    4038              : //                              // denn später müssen neue Edges und neue Faces basierend auf den neuen Vertizes erzeugt werden
    4039              : //                              // vielleicht braucht die edge und das face ein Attachment, das ihnen das sagt, ähnlihc wie VertexTrible std Vektoren?
    4040              : //
    4041              : //
    4042              : //
    4043              : 
    4044              : 
    4045              :                                 UG_LOG("END THIS VERTEX NORMAL COSINE" << std::endl);
    4046              : 
    4047              : 
    4048              : 
    4049              :                         }
    4050              : //                      else // two fractures completely crossing, numFracsCrossAtVrt >= 3, i.e. T crossing and two fractures completely crossing
    4051              :                         else // two fractures completely crossing, numFracsCrossAtVrt >= 2, i.e. durchgehend, T crossing and two fractures completely crossing
    4052              :                         {
    4053              : 
    4054              : 
    4055            0 :                                 CrossVertInf crossVrtInf( *iterV, numFracsCrossAtVrt );
    4056              :                                 VecVertexOfFaceInfo orderedFaces;
    4057              :                                 SegmentsFractExtrus segments;
    4058              : //                              VecVertexOfFaceInfo segmentPart;
    4059              : 
    4060              :                                 // note: we do not attach this info to the vertex, as we only need it local; in principle, in case of further need, it would
    4061              :                                 // be usful to establish some sort of attachment
    4062              : 
    4063              :                                 IndexType startIndex = 0;
    4064              : 
    4065            0 :                                 determineOrderOfFaces(
    4066              :                                                 vecVertFracTrip, assoFaces,  orderedFaces,
    4067              :                                                 segments, //segmentPart,
    4068              :                                                 startIndex, allAssoEdges,
    4069              :                                                 sh, aaMarkEdgeB
    4070              :                                 );
    4071              : 
    4072              : //                              CrossingVertexInfo<Vertex*, IndexType> crossVrtInf( *iterV, numFracsCrossAtVrt );
    4073              : 
    4074              :                                 UG_LOG("number fracs " << numFracsCrossAtVrt << std::endl);
    4075              : 
    4076              : 
    4077              :                                 UG_LOG("Nummer vorbei " << std::endl);
    4078              : 
    4079              : //                              for( auto const & aae : allAssoEdges )
    4080              : //                              {
    4081              : //                                      crossVrtInf.addOriginalFracEdge( aae );
    4082              : //                              }
    4083              : 
    4084              : //                              crossVrtInf.setOriginalFracEdge(allAssoEdges);
    4085              : 
    4086              :                                 //  in case of three fractures, we have to use the method for eine durchgehende fracture
    4087              :                                 // auf der Seite, wo die zweite fracture NICHT rein geht
    4088              : 
    4089              :                                 //  kreuzende Fractures im Innenraum -> Arte in Reinform implementieren
    4090              : 
    4091              :                                 // verkettete Liste der anhängenden fractures in Reihenfolge
    4092              :                                 // der Anhängung mit INfo, ob eine Kluft vorliegt
    4093              : 
    4094              : //                              for( auto const & attVFT : vecVertFracTrip )
    4095              : //                              {
    4096              : //                                      Edge * edg = attVFT.getEdge();
    4097              : //                                      Face * fac = attVFT.getFace();
    4098              : //                                      vector3 nv = attVFT.getNormal();
    4099              : //                              }
    4100              : 
    4101              : //                              // hier werden  ALLE attached Faces benötigt, auch die, die zwischen den direkt an den fractures liegenden Faces sind
    4102              : //
    4103              :                                 // copies of all faces and of fractured ones
    4104              : //                              auto vVFT = vecVertFracTrip; // caution: COPY, not reference!
    4105              : //                              auto aF = assoFaces; // caution: COPY, not reference!
    4106              : 
    4107              : //                              UG_LOG("Gesamtanzahl faces um Knoten " <<  aF.size() << std::endl );
    4108              : 
    4109              :                                 //  erstmal die ganzen anhaengenden Faces ordnen, dass wir wissen, in welcher Reihenfolge wir durchlaufen muessen
    4110              :                                 // jede Edge hat ein bool attachment schon, das weiss, ob sie Fracture edge ist oder nicht
    4111              :                                 // Reihenfolge der faces und die edges auch dazu, vielleicht neues Triple oder dergleiche, dabei zwei edges und zwei normals
    4112              :                                 // und wie gesagt, die edges wissen, ob sie fractures sind, dazu keine neuen Variablen notwendig
    4113              : 
    4114              : //                              using VertexOfFaceInfo = VertexFractureTriple< std::pair<Edge*, Edge*>, Face*, std::pair<vector3,vector3> >;
    4115              : //                              // all edges of the attached face - must always be two, the face itself, and the normal vectors of the face in direction of the two edges
    4116              : //                              // the size of the normal vector vector also must be two
    4117              : //                              // however, if an edge of the face is not a fracture edge, we do not compute the normal, but assign zero as norm
    4118              : //                              // for those edges and faces which are Kluft edges, we assign the normal known from the info computed before, vertex fracture triple
    4119              : //
    4120              : #if 0
    4121              :                                 CrossVertInf crossVrtInf( *iterV, numFracsCrossAtVrt );
    4122              : 
    4123              :                                 //                              using VecVertexOfFaceInfo = std::vector<VertexOfFaceInfo>;
    4124              : 
    4125              :                                 VecVertexOfFaceInfo orderedFaces;
    4126              : 
    4127              : //                              using SegmentsFractExtrus = std::vector<VecVertexOfFaceInfo>;
    4128              : 
    4129              :                                 SegmentsFractExtrus segments;
    4130              :                                 // single components always from one fracture edge to the next one
    4131              : 
    4132              :                                 VecVertexOfFaceInfo segmentPart;
    4133              : 
    4134              :                                 // note: we do not attach this info to the vertex, as we only need it local; in principle, in case of further need, it would
    4135              :                                 // be usful to establish some sort of attachment
    4136              : 
    4137              :                                 // fixed diesen Sortierungsalgorithmus bei allen inneren Knoten anwenden,
    4138              :                                 // um zweifelsfrei alle anhängenden Faces der richtigen Seite zuordnen zu können!!!!
    4139              : 
    4140              :                                 // VecVertFracTrip & vecVertFracTrip = aaVrtInfoFraTri[*iterV];
    4141              :                                 // VecFace & assoFaces = aaVrtInfoAssoFaces[*iterV];
    4142              : 
    4143              :                                 IndexType startIndex = 0;
    4144              : 
    4145              :                                 determineOrderOfFaces( crossVrtInf, vecVertFracTrip, assoFaces,  orderedFaces,
    4146              :                                                                                         segments, segmentPart, startIndex, allAssoEdges,
    4147              :                                                                                         sh, aaMarkEdgeB
    4148              :                                                                                 );
    4149              : #endif
    4150              : 
    4151              : #if 0
    4152              : 
    4153              :                                 IndexType countedCrossingFracEdgs = 0;
    4154              : 
    4155              :                                 if( vVFT.size() == 0 )
    4156              :                                         UG_THROW("vertex frac triple zu klein an Kreuzung " << std::endl);
    4157              : 
    4158              :                                 // we start with the first fracture face edge stuff, copy it,  and delete this immidiately
    4159              :                                 VertFracTrip startVertFracTrip = vVFT[0];
    4160              : 
    4161              :                                 vVFT.erase(vVFT.begin());
    4162              : 
    4163              :                                 bool atFirstTriple = true;
    4164              : 
    4165              :                                 Face* fracFac = startVertFracTrip.getFace();
    4166              :                                 Edge* fracEdg = startVertFracTrip.getEdge();
    4167              :                                 vector3 fracNorm = startVertFracTrip.getNormal();
    4168              : 
    4169              :                                 Edge* originalStartEdge = startVertFracTrip.getEdge();
    4170              : 
    4171              :                                 if( fracEdg != 0 )
    4172              :                                 {
    4173              :                                         countedCrossingFracEdgs++;
    4174              :                                 }
    4175              : 
    4176              :                                 // do not change this pointer
    4177              :                                 Edge* startEdg = fracEdg;
    4178              :                                 Face* startFace = fracFac;
    4179              : 
    4180              :                                 vector3 startNormal = fracNorm;
    4181              : 
    4182              :                                 Face* nextFace = NULL;
    4183              : 
    4184              :                                 UG_LOG("Gesamtanzahl faces um Knoten vor while " <<  aF.size() << std::endl );
    4185              : 
    4186              :                                 while( aF.size() != 0 )
    4187              :                                 {
    4188              : 
    4189              :                                         UG_LOG("Gesamtanzahl faces um Knoten Anfang while " <<  aF.size() << std::endl );
    4190              : 
    4191              : 
    4192              :                                         Face* face2Append = startFace;
    4193              :                                         Edge* startEdg2Append = startEdg;
    4194              : 
    4195              : 
    4196              :                                         IndexType fndCommEdg = 0;
    4197              :                                         vector3 nuVe(0,0,0);
    4198              : 
    4199              :                                         Edge* nextEdge = NULL;
    4200              : 
    4201              :                                         std::pair<Edge*, Edge *> edge2Append( startEdg2Append, nextEdge );
    4202              :                                         std::pair<vector3, vector3 > normal2Append( startNormal, nuVe );
    4203              : 
    4204              : 
    4205              :                                         // if start face and start edge from a triple, then has to be erased this triple, exept for the entire start, as already erased
    4206              :                                         if( ! atFirstTriple )
    4207              :                                         {
    4208              :                                                 for( VecVertFracTrip::iterator itAttVFT = vVFT.begin(); itAttVFT !=  vVFT.end(); itAttVFT++ )
    4209              :                                                 {
    4210              :                                                         auto vft = *itAttVFT;
    4211              : 
    4212              :                                                         Edge * edgIt = vft.getEdge();
    4213              : 
    4214              :                                                         Face * facIt = vft.getFace();
    4215              : 
    4216              :                                                         if( edgIt == startEdg && facIt == startFace )
    4217              :                                                         {
    4218              :                                                                 // the first edge if from a fracture and the face is connected to it
    4219              : 
    4220              :                                                                 vVFT.erase(itAttVFT);
    4221              : 
    4222              :                                                                 normal2Append.first = vft.getNormal();
    4223              : 
    4224              :                                                                 if( ! FaceContains( facIt, startEdg ))
    4225              :                                                                 {
    4226              :                                                                         UG_THROW("Face does not contain start edge of its edge" << std::endl);
    4227              :                                                                 }
    4228              : 
    4229              :                                                                 break;
    4230              :                                                         }
    4231              :                                                 }
    4232              : 
    4233              :                                         }
    4234              :                                         else // we can save the investigation if we have a triple, and we do not need to erase, as already erased.....
    4235              :                                         {
    4236              :                                                 atFirstTriple = false;
    4237              :                                         }
    4238              : 
    4239              : 
    4240              :                                         for( auto const & iE : allAssoEdges ) // werden nicht gelöscht, deswegen Zugriff auf attachment direkt
    4241              :                                         {
    4242              :                                                 if( FaceContains(face2Append, iE) )
    4243              :                                                 {
    4244              :                                                         fndCommEdg++;
    4245              : 
    4246              :                                                         if( iE != startEdg )
    4247              :                                                         {
    4248              :                                                                 nextEdge = iE;
    4249              : 
    4250              :                                                                 edge2Append.second = iE;
    4251              : 
    4252              :                                                         }
    4253              :                                                 }
    4254              : 
    4255              : 
    4256              :                                         }
    4257              : 
    4258              :                                         if( fndCommEdg != 2 )
    4259              :                                         {
    4260              :                                                 UG_THROW("komische Anzahl gemeinsamer Ecke " << fndCommEdg << std::endl);
    4261              :                                         }
    4262              : 
    4263              :                                         if( nextEdge == NULL )
    4264              :                                         {
    4265              :                                                 UG_THROW("wieso keine zweite Ecke gefunden???? " << std::endl);
    4266              :                                         }
    4267              : 
    4268              :                                                 if( edge2Append.first == NULL || edge2Append.second == NULL )
    4269              :                                         {
    4270              :                                                 UG_THROW("null immer noch?" << std::endl);
    4271              :                                         }
    4272              : 
    4273              :                                         // erase the face from the list
    4274              : 
    4275              :                                         IndexType faceFound = 0;
    4276              : 
    4277              :                                         for( std::vector<Face*>::iterator itFac = aF.begin(); itFac != aF.end(); itFac++ )
    4278              :                                         {
    4279              :                                                 Face * iFa = *itFac;
    4280              : 
    4281              :                                                 if( iFa == startFace &&  FaceContains( iFa, nextEdge ) && FaceContains(iFa, startEdg))
    4282              :                                                 {
    4283              :                                                         faceFound++;
    4284              :                                                 }
    4285              :                                         }
    4286              : 
    4287              :                                         int totalSubsNum = sh.num_subsets();
    4288              : 
    4289              :                                         int newSubsToAdd = totalSubsNum;
    4290              : 
    4291              :                                         if( faceFound != 1 )
    4292              :                                         {
    4293              : 
    4294              : 
    4295              :                                                 sh.assign_subset(startFace,newSubsToAdd++);
    4296              :                                                 sh.assign_subset(startEdg,newSubsToAdd++);
    4297              :                                                 sh.assign_subset(nextEdge,newSubsToAdd++);
    4298              : 
    4299              :                                                 int faNum = aF.size();
    4300              : 
    4301              :                                                 UG_LOG("Gesamtzahl faces vor Absturz " << faNum << std::endl);
    4302              : 
    4303              :                                                 UG_LOG("Gesicht in falscher Anztahl gefunden " << faceFound << std::endl);
    4304              : 
    4305              : //                                              return true;
    4306              : 
    4307              : 
    4308              : 
    4309              :                                                 UG_THROW("Gesicht in falscher Anztahl gefunden " << faceFound << std::endl);
    4310              :                                         }
    4311              :                                         else
    4312              :                                         {
    4313              : //                                              sh.assign_subset(startFace,newSubsToAdd++);
    4314              : //                                              sh.assign_subset(startEdg,newSubsToAdd++);
    4315              : //                                              sh.assign_subset(nextEdge,newSubsToAdd++);
    4316              : 
    4317              :                                                 int faNum = aF.size();
    4318              : 
    4319              :                                                 UG_LOG("Gesamtzahl faces ohne Absturz " << faNum << std::endl);
    4320              : 
    4321              :                                         }
    4322              : 
    4323              :                                         for( std::vector<Face*>::iterator itFac = aF.begin(); itFac != aF.end(); itFac++ )
    4324              :                                         {
    4325              :                                                 Face * iFa = *itFac;
    4326              : 
    4327              :                                                 if( iFa == startFace && FaceContains( iFa, nextEdge ) && FaceContains(iFa, startEdg) )
    4328              :                                                 {
    4329              :                                                         aF.erase(itFac);
    4330              :                                                         break;
    4331              :                                                 }
    4332              :                                         }
    4333              : 
    4334              : 
    4335              : 
    4336              : 
    4337              :                                         bool sndEdgIsFracEdgeAlso = aaMarkEdgeB[nextEdge];
    4338              : 
    4339              :                                         bool tripFound = false;
    4340              : 
    4341              :                                         if( sndEdgIsFracEdgeAlso )
    4342              :                                         {
    4343              : 
    4344              :                                                 if( nextEdge != originalStartEdge )
    4345              :                                                         countedCrossingFracEdgs++;
    4346              : 
    4347              :                                                 // we need to have a look for the next triple
    4348              : 
    4349              :                                                 // check if the next normal is a frac normal which contains the face as well
    4350              : 
    4351              :                                                 for( VecVertFracTrip::iterator itAttVFT = vVFT.begin(); itAttVFT !=  vVFT.end(); itAttVFT++ )
    4352              :                                                 {
    4353              :                                                         auto vft = *itAttVFT;
    4354              : 
    4355              :                                                         Edge * edgIt = vft.getEdge();
    4356              : 
    4357              :                                                         Face * facIt = vft.getFace();
    4358              : 
    4359              :                                                         if( edgIt == nextEdge && facIt == face2Append )
    4360              :                                                         {
    4361              :                                                                 // the second edge if from a fracture and the face is connected to it
    4362              : 
    4363              :                                                                 tripFound = true;
    4364              : 
    4365              :                                                                 vVFT.erase(itAttVFT);
    4366              : 
    4367              :                                                                 normal2Append.second = vft.getNormal();
    4368              : 
    4369              :                                                                 if( ! FaceContains( facIt, nextEdge ))
    4370              :                                                                 {
    4371              :                                                                         UG_THROW("Face does not contain edge of its edge" << std::endl);
    4372              :                                                                 }
    4373              : 
    4374              :                                                                 break;
    4375              :                                                         }
    4376              :                                                 }
    4377              : 
    4378              :                                         }
    4379              : 
    4380              :                                         if( ! tripFound && sndEdgIsFracEdgeAlso )
    4381              :                                         {
    4382              :                                                 UG_THROW("Triple nicht gefunden trotz markierter Edge" << std::endl);
    4383              :                                         }
    4384              : 
    4385              : 
    4386              :                                         // check if aF or vVFT still contain the former or the next face - must not be the case!
    4387              : 
    4388              :                                         VertexOfFaceInfo vOFI( edge2Append, face2Append, normal2Append );
    4389              : 
    4390              :                                         orderedFaces.push_back( vOFI );
    4391              : 
    4392              :                                         segmentPart.push_back( vOFI );
    4393              : 
    4394              :                                         if( sndEdgIsFracEdgeAlso )
    4395              :                                         {
    4396              :                                                 segments.push_back( segmentPart );
    4397              : 
    4398              :                                                 segmentPart.clear();
    4399              :                                         }
    4400              : 
    4401              : 
    4402              :                                         // what is next face, what is next edge?
    4403              :                                         // wie kriegen wir es hin, auch das nächste Triple zu erasen, wenn es jetzt kommt als nächstes?
    4404              : 
    4405              : 
    4406              :                                         startNormal = nuVe;
    4407              :                                         startEdg = nextEdge;
    4408              : 
    4409              :                                         if( aF.size() == 0 )
    4410              :                                         {
    4411              :                                                 if( nextEdge != originalStartEdge )
    4412              :                                                 {
    4413              :                                                         UG_THROW("Gesichter leer, aber keine Anfangsecke gefunden" << std::endl);
    4414              :                                                 }
    4415              :                                                 else
    4416              :                                                 {
    4417              :                                                         break; // while loop zu Ende, raus aus dem while loop, den Rest nicht mehr machen, würde schief gehen zwingendermassen
    4418              :                                                 }
    4419              : 
    4420              :                                         }
    4421              : 
    4422              : 
    4423              :                                         // bleibt noch das nächste Gesicht heraus zu finden, dafür kommt eigentlich nur noch eines in Frage, da das zweite Gesicht vom edge
    4424              :                                         // geloescht sein muss in aF, es muss das einzig übrige face sein, das die jetzt start edge enthält, davon darf es nur eines geben, wir löschen aber noch nicht
    4425              : 
    4426              :                                         IndexType nextFaceFound = 0;
    4427              : 
    4428              :                                         for( std::vector<Face*>::iterator itFac = aF.begin(); itFac != aF.end(); itFac++ )
    4429              :                                         {
    4430              :                                                 Face * iFa = *itFac;
    4431              : 
    4432              :                                                 if( FaceContains(iFa, startEdg ) )
    4433              :                                                 {
    4434              :                                                         nextFaceFound++;
    4435              :                                                 }
    4436              :                                         }
    4437              : 
    4438              :                                         if( nextFaceFound != 1 )
    4439              :                                         {
    4440              :                                                 UG_THROW("folgendes Gesicht in falscher Anztahl gefunden " << nextFaceFound << std::endl);
    4441              :                                         }
    4442              : 
    4443              :                                         for( std::vector<Face*>::iterator itFac = aF.begin(); itFac != aF.end(); itFac++ )
    4444              :                                         {
    4445              :                                                 Face * iFa = *itFac;
    4446              : 
    4447              :                                                 if( FaceContains(iFa, startEdg ) )
    4448              :                                                 {
    4449              :                                                         startFace = iFa;
    4450              :                                                         break;
    4451              :                                                 }
    4452              :                                         }
    4453              : 
    4454              : 
    4455              :                                 }
    4456              : 
    4457              :                                 if( vVFT.size() != 0 )
    4458              :                                 {
    4459              :                                         UG_THROW("not all triples found! " << std::endl);
    4460              :                                 }
    4461              : 
    4462              :                                 if( aF.size() != 0 )
    4463              :                                         UG_THROW("not all faces found " << std::endl);
    4464              : 
    4465              :                                 if( startEdg != originalStartEdge )
    4466              :                                 {
    4467              :                                         UG_THROW("wir sind nicht am Anfang wieder angekommen" << std::endl);
    4468              :                                 }
    4469              : 
    4470              : 
    4471              :                                 if( segmentPart.size() != 0 )
    4472              :                                 {
    4473              :                                         UG_THROW("die Segmentteile muessen alle verarbeitet sein"  << std::endl);
    4474              :                                 }
    4475              : 
    4476              :                                 UG_LOG("Kreislauf geschlossen" << std::endl);
    4477              : 
    4478              : #endif
    4479              : 
    4480              :                                 // test if the segments and their partition produce sumething useful, for debug purposes
    4481              : 
    4482              :                                 // als nächstes muss man die Klassen von durch Klüften abgetrennten ordered Faces durchgehen, und die Verschiebevertizes erzeugen
    4483              :                                 // als nächstes die verschiedenen Sektionen durch gehen, eventuell nochmal extra Objekte dafür erzeugen
    4484              :                                 // oder gleich beim Durchgehen die neuen Vertizes erzeugen, Startsignal durch ein Face mit erster Edge KLuft, und dann die nächste
    4485              :                                 // Kluftedge finden, egal ob vom gleihen face oder von einem späteren face im kreis
    4486              : 
    4487              :                                 // now figure out to which face this next edge belongs, and if this is a fracture edge, then we have the triple and the normal info
    4488              :                                 // else we let the normal zero
    4489              : 
    4490              :                                 // figure out if second edge is also frac edge, i.e. if it belongs to an edge  of the remaining vVFT elements
    4491              :                                 // first easily asking if it is marked as frac edge, simplifies research
    4492              : 
    4493              :                                 // in principle from here on need to loop through all triples and through all faces, find out some way to construct next edge and to
    4494              :                                 // build one element after the other of the ordered faces vector, still even the first element is not completed
    4495              : 
    4496              :                                 // TODO FIXME kreuzende Fractures im Innenraum -> Arte in Reinform implementieren
    4497              :                                 // later assign somehow next edge to start edge, or use new variable, when we have figured out next face
    4498              :                                 // at end, chech if we have arrived again at original first edge
    4499              : 
    4500              : 
    4501              :                                 int totalSubsNum = sh.num_subsets();
    4502              : 
    4503              : //                              int newSubsToAdd = totalSubsNum;
    4504              : 
    4505              : //                              for( VertexOfFaceInfo const & vertFracInfo : orderedFaces )
    4506              : //                              {
    4507              : ////                                    Face * fa = vertFracInfo.getFace();
    4508              : ////
    4509              : ////                                    sh.assign_subset(fa,newSubsToAdd++);
    4510              : //                              }
    4511              : 
    4512              :                                 number totAnglsEdg = 0;
    4513              :                                 number totAnglsNrm = 0;
    4514              : 
    4515            0 :                                 for( VecVertexOfFaceInfo const & segPart : segments )
    4516              :                                 {
    4517              : //                                      newSubsToAdd++;
    4518              : 
    4519            0 :                                         IndexType numbTriangs = segPart.size();
    4520              : 
    4521            0 :                                         if( numbAttTripl == 0 )
    4522              :                                         {
    4523            0 :                                                 UG_THROW("zu wenig Dreiecke " << std::endl);
    4524              :                                         }
    4525              : 
    4526              :                                         VertexOfFaceInfo const & vFISBegin = segPart[0];
    4527            0 :                                         VertexOfFaceInfo const & vFISEnd = segPart[numbTriangs-1];
    4528              : 
    4529              :                                         std::pair<Edge*, Edge* >  edgesBegin = vFISBegin.getEdge();
    4530              :                                         std::pair<Edge*, Edge* >  edgesEnd = vFISEnd.getEdge();
    4531              : 
    4532              :                                         std::pair<vector3, vector3> normalBegin = vFISBegin.getNormal();
    4533              :                                         std::pair<vector3, vector3> normalEnd = vFISEnd.getNormal();
    4534              : 
    4535            0 :                                         Edge* edgeFracOne = edgesBegin.first;
    4536            0 :                                         Edge* edgeFracTwo = edgesEnd.second;
    4537              : 
    4538            0 :                                         auto subsIndFracOne = sh.get_subset_index(edgeFracOne);
    4539              :                                         auto subsIndFracTwo = sh.get_subset_index(edgeFracTwo);
    4540              : 
    4541              :                                         vector3 normalFracOne = normalBegin.first;
    4542              :                                         vector3 normalFracTwo = normalEnd.second;
    4543              : 
    4544              : //                                      sh.assign_subset(edgeFracOne, newSubsToAdd);
    4545              : //
    4546              : //                                      if( edgeFracTwo != originalStartEdge )
    4547              : //                                              sh.assign_subset(edgeFracTwo, newSubsToAdd);
    4548              : 
    4549              :                                         // neue Punkte erzeugen
    4550              : 
    4551              :                                         number cosBetweenNormals = VecDot( normalFracOne, normalFracTwo );
    4552              : 
    4553              :                                         constexpr bool useOldMethodeNotAngleDep = false;
    4554              : 
    4555              :                                         if( useOldMethodeNotAngleDep )
    4556              :                                         {
    4557              : 
    4558              :                                                 if( subsIndFracOne == subsIndFracTwo )
    4559              :                                                 {
    4560              :         //                                              if( numFracsCrossAtVrt != 3 )
    4561              :                                                         if( numFracsCrossAtVrt != 2 && numFracsCrossAtVrt != 3 )
    4562              :                                                         {
    4563              :         //                                                      UG_THROW("Fracture Segment an beiden Seiten gleiche sudo, aber keine T Kreuzung?" << std::endl);
    4564              :                                                                 UG_THROW("Fracture Segment an beiden Seiten gleiche sudo, aber keine durchgehende Kluft?" << std::endl);
    4565              :                                                         }
    4566              : 
    4567              :                                                         // dieselben Methoden wie im Fall von einer durchgehenden Kluft an einem Vertex, dort kopieren
    4568              :                                                         // bzw Funktion schreiben, die beides macht
    4569              : 
    4570              :                                                         // hier wird der Fall abgezweigt, dass wir auf der durchgehenden Seite einer Kluft sind
    4571              :                                                         // wenn wir eine T-Kreuzung haben
    4572              : 
    4573              :                                                         std::vector<Vertex *> nextFracVrt;
    4574              : 
    4575              :                                                         IndexType foundThisVrtOne = 0;
    4576              : 
    4577              :                                                         for( size_t i = 0; i < 2; ++i )
    4578              :                                                         {
    4579              :                                                                 Vertex * vrtEdgEnd = edgeFracOne->vertex(i);
    4580              : 
    4581              :                                                                 if( vrtEdgEnd == *iterV )
    4582              :                                                                 {
    4583              :                                                                         foundThisVrtOne++;
    4584              :                                                                 }
    4585              :                                                                 else
    4586              :                                                                 {
    4587              :                                                                         nextFracVrt.push_back( vrtEdgEnd );
    4588              :                                                                 }
    4589              : 
    4590              :                                                         }
    4591              : 
    4592              :                                                         if( foundThisVrtOne != 1 )
    4593              :                                                         {
    4594              :                                                                 UG_THROW("zu viel zu wenig vertizex one " << std::endl);
    4595              :                                                         }
    4596              : 
    4597              : 
    4598              :                                                         IndexType foundThisVrtTwo = 0;
    4599              : 
    4600              :                                                         for( size_t i = 0; i < 2; ++i )
    4601              :                                                         {
    4602              :                                                                 Vertex * vrtEdgEnd = edgeFracTwo->vertex(i);
    4603              : 
    4604              :                                                                 if( vrtEdgEnd == *iterV )
    4605              :                                                                 {
    4606              :                                                                         foundThisVrtTwo++;
    4607              :                                                                 }
    4608              :                                                                 else
    4609              :                                                                 {
    4610              :                                                                         nextFracVrt.push_back( vrtEdgEnd );
    4611              :                                                                 }
    4612              : 
    4613              :                                                         }
    4614              : 
    4615              :                                                         if( foundThisVrtTwo != 1 )
    4616              :                                                         {
    4617              :                                                                 UG_THROW("zu viel zu wenig vertizex two " << std::endl);
    4618              :                                                         }
    4619              : 
    4620              :                                                         Face *  faceBegin = vFISBegin.getFace();
    4621              :                                                         Face *  faceEnd = vFISEnd.getFace();
    4622              : 
    4623              : 
    4624              :                                                         // TODO FIXME hier die Segmentinformation übergeben, da die Faces bekannt sind, die dran hängen!!!!!
    4625              :         //                                              expandSingleFractureAtGivenSide( normalFracTwo, normalFracTwo,
    4626              :         //                                                                                                               edgeFracOne, edgeFracTwo,
    4627              :         //                                                                                                               faceBegin, faceEnd,
    4628              :         //                                                                                                               fracInfosBySubset,
    4629              :         //                                                                                                               posOldVrt,
    4630              :         //                                                                                                               aaPos,
    4631              :         //                                                                                                               grid, sh,
    4632              :         //                                                                                                               assoFaces,
    4633              :         //                                                                                                               nextFracVrt,
    4634              :         //                                                                                                               aaVrtVecFace,
    4635              :         //                                                                                                               dbg_flachen_passiert,
    4636              :         //                                                                                                               *iterV,
    4637              :         //                                                                                                               crossVrtInf,
    4638              :         //                                                                                                               ( numFracsCrossAtVrt == 3 )
    4639              :         //                                                                                                              );
    4640              :                                                         expandSingleFractureAtGivenSide( normalFracOne, normalFracTwo,
    4641              :                                                                                                                          edgeFracOne, edgeFracTwo,
    4642              :                                                                                                                          faceBegin, faceEnd,
    4643              :                                                                                                                          fracInfosBySubset,
    4644              :                                                                                                                          posOldVrt,
    4645              :                                                                                                                          aaPos,
    4646              :                                                                                                                          grid, sh,
    4647              :                                                                                                                          segPart,
    4648              :                                                                                                                          nextFracVrt,
    4649              :                                                                                                                          aaVrtVecFace,
    4650              :                                                                                                                          dbg_flachen_passiert,
    4651              :                                                                                                                          *iterV,
    4652              :                                                                                                                          crossVrtInf,
    4653              :                                                                                                                          ( numFracsCrossAtVrt == 3 )
    4654              :                                                                                                                         );
    4655              : 
    4656              : 
    4657              : 
    4658              :                                                 }
    4659              :                                                 else
    4660              :                                                 {
    4661              : 
    4662              : //                                                      UG_THROW("in dieser Funktion alt" << std::endl);
    4663              : 
    4664              :                                                         // create normal vectors into direction of relevant edges
    4665              : 
    4666              :                                                         vector3 alongEdgeOne;
    4667              :                                                         vector3 alongEdgeTwo;
    4668              : 
    4669              :                                                         Vertex * vrtEdgeOneBegin = nullptr;
    4670              :                                                         Vertex * vrtEdgeTwoBegin = nullptr;
    4671              :                                                         Vertex * vrtEdgeOneEnd = nullptr;
    4672              :                                                         Vertex * vrtEdgeTwoEnd = nullptr;
    4673              : 
    4674              : 
    4675              :                                                         for( size_t i = 0; i < 2; ++i )
    4676              :                                                         {
    4677              :                                                                 Vertex * vrtFromEdgeOne = edgeFracOne->vertex(i);
    4678              :                                                                 Vertex * vrtFromEdgeTwo = edgeFracTwo->vertex(i);
    4679              : 
    4680              :                                                                 if( vrtFromEdgeOne == *iterV )
    4681              :                                                                 {
    4682              :                                                                         vrtEdgeOneBegin = vrtFromEdgeOne;
    4683              :                                                                 }
    4684              :                                                                 else
    4685              :                                                                 {
    4686              :                                                                         vrtEdgeOneEnd = vrtFromEdgeOne;
    4687              :                                                                 }
    4688              : 
    4689              :                                                                 if( vrtFromEdgeTwo == *iterV )
    4690              :                                                                 {
    4691              :                                                                         vrtEdgeTwoBegin = vrtFromEdgeTwo;
    4692              :                                                                 }
    4693              :                                                                 else
    4694              :                                                                 {
    4695              :                                                                         vrtEdgeTwoEnd = vrtFromEdgeTwo;
    4696              :                                                                 }
    4697              : 
    4698              :                                                         }
    4699              : 
    4700              :                                                         if( vrtEdgeOneBegin == nullptr || vrtEdgeTwoBegin == nullptr || vrtEdgeOneEnd == nullptr || vrtEdgeTwoEnd == nullptr )
    4701              :                                                         {
    4702              :                                                                 UG_THROW("lauter Nullen vertizes" << std::endl);
    4703              :                                                         }
    4704              : 
    4705              :                                                         vector3 fracVrtPos = aaPos[*iterV];
    4706              : 
    4707              :                                                         vector3 fracEdgOneEndPos = aaPos[ vrtEdgeOneEnd ];
    4708              :                                                         vector3 fracEdgTwoEndPos = aaPos[ vrtEdgeTwoEnd ];
    4709              : 
    4710              :                                                         vector3 directionEdgOne;
    4711              :                                                         VecSubtract(directionEdgOne, fracEdgOneEndPos, fracVrtPos);
    4712              : 
    4713              :                                                         vector3 directionEdgTwo;
    4714              :                                                         VecSubtract(directionEdgTwo, fracEdgTwoEndPos, fracVrtPos);
    4715              : 
    4716              :                                                         vector3 nrmdVecEdgOne;
    4717              :                                                         VecNormalize(nrmdVecEdgOne, directionEdgOne);
    4718              : 
    4719              :                                                         vector3 nrmdVecEdgTwo;
    4720              :                                                         VecNormalize(nrmdVecEdgTwo, directionEdgTwo);
    4721              : 
    4722              :                                                         number cosBetweenEdges = VecDot(nrmdVecEdgOne,nrmdVecEdgTwo);
    4723              : 
    4724              :                                                         // TODO FIXME wenn Winkel zu klein, dann die Methode verwenden der Mittelung der beiden Normalen!!!!
    4725              : 
    4726              :                                                         number angleEdges = std::acos( cosBetweenEdges );
    4727              :                                                         number angleNormls = std::acos( cosBetweenNormals );
    4728              : 
    4729              :                                                         totAnglsEdg += angleEdges;
    4730              :                                                         totAnglsNrm += angleNormls;
    4731              : 
    4732              :                                                         UG_LOG("cosinus Edges Normals " << cosBetweenEdges << "  " << cosBetweenNormals << std::endl);
    4733              :                                                         UG_LOG("angles edges normals " << angleEdges << "  " << angleNormls << std::endl);
    4734              : 
    4735              :                                                         // prject normal 1 onto edge 2 and normal 2 on edge 1, scale with width one half resp with width two half
    4736              : 
    4737              : 
    4738              :                                                         number cosBetweenNrmFraOneEdgTwo = VecDot(normalFracOne,nrmdVecEdgTwo);
    4739              :                                                         number cosBetweenNrmFraTwoEdgOne = VecDot(normalFracTwo,nrmdVecEdgOne);
    4740              : 
    4741              :                                                         vector3 projectNrmFraOneToEdgTwoDirection;
    4742              :                                                         VecScale(projectNrmFraOneToEdgTwoDirection, nrmdVecEdgTwo, 1./cosBetweenNrmFraOneEdgTwo);
    4743              : 
    4744              :                                                         vector3 projectNrmFraTwoToEdgOneDirection;
    4745              :                                                         VecScale(projectNrmFraTwoToEdgOneDirection, nrmdVecEdgOne, 1./cosBetweenNrmFraTwoEdgOne);
    4746              : 
    4747              :                 //                                      auto subsIndFracOne = sh.get_subset_index(edgeFracOne);
    4748              :                 //                                      auto subsIndFracTwo = sh.get_subset_index(edgeFracTwo);
    4749              : 
    4750              :                                                         number shiftOne = fracInfosBySubset.at( subsIndFracOne ).width / 2. ;
    4751              :                                                         number shiftTwo = fracInfosBySubset.at( subsIndFracTwo ).width / 2. ;
    4752              : 
    4753              :                                                         vector3 shiftAlongEdgeTwo;
    4754              :                                                         VecScale(shiftAlongEdgeTwo, projectNrmFraOneToEdgTwoDirection, shiftOne);
    4755              : 
    4756              :                                                         vector3 shiftAlongEdgeOne;
    4757              :                                                         VecScale(shiftAlongEdgeOne, projectNrmFraTwoToEdgOneDirection, shiftTwo);
    4758              : 
    4759              :                                                         vector3 shiftPart;
    4760              :                                                         VecAdd(shiftPart, fracVrtPos, shiftAlongEdgeTwo);
    4761              : 
    4762              :                                                         vector3 posNewVrt;
    4763              :                                                         VecAdd( posNewVrt, shiftPart, shiftAlongEdgeOne);
    4764              : 
    4765              :                                                         UG_LOG("neuer Vertex Kreuzung " << posNewVrt << std::endl );
    4766              : 
    4767              :                                                         Vertex * newShiftVrtx = *grid.create<RegularVertex>();
    4768              :                                                         aaPos[newShiftVrtx] = posNewVrt;
    4769              : 
    4770              :                                                         //                                      sh.assign_subset(newShiftVrtx,  newSubsToAdd );
    4771              :                                                         sh.assign_subset(newShiftVrtx, subsIndFracOne );
    4772              :                                                         // could also be two, but have to select one, no Kompromiss possible......
    4773              : 
    4774              :                                                         crossVrtInf.addShiftVrtx(newShiftVrtx);
    4775              : 
    4776              :         //                                              UG_LOG("ADDED SHIFT VECTOR " << aaPos[newShiftVrtx] << std::endl);
    4777              : 
    4778              :                                                         // TODO FIXME eigene Funktion, da bei 2 und 3 Klüften exakt dieselbe Routine, mit copy und paste übernommen worden
    4779              : 
    4780              :                                                         for( VertexOfFaceInfo const & vertFracInfoSeg : segPart )
    4781              :                                                         {
    4782              :                                                                 Face * fac = vertFracInfoSeg.getFace();
    4783              : 
    4784              :                 //                                              sh.assign_subset(fa,newSubsToAdd);
    4785              : 
    4786              : 
    4787              :                                                                 // ACHTUNG neue Variable Face klein geschrieben im Gegensatz zu Prof. Reiter! nicht später falsche verwenden!
    4788              :                                                                 vector<Vertex*>& newVrts4Fac = aaVrtVecFace[ fac ];
    4789              : 
    4790              :                                                                 IndexType vrtxFnd = 0;
    4791              : 
    4792              :                                                                 for(size_t indVrt = 0; indVrt < (fac)->num_vertices();  indVrt++ )
    4793              :                                                                 {
    4794              :                                                                         Vertex* facVrt = (fac)->vertex(indVrt);
    4795              : 
    4796              :                                                                         if(  facVrt == *iterV )
    4797              :                                                                         {
    4798              :                                                                                 newVrts4Fac[ indVrt ] = newShiftVrtx;
    4799              :                                                                                 vrtxFnd++;
    4800              : 
    4801              :         //                                                                      crossVrtInf.addShiftVrtx(newShiftVrtx);
    4802              :         //
    4803              :         //                                                                      UG_LOG("ADDED SHIFT VECTOR " << aaPos[newShiftVrtx] << std::endl);
    4804              : 
    4805              :                                                                         }
    4806              :                                                                 }
    4807              : 
    4808              :         //                                                      crossVrtInf.setShiftVrtx(newVrts4Fac);
    4809              : 
    4810              :                                                                 if( vrtxFnd <= 0 )
    4811              :                                                                 {
    4812              :                                                                         UG_THROW("vertex not found kreuzung!" << std::endl);
    4813              :                                                                                                                                         }
    4814              :                                                                 else if( vrtxFnd > 1 )
    4815              :                                                                 {
    4816              :                                                                         UG_THROW("vertex zu oft gefunden kreuzung " << vrtxFnd << std::endl );
    4817              :                                                                 }
    4818              :                                                                 else if ( vrtxFnd == 1 )
    4819              :                                                                 {
    4820              :                                                                 }
    4821              :                                                                 else
    4822              :                                                                 {
    4823              :                                                                         UG_THROW("vertex finden komisch kreuzung " << std::endl);
    4824              :                                                                 }
    4825              : 
    4826              :                                                         }
    4827              :                                                 }
    4828              :                                         }
    4829              :                                         else // angle dependent, new method
    4830              :                                         {
    4831            0 :                                                 if( subsIndFracOne == subsIndFracTwo )
    4832              :                                                 {
    4833              :         //                                              if( numFracsCrossAtVrt != 3 )
    4834            0 :                                                         if( numFracsCrossAtVrt != 2 && numFracsCrossAtVrt != 3 )
    4835              :                                                         {
    4836              :         //                                                      UG_THROW("Fracture Segment an beiden Seiten gleiche sudo, aber keine T Kreuzung?" << std::endl);
    4837            0 :                                                                 UG_THROW("Fracture Segment an beiden Seiten gleiche sudo, aber keine durchgehende Kluft?" << std::endl);
    4838              :                                                         }
    4839              :                                                 }
    4840              : 
    4841            0 :                                                 if( subsIndFracOne != subsIndFracTwo && numFracsCrossAtVrt == 2 )
    4842              :                                                 {
    4843            0 :                                                         UG_THROW("subsets passen nicht Vereinheitlichung" << std::endl );
    4844              :                                                 }
    4845              : 
    4846              :                                                 vector3 moveVrt;
    4847              : 
    4848              :                                                 number pi = 3.1415926535897932385;
    4849              : 
    4850              :                                                 number cosinusLim = std::cos( pi/8. );
    4851              : 
    4852              :                                                 vector3 posNewVrt;
    4853              : 
    4854              : //                                              if( cosBetweenNormals > cosinusLim )
    4855            0 :                                                 if( cosBetweenNormals > cosinusLim && numFracsCrossAtVrt < 4 )
    4856              : //                                              if( cosBetweenNormals > cosinusLim && subsIndFracOne == subsIndFracTwo )
    4857              : //                                              if( false )
    4858              :                                                 {
    4859              : 
    4860              : //                                                      UG_THROW("in dieser Funktion neu cos" << std::endl);
    4861              : 
    4862              : 
    4863              :                                                         // dieselben Methoden wie im Fall von einer durchgehenden Kluft an einem Vertex, dort kopieren
    4864              :                                                         // bzw Funktion schreiben, die beides macht
    4865              : 
    4866              :                                                         // hier wird der Fall abgezweigt, dass wir auf der durchgehenden Seite einer Kluft sind
    4867              :                                                         // wenn wir eine T-Kreuzung haben
    4868              : 
    4869              :                                                         std::vector<Vertex *> nextFracVrt;
    4870              : 
    4871              :                                                         IndexType foundThisVrtOne = 0;
    4872              : 
    4873            0 :                                                         for( size_t i = 0; i < 2; ++i )
    4874              :                                                         {
    4875            0 :                                                                 Vertex * vrtEdgEnd = edgeFracOne->vertex(i);
    4876              : 
    4877            0 :                                                                 if( vrtEdgEnd == *iterV )
    4878              :                                                                 {
    4879            0 :                                                                         foundThisVrtOne++;
    4880              :                                                                 }
    4881              :                                                                 else
    4882              :                                                                 {
    4883            0 :                                                                         nextFracVrt.push_back( vrtEdgEnd );
    4884              :                                                                 }
    4885              : 
    4886              :                                                         }
    4887              : 
    4888            0 :                                                         if( foundThisVrtOne != 1 )
    4889              :                                                         {
    4890            0 :                                                                 UG_THROW("zu viel zu wenig vertizex one " << std::endl);
    4891              :                                                         }
    4892              : 
    4893              : 
    4894              :                                                         IndexType foundThisVrtTwo = 0;
    4895              : 
    4896            0 :                                                         for( size_t i = 0; i < 2; ++i )
    4897              :                                                         {
    4898            0 :                                                                 Vertex * vrtEdgEnd = edgeFracTwo->vertex(i);
    4899              : 
    4900            0 :                                                                 if( vrtEdgEnd == *iterV )
    4901              :                                                                 {
    4902            0 :                                                                         foundThisVrtTwo++;
    4903              :                                                                 }
    4904              :                                                                 else
    4905              :                                                                 {
    4906            0 :                                                                         nextFracVrt.push_back( vrtEdgEnd );
    4907              :                                                                 }
    4908              : 
    4909              :                                                         }
    4910              : 
    4911            0 :                                                         if( foundThisVrtTwo != 1 )
    4912              :                                                         {
    4913            0 :                                                                 UG_THROW("zu viel zu wenig vertizex two " << std::endl);
    4914              :                                                         }
    4915              : 
    4916            0 :                                                         Face *  faceBegin = vFISBegin.getFace();
    4917            0 :                                                         Face *  faceEnd = vFISEnd.getFace();
    4918              : 
    4919              : 
    4920              :                                                         vector3 normSum;
    4921              : 
    4922              :                                                         VecAdd( normSum, normalFracOne, normalFracTwo );
    4923              : 
    4924              :                                                         vector3 normSumNormed;
    4925              : 
    4926            0 :                                                         VecNormalize(normSumNormed, normSum);
    4927              : 
    4928            0 :                                                         UG_LOG("averaged normal " << normSumNormed << std::endl);
    4929              : 
    4930              :                                                         std::vector<Edge * > attEdg;
    4931              :                                                         std::vector<Face * > attFac;
    4932              : 
    4933            0 :                                                         attEdg.push_back( edgeFracOne );
    4934            0 :                                                         attEdg.push_back( edgeFracTwo );
    4935              : 
    4936            0 :                                                         attFac.push_back( faceBegin );
    4937            0 :                                                         attFac.push_back( faceEnd );
    4938              : 
    4939              :                                                         // jetzt neuen Vertex erzeugen in Richtung der Normalen
    4940              :                                                         // sonst ist das attachment Schwachsinn!
    4941              : 
    4942            0 :                                                         number widthOne = fracInfosBySubset.at(subsIndFracOne).width;
    4943            0 :                                                         number widthTwo = fracInfosBySubset.at(subsIndFracTwo).width;
    4944              : 
    4945            0 :                                                         number width = ( widthOne + widthTwo ) /2.;
    4946              : 
    4947              :                                                         // FALSCH
    4948              :                                                         // der Faktor ist Käse und muss noch aus den Eingaben übernommen werden
    4949            0 :                                                         VecScale(moveVrt, normSumNormed, width/2. );
    4950              : 
    4951              : //                                                      vector3 posNewVrt;
    4952              : 
    4953              :                                                         VecAdd(posNewVrt, posOldVrt, moveVrt );
    4954              : 
    4955            0 :                                                         UG_LOG("neuer Vertex " << posNewVrt << std::endl );
    4956              : 
    4957              :                                                         // TODO FIXME hier ist das PROBLEM, SEGFAULT durch create regular vertex
    4958              : 
    4959            0 :                                                 }
    4960              :                                                 else
    4961              :                                                 {
    4962              : 
    4963              : //                                                      UG_THROW("in dieser Funktion neu" << std::endl);
    4964              : 
    4965              :                                                         // create normal vectors into direction of relevant edges
    4966              : 
    4967              :                                                         vector3 alongEdgeOne;
    4968              :                                                         vector3 alongEdgeTwo;
    4969              : 
    4970              :                                                         Vertex * vrtEdgeOneBegin = nullptr;
    4971              :                                                         Vertex * vrtEdgeTwoBegin = nullptr;
    4972              :                                                         Vertex * vrtEdgeOneEnd = nullptr;
    4973              :                                                         Vertex * vrtEdgeTwoEnd = nullptr;
    4974              : 
    4975              : 
    4976            0 :                                                         for( size_t i = 0; i < 2; ++i )
    4977              :                                                         {
    4978            0 :                                                                 Vertex * vrtFromEdgeOne = edgeFracOne->vertex(i);
    4979            0 :                                                                 Vertex * vrtFromEdgeTwo = edgeFracTwo->vertex(i);
    4980              : 
    4981            0 :                                                                 if( vrtFromEdgeOne == *iterV )
    4982              :                                                                 {
    4983              :                                                                         vrtEdgeOneBegin = vrtFromEdgeOne;
    4984              :                                                                 }
    4985              :                                                                 else
    4986              :                                                                 {
    4987              :                                                                         vrtEdgeOneEnd = vrtFromEdgeOne;
    4988              :                                                                 }
    4989              : 
    4990            0 :                                                                 if( vrtFromEdgeTwo == *iterV )
    4991              :                                                                 {
    4992              :                                                                         vrtEdgeTwoBegin = vrtFromEdgeTwo;
    4993              :                                                                 }
    4994              :                                                                 else
    4995              :                                                                 {
    4996              :                                                                         vrtEdgeTwoEnd = vrtFromEdgeTwo;
    4997              :                                                                 }
    4998              : 
    4999              :                                                         }
    5000              : 
    5001            0 :                                                         if( vrtEdgeOneBegin == nullptr || vrtEdgeTwoBegin == nullptr || vrtEdgeOneEnd == nullptr || vrtEdgeTwoEnd == nullptr )
    5002              :                                                         {
    5003            0 :                                                                 UG_THROW("lauter Nullen vertizes" << std::endl);
    5004              :                                                         }
    5005              : 
    5006              :                                                         vector3 fracVrtPos = aaPos[*iterV];
    5007              : 
    5008              :                                                         vector3 fracEdgOneEndPos = aaPos[ vrtEdgeOneEnd ];
    5009              :                                                         vector3 fracEdgTwoEndPos = aaPos[ vrtEdgeTwoEnd ];
    5010              : 
    5011              :                                                         vector3 directionEdgOne;
    5012              :                                                         VecSubtract(directionEdgOne, fracEdgOneEndPos, fracVrtPos);
    5013              : 
    5014              :                                                         vector3 directionEdgTwo;
    5015              :                                                         VecSubtract(directionEdgTwo, fracEdgTwoEndPos, fracVrtPos);
    5016              : 
    5017              :                                                         vector3 nrmdVecEdgOne;
    5018            0 :                                                         VecNormalize(nrmdVecEdgOne, directionEdgOne);
    5019              : 
    5020              :                                                         vector3 nrmdVecEdgTwo;
    5021            0 :                                                         VecNormalize(nrmdVecEdgTwo, directionEdgTwo);
    5022              : 
    5023              :                                                         number cosBetweenEdges = VecDot(nrmdVecEdgOne,nrmdVecEdgTwo);
    5024              : 
    5025              :                                                         // TODO FIXME wenn Winkel zu klein, dann die Methode verwenden der Mittelung der beiden Normalen!!!!
    5026              : 
    5027            0 :                                                         number angleEdges = std::acos( cosBetweenEdges );
    5028            0 :                                                         number angleNormls = std::acos( cosBetweenNormals );
    5029              : 
    5030            0 :                                                         totAnglsEdg += angleEdges;
    5031            0 :                                                         totAnglsNrm += angleNormls;
    5032              : 
    5033              :                                                         UG_LOG("cosinus Edges Normals " << cosBetweenEdges << "  " << cosBetweenNormals << std::endl);
    5034              :                                                         UG_LOG("angles edges normals " << angleEdges << "  " << angleNormls << std::endl);
    5035              : 
    5036              :                                                         // prject normal 1 onto edge 2 and normal 2 on edge 1, scale with width one half resp with width two half
    5037              : 
    5038              : 
    5039              :                                                         number cosBetweenNrmFraOneEdgTwo = VecDot(normalFracOne,nrmdVecEdgTwo);
    5040              :                                                         number cosBetweenNrmFraTwoEdgOne = VecDot(normalFracTwo,nrmdVecEdgOne);
    5041              : 
    5042              :                                                         vector3 projectNrmFraOneToEdgTwoDirection;
    5043            0 :                                                         VecScale(projectNrmFraOneToEdgTwoDirection, nrmdVecEdgTwo, 1./cosBetweenNrmFraOneEdgTwo);
    5044              : 
    5045              :                                                         vector3 projectNrmFraTwoToEdgOneDirection;
    5046            0 :                                                         VecScale(projectNrmFraTwoToEdgOneDirection, nrmdVecEdgOne, 1./cosBetweenNrmFraTwoEdgOne);
    5047              : 
    5048              :                 //                                      auto subsIndFracOne = sh.get_subset_index(edgeFracOne);
    5049              :                 //                                      auto subsIndFracTwo = sh.get_subset_index(edgeFracTwo);
    5050              : 
    5051            0 :                                                         number shiftOne = fracInfosBySubset.at( subsIndFracOne ).width / 2. ;
    5052            0 :                                                         number shiftTwo = fracInfosBySubset.at( subsIndFracTwo ).width / 2. ;
    5053              : 
    5054              :                                                         vector3 shiftAlongEdgeTwo;
    5055              :                                                         VecScale(shiftAlongEdgeTwo, projectNrmFraOneToEdgTwoDirection, shiftOne);
    5056              : 
    5057              :                                                         vector3 shiftAlongEdgeOne;
    5058              :                                                         VecScale(shiftAlongEdgeOne, projectNrmFraTwoToEdgOneDirection, shiftTwo);
    5059              : 
    5060              :                                                         vector3 shiftPart;
    5061              :                                                         VecAdd(shiftPart, fracVrtPos, shiftAlongEdgeTwo);
    5062              : 
    5063              : //                                                      vector3 posNewVrt;
    5064              :                                                         VecAdd( posNewVrt, shiftPart, shiftAlongEdgeOne);
    5065              : 
    5066            0 :                                                         UG_LOG("neuer Vertex Kreuzung " << posNewVrt << std::endl );
    5067              :                                                 }
    5068              : 
    5069            0 :                                                 Vertex * newShiftVrtx = *grid.create<RegularVertex>();
    5070              :                                                 aaPos[newShiftVrtx] = posNewVrt;
    5071              : 
    5072            0 :                                                 sh.assign_subset(newShiftVrtx, subsIndFracOne );
    5073              : 
    5074              : 
    5075            0 :                                                 if( numFracsCrossAtVrt > 2 )
    5076              :                                                 {
    5077              :                                                         bool isAtFreeTEnd = false;
    5078              : 
    5079            0 :                                                         if( numFracsCrossAtVrt == 3 && subsIndFracOne == subsIndFracTwo )
    5080              :                                                                 isAtFreeTEnd = true;
    5081              : 
    5082            0 :                                                         crossVrtInf.addShiftVrtx(newShiftVrtx, isAtFreeTEnd );
    5083              :                                                 }
    5084              : 
    5085              : #if 1
    5086            0 :                                                 teachAssoFacesNewVrtx(  segPart, aaVrtVecFace, *iterV, newShiftVrtx );
    5087              : 
    5088              : #else
    5089              :                                                 for( VertexOfFaceInfo const & vertFracInfoSeg : segPart )
    5090              :                                                 {
    5091              :                                                         Face * fac = vertFracInfoSeg.getFace();
    5092              : 
    5093              :         //                                              sh.assign_subset(fa,newSubsToAdd);
    5094              : 
    5095              :                                                         // ACHTUNG neue Variable Face klein geschrieben im Gegensatz zu SR! nicht später falsche verwenden!
    5096              :                                                         vector<Vertex*>& newVrts4Fac = aaVrtVecFace[ fac ];
    5097              : 
    5098              :                                                         IndexType vrtxFnd = 0;
    5099              : 
    5100              :                                                         for(size_t indVrt = 0; indVrt < (fac)->num_vertices();  indVrt++ )
    5101              :                                                         {
    5102              :                                                                 Vertex* facVrt = (fac)->vertex(indVrt);
    5103              : 
    5104              :                                                                 if(  facVrt == *iterV )
    5105              :                                                                 {
    5106              :                                                                         newVrts4Fac[ indVrt ] = newShiftVrtx;
    5107              :                                                                         vrtxFnd++;
    5108              : 
    5109              : //                                                                      UG_LOG("ADDED SHIFT VECTOR " << aaPos[newShiftVrtx] << std::endl);
    5110              : 
    5111              :                                                                 }
    5112              :                                                         }
    5113              : 
    5114              :                                                         if( vrtxFnd <= 0 )
    5115              :                                                         {
    5116              :                                                                 UG_THROW("vertex not found kreuzung!" << std::endl);
    5117              :                                                                                                                                 }
    5118              :                                                         else if( vrtxFnd > 1 )
    5119              :                                                         {
    5120              :                                                                 UG_THROW("vertex zu oft gefunden kreuzung " << vrtxFnd << std::endl );
    5121              :                                                         }
    5122              :                                                         else if ( vrtxFnd == 1 )
    5123              :                                                         {
    5124              :                                                         }
    5125              :                                                         else
    5126              :                                                         {
    5127              :                                                                 UG_THROW("vertex finden komisch kreuzung " << std::endl);
    5128              :                                                         }
    5129              : 
    5130              :                                                 }
    5131              : #endif
    5132              :                                         }
    5133              : 
    5134              :                                 }
    5135              : 
    5136              :                                 UG_LOG("sum angles edges normals " << totAnglsEdg << "  " << totAnglsNrm << std::endl);
    5137              : 
    5138              : //                              return true;
    5139              : 
    5140              : #if 0
    5141              :                                 // das folgende ist vermutlich Unsinn TODO FIXME, waren wohl Versuche am Anfang..... nochmal prüfen!!!!
    5142              : 
    5143              :                                 // get starting point of the "rotation" around the vertex where fractures are crossing
    5144              : //                              for( auto & attVFT : vVFT ) // not const, as we need to erase found elements!
    5145              :                                 for( VecVertFracTrip::iterator itAttVFT = vVFT.begin(); itAttVFT !=  vVFT.end(); )
    5146              :                                 {
    5147              :                                         Face * facAtVrtWithFrac = itAttVFT->getFace();
    5148              : 
    5149              :                                         bool facFound = false;
    5150              : 
    5151              : //                                      for( auto const & ifac : assoFaces ) // not const, as we need to erase found elements!
    5152              :                                         for( std::vector<Face*>::iterator itFac = aF.begin(); itFac != aF.end(); )
    5153              :                                         {
    5154              :                                                 if( *itFac == facAtVrtWithFrac )
    5155              :                                                 {
    5156              :                                                         // found a starting face
    5157              :                                                         // copy first the found info, then delete the original one
    5158              :                                                         auto attVFTCop = *itAttVFT; // copy, not reference!
    5159              : 
    5160              :                                                         vVFT.erase(itAttVFT);
    5161              :                                                         aF.erase(itFac);
    5162              : 
    5163              :                                                         // TODO FIXME erase ifac and attVFT, how to do?
    5164              : 
    5165              :                                                         Face * startFace = facAtVrtWithFrac;
    5166              : 
    5167              :                                                         // now determine the common edge(s), the first edge of the vector must be a frac edge, the second one might be one
    5168              : 
    5169              :                                                         Edge * startEdg = attVFTCop.getEdge();
    5170              : 
    5171              :                                                         // unnecessary check, but for test purposes at beginning, later should be removed
    5172              :                                                         if( !FaceContains(facAtVrtWithFrac, startEdg ))
    5173              :                                                         {
    5174              :                                                                 UG_THROW("face hat ecke nicht, die es haben soll" << std::endl);
    5175              :                                                         }
    5176              : 
    5177              :                                                         // loop around the edges of the ifac face attached to the vertex
    5178              : 
    5179              :                                                         // determin second edge of the startFace, not stored in the vecVertFracTrip information
    5180              :                                                         // check number of common edges containing the same vertex
    5181              : 
    5182              :                                                         IndexType fndCommEdg = 0;
    5183              :                                                         std::vector<Edge*> assoEdg2Fac;
    5184              : 
    5185              :                                                         assoEdg2Fac.push_back( startEdg );
    5186              : 
    5187              :                                                         std::vector<vector3> assoNorm;
    5188              : 
    5189              :                                                         vector3 norm2Frac = attVFTCop.getNormal();
    5190              : 
    5191              :                                                         Edge * secondEdge;
    5192              :                                                         secondEdge = NULL;
    5193              : 
    5194              :                                                         for( auto const & iE : allAssoEdges ) // werden nicht gelöscht, deswegen Zugriff auf attachment direkt
    5195              :                                                         {
    5196              :                                                                 if( FaceContains(facAtVrtWithFrac, iE) )
    5197              :                                                                 {
    5198              :                                                                         fndCommEdg++;
    5199              :                                                                         if( iE != startEdg )
    5200              :                                                                         {
    5201              :                                                                                 secondEdge = iE;
    5202              :                                                                         }
    5203              :                                                                 }
    5204              : 
    5205              :                                                                 if( fndCommEdg != 2 )
    5206              :                                                                 {
    5207              :                                                                         UG_THROW("komische Anzahl gemeinsamer Ecke " << fndCommEdg << std::endl);
    5208              :                                                                 }
    5209              : 
    5210              :                                                                 if( secondEdge == NULL )
    5211              :                                                                 {
    5212              :                                                                         UG_THROW("wieso keine zweite Ecke gefunden???? " << std::endl);
    5213              :                                                                 }
    5214              : 
    5215              :                                                                 assoEdg2Fac.push_back(secondEdge);
    5216              : 
    5217              :                                                                 // check, if second edge belongs to anothter fracture fac, i.e. if it is also a fracture edge
    5218              : 
    5219              :                                                                 // check if second edge is edge of a fracture face, i.e. either this edge, or another one is from a fracture
    5220              : 
    5221              :                                                                 bool scndEdgIsFracEdg = aaMarkEdgeB[secondEdge];
    5222              : 
    5223              :                                                                 if( scndEdgIsFracEdg )
    5224              :                                                                 {
    5225              :                                                                         // TODO FIXME figure out second vertex fracture info, in this case, we have found the next part of the chain!
    5226              : 
    5227              :                                                                         for( VecVertFracTrip::iterator itAttVFTTwo = vVFT.begin(); itAttVFTTwo !=  vVFT.end(); )
    5228              :                                                                         {
    5229              :                                                                                 // need to erase also this element soon, also in the list of all attached elements
    5230              : 
    5231              :                                                                                 Face* vFTTwoFac = itAttVFTTwo->getFace();
    5232              : 
    5233              :                                                                                 if( FaceContains( vFTTwoFac, secondEdge))
    5234              :                                                                                 {
    5235              :                                                                                         auto vVFT2 = *itAttVFTTwo;
    5236              :                                                                                         vVFT.erase( itAttVFTTwo );
    5237              : 
    5238              :                                                                                         Face * nextFace = vFTTwoFac;
    5239              : 
    5240              :                                                                                         if( secondEdge != vVFT2.getEdge() )
    5241              :                                                                                         {
    5242              :                                                                                                 UG_THROW("Ecke nicht Ecke " << std::endl);
    5243              :                                                                                         }
    5244              : 
    5245              : 
    5246              :                                                                                 }
    5247              :                                                                         }
    5248              :                                                                 }
    5249              :                                                                 else // find the next attached face, either from the
    5250              :                                                                 {
    5251              : 
    5252              :                                                                 }
    5253              :                                                         }
    5254              : 
    5255              :                                                         break;
    5256              :                                                 }
    5257              : 
    5258              :                                                 if( ! facFound )
    5259              :                                                 {
    5260              :                                                         UG_THROW("Gesicht unauffindbar" << std::endl);
    5261              :                                                 }
    5262              : 
    5263              :                                                 break;
    5264              :                                         }
    5265              :                                 }
    5266              : 
    5267              :                                 while( vVFT.size() != 0 )
    5268              :                                 {
    5269              :                                         while( aF.size() != 0 )
    5270              :                                         {
    5271              : 
    5272              :                                         }
    5273              :                                 }
    5274              : 
    5275              : #endif
    5276              : 
    5277              : //                              if( numFracsCrossAtVrt == 3 )
    5278              : //                              {
    5279              : //                                      teeVrts.push_back(*iterV);
    5280              : //                              }
    5281              : //                              else if( numFracsCrossAtVrt == 4 )
    5282              : //                              {
    5283              : //                                      crossVrts.push_back(*iterV);
    5284              : //                              }
    5285              : 
    5286            0 :                                 IndexType groesseShiVe = crossVrtInf.getVecShiftedVrts().size();
    5287              : 
    5288              :                                 auto gro = groesseShiVe;
    5289              : 
    5290              :                                 UG_LOG("GROESSE SHIFT VECTORS " << gro << std::endl);
    5291              : 
    5292            0 :                                 vecCrossVrtInf.push_back(crossVrtInf);
    5293              : 
    5294            0 :                         }
    5295              : 
    5296              :                 }
    5297              : //              // // different treatment for boundary vertizes
    5298              :                 else
    5299              :                 {
    5300              : 
    5301              :                         // es muss wohl noch ein Problem mit den Verschiebungen bei boundary Vertizes geben.....
    5302              : 
    5303              : 
    5304            0 :                         if( numFracsCrossAtVrt < 1 )
    5305              :                         {
    5306            0 :                                 UG_THROW("no fracs crossing but marked vertex at boundary? << std::endl");
    5307              :                         }
    5308            0 :                         else if( numFracsCrossAtVrt == 1 ) // no crossing point  at boundary
    5309              :                         {
    5310              :                                 // in this case, we have ONE attached edges, the edges has two attached faces
    5311              :                                 // the faces have a normal, and based on the normal, we can decide which faces belong to the same side of the edges
    5312              : 
    5313            0 :                                 if( numbAttTripl != 2 )
    5314              :                                 {
    5315            0 :                                         UG_THROW("Anzahl der angehaengten Triples kann nicht stimmen, Vertex einer Kluft ohne Schnittpunkte  am Rand " << std::endl);
    5316              :                                 }
    5317              : 
    5318              :                                 VecVertexOfFaceInfo orderedFaces;
    5319              :                                 SegmentsFractExtrus segments;
    5320              :                                 //VecVertexOfFaceInfo segmentPart;
    5321              : 
    5322              :                                 // Zuordnung der Edges und Faces, die auf der gleichen Seite der fracture sind
    5323              : 
    5324              :                                 // und gleich auch Erzeugung der neuen Knoten, die dann
    5325              :                                 // in einem Doublett zusammen mit ihren Normalen an die alten Vertizes
    5326              :                                 // angehängt werden; der Winkel zur Normalen hilft später, die Seite
    5327              :                                 // heraus zu finden, Seite von den Edges
    5328              : 
    5329              :                                 // get  edges adjacent to this vertex which lie on the boundary of the domain
    5330              : 
    5331              :                                 std::vector<Edge* > adjBndEdgs;
    5332              : 
    5333              : //                              std::vector<Edge*> & allAssoEdges = aaVrtInfoAssoEdges[*iterV];
    5334              : 
    5335              : //                              for( std::vector<Edge*>::iterator iterBVEdg = grid.associated_edges_begin(*iterV); iterBVEdg != grid.associated_edges_end(*iterV); iterBVEdg++  )
    5336              : //                              {
    5337              : //                                      if( IsBoundaryEdge2D(grid,*iterBVEdg) )
    5338              : //                                      {
    5339              : //                                              adjBndEdgs.push_back( *iterBVEdg );
    5340              : //                                      }
    5341              : //                              }
    5342            0 :                                 for( auto const & iBVE : allAssoEdges )
    5343              :                                 {
    5344            0 :                                         if( IsBoundaryEdge2D(grid, iBVE ) )
    5345              :                                         {
    5346            0 :                                                 adjBndEdgs.push_back( iBVE );
    5347              :                                         }
    5348              :                                 }
    5349              : 
    5350            0 :                                 if( adjBndEdgs.size() != 2  )
    5351            0 :                                         UG_THROW("how many boundary edges????" << std::endl);
    5352              : 
    5353              :                                 IndexType startInd = -1; // to avoid errornous use
    5354              : 
    5355            0 :                                 Face * attFaceOf1stBndEdg = nullptr; // TODO FIXME bestimmen sofort!!!
    5356              : 
    5357            0 :                                 Edge * begOrdEdg = adjBndEdgs[0];
    5358              : 
    5359              :                                 IndexType fndBndFac = 0;
    5360              : 
    5361            0 :                                 for( std::vector<Face* >::iterator itFa = grid.associated_faces_begin(begOrdEdg);
    5362            0 :                                                 itFa < grid.associated_faces_end(begOrdEdg);
    5363              :                                                 itFa++ )
    5364              :                                 {
    5365            0 :                                         attFaceOf1stBndEdg = *itFa;
    5366            0 :                                         fndBndFac++;
    5367              :                                 }
    5368              : 
    5369            0 :                                 if( fndBndFac != 1 || attFaceOf1stBndEdg == nullptr )
    5370              :                                 {
    5371            0 :                                         UG_THROW("Grenzgesicht nicht gefunden " << fndBndFac << std::endl);
    5372              :                                 }
    5373              : 
    5374            0 :                                 determineOrderOfFaces( vecVertFracTrip, assoFaces, orderedFaces,
    5375              :                                                                                 segments,  //segmentPart,
    5376              :                                                                                 startInd,
    5377              :                                                                                 allAssoEdges,
    5378              :                                                                                 sh,
    5379              :                                                                                 aaMarkEdgeB,
    5380              :                                                                                 adjBndEdgs,
    5381              :                                                                                 attFaceOf1stBndEdg
    5382              :                                                                                 );
    5383              : 
    5384              : //                              for( auto const & segPart : segments )
    5385              : //                              {
    5386              : //                                      for( auto const & vi : segPart )
    5387              : //                                      {
    5388              : //                                              Face * fac = vi.getFace();
    5389              : //
    5390              : //                                              IndexType sudoNew = sh.num_subsets();
    5391              : //
    5392              : //                                              sh.assign_subset(fac, sudoNew);
    5393              : //                                      }
    5394              : //                              }
    5395              : //
    5396              : //                              return true;
    5397              : 
    5398              :                                 // to compute the normals, compute the vector of the edge and normalize it
    5399              :                                 std::vector<vector3> bndEdgeDirection;
    5400              : 
    5401            0 :                                 for( auto const & bE : adjBndEdgs )
    5402              :                                 {
    5403              : 
    5404              :                                         // get vertices, i.e. get seocnd vertex, first one must be known
    5405              : 
    5406              : //                                      std::vector<Vertex* > verticesEdg;
    5407              : 
    5408              :                                         // DEBUG ASSERT TEST static_assert( std::is_same< Edge* const &, decltype( bE ) >::value );
    5409              : 
    5410              :                                         // DEBUG ASSERT TEST static_assert( std::is_same< Vertex*, decltype( bE->vertex(0) ) >::value );
    5411              : 
    5412              :                                         IndexType fndIV = 0;
    5413              : 
    5414              :                                         Vertex * vrtOtherEdg;
    5415              :                                         vrtOtherEdg = NULL;
    5416              : 
    5417            0 :                                         for( size_t i = 0; i < 2; ++i )
    5418              :                                         {
    5419              : //                                              verticesEdg.push_back( adjBndEdgs.vertex(i) );
    5420              : 
    5421            0 :                                                 Vertex * vrtOfEdg = bE->vertex(i);
    5422              : 
    5423            0 :                                                 if( vrtOfEdg == *iterV )
    5424              :                                                 {
    5425              :                                                         fndIV++;
    5426              :                                                 }
    5427              :                                                 else
    5428              :                                                 {
    5429              :                                                         vrtOtherEdg = vrtOfEdg;
    5430              :                                                 }
    5431              :                                         }
    5432              : 
    5433              :                                         vector3 posOtherVrt = aaPos[vrtOtherEdg];
    5434              : 
    5435            0 :                                         UG_LOG("BOUNDARY EDGE VERTIZES " << posOldVrt << ", " << posOtherVrt << std::endl);
    5436              : 
    5437              :                                         vector3 fromIterV2Other;
    5438              : 
    5439              :                                         VecSubtract(fromIterV2Other, posOtherVrt, posOldVrt);
    5440              : 
    5441              :                                         vector3 nV;
    5442              : 
    5443            0 :                                         VecNormalize(nV, fromIterV2Other);
    5444              : 
    5445            0 :                                         bndEdgeDirection.push_back(nV);
    5446              :                                 }
    5447              : 
    5448              : 
    5449              :                                 constexpr bool useOldBndryOdering = false;
    5450              : 
    5451              :                                 if( useOldBndryOdering )
    5452              :                                 {
    5453              : 
    5454              : #if WORKAROUND_ARTE_SEGFAULT
    5455              : 
    5456              :                                         IndexType dbg_lim = vecVertFracTrip.size();
    5457              : 
    5458              :                                         int dbg_cnt = 0;
    5459              : #endif
    5460              : 
    5461              :                                         // TODO FIXME HHHHHHHHH hier die Sortierungsroutine einbauen, um die attachten faces sicher richtig zu zu ordnen!!!
    5462              : 
    5463              :                                         for( VvftIterator vvftAtBnd = vecVertFracTrip.begin();
    5464              :                                                         vvftAtBnd != vecVertFracTrip.end();
    5465              :                                                         vvftAtBnd++
    5466              :                                         )
    5467              :                                         {
    5468              : #if WORKAROUND_ARTE_SEGFAULT
    5469              : 
    5470              :                                                 if( dbg_lim == dbg_cnt )
    5471              :                                                 {
    5472              :                                                         UG_LOG("DARF NICHT SEIN" << std::endl);
    5473              :                                                         break;
    5474              :                                                 }
    5475              : 
    5476              :                                                 dbg_cnt++;
    5477              : #endif
    5478              : 
    5479              :                                                 // Ziel: den parallelen Anteil der Normalen auf die jeweilige Randkante projizieren
    5480              : 
    5481              :                                                 vector3 nrmEdg = vvftAtBnd->getNormal();
    5482              : 
    5483              :                                                 Edge * edgeOfFrac = vvftAtBnd->getEdge();
    5484              : 
    5485              :                                                 // figure out the adjoint boundary edge into the same direction
    5486              : 
    5487              :                                                 // the normal in both directions have to be compared with the vectors in direction of boundary edges
    5488              :                                                 for( auto bED : bndEdgeDirection )
    5489              :                                                 {
    5490              :                                                         // check orientation of boundary edges wrt the normals
    5491              : 
    5492              :                                                         number cosinus = VecDot( nrmEdg, bED );
    5493              : 
    5494              :                                                         UG_LOG("BOUNDARY COSINUS between " << nrmEdg << " and " << bED << " -> " << cosinus << std::endl);
    5495              : 
    5496              :                                                         if( cosinus > 0 )
    5497              :                                                         {
    5498              :                                                                 // gleiche Seite vermutet
    5499              : 
    5500              :                                                                 // muessen wissen, wie lange das gestreckt werden soll
    5501              : 
    5502              :                                                                 vector3 alongEdgV;
    5503              : 
    5504              :                                                                 auto subsIndEdgOF = sh.get_subset_index(edgeOfFrac);
    5505              : 
    5506              :                                                                 number width = fracInfosBySubset.at(subsIndEdgOF).width;
    5507              : 
    5508              :                                                                 number scal = width / 2. / cosinus;
    5509              : 
    5510              :                                                                 VecScale( alongEdgV, bED, scal );
    5511              : 
    5512              :                                                                 vector3 posNewVrtOnBnd;
    5513              : 
    5514              :                                                                 VecAdd(posNewVrtOnBnd, posOldVrt, alongEdgV );
    5515              : 
    5516              :                                                                 UG_LOG("neuer Vertex Edge " << posNewVrtOnBnd << std::endl );
    5517              : 
    5518              :                                                                 Vertex * newShiftEdgVrtx = *grid.create<RegularVertex>();
    5519              :                                                                 aaPos[newShiftEdgVrtx] = posNewVrtOnBnd;
    5520              : 
    5521              :                                                                 sh.assign_subset(newShiftEdgVrtx, subsIndEdgOF );
    5522              : 
    5523              :                                                                 std::vector<Edge * > attEdg;
    5524              :                                                                 std::vector<Face * > attFac;
    5525              : 
    5526              :                                                                 attEdg.push_back(edgeOfFrac);
    5527              : 
    5528              :                                                                 Face * facFrac = vvftAtBnd->getFace();
    5529              : 
    5530              :                                                                 attFac.push_back( facFrac );
    5531              : 
    5532              :                                                                 // we store the boundary edge direction for boundary verzizes rather than the normal, in contrast to inner vertizes, where we store the averaged normal
    5533              :                                                                 ExpandVertexMultiplett vrtMtpl( attEdg, attFac, bED );
    5534              : 
    5535              :                                                                 aaVrtExpMP[ *iterV ].push_back( vrtMtpl );
    5536              : 
    5537              : #if 0
    5538              :                                                                 // the attached faces need to know that they need a new vertex to be shifted
    5539              :                                                                 for( std::vector<Face *>::iterator iterFac = grid.associated_faces_begin(*iterV); iterFac != grid.associated_faces_end(*iterV); iterFac++ )
    5540              :                                                                 {
    5541              :                                                                         bool isFromFrac = false;
    5542              : 
    5543              :                                                                         for( auto const & facFrac : attFac )
    5544              :                                                                         {
    5545              :                                                                                 if( *iterFac == facFrac )
    5546              :                                                                                 {
    5547              :                                                                                         isFromFrac = true;
    5548              :                                                                                 }
    5549              :                                                                         }
    5550              : 
    5551              :                                                                         bool atRightSide = false;
    5552              : 
    5553              :                                                                         if( isFromFrac )
    5554              :                                                                                 atRightSide = true;
    5555              : 
    5556              :                                                                         if( !isFromFrac )
    5557              :                                                                         {
    5558              : 
    5559              :                                                                                 // check if on same side of edge where the normal points to: compute cosinus between vector of face center
    5560              :                                                                                 //  perpendicular to the edge
    5561              :                                                                                 // TODO FIXME
    5562              : 
    5563              :                                                                                 vector3 facCenter = CalculateCenter( *iterFac, aaPos );
    5564              : 
    5565              :                                                                                 vector3 perpendicu;
    5566              : 
    5567              :                                                                                 DropAPerpendicular(perpendicu, facCenter, aaPos[edgeOfFrac->vertex(0)], aaPos[edgeOfFrac->vertex(1)]);
    5568              : 
    5569              :                                                                                 vector3 tmpN;
    5570              : 
    5571              :                                                                                 VecSubtract(tmpN, facCenter, perpendicu );
    5572              : 
    5573              :                                                                                 VecNormalize(tmpN, tmpN);
    5574              : 
    5575              :                                                                                 UG_LOG("Normale Boundary zum Face ist " << tmpN << std::endl);
    5576              : 
    5577              :                                                                                 number cosBetwFracEdgAndDirection2Face = VecDot(tmpN, nrmEdg );
    5578              : 
    5579              :                                                                                 UG_LOG("Cosinus Boundary zur Normalen ist " << cosBetwFracEdgAndDirection2Face << std::endl);
    5580              : 
    5581              :                                                                                 if( cosBetwFracEdgAndDirection2Face > 0 )
    5582              :                                                                                 {
    5583              :                                                                                         UG_LOG("assuming boundary face to be on richt side" << std::endl);
    5584              : 
    5585              :                                                                                         atRightSide = true;
    5586              : 
    5587              : #if ESTABLISH_DEBUG_SUDOS
    5588              :                                                                                                         Vertex * otherFacCent = *grid.create<RegularVertex>();
    5589              :                                                                                                         aaPos[otherFacCent] = facCenter;
    5590              :                                                                                                         sh.assign_subset(otherFacCent, 5 );
    5591              : 
    5592              :                                                                                                         Vertex * pp = *grid.create<RegularVertex>();
    5593              :                                                                                                         aaPos[pp] = perpendicu;
    5594              :                                                                                                         sh.assign_subset(pp, 6 );
    5595              : 
    5596              :                                                                                                         sh.assign_subset(*iterFac,7);
    5597              : #endif
    5598              : 
    5599              : 
    5600              :                                                                                 }
    5601              :                                                                                 else
    5602              :                                                                                 {
    5603              :                                                                                         UG_LOG("assuming boundary face to be on wrong side" << std::endl);
    5604              :                                                                                 }
    5605              : 
    5606              :                                                                         }
    5607              : 
    5608              :                                                                         if( atRightSide ) // atRightSide ) NOCH FALSCH TODO FIXME muss nur auf richtiger Seite sein
    5609              :                                                                         {
    5610              : 
    5611              : 
    5612              :                                                                                 vector<Vertex*>& newVrts4Fac = aaVrtVecFace[ * iterFac ];
    5613              : 
    5614              :                                                                                 IndexType vrtxFnd = 0;
    5615              : 
    5616              :                                                                                 for(size_t indVrt = 0; indVrt < (*iterFac)->num_vertices();  indVrt++ )
    5617              :                                                                                 {
    5618              :                                                                                         Vertex* facVrt = (*iterFac)->vertex(indVrt);
    5619              : 
    5620              :                                                                                         if(  facVrt == *iterV )
    5621              :                                                                                         {
    5622              :                                                                                                 newVrts4Fac[ indVrt ] = newShiftEdgVrtx;
    5623              :                                                                                                 vrtxFnd++;
    5624              :                                                                                         }
    5625              :                                                                                 }
    5626              : 
    5627              : 
    5628              : 
    5629              :                                                                                 if( vrtxFnd <= 0 )
    5630              :                                                                                 {
    5631              :                                                                                         UG_THROW("vertex not found bnd!" << std::endl);
    5632              :                                                                                 }
    5633              :                                                                                 else if( vrtxFnd > 1 )
    5634              :                                                                                 {
    5635              :                                                                                         UG_THROW("vertex zu oft gefunden bnd " << vrtxFnd << std::endl );
    5636              :                                                                                 }
    5637              :                                                                                 else if ( vrtxFnd == 1 )
    5638              :                                                                                 {
    5639              :         //                                                                                                              UG_LOG("vertex found abgeschlossen" << std::endl);
    5640              :                                                                                 }
    5641              :                                                                                 else
    5642              :                                                                                 {
    5643              :                                                                                         UG_THROW("vertex finden bnd komisch " << std::endl);
    5644              :                                                                                 }
    5645              :                                                                         }
    5646              : 
    5647              :                                                                 }
    5648              : #else
    5649              : 
    5650              :                                                                 // TODO FIXME HHHHHHHHH hier die Sortierungsroutine einbauen, um die attachten faces sicher richtig zu zu ordnen!!!
    5651              : 
    5652              :                                                                 for( auto const & ifac : assoFaces )
    5653              :                                                                 {
    5654              :                                                                         bool isFromFrac = false;
    5655              : 
    5656              :                                                                         for( auto const & facFrac : attFac )
    5657              :                                                                         {
    5658              :                                                                                 if( ifac == facFrac )
    5659              :                                                                                 {
    5660              :                                                                                         isFromFrac = true;
    5661              :                                                                                 }
    5662              :                                                                         }
    5663              : 
    5664              :                                                                         bool atRightSide = false;
    5665              : 
    5666              :                                                                         if( isFromFrac )
    5667              :                                                                                 atRightSide = true;
    5668              : 
    5669              :                                                                         if( !isFromFrac )
    5670              :                                                                         {
    5671              : 
    5672              :                                                                                 // check if on same side of edge where the normal points to: compute cosinus between vector of face center
    5673              :                                                                                 //  perpendicular to the edge
    5674              :                                                                                 // TODO FIXME
    5675              : 
    5676              :                                                                                 vector3 facCenter = CalculateCenter( ifac, aaPos );
    5677              : 
    5678              :                                                                                 vector3 perpendicu;
    5679              : 
    5680              :                                                                                 DropAPerpendicular(perpendicu, facCenter, aaPos[edgeOfFrac->vertex(0)], aaPos[edgeOfFrac->vertex(1)]);
    5681              : 
    5682              :                                                                                 vector3 tmpN;
    5683              : 
    5684              :                                                                                 VecSubtract(tmpN, facCenter, perpendicu );
    5685              : 
    5686              :                                                                                 VecNormalize(tmpN, tmpN);
    5687              : 
    5688              :                                                                                 UG_LOG("Normale Boundary zum Face ist " << tmpN << std::endl);
    5689              : 
    5690              :                                                                                 number cosBetwFracEdgAndDirection2Face = VecDot(tmpN, nrmEdg );
    5691              : 
    5692              :                                                                                 UG_LOG("Cosinus Boundary zur Normalen ist " << cosBetwFracEdgAndDirection2Face << std::endl);
    5693              : 
    5694              :                                                                                 if( cosBetwFracEdgAndDirection2Face > 0 )
    5695              :                                                                                 {
    5696              :                                                                                         UG_LOG("assuming boundary face to be on richt side" << std::endl);
    5697              : 
    5698              :                                                                                         atRightSide = true;
    5699              : 
    5700              : #if ESTABLISH_DEBUG_SUDOS
    5701              : 
    5702              :         //                                                                              IndexType suNu = sh.num_subsets();
    5703              : 
    5704              :                                                                                         Vertex * otherFacCent = *grid.create<RegularVertex>();
    5705              :                                                                                         aaPos[otherFacCent] = facCenter;
    5706              :                                                                                         sh.assign_subset(otherFacCent, sh.num_subsets() );
    5707              :                                                                                         // sh.assign_subset(otherFacCent, 5 );
    5708              : 
    5709              :                                                                                         Vertex * pp = *grid.create<RegularVertex>();
    5710              :                                                                                         aaPos[pp] = perpendicu;
    5711              :         //                                                                              sh.assign_subset(pp, 6 );
    5712              :                                                                                         sh.assign_subset(pp, sh.num_subsets() );
    5713              : 
    5714              :         //                                                                              sh.assign_subset(*iterFac,7);
    5715              :                                                                                         sh.assign_subset(*iterFac, sh.num_subsets() );
    5716              : #endif
    5717              : 
    5718              : 
    5719              :                                                                                 }
    5720              :                                                                                 else
    5721              :                                                                                 {
    5722              :                                                                                         UG_LOG("assuming boundary face to be on wrong side" << std::endl);
    5723              :                                                                                 }
    5724              : 
    5725              :                                                                         }
    5726              : 
    5727              :                                                                         if( atRightSide ) // atRightSide ) NOCH FALSCH TODO FIXME muss nur auf richtiger Seite sein
    5728              :                                                                         {
    5729              : 
    5730              : 
    5731              :                                                                                 vector<Vertex*>& newVrts4Fac = aaVrtVecFace[ ifac ];
    5732              : 
    5733              :                                                                                 IndexType vrtxFnd = 0;
    5734              : 
    5735              :                                                                                 for(size_t indVrt = 0; indVrt < (ifac)->num_vertices();  indVrt++ )
    5736              :                                                                                 {
    5737              :                                                                                         Vertex* facVrt = (ifac)->vertex(indVrt);
    5738              : 
    5739              :                                                                                         if(  facVrt == *iterV )
    5740              :                                                                                         {
    5741              :                                                                                                 newVrts4Fac[ indVrt ] = newShiftEdgVrtx;
    5742              :                                                                                                 vrtxFnd++;
    5743              :                                                                                         }
    5744              :                                                                                 }
    5745              : 
    5746              : 
    5747              : 
    5748              :                                                                                 if( vrtxFnd <= 0 )
    5749              :                                                                                 {
    5750              :                                                                                         UG_THROW("vertex not found bnd!" << std::endl);
    5751              :                                                                                 }
    5752              :                                                                                 else if( vrtxFnd > 1 )
    5753              :                                                                                 {
    5754              :                                                                                         UG_THROW("vertex zu oft gefunden bnd " << vrtxFnd << std::endl );
    5755              :                                                                                 }
    5756              :                                                                                 else if ( vrtxFnd == 1 )
    5757              :                                                                                 {
    5758              :         //                                                                                                              UG_LOG("vertex found abgeschlossen" << std::endl);
    5759              :                                                                                 }
    5760              :                                                                                 else
    5761              :                                                                                 {
    5762              :                                                                                         UG_THROW("vertex finden bnd komisch " << std::endl);
    5763              :                                                                                 }
    5764              :                                                                         }
    5765              :                                                                 }
    5766              : 
    5767              : #endif
    5768              :                                                         }
    5769              :                                                 }
    5770              :                                         }
    5771              :                                 }
    5772              :                                 else // sicher ordnungsbasiertes Arbeiten
    5773              :                                 {
    5774              : 
    5775            0 :                                         IndexType numbSegments = segments.size();
    5776              : 
    5777            0 :                                         if( numbSegments != 2 )
    5778            0 :                                                 UG_THROW("only two segments possible at boundary as long as only one ending fracture " << std::endl;)
    5779              : 
    5780              :                                         bool beforeFrac = true;
    5781              : 
    5782              :                                         IndexType segInd = 0;
    5783              : 
    5784              :                                         // TODO FIXME ausfuellen
    5785            0 :                                         for( VecVertexOfFaceInfo const & segPart : segments )
    5786              :                                         {
    5787              : 
    5788            0 :                                                 IndexType numbTriangs = segPart.size();
    5789              : 
    5790              :                                                 VertexOfFaceInfo const & vFISBegin = segPart[0];
    5791            0 :                                                 VertexOfFaceInfo const & vFISEnd = segPart[numbTriangs-1];
    5792              : 
    5793              :                                                 Face * fracFace = vFISEnd.getFace();
    5794              : 
    5795              :                                                 std::pair<Edge*, Edge* >  edgesBegin = vFISBegin.getEdge();
    5796              :                                                 std::pair<Edge*, Edge* >  edgesEnd = vFISEnd.getEdge();
    5797              : 
    5798              :                                                 std::pair<vector3, vector3> normalBegin = vFISBegin.getNormal();
    5799              :                                                 std::pair<vector3, vector3> normalEnd = vFISEnd.getNormal();
    5800              : 
    5801              :                                                 Edge* edgeBnd = edgesBegin.first;
    5802              :                                                 Edge* edgeFrac = edgesEnd.second;
    5803              : 
    5804              :                                                 vector3 normalBnd = normalBegin.first;
    5805              :                                                 vector3 normalFrac = normalEnd.second;
    5806              : 
    5807            0 :                                                 if( ! beforeFrac )
    5808              :                                                 {
    5809              :                                                         fracFace = vFISBegin.getFace();
    5810              : 
    5811              :                                                         edgeBnd = edgesEnd.second;
    5812              :                                                         edgeFrac = edgesBegin.first;
    5813              : 
    5814              :                                                         normalBnd = normalEnd.second;
    5815              :                                                         normalFrac = normalBegin.first;
    5816              :                                                 }
    5817              : 
    5818            0 :                                                 if( edgeBnd != adjBndEdgs[segInd] )
    5819            0 :                                                         UG_THROW("Boundary edge does not fit " << segInd << std::endl);
    5820              : 
    5821              : //                                              auto const & vft = vecVertFracTrip[segInd];
    5822              : //
    5823              : //                                              if( normalFrac != vft.getNormal())
    5824              : //                                                      UG_THROW("Normale nicht gegeben " << segInd << std::endl);
    5825              : //
    5826              : //                                              if( edgeFrac != vft.getEdge() )
    5827              : //                                                      UG_THROW("Kante nicht bekannt " << segInd << std::endl);
    5828              : //
    5829              : //                                              if( fracFace != vft.getFace() )
    5830              : //                                                      UG_THROW("Gesicht nicht bekannt " << segInd << std::endl);
    5831              : 
    5832              :                                                 // check if belonging to one vertFracTrip of bnd vrtx
    5833              : 
    5834              :                                                 IndexType fndNormal = 0;
    5835              :                                                 IndexType fndEdge = 0;
    5836              :                                                 IndexType fndFace = 0;
    5837              : 
    5838            0 :                                                 for( auto const & vft : vecVertFracTrip )
    5839              :                                                 {
    5840            0 :                                                         if( vft.getNormal() == normalFrac )
    5841            0 :                                                                 fndNormal++;
    5842              : 
    5843            0 :                                                         if( vft.getEdge() == edgeFrac )
    5844            0 :                                                                 fndEdge++;
    5845              : 
    5846            0 :                                                         if( vft.getFace() == fracFace )
    5847            0 :                                                                 fndFace++;
    5848              :                                                 }
    5849              : 
    5850            0 :                                                 if( fndNormal != 1 || fndEdge != 2 || fndFace != 1 )
    5851            0 :                                                         UG_THROW("Findungen komisch " << fndNormal << " " << fndEdge << " " << fndFace << std::endl);
    5852              : 
    5853            0 :                                                 auto subsIndFrac = sh.get_subset_index(edgeFrac);
    5854              : 
    5855              :                                                 // neue Punkte erzeugen
    5856              : 
    5857              :                                                 auto & bED = bndEdgeDirection[segInd];
    5858              : 
    5859              :                                                 // DEBUG ASSERT TEST static_assert( std::is_same< decltype( bED), vector3 & >::value );
    5860              : 
    5861              :                                                 vector3 & nrmEdg = normalFrac; //normalBnd;
    5862              : 
    5863              :                                                 Edge * edgeOfFrac = edgeFrac;
    5864              : 
    5865              :                                                 number cosinus = VecDot( nrmEdg, bED );
    5866              : 
    5867            0 :                                                 UG_LOG("BOUNDARY COSINUS between " << nrmEdg << " and " << bED << " -> " << cosinus << std::endl);
    5868              : 
    5869            0 :                                                 if( cosinus < 0 )
    5870              :                                                 {
    5871              :                                                         // andere Seite vermutet
    5872              : 
    5873            0 :                                                         UG_THROW("check if really on same side " << std::endl);
    5874              :                                                 }
    5875              : 
    5876              :                                                 // gleiche Seite muss es sein
    5877              : 
    5878              :                                                 // muessen wissen, wie lange das gestreckt werden soll
    5879              : 
    5880              :                                                 vector3 alongEdgV;
    5881              : 
    5882              :                                                 auto subsIndEdgOF = sh.get_subset_index(edgeOfFrac);
    5883              : 
    5884            0 :                                                 number width = fracInfosBySubset.at(subsIndEdgOF).width;
    5885              : 
    5886            0 :                                                 number scal = width / 2. / cosinus;
    5887              : 
    5888              :                                                 VecScale( alongEdgV, bED, scal );
    5889              : 
    5890              :                                                 vector3 posNewVrtOnBnd;
    5891              : 
    5892              :                                                 VecAdd(posNewVrtOnBnd, posOldVrt, alongEdgV );
    5893              : 
    5894            0 :                                                 UG_LOG("neuer Vertex Edge " << posNewVrtOnBnd << std::endl );
    5895              : 
    5896            0 :                                                 Vertex * newShiftEdgVrtx = *grid.create<RegularVertex>();
    5897              :                                                 aaPos[newShiftEdgVrtx] = posNewVrtOnBnd;
    5898              : 
    5899            0 :                                                 sh.assign_subset(newShiftEdgVrtx, subsIndEdgOF );
    5900              : 
    5901            0 :                                                 teachAssoFacesNewVrtx(  segPart, aaVrtVecFace, *iterV, newShiftEdgVrtx );
    5902              : 
    5903            0 :                                                 segInd++;
    5904              : 
    5905            0 :                                                 beforeFrac = ! beforeFrac; // more complicated eventual if more than one ending frac, but no topic so far
    5906              :                                         }
    5907              : 
    5908              :                                 }
    5909              : 
    5910              : //                              return true;
    5911              : 
    5912            0 :                         }
    5913              :                         else // fractures are crossing at boundary even
    5914              :                         {
    5915            0 :                                 UG_THROW("not implemented so far: multiple fractures crossing at boundary " << std::endl);
    5916              :                         }
    5917              : 
    5918              : 
    5919              :                         UG_LOG("END THIS BOUNDARY VERTEX" << std::endl);
    5920              :                 }
    5921              : 
    5922              :                 dbg_vertizesPassiert++;
    5923              : 
    5924              :         }
    5925              : 
    5926              : 
    5927              : //              // neue Vertizes in der Entfernung der Klüfte von den Klüften weg erzeugen,
    5928              : //              // basierend auf den Normalen multipliziert mit der halben Kluftdicke
    5929              : //              //für eine Kluft erstmal nur
    5930              : //              // die neuen Kanten und Faces erzeugen, die alten falschen Kanten löschen und ebenso die alten Faces
    5931              : //              // später auf mehr Klüfte ausdehnen, mit Problemstelle Kreuzung, aber erst, wenn eine Kluft funktioniert
    5932              : //
    5933              : 
    5934              : //      return true;
    5935              : 
    5936              :         // jetzt Seb Sachen beinahe unverändert
    5937              : 
    5938              :         ////////////////////////////////
    5939              :         //      create new elements
    5940              : 
    5941              :         //      first we create new edges from selected ones which are connected to
    5942              :         //      inner vertices. This allows to preserve old subsets.
    5943              :         //      Since we have to make sure that we use the right vertices,
    5944              :         //      we have to iterate over the selected faces and perform all actions on the edges
    5945              :         //      of those faces.
    5946            0 :         for(FaceIterator iter_sf = sel.faces_begin(); iter_sf != sel.faces_end(); ++iter_sf)
    5947              :         {
    5948              :                 Face* sf = *iter_sf;
    5949              :                 //      check for each edge whether it has to be copied.
    5950            0 :                 for(size_t i_edge = 0; i_edge < sf->num_edges(); ++i_edge)
    5951              :                 {
    5952            0 :                         Edge* e = grid.get_edge(sf, i_edge);
    5953              : 
    5954            0 :                         if(sel.is_selected(e))
    5955              :                         {
    5956              :                                 //      check the associated vertices through the volumes aaVrtVecVol attachment.
    5957              :                                 //      If at least one has an associated new vertex and if no edge between the
    5958              :                                 //      new vertices already exists, we'll create the new edge.
    5959              :                                 size_t ind0 = i_edge;
    5960            0 :                                 size_t ind1 = (i_edge + 1) % sf->num_edges();
    5961              : 
    5962            0 :                                 Vertex* nv0 = (aaVrtVecFace[sf])[ind0];
    5963            0 :                                 Vertex* nv1 = (aaVrtVecFace[sf])[ind1];
    5964              : 
    5965            0 :                                 if(nv0 || nv1)
    5966              :                                 {
    5967              :                                         //      if one vertex has no associated new one, then we use the vertex itself
    5968            0 :                                         if(!nv0)
    5969            0 :                                                 nv0 = sf->vertex(ind0);
    5970            0 :                                         if(!nv1)
    5971            0 :                                                 nv1 = sf->vertex(ind1);
    5972              : 
    5973              :                                         //      create the new edge if it not already exists.
    5974            0 :                                         if(!grid.get_edge(nv0, nv1))
    5975            0 :                                                 grid.create_by_cloning(e, EdgeDescriptor(nv0, nv1), e);
    5976              :                                 }
    5977              :                         }
    5978              :                 }
    5979              :         }
    5980              : 
    5981              : 
    5982              :         std::vector<Face * > newFaces;
    5983              :         std::vector<int> subsOfNewFaces;
    5984              : 
    5985              :         //      iterate over all surrounding faces and create new vertices.
    5986              :         //      Since faces are replaced on the fly, we have to take care with the iterator.
    5987            0 :         for(FaceIterator iter_sf = sel.faces_begin(); iter_sf != sel.faces_end();)
    5988              :         {
    5989              :                 Face* sf = *iter_sf;
    5990              :                 ++iter_sf;
    5991              : 
    5992            0 :                 std::vector<Vertex*> newVrts = aaVrtVecFace[sf];
    5993              : 
    5994              :                 //      all new vertices have been assigned to newVrts.
    5995              :                 //      Note that if newVrts[i] == NULL, then we have to take the
    5996              :                 //      old vertex sf->vertex(i).
    5997              :                 //      now expand the fracture edges of sf to faces.
    5998            0 :                 for(size_t i_vrt = 0; i_vrt < sf->num_vertices(); ++i_vrt)
    5999              :                 {
    6000              :                         size_t iv1 = i_vrt;
    6001            0 :                         size_t iv2 = (i_vrt + 1) % sf->num_vertices();
    6002              : 
    6003            0 :                         Edge* tEdge = grid.get_edge(sf->vertex(iv1), sf->vertex(iv2));
    6004              : 
    6005            0 :                         if(tEdge)
    6006              :                         {
    6007            0 :                                 if( aaMarkEdgeB[tEdge] )
    6008              :                                 {
    6009            0 :                                         Face* expFace = NULL;
    6010            0 :                                         if(newVrts[iv1] && newVrts[iv2])
    6011              :                                         {
    6012              :                                                 //      create a new quadrilateral
    6013            0 :                                                 expFace = *grid.create<Quadrilateral>(
    6014            0 :                                                                                 QuadrilateralDescriptor(sf->vertex(iv1), sf->vertex(iv2),
    6015              :                                                                                                                                 newVrts[iv2], newVrts[iv1]));
    6016              :                                         }
    6017            0 :                                         else if(newVrts[iv1])
    6018              :                                         {
    6019              :                                                         //      create a new triangle
    6020            0 :                                                 expFace = *grid.create<Triangle>(
    6021            0 :                                                                                 TriangleDescriptor(sf->vertex(iv1), sf->vertex(iv2), newVrts[iv1]));
    6022              :                                         }
    6023            0 :                                         else if(newVrts[iv2])
    6024              :                                         {
    6025              :                                                 //      create a new triangle
    6026            0 :                                                 expFace = *grid.create<Triangle>(
    6027            0 :                                                                                 TriangleDescriptor(sf->vertex(iv1), sf->vertex(iv2), newVrts[iv2]));
    6028              :                                         }
    6029              :                                         else
    6030              :                                         {
    6031              : 
    6032              : ////                                            sh.assign_subset(*iter_sf,10);
    6033              : ////                                            sh.assign_subset(tEdge,11);
    6034              : //
    6035              : //                                              return true;
    6036              : //                                              //      this code-block should never be entered. If it is entered then
    6037              : //                                              //      we selected the wrong faces. This is would be a BUG!!!
    6038              : //                                              //      remove the temporary attachments and throw an error
    6039              : //
    6040              : //                                              //      remove the temporary attachments
    6041              : //#if FORMER_PROMESH_FINITE_CLEFT_TECHNIQUE
    6042              : //                                              grid.detach_from_vertices(aAdjMarker);
    6043              : //                                              grid.detach_from_edges(aAdjMarker);
    6044              : //#endif
    6045              : //                                              grid.detach_from_vertices(aAdjMarkerVFP);
    6046              : //                                              grid.detach_from_edges(aAdjMarkerB);
    6047              : //
    6048              : //                                              grid.detach_from_vertices( aAdjInfoAVVFT );
    6049              : //                                              grid.detach_from_faces(attVrtVec);
    6050              : //
    6051              : //                                              grid.detach_from_vertices( aAdjInfoEdges );
    6052              : //                                              grid.detach_from_vertices( aAdjInfoFaces );
    6053              : //
    6054              : //
    6055              : //                                              // TODO FIXME auch die weiteren Marker und INfos, alle Attachments, detachen!!!!
    6056              : //
    6057              : //                                              throw(UGError("Implementation error in ExpandFractures2d Arte."));
    6058              :                                         }
    6059              : 
    6060              :                                         // TODO FIXME selektion closen irgendwie, damit auch alle Randkanten zum subset gehoeren!!!
    6061              : 
    6062            0 :                                         if( expFace )
    6063              :                                         {
    6064            0 :                                                 sh.assign_subset(expFace, fracInfosBySubset.at(sh.get_subset_index(tEdge)).newSubsetIndex);
    6065              : 
    6066            0 :                                                 int subs = fracInfosBySubset.at(sh.get_subset_index(tEdge)).newSubsetIndex;
    6067              : 
    6068            0 :                                                 subsOfNewFaces.push_back( subs );
    6069              : 
    6070            0 :                                                 newFaces.push_back( expFace );
    6071              :                                         }
    6072              :                                 }
    6073              :                         }
    6074              :                 }
    6075              : 
    6076              : 
    6077              : 
    6078              : 
    6079              :                 //      now set up a new face descriptor and replace the face.
    6080            0 :                 if(fd.num_vertices() != sf->num_vertices())
    6081            0 :                         fd.set_num_vertices(sf->num_vertices());
    6082              : 
    6083            0 :                 for(size_t i_vrt = 0; i_vrt < sf->num_vertices(); ++i_vrt)
    6084              :                 {
    6085            0 :                         if(newVrts[i_vrt])
    6086            0 :                                 fd.set_vertex(i_vrt, newVrts[i_vrt]);
    6087              :                         else
    6088            0 :                                 fd.set_vertex(i_vrt, sf->vertex(i_vrt));
    6089              :                 }
    6090              : 
    6091            0 :                 grid.create_by_cloning(sf, fd, sf);
    6092            0 :                 grid.erase(sf);
    6093            0 :         }
    6094              : 
    6095              :         //      we have to clean up unused edges.
    6096              :         //      All selected edges with mark 0 have to be deleted.
    6097            0 :         for(EdgeIterator iter = sel.edges_begin(); iter != sel.edges_end();)
    6098              :         {
    6099              :                 //      be careful with the iterator
    6100              :                 Edge* e = *iter;
    6101              :                 ++iter;
    6102              : 
    6103            0 :                 if(!aaMarkEdgeB[e])
    6104            0 :                         grid.erase(e);
    6105              :         }
    6106              : 
    6107            0 :         if( subsOfNewFaces.size() != newFaces.size() )
    6108              :         {
    6109            0 :                 UG_THROW("andere zahl neue faces als subdoms " << std::endl);
    6110              :         }
    6111              : 
    6112              :         IndexType nfn = 0;
    6113              : 
    6114            0 :         for( auto const & nf : newFaces )
    6115              :         {
    6116            0 :                 for(size_t i_edge = 0; i_edge < nf->num_edges(); ++i_edge)
    6117              :                 {
    6118            0 :                         Edge* edg = grid.get_edge(nf, i_edge);
    6119              : 
    6120            0 :                         sh.assign_subset( edg, subsOfNewFaces[nfn] );
    6121              : 
    6122              :                 }
    6123              : 
    6124            0 :                 for( size_t iVrt = 0; iVrt < nf->num_vertices(); iVrt++ )
    6125              :                 {
    6126            0 :                         Vertex * vrt = nf->vertex(iVrt);
    6127              : 
    6128            0 :                         sh.assign_subset( vrt, subsOfNewFaces[nfn] );
    6129              :                 }
    6130              : 
    6131            0 :                 nfn++;
    6132              :         }
    6133              : 
    6134              :         // sollen die Boundary Edges zur boundary gehören, oder zur Kluft?
    6135              :         // wie ist es mit den Knoten, sind die alle richtig zugewiesen bezüglich subset?
    6136              : 
    6137              :         // jetzt muss noch der Diamant erzeugt werden
    6138              :         // Ziel: KluftInnen erzeugen
    6139              : 
    6140              : 
    6141              :         //      remove the temporary attachments
    6142              : 
    6143              : #if FORMER_PROMESH_FINITE_CLEFT_TECHNIQUE
    6144              :         grid.detach_from_vertices(aAdjMarker);
    6145              :         grid.detach_from_edges(aAdjMarker);
    6146              : #endif
    6147              : //      grid.detach_from_vertices(aAdjMarkerVFP);
    6148              : //      grid.detach_from_edges(aAdjMarkerB);
    6149              : //
    6150              : //      grid.detach_from_vertices( aAdjInfoAVVFT );
    6151              : //      grid.detach_from_faces(attVrtVec);
    6152              : //
    6153              : //      grid.detach_from_vertices( aAdjInfoEdges );
    6154              : //      grid.detach_from_vertices(aAdjInfoFaces );
    6155              : 
    6156              : 
    6157              :         grid.detach_from_vertices(aAdjMarkerVFP );
    6158              :         grid.detach_from_edges(aAdjMarkerB);
    6159              :         grid.detach_from_vertices( aAdjInfoAVVFT  );
    6160              :         grid.detach_from_vertices( aAdjInfoEdges );
    6161              :         grid.detach_from_vertices( aAdjInfoFaces );
    6162              :         grid.detach_from_faces(attVrtVec);
    6163              :         grid.detach_from_vertices( aAdjInfoVVEVM );
    6164              : 
    6165              : //      sel.clear();
    6166              : 
    6167              : //      return true;
    6168              : 
    6169              :         // only Keile, basic system
    6170            0 :         if( ! establishDiamonds )
    6171              :                 return true;
    6172              : 
    6173              :         //  alles detachen, was noch attached ist, da ist einiges hinzu gekommen!
    6174              : 
    6175              : 
    6176              :         // Keilstruktur entfernen und durch den gewünschten Diamanten ersetzen
    6177              : 
    6178              :         // new vertices which divide the fracture edges
    6179              : 
    6180              : //      AVertex aAdjVert; // used to know if an edge is frac edge and in the old faces
    6181              : //      grid.attach_to_edges_dv( aAdjVert, nullptr );
    6182              : //      grid.attach_to_faces_dv( aAdjVert, nullptr );
    6183              : //      Grid::EdgeAttachmentAccessor<AVertex> aaEdgeVert( grid, aAdjVert );
    6184              : //      Grid::FaceAttachmentAccessor<AVertex> aaFaceVert( grid, aAdjVert );
    6185              : 
    6186            0 :         for( auto const & cfi : vecCrossVrtInf )
    6187              :         {
    6188              : 
    6189              : //              IndexType nuCroFra =  cfi.getNumbCrossFracs();
    6190              :                 CrossVertInf::FracTyp fracTyp =  cfi.getFracTyp();
    6191              : 
    6192            0 :                 if( fracTyp == CrossVertInf::SingleFrac )
    6193            0 :                         continue;
    6194              : 
    6195            0 :                 Vertex * crossPt = cfi.getCrossVertex();
    6196              : 
    6197              :                 std::vector<Vertex * > shiftVrtcs = cfi.getVecShiftedVrts();
    6198              : 
    6199              : //              IndexType shiffsOrig = shiftVrtcs.size();
    6200              : //
    6201              : //              auto soc = shiffsOrig;
    6202              : 
    6203              :                 VecEdge origFracEdg; // = cfi.getVecOrigFracEdges();
    6204              : 
    6205              :                 // all edges associated to the crossing point
    6206              :                 VecEdge allAssoEdgCP;
    6207              : 
    6208            0 :                 for( std::vector<Edge *>::iterator iterEdg = grid.associated_edges_begin(crossPt); iterEdg != grid.associated_edges_end(crossPt); iterEdg++ )
    6209              :                 {
    6210              : 
    6211            0 :                         allAssoEdgCP.push_back(*iterEdg);
    6212              : 
    6213              :                         bool hasShiftedVrtx = false;
    6214              : 
    6215            0 :                         for( IndexType i = 0; i < 2; i++ )
    6216              :                         {
    6217            0 :                                 Vertex * side = (*iterEdg)->vertex(i);
    6218              : 
    6219            0 :                                 for( auto const & vrt : shiftVrtcs )
    6220              :                                 {
    6221            0 :                                         if( side == vrt )
    6222              :                                                 hasShiftedVrtx = true;
    6223              :                                 }
    6224              : 
    6225              :                         }
    6226              : 
    6227            0 :                         if( ! hasShiftedVrtx )
    6228            0 :                                 origFracEdg.push_back(*iterEdg);
    6229              :                 }
    6230              : 
    6231              : 
    6232              : //              UG_LOG("Shift Vectors Orig " <<  soc << std::endl);
    6233              : 
    6234              : //              // aim: old cross vertex first, shift vertex second, new established vertex third
    6235              : //              using VrtxPair = std::pair<Vertex*, Vertex*>;
    6236              : //
    6237              : //              using DiamondVertexInfo = VertexFractureTriple<Edge*, Face*, Vertex *>;
    6238              : //
    6239              : //              using VecDiamondVertexInfo = std::vector<DiamondVertexInfo>;
    6240              : //
    6241              : //              VecDiamondVertexInfo vecDiamVrtInfo;
    6242              : 
    6243              :                 // need to know the subsets of all faces!
    6244              :                 std::vector<IndexType> subdomList;
    6245              : 
    6246              :                 // all faces associated to the crossing point
    6247              :                 std::vector<Face *> assoFacCross;
    6248              : 
    6249            0 :                 for( std::vector<Face *>::iterator iterFac = grid.associated_faces_begin(crossPt); iterFac != grid.associated_faces_end(crossPt); iterFac++ )
    6250              :                 {
    6251            0 :                         assoFacCross.push_back(*iterFac);
    6252              : 
    6253              :                         bool sudoAlreadyThere = false;
    6254              : 
    6255            0 :                         IndexType sudo = sh.get_subset_index(*iterFac);
    6256              : 
    6257            0 :                         for( auto sl : subdomList )
    6258              :                         {
    6259            0 :                                 if( sl == sudo )
    6260              :                                         sudoAlreadyThere = true;
    6261              :                         }
    6262              : 
    6263            0 :                         if( !sudoAlreadyThere )
    6264            0 :                                 subdomList.push_back(sudo);
    6265              :                 }
    6266              : 
    6267            0 :                 if( subdomList.size() != 2 )
    6268            0 :                         UG_THROW("wieviele Subdoms um Kreuz herum?         " << subdomList.size() << std::endl );
    6269              : 
    6270              : 
    6271              :                 // finales Ziel: alle neuen faces entfernen, die an den Schnittknoten anhängen
    6272              :                 // ein Test noch
    6273              : 
    6274            0 :                 for( auto const & afc : assoFacCross )
    6275              :                 {
    6276              :                         // figure out respective original frac edge, need to know all edges and all vertices of this fracture
    6277              : 
    6278              :                         // was sind die Ecken und Kanten dieses Faces? welche Ecke davon ist die originale Fracture edge?
    6279              :                         // was ist die subdomain der originalen Fracture edge? klar das ist die subdomain des faces
    6280              : 
    6281            0 :                         auto subdom = sh.get_subset_index(afc);
    6282              : 
    6283              :                         bool subdomFnd = false;
    6284              : 
    6285            0 :                         for( auto const & sd : subdomList )
    6286              :                         {
    6287            0 :                                 if( subdom == sd )
    6288              :                                         subdomFnd = true;
    6289              :                         }
    6290              : 
    6291            0 :                         if( ! subdomFnd )
    6292            0 :                                 UG_THROW("SUBDOM NOT found" << std::endl);
    6293              : 
    6294              : //                              for( auto const &  )
    6295              : //                              AssociatedEdgeIterator associated_edges_begin(Face* face);///< DO NOT INVOKE! Subject to change.
    6296              : //                                              AssociatedEdgeIterator associated_edges_end(Face* face);///
    6297              : 
    6298              : //                              std::vector<Edge*> edgesThisFac;
    6299              : //
    6300              : //                              for( std::vector<Edge *>::iterator iterEdgF = grid.associated_edges_begin(afc);
    6301              : //                                              iterEdgF != grid.associated_edges_end(afc); iterEdgF++ )
    6302              : //                              {
    6303              : //                                      edgesThisFac.push_back(*iterEdgF);
    6304              : //                              }
    6305              : 
    6306              : 
    6307              :                 }
    6308              : 
    6309              : //              //                      for( auto const & edg : origFracEdg )
    6310              : //                                      for( auto edg : origFracEdg )
    6311              : //                                      {
    6312              : //
    6313              : //                                              // DEBUG ASSERT TEST static_assert( std::is_same< decltype( edg ), Edge * >::value  );
    6314              : //              //                              // DEBUG ASSERT TEST static_assert( std::is_same< const_cast<Edge*>(decltype( edg )), Edge * >::value  );
    6315              : //
    6316              : //              //                              //Vertex* vrtSpliEd =
    6317              : //              //                              if( edg != nullptr )
    6318              : //              //                              SplitEdge<Vertex>( grid, static_cast<Edge*>(edg) );
    6319              : //              ////                            else
    6320              : //              ////                                    UG_LOG("Nullptr getroffen " << std::endl);
    6321              : //              //
    6322              : //              ////                            size_t numSubs = sh.num_subsets();
    6323              : //              ////
    6324              : //              ////                            sh.assign_subset(edg, numSubs );
    6325              : //              //
    6326              : //              //                              //SplitEdge
    6327              : //              //
    6328              : //              //                              return true;
    6329              : //
    6330              : //                                      }
    6331              : 
    6332              : 
    6333              : 
    6334              : 
    6335              :                 // different Vorgehensweisen for T End and X Cross
    6336              : 
    6337              : //              using ExpandCrossFracInfo = VertexFractureTriple< std::pair<Edge*, Edge*>, Face*, std::pair<Vertex*, Vertex*> >;
    6338              : //              // Vertex nullptr wo original fracture, und shift vertex, wo Keilecke, die weg soll
    6339              : //
    6340              : //              using VecExpandCrossFracInfo = std::vector<ExpandCrossFracInfo>;
    6341              : 
    6342              :                 Edge * avoidToDeleteEdge = nullptr;
    6343              : 
    6344              :                 VecExpandCrossFracInfo vecExpCrossFI;
    6345              : 
    6346              :                 //              if( nuCroFra == 3 )
    6347            0 :                 if( fracTyp == CrossVertInf::TEnd )
    6348              :                 {
    6349              : 
    6350            0 :                         std::vector<std::pair<Vertex*,bool>> shiftVertcsWithTI = cfi.getVecShiftedVrtsWithTypInfo();
    6351              : 
    6352              :                         // test if the vertex vector is the same as the vertex vector without info
    6353              : 
    6354            0 :                         if( shiftVertcsWithTI.size() != shiftVrtcs.size() )
    6355            0 :                                 UG_THROW("Unterschiedlich grosse shift vertices " << shiftVertcsWithTI.size() << " != " << shiftVrtcs.size()  << std::endl);
    6356              : 
    6357            0 :                         for( IndexType i = 0; i < shiftVertcsWithTI.size(); i++ )
    6358              :                         {
    6359            0 :                                 if( shiftVertcsWithTI[i].first != shiftVrtcs[i]  )
    6360            0 :                                         UG_THROW("komische Shift vertizes" << std::endl);
    6361              :                         }
    6362              : 
    6363              :                         // aim: sorting faces
    6364            0 :                         auto assoFacTEndCop = assoFacCross;
    6365              : 
    6366              :                         // figure out that shift vertex that is at the T End
    6367              : 
    6368              :                         // start at defined face or edge
    6369              :                         // start sorted faces at one of the faces which belong to the T End , i.e. that side where no fracture sorts
    6370              :                         // figure out the corresponding index
    6371              : 
    6372              :                         int indxFrcWithTE = -1;
    6373              :                         IndexType indxFnd = 0;
    6374              :                         IndexType startEdgeFnd = 0;
    6375              :                         IndexType endEdgFnd = 0;
    6376              : 
    6377              :                         IndexType cntr = 0;
    6378              : 
    6379              :                         // muss sofort festgelegt werden - Startecke und zweite Ecke des gewählten faces
    6380              :                         Edge * shiftVrtxAtFirstFacEdg = nullptr;
    6381              :                         Edge * fracVrtxAtFirstFacEdg = nullptr;
    6382              : 
    6383              :                         Vertex * shiftVrtxAtFreeEnd = nullptr;
    6384              : 
    6385            0 :                         for( auto const & aft : assoFacTEndCop )
    6386              :                         {
    6387            0 :                                 for( auto const & svwi : shiftVertcsWithTI )
    6388              :                                 {
    6389            0 :                                         if( svwi.second == true )
    6390              :                                         {
    6391              : 
    6392            0 :                                                 shiftVrtxAtFreeEnd = svwi.first;
    6393              : 
    6394              : //                                              if( FaceContains(aft, svwi.first ) )
    6395            0 :                                                 if( FaceContains(aft, shiftVrtxAtFreeEnd ) )
    6396              :                                                 {
    6397            0 :                                                         indxFrcWithTE = cntr;
    6398            0 :                                                         indxFnd++;
    6399              : 
    6400            0 :                                                         for( std::vector<Edge *>::iterator iterEdgF = grid.associated_edges_begin(aft);
    6401            0 :                                                                         iterEdgF != grid.associated_edges_end(aft); iterEdgF++ )
    6402              :                                                         {
    6403              : 
    6404              : //                                                              bool edgCntsShiVe = EdgeContains(*iterEdgF, svwi.first);
    6405            0 :                                                                 bool edgCntsShiVe = EdgeContains(*iterEdgF, shiftVrtxAtFreeEnd);
    6406            0 :                                                                 bool edgCntsCrsPt = EdgeContains(*iterEdgF,crossPt);
    6407              : 
    6408              : //                                                              if( EdgeContains(*iterEdgF, svwi.first) && EdgeContains(*iterEdgF,crossPt) )
    6409            0 :                                                                 if( edgCntsShiVe && edgCntsCrsPt )
    6410              :                                                                 {
    6411            0 :                                                                         shiftVrtxAtFirstFacEdg = *iterEdgF;
    6412            0 :                                                                         startEdgeFnd++;
    6413              :                                                                 }
    6414            0 :                                                                 else if( edgCntsCrsPt && ! edgCntsShiVe )
    6415              :                                                                 {
    6416            0 :                                                                         fracVrtxAtFirstFacEdg = *iterEdgF;
    6417            0 :                                                                         endEdgFnd++;
    6418              :                                                                 }
    6419              :                                                         }
    6420              : 
    6421              :                                                 }
    6422              :                                         }
    6423              :                                 }
    6424              : 
    6425            0 :                                 cntr++;
    6426              :                         }
    6427              : 
    6428              :                         // we hit twice, and finally take the second one, as we also want to count
    6429              : 
    6430            0 :                         if( indxFrcWithTE < 0 || indxFrcWithTE >=  assoFacTEndCop.size() )
    6431            0 :                                 UG_THROW("Start nicht gefunden, freies Ende verloren " << std::endl);
    6432              : 
    6433            0 :                         if( indxFnd != 2 || startEdgeFnd != 2 || endEdgFnd != 2 )
    6434            0 :                                 UG_THROW("Index Free point or edge not found correct number " << indxFnd << " " << startEdgeFnd << " " << endEdgFnd << std::endl);
    6435              : 
    6436            0 :                         Edge * firstEdgeFac = shiftVrtxAtFirstFacEdg;
    6437            0 :                         Edge * secondEdgeFac = fracVrtxAtFirstFacEdg;
    6438              : 
    6439            0 :                         if( firstEdgeFac == nullptr || secondEdgeFac == nullptr )
    6440            0 :                                 UG_THROW("nullecke am Anfang?" << std::endl);
    6441              : 
    6442            0 :                         Face * assoFacTEndConsider = assoFacTEndCop[ indxFrcWithTE ];
    6443              : 
    6444            0 :                         if( ! FaceContains(assoFacTEndConsider, firstEdgeFac ))
    6445            0 :                                 UG_THROW("Ecke verloren geangen T " << std::endl);
    6446              : 
    6447              : //                      bool atStartSort = true;
    6448              : 
    6449              :                         // already fixed in contrast to XCross case!
    6450            0 :                         Edge * assoFacEdgBeg2Fix = firstEdgeFac;
    6451              : 
    6452              :                         // soll erst ganz am Schluss festgelegt werden
    6453            0 :                         Edge * assoFacEdgEnd2Fix = nullptr;
    6454              : 
    6455            0 :                         if( ! SortFaces4DiamondCreation( sh, assoFacTEndCop, firstEdgeFac, secondEdgeFac,
    6456              :                                         assoFacTEndConsider, origFracEdg, shiftVrtcs,
    6457              :                                         crossPt, assoFacEdgBeg2Fix, assoFacEdgEnd2Fix, grid, vecExpCrossFI
    6458              :                                         , false
    6459              :                                 )
    6460              :                         )
    6461            0 :                                 UG_THROW("Ordnen Diamant TEnd schief gegangen " << std::endl);
    6462              : 
    6463              :                         UG_LOG("Kreis des Diamanten T End Fall geschlossen " << std::endl);
    6464              : 
    6465              : //                      for( auto const & ecf : vecExpCrossFI )
    6466              : //                      {
    6467              : //                              Face * fac = ecf.getFace();
    6468              : //
    6469              : //                              IndexType sudos = sh.num_subsets();
    6470              : //
    6471              : //                              sh.assign_subset(fac,sudos);
    6472              : //                      }
    6473              : 
    6474              :                         // erfuellt, aber keine so gute Idee
    6475              :                         // im Falle von gekrümmten Fractures:
    6476              :                         // first shift the free end shift vertex along prolongation of T End incoming edge, else later problematic
    6477              : 
    6478              : 
    6479              : 
    6480              : #if 0
    6481              :                         IndexType faceOrderNumber = 0;
    6482              : 
    6483              :                         // TODO FIXME hier muss die FUnkiton verwendet und angepasst werden!
    6484              :                         while( assoFacTEndCop.size() != 0 )
    6485              :                         {
    6486              :                                 Edge * fracEdge = nullptr;
    6487              :                                 Edge * shiftVrtxEdg = nullptr;
    6488              : 
    6489              :                                 std::vector<Edge*> edgesThisFac;
    6490              : 
    6491              :                                 edgesThisFac.clear();
    6492              : 
    6493              :                                 for( std::vector<Edge *>::iterator iterEdgF = grid.associated_edges_begin(assoFacTConsider);
    6494              :                                                 iterEdgF != grid.associated_edges_end(assoFacTConsider); iterEdgF++ )
    6495              :                                 {
    6496              :                                         edgesThisFac.push_back(*iterEdgF);
    6497              :                                 }
    6498              : 
    6499              :                                 if( ! atStartSort )
    6500              :                                 {
    6501              :                                         secondEdgeFac = nullptr;
    6502              :                                 }
    6503              : 
    6504              :                                 IndexType fndFracEdg = 0;
    6505              : 
    6506              :                                 for( auto const & etf : edgesThisFac )
    6507              :                                 {
    6508              :                                         for( auto const & ofe : origFracEdg )
    6509              :                                         {
    6510              :                                                 if( etf == ofe )
    6511              :                                                 {
    6512              :                                                         fndFracEdg++;
    6513              :                                                         fracEdge = etf;
    6514              :                                                 }
    6515              :                                         }
    6516              :                                 }
    6517              : 
    6518              :                                 if( fracEdge == nullptr || fndFracEdg != 1 )
    6519              :                                 {
    6520              :                                         UG_LOG("Frac Orig Ecke nicht gefunden oder falsche Zahl " << fndFracEdg << std::endl );
    6521              : //                                      return false;
    6522              :                                         UG_THROW("Frac Orig Ecke nicht gefunden oder falsche Zahl " << fndFracEdg << std::endl );
    6523              :                                 }
    6524              : 
    6525              :                                 // find expanded shift vertex
    6526              : 
    6527              :                                 Vertex * shiftVrtxFound = nullptr;
    6528              :                                 IndexType fndVrt = 0;
    6529              :                                 IndexType helpVarEdges = 0;
    6530              : 
    6531              :                                 bool isAtFreeSideShiVe = false;
    6532              : 
    6533              :                                 for( auto const & etf : edgesThisFac )
    6534              :                                 {
    6535              :                                         if( helpVarEdges >= edgesThisFac.size() )
    6536              :                                         {
    6537              :                                                 UG_LOG("Indexueberschreitung Edges" << std::endl);
    6538              :                                                 break;
    6539              :                                         }
    6540              : 
    6541              :                                         helpVarEdges++;
    6542              : 
    6543              :                                         IndexType helpShiVaNum = 0;
    6544              : 
    6545              :                                         for( auto const & svwi : shiftVertcsWithTI )
    6546              :                                         {
    6547              :                                                 Vertex * sv = svwi.first;
    6548              : 
    6549              :                                                 if( helpShiVaNum >= shiftVrtcs.size() )
    6550              :                                                 {
    6551              :                                                         UG_LOG("Shift Vertex Index Verletzung T " << std::endl);
    6552              :                                                         break;
    6553              :                                                 }
    6554              : 
    6555              :                                                 helpShiVaNum++;
    6556              : 
    6557              : //                                              for( IndexType i = 0; i < 2; i++ )
    6558              : //                                              {
    6559              : //                                                      if( etf->vertex(i) == crossPt && etf->vertex((i+1)%2) == sv )
    6560              : //                                                      {
    6561              : //                                                              shiftVrtxFound = sv;
    6562              : //                                                              fndVrt++;
    6563              : //                                                              shiftVrtxEdg = etf;
    6564              : //
    6565              : //                                                      }
    6566              : //                                              }
    6567              : 
    6568              :                                                 // TODO FIXME expand this construct also to X Cross, so far loop
    6569              :                                                 if( EdgeContains(etf, crossPt ) && EdgeContains( etf, sv ) )
    6570              :                                                 {
    6571              :                                                         shiftVrtxFound = sv;
    6572              :                                                         fndVrt++;
    6573              :                                                         shiftVrtxEdg = etf;
    6574              : 
    6575              :                                                         isAtFreeSideShiVe = svwi.second;
    6576              :                                                 }
    6577              :                                         }
    6578              :                                 }
    6579              : 
    6580              :                                 if( fndVrt != 1 || shiftVrtxFound == nullptr || shiftVrtxEdg == nullptr )
    6581              :                                 {
    6582              :                                         UG_LOG("shift vertex komische Zahl oder null T " << fndVrt << std::endl);
    6583              : //                                      return false;
    6584              :                                         UG_THROW("shift vertex komische Zahl oder null T " << fndVrt << std::endl);
    6585              :                                 }
    6586              : 
    6587              : 
    6588              :                                 Vertex * firstVrt = shiftVrtxFound;
    6589              :                                 Vertex * secondVrt = nullptr;
    6590              : 
    6591              :                                 if( atStartSort )
    6592              :                                 {
    6593              : 
    6594              :                                         if( fracEdge != secondEdgeFac || shiftVrtxEdg != firstEdgeFac )
    6595              :                                                 UG_THROW("ALler Anfang ist schwer " << std::endl);
    6596              : 
    6597              :                                         atStartSort = false;
    6598              :                                 }
    6599              :                                 else
    6600              :                                 {
    6601              :                                         bool setShftVrtFirst = false;
    6602              : //                                      bool boundAtShiftVrtEdg = true; TODO FIXME ist das global am Anfang vom while loop setzbar wie im anderen Fall?
    6603              : 
    6604              :                                         // TODO FIXME erfuellt durch den Wechsel, sowieso die Funktion anpassen oben
    6605              : //                                      switch ( faceOrderNumber )
    6606              : //                                      {
    6607              : //                                              case 2:
    6608              : //                                                      setShftVrtFirst = false;
    6609              : //                                                      break;
    6610              : //                                              case 3:
    6611              : //                                                      setShftVrtFirst = true;
    6612              : //                                                      break;
    6613              : //                                              case 4:
    6614              : //                                                      break;
    6615              : //                                              case 5:
    6616              : //                                                      break;
    6617              : //                                              default:
    6618              : //                                                      UG_THROW("zu grosse Ordnungsnummer " << std::endl);
    6619              : //                                                      break;
    6620              : //                                      }
    6621              : 
    6622              :                                         if( setShftVrtFirst )
    6623              :                                         {
    6624              : 
    6625              :                                         }
    6626              :                                         else
    6627              :                                         {
    6628              : 
    6629              :                                         }
    6630              : 
    6631              : //                                      firstEdgeFac = fracEdge;
    6632              : //                                      secondEdgeFac = shiftVrtxEdg;
    6633              : 
    6634              : 
    6635              : //                                      if( isAtFreeSideShiVe ) // obviously not at start
    6636              : //                                      {
    6637              : //
    6638              : //                                              firstEdgeFac = fracEdge;
    6639              : //                                              secondEdgeFac = shiftVrtxEdg;
    6640              : //
    6641              : //                                      }
    6642              : //                                              firstEdgeFac = shiftVrtxEdg;
    6643              : //                                              secondEdgeFac = fracEdge;
    6644              : //
    6645              : //                                              firstVrt = shiftVrtxFound;
    6646              : //                                              secondVrt = nullptr;
    6647              : //                                      }
    6648              : //
    6649              :         //                              UG_LOG("Debug Paarbildung   " << std::endl);
    6650              : 
    6651              : 
    6652              : 
    6653              :                                 }
    6654              : 
    6655              : //                              std::pair<Edge*, Edge*> edgesFac( firstEdgeFac, secondEdgeFac );
    6656              : //
    6657              : //                              std::pair<Vertex*,Vertex*> vrtcsSF( firstVrt, secondVrt );
    6658              : //                              ExpandCrossFracInfo startFacInf( edgesFac, assoFacConsider, vrtcsSF );
    6659              : 
    6660              : 
    6661              :                                 faceOrderNumber++;
    6662              : 
    6663              :                         }
    6664              : 
    6665              : #endif
    6666              : 
    6667              :                         // create new vertex
    6668              : 
    6669              :                         // for the ending frac region, the same algorithm applies as for the X Cross in all 4 branches
    6670              :                         // for the free end, no new vertex, but new vertices along the durchgehende fracture
    6671              :                         // repectively along the original edges of the durchgehende fracture
    6672              : 
    6673              : 
    6674              : 
    6675            0 :                         IndexType sizeECF = vecExpCrossFI.size();
    6676              : 
    6677            0 :                         if( sizeECF != 6 )
    6678            0 :                                 UG_THROW("Momische Länge TEnd " << std::endl);
    6679              : 
    6680            0 :                         for( IndexType i = 0; i < sizeECF; i = i + 2 )
    6681              :                         {
    6682            0 :                                 if( vecExpCrossFI[i].getNormal().first !=  vecExpCrossFI[(i+sizeECF-1) % sizeECF].getNormal().second  )
    6683            0 :                                         UG_THROW("Kleberei TEnd schief gegangen " << std::endl);
    6684              :                         }
    6685              : //
    6686              : //                      // new vertex between face 0 and 1 and between face 4 and 5
    6687              : //
    6688              : //                      // first those along the passing fracture
    6689              : //
    6690              : ////                    ExpandCrossFracInfo & alongFreeEndStartF = vecExpCrossFI[0];
    6691              : ////                    ExpandCrossFracInfo & closeToEndingCleftBeginF = vecExpCrossFI[1];
    6692              : ////                    ExpandCrossFracInfo & endingCleftBeginF = vecExpCrossFI[2];
    6693              : ////                    ExpandCrossFracInfo & endingCleftEndF = vecExpCrossFI[3];
    6694              : ////                    ExpandCrossFracInfo & closeToEndingCleftEndF = vecExpCrossFI[4];
    6695              : ////                    ExpandCrossFracInfo & alongFreeEndEndF = vecExpCrossFI[5];
    6696              : ////
    6697              : ////                    Vertex * remainVrtx = alongFreeEndStartF.getNormal().first;
    6698              : ////                    Vertex * shiftVrtxOne = closeToEndingCleftBeginF.getNormal().second;
    6699              : ////                    Vertex * shiftVrtxTwo = endingCleftEndF.getNomal().first;
    6700              : ////
    6701              : ////                    vector3 posVRem = aaPos[remainVrtx];
    6702              : ////                    vector3 posVOne = aaPos[shiftVrtxOne];
    6703              : ////                    vector3 posVTwo = aaPos[shiftVrtxTwo];
    6704              : ////
    6705              : ////                    vector3 distOne;
    6706              : ////                    VecSubtract(distOne, posVOne, posVRem);
    6707              : ////
    6708              : ////                    vector3 distTwo;
    6709              : ////                    VecSubtract(distTwo, posVTwo, posVRem);
    6710              : ////
    6711              : ////                    vector3 distOneHalf, distTwoHalf;
    6712              : ////                    VecScale(distOneHalf, distOne, 0.5 );
    6713              : ////                    VecScale(distTwoHalf, distTwo, 0.5 );
    6714              : ////
    6715              : ////                    vector3 posNewVrtOne, posNewVrtTwo;
    6716              : ////                    VecAdd(posNewVrtOne, posVRem, distOneHalf);
    6717              : ////                    VecAdd(posNewVrtTwo, posVRem, distTwoHalf);
    6718              : ////
    6719              : ////                    Vertex * newVrtOne = *grid.create<RegularVertex>();
    6720              : ////                    Vertex * newVrtTwo = *grid.create<RegularVertex>();
    6721              : ////
    6722              : ////                    aaPos[newVrtOne] = posNewVrtOne;
    6723              : ////                    aaPos[newVrtTwo] = posNewVrtTwo;
    6724              : ////
    6725              : ////                    IndexType sudoTEnd = sh.num_subsets();
    6726              : ////
    6727              : ////                    sh.assign_subset(newVrtOne, sudoTEnd);
    6728              : ////                    sh.assign_subset(newVrtTwo, sudoTEnd);
    6729              : ////
    6730              : ////
    6731              : ////                    std::pair<Vertex*,Vertex*>  vrtcsAlongFreeEndStartF = alongFreeEndStartF.getNormal();
    6732              : ////                    std::pair<Vertex*,Vertex*>  vrtcsCloseToEndingCleftBeginF = closeToEndingCleftBeginF.getNormal();
    6733              : ////                    std::pair<Vertex*,Vertex*>  vrtcsEndingCleftBeginF = endingCleftBeginF.getNormal();
    6734              : ////                    std::pair<Vertex*,Vertex*>  vrtcsEndingCleftEndF = endingCleftEndF.getNormal();
    6735              : ////                    std::pair<Vertex*,Vertex*>  vrtcsCloseToEndingCleftEndF = closeToEndingCleftEndF.getNormal();
    6736              : ////                    std::pair<Vertex*,Vertex*>  vrtcsAlongFreeEndEndF = alongFreeEndEndF.getNormal();
    6737              : ////
    6738              : ////
    6739              : ////                    alongFreeEndStartF.setNewNormal( vrtcsAlongFreeEndStartF );
    6740              : ////                    closeToEndingCleftBeginF.setNewNormal( vrtcsCloseToEndingCleftBeginF );
    6741              : ////                    endingCleftBeginF.setNewNormal( vrtcsEndingCleftBeginF );
    6742              : ////                    endingCleftEndF.setNewNormal( vrtcsEndingCleftEndF );
    6743              : ////                    closeToEndingCleftEndF.setNewNormal( vrtcsCloseToEndingCleftEndF );
    6744              : ////                    alongFreeEndEndF.setNewNormal( vrtcsAlongFreeEndEndF );
    6745              : //
    6746            0 :                         IndexType sudoTEnd = sh.num_subsets();
    6747              : 
    6748              :                         // gemeinsame Funktion wie bei XCross neue Punkte erzeugen und anwenden in dem einzigen speziellen Fall hier!
    6749              : 
    6750              :                         IndexType indBeforeT = sizeECF / 2 - 1;
    6751              :                         IndexType indAfterT = sizeECF / 2;
    6752              : 
    6753              :                         ExpandCrossFracInfo & expCFIBeforeFracEdg = vecExpCrossFI[ indBeforeT ];
    6754              :                         ExpandCrossFracInfo & expCFIAfterFracEdg = vecExpCrossFI[ indAfterT ];
    6755              : 
    6756              :                         vector3 distVecNewVrt2SCrossPt;
    6757              : 
    6758              :                         // new vertex in ending frac
    6759              : 
    6760              : //                      computeDiamondPointXCrossType( expCFIBeforeFracEdg, expCFIAfterFracEdg, crossPt, aaPos, sh, grid, sudoTEnd, distVecNewVrt2SCrossPt );
    6761              : 
    6762              :                         // shift of free shift point to virtual prolongation of ending fracture center line
    6763              : 
    6764              : //                      computeDiamondPointXCrossType( expCFIBeforeFracEdg, expCFIAfterFracEdg, crossPt, aaPos, sh, grid, sudoTEnd, distVecNewVrt2SCrossPt );
    6765            0 :                         computeDiamondPointXCrossType( expCFIBeforeFracEdg, expCFIAfterFracEdg, crossPt, aaPos, sh, grid, sudoTEnd, distVecNewVrt2SCrossPt, useTrianglesInDiamonds );
    6766              : 
    6767              :                         constexpr bool shiftFreePt = false;
    6768              : 
    6769              :                         if( shiftFreePt )
    6770              :                         {
    6771              : //                              computeDiamondPointXCrossType( expCFIBeforeFracEdg, expCFIAfterFracEdg, crossPt, aaPos, sh, grid, sudoTEnd, distVecNewVrt2SCrossPt );
    6772              : 
    6773              :                                 vector3 posCrossPt = aaPos[crossPt];
    6774              : 
    6775              :                                 vector3 newPosFreeShiftPt;
    6776              : 
    6777              :                                 VecAdd(newPosFreeShiftPt,posCrossPt,distVecNewVrt2SCrossPt);
    6778              : 
    6779              :                                 // assign this position to shift vertex at free end
    6780              : 
    6781              :                                 aaPos[shiftVrtxAtFreeEnd] = newPosFreeShiftPt;
    6782              : 
    6783              : 
    6784              :                                 for( IndexType i = 0; i < sizeECF; i = i + ( sizeECF ) / 2 + 1 )
    6785              :                                 {
    6786              :                                         bool atStart = ( i < sizeECF / 2 );
    6787              : 
    6788              :                                         IndexType firstInd = atStart ? ( i ) % sizeECF: ( i + 1 ) % sizeECF;
    6789              :                                         IndexType secndInd = atStart ? ( i + 1 ) % sizeECF : ( i ) % sizeECF;
    6790              : 
    6791              :                                         UG_LOG("indices " << firstInd << " " << secndInd << std::endl);
    6792              : 
    6793              :                                         ExpandCrossFracInfo & alongFreeEndF = vecExpCrossFI[firstInd];
    6794              :                                         ExpandCrossFracInfo & closeToTEndF = vecExpCrossFI[secndInd];
    6795              : 
    6796              :                                         std::pair<Edge*, Edge*> freeEdgs = alongFreeEndF.getEdge();
    6797              :                                         std::pair<Edge*, Edge*> tEndEdgs = closeToTEndF.getEdge();
    6798              : 
    6799              :                                         Edge * freeCommEdg = atStart ? freeEdgs.second : freeEdgs.first;
    6800              :                                         Edge * closTCommEdg = atStart ? tEndEdgs.first : tEndEdgs.second;
    6801              : 
    6802              :                                         if( freeCommEdg != closTCommEdg || freeCommEdg == nullptr || closTCommEdg == nullptr )
    6803              :                                                 UG_THROW("freie und geschlossene Ecke ungleich oder null " << freeCommEdg << " " << closTCommEdg << std::endl);
    6804              : 
    6805              :                                         std::pair<Vertex*, Vertex*> freeVrtcs = alongFreeEndF.getNormal();
    6806              :                                         std::pair<Vertex*, Vertex*> tEndVrtcs = closeToTEndF.getNormal();
    6807              : 
    6808              :                                         Vertex * remainVrtx = atStart ? freeVrtcs.first : freeVrtcs.second;
    6809              :                                         Vertex * shiftTVrt = atStart ? tEndVrtcs.second : tEndVrtcs.first;
    6810              : 
    6811              :                                         Vertex * freeNull = atStart ? freeVrtcs.second : freeVrtcs.first;
    6812              :                                         Vertex * teNull = atStart ? tEndVrtcs.first : tEndVrtcs.second;
    6813              : 
    6814              :                                         if( freeNull != nullptr || teNull != nullptr ||  remainVrtx == nullptr || shiftTVrt == nullptr )
    6815              :                                         {
    6816              :         //                                      UG_THROW("TEnd schon falsch zugewiesene Vertizex" << std::endl);
    6817              :                                                 UG_LOG("TEnd schon falsch zugewiesene Vertizex" << std::endl);
    6818              : 
    6819              :                                                 UG_LOG("Falsch feee null " << freeNull << " T " << teNull << " R " << remainVrtx << " S " << shiftTVrt << std::endl);
    6820              : 
    6821              :                                                 UG_THROW("TEnd schon falsch zugewiesene Vertizex" << std::endl);
    6822              : 
    6823              :                                                 UG_THROW("Falsch feee null " << freeNull << " T " << teNull << " R " << remainVrtx << " S " << shiftTVrt << std::endl);
    6824              :                                         }
    6825              :                                         else
    6826              :                                         {
    6827              :                                                 UG_LOG("TEnd richtig zugewiesene Vertizex" << std::endl);
    6828              : 
    6829              :                                                 UG_LOG("Richtig feee null " << freeNull << " T " << teNull << " R " << remainVrtx << " S " << shiftTVrt << std::endl);
    6830              : 
    6831              :                                         }
    6832              : 
    6833              :                                         vector3 posVRem = aaPos[remainVrtx];
    6834              :                                         vector3 posShiVe = aaPos[shiftTVrt];
    6835              : 
    6836              :         //                              UG_LOG("pos T " << posVRem << " " << posShiVe << std::endl);
    6837              :         //
    6838              :                                         vector3 dist;
    6839              :                                         VecSubtract(dist, posShiVe, posVRem);
    6840              :         //
    6841              :         //                              UG_LOG("dist TR " << dist << std::endl);
    6842              :         //
    6843              :                                         vector3 distHalf;
    6844              :                                         VecScale(distHalf, dist, 0.5);
    6845              :         //
    6846              :         //                              UG_LOG("dist half TR " << distHalf << std::endl);
    6847              :         //
    6848              :                                         vector3 posNewVrt;
    6849              :                                         VecAdd(posNewVrt, posVRem, distHalf);
    6850              :         //
    6851              :         //                              UG_LOG("neuer Vertex Position " << posNewVrt << std::endl);
    6852              :         //
    6853              : 
    6854              :                                         Vertex * newVrt = *grid.create<RegularVertex>();
    6855              :                                         aaPos[newVrt] = posNewVrt;
    6856              : 
    6857              :                                         sh.assign_subset(newVrt, sudoTEnd);
    6858              :         //
    6859              :                                         if( atStart )
    6860              :                                         {
    6861              :                                                 freeVrtcs.second = newVrt;
    6862              :                                                 tEndVrtcs.first = newVrt;
    6863              :                                         }
    6864              :                                         else
    6865              :                                         {
    6866              :                                                 freeVrtcs.first = newVrt;
    6867              :                                                 tEndVrtcs.second = newVrt;
    6868              :                                         }
    6869              :         //
    6870              :                                         alongFreeEndF.setNewNormal( freeVrtcs );
    6871              :                                         closeToTEndF.setNewNormal( tEndVrtcs );
    6872              : 
    6873              :                                 }
    6874              : 
    6875              :                         }
    6876              :                         else // go to left and right from crossPt at same distance as where the ending cleft enters the durchgehende one
    6877              :                         {
    6878              : 
    6879              : //                              vector3 distVecNewVrt2ShiVeBefore;
    6880              : //                              vector3 distVecNewVrt2ShiVeAfter;
    6881              : 
    6882              : 
    6883              : //                              computeDiamondPointXCrossType( expCFIBeforeFracEdg, expCFIAfterFracEdg, crossPt, aaPos, sh, grid, sudoTEnd,
    6884              : //                                                                                         distVecNewVrt2SCrossPt. distVecNewVrt2ShiVeBefore, distVecNewVrt2ShiVeAfter, true );
    6885              :                                 //              VecSubtract(distVecNewVrt2ShiVeBefore, posShiftBefore, posNewVrtOnEdg );
    6886              : 
    6887              : 
    6888            0 :                                 for( IndexType i = 0; i < sizeECF; i = i + ( sizeECF ) / 2 + 1 )
    6889              :                                 {
    6890              :                                         bool atStart = ( i < sizeECF / 2 );
    6891              : 
    6892            0 :                                         IndexType firstInd = atStart ? ( i ) % sizeECF: ( i + 1 ) % sizeECF;
    6893            0 :                                         IndexType secndInd = atStart ? ( i + 1 ) % sizeECF : ( i ) % sizeECF;
    6894              : 
    6895              :                                         UG_LOG("indices " << firstInd << " " << secndInd << std::endl);
    6896              : 
    6897              :                                         ExpandCrossFracInfo & alongFreeEndF = vecExpCrossFI[firstInd];
    6898              :                                         ExpandCrossFracInfo & closeToTEndF = vecExpCrossFI[secndInd];
    6899              : 
    6900              :                                         std::pair<Edge*, Edge*> freeEdgs = alongFreeEndF.getEdge();
    6901              :                                         std::pair<Edge*, Edge*> tEndEdgs = closeToTEndF.getEdge();
    6902              : 
    6903            0 :                                         Edge * freeCommEdg = atStart ? freeEdgs.second : freeEdgs.first;
    6904            0 :                                         Edge * closTCommEdg = atStart ? tEndEdgs.first : tEndEdgs.second;
    6905              : 
    6906            0 :                                         if( freeCommEdg != closTCommEdg || freeCommEdg == nullptr || closTCommEdg == nullptr )
    6907            0 :                                                 UG_THROW("freie und geschlossene Ecke ungleich oder null " << freeCommEdg << " " << closTCommEdg << std::endl);
    6908              : 
    6909              :                                         std::pair<Vertex*, Vertex*> freeVrtcs = alongFreeEndF.getNormal();
    6910              :                                         std::pair<Vertex*, Vertex*> tEndVrtcs = closeToTEndF.getNormal();
    6911              : 
    6912            0 :                                         Vertex * remainVrtx = atStart ? freeVrtcs.first : freeVrtcs.second;
    6913            0 :                                         Vertex * shiftTVrt = atStart ? tEndVrtcs.second : tEndVrtcs.first;
    6914              : 
    6915            0 :                                         Vertex * freeNull = atStart ? freeVrtcs.second : freeVrtcs.first;
    6916            0 :                                         Vertex * teNull = atStart ? tEndVrtcs.first : tEndVrtcs.second;
    6917              : 
    6918            0 :                                         if( freeNull != nullptr || teNull != nullptr ||  remainVrtx == nullptr || shiftTVrt == nullptr )
    6919              :                                         {
    6920              :         //                                      UG_THROW("TEnd schon falsch zugewiesene Vertizex" << std::endl);
    6921              :                                                 UG_LOG("TEnd schon falsch zugewiesene Vertizex" << std::endl);
    6922              : 
    6923              :                                                 UG_LOG("Falsch feee null " << freeNull << " T " << teNull << " R " << remainVrtx << " S " << shiftTVrt << std::endl);
    6924              : 
    6925            0 :                                                 UG_THROW("TEnd schon falsch zugewiesene Vertizex" << std::endl);
    6926              : 
    6927              :                                                 UG_THROW("Falsch feee null " << freeNull << " T " << teNull << " R " << remainVrtx << " S " << shiftTVrt << std::endl);
    6928              :                                         }
    6929              :                                         else
    6930              :                                         {
    6931              :                                                 UG_LOG("TEnd richtig zugewiesene Vertizex" << std::endl);
    6932              : 
    6933              :                                                 UG_LOG("Richtig feee null " << freeNull << " T " << teNull << " R " << remainVrtx << " S " << shiftTVrt << std::endl);
    6934              : 
    6935              :                                         }
    6936              : 
    6937            0 :                                         vector3 posCrossPt = aaPos[crossPt];
    6938              :                                         vector3 posShiVe = aaPos[shiftTVrt];
    6939              : 
    6940              :                                         vector3 posNewVrtOnFrctrsTouchEdg;
    6941              :                                         VecSubtract( posNewVrtOnFrctrsTouchEdg, posCrossPt, distVecNewVrt2SCrossPt );
    6942              : 
    6943              :                                         vector3 distNewTouchEdgVrt2ShiVe;
    6944              :                                         VecSubtract(distNewTouchEdgVrt2ShiVe, posShiVe, posNewVrtOnFrctrsTouchEdg);
    6945              : 
    6946              :                                         number distNrm = VecLength(distNewTouchEdgVrt2ShiVe);
    6947              : 
    6948              :                                         // go along old frac edge with this length
    6949              : 
    6950              :                                         Vertex * endEdgFracV = nullptr;
    6951              : 
    6952              :                                         IndexType fndCr = 0;
    6953              : 
    6954            0 :                                         for( IndexType i = 0; i < 2; i++ )
    6955              :                                         {
    6956              : 
    6957            0 :                                                 Vertex * tV =  closTCommEdg->vertex(i);
    6958              : 
    6959            0 :                                                 if( tV == crossPt )
    6960            0 :                                                         fndCr++;
    6961              :                                                 else
    6962              :                                                         endEdgFracV = tV;
    6963              :                                         }
    6964              : 
    6965            0 :                                         if( fndCr != 1 || endEdgFracV == nullptr )
    6966            0 :                                                 UG_THROW("ENde nicht gefunden " << std::endl);
    6967              : 
    6968              :                                         vector3 posEndPt = aaPos[endEdgFracV];
    6969              : 
    6970              :                                         vector3 crsPt2EndPt;
    6971              :                                         VecSubtract(crsPt2EndPt, posEndPt, posCrossPt);
    6972              : 
    6973              :                                         vector3 unitAlong;
    6974            0 :                                         VecNormalize(unitAlong, crsPt2EndPt);
    6975              : 
    6976              :                                         vector3 scaAlong;
    6977              :                                         VecScale(scaAlong, unitAlong, distNrm);
    6978              : 
    6979              :                                         vector3 posNewVrt;
    6980              : 
    6981              :                                         VecAdd(posNewVrt, posCrossPt, scaAlong);
    6982              : 
    6983            0 :                                         Vertex * newVrt = *grid.create<RegularVertex>();
    6984              :                                         aaPos[newVrt] = posNewVrt;
    6985              : 
    6986            0 :                                         sh.assign_subset(newVrt, sudoTEnd);
    6987              :         //
    6988            0 :                                         if( atStart )
    6989              :                                         {
    6990              :                                                 freeVrtcs.second = newVrt;
    6991              :                                                 tEndVrtcs.first = newVrt;
    6992              :                                         }
    6993              :                                         else
    6994              :                                         {
    6995              :                                                 freeVrtcs.first = newVrt;
    6996              :                                                 tEndVrtcs.second = newVrt;
    6997              :                                         }
    6998              :         //
    6999              :                                         alongFreeEndF.setNewNormal( freeVrtcs );
    7000              :                                         closeToTEndF.setNewNormal( tEndVrtcs );
    7001              : 
    7002              :                                 }
    7003              : 
    7004              :                         }
    7005              : 
    7006              : 
    7007              :                         // create new edges and new faces
    7008              : 
    7009              :                         // edges and faces outside the diamond, at the crossing fractures attached to the diamond
    7010              : 
    7011              :                         std::vector<Face*> newFracFaceVec = std::vector<Face*>();
    7012              : 
    7013            0 :                         bool boundAtShiftVrtEdg = false;
    7014              : //                      bool atStartSort = false;
    7015              : 
    7016              : //                      for( IndexType i = indBeforeT; i <= indAfterT; i++ )
    7017            0 :                         for( auto const & ecf : vecExpCrossFI )
    7018              :                         {
    7019              : //                              createNewFacesForExtXCrossFracs( vecExpCrossFI[i], newFracFaceVec, boundAtShiftVrtEdg, atStartSort, sh, grid, crossPt, subdomList );
    7020            0 :                                 createNewFacesForExtXCrossFracs( ecf, newFracFaceVec, boundAtShiftVrtEdg, sh, grid, crossPt, subdomList );
    7021              :                         }
    7022              : 
    7023              :                         // edges and faces of the diamond itself respectively its analogon for the TEnd case here
    7024              : 
    7025              :                         std::vector<Face*> newDiamFaceVec = std::vector<Face*>();
    7026              : 
    7027              : //                      ExpandCrossFracInfo & expCFIBeforeFracEdg = vecExpCrossFI[ indBeforeT ];
    7028              : //                      ExpandCrossFracInfo & expCFIAfterFracEdg = vecExpCrossFI[ indAfterT ];
    7029              : 
    7030              : 
    7031              : //                      createDiamondFacesXCrossType( expCFIAfterFracEdg, expCFIBeforeFracEdg,
    7032              : //                                                                      newDiamFaceVec,  sh, grid, sudoTEnd, crossPt );
    7033              : 
    7034              :                         // only the non free part
    7035              : //                      for( int indC = 1; indC < sizeECF-2; indC = indC + 2 )
    7036            0 :                         for( int indC = -1; indC < sizeECF-2; indC = indC + 2 )
    7037              :                         {
    7038              : 
    7039              :                                 // Create Spitze at free side
    7040            0 :                                 bool isAtFreeEnd = ( indC == -1 );
    7041              : 
    7042            0 :                                 IndexType indBefore = ( indC + sizeECF ) % sizeECF;
    7043            0 :                                 IndexType indAfter = ( indC + 1 + sizeECF ) % sizeECF;
    7044              : 
    7045              : 
    7046            0 :                                 ExpandCrossFracInfo & expCFIBeforeFracEdg = vecExpCrossFI[ indBefore ];
    7047            0 :                                 ExpandCrossFracInfo & expCFIAfterFracEdg = vecExpCrossFI[ indAfter ];
    7048              : 
    7049              : 
    7050              : //                              createDiamondFacesXCrossType( expCFIBeforeFracEdg, expCFIAfterFracEdg,
    7051              : //                                              newDiamFaceVec,  sh, grid, sudoTEnd, crossPt, isAtFreeEnd );
    7052            0 :                                 createDiamondFacesXCrossType( expCFIBeforeFracEdg, expCFIAfterFracEdg,
    7053            0 :                                                 newDiamFaceVec,  sh, grid, sudoTEnd, crossPt, isAtFreeEnd || useTrianglesInDiamonds );
    7054              : 
    7055              :                         }
    7056              : //                      }
    7057              : 
    7058              : 
    7059              : 
    7060            0 :                         std::string diamNam = std::string("spitzDiam_") + std::string(const_cast<char*>( sh.get_subset_name( subdomList[0] ) ))
    7061            0 :                                                       + std::string("_") + std::string(const_cast<char*>( sh.get_subset_name( subdomList[1] ) ));
    7062              : 
    7063            0 :                         sh.set_subset_name(diamNam.c_str(),sudoTEnd);
    7064              : 
    7065            0 :                         assignFaceSubsetToClosedFace( newFracFaceVec, grid, sh );
    7066            0 :                         assignFaceSubsetToClosedFace( newDiamFaceVec, grid, sh );
    7067              : 
    7068              : //                      for( auto const & fdel : vecExpCrossFI )
    7069              : //                      {
    7070              : //                              Face * fac2BeDeleted = fdel.getFace();
    7071              : //
    7072              : //                              if( fac2BeDeleted != nullptr )
    7073              : //                                      grid.erase(fac2BeDeleted);
    7074              : //                              else
    7075              : //                                      UG_THROW("hier fehlt ein Gesicht " << std::endl);
    7076              : //                      }
    7077              : //
    7078              : //                      for( auto const & edg : allAssoEdgCP )
    7079              : //                      {
    7080              : ////                            Edge * e2D = oEdg;
    7081              : //
    7082              : //                              if( edg != nullptr && edg != shiftVrtxAtFirstFacEdg )
    7083              : //                              {
    7084              : //                                      UG_LOG("will erasieren " << edg << std::endl );
    7085              : //                                      grid.erase(edg);
    7086              : //
    7087              : ////                                    sh.assign_subset( e2D, subsNumNow );
    7088              : ////                                    sh.assign_subset( e2D, subsNumNow );
    7089              : //                              }
    7090              : //                              else
    7091              : //                              {
    7092              : //                                      UG_LOG("hier fehlt eine Ecke " << std::endl);
    7093              : //                              }
    7094              : //                      }
    7095              : 
    7096              :                         avoidToDeleteEdge = shiftVrtxAtFirstFacEdg;
    7097              : 
    7098            0 :                         UG_LOG("T End Kreis fertig an " << aaPos[crossPt] << std::endl );
    7099              : 
    7100            0 :                 }
    7101              :                 //              else if( nuCroFra == 4 )
    7102            0 :                 else if( fracTyp == CrossVertInf::XCross )
    7103              :                 {
    7104              :                         // sort faces and corresponding edges, start with an oririnal fracture edge and select the next edge which
    7105              :                         // has a newly created shift vertex
    7106              : 
    7107            0 :                         auto assoFacXCrossCop = assoFacCross;
    7108              : 
    7109              :                         // "durchdrehen"
    7110              : 
    7111              : //                      Face * assoFacConsider = *(assoFacXCrossCop.begin());
    7112            0 :                         Face * assoFacConsider = assoFacXCrossCop[0];
    7113              : 
    7114              :                         // soll einmal am Anfang festgelegt werden und dann bleiben
    7115            0 :                         Edge * assoFacEdgBeg2Fix = nullptr;
    7116              :                         // soll erst ganz am Schluss festgelegt werden
    7117            0 :                         Edge * assoFacEdgEnd2Fix = nullptr;
    7118              : 
    7119              :                         // soll in jedem Lauf aktualisiert werden
    7120            0 :                         Edge * firstEdgeFac = assoFacEdgBeg2Fix;
    7121            0 :                         Edge * secondEdgeFac = nullptr;
    7122              : 
    7123              : //                      bool atStartSort = true;
    7124              : 
    7125              : //                      using ExpandCrossFracInfo = VertexFractureTriple< std::pair<Edge*, Edge*>, Face*, std::pair<Vertex*, Vertex*> >;
    7126              : //                      // Vertex nullptr wo original fracture, und shift vertex, wo Keilecke, die weg soll
    7127              : //
    7128              : //                      using VecExpandCrossFracInfo = std::vector<ExpandCrossFracInfo>;
    7129              : 
    7130              : //                      VecExpandCrossFracInfo vecExpCrossFI;
    7131              : 
    7132              : //                      bool boundAtShiftVrtEdg = true;
    7133              : 
    7134              : //                      auto shiftVrtcsCop = shiftVrtcs;
    7135              : 
    7136              : //                      UG_LOG("starting Rundlauf " << std::endl);
    7137              : 
    7138              : //                      IndexType dbg_rndl = 0;
    7139              : 
    7140            0 :                         if( ! SortFaces4DiamondCreation( sh, assoFacXCrossCop, firstEdgeFac, secondEdgeFac,
    7141              :                                         assoFacConsider, origFracEdg, shiftVrtcs,
    7142              :                                         crossPt, assoFacEdgBeg2Fix, assoFacEdgEnd2Fix, grid, vecExpCrossFI
    7143              :                                         , true
    7144              :                                 )
    7145              :                         )
    7146            0 :                                 UG_THROW("Ordnen Diamant X Cross schief gegangen " << std::endl);
    7147              : 
    7148              : #if 0
    7149              :                         while( assoFacXCrossCop.size() != 0 )
    7150              :                         {
    7151              : 
    7152              : //                              UG_LOG("Debug Rundlauf " << dbg_rndl << std::endl);
    7153              : 
    7154              :                                 dbg_rndl++;
    7155              : 
    7156              :                                 secondEdgeFac = nullptr;
    7157              : 
    7158              :                                 Edge * fracEdge = nullptr;
    7159              :                                 Edge * shiftVrtxEdg = nullptr;
    7160              : 
    7161              : //                              IndexType fndEdgEnd = 0;
    7162              : 
    7163              :                                 std::vector<Edge*> edgesThisFac;
    7164              : 
    7165              :                                 edgesThisFac.clear();
    7166              : 
    7167              : //                              IndexType eoeo = edgesThisFac.size();
    7168              : //
    7169              : //                              auto eiei = eoeo;
    7170              : 
    7171              : //                              UG_LOG("Edges this fac Orig Orig " << eiei <<  " " << dbg_rndl << std::endl);
    7172              : 
    7173              : 
    7174              : //                              UG_LOG("Debug Ecken " << std::endl);
    7175              : 
    7176              :                                 IndexType dbg_itEd = 0;
    7177              : 
    7178              :                                 for( std::vector<Edge *>::iterator iterEdgF = grid.associated_edges_begin(assoFacConsider);
    7179              :                                                 iterEdgF != grid.associated_edges_end(assoFacConsider); iterEdgF++ )
    7180              :                                 {
    7181              :                                         edgesThisFac.push_back(*iterEdgF);
    7182              : 
    7183              : //                                      UG_LOG("und noch eines dazu " << dbg_itEd << " " << dbg_rndl << std::endl);
    7184              : 
    7185              :                                         //IndexType sudos = sh.num_subsets();
    7186              : 
    7187              :                                         //sh.assign_subset(*iterEdgF,sudos);
    7188              :                                 }
    7189              : 
    7190              : //                              IndexType effsOrig = edgesThisFac.size();
    7191              : 
    7192              : //                              auto efeu = effsOrig;
    7193              : 
    7194              : //                              UG_LOG("Edges this fac Orig " << efeu <<  dbg_rndl << std::endl);
    7195              : 
    7196              : 
    7197              :                                 // figure out original fracture edge
    7198              : 
    7199              :                                 IndexType fndFracEdg = 0;
    7200              : 
    7201              :                                 for( auto const & etf : edgesThisFac )
    7202              :                                 {
    7203              :                                         for( auto const & ofe : origFracEdg )
    7204              :                                         {
    7205              :                                                 if( etf == ofe )
    7206              :                                                 {
    7207              :                                                         fndFracEdg++;
    7208              :                                                         fracEdge = etf;
    7209              :                                                 }
    7210              :                                         }
    7211              :                                 }
    7212              : 
    7213              : //                              UG_LOG("Debug Ofen  " << std::endl);
    7214              : 
    7215              : 
    7216              :                                 if( fracEdge == nullptr || fndFracEdg != 1 )
    7217              :                                 {
    7218              :                                         UG_LOG("Frac Orig Ecke nicht gefunden oder falsche Zahl " << fndFracEdg << std::endl );
    7219              : //                                      return false;
    7220              :                                         UG_THROW("Frac Orig Ecke nicht gefunden oder falsche Zahl " << fndFracEdg << std::endl );
    7221              :                                 }
    7222              : 
    7223              : 
    7224              :                                 // find expanded shift vertex
    7225              : 
    7226              :                                 Vertex * shiftVrtxFound = nullptr;
    7227              :                                 IndexType fndVrt = 0;
    7228              : 
    7229              : //                              IndexType suse = sh.num_subsets();
    7230              : 
    7231              :                                 //sh.assign_subset(crossPt,suse);
    7232              : 
    7233              : //                              for( auto & sv : shiftVrtcsCop )
    7234              : //                              {
    7235              : //                                      IndexType suseV = sh.num_subsets();
    7236              : //                                      //sh.assign_subset(sv,suseV);
    7237              : //                              }
    7238              : 
    7239              : //                              return true;
    7240              : 
    7241              : //                              UG_LOG("Debug Entfernene    " << std::endl);
    7242              : 
    7243              :                                 IndexType dbg_edgnum = 0;
    7244              : 
    7245              :                                 IndexType helpVarEdges = 0;
    7246              : 
    7247              : //                              IndexType effs = edgesThisFac.size();
    7248              : //                              IndexType shiffs = shiftVrtcs.size();
    7249              : 
    7250              : //                              UG_LOG("Edges this fac " <<  effs <<  dbg_rndl << std::endl);
    7251              : //                              UG_LOG("Shift Vectors " <<  shiffs <<  dbg_rndl << std::endl);
    7252              : 
    7253              : 
    7254              :                                 for( auto const & etf : edgesThisFac )
    7255              :                                 {
    7256              : 
    7257              :                                         if( helpVarEdges >= edgesThisFac.size() )
    7258              :                                         {
    7259              :                                                 UG_LOG("Indexueberschreitung Edges" << std::endl);
    7260              :                                                 break;
    7261              :                                         }
    7262              : 
    7263              :                                         helpVarEdges++;
    7264              : 
    7265              :                                         dbg_edgnum++;
    7266              : 
    7267              :                                         IndexType helpShiVaNum = 0;
    7268              : 
    7269              :                                         IndexType dbg_shiVe = 0;
    7270              : 
    7271              : //                                      for( Vertex * const & sv : shiftVrtcs )
    7272              :                                         for( auto const & sv : shiftVrtcs )
    7273              :                                         {
    7274              : 
    7275              :                                                 if( helpShiVaNum >= shiftVrtcs.size() )
    7276              :                                                 {
    7277              :                                                         UG_LOG("Shift Vertex Index Verletzung " << std::endl);
    7278              :                                                         break;
    7279              :                                                 }
    7280              : 
    7281              :                                                 helpShiVaNum++;
    7282              : 
    7283              :                                                 dbg_shiVe++;
    7284              : 
    7285              :                                                 for( IndexType i = 0; i < 2; i++ )
    7286              :                                                 {
    7287              : //                                                      if( ( etf->vertex(i) == crossPt && etf->vertex((i+1)%2) == sv )  || (etf->vertex((i+1)%2) == crossPt && etf->vertex(i) == sv ))
    7288              :                                                         if( etf->vertex(i) == crossPt && etf->vertex((i+1)%2) == sv )
    7289              :                                                         {
    7290              :                                                                 shiftVrtxFound = sv;
    7291              :                                                                 fndVrt++;
    7292              :                                                                 shiftVrtxEdg = etf;
    7293              : 
    7294              : //                                                              UG_LOG("Shift Vertex " << aaPos[shiftVrtxFound] << " " << dbg_edgnum << " " << dbg_shiVe << " " << dbg_rndl << std::endl);
    7295              : //                                                              UG_LOG("Cross Vertex " << aaPos[crossPt] << " " << dbg_edgnum << " " << dbg_shiVe <<  " " << dbg_rndl <<  std::endl );
    7296              : //
    7297              : //                                                              UG_LOG("dbg edgenu shive " << dbg_edgnum << " " << dbg_shiVe <<  " " << dbg_rndl <<  std::endl);
    7298              :                                                         }
    7299              :                                                 }
    7300              :                                         }
    7301              :                                 }
    7302              : 
    7303              : //                              UG_LOG("Debug Entfert durch         " << std::endl);
    7304              : 
    7305              : 
    7306              :                                 if( fndVrt != 1 || shiftVrtxFound == nullptr || shiftVrtxEdg == nullptr )
    7307              :                                 {
    7308              :                                         UG_LOG("shift vertex komische Zahl oder null " << fndVrt << std::endl);
    7309              : //                                      return false;
    7310              :                                         UG_THROW("shift vertex komische Zahl oder null " << fndVrt << std::endl);
    7311              :                                 }
    7312              : 
    7313              : //                              UG_LOG("Debug Entfert Text durch    " << std::endl);
    7314              : 
    7315              : 
    7316              : //                              for( std::vector<Vertex*>::iterator itV = shiftVrtcsCop.begin(); itV != shiftVrtcsCop.end(); itV++ )
    7317              : //                              {
    7318              : //                                      Vertex * vrt = *itV;
    7319              : //
    7320              : //                                      if( vrt == shiftVrtxFound )
    7321              : //                                      {
    7322              : //                                              shiftVrtcsCop.erase(itV);
    7323              : //                                              break;
    7324              : //                                      }
    7325              : //                              }
    7326              : //
    7327              : //                              UG_LOG("Debug Rasieren durch        " << std::endl);
    7328              : 
    7329              : 
    7330              :                                 if( atStartSort )
    7331              :                                 {
    7332              :                                         assoFacEdgBeg2Fix = fracEdge;
    7333              :                                         atStartSort = false;
    7334              :                                 }
    7335              : 
    7336              : //                              Edge * firstEdgeFac = fracEdge;
    7337              : //                              Edge * secondEdgeFac = shiftEdge;
    7338              :                                 firstEdgeFac = fracEdge;
    7339              :                                 secondEdgeFac = shiftVrtxEdg;
    7340              : 
    7341              : 
    7342              :                                 Vertex * firstVrt = nullptr;
    7343              :                                 Vertex * secondVrt = shiftVrtxFound;
    7344              : 
    7345              :                                 if( !boundAtShiftVrtEdg )
    7346              :                                 {
    7347              :                                         firstEdgeFac = shiftVrtxEdg;
    7348              :                                         secondEdgeFac = fracEdge;
    7349              : 
    7350              :                                         firstVrt = shiftVrtxFound;
    7351              :                                         secondVrt = nullptr;
    7352              :                                 }
    7353              : 
    7354              : //                              UG_LOG("Debug Paarbildung   " << std::endl);
    7355              : 
    7356              : 
    7357              :                                 std::pair<Edge*, Edge*> edgesFac( firstEdgeFac, secondEdgeFac );
    7358              : 
    7359              :                                 std::pair<Vertex*,Vertex*> vrtcsSF( firstVrt, secondVrt );
    7360              : 
    7361              :                                 ExpandCrossFracInfo startFacInf( edgesFac, assoFacConsider, vrtcsSF );
    7362              : 
    7363              :                                 vecExpCrossFI.push_back(startFacInf);
    7364              : 
    7365              : //                              IndexType sui = sh.num_subsets();
    7366              : //
    7367              : //                              sh.assign_subset(assoFacConsider,sui);
    7368              : 
    7369              : //                              UG_LOG("Debug Paarbildung  Rasieren " << std::endl);
    7370              : 
    7371              :                                 IndexType dbg_it_er = 0;
    7372              : 
    7373              :                                 for( std::vector<Face*>::iterator itFac = assoFacXCrossCop.begin(); itFac != assoFacXCrossCop.end(); itFac++ )
    7374              :                                 {
    7375              :                                         Face * iFa = *itFac;
    7376              : 
    7377              : //                                      UG_LOG("interieren " << dbg_it_er << std::endl );
    7378              : 
    7379              :                                         dbg_it_er++;
    7380              : 
    7381              : //                                      UG_LOG("ifa " << iFa << std::endl );
    7382              : //                                      UG_LOG("assoFac " << assoFacConsider << std::endl );
    7383              : 
    7384              : //                                      bool enthaltung = FaceContains( iFa, firstEdgeFac );
    7385              : //
    7386              : ////                                    UG_LOG("Enthaltung " << std::endl);
    7387              : //
    7388              : //                                      bool entzwei = FaceContains(iFa, secondEdgeFac);
    7389              : //
    7390              : ////                                    UG_LOG("Entzweiung " << std::endl);
    7391              : 
    7392              : 
    7393              :                                         if( iFa == assoFacConsider && FaceContains( iFa, firstEdgeFac ) && FaceContains(iFa, secondEdgeFac) )
    7394              :                                         {
    7395              : //                                              UG_LOG("Erasieren " << std::endl);
    7396              :                                                 assoFacXCrossCop.erase(itFac);
    7397              :                                                 break;
    7398              :                                         }
    7399              :                                 }
    7400              : 
    7401              : //                              UG_LOG("Debug Paarbildung  Rasieren durch " << std::endl);
    7402              : 
    7403              : 
    7404              :                                 if( assoFacXCrossCop.size() == 0 )
    7405              :                                 {
    7406              :                                         if( secondEdgeFac != assoFacEdgBeg2Fix )
    7407              :                                         {
    7408              :                                                 UG_LOG("Gesichter Diamant leer, aber keine Anfangsecke gefunden" << std::endl);
    7409              : //                                              return false;
    7410              :                                                 UG_THROW("Gesichter Diamant leer, aber keine Anfangsecke gefunden" << std::endl);
    7411              :                                         }
    7412              :                                         else
    7413              :                                         {
    7414              :                                                 assoFacEdgEnd2Fix = secondEdgeFac;
    7415              : 
    7416              :                                                 break; // while loop zu Ende, raus aus dem while loop, den Rest nicht mehr machen, würde schief gehen zwingendermassen
    7417              :                                         }
    7418              : 
    7419              :                                 }
    7420              : 
    7421              :                                 // figure out the next face
    7422              : 
    7423              :                                 firstEdgeFac = secondEdgeFac;
    7424              :                                 secondEdgeFac = nullptr;
    7425              : 
    7426              :                                 IndexType nextFaceFound = 0;
    7427              : 
    7428              :                                 for( std::vector<Face*>::iterator itFac = assoFacXCrossCop.begin(); itFac != assoFacXCrossCop.end(); itFac++ )
    7429              :                                 {
    7430              :                                         Face * iFa = *itFac;
    7431              : 
    7432              :                                         if( FaceContains(iFa, firstEdgeFac ) )
    7433              :                                         {
    7434              :                                                 nextFaceFound++;
    7435              :                                         }
    7436              :                                 }
    7437              : 
    7438              :                                 if( nextFaceFound != 1 )
    7439              :                                 {
    7440              :                                         UG_LOG("folgendes Gesicht in falscher Anztahl gefunden Diamant " << nextFaceFound << std::endl);
    7441              : //                                      return false;
    7442              :                                         UG_THROW("folgendes Gesicht in falscher Anztahl gefunden Diamant " << nextFaceFound << std::endl);
    7443              :                                 }
    7444              : 
    7445              :                                 for( std::vector<Face*>::iterator itFac = assoFacXCrossCop.begin(); itFac != assoFacXCrossCop.end(); itFac++ )
    7446              :                                 {
    7447              :                                         Face * iFa = *itFac;
    7448              : 
    7449              :                                         if( FaceContains(iFa, firstEdgeFac ) )
    7450              :                                         {
    7451              :                                                 assoFacConsider = iFa;
    7452              :                                                 break;
    7453              :                                         }
    7454              :                                 }
    7455              : 
    7456              : 
    7457              :                                 boundAtShiftVrtEdg = ! boundAtShiftVrtEdg;
    7458              :                         }
    7459              : 
    7460              : 
    7461              :                         if( assoFacEdgEnd2Fix != assoFacEdgBeg2Fix || assoFacEdgEnd2Fix == nullptr || assoFacEdgBeg2Fix == nullptr )
    7462              :                         {
    7463              :                                 UG_THROW("Anfang und Ende stimmen nicht ueberein " << std::endl);
    7464              : //                              return false;
    7465              :                                 UG_THROW("Anfang und Ende stimmen nicht ueberein " << std::endl);
    7466              :                         }
    7467              : 
    7468              : //                      if( shiftVrtcsCop.size() != 0 )
    7469              : //                      {
    7470              : //                              UG_LOG("Shift vertizes nicht alle gefinden " << std::endl);
    7471              : //                              return false;
    7472              : //                              UG_THROW("Shift vertizes nicht alle gefinden " << std::endl);
    7473              : //                      }
    7474              : 
    7475              :                         if( assoFacXCrossCop.size() != 0 )
    7476              :                         {
    7477              :                                 UG_LOG("nicht alle asso facs gefunden " << std::endl);
    7478              : //                              return false;
    7479              :                                 UG_THROW("nicht alle asso facs gefunden " << std::endl);
    7480              :                         }
    7481              : #endif
    7482              : 
    7483              :                         UG_LOG("Kreis des Diamanten X Fall geschlossen " << std::endl);
    7484              : 
    7485              :                         // create new vertices and new edges and new faces, delete the old ones at end not to forget
    7486              : 
    7487              : //                      IndexType vecfis = vecExpCrossFI.size();
    7488              : //
    7489              : //                      UG_LOG("Punkte werden erzeugt " << vecfis << std::endl);
    7490              : //
    7491              : //                      for( IndexType i = -1; i < 8; i = i + 2 )
    7492              : //                              UG_LOG("iiii " << i << std::endl);
    7493              : //
    7494              : //                      for( IndexType indC = -1; indC < 8; indC = indC + 2 )
    7495              : //                      {
    7496              : //
    7497              : //                              UG_LOG("Punkterzeugung Test " << indC << std::endl );
    7498              : //
    7499              : //                      }
    7500              : //
    7501              : //                      return true;
    7502              : 
    7503              :                         //                      IndexType diamantSubsNum = sh.num_subsets()+1; // +1 notwendig? TODO FIXME wieso nicht +1?
    7504            0 :                         IndexType diamantSubsNum = sh.num_subsets(); // +1 notwendig? TODO FIXME
    7505              : 
    7506            0 :                         int vecfis = vecExpCrossFI.size();
    7507              : 
    7508              : //                      for( int indC = -1; indC < vecfis; indC = indC + 2 )
    7509              : //                              UG_LOG("Punkterzeugung " << indC << std::endl );
    7510              : //
    7511              : 
    7512              : //                      for( int indC = -1; indC < vecExpCrossFI.size(); indC = indC + 2 )
    7513            0 :                         for( int indC = -1; indC < vecfis-2; indC = indC + 2 )
    7514              :                         {
    7515              : 
    7516              : //                              UG_LOG("Punkterzeugung X " << indC << std::endl );
    7517              : 
    7518              : 
    7519            0 :                                 IndexType indBefore = ( indC + vecExpCrossFI.size() ) % vecExpCrossFI.size();
    7520            0 :                                 IndexType indAfter = ( indC + 1 + vecExpCrossFI.size() ) % vecExpCrossFI.size();
    7521              : 
    7522              :                                 // TODO FIXME ab hier in externe Funktion stecken, damit auch für TEnd endende Frac Seite verwendbar!!!!
    7523              : 
    7524              :                                 ExpandCrossFracInfo & expCFIBeforeFracEdg = vecExpCrossFI[ indBefore ];
    7525              :                                 ExpandCrossFracInfo & expCFIAfterFracEdg = vecExpCrossFI[ indAfter ];
    7526              : 
    7527              :                                 vector3 distVecNewVrt2SCrossPt; // not ot interest here, but only with c++17 possible to rule out computation in a clever way
    7528              : 
    7529              : //                              computeDiamondPointXCrossType( expCFIBeforeFracEdg, expCFIAfterFracEdg, crossPt, aaPos, sh, grid, diamantSubsNum, distVecNewVrt2SCrossPt );
    7530            0 :                                 computeDiamondPointXCrossType( expCFIBeforeFracEdg, expCFIAfterFracEdg, crossPt, aaPos, sh, grid, diamantSubsNum, distVecNewVrt2SCrossPt, useTrianglesInDiamonds );
    7531              : 
    7532              : #if 0
    7533              : 
    7534              : 
    7535              :                                 // compute cross point
    7536              : 
    7537              :                                 std::pair<Edge*, Edge*> edgesCrossSegBefore = expCFIBeforeFracEdg.getEdge();
    7538              :                                 std::pair<Edge*, Edge*> edgesCrossSegAfter = expCFIAfterFracEdg.getEdge();
    7539              : 
    7540              :                                 Edge * beforeShiftEdg = edgesCrossSegBefore.first;
    7541              :                                 Edge * beforeFracEdg = edgesCrossSegBefore.second;
    7542              :                                 Edge * afterFracEdg = edgesCrossSegAfter.first;
    7543              :                                 Edge * afterShiftEdg = edgesCrossSegAfter.second;
    7544              : 
    7545              :                                 std::pair<Vertex*,Vertex*> vrtcsCrossSegBefore = expCFIBeforeFracEdg.getNormal();
    7546              :                                 std::pair<Vertex*,Vertex*> vrtcsCrossSegAfter = expCFIAfterFracEdg.getNormal();
    7547              : 
    7548              :                                 Vertex * shiftBefore = vrtcsCrossSegBefore.first;
    7549              :                                 Vertex * shiftAfter = vrtcsCrossSegAfter.second;
    7550              : 
    7551              :                                 // zur Zielsetzung
    7552              : //                              Vertex * toBeEstablishedCutEdgeVrtBefore = vrtcsCrossSegBefore.second;
    7553              : //                              Vertex * toBeEstablishedCutEdgeVrtAfter = vrtcsCrossSegAfter.first;
    7554              : 
    7555              :                                 if(    vrtcsCrossSegBefore.second != nullptr ||  vrtcsCrossSegAfter.first != nullptr
    7556              :                                         ||      shiftBefore == nullptr || shiftAfter == nullptr
    7557              : //                              if(    toBeEstablishedCutEdgeVrtBefore != nullptr ||  toBeEstablishedCutEdgeVrtAfter != nullptr
    7558              : //                                      ||      shiftBefore == nullptr || shiftAfter == nullptr
    7559              :                                   )
    7560              :                                         UG_THROW("Nullpointer fehlen oder zu viel " << std::endl);
    7561              : 
    7562              :                                 if(    beforeFracEdg != afterFracEdg || beforeFracEdg == nullptr || afterFracEdg == nullptr
    7563              :                                         || beforeShiftEdg == nullptr || afterShiftEdg == nullptr
    7564              :                                   )
    7565              :                                         UG_LOG("Ecken Nullpunkter " << std::endl);
    7566              : 
    7567              :                                 // determin cut point of line between the shift vertices and the frac edge
    7568              : 
    7569              :                                 Edge * fracEdge = beforeFracEdg; // muss gleich sein offenkundig afterFracEdge, ist getestet auch
    7570              : 
    7571              :                                 // Gerade bestimmen, die durch fracEdge bestimmt wird, und Gerade, die durch Verbindungsvektor shift Verzices bestimmt wird
    7572              : 
    7573              :                                 // figure out frac vertex which is the cross point
    7574              : 
    7575              :                                 IndexType fracEdgInd = -1;
    7576              : 
    7577              :                                 for( IndexType fiv = 0; fiv < 2; fiv++ )
    7578              :                                 {
    7579              :                                         if( fracEdge->vertex(fiv) == crossPt )
    7580              :                                                 fracEdgInd = fiv;
    7581              :                                 }
    7582              : 
    7583              :                                 if( fracEdgInd < 0 || fracEdgInd > 1 )
    7584              :                                         UG_THROW("cross point nicht Teil von fracture edge" << std::endl );
    7585              : 
    7586              :                                 Vertex * fracEdgEnd = fracEdge->vertex( ( fracEdgInd + 1 ) % 2 );
    7587              : 
    7588              :                                 vector3 posCrossPt = aaPos[ crossPt ];
    7589              :                                 vector3 posFracEnd = aaPos[ fracEdgEnd ];
    7590              : 
    7591              :                                 vector3 posShiftBefore = aaPos[ shiftBefore ];
    7592              :                                 vector3 posShiftAfter = aaPos[ shiftAfter ];
    7593              : 
    7594              :                                 vector3 directionFrac;
    7595              : 
    7596              :                                 VecSubtract(directionFrac, posFracEnd, posCrossPt );
    7597              : 
    7598              :                                 vector3 directionShiftBefore;
    7599              : 
    7600              :                                 VecSubtract(directionShiftBefore, posShiftBefore, posCrossPt);
    7601              : 
    7602              :                                 vector3 directionShiftAfter;
    7603              : 
    7604              :                                 VecSubtract(directionShiftAfter, posShiftAfter, posCrossPt );
    7605              : 
    7606              :                                 vector3 sumShift;
    7607              : 
    7608              :                                 VecAdd(sumShift, directionShiftBefore, directionShiftAfter);
    7609              : 
    7610              :                                 vector3 halfSumShift;
    7611              : 
    7612              :                                 VecScale(halfSumShift,sumShift,0.5);
    7613              : 
    7614              :                                 vector3 posNewVrtOnEdg;
    7615              : 
    7616              :                                 VecAdd( posNewVrtOnEdg, posCrossPt, halfSumShift );
    7617              : 
    7618              :                                 Vertex * newEdgVrtx = *grid.create<RegularVertex>();
    7619              :                                 aaPos[newEdgVrtx] = posNewVrtOnEdg;
    7620              : 
    7621              :                                 IndexType sudoEdg = sh.get_subset_index(fracEdge);
    7622              : 
    7623              :                                 Face * faceBefore = expCFIBeforeFracEdg.getFace();
    7624              :                                 Face * faceAfter = expCFIAfterFracEdg.getFace();
    7625              : 
    7626              :                                 IndexType sudoBefore = sh.get_subset_index(faceBefore);
    7627              :                                 IndexType sudoAfter = sh.get_subset_index(faceAfter);
    7628              : 
    7629              :                                 if( sudoEdg != sudoBefore || sudoBefore != sudoAfter )
    7630              :                                         UG_THROW("komische sudos vor Diamant " << std::endl);
    7631              : 
    7632              :                                 sh.assign_subset(newEdgVrtx, sudoEdg);
    7633              : 
    7634              :                                 UG_LOG("neuer Diamant Vorbereitungs Vertex " << posNewVrtOnEdg << std::endl);
    7635              : 
    7636              :                                 //                              Vertex * toBeEstablishedCutEdgeVrtBefore = vrtcsCrossSegBefore.second;
    7637              :                                 //                              Vertex * toBeEstablishedCutEdgeVrtAfter = vrtcsCrossSegAfter.first;
    7638              : 
    7639              : 
    7640              : 
    7641              :                                 // gleich neue Faces erzeugen?
    7642              : //                              std::pair<Vertex*,Vertex*> vrtcsCrossSegBefore = expCFIBeforeFracEdg.getNormal();
    7643              : //                              std::pair<Vertex*,Vertex*> vrtcsCrossSegAfter = expCFIAfterFracEdg.getNormal();
    7644              : 
    7645              :                                 // insert the newly established vertex into the vertex info of the ExpandCrossFracInfo of the face
    7646              : ////                            vrtcsCrossSegBefore.second = newEdgVrtx;
    7647              : ////                            vrtcsCrossSegAfter.first = newEdgVrtx;
    7648              : ////
    7649              : //                              std::pair<Vertex*,Vertex*> vrtcsCrossSegBeforeNew( vrtcsCrossSegBefore.first, newEdgVrtx );
    7650              : //                              std::pair<Vertex*,Vertex*> vrtcsCrossSegAfterNew( newEdgVrtx, vrtcsCrossSegAfter.second );
    7651              : //
    7652              : //
    7653              : //                              expCFIBeforeFracEdg.setNewNormal( vrtcsCrossSegBeforeNew );
    7654              : //                              expCFIAfterFracEdg.setNewNormal( vrtcsCrossSegAfterNew );
    7655              : 
    7656              :                                 vrtcsCrossSegBefore.second = newEdgVrtx;
    7657              :                                 vrtcsCrossSegAfter.first = newEdgVrtx;
    7658              :                                 expCFIBeforeFracEdg.setNewNormal( vrtcsCrossSegBefore );
    7659              :                                 expCFIAfterFracEdg.setNewNormal( vrtcsCrossSegAfter );
    7660              : 
    7661              : #endif
    7662              : 
    7663              : //                               vecExpCrossFI[ indBefore ].setNewEdgVertex(newEdgVrtx);
    7664              : //                               vecExpCrossFI[ indAfter ].setNewEdgVertex(newEdgVrtx);
    7665              : 
    7666              : //                               DiamondVertexInfo dviBefore();
    7667              : //                               DiamondVertexInfo dviAfter();
    7668              : 
    7669              :                         }
    7670              : 
    7671              : 
    7672              :                         // create new edges and new faces
    7673              : 
    7674              :                         std::vector<Face*> newFracFaceVec = std::vector<Face*>();
    7675              : 
    7676            0 :                         bool boundAtShiftVrtEdg = true;
    7677              : //                      bool atStartSort = true;
    7678              : 
    7679              :                         // ecf typ: ExpandCrossFracInfo
    7680              : 
    7681            0 :                         for( auto const & ecf : vecExpCrossFI )
    7682              :                         {
    7683              : 
    7684              :                                 // DEBUG ASSERT TEST static_assert( std::is_same< ExpandCrossFracInfo const &, decltype( ecf ) >::value );
    7685              :                                 // get new vertex at the original fracture edge
    7686              : 
    7687              :                                 // extract this functionality to own function
    7688              : 
    7689              : //                              void createNewFacesForExtXCrossFracs( ExpandCrossFracInfo const & ecf,
    7690              : //                                                                                                        std::vector<Face*> & newFracFaceVec,
    7691              : //
    7692              : //                              )
    7693              : 
    7694              : //                              createNewFacesForExtXCrossFracs( ecf, newFracFaceVec, boundAtShiftVrtEdg, atStartSort, sh, grid, crossPt, subdomList );
    7695            0 :                                 createNewFacesForExtXCrossFracs( ecf, newFracFaceVec, boundAtShiftVrtEdg, sh, grid, crossPt, subdomList );
    7696              : 
    7697              : #if 0
    7698              :                                 std::pair<Edge*, Edge*> edgesCrossSeg = ecf.getEdge();
    7699              : 
    7700              :                                 Face * facSeg = ecf.getFace();
    7701              : 
    7702              :                                 std::pair<Vertex*, Vertex*> vertcsCrossSeg = ecf.getNormal();
    7703              : 
    7704              :                                 std::pair<Vertex*, Vertex*> vertcsCrossSegWithNewV = ecf.getNewNormal();
    7705              : 
    7706              : 
    7707              :                                 if( atStartSort || boundAtShiftVrtEdg )
    7708              :                                 {
    7709              :                                         if( vertcsCrossSeg.first != nullptr || vertcsCrossSeg.second == nullptr )
    7710              :                                                 UG_THROW("Verwechslung " << vertcsCrossSeg.first << " " << vertcsCrossSeg.second << std::endl);
    7711              :                                 }
    7712              : 
    7713              :                                 atStartSort = false;
    7714              : 
    7715              :                                 Edge * fracEdge = boundAtShiftVrtEdg ? edgesCrossSeg.first : edgesCrossSeg.second;
    7716              :                                 Edge * shiftVrtEdge = boundAtShiftVrtEdg ?  edgesCrossSeg.second : edgesCrossSeg.first;
    7717              : 
    7718              :                                 Vertex * fracVrtNew =  boundAtShiftVrtEdg ? vertcsCrossSegWithNewV.first : vertcsCrossSegWithNewV.second; // should be nullptr at first segment, to be assigned afterwards / shifted
    7719              :                                 Vertex * shiftVrt = boundAtShiftVrtEdg ? vertcsCrossSeg.second : vertcsCrossSeg.first;
    7720              :                                 Vertex * shiftVrtTest = boundAtShiftVrtEdg ? vertcsCrossSegWithNewV.second : vertcsCrossSegWithNewV.first;
    7721              : 
    7722              :                                 if( shiftVrtTest != shiftVrt )
    7723              :                                         UG_THROW("Shift Vertex verloren gegangen " << std::endl);
    7724              : 
    7725              :                                 IndexType sudoFac = sh.get_subset_index(facSeg);
    7726              : 
    7727              :                                 IndexType sudoFracEdge = sh.get_subset_index(fracEdge);
    7728              : 
    7729              :                                 if( sudoFac != sudoFracEdge )
    7730              :                                 {
    7731              :                                         UG_THROW("subdoms frac edge und face nicht gleich " << std::endl);
    7732              :                                 }
    7733              : 
    7734              :                                 // get all vertices of face, check if both known ones are contained, delete the face, create
    7735              :                                 // the additional needed edge, and create new face with new vertex
    7736              : 
    7737              : 
    7738              :                                 std::vector<Vertex*> vrtcsFace;
    7739              :                                 // assign first old vertices, then replace
    7740              : //                              std::vector<Vertex*> vrtcsNewFaceFrac = vrtcsFace;
    7741              : //                              std::vector<Vertex*> vrtcsNewFaceDiam = vrtcsFace;
    7742              : 
    7743              :                                 //      all new vertices have been assigned to newVrts.
    7744              :                                 //      Note that if newVrts[i] == NULL, then we have to take the
    7745              :                                 //      old vertex sf->vertex(i).
    7746              :                                 //      now expand the fracture edges of sf to faces.
    7747              :                                 for(size_t iVrt = 0; iVrt < facSeg->num_vertices(); iVrt++ )
    7748              :                                 {
    7749              : 
    7750              :                                         Vertex * vrt = facSeg->vertex(iVrt);
    7751              :                                         vrtcsFace.push_back( vrt );
    7752              : //                                      vrtcsNewFaceFrac.push_back( vrt );
    7753              : //                                      vrtcsNewFaceDiam.push_back( vrt );
    7754              :                                 }
    7755              : 
    7756              :                                 std::vector<Vertex*> vrtcsNewFaceFrac = vrtcsFace;
    7757              : //                              std::vector<Vertex*> vrtcsNewFaceDiam = vrtcsFace;
    7758              : 
    7759              : 
    7760              :                                 // check if known vertices are contained
    7761              : 
    7762              :                                 IndexType fraVeNuInd = -1;
    7763              :                                 IndexType shiftVeNuInd = -1;
    7764              : 
    7765              :                                 IndexType cntr = 0;
    7766              : 
    7767              :                                 for( auto const & vf : vrtcsFace )
    7768              :                                 {
    7769              :                                         if( vf == fracVrtNew )
    7770              :                                         {
    7771              :                                                 fraVeNuInd = cntr;
    7772              :                                                 UG_THROW("wie kann man hierher kommen?" << std::endl);
    7773              :                                         }
    7774              : 
    7775              :                                         if( vf == crossPt )
    7776              :                                         {
    7777              :                                                 fraVeNuInd = cntr;
    7778              :                                         }
    7779              : 
    7780              : //
    7781              :                                         if( vf == shiftVrt )
    7782              :                                                 shiftVeNuInd = cntr;
    7783              : 
    7784              :                                         cntr++;
    7785              :                                 }
    7786              : 
    7787              :                                 if( fraVeNuInd < 0 || shiftVeNuInd < 0 )
    7788              :                                         UG_THROW("frac vertex oder shift vertex not contained " << std::endl);
    7789              : 
    7790              :                                 UG_LOG("neuer frac vertex " << fraVeNuInd << " " << shiftVeNuInd << std::endl );
    7791              : 
    7792              :                                 // replace vrtcs
    7793              :                                 vrtcsNewFaceFrac[fraVeNuInd] = fracVrtNew;
    7794              : 
    7795              :                                 // compute shift of center vertex along frac edge
    7796              : 
    7797              :                                 // check subdom of frac vertex and check if in subdom List of X cross
    7798              : 
    7799              :                                 IndexType sudoOther = -1;
    7800              : 
    7801              :                                 IndexType foundSudoOther = 0;
    7802              :                                 IndexType foundSudoFac = 0;
    7803              : 
    7804              :                                 for( auto const & sd : subdomList )
    7805              :                                 {
    7806              :                                         if( sd != sudoFac )
    7807              :                                         {
    7808              :                                                 sudoOther = sd;
    7809              :                                                 foundSudoOther++;
    7810              :                                         }
    7811              :                                         else if( sd == sudoFac )
    7812              :                                         {
    7813              :                                                 foundSudoFac++;
    7814              :                                         }
    7815              :                                         else
    7816              :                                         {
    7817              :                                                 UG_THROW("Sudo not from frac and not from other?" << std::endl);
    7818              :                                         }
    7819              :                                 }
    7820              : 
    7821              :                                 if( foundSudoFac != 1 && foundSudoOther != 1 )
    7822              :                                         UG_THROW("sudo zu oft oder zu selten gefunden " << std::endl);
    7823              : 
    7824              :                                 // establish new edges and new faces
    7825              : 
    7826              :                                 if( vrtcsNewFaceFrac.size() != 4 )
    7827              :                                         UG_LOG("komische Groesse Gesicht " << std::endl);
    7828              : 
    7829              :                                 for( IndexType i = 0; i < vrtcsNewFaceFrac.size(); i++ )
    7830              :                                 {
    7831              :                                         if( vrtcsNewFaceFrac[i] == nullptr )
    7832              :                                         {
    7833              :                                                 UG_THROW("null auf " << i << std::endl);
    7834              :                                         }
    7835              : //                                      else
    7836              : //                                      {
    7837              : //                                              UG_LOG("kein null auf " << i << std::endl );
    7838              : //                                      }
    7839              :                                 }
    7840              : 
    7841              : 
    7842              :                                 UG_LOG("neue Gesichter ausserhalb Diamant Ziel " << std::endl);
    7843              : 
    7844              : //                              int a = 1 + 2;
    7845              : //
    7846              :                                 Face * newFracFace =
    7847              :                                         *grid.create<Quadrilateral>( QuadrilateralDescriptor( vrtcsNewFaceFrac[0], vrtcsNewFaceFrac[1],
    7848              :                                                                                                                                                   vrtcsNewFaceFrac[2], vrtcsNewFaceFrac[3]
    7849              :                                                                                                 ) );
    7850              : 
    7851              :                                 sh.assign_subset(newFracFace, sh.get_subset_index(facSeg) );
    7852              : //                              sh.assign_subset(newFracFace, diamantSubsNum ); testweise
    7853              : 
    7854              :                                 newFracFaceVec.push_back(newFracFace);
    7855              : 
    7856              :                                 boundAtShiftVrtEdg = ! boundAtShiftVrtEdg;
    7857              : #endif
    7858              : 
    7859              :                         }
    7860              : 
    7861              :                         UG_LOG("neue Gesichter ausserhalb Diamant erzeugt " << std::endl);
    7862              : 
    7863              :                         std::vector<Face*> newDiamFaceVec = std::vector<Face*>();
    7864              : 
    7865            0 :                         for( int indC = 0; indC < vecfis-1; indC = indC + 2 )
    7866              :                         {
    7867              : //                              IndexType indBefore = ( indC + vecExpCrossFI.size() ) % vecExpCrossFI.size();
    7868              : //                              IndexType indAfter = ( indC + 1 + vecExpCrossFI.size() ) % vecExpCrossFI.size();
    7869            0 :                                 IndexType indBefore = ( indC + vecfis ) % vecfis;
    7870            0 :                                 IndexType indAfter = ( indC + 1 + vecfis ) % vecfis;
    7871              : 
    7872              : 
    7873            0 :                                 ExpandCrossFracInfo & expCFIBeforeFracEdg = vecExpCrossFI[ indBefore ];
    7874            0 :                                 ExpandCrossFracInfo & expCFIAfterFracEdg = vecExpCrossFI[ indAfter ];
    7875              : 
    7876              :                                 // auslagern
    7877              : 
    7878              : //                              createDiamondFacesXCrossType( ExpandCrossFracInfo & expCFIBeforeFracEdg, ExpandCrossFracInfo & expCFIAfterFracEdg,
    7879              : //                                              std::vector<Face*> newDiamFaceVec )
    7880              : 
    7881              : #if 1
    7882              : //                              createDiamondFacesXCrossType( expCFIBeforeFracEdg, expCFIAfterFracEdg,
    7883              : //                                              newDiamFaceVec,  sh, grid, diamantSubsNum, crossPt );
    7884              : 
    7885            0 :                                 createDiamondFacesXCrossType( expCFIBeforeFracEdg, expCFIAfterFracEdg,
    7886              :                                                 newDiamFaceVec,  sh, grid, diamantSubsNum, crossPt, useTrianglesInDiamonds );
    7887              : 
    7888              : #else
    7889              :                                 Face * facBefore = expCFIBeforeFracEdg.getFace();
    7890              :                                 Face * facAfter = expCFIAfterFracEdg.getFace();
    7891              : 
    7892              :                                 std::vector<Vertex*> vrtcsFaceBefore;
    7893              :                                 std::vector<Vertex*> vrtcsFaceAfter;
    7894              : 
    7895              : 
    7896              :                                 for(size_t iVrt = 0; iVrt < facBefore->num_vertices(); iVrt++ )
    7897              :                                 {
    7898              :                                         Vertex * vrt = facBefore->vertex(iVrt);
    7899              :                                         vrtcsFaceBefore.push_back( vrt );
    7900              :                                 }
    7901              : 
    7902              :                                 for(size_t iVrt = 0; iVrt < facAfter->num_vertices(); iVrt++ )
    7903              :                                 {
    7904              :                                         Vertex * vrt = facAfter->vertex(iVrt);
    7905              :                                         vrtcsFaceAfter.push_back( vrt );
    7906              :                                 }
    7907              : 
    7908              :                                 Vertex * newVrtBefore = expCFIBeforeFracEdg.getNewNormal().first;
    7909              :                                 Vertex * shiftVrt = expCFIBeforeFracEdg.getNewNormal().second;
    7910              :                                 Vertex * newVrtAfter = expCFIAfterFracEdg.getNewNormal().second;
    7911              : 
    7912              :                                 if(    expCFIBeforeFracEdg.getNewNormal().second != expCFIBeforeFracEdg.getNormal().second
    7913              :                                         || expCFIBeforeFracEdg.getNewNormal().second == nullptr
    7914              :                                         || expCFIBeforeFracEdg.getNewNormal().second != expCFIAfterFracEdg.getNewNormal().first
    7915              :                                         || expCFIAfterFracEdg.getNewNormal().first == nullptr
    7916              :                                         || expCFIAfterFracEdg.getNewNormal().first != expCFIAfterFracEdg.getNormal().first
    7917              :                                 )
    7918              :                                 {
    7919              :                                         UG_THROW("Vektorchaos " << std::endl);
    7920              :                                 }
    7921              : 
    7922              :                                 std::vector<Vertex *> vrtxSmallDiam;
    7923              : 
    7924              :                                 vrtxSmallDiam.push_back( crossPt );
    7925              :                                 vrtxSmallDiam.push_back( newVrtBefore );
    7926              :                                 vrtxSmallDiam.push_back( shiftVrt );
    7927              :                                 vrtxSmallDiam.push_back( newVrtAfter );
    7928              : 
    7929              :                                 Face * newFracFace =
    7930              :                                         *grid.create<Quadrilateral>( QuadrilateralDescriptor( vrtxSmallDiam[0], vrtxSmallDiam[1],
    7931              :                                                                                                                                                   vrtxSmallDiam[2], vrtxSmallDiam[3]
    7932              :                                                                                                 ) );
    7933              : 
    7934              :                                 sh.assign_subset(newFracFace, diamantSubsNum );
    7935              : 
    7936              :                                 newDiamFaceVec.push_back(newFracFace);
    7937              : 
    7938              : #endif
    7939              : 
    7940              :                         }
    7941              : 
    7942              : //                      sh.get_subset_name() XXXXX
    7943              : 
    7944              : //                      auto sunam = sh.get_subset_name(subdomList[0]);
    7945              : //
    7946              : //                      for( auto const & su : subdomList )
    7947              : //                      {
    7948              : //
    7949              : //                      }
    7950              : 
    7951              : //                      using SuNaTyp = decltype( sh.get_subset_name(0) );
    7952              : 
    7953              :                         // DEBUG ASSERT TEST static_assert( std::is_same<char const *, decltype( sh.get_subset_name(subdomList[0]) ) >::value );
    7954              : 
    7955            0 :                         std::string diamNam = std::string("diamant_") + std::string(const_cast<char*>( sh.get_subset_name( subdomList[0] ) ))
    7956            0 :                                                       + std::string("_") + std::string(const_cast<char*>( sh.get_subset_name( subdomList[1] ) ));
    7957              : 
    7958            0 :                         sh.set_subset_name(diamNam.c_str(),diamantSubsNum);
    7959              : 
    7960              :                         // TODO FIXME in extra Funktion packen, vielfach aufgerufen in der Art!
    7961              : 
    7962            0 :                         assignFaceSubsetToClosedFace( newFracFaceVec, grid, sh );
    7963              : 
    7964              : //                      for( auto const & nF : newFracFaceVec )
    7965              : //                      {
    7966              : //                              for(size_t iEdge = 0; iEdge < nF->num_edges(); iEdge++ )
    7967              : //                              {
    7968              : //                                      Edge* edg = grid.get_edge(nF, iEdge);
    7969              : //
    7970              : //                                      sh.assign_subset( edg, sh.get_subset_index(nF) );
    7971              : //
    7972              : //                              }
    7973              : //
    7974              : //                              for( size_t iVrt = 0; iVrt < nF->num_vertices(); iVrt++ )
    7975              : //                              {
    7976              : //                                      Vertex * vrt = nF->vertex(iVrt);
    7977              : //
    7978              : //                                      sh.assign_subset( vrt, sh.get_subset_index(nF) );
    7979              : //                              }
    7980              : //
    7981              : //                      }
    7982              : 
    7983            0 :                         assignFaceSubsetToClosedFace( newDiamFaceVec, grid, sh );
    7984              : 
    7985              : 
    7986              : //                      for( auto const & nF : newDiamFaceVec )
    7987              : //                      {
    7988              : //                              for(size_t iEdge = 0; iEdge < nF->num_edges(); iEdge++ )
    7989              : //                              {
    7990              : //                                      Edge* edg = grid.get_edge(nF, iEdge);
    7991              : //
    7992              : //                                      sh.assign_subset( edg, sh.get_subset_index(nF) );
    7993              : //
    7994              : //                              }
    7995              : //
    7996              : //                              for( size_t iVrt = 0; iVrt < nF->num_vertices(); iVrt++ )
    7997              : //                              {
    7998              : //                                      Vertex * vrt = nF->vertex(iVrt);
    7999              : //
    8000              : //                                      sh.assign_subset( vrt, sh.get_subset_index(nF) );
    8001              : //                              }
    8002              : //
    8003              : //                      }
    8004              : 
    8005              : 
    8006              : #if 0
    8007              :                         // at end delete all fracture edges which are too long
    8008              : 
    8009              :                         for( auto const & fdel : vecExpCrossFI )
    8010              :                         {
    8011              :                                 Face * fac2BeDeleted = fdel.getFace();
    8012              : 
    8013              :                                 if( fac2BeDeleted != nullptr )
    8014              :                                         grid.erase(fac2BeDeleted);
    8015              :                                 else
    8016              :                                         UG_THROW("hier fehlt ein Gesicht " << std::endl);
    8017              :                         }
    8018              : 
    8019              : //                      IndexType subsNumNow = sh.num_subsets();
    8020              : //
    8021              : ////                    IndexType susu = subsNumNow;
    8022              : //
    8023              : ////                    UG_LOG("subs num " << susu << std::endl);
    8024              : //                      UG_LOG("subs num " << subsNumNow << std::endl);
    8025              : //
    8026              :                         for( auto const & edg : allAssoEdgCP )
    8027              :                         {
    8028              : //                              Edge * e2D = oEdg;
    8029              : 
    8030              :                                 if( edg != nullptr )
    8031              :                                 {
    8032              :                                         UG_LOG("will erasieren " << edg << std::endl );
    8033              :                                         grid.erase(edg);
    8034              : 
    8035              : //                                      sh.assign_subset( e2D, subsNumNow );
    8036              : //                                      sh.assign_subset( e2D, subsNumNow );
    8037              :                                 }
    8038              :                                 else
    8039              :                                 {
    8040              :                                         UG_LOG("hier fehlt eine Ecke " << std::endl);
    8041              :                                 }
    8042              :                         }
    8043              : 
    8044              :                         UG_LOG("ALles erasiert " << std::endl);
    8045              : #endif
    8046              : //                      for( auto & afc : assoFacCross )
    8047              : //                      {
    8048              : //                              grid.erase(afc);
    8049              : //                      }
    8050              : //
    8051              : //                      // von den Edges, die vom Schnittknoten ausgehen, die anderen Endvertizes merken, dann edges löschen
    8052              : //
    8053              : //                      std::vector<Edge *> assoEdgCross;
    8054              : //                      std::vector<Vertex *> endVertices;
    8055              : //
    8056              : //                      for( std::vector<Edge *>::iterator iterEdg = grid.associated_edges_begin(crossPt); iterEdg != grid.associated_edges_end(crossPt); iterEdg++ )
    8057              : //                      {
    8058              : //                              assoEdgCross.push_back(*iterEdg);
    8059              : //
    8060              : //                              for( size_t i = 0; i < 2; i++ )
    8061              : //                              {
    8062              : //                                      Vertex * vrtEdgEnd = (*iterEdg)->vertex(i);
    8063              : //
    8064              : //                                      if( vrtEdgEnd != crossPt )
    8065              : //                                      {
    8066              : //                                              endVertices.push_back( vrtEdgEnd );
    8067              : //                                      }
    8068              : //                              }
    8069              : //                      }
    8070              : //
    8071              : //#if 0
    8072              : //                      vector3 shiftPart;
    8073              : //                      VecAdd(shiftPart, fracVrtPos, shiftAlongEdgeTwo);
    8074              : //
    8075              : //                      vector3 posNewVrt;
    8076              : //                      VecAdd( posNewVrt, shiftPart, shiftAlongEdgeOne);
    8077              : //
    8078              : //                      UG_LOG("neuer Vertex Kreuzung " << posNewVrt << std::endl );
    8079              : //
    8080              : //                      Vertex * newShiftVrtx = *grid.create<RegularVertex>();
    8081              : //                      aaPos[newShiftVrtx] = posNewVrt;
    8082              : //
    8083              : //#endif
    8084              : //
    8085              : //                      for( auto & aec : assoEdgCross )
    8086              : //                      {
    8087              : //                              grid.erase(aec);
    8088              : //                      }
    8089              : 
    8090              : 
    8091            0 :                 }
    8092              : 
    8093              : #if 1
    8094            0 :                 for( auto const & fdel : vecExpCrossFI )
    8095              :                 {
    8096              :                         Face * fac2BeDeleted = fdel.getFace();
    8097              : 
    8098            0 :                         if( fac2BeDeleted != nullptr )
    8099            0 :                                 grid.erase(fac2BeDeleted);
    8100              :                         else
    8101            0 :                                 UG_THROW("hier fehlt ein Gesicht " << std::endl);
    8102              :                 }
    8103              : 
    8104            0 :                 if( ! useTrianglesInDiamonds ) // stamdard case
    8105              :                 {
    8106            0 :                         for( auto const & edg : allAssoEdgCP )
    8107              :                         {
    8108            0 :                                 if( edg != nullptr && edg != avoidToDeleteEdge )
    8109              :                                 {
    8110            0 :                                         UG_LOG("will erasieren " << edg << std::endl );
    8111            0 :                                         grid.erase(edg);
    8112              : 
    8113              :                                 }
    8114              :                                 else
    8115              :                                 {
    8116              :                                         UG_LOG("hier fehlt eine Ecke " << std::endl);
    8117              :                                 }
    8118              :                         }
    8119              :                 }
    8120              :                 else
    8121              :                 {
    8122            0 :                         for( auto const & edg : origFracEdg )
    8123              :                         {
    8124            0 :                                 grid.erase(edg);
    8125              :                         }
    8126              :                 }
    8127              : 
    8128              : 
    8129              :                 UG_LOG("ALles erasiert " << std::endl);
    8130              : #endif
    8131            0 :         }
    8132              : 
    8133              : //      grid.detach_from_edges( aAdjVert );
    8134              : 
    8135              :         // die frac vertices entfernen noch
    8136              : 
    8137              : //      for( auto const & cfi : vecCrossVrtInf )
    8138              : //      {
    8139              : //              IndexType nuCroFra =  cfi.getNumbCrossFracs();
    8140              : //
    8141              : //              VecEdge origFracEdg = cfi.getVecOrigFracEdges();
    8142              : //
    8143              : //
    8144              : //              if( nuCroFra == 3 )
    8145              : //              {
    8146              : //
    8147              : //              }
    8148              : //              else if( nuCroFra == 4 )
    8149              : //              {
    8150              : //                      IndexType subsNumNow = sh.num_subsets();
    8151              : //
    8152              : //      //                      IndexType susu = subsNumNow;
    8153              : //
    8154              : //      //                      UG_LOG("subs num " << susu << std::endl);
    8155              : //                      UG_LOG("subs num " << subsNumNow << std::endl);
    8156              : //
    8157              : //                      for( auto const & oEdg : origFracEdg )
    8158              : //                      {
    8159              : //                              Edge * e2D = oEdg;
    8160              : //
    8161              : //                              if( e2D != nullptr )
    8162              : //                              {
    8163              : //      //                                      grid.erase(edg2BeDel);
    8164              : //                                      UG_LOG("will erasieren " << e2D << std::endl );
    8165              : //
    8166              : //                                      sh.assign_subset( e2D, subsNumNow );
    8167              : //      //                                      sh.assign_subset( e2D, subsNumNow );
    8168              : //                              }
    8169              : //                              else
    8170              : //                              {
    8171              : //                                              UG_LOG("hier fehlt eine Ecke " << std::endl);
    8172              : //                              }
    8173              : //                      }
    8174              : //
    8175              : //              }
    8176              : //      }
    8177              : 
    8178              :         UG_LOG("zu Ende gekommen mit Arte 2D" << std::endl);
    8179              : 
    8180              :         return true;
    8181              : 
    8182              :         // ENDE NEUES ZEUG SELEKTION
    8183              : 
    8184              : 
    8185              : 
    8186              : 
    8187              : 
    8188              : 
    8189              : 
    8190              : #if FORMER_PROMESH_FINITE_CLEFT_TECHNIQUE
    8191              :         // TODO FIXME von diesem Loop kann man noch für oben die calculate crease normal lernen, vielleicht minimal abgewandelt, vielleicht exakt gleich
    8192              : 
    8193              :         //      a callback that returns true if the edge is a fracture edge, neues System
    8194              :         AttachmentUnequal<Edge, Grid::EdgeAttachmentAccessor<ABool> > isFracEdgeB(aaMarkEdgeB, false);
    8195              : 
    8196              :         //      iterate over all surrounding faces and create new vertices.
    8197              :         for(FaceIterator iter_sf = sel.faces_begin(); iter_sf != sel.faces_end(); ++iter_sf)
    8198              :         {
    8199              :                 Face* sf = *iter_sf;
    8200              : 
    8201              :         //      check for each vertex whether it lies in the fracture
    8202              :         //      (aaMarkVRT > 1 in this case)
    8203              :         //      if so, we have to copy or create a vertex from/in aaVrtVec[vrt] which is
    8204              :         //      associated with the crease normal on the side of sf.
    8205              :                 for(size_t i_vrt = 0; i_vrt < sf->num_vertices(); ++i_vrt)
    8206              :                 {
    8207              :                         Vertex* vrt = sf->vertex(i_vrt);
    8208              :                         if(aaMarkVRT[vrt] > 1)
    8209              :                         {
    8210              :                         //      calculate the normal on this side of the frac
    8211              :                                 // TODO FIXME so eine Funktion brauchen wir vielleicht oben auch zur Vereinfachung des Codes!!!
    8212              :                                 vector3 n_v2 = CalculateCreaseNormal(grid, sf, vrt, isFracEdgeB, aaPos);
    8213              :                                 // das calculate crease normal scheint mir ein Schwachsinn zu sein
    8214              :                                 // aber vielleicht doch nicht?
    8215              : 
    8216              :                                 UG_LOG("calculated crease normal v2: " << n_v2 << endl);
    8217              : 
    8218              :                 }
    8219              :         }
    8220              : #endif
    8221              : 
    8222              : 
    8223              : 
    8224              : 
    8225              : 
    8226              : 
    8227              : 
    8228            0 : }
    8229              : 
    8230              : 
    8231              : 
    8232              : }// end of namespace
    8233              : 
        

Generated by: LCOV version 2.0-1