MeshLib C++ Docs
Loading...
Searching...
No Matches
MRMeshTopology.h
Go to the documentation of this file.
1#pragma once
2
3#include "MRPch/MRBindingMacros.h"
4#include "MRId.h"
5#include "MRVector.h"
6#include "MRBitSet.h"
7#include "MRPartMapping.h"
8#include "MRMeshTriPoint.h"
10#include "MRExpected.h"
11#include "MREnums.h"
12#include <iosfwd>
13
14namespace MR
15{
18
19
21{
22 UndirectedEdgeBitSet edges;
23 VertBitSet verts;
24 FaceBitSet faces;
25};
26
30{
31public:
33 [[nodiscard]] MRMESH_API EdgeId makeEdge();
34
36 [[nodiscard]] MRMESH_API bool isLoneEdge( EdgeId a ) const;
37
39 [[nodiscard]] MRMESH_API UndirectedEdgeId lastNotLoneUndirectedEdge() const;
40
42 [[nodiscard]] EdgeId lastNotLoneEdge() const { auto ue = lastNotLoneUndirectedEdge(); return ue ? EdgeId( ue ) + 1 : EdgeId(); }
43
45 MRMESH_API void excludeLoneEdges( UndirectedEdgeBitSet & edges ) const;
46
48 [[nodiscard]] size_t edgeSize() const { return edges_.size(); }
49
51 [[nodiscard]] size_t edgeCapacity() const { return edges_.capacity(); }
52
54 [[nodiscard]] size_t undirectedEdgeSize() const { return edges_.size() >> 1; }
55
57 [[nodiscard]] size_t undirectedEdgeCapacity() const { return edges_.capacity() >> 1; }
58
60 [[nodiscard]] MRMESH_API size_t computeNotLoneUndirectedEdges() const;
61
63 [[nodiscard]] MRMESH_API UndirectedEdgeBitSet findNotLoneUndirectedEdges() const;
64
66 void edgeReserve( size_t newCapacity ) { edges_.reserve( newCapacity ); }
67
69 [[nodiscard]] bool hasEdge( EdgeId e ) const { assert( e.valid() ); return e < (int)edgeSize() && !isLoneEdge( e ); }
70
72 [[nodiscard]] MRMESH_API size_t heapBytes() const;
73
76
79
80
85 MRMESH_API void splice( EdgeId a, EdgeId b );
86
94 MRMESH_API EdgeId collapseEdge( EdgeId e, const std::function<void( EdgeId del, EdgeId rem )> & onEdgeDel );
95
96
98 [[nodiscard]] EdgeId next( EdgeId he ) const { assert(he.valid()); return edges_[he].next; }
99
101 [[nodiscard]] EdgeId prev( EdgeId he ) const { assert(he.valid()); return edges_[he].prev; }
102
104 [[nodiscard]] VertId org( EdgeId he ) const { assert(he.valid()); return edges_[he].org; }
105
107 [[nodiscard]] VertId dest( EdgeId he ) const { assert(he.valid()); return edges_[he.sym()].org; }
108
110 [[nodiscard]] FaceId left( EdgeId he ) const { assert(he.valid()); return edges_[he].left; }
111
113 [[nodiscard]] FaceId right( EdgeId he ) const { assert(he.valid()); return edges_[he.sym()].left; }
114
115
118 MRMESH_API void setOrg( EdgeId a, VertId v );
119
122 MRMESH_API void setLeft( EdgeId a, FaceId f );
123
124
126 [[nodiscard]] MRMESH_API bool fromSameOriginRing( EdgeId a, EdgeId b ) const;
127
129 [[nodiscard]] MRMESH_API bool fromSameLeftRing( EdgeId a, EdgeId b ) const;
130
131
133 [[nodiscard]] MRMESH_API int getOrgDegree( EdgeId a ) const;
134
136 [[nodiscard]] int getVertDegree( VertId v ) const { return getOrgDegree( edgeWithOrg( v ) ); }
137
139 [[nodiscard]] MRMESH_API bool isOrgInnerAndHasDegree( EdgeId a, int d ) const;
140
142 [[nodiscard]] bool isVertInnerAndHasDegree( VertId v, int d ) const { return isOrgInnerAndHasDegree( edgeWithOrg( v ), d ); }
143
145 [[nodiscard]] MRMESH_API int getLeftDegree( EdgeId a ) const;
146
148 [[nodiscard]] int getFaceDegree( FaceId f ) const { return getLeftDegree( edgeWithLeft( f ) ); }
149
151 [[nodiscard]] MRMESH_API bool isLeftTri( EdgeId a ) const;
152
155 void getTriVerts( FaceId f, VertId & v0, VertId & v1, VertId & v2 ) const { getLeftTriVerts( edgeWithLeft( f ), v0, v1, v2 ); }
156 MR_BIND_IGNORE void getTriVerts( FaceId f, VertId (&v)[3] ) const { getLeftTriVerts( edgeWithLeft( f ), v ); }
157 void getTriVerts( FaceId f, ThreeVertIds & v ) const { getLeftTriVerts( edgeWithLeft( f ), v ); }
158 [[nodiscard]] ThreeVertIds getTriVerts( FaceId f ) const { return getLeftTriVerts( edgeWithLeft( f ) ); }
159
161 [[nodiscard]] bool isTriVert( FaceId f, VertId v ) const { auto vs = getTriVerts( f ); return v == vs[0] || v == vs[1] || v == vs[2]; }
162
164 [[nodiscard]] MRMESH_API std::vector<ThreeVertIds> getAllTriVerts() const;
165
168 [[nodiscard]] MRMESH_API Triangulation getTriangulation() const;
169
172 MRMESH_API void getLeftTriVerts( EdgeId a, VertId & v0, VertId & v1, VertId & v2 ) const;
173 MR_BIND_IGNORE void getLeftTriVerts( EdgeId a, VertId (&v)[3] ) const { getLeftTriVerts( a, v[0], v[1], v[2] ); }
174 void getLeftTriVerts( EdgeId a, ThreeVertIds & v ) const { getLeftTriVerts( a, v[0], v[1], v[2] ); }
175 [[nodiscard]] ThreeVertIds getLeftTriVerts( EdgeId a ) const { ThreeVertIds v; getLeftTriVerts( a, v[0], v[1], v[2] ); return v; }
176
181 template <typename T>
182 void forEachVertex( const MeshTriPoint & p, T && callback ) const;
183
187 MRMESH_API void getLeftTriEdges( EdgeId e0, EdgeId & e1, EdgeId & e2 ) const;
188
191 void getTriEdges( FaceId f, EdgeId & e0, EdgeId & e1, EdgeId & e2 ) const { getLeftTriEdges( e0 = edgeWithLeft( f ), e1, e2 ); }
192 MR_BIND_IGNORE void getTriEdges( FaceId f, EdgeId (&e)[3] ) const { getLeftTriEdges( e[0] = edgeWithLeft( f ), e[1], e[2] ); }
193
195 [[nodiscard]] MRMESH_API bool isLeftQuad( EdgeId a ) const;
196
198 [[nodiscard]] const Vector<EdgeId, VertId> & edgePerVertex() const { return edgePerVertex_; }
199
201 [[nodiscard]] EdgeId edgeWithOrg( VertId a ) const { assert( a.valid() ); return a < int(edgePerVertex_.size()) ? edgePerVertex_[a] : EdgeId(); }
202
204 [[nodiscard]] bool hasVert( VertId a ) const { assert( updateValids_ ); return validVerts_.test( a ); }
205
207 [[nodiscard]] int numValidVerts() const { assert( updateValids_ ); return numValidVerts_; }
208
210 [[nodiscard]] MRMESH_API VertId lastValidVert() const;
211
213 [[nodiscard]] VertId addVertId() { edgePerVertex_.emplace_back(); if ( updateValids_ ) { validVerts_.push_back( false ); } return edgePerVertex_.backId(); }
214
216 MRMESH_API void vertResize( size_t newSize );
217
219 MRMESH_API void vertResizeWithReserve( size_t newSize );
220
222 void vertReserve( size_t newCapacity ) { edgePerVertex_.reserve( newCapacity ); if ( updateValids_ ) { validVerts_.reserve( newCapacity ); } }
223
225 [[nodiscard]] size_t vertSize() const { return edgePerVertex_.size(); }
226
228 [[nodiscard]] size_t vertCapacity() const { return edgePerVertex_.capacity(); }
229
231 [[nodiscard]] const VertBitSet & getValidVerts() const { assert( updateValids_ ); return validVerts_; }
232
234 void flip( VertBitSet & vs ) const { vs = getValidVerts() - vs; }
235
237 [[nodiscard]] const VertBitSet & getVertIds( const VertBitSet * region ) const
238 {
239 assert( region || updateValids_ );
240 assert( !updateValids_ || !region || region->is_subset_of( validVerts_ ) );
241 return region ? *region : validVerts_;
242 }
243
244
246 [[nodiscard]] const Vector<EdgeId, FaceId> & edgePerFace() const { return edgePerFace_; }
247
249 [[nodiscard]] EdgeId edgeWithLeft( FaceId a ) const { assert( a.valid() ); return a < int(edgePerFace_.size()) ? edgePerFace_[a] : EdgeId(); }
250
252 [[nodiscard]] bool hasFace( FaceId a ) const { assert( updateValids_ ); return validFaces_.test( a ); }
253
255 [[nodiscard]] MRMESH_API EdgeId sharedEdge( FaceId l, FaceId r ) const;
256
258 [[nodiscard]] MRMESH_API EdgeId sharedVertInOrg( EdgeId a, EdgeId b ) const;
259
261 [[nodiscard]] MRMESH_API EdgeId sharedVertInOrg( FaceId l, FaceId r ) const;
262
264 [[nodiscard]] MRMESH_API FaceId sharedFace( EdgeId a, EdgeId b ) const;
265
267 [[nodiscard]] int numValidFaces() const { assert( updateValids_ ); return numValidFaces_; }
268
270 [[nodiscard]] MRMESH_API FaceId lastValidFace() const;
271
273 [[nodiscard]] FaceId addFaceId() { edgePerFace_.emplace_back(); if ( updateValids_ ) { validFaces_.push_back( false ); } return edgePerFace_.backId(); }
274
276 MRMESH_API void deleteFace( FaceId f, const UndirectedEdgeBitSet * keepEdges = nullptr );
277
283 MRMESH_API VacantElements deleteFaces( const FaceBitSet & fs, const UndirectedEdgeBitSet * keepEdges = nullptr );
284
286 MRMESH_API void faceResize( size_t newSize );
287
289 MRMESH_API void faceResizeWithReserve( size_t newSize );
290
292 void faceReserve( size_t newCapacity ) { edgePerFace_.reserve( newCapacity ); if ( updateValids_ ) { validFaces_.reserve( newCapacity ); } }
293
295 [[nodiscard]] size_t faceSize() const { return edgePerFace_.size(); }
296
298 [[nodiscard]] size_t faceCapacity() const { return edgePerFace_.capacity(); }
299
301 [[nodiscard]] const FaceBitSet & getValidFaces() const { assert( updateValids_ ); return validFaces_; }
302
304 void flip( FaceBitSet & fs ) const { fs = getValidFaces() - fs; }
305
307 [[nodiscard]] const FaceBitSet & getFaceIds( const FaceBitSet * region ) const
308 {
309 assert( region || updateValids_ );
310 assert( !updateValids_ || !region || region->is_subset_of( validFaces_ ) );
311 return region ? *region : validFaces_;
312 }
313
316 [[nodiscard]] MRMESH_API EdgeId bdEdgeSameLeft( EdgeId e, const FaceBitSet * region = nullptr ) const;
317
320 [[nodiscard]] bool isLeftBdFace( EdgeId e, const FaceBitSet * region = nullptr ) const { return contains( region, left( e ) ) && bdEdgeSameLeft( e, region ).valid(); }
321
324 [[nodiscard]] EdgeId bdEdgeWithLeft( FaceId f, const FaceBitSet * region = nullptr ) const { return bdEdgeSameLeft( edgeWithLeft( f ), region ); }
325
327 [[nodiscard]] bool isBdFace( FaceId f, const FaceBitSet * region = nullptr ) const { return isLeftBdFace( edgeWithLeft( f ), region ); }
328
330 [[nodiscard]] MRMESH_API FaceBitSet findBdFaces( const FaceBitSet * region = nullptr ) const;
331
332
334 [[nodiscard]] bool isLeftInRegion( EdgeId e, const FaceBitSet * region = nullptr ) const { return contains( region, left( e ) ); }
335
337 [[nodiscard]] bool isInnerEdge( EdgeId e, const FaceBitSet * region = nullptr ) const { return isLeftInRegion( e, region ) && isLeftInRegion( e.sym(), region ); }
338
344 [[nodiscard]] MRMESH_API bool isBdEdge( EdgeId e, const FaceBitSet * region = nullptr ) const;
345
347 [[nodiscard]] MRMESH_API EdgeBitSet findLeftBdEdges( const FaceBitSet * region = nullptr, const EdgeBitSet * test = nullptr ) const;
348
351 [[nodiscard]] MRMESH_API EdgeId bdEdgeSameOrigin( EdgeId e, const FaceBitSet * region = nullptr ) const;
352
354 [[nodiscard]] bool isBdVertexInOrg( EdgeId e, const FaceBitSet * region = nullptr ) const { return bdEdgeSameOrigin( e, region ).valid(); }
355
358 [[nodiscard]] EdgeId bdEdgeWithOrigin( VertId v, const FaceBitSet * region = nullptr ) const { return bdEdgeSameOrigin( edgeWithOrg( v ), region ); }
359
361 [[nodiscard]] bool isBdVertex( VertId v, const FaceBitSet * region = nullptr ) const { return isBdVertexInOrg( edgeWithOrg( v ), region ); }
362
364 [[nodiscard]] MRMESH_API VertBitSet findBdVerts( const FaceBitSet * region = nullptr, const VertBitSet * test = nullptr ) const;
365
367 [[nodiscard]] MRMESH_API bool isInnerOrBdVertex( VertId v, const FaceBitSet * region = nullptr ) const;
368
370 [[nodiscard]] bool isLeftBdEdge( EdgeId e, const FaceBitSet * region = nullptr ) const { return region ? ( isLeftInRegion( e, region ) && !isLeftInRegion( e.sym(), region ) ) : !right( e ); }
371
373 [[nodiscard]] bool isInnerOrBdEdge( EdgeId e, const FaceBitSet * region = nullptr ) const { return isLeftInRegion( e, region ) || isLeftInRegion( e.sym(), region ); }
374
377 [[nodiscard]] MRMESH_API EdgeId nextLeftBd( EdgeId e, const FaceBitSet * region = nullptr, Turn turn = Turn::Rightmost ) const;
378
381 [[nodiscard]] MRMESH_API EdgeId prevLeftBd( EdgeId e, const FaceBitSet * region = nullptr, Turn turn = Turn::Rightmost ) const;
382
383
385 [[nodiscard]] MRMESH_API EdgeId findEdge( VertId o, VertId d ) const;
386
388 [[nodiscard]] MRMESH_API bool isClosed( const FaceBitSet * region = nullptr ) const;
389
392 [[nodiscard]] MRMESH_API std::vector<EdgeId> findHoleRepresentiveEdges( const FaceBitSet * region = nullptr ) const;
393
396 [[nodiscard]] MRMESH_API int findNumHoles( EdgeBitSet * holeRepresentativeEdges = nullptr ) const;
397
399 [[nodiscard]] MRMESH_API EdgeLoop getLeftRing( EdgeId e ) const;
400
403 [[nodiscard]] MRMESH_API std::vector<EdgeLoop> getLeftRings( const std::vector<EdgeId> & es ) const;
404
406 [[nodiscard]] [[deprecated( "Use findLeftBdEdges")]] MRMESH_API MR_BIND_IGNORE EdgeBitSet findBoundaryEdges() const;
407
410 [[nodiscard]] [[deprecated( "Use findBdFaces")]] MRMESH_API MR_BIND_IGNORE FaceBitSet findBoundaryFaces( const FaceBitSet * region = nullptr ) const;
411
414 [[nodiscard]] [[deprecated( "Use findBdVerts")]] MRMESH_API MR_BIND_IGNORE VertBitSet findBoundaryVerts( const VertBitSet * region = nullptr ) const;
415
416
418 [[nodiscard]] MRMESH_API VertBitSet getPathVertices( const EdgePath & path ) const;
419
421 [[nodiscard]] MRMESH_API FaceBitSet getPathLeftFaces( const EdgePath & path ) const;
422
424 [[nodiscard]] MRMESH_API FaceBitSet getPathRightFaces( const EdgePath & path ) const;
425
426
429 MRMESH_API void flipEdge( EdgeId e );
430
433 template<typename T>
434 void flipEdgesIn( EdgeId e0, T && flipNeeded );
435
438 template<typename T>
439 void flipEdgesIn( VertId v, T && flipNeeded ) { flipEdgesIn( edgeWithOrg( v ), std::forward<T>( flipNeeded ) ); }
440
443 template<typename T>
444 void flipEdgesOut( EdgeId e0, T && flipNeeded );
445
448 template<typename T>
449 void flipEdgesOut( VertId v, T && flipNeeded ) { flipEdgesOut( edgeWithOrg( v ), std::forward<T>( flipNeeded ) ); }
450
459 MRMESH_API EdgeId splitEdge( EdgeId e, FaceBitSet * region = nullptr, FaceHashMap * new2Old = nullptr );
460
464 MRMESH_API VertId splitFace( FaceId f, FaceBitSet * region = nullptr, FaceHashMap * new2Old = nullptr );
465
470 MRMESH_API void flipOrientation( const UndirectedEdgeBitSet * fullComponents = nullptr );
471
472
476 MRMESH_API void addPart( const MeshTopology & from, const PartMapping & map = {}, bool rearrangeTriangles = false );
477 MRMESH_API void addPart( const MeshTopology & from,
478 FaceMap * outFmap = nullptr, VertMap * outVmap = nullptr, WholeEdgeMap * outEmap = nullptr,
479 bool rearrangeTriangles = false );
480
483 MRMESH_API void addPartByMask( const MeshTopology & from, const FaceBitSet * fromFaces, const PartMapping & map = {}, VacantElements * vacant = {} );
484
486 MR_BIND_IGNORE void addPartByMask( const MeshTopology & from, const FaceBitSet & fromFaces, const PartMapping & map = {}, VacantElements * vacant = {} )
487 { addPartByMask( from, &fromFaces, map, vacant ); }
488
496 MRMESH_API bool addPartByMask( const MeshTopology & from, const FaceBitSet * fromFaces, bool flipOrientation = false,
497 const std::vector<EdgePath> & thisContours = {}, const std::vector<EdgePath> & fromContours = {},
498 const PartMapping & map = {}, VacantElements * vacant = {} );
499
501 MR_BIND_IGNORE bool addPartByMask( const MeshTopology & from, const FaceBitSet & fromFaces, bool flipOrientation = false,
502 const std::vector<EdgePath> & thisContours = {}, const std::vector<EdgePath> & fromContours = {},
503 const PartMapping & map = {}, VacantElements * vacant = {} ) { return addPartByMask( from, &fromFaces, flipOrientation, thisContours, fromContours, map, vacant ); }
504
507
512 MRMESH_API void pack( FaceMap * outFmap = nullptr, VertMap * outVmap = nullptr, WholeEdgeMap * outEmap = nullptr, bool rearrangeTriangles = false );
513
516 MRMESH_API void pack( const PackMapping & map );
517
521 MRMESH_API void packMinMem( const PackMapping & map );
522
523
525 MRMESH_API void write( std::ostream & s ) const;
526
529 MRMESH_API Expected<void> read( std::istream& s, ProgressCallback callback = {} );
530
532 [[nodiscard]] MRMESH_API bool operator ==( const MeshTopology & b ) const;
533
538
542 MRMESH_API void addPackedPart( const MeshTopology & from, EdgeId toEdgeId,
543 const FaceMap & fmap, const VertMap & vmap );
544
550
553
555 [[nodiscard]] bool updatingValids() const { return updateValids_; }
556
559 MRMESH_API void preferEdges( const UndirectedEdgeBitSet & stableEdges );
560
562 MRMESH_API bool buildGridMesh( const GridSettings& settings, ProgressCallback cb = {} );
563
566 MRMESH_API bool checkValidity( ProgressCallback cb = {}, bool allVerts = true ) const;
567
568private:
569 friend class MeshTopologyDiff;
573 MRMESH_API void computeAllFromEdges_();
574
575private:
577 void setOrg_( EdgeId a, VertId v );
578
580 void fillOrg_();
581
583 void setLeft_( EdgeId a, FaceId f );
584
586 void fillLeft_();
587
589 struct alignas( 16 ) HalfEdgeRecord
590 {
591 EdgeId next;
592 EdgeId prev;
593 VertId org;
594 FaceId left;
595
596 bool operator ==( const HalfEdgeRecord& b ) const
597 {
598 return next == b.next && prev == b.prev && org == b.org && left == b.left;
599 }
600 HalfEdgeRecord() noexcept = default;
601 explicit HalfEdgeRecord( NoInit ) noexcept : next( noInit ), prev( noInit ), org( noInit ), left( noInit ) {}
602 };
603 static_assert( sizeof( HalfEdgeRecord ) == 16 );
604
606 template<typename FM, typename VM, typename WEM>
607 void translateNoFlip_( HalfEdgeRecord & r, const FM & fmap, const VM & vmap, const WEM & emap ) const;
608 template<typename FM, typename VM, typename WEM>
609 void translate_( HalfEdgeRecord & r, HalfEdgeRecord & rsym,
610 const FM & fmap, const VM & vmap, const WEM & emap, bool flipOrientation ) const;
611
614
616 Vector<EdgeId, VertId> edgePerVertex_;
617 VertBitSet validVerts_;
618
620 Vector<EdgeId, FaceId> edgePerFace_;
621 FaceBitSet validFaces_;
622
623 int numValidVerts_ = 0;
624 int numValidFaces_ = 0;
625
626 bool updateValids_ = true;
627};
628
629template <typename T>
630void MeshTopology::forEachVertex( const MeshTriPoint & p, T && callback ) const
631{
632 if ( auto v = p.inVertex( *this ) )
633 {
634 callback( v );
635 return;
636 }
637 if ( auto e = p.onEdge( *this ) )
638 {
639 callback( org( e.e ) );
640 callback( dest( e.e ) );
641 return;
642 }
643
644 VertId v[3];
645 getLeftTriVerts( p.e, v );
646 for ( int i = 0; i < 3; ++i )
647 callback( v[i] );
648}
649
650template<typename T>
651void MeshTopology::flipEdgesIn( const EdgeId e0, T && flipNeeded )
652{
653 EdgeId e = e0;
654 for (;;)
655 {
656 auto testEdge = prev( e.sym() );
657 if ( left( testEdge ) && right( testEdge ) && flipNeeded( testEdge ) )
658 flipEdge( testEdge );
659 else
660 {
661 e = next( e );
662 if ( e == e0 )
663 break;
664 }
665 }
666}
667
668template<typename T>
669void MeshTopology::flipEdgesOut( EdgeId e0, T && flipNeeded )
670{
671 EdgeId e = e0;
672 for (;;)
673 {
674 if ( left( e ) && right( e ) && flipNeeded( e ) )
675 {
676 e0 = next( e );
677 flipEdge( e );
678 e = e0;
679 }
680 else
681 {
682 e = next( e );
683 if ( e == e0 )
684 break;
685 }
686 }
687}
688
690template<typename T, typename I>
691[[nodiscard]] Vector<T, I> rearrangeVectorByMap( const Vector<T, I>& oldVector, const BMap<I, I>& map )
692{
693 Vector<T, I> newVector;
694 newVector.resize( map.tsize );
695
696 const auto& mData = map.b.data();
697 const auto sz = std::min( oldVector.size(), map.b.size() );
698 for ( I i = I(0); i < sz; ++i)
699 {
700 I newV = mData[i];
701 if ( newV.valid() )
702 newVector[newV] = oldVector[i];
703 }
704 return newVector;
705}
706
707}
#define MRMESH_API
Definition MRMeshFwd.h:85
Definition MRMeshTopology.h:30
std::vector<T>-like container that requires specific indexing type,
Definition MRVector.h:23
bool contains(const TypedBitSet< I > *bitset, I id)
Definition MRBitSet.h:405
std::function< bool(float)> ProgressCallback
Definition MRMeshFwd.h:759
EdgeId collapseEdge(EdgeId e, const std::function< void(EdgeId del, EdgeId rem)> &onEdgeDel)
void flipEdgesIn(EdgeId e0, T &&flipNeeded)
Definition MRMeshTopology.h:651
MR_BIND_IGNORE void getTriVerts(FaceId f, VertId(&v)[3]) const
Definition MRMeshTopology.h:156
size_t faceCapacity() const
returns the number of allocated face records
Definition MRMeshTopology.h:298
VertId addVertId()
creates new vert-id not associated with any edge yet
Definition MRMeshTopology.h:213
Buffer< T, I > b
Definition MRBuffer.h:137
std::vector< EdgeId > EdgeLoop
Definition MRMeshFwd.h:156
bool fromSameLeftRing(EdgeId a, EdgeId b) const
returns true if a and b are both from the same left face ring
void flipEdge(EdgeId e)
void addPartByMask(const MeshTopology &from, const FaceBitSet *fromFaces, const PartMapping &map={}, VacantElements *vacant={})
void excludeLoneEdges(UndirectedEdgeBitSet &edges) const
remove all lone edges from given set
bool isOrgInnerAndHasDegree(EdgeId a, int d) const
returns true if the origin of given edge is inner to the mesh (no boundary passes via it),...
EdgeId sharedVertInOrg(EdgeId a, EdgeId b) const
if two valid edges share the same vertex then it is found and returned as Edge with this vertex in or...
EdgeId splitEdge(EdgeId e, FaceBitSet *region=nullptr, FaceHashMap *new2Old=nullptr)
EdgeId makeEdge()
creates an edge not associated with any vertex or face
Turn
what way a path can follow in case of several alternatives
Definition MREnums.h:117
UndirectedEdgeId lastNotLoneUndirectedEdge() const
returns last not lone undirected edge id, or invalid id if no such edge exists
void getTriVerts(FaceId f, VertId &v0, VertId &v1, VertId &v2) const
Definition MRMeshTopology.h:155
void getLeftTriEdges(EdgeId e0, EdgeId &e1, EdgeId &e2) const
VertBitSet verts
Definition MRMeshTopology.h:23
MR_BIND_IGNORE VertBitSet findBoundaryVerts(const VertBitSet *region=nullptr) const
struct MRMESH_CLASS PartMapping
Definition MRMeshFwd.h:640
void packMinMem(const PackMapping &map)
bool computeValidsFromEdges(ProgressCallback cb={})
void flipEdgesOut(EdgeId e0, T &&flipNeeded)
Definition MRMeshTopology.h:669
VertId org
vertex at the origin of the edge
Definition MRMeshTopology.h:593
void faceReserve(size_t newCapacity)
sets the capacity of faces vector
Definition MRMeshTopology.h:292
bool isLeftInRegion(EdgeId e, const FaceBitSet *region=nullptr) const
return true if left face of given edge belongs to region (or just have valid id if region is nullptr)
Definition MRMeshTopology.h:334
void shrinkToFit()
requests the removal of unused capacity
std::size_t size() const
Definition MRVector.h:55
EdgeId sharedEdge(FaceId l, FaceId r) const
if two valid faces share the same edge then it is found and returned
void faceResize(size_t newSize)
explicitly increases the size of faces vector
size_t vertSize() const
returns the number of vertex records including invalid ones
Definition MRMeshTopology.h:225
void resize(size_t newSize) MR_REQUIRES_IF_SUPPORTED(sizeof(T)>0 &&std
Definition MRVector.h:57
void clear()
resets to the default-constructed state (including resuming valids updating), keeping the buffers' ca...
EdgeId next(EdgeId he) const
next (counter clock wise) half-edge in the origin ring
Definition MRMeshTopology.h:98
EdgeId nextLeftBd(EdgeId e, const FaceBitSet *region=nullptr, Turn turn=Turn::Rightmost) const
MR_BIND_IGNORE void addPartByMask(const MeshTopology &from, const FaceBitSet &fromFaces, const PartMapping &map={}, VacantElements *vacant={})
This is skipped in the bindings because it conflicts with the overload taking a pointer in C#....
Definition MRMeshTopology.h:486
int getVertDegree(VertId v) const
returns the number of edges around the given vertex
Definition MRMeshTopology.h:136
EdgeId sharedVertInOrg(FaceId l, FaceId r) const
if two valid faces share the same vertex then it is found and returned as Edge with this vertex in or...
EdgeId bdEdgeWithOrigin(VertId v, const FaceBitSet *region=nullptr) const
Definition MRMeshTopology.h:358
bool isBdEdge(EdgeId e, const FaceBitSet *region=nullptr) const
std::vector< EdgeId > findHoleRepresentiveEdges(const FaceBitSet *region=nullptr) const
bool hasVert(VertId a) const
returns true if given vertex is present in the mesh
Definition MRMeshTopology.h:204
FaceId left(EdgeId he) const
returns left face of half-edge
Definition MRMeshTopology.h:110
const Vector< EdgeId, VertId > & edgePerVertex() const
for all valid vertices this vector contains an edge with the origin there
Definition MRMeshTopology.h:198
void resizeBeforeParallelAdd(size_t edgeSize, size_t vertSize, size_t faceSize)
void vertResize(size_t newSize)
explicitly increases the size of vertices vector
VacantElements deleteFaces(const FaceBitSet &fs, const UndirectedEdgeBitSet *keepEdges=nullptr)
Triangulation getTriangulation() const
EdgeId bdEdgeWithLeft(FaceId f, const FaceBitSet *region=nullptr) const
Definition MRMeshTopology.h:324
std::vector< ThreeVertIds > getAllTriVerts() const
returns three vertex ids for valid triangles, invalid triangles are skipped
MR_BIND_IGNORE bool addPartByMask(const MeshTopology &from, const FaceBitSet &fromFaces, bool flipOrientation=false, const std::vector< EdgePath > &thisContours={}, const std::vector< EdgePath > &fromContours={}, const PartMapping &map={}, VacantElements *vacant={})
This is skipped in the bindings because it conflicts with the overload taking a pointer in C#....
Definition MRMeshTopology.h:501
void addPart(const MeshTopology &from, FaceMap *outFmap=nullptr, VertMap *outVmap=nullptr, WholeEdgeMap *outEmap=nullptr, bool rearrangeTriangles=false)
auto size() const
Definition MRBuffer.h:70
bool isInnerOrBdVertex(VertId v, const FaceBitSet *region=nullptr) const
returns true if one of incident faces of given vertex pertain to given region (or any such face exist...
FaceBitSet findBdFaces(const FaceBitSet *region=nullptr) const
returns all faces for which isBdFace(f, region) is true
VertId dest(EdgeId he) const
returns destination vertex of half-edge
Definition MRMeshTopology.h:107
FaceBitSet getPathRightFaces(const EdgePath &path) const
returns all valid right faces of path edges
int getOrgDegree(EdgeId a) const
returns the number of edges around the origin vertex, returns 1 for lone edges
bool updatingValids() const
returns whether the methods validVerts(), validFaces(), numValidVerts(), numValidFaces() can be calle...
Definition MRMeshTopology.h:555
void splice(EdgeId a, EdgeId b)
int getLeftDegree(EdgeId a) const
returns the number of edges around the left face: 3 for triangular faces, ...
MR_BIND_IGNORE FaceBitSet findBoundaryFaces(const FaceBitSet *region=nullptr) const
std::vector< EdgeLoop > getLeftRings(const std::vector< EdgeId > &es) const
void getTriEdges(FaceId f, EdgeId &e0, EdgeId &e1, EdgeId &e2) const
Definition MRMeshTopology.h:191
bool isLoneEdge(EdgeId a) const
checks whether the edge is disconnected from all other edges and disassociated from all vertices and ...
bool operator==(const HalfEdgeRecord &b) const
Definition MRMeshTopology.h:596
void faceResizeWithReserve(size_t newSize)
explicitly increases the size of faces vector, doubling the current capacity if it was not enough
UndirectedEdgeBitSet findNotLoneUndirectedEdges() const
finds and returns all not-lone (valid) undirected edges
HalfEdgeRecord() noexcept=default
bool hasFace(FaceId a) const
returns true if given face is present in the mesh
Definition MRMeshTopology.h:252
size_t edgeSize() const
returns the number of half-edge records including lone ones
Definition MRMeshTopology.h:48
EdgeId bdEdgeSameOrigin(EdgeId e, const FaceBitSet *region=nullptr) const
void flipOrientation(const UndirectedEdgeBitSet *fullComponents=nullptr)
bool isLeftQuad(EdgeId a) const
This one is not in the bindings because of the reference-to-array parameter.
FaceBitSet faces
Definition MRMeshTopology.h:24
FaceId lastValidFace() const
returns last valid face id, or invalid id if no single valid face exists
void vertResizeWithReserve(size_t newSize)
explicitly increases the size of vertices vector, doubling the current capacity if it was not enough
bool isLeftBdFace(EdgeId e, const FaceBitSet *region=nullptr) const
Definition MRMeshTopology.h:320
bool isInnerOrBdEdge(EdgeId e, const FaceBitSet *region=nullptr) const
return true if given edge is inner or boundary for given region (or for whole mesh if region is nullp...
Definition MRMeshTopology.h:373
bool isClosed(const FaceBitSet *region=nullptr) const
returns true if the mesh (region) does not have any neighboring holes
int getFaceDegree(FaceId f) const
returns the number of edges around the given face: 3 for triangular faces, ...
Definition MRMeshTopology.h:148
tl::expected< T, E > Expected
Definition MRExpected.h:31
void rotateTriangles()
for each triangle selects edgeWithLeft with minimal origin vertex
bool isBdFace(FaceId f, const FaceBitSet *region=nullptr) const
returns true if given face belongs to the region and it has a boundary edge (isBdEdge(e,...
Definition MRMeshTopology.h:327
EdgeLoop getLeftRing(EdgeId e) const
returns full edge-loop of left face from (e) starting from (e) itself
bool isLeftBdEdge(EdgeId e, const FaceBitSet *region=nullptr) const
returns true if left face of given edge belongs to given region (if provided) and right face either d...
Definition MRMeshTopology.h:370
int numValidVerts() const
returns the number of valid vertices
Definition MRMeshTopology.h:207
EdgeId prev
next clock wise half-edge in the origin ring
Definition MRMeshTopology.h:592
VertId org(EdgeId he) const
returns origin vertex of half-edge
Definition MRMeshTopology.h:104
VertBitSet findBdVerts(const FaceBitSet *region=nullptr, const VertBitSet *test=nullptr) const
returns all (test) vertices for which isBdVertex(v, region) is true
EdgeId edgeWithLeft(FaceId a) const
returns valid edge if given vertex is present in the mesh
Definition MRMeshTopology.h:249
auto data() MR_LIFETIMEBOUND
Definition MRBuffer.h:101
VertId splitFace(FaceId f, FaceBitSet *region=nullptr, FaceHashMap *new2Old=nullptr)
void flipEdgesIn(VertId v, T &&flipNeeded)
Definition MRMeshTopology.h:439
EdgeId prev(EdgeId he) const
previous (clock wise) half-edge in the origin ring
Definition MRMeshTopology.h:101
bool addPartByMask(const MeshTopology &from, const FaceBitSet *fromFaces, bool flipOrientation=false, const std::vector< EdgePath > &thisContours={}, const std::vector< EdgePath > &fromContours={}, const PartMapping &map={}, VacantElements *vacant={})
class MRMESH_CLASS I
Definition MRMeshFwd.h:144
void write(std::ostream &s) const
saves in binary stream
size_t tsize
target size, all values inside b must be less than this value
Definition MRBuffer.h:138
ThreeVertIds getTriVerts(FaceId f) const
Definition MRMeshTopology.h:158
EdgeId lastNotLoneEdge() const
returns last not lone edge id, or invalid id if no such edge exists
Definition MRMeshTopology.h:42
EdgeId findEdge(VertId o, VertId d) const
finds and returns edge from o to d in the mesh; returns invalid edge otherwise
bool isInnerEdge(EdgeId e, const FaceBitSet *region=nullptr) const
return true if given edge is inner for given region (or for whole mesh if region is nullptr)
Definition MRMeshTopology.h:337
void addPackedPart(const MeshTopology &from, EdgeId toEdgeId, const FaceMap &fmap, const VertMap &vmap)
HashMap< FaceId, FaceId > FaceHashMap
Definition MRMeshFwd.h:610
size_t edgeCapacity() const
returns the number of allocated edge records
Definition MRMeshTopology.h:51
int numValidFaces() const
returns the number of valid faces
Definition MRMeshTopology.h:267
size_t heapBytes() const
returns the amount of memory this object occupies on heap
MR_BIND_IGNORE EdgeBitSet findBoundaryEdges() const
returns all boundary edges, where each edge does not have valid left face
size_t computeNotLoneUndirectedEdges() const
computes the number of not-lone (valid) undirected edges
EdgeId edgeWithOrg(VertId a) const
returns valid edge if given vertex is present in the mesh
Definition MRMeshTopology.h:201
size_t faceSize() const
returns the number of face records including invalid ones
Definition MRMeshTopology.h:295
void deleteFace(FaceId f, const UndirectedEdgeBitSet *keepEdges=nullptr)
deletes the face, also deletes its edges and vertices if they were not shared by other faces and not ...
void setLeft(EdgeId a, FaceId f)
MR_BIND_IGNORE void getTriEdges(FaceId f, EdgeId(&e)[3]) const
Definition MRMeshTopology.h:192
void edgeReserve(size_t newCapacity)
sets the capacity of half-edges vector
Definition MRMeshTopology.h:66
UndirectedEdgeBitSet edges
Definition MRMeshTopology.h:22
std::vector< EdgeId > EdgePath
Definition MRMeshFwd.h:155
std::array< VertId, 3 > ThreeVertIds
three vertex ids describing a triangle with the corners in vertices given by their ids
Definition MRMeshFwd.h:519
void getLeftTriVerts(EdgeId a, ThreeVertIds &v) const
This one is not in the bindings because of the reference-to-array parameter.
Definition MRMeshTopology.h:174
int findNumHoles(EdgeBitSet *holeRepresentativeEdges=nullptr) const
EdgeId next
next counter clock wise half-edge in the origin ring
Definition MRMeshTopology.h:591
constexpr NoInit noInit
Definition MRMeshFwd.h:103
void forEachVertex(const MeshTriPoint &p, T &&callback) const
Definition MRMeshTopology.h:630
Vector< T, I > rearrangeVectorByMap(const Vector< T, I > &oldVector, const BMap< I, I > &map)
rearrange vector values by map (old.id -> new.id)
Definition MRMeshTopology.h:691
VertBitSet getPathVertices(const EdgePath &path) const
returns all vertices incident to path edges
void pack(FaceMap *outFmap=nullptr, VertMap *outVmap=nullptr, WholeEdgeMap *outEmap=nullptr, bool rearrangeTriangles=false)
EdgeId bdEdgeSameLeft(EdgeId e, const FaceBitSet *region=nullptr) const
void setOrg(EdgeId a, VertId v)
void addPart(const MeshTopology &from, const PartMapping &map={}, bool rearrangeTriangles=false)
FaceBitSet getPathLeftFaces(const EdgePath &path) const
returns all valid left faces of path edges
FaceId addFaceId()
creates new face-id not associated with any edge yet
Definition MRMeshTopology.h:273
void flipEdgesOut(VertId v, T &&flipNeeded)
Definition MRMeshTopology.h:449
FaceId left
face at the left of the edge
Definition MRMeshTopology.h:594
EdgeId prevLeftBd(EdgeId e, const FaceBitSet *region=nullptr, Turn turn=Turn::Rightmost) const
bool buildGridMesh(const GridSettings &settings, ProgressCallback cb={})
constructs triangular grid mesh topology in parallel
void preferEdges(const UndirectedEdgeBitSet &stableEdges)
void stopUpdatingValids()
stops updating validVerts(), validFaces(), numValidVerts(), numValidFaces() for parallel processing o...
FaceId sharedFace(EdgeId a, EdgeId b) const
if two valid edges belong to same valid face then it is found and returned
std::array< Vector3f, 3 > MR_BIND_IGNORE
Definition MRMeshBuilderTypes.h:13
size_t undirectedEdgeSize() const
returns the number of undirected edges (pairs of half-edges) including lone ones
Definition MRMeshTopology.h:54
void vertReserve(size_t newCapacity)
sets the capacity of vertices vector
Definition MRMeshTopology.h:222
friend class MeshTopologyDiff
Definition MRMeshTopology.h:569
void flip(VertBitSet &vs) const
sets in (vs) all valid vertices that were not selected before the call, and resets other bits
Definition MRMeshTopology.h:234
void getTriVerts(FaceId f, ThreeVertIds &v) const
This one is not in the bindings because of the reference-to-array parameter.
Definition MRMeshTopology.h:157
bool fromSameOriginRing(EdgeId a, EdgeId b) const
returns true if a and b are both from the same origin ring
void getLeftTriVerts(EdgeId a, VertId &v0, VertId &v1, VertId &v2) const
bool isLeftTri(EdgeId a) const
returns true if the cell to the left of a is triangular
FaceId right(EdgeId he) const
returns right face of half-edge
Definition MRMeshTopology.h:113
MR_BIND_IGNORE void getLeftTriVerts(EdgeId a, VertId(&v)[3]) const
Definition MRMeshTopology.h:173
bool isVertInnerAndHasDegree(VertId v, int d) const
returns true if the given vertex is inner to the mesh (no boundary passes via it),...
Definition MRMeshTopology.h:142
bool checkValidity(ProgressCallback cb={}, bool allVerts=true) const
bool hasEdge(EdgeId e) const
returns true if given edge is within valid range and not-lone
Definition MRMeshTopology.h:69
bool operator==(const MeshTopology &b) const
compare that two topologies are exactly the same
const VertBitSet & getVertIds(const VertBitSet *region) const
if region pointer is not null then converts it in reference, otherwise returns all valid vertices in ...
Definition MRMeshTopology.h:237
const Vector< EdgeId, FaceId > & edgePerFace() const
for all valid faces this vector contains an edge with that face at left
Definition MRMeshTopology.h:246
void pack(const PackMapping &map)
bool isBdVertex(VertId v, const FaceBitSet *region=nullptr) const
returns true if given vertex is on (region) boundary
Definition MRMeshTopology.h:361
bool isBdVertexInOrg(EdgeId e, const FaceBitSet *region=nullptr) const
returns true if edge's origin is on (region) boundary
Definition MRMeshTopology.h:354
Expected< void > read(std::istream &s, ProgressCallback callback={})
const VertBitSet & getValidVerts() const
returns cached set of all valid vertices
Definition MRMeshTopology.h:231
size_t undirectedEdgeCapacity() const
returns the number of allocated undirected edges (pairs of half-edges)
Definition MRMeshTopology.h:57
void flip(FaceBitSet &fs) const
sets in (fs) all valid faces that were not selected before the call, and resets other bits
Definition MRMeshTopology.h:304
ThreeVertIds getLeftTriVerts(EdgeId a) const
Definition MRMeshTopology.h:175
MeshEdgePoint onEdge(const MeshTopology &topology) const
bool isTriVert(FaceId f, VertId v) const
return true if triangular face (f) has (v) as one of its vertices
Definition MRMeshTopology.h:161
EdgeBitSet findLeftBdEdges(const FaceBitSet *region=nullptr, const EdgeBitSet *test=nullptr) const
returns all (test) edges for which left(e) does not belong to the region and isBdEdge(e,...
const FaceBitSet & getValidFaces() const
returns cached set of all valid faces
Definition MRMeshTopology.h:301
const FaceBitSet & getFaceIds(const FaceBitSet *region) const
if region pointer is not null then converts it in reference, otherwise returns all valid faces in the...
Definition MRMeshTopology.h:307
EdgeId e
Definition MRMeshTriPoint.h:27
VertId lastValidVert() const
returns last valid vertex id, or invalid id if no single valid vertex exists
VertId inVertex(const MeshTopology &topology) const
returns valid vertex id if the point is in vertex, otherwise returns invalid id
size_t vertCapacity() const
returns the number of allocated vert records
Definition MRMeshTopology.h:228
@ Rightmost
Definition MREnums.h:119
only for bindings generation
Definition MRCameraOrientationPlugin.h:8
flat map: I -> T
Definition MRBuffer.h:136
settings defining regular grid, where each quadrangular cell is split on two triangles in one of two ...
Definition MRGridSettings.h:14
Definition MRMeshTriPoint.h:26
Definition MRMeshFwd.h:102
Definition MRBuffer.h:144
mapping among elements of source mesh, from which a part is taken, and target mesh
Definition MRPartMapping.h:13
Definition MRMeshTopology.h:21