Tissue Forge C++ 0.2.1
Interactive, particle-based physics, chemistry and biology modeling and simulation environment
Loading...
Searching...
No Matches
tf_mesh_ops.h
Go to the documentation of this file.
1/*******************************************************************************
2 * This file is part of Tissue Forge.
3 * Copyright (c) 2022-2024 T.J. Sego and Tien Comlekoglu
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published
7 * by the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 ******************************************************************************/
19
24
25#ifndef _MODELS_VERTEX_SOLVER_TF_MESH_OPS_H_
26#define _MODELS_VERTEX_SOLVER_TF_MESH_OPS_H_
27
28
29#include "tfVertex.h"
30#include "tfSurface.h"
31#include "tfBody.h"
32
33#include <unordered_set>
34#include <unordered_map>
35#include <vector>
36
37
38namespace TissueForge::models::vertex {
39
40
47static HRESULT definedBy(const std::unordered_set<Vertex*> &verts, std::unordered_set<Surface*> &surfs) {
48 for(auto &v : verts)
49 for(auto &s : v->getSurfaces())
50 surfs.insert(s);
51 return S_OK;
52}
53
60static HRESULT definedBy(const std::unordered_set<Vertex*> &verts, std::unordered_set<Body*> &bodys) {
61 for(auto &v : verts)
62 for(auto &b : v->getBodies())
63 bodys.insert(b);
64 return S_OK;
65}
66
74static HRESULT definedBy(const std::unordered_set<Vertex*> &verts, std::unordered_set<Surface*> &surfs, std::unordered_set<Body*> &bodys) {
75 for(auto &v : verts) {
76 for(auto &s : v->getSurfaces())
77 surfs.insert(s);
78 for(auto &b : v->getBodies())
79 bodys.insert(b);
80 }
81 return S_OK;
82}
83
90static HRESULT definedBy(const std::unordered_set<Surface*> &surfs, std::unordered_set<Vertex*> &verts) {
91 for(auto &s : surfs)
92 for(auto &v : s->getVertices())
93 verts.insert(v);
94 return S_OK;
95}
96
103static HRESULT definedBy(const std::unordered_set<Surface*> &surfs, std::unordered_set<Body*> &bodys) {
104 for(auto &s : surfs)
105 for(auto &b : s->getBodies())
106 bodys.insert(b);
107 return S_OK;
108}
109
117static HRESULT definedBy(const std::unordered_set<Surface*> &surfs, std::unordered_set<Vertex*> &verts, std::unordered_set<Body*> &bodys) {
118 for(auto &s : surfs) {
119 for(auto &v : s->getVertices())
120 verts.insert(v);
121 for(auto &b : s->getBodies())
122 bodys.insert(b);
123 }
124 return S_OK;
125}
126
133static HRESULT definedBy(const std::unordered_set<Body*> &bodys, std::unordered_set<Vertex*> &verts) {
134 for(auto &b : bodys)
135 for(auto &v : b->getVertices())
136 verts.insert(v);
137 return S_OK;
138}
139
146static HRESULT definedBy(const std::unordered_set<Body*> &bodys, std::unordered_set<Surface*> &surfs) {
147 for(auto &b : bodys)
148 for(auto &s : b->getSurfaces())
149 surfs.insert(s);
150 return S_OK;
151}
152
160static HRESULT definedBy(const std::unordered_set<Body*> &bodys, std::unordered_set<Vertex*> &verts, std::unordered_set<Surface*> &surfs) {
161 for(auto &b : bodys) {
162 for(auto &v : b->getVertices())
163 verts.insert(v);
164 for(auto &s : b->getSurfaces())
165 surfs.insert(s);
166 }
167 return S_OK;
168}
169
175static std::unordered_set<Vertex*> connectedTo(const std::unordered_set<Vertex*> &verts) {
176 std::unordered_set<Vertex*> result;
177 for(auto &v : verts)
178 for(auto &nv : v->connectedVertices())
179 result.insert(nv);
180 for(auto &v : verts)
181 result.erase(v);
182 return result;
183}
184
193static HRESULT connectedTo(
194 const std::unordered_set<Vertex*> &verts,
195 std::unordered_set<Vertex*> &connectedVerts,
196 std::unordered_map<Surface*, std::unordered_set<Vertex*> > &vsmapConnected,
197 std::unordered_map<Surface*, std::unordered_set<Vertex*> > &vsmapGiven)
198{
199 for(auto &v : verts) {
200 for(auto &nv : v->connectedVertices())
201 connectedVerts.insert(nv);
202 for(auto &s : v->getSurfaces()) {
203 auto itr = vsmapGiven.find(s);
204 if(itr == vsmapGiven.end()) vsmapGiven.insert({s, {v}});
205 else itr->second.insert(v);
206 }
207 }
208 for(auto &v : verts)
209 connectedVerts.erase(v);
210 for(auto &v : connectedVerts)
211 for(auto &s : v->getSurfaces()) {
212 auto itr = vsmapConnected.find(s);
213 if(itr == vsmapConnected.end()) vsmapConnected.insert({s, {v}});
214 else itr->second.insert(v);
215 }
216 return S_OK;
217}
218
226static HRESULT connectedToMapConnected(
227 const std::unordered_set<Vertex*> &verts,
228 std::unordered_set<Vertex*> &connectedVerts,
229 std::unordered_map<Surface*, std::unordered_set<Vertex*> > &vsmap)
230{
231 for(auto &v : verts)
232 for(auto &nv : v->connectedVertices())
233 connectedVerts.insert(nv);
234 for(auto &v : verts)
235 connectedVerts.erase(v);
236 for(auto &v : connectedVerts)
237 for(auto &s : v->getSurfaces()) {
238 auto itr = vsmap.find(s);
239 if(itr == vsmap.end()) vsmap.insert({s, {v}});
240 else itr->second.insert(v);
241 }
242 return S_OK;
243}
244
252static HRESULT connectedToMapGiven(
253 const std::unordered_set<Vertex*> &verts,
254 std::unordered_set<Vertex*> &connectedVerts,
255 std::unordered_map<Surface*, std::unordered_set<Vertex*> > &vsmap)
256{
257 for(auto &v : verts) {
258 for(auto &nv : v->connectedVertices())
259 connectedVerts.insert(nv);
260 for(auto &s : v->getSurfaces()) {
261 auto itr = vsmap.find(s);
262 if(itr == vsmap.end()) vsmap.insert({s, {v}});
263 else itr->second.insert(v);
264 }
265 }
266 for(auto &v : verts)
267 connectedVerts.erase(v);
268 return S_OK;
269}
270
276static std::unordered_set<Surface*> connectedTo(const std::unordered_set<Surface*> &surfs) {
277 std::unordered_set<Surface*> result;
278 for(auto &s : surfs)
279 for(auto ns : s->connectedSurfaces())
280 result.insert(ns);
281 for(auto &s : surfs)
282 result.erase(s);
283 return result;
284}
285
291static HRESULT connectedTo(
292 const std::unordered_set<Surface*> &surfs,
293 std::unordered_set<Surface*> &connectedSurfs,
294 std::unordered_map<Body*, std::unordered_set<Surface*> > &sbmapConnected,
295 std::unordered_map<Body*, std::unordered_set<Surface*> > &sbmapGiven)
296{
297 for(auto &s : surfs) {
298 for(auto ns : s->connectedSurfaces())
299 connectedSurfs.insert(ns);
300 for(auto b : s->getBodies()) {
301 auto itr = sbmapGiven.find(b);
302 if(itr == sbmapGiven.end()) sbmapGiven.insert({b, {s}});
303 else itr->second.insert(s);
304 }
305 }
306 for(auto &s : surfs)
307 connectedSurfs.erase(s);
308 for(auto &s : connectedSurfs)
309 for(auto &b : s->getBodies()) {
310 auto itr = sbmapConnected.find(b);
311 if(itr == sbmapConnected.end()) sbmapConnected.insert({b, {s}});
312 else itr->second.insert(s);
313 }
314 return S_OK;
315}
316
324static HRESULT connectedToMapConnected(
325 const std::unordered_set<Surface*> &surfs,
326 std::unordered_set<Surface*> &connectedSurfs,
327 std::unordered_map<Body*, std::unordered_set<Surface*> > &sbmap)
328{
329 for(auto &s : surfs)
330 for(auto ns : s->connectedSurfaces())
331 connectedSurfs.insert(ns);
332 for(auto &s : surfs)
333 connectedSurfs.erase(s);
334 for(auto &s : connectedSurfs)
335 for(auto &b : s->getBodies()) {
336 auto itr = sbmap.find(b);
337 if(itr == sbmap.end()) sbmap.insert({b, {s}});
338 else itr->second.insert(s);
339 }
340 return S_OK;
341}
342
350static HRESULT connectedToMapGiven(
351 const std::unordered_set<Surface*> &surfs,
352 std::unordered_set<Surface*> &connectedSurfs,
353 std::unordered_map<Body*, std::unordered_set<Surface*> > &sbmap)
354{
355 for(auto &s : surfs) {
356 for(auto ns : s->connectedSurfaces())
357 connectedSurfs.insert(ns);
358 for(auto &b : s->getBodies()) {
359 auto itr = sbmap.find(b);
360 if(itr == sbmap.end()) sbmap.insert({b, {s}});
361 else itr->second.insert(s);
362 }
363 }
364 for(auto &s : surfs)
365 connectedSurfs.erase(s);
366 return S_OK;
367}
368
374static std::unordered_set<Body*> connectedTo(const std::unordered_set<Body*> &bodys) {
375 std::unordered_set<Body*> result;
376 for(auto &b : bodys)
377 for(auto nb : b->connectedBodies())
378 result.insert(nb);
379 for(auto &b : bodys)
380 result.erase(b);
381 return result;
382}
383
389static std::unordered_set<Vertex*> connectingThrough(const std::unordered_set<Surface*> surfs) {
390 std::unordered_multimap<Surface*, Vertex*> cpmap;
391 std::unordered_set<Vertex*> result;
392 for(auto &s : surfs)
393 for(auto &ns : s->connectedSurfaces())
394 for(auto &v : ns->connectingVertices(s))
395 cpmap.insert({ns, v});
396 for(auto &s : surfs)
397 cpmap.erase(s);
398 for(auto &p : cpmap)
399 result.insert(p.second);
400 return result;
401}
402
408static std::unordered_set<Surface*> connectingThrough(const std::unordered_set<Body*> bodys) {
409 std::unordered_multimap<Body*, Surface*> cpmap;
410 std::unordered_set<Surface*> result;
411 for(auto &b : bodys)
412 for(auto &nb : b->connectedBodies())
413 for(auto &s : nb->findInterface(b))
414 cpmap.insert({nb, s});
415 for(auto &b : bodys)
416 cpmap.erase(b);
417 for(auto &p : cpmap)
418 result.insert(p.second);
419 return result;
420}
421
428static HRESULT connectingThrough(const std::unordered_set<Body*> bodys, std::unordered_set<Vertex*> &result) {
429 std::unordered_multimap<Body*, Vertex*> cpmap;
430 for(auto &b : bodys)
431 for(auto &v : b->getVertices())
432 for(auto &nb : v->getBodies())
433 if(b != nb)
434 cpmap.insert({nb, v});
435 for(auto &b : bodys)
436 cpmap.erase(b);
437 for(auto &p : cpmap)
438 result.insert(p.second);
439 return S_OK;
440}
441
449static HRESULT connectingThrough(
450 const std::unordered_set<Body*> bodys,
451 std::unordered_set<Surface*> &interfaceSurfs,
452 std::unordered_set<Vertex*> &interfaceVerts)
453{
454 std::unordered_multimap<Body*, Vertex*> bvmap;
455 std::unordered_multimap<Body*, Surface*> bsmap;
456 for(auto &b : bodys)
457 for(auto &nb : b->adjacentBodies()) {
458 bool hasInterface = false;
459 for(auto &s : nb->findInterface(b)) {
460 hasInterface = true;
461 bsmap.insert({nb, s});
462 }
463 if(!hasInterface)
464 for(auto v : nb->sharedVertices(b))
465 bvmap.insert({nb, v});
466 }
467 for(auto &b : bodys) {
468 bsmap.erase(b);
469 bvmap.erase(b);
470 }
471 for(auto &p : bsmap)
472 interfaceSurfs.insert(p.second);
473 for(auto &p : bvmap)
474 interfaceVerts.insert(p.second);
475 return S_OK;
476}
477
484static std::unordered_set<Body*> adjacentTo(const std::unordered_set<Body*> &bodys) {
485 std::unordered_set<Body*> result;
486 for(auto &b : bodys)
487 for(auto &nb : b->adjacentBodies())
488 result.insert(nb);
489 for(auto &b : bodys)
490 result.erase(b);
491 return result;
492}
493
499static std::unordered_set<Vertex*> orphanedVertices(const std::unordered_set<Surface*> &toRemove) {
500 std::unordered_set<Vertex*> result, affected;
501 for(auto &r : toRemove)
502 for(auto &a : r->getVertices())
503 affected.insert(a);
504 for(auto &a : affected) {
505 int numChildren = a->getSurfaces().size();
506 for(auto &r : toRemove)
507 if(a->defines(r))
508 numChildren--;
509 if(numChildren < 1)
510 result.insert(a);
511 }
512 return result;
513}
514
520static std::unordered_set<Surface*> orphanedSurfaces(const std::unordered_set<Body*> &toRemove) {
521 std::unordered_set<Surface*> result, affected;
522 for(auto &r : toRemove)
523 for(auto &a : r->getSurfaces())
524 affected.insert(a);
525 for(auto &a : affected) {
526 int numChildren = a->getBodies().size();
527 for(auto &r : toRemove)
528 if(a->defines(r))
529 numChildren--;
530 if(numChildren < 1)
531 result.insert(a);
532 }
533 return result;
534}
535
543static std::unordered_set<Surface*> removedChildrenByRemovedParents(const std::unordered_set<Vertex*> &toRemove) {
544 if(toRemove.empty())
545 return {};
546
547 // Get the affected surfaces by all removed vertices
548 std::vector<Surface*> affectedSurfacesTotal;
549 std::unordered_set<Surface*> affectedSurfacesSet;
550 for(auto &v : toRemove)
551 for(auto &s : v->getSurfaces()) {
552 affectedSurfacesSet.insert(s);
553 affectedSurfacesTotal.push_back(s);
554 }
555 if(affectedSurfacesSet.empty())
556 return {};
557
558 std::vector<Surface*> affectedSurfaces(affectedSurfacesSet.begin(), affectedSurfacesSet.end());
559 std::vector<unsigned int> removedSurfCount(affectedSurfaces.size(), 0);
560
561 // Count number of removed vertices per surface
562 for(auto &s : affectedSurfacesTotal)
563 for(int i = 0; i < affectedSurfaces.size(); i++)
564 if(affectedSurfaces[i] == s)
565 removedSurfCount[i]++;
566
567 // Collect bodies that would become invalidated and return the collection
568 std::unordered_set<Surface*> result;
569 for(int i = 0; i < affectedSurfaces.size(); i++) {
570 Surface *s = affectedSurfaces[i];
571 if(s->getVertices().size() - removedSurfCount[i] < 3)
572 result.insert(s);
573 }
574 return result;
575}
576
584static std::vector<Surface*> removedChildrenByRemovedParents(const std::vector<Vertex*> &toRemove) {
585 std::unordered_set<Surface*> result = removedChildrenByRemovedParents(std::unordered_set<Vertex*>(toRemove.begin(), toRemove.end()));
586 return std::vector<Surface*>(result.begin(), result.end());
587}
588
594static std::unordered_set<Body*> removedChildrenByRemovedParents(const std::unordered_set<Surface*> &toRemove) {
595 if(toRemove.empty())
596 return {};
597
598 // Get the affected bodies by all removed surfaces
599 std::vector<Body*> affectedBodiesTotal;
600 std::unordered_set<Body*> affectedBodiesSet;
601 for(auto &s : toRemove)
602 for(auto &b : s->getBodies()) {
603 affectedBodiesSet.insert(b);
604 affectedBodiesTotal.push_back(b);
605 }
606 if(affectedBodiesSet.empty())
607 return {};
608
609 std::vector<Body*> affectedBodies(affectedBodiesSet.begin(), affectedBodiesSet.end());
610 std::vector<unsigned int> removedSurfCount(affectedBodies.size(), 0);
611
612 // Count number of removed surfaces per body
613 for(auto &b : affectedBodiesTotal)
614 for(int i = 0; i < affectedBodies.size(); i++)
615 if(affectedBodies[i] == b)
616 removedSurfCount[i]++;
617
618 // Collect bodies that would become invalidated and return the collection
619 std::unordered_set<Body*> result;
620 for(int i = 0; i < affectedBodies.size(); i++) {
621 Body *b = affectedBodies[i];
622 if(b->getSurfaces().size() - removedSurfCount[i] < 4)
623 result.insert(b);
624 }
625 return result;
626}
627
633static std::vector<Body*> removedChildrenByRemovedParents(const std::vector<Surface*> &toRemove) {
634 std::unordered_set<Body*> result = removedChildrenByRemovedParents(std::unordered_set<Surface*>(toRemove.begin(), toRemove.end()));
635 return std::vector<Body*>(result.begin(), result.end());
636}
637
645static std::unordered_set<Surface*> removedSurfacesByS2V(const Surface *toRemove) {
646 std::unordered_set<Surface*> result;
647 for(auto &s : toRemove->connectedSurfaces())
648 if(s->getVertices().size() - s->connectingVertices(toRemove).size() < 2)
649 result.insert(s);
650 return result;
651}
652
658static std::unordered_set<Surface*> connectedSurfacesToS2V(const std::unordered_set<Surface*> &removed) {
659 std::unordered_set<Surface*> result;
660 for(auto &s : removed)
661 for(auto &ns : s->connectedSurfaces())
662 result.insert(ns);
663 for(auto &s : removed)
664 result.erase(s);
665 return result;
666}
667
673static std::unordered_set<Surface*> connectedSurfacesToS2V(const Surface *toRemove) {
674 std::unordered_set<Surface*> result = connectedSurfacesToS2V(removedSurfacesByS2V(toRemove));
675 result.erase(const_cast<Surface*>(toRemove));
676 return result;
677}
678
679static std::unordered_map<Surface*, std::unordered_set<Vertex*> > mapSurfaceReplacementsByB2V(
680 std::unordered_set<Body*> &removedBodies,
681 std::unordered_set<Surface*> &removedSurfaces)
682{
683 std::unordered_map<Surface*, std::unordered_set<Vertex*> > result;
684
685 std::unordered_set<Surface*> connectingSurfs;
686 std::unordered_set<Vertex*> connectingVerts;
687 connectingThrough(removedBodies, connectingSurfs, connectingVerts);
688
689 std::unordered_multimap<Body*, std::pair<Surface*, std::unordered_set<Vertex*> > > bsmap;
690 for(auto &v : connectingVerts)
691 for(auto &s : v->getSurfaces())
692 for(auto &b : s->getBodies())
693 bsmap.insert({b, {s, {v}}});
694 for(auto &s : connectingSurfs)
695 for(auto &ns : s->connectedSurfaces()) {
696 std::vector<Vertex*> connectingVertices = s->connectingVertices(ns);
697 std::pair<Surface*, std::unordered_set<Vertex*> > p = {ns, {connectingVertices.begin(), connectingVertices.end()}};
698 for(auto &b : ns->getBodies())
699 bsmap.insert({b, p});
700 }
701 for(auto &b : removedBodies)
702 bsmap.erase(b);
703 std::unordered_multimap<Surface*, std::unordered_set<Vertex*> > svmap;
704 for(auto &p : bsmap)
705 svmap.insert({p.second.first, p.second.second});
706 for(auto &s : removedSurfaces)
707 svmap.erase(s);
708 for(unsigned int i = 0; i < svmap.bucket_count(); i++) {
709 Surface *s = NULL;
710 std::unordered_set<Vertex*> vs;
711 for(auto itr = svmap.begin(i); itr != svmap.end(i); itr++) {
712 if(!s)
713 s = itr->first;
714 for(auto &v : itr->second)
715 vs.insert(v);
716 }
717 if(!s)
718 continue;
719 if(s->getVertices().size() - vs.size() < 2)
720 removedSurfaces.insert(s);
721 else
722 result.insert({s, vs});
723 }
724
725 return result;
726}
727
738static HRESULT transformedByB2V(
739 const Body *body,
740 std::unordered_set<Vertex*> &removedVertices,
741 std::unordered_set<Surface*> &removedSurfaces,
742 std::unordered_set<Body*> &removedBodies,
743 std::unordered_map<Surface*, std::unordered_set<Vertex*> > &replacementMap)
744{
745 std::unordered_set<Body*> _removedBodies = {const_cast<Body*>(body)};
746 std::unordered_set<Vertex*> _removedVertices;
747 std::unordered_set<Surface*> _removedSurfaces;
748
749 definedBy(_removedBodies, _removedVertices, _removedSurfaces);
750 size_t num_surfs = _removedSurfaces.size();
751 std::unordered_map<Surface*, std::unordered_set<Vertex*> > _replacementMap = mapSurfaceReplacementsByB2V(_removedBodies, _removedSurfaces);
752
753 while(_removedSurfaces.size() > num_surfs) {
754 num_surfs = _removedSurfaces.size();
755 _removedBodies = removedChildrenByRemovedParents(_removedSurfaces);
756 definedBy(_removedBodies, _removedVertices, _removedSurfaces);
757 _replacementMap = mapSurfaceReplacementsByB2V(_removedBodies, _removedSurfaces);
758 }
759
760 for(auto &v : _removedVertices)
761 removedVertices.insert(v);
762 for(auto &s : _removedSurfaces)
763 removedSurfaces.insert(s);
764 for(auto &b : _removedBodies)
765 removedBodies.insert(b);
766 for(auto &p : _replacementMap)
767 replacementMap.insert(p);
768
769 return S_OK;
770}
771
777static std::unordered_set<Vertex*> removedVerticesByB2V(const Body *body) {
778 std::unordered_set<Body*> _removedBodies = {const_cast<Body*>(body)};
779 std::unordered_set<Vertex*> _removedVertices;
780 std::unordered_set<Surface*> _removedSurfaces;
781
782 definedBy(_removedBodies, _removedVertices, _removedSurfaces);
783 size_t num_surfs = _removedSurfaces.size();
784 mapSurfaceReplacementsByB2V(_removedBodies, _removedSurfaces);
785
786 while(_removedSurfaces.size() > num_surfs) {
787 num_surfs = _removedSurfaces.size();
788 _removedBodies = removedChildrenByRemovedParents(_removedSurfaces);
789 definedBy(_removedBodies, _removedVertices, _removedSurfaces);
790 mapSurfaceReplacementsByB2V(_removedBodies, _removedSurfaces);
791 }
792
793 return _removedVertices;
794}
795
801static std::unordered_set<Surface*> removedSurfacesByB2V(const Body *body) {
802 std::unordered_set<Body*> _removedBodies = {const_cast<Body*>(body)};
803 std::unordered_set<Vertex*> _removedVertices;
804 std::unordered_set<Surface*> _removedSurfaces;
805
806 definedBy(_removedBodies, _removedVertices, _removedSurfaces);
807 size_t num_surfs = _removedSurfaces.size();
808 mapSurfaceReplacementsByB2V(_removedBodies, _removedSurfaces);
809
810 while(_removedSurfaces.size() > num_surfs) {
811 num_surfs = _removedSurfaces.size();
812 _removedBodies = removedChildrenByRemovedParents(_removedSurfaces);
813 definedBy(_removedBodies, _removedVertices, _removedSurfaces);
814 mapSurfaceReplacementsByB2V(_removedBodies, _removedSurfaces);
815 }
816
817 return _removedSurfaces;
818}
819
825static std::unordered_set<Body*> removedBodiesByB2V(const Body *body) {
826 std::unordered_set<Body*> _removedBodies = {const_cast<Body*>(body)};
827 std::unordered_set<Vertex*> _removedVertices;
828 std::unordered_set<Surface*> _removedSurfaces;
829
830 definedBy(_removedBodies, _removedVertices, _removedSurfaces);
831 size_t num_surfs = _removedSurfaces.size();
832 mapSurfaceReplacementsByB2V(_removedBodies, _removedSurfaces);
833
834 while(_removedSurfaces.size() > num_surfs) {
835 num_surfs = _removedSurfaces.size();
836 _removedBodies = removedChildrenByRemovedParents(_removedSurfaces);
837 definedBy(_removedBodies, _removedVertices, _removedSurfaces);
838 mapSurfaceReplacementsByB2V(_removedBodies, _removedSurfaces);
839 }
840
841 return _removedBodies;
842}
843
844static std::unordered_map<Surface*, std::unordered_set<Vertex*> > surfaceReplacementsByB2V(const Body *body)
845{
846 std::unordered_set<Body*> _removedBodies = {const_cast<Body*>(body)};
847 std::unordered_set<Vertex*> _removedVertices;
848 std::unordered_set<Surface*> _removedSurfaces;
849
850 definedBy(_removedBodies, _removedVertices, _removedSurfaces);
851 size_t num_surfs = _removedSurfaces.size();
852 std::unordered_map<Surface*, std::unordered_set<Vertex*> > _replacementMap = mapSurfaceReplacementsByB2V(_removedBodies, _removedSurfaces);
853
854 while(_removedSurfaces.size() > num_surfs) {
855 num_surfs = _removedSurfaces.size();
856 _removedBodies = removedChildrenByRemovedParents(_removedSurfaces);
857 definedBy(_removedBodies, _removedVertices, _removedSurfaces);
858 _replacementMap = mapSurfaceReplacementsByB2V(_removedBodies, _removedSurfaces);
859 }
860
861 return _replacementMap;
862}
863
871static std::unordered_set<Vertex*> removedVerticesByS2V(const Surface *toRemove) {
872 std::unordered_set<Vertex*> result;
873 definedBy(removedSurfacesByS2V(toRemove), result);
874 return result;
875}
876
877
878};
879
880
881#endif // _MODELS_VERTEX_SOLVER_TF_MESH_OPS_H_
The mesh body is a volume-enclosing object of mesh surfaces.
Definition tfBody.h:59
The mesh surface is an area-enclosed object of implicit mesh edges defined by mesh vertices.
Definition tfSurface.h:65
HRESULT insert(Vertex *v, const int &idx)
Insert a vertex at a location in the list of vertices.
HRESULT body(MeshObjActor *a, BodyType *b)
Bind an actor to a body type.
int32_t HRESULT
Definition tf_port.h:255