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 :
|