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