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