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 <fstream>
13
14namespace MR
15{
18
19
23{
24public:
26 [[nodiscard]] MRMESH_API EdgeId makeEdge();
27
29 [[nodiscard]] MRMESH_API bool isLoneEdge( EdgeId a ) const;
30
32 [[nodiscard]] MRMESH_API UndirectedEdgeId lastNotLoneUndirectedEdge() const;
33
35 [[nodiscard]] EdgeId lastNotLoneEdge() const { auto ue = lastNotLoneUndirectedEdge(); return ue ? EdgeId( ue ) + 1 : EdgeId(); }
36
38 MRMESH_API void excludeLoneEdges( UndirectedEdgeBitSet & edges ) const;
39
41 [[nodiscard]] size_t edgeSize() const { return edges_.size(); }
42
44 [[nodiscard]] size_t edgeCapacity() const { return edges_.capacity(); }
45
47 [[nodiscard]] size_t undirectedEdgeSize() const { return edges_.size() >> 1; }
48
50 [[nodiscard]] size_t undirectedEdgeCapacity() const { return edges_.capacity() >> 1; }
51
53 [[nodiscard]] MRMESH_API size_t computeNotLoneUndirectedEdges() const;
54
56 [[nodiscard]] MRMESH_API UndirectedEdgeBitSet findNotLoneUndirectedEdges() const;
57
59 void edgeReserve( size_t newCapacity ) { edges_.reserve( newCapacity ); }
60
62 [[nodiscard]] bool hasEdge( EdgeId e ) const { assert( e.valid() ); return e < (int)edgeSize() && !isLoneEdge( e ); }
63
65 [[nodiscard]] MRMESH_API size_t heapBytes() const;
66
69
70
75 MRMESH_API void splice( EdgeId a, EdgeId b );
76
84 MRMESH_API EdgeId collapseEdge( EdgeId e, const std::function<void( EdgeId del, EdgeId rem )> & onEdgeDel );
85
86
88 [[nodiscard]] EdgeId next( EdgeId he ) const { assert(he.valid()); return edges_[he].next; }
89
91 [[nodiscard]] EdgeId prev( EdgeId he ) const { assert(he.valid()); return edges_[he].prev; }
92
94 [[nodiscard]] VertId org( EdgeId he ) const { assert(he.valid()); return edges_[he].org; }
95
97 [[nodiscard]] VertId dest( EdgeId he ) const { assert(he.valid()); return edges_[he.sym()].org; }
98
100 [[nodiscard]] FaceId left( EdgeId he ) const { assert(he.valid()); return edges_[he].left; }
101
103 [[nodiscard]] FaceId right( EdgeId he ) const { assert(he.valid()); return edges_[he.sym()].left; }
104
105
108 MRMESH_API void setOrg( EdgeId a, VertId v );
109
112 MRMESH_API void setLeft( EdgeId a, FaceId f );
113
114
116 [[nodiscard]] MRMESH_API bool fromSameOriginRing( EdgeId a, EdgeId b ) const;
117
119 [[nodiscard]] MRMESH_API bool fromSameLeftRing( EdgeId a, EdgeId b ) const;
120
121
123 [[nodiscard]] MRMESH_API int getOrgDegree( EdgeId a ) const;
124
126 [[nodiscard]] int getVertDegree( VertId v ) const { return getOrgDegree( edgeWithOrg( v ) ); }
127
129 [[nodiscard]] MRMESH_API int getLeftDegree( EdgeId a ) const;
130
132 [[nodiscard]] int getFaceDegree( FaceId f ) const { return getLeftDegree( edgeWithLeft( f ) ); }
133
135 [[nodiscard]] MRMESH_API bool isLeftTri( EdgeId a ) const;
136
139 void getTriVerts( FaceId f, VertId & v0, VertId & v1, VertId & v2 ) const { getLeftTriVerts( edgeWithLeft( f ), v0, v1, v2 ); }
140 MR_BIND_IGNORE void getTriVerts( FaceId f, VertId (&v)[3] ) const { getLeftTriVerts( edgeWithLeft( f ), v ); }
141 void getTriVerts( FaceId f, ThreeVertIds & v ) const { getLeftTriVerts( edgeWithLeft( f ), v ); }
142 [[nodiscard]] ThreeVertIds getTriVerts( FaceId f ) const { return getLeftTriVerts( edgeWithLeft( f ) ); }
143
145 [[nodiscard]] bool isTriVert( FaceId f, VertId v ) const { auto vs = getTriVerts( f ); return v == vs[0] || v == vs[1] || v == vs[2]; }
146
148 [[nodiscard]] MRMESH_API std::vector<ThreeVertIds> getAllTriVerts() const;
149
152 [[nodiscard]] MRMESH_API Triangulation getTriangulation() const;
153
156 MRMESH_API void getLeftTriVerts( EdgeId a, VertId & v0, VertId & v1, VertId & v2 ) const;
157 MR_BIND_IGNORE void getLeftTriVerts( EdgeId a, VertId (&v)[3] ) const { getLeftTriVerts( a, v[0], v[1], v[2] ); }
158 void getLeftTriVerts( EdgeId a, ThreeVertIds & v ) const { getLeftTriVerts( a, v[0], v[1], v[2] ); }
159 [[nodiscard]] ThreeVertIds getLeftTriVerts( EdgeId a ) const { ThreeVertIds v; getLeftTriVerts( a, v[0], v[1], v[2] ); return v; }
160
165 template <typename T>
166 void forEachVertex( const MeshTriPoint & p, T && callback ) const;
167
171 MRMESH_API void getLeftTriEdges( EdgeId e0, EdgeId & e1, EdgeId & e2 ) const;
172
175 void getTriEdges( FaceId f, EdgeId & e0, EdgeId & e1, EdgeId & e2 ) const { getLeftTriEdges( e0 = edgeWithLeft( f ), e1, e2 ); }
176 MR_BIND_IGNORE void getTriEdges( FaceId f, EdgeId (&e)[3] ) const { getLeftTriEdges( e[0] = edgeWithLeft( f ), e[1], e[2] ); }
177
179 [[nodiscard]] MRMESH_API bool isLeftQuad( EdgeId a ) const;
180
182 [[nodiscard]] const Vector<EdgeId, VertId> & edgePerVertex() const { return edgePerVertex_; }
183
185 [[nodiscard]] EdgeId edgeWithOrg( VertId a ) const { assert( a.valid() ); return a < int(edgePerVertex_.size()) ? edgePerVertex_[a] : EdgeId(); }
186
188 [[nodiscard]] bool hasVert( VertId a ) const { assert( updateValids_ ); return validVerts_.test( a ); }
189
191 [[nodiscard]] int numValidVerts() const { assert( updateValids_ ); return numValidVerts_; }
192
194 [[nodiscard]] MRMESH_API VertId lastValidVert() const;
195
197 [[nodiscard]] VertId addVertId() { edgePerVertex_.emplace_back(); if ( updateValids_ ) { validVerts_.push_back( false ); } return edgePerVertex_.backId(); }
198
200 MRMESH_API void vertResize( size_t newSize );
201
203 MRMESH_API void vertResizeWithReserve( size_t newSize );
204
206 void vertReserve( size_t newCapacity ) { edgePerVertex_.reserve( newCapacity ); if ( updateValids_ ) { validVerts_.reserve( newCapacity ); } }
207
209 [[nodiscard]] size_t vertSize() const { return edgePerVertex_.size(); }
210
212 [[nodiscard]] size_t vertCapacity() const { return edgePerVertex_.capacity(); }
213
215 [[nodiscard]] const VertBitSet & getValidVerts() const { assert( updateValids_ ); return validVerts_; }
216
218 void flip( VertBitSet & vs ) const { vs = getValidVerts() - vs; }
219
221 [[nodiscard]] const VertBitSet & getVertIds( const VertBitSet * region ) const
222 {
223 assert( region || updateValids_ );
224 assert( !updateValids_ || !region || region->is_subset_of( validVerts_ ) );
225 return region ? *region : validVerts_;
226 }
227
228
230 [[nodiscard]] const Vector<EdgeId, FaceId> & edgePerFace() const { return edgePerFace_; }
231
233 [[nodiscard]] EdgeId edgeWithLeft( FaceId a ) const { assert( a.valid() ); return a < int(edgePerFace_.size()) ? edgePerFace_[a] : EdgeId(); }
234
236 [[nodiscard]] bool hasFace( FaceId a ) const { assert( updateValids_ ); return validFaces_.test( a ); }
237
239 [[nodiscard]] MRMESH_API EdgeId sharedEdge( FaceId l, FaceId r ) const;
240
242 [[nodiscard]] MRMESH_API EdgeId sharedVertInOrg( EdgeId a, EdgeId b ) const;
243
245 [[nodiscard]] MRMESH_API EdgeId sharedVertInOrg( FaceId l, FaceId r ) const;
246
248 [[nodiscard]] MRMESH_API FaceId sharedFace( EdgeId a, EdgeId b ) const;
249
251 [[nodiscard]] int numValidFaces() const { assert( updateValids_ ); return numValidFaces_; }
252
254 [[nodiscard]] MRMESH_API FaceId lastValidFace() const;
255
257 [[nodiscard]] FaceId addFaceId() { edgePerFace_.emplace_back(); if ( updateValids_ ) { validFaces_.push_back( false ); } return edgePerFace_.backId(); }
258
260 MRMESH_API void deleteFace( FaceId f, const UndirectedEdgeBitSet * keepEdges = nullptr );
261
263 MRMESH_API void deleteFaces( const FaceBitSet & fs, const UndirectedEdgeBitSet * keepEdges = nullptr );
264
266 MRMESH_API void faceResize( size_t newSize );
267
269 MRMESH_API void faceResizeWithReserve( size_t newSize );
270
272 void faceReserve( size_t newCapacity ) { edgePerFace_.reserve( newCapacity ); if ( updateValids_ ) { validFaces_.reserve( newCapacity ); } }
273
275 [[nodiscard]] size_t faceSize() const { return edgePerFace_.size(); }
276
278 [[nodiscard]] size_t faceCapacity() const { return edgePerFace_.capacity(); }
279
281 [[nodiscard]] const FaceBitSet & getValidFaces() const { assert( updateValids_ ); return validFaces_; }
282
284 void flip( FaceBitSet & fs ) const { fs = getValidFaces() - fs; }
285
287 [[nodiscard]] const FaceBitSet & getFaceIds( const FaceBitSet * region ) const
288 {
289 assert( region || updateValids_ );
290 assert( !updateValids_ || !region || region->is_subset_of( validFaces_ ) );
291 return region ? *region : validFaces_;
292 }
293
296 [[nodiscard]] MRMESH_API EdgeId bdEdgeSameLeft( EdgeId e, const FaceBitSet * region = nullptr ) const;
297
300 [[nodiscard]] bool isLeftBdFace( EdgeId e, const FaceBitSet * region = nullptr ) const { return contains( region, left( e ) ) && bdEdgeSameLeft( e, region ).valid(); }
301
304 [[nodiscard]] EdgeId bdEdgeWithLeft( FaceId f, const FaceBitSet * region = nullptr ) const { return bdEdgeSameLeft( edgeWithLeft( f ), region ); }
305
307 [[nodiscard]] bool isBdFace( FaceId f, const FaceBitSet * region = nullptr ) const { return isLeftBdFace( edgeWithLeft( f ), region ); }
308
310 [[nodiscard]] MRMESH_API FaceBitSet findBdFaces( const FaceBitSet * region = nullptr ) const;
311
312
314 [[nodiscard]] bool isLeftInRegion( EdgeId e, const FaceBitSet * region = nullptr ) const { return contains( region, left( e ) ); }
315
317 [[nodiscard]] bool isInnerEdge( EdgeId e, const FaceBitSet * region = nullptr ) const { return isLeftInRegion( e, region ) && isLeftInRegion( e.sym(), region ); }
318
324 [[nodiscard]] MRMESH_API bool isBdEdge( EdgeId e, const FaceBitSet * region = nullptr ) const;
325
327 [[nodiscard]] MRMESH_API EdgeBitSet findLeftBdEdges( const FaceBitSet * region = nullptr, const EdgeBitSet * test = nullptr ) const;
328
331 [[nodiscard]] MRMESH_API EdgeId bdEdgeSameOrigin( EdgeId e, const FaceBitSet * region = nullptr ) const;
332
334 [[nodiscard]] bool isBdVertexInOrg( EdgeId e, const FaceBitSet * region = nullptr ) const { return bdEdgeSameOrigin( e, region ).valid(); }
335
338 [[nodiscard]] EdgeId bdEdgeWithOrigin( VertId v, const FaceBitSet * region = nullptr ) const { return bdEdgeSameOrigin( edgeWithOrg( v ), region ); }
339
341 [[nodiscard]] bool isBdVertex( VertId v, const FaceBitSet * region = nullptr ) const { return isBdVertexInOrg( edgeWithOrg( v ), region ); }
342
344 [[nodiscard]] MRMESH_API VertBitSet findBdVerts( const FaceBitSet * region = nullptr, const VertBitSet * test = nullptr ) const;
345
347 [[nodiscard]] MRMESH_API bool isInnerOrBdVertex( VertId v, const FaceBitSet * region = nullptr ) const;
348
350 [[nodiscard]] bool isLeftBdEdge( EdgeId e, const FaceBitSet * region = nullptr ) const { return region ? ( isLeftInRegion( e, region ) && !isLeftInRegion( e.sym(), region ) ) : !right( e ); }
351
353 [[nodiscard]] bool isInnerOrBdEdge( EdgeId e, const FaceBitSet * region = nullptr ) const { return isLeftInRegion( e, region ) || isLeftInRegion( e.sym(), region ); }
354
357 [[nodiscard]] MRMESH_API EdgeId nextLeftBd( EdgeId e, const FaceBitSet * region = nullptr, Turn turn = Turn::Rightmost ) const;
358
361 [[nodiscard]] MRMESH_API EdgeId prevLeftBd( EdgeId e, const FaceBitSet * region = nullptr, Turn turn = Turn::Rightmost ) const;
362
363
365 [[nodiscard]] MRMESH_API EdgeId findEdge( VertId o, VertId d ) const;
366
368 [[nodiscard]] MRMESH_API bool isClosed( const FaceBitSet * region = nullptr ) const;
369
372 [[nodiscard]] MRMESH_API std::vector<EdgeId> findHoleRepresentiveEdges( const FaceBitSet * region = nullptr ) const;
373
376 [[nodiscard]] MRMESH_API int findNumHoles( EdgeBitSet * holeRepresentativeEdges = nullptr ) const;
377
379 [[nodiscard]] MRMESH_API EdgeLoop getLeftRing( EdgeId e ) const;
380
383 [[nodiscard]] MRMESH_API std::vector<EdgeLoop> getLeftRings( const std::vector<EdgeId> & es ) const;
384
386 [[nodiscard]] [[deprecated( "Use findLeftBdEdges")]] MRMESH_API MR_BIND_IGNORE EdgeBitSet findBoundaryEdges() const;
387
390 [[nodiscard]] [[deprecated( "Use findBdFaces")]] MRMESH_API MR_BIND_IGNORE FaceBitSet findBoundaryFaces( const FaceBitSet * region = nullptr ) const;
391
394 [[nodiscard]] [[deprecated( "Use findBdVerts")]] MRMESH_API MR_BIND_IGNORE VertBitSet findBoundaryVerts( const VertBitSet * region = nullptr ) const;
395
396
398 [[nodiscard]] MRMESH_API VertBitSet getPathVertices( const EdgePath & path ) const;
399
401 [[nodiscard]] MRMESH_API FaceBitSet getPathLeftFaces( const EdgePath & path ) const;
402
404 [[nodiscard]] MRMESH_API FaceBitSet getPathRightFaces( const EdgePath & path ) const;
405
406
409 MRMESH_API void flipEdge( EdgeId e );
410
413 template<typename T>
414 void flipEdgesIn( EdgeId e0, T && flipNeeded );
415
418 template<typename T>
419 void flipEdgesIn( VertId v, T && flipNeeded ) { flipEdgesIn( edgeWithOrg( v ), std::forward<T>( flipNeeded ) ); }
420
423 template<typename T>
424 void flipEdgesOut( EdgeId e0, T && flipNeeded );
425
428 template<typename T>
429 void flipEdgesOut( VertId v, T && flipNeeded ) { flipEdgesOut( edgeWithOrg( v ), std::forward<T>( flipNeeded ) ); }
430
439 MRMESH_API EdgeId splitEdge( EdgeId e, FaceBitSet * region = nullptr, FaceHashMap * new2Old = nullptr );
440
444 MRMESH_API VertId splitFace( FaceId f, FaceBitSet * region = nullptr, FaceHashMap * new2Old = nullptr );
445
450 MRMESH_API void flipOrientation( const UndirectedEdgeBitSet * fullComponents = nullptr );
451
452
456 MRMESH_API void addPart( const MeshTopology & from, const PartMapping & map = {}, bool rearrangeTriangles = false );
457 MRMESH_API void addPart( const MeshTopology & from,
458 FaceMap * outFmap = nullptr, VertMap * outVmap = nullptr, WholeEdgeMap * outEmap = nullptr,
459 bool rearrangeTriangles = false );
460
462 MRMESH_API void addPartByMask( const MeshTopology & from, const FaceBitSet * fromFaces, const PartMapping & map = {} );
464 MR_BIND_IGNORE void addPartByMask( const MeshTopology & from, const FaceBitSet & fromFaces, const PartMapping & map = {} )
465 { addPartByMask( from, &fromFaces, map ); }
466
471 MRMESH_API void addPartByMask( const MeshTopology & from, const FaceBitSet * fromFaces, bool flipOrientation = false,
472 const std::vector<EdgePath> & thisContours = {}, const std::vector<EdgePath> & fromContours = {},
473 const PartMapping & map = {} );
474
476 MR_BIND_IGNORE void addPartByMask( const MeshTopology & from, const FaceBitSet & fromFaces, bool flipOrientation = false,
477 const std::vector<EdgePath> & thisContours = {}, const std::vector<EdgePath> & fromContours = {},
478 const PartMapping & map = {} ) { addPartByMask( from, &fromFaces, flipOrientation, thisContours, fromContours, map ); }
479
482
487 MRMESH_API void pack( FaceMap * outFmap = nullptr, VertMap * outVmap = nullptr, WholeEdgeMap * outEmap = nullptr, bool rearrangeTriangles = false );
488
491 MRMESH_API void pack( const PackMapping & map );
492
496 MRMESH_API void packMinMem( const PackMapping & map );
497
498
500 MRMESH_API void write( std::ostream & s ) const;
501
504 MRMESH_API Expected<void> read( std::istream& s, ProgressCallback callback = {} );
505
507 [[nodiscard]] MRMESH_API bool operator ==( const MeshTopology & b ) const;
508
513
517 MRMESH_API void addPackedPart( const MeshTopology & from, EdgeId toEdgeId,
518 const FaceMap & fmap, const VertMap & vmap );
519
525
528
530 [[nodiscard]] bool updatingValids() const { return updateValids_; }
531
534 MRMESH_API void preferEdges( const UndirectedEdgeBitSet & stableEdges );
535
537 MRMESH_API bool buildGridMesh( const GridSettings& settings, ProgressCallback cb = {} );
538
541 MRMESH_API bool checkValidity( ProgressCallback cb = {}, bool allVerts = true ) const;
542
543private:
544 friend class MeshTopologyDiff;
548 MRMESH_API void computeAllFromEdges_();
549
550private:
552 void setOrg_( EdgeId a, VertId v );
553
555 void fillOrg_();
556
558 void setLeft_( EdgeId a, FaceId f );
559
561 void fillLeft_();
562
564 struct alignas( 16 ) HalfEdgeRecord
565 {
566 EdgeId next;
567 EdgeId prev;
568 VertId org;
569 FaceId left;
570
571 bool operator ==( const HalfEdgeRecord& b ) const
572 {
573 return next == b.next && prev == b.prev && org == b.org && left == b.left;
574 }
575 HalfEdgeRecord() noexcept = default;
576 explicit HalfEdgeRecord( NoInit ) noexcept : next( noInit ), prev( noInit ), org( noInit ), left( noInit ) {}
577 };
578 static_assert( sizeof( HalfEdgeRecord ) == 16 );
579
581 template<typename FM, typename VM, typename WEM>
582 void translateNoFlip_( HalfEdgeRecord & r, const FM & fmap, const VM & vmap, const WEM & emap ) const;
583 template<typename FM, typename VM, typename WEM>
584 void translate_( HalfEdgeRecord & r, HalfEdgeRecord & rsym,
585 const FM & fmap, const VM & vmap, const WEM & emap, bool flipOrientation ) const;
586
589
591 Vector<EdgeId, VertId> edgePerVertex_;
592 VertBitSet validVerts_;
593
595 Vector<EdgeId, FaceId> edgePerFace_;
596 FaceBitSet validFaces_;
597
598 int numValidVerts_ = 0;
599 int numValidFaces_ = 0;
600
601 bool updateValids_ = true;
602};
603
604template <typename T>
605void MeshTopology::forEachVertex( const MeshTriPoint & p, T && callback ) const
606{
607 if ( auto v = p.inVertex( *this ) )
608 {
609 callback( v );
610 return;
611 }
612 if ( auto e = p.onEdge( *this ) )
613 {
614 callback( org( e.e ) );
615 callback( dest( e.e ) );
616 return;
617 }
618
619 VertId v[3];
620 getLeftTriVerts( p.e, v );
621 for ( int i = 0; i < 3; ++i )
622 callback( v[i] );
623}
624
625template<typename T>
626void MeshTopology::flipEdgesIn( const EdgeId e0, T && flipNeeded )
627{
628 EdgeId e = e0;
629 for (;;)
630 {
631 auto testEdge = prev( e.sym() );
632 if ( left( testEdge ) && right( testEdge ) && flipNeeded( testEdge ) )
633 flipEdge( testEdge );
634 else
635 {
636 e = next( e );
637 if ( e == e0 )
638 break;
639 }
640 }
641}
642
643template<typename T>
644void MeshTopology::flipEdgesOut( EdgeId e0, T && flipNeeded )
645{
646 EdgeId e = e0;
647 for (;;)
648 {
649 if ( left( e ) && right( e ) && flipNeeded( e ) )
650 {
651 e0 = next( e );
652 flipEdge( e );
653 e = e0;
654 }
655 else
656 {
657 e = next( e );
658 if ( e == e0 )
659 break;
660 }
661 }
662}
663
665template<typename T, typename I>
666[[nodiscard]] Vector<T, I> rearrangeVectorByMap( const Vector<T, I>& oldVector, const BMap<I, I>& map )
667{
668 Vector<T, I> newVector;
669 newVector.resize( map.tsize );
670
671 const auto& mData = map.b.data();
672 const auto sz = std::min( oldVector.size(), map.b.size() );
673 for ( I i = I(0); i < sz; ++i)
674 {
675 I newV = mData[i];
676 if ( newV.valid() )
677 newVector[newV] = oldVector[i];
678 }
679 return newVector;
680}
681
682}
#define MRMESH_API
Definition MRMeshFwd.h:80
Definition MRMeshTopology.h:23
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:392
std::function< bool(float)> ProgressCallback
Definition MRMeshFwd.h:753
EdgeId collapseEdge(EdgeId e, const std::function< void(EdgeId del, EdgeId rem)> &onEdgeDel)
void flipEdgesIn(EdgeId e0, T &&flipNeeded)
Definition MRMeshTopology.h:626
MR_BIND_IGNORE void getTriVerts(FaceId f, VertId(&v)[3]) const
Definition MRMeshTopology.h:140
size_t faceCapacity() const
returns the number of allocated face records
Definition MRMeshTopology.h:278
VertId addVertId()
creates new vert-id not associated with any edge yet
Definition MRMeshTopology.h:197
Buffer< T, I > b
Definition MRBuffer.h:137
std::vector< EdgeId > EdgeLoop
Definition MRMeshFwd.h:148
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 excludeLoneEdges(UndirectedEdgeBitSet &edges) const
remove all lone edges from given set
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:139
void deleteFaces(const FaceBitSet &fs, const UndirectedEdgeBitSet *keepEdges=nullptr)
deletes multiple given faces by calling deleteFace for each
void getLeftTriEdges(EdgeId e0, EdgeId &e1, EdgeId &e2) const
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:644
VertId org
vertex at the origin of the edge
Definition MRMeshTopology.h:568
void faceReserve(size_t newCapacity)
sets the capacity of faces vector
Definition MRMeshTopology.h:272
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:314
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:209
void resize(size_t newSize) MR_REQUIRES_IF_SUPPORTED(sizeof(T)>0 &&std
Definition MRVector.h:57
EdgeId next(EdgeId he) const
next (counter clock wise) half-edge in the origin ring
Definition MRMeshTopology.h:88
EdgeId nextLeftBd(EdgeId e, const FaceBitSet *region=nullptr, Turn turn=Turn::Rightmost) const
int getVertDegree(VertId v) const
returns the number of edges around the given vertex
Definition MRMeshTopology.h:126
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:338
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:188
FaceId left(EdgeId he) const
returns left face of half-edge
Definition MRMeshTopology.h:100
const Vector< EdgeId, VertId > & edgePerVertex() const
for all valid vertices this vector contains an edge with the origin there
Definition MRMeshTopology.h:182
void resizeBeforeParallelAdd(size_t edgeSize, size_t vertSize, size_t faceSize)
void vertResize(size_t newSize)
explicitly increases the size of vertices vector
Triangulation getTriangulation() const
EdgeId bdEdgeWithLeft(FaceId f, const FaceBitSet *region=nullptr) const
Definition MRMeshTopology.h:304
std::vector< ThreeVertIds > getAllTriVerts() const
returns three vertex ids for valid triangles, invalid triangles are skipped
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:97
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:530
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:175
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:571
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:236
size_t edgeSize() const
returns the number of half-edge records including lone ones
Definition MRMeshTopology.h:41
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.
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:300
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:353
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:132
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:307
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:350
int numValidVerts() const
returns the number of valid vertices
Definition MRMeshTopology.h:191
EdgeId prev
next clock wise half-edge in the origin ring
Definition MRMeshTopology.h:567
VertId org(EdgeId he) const
returns origin vertex of half-edge
Definition MRMeshTopology.h:94
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:233
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:419
EdgeId prev(EdgeId he) const
previous (clock wise) half-edge in the origin ring
Definition MRMeshTopology.h:91
class MRMESH_CLASS I
Definition MRMeshFwd.h:137
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:142
EdgeId lastNotLoneEdge() const
returns last not lone edge id, or invalid id if no such edge exists
Definition MRMeshTopology.h:35
void addPartByMask(const MeshTopology &from, const FaceBitSet *fromFaces, const PartMapping &map={})
the same but copies only portion of (from) specified by fromFaces,
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:317
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:44
int numValidFaces() const
returns the number of valid faces
Definition MRMeshTopology.h:251
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:185
size_t faceSize() const
returns the number of face records including invalid ones
Definition MRMeshTopology.h:275
MR_BIND_IGNORE void addPartByMask(const MeshTopology &from, const FaceBitSet &fromFaces, const PartMapping &map={})
This is skipped in the bindings because it conflicts with the overload taking a pointer in C#....
Definition MRMeshTopology.h:464
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:176
void edgeReserve(size_t newCapacity)
sets the capacity of half-edges vector
Definition MRMeshTopology.h:59
std::vector< EdgeId > EdgePath
Definition MRMeshFwd.h:147
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:158
int findNumHoles(EdgeBitSet *holeRepresentativeEdges=nullptr) const
EdgeId next
next counter clock wise half-edge in the origin ring
Definition MRMeshTopology.h:566
constexpr NoInit noInit
Definition MRMeshFwd.h:98
void forEachVertex(const MeshTriPoint &p, T &&callback) const
Definition MRMeshTopology.h:605
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:666
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:257
void flipEdgesOut(VertId v, T &&flipNeeded)
Definition MRMeshTopology.h:429
FaceId left
face at the left of the edge
Definition MRMeshTopology.h:569
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:47
void vertReserve(size_t newCapacity)
sets the capacity of vertices vector
Definition MRMeshTopology.h:206
friend class MeshTopologyDiff
Definition MRMeshTopology.h:544
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:218
void getTriVerts(FaceId f, ThreeVertIds &v) const
This one is not in the bindings because of the reference-to-array parameter.
Definition MRMeshTopology.h:141
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:103
MR_BIND_IGNORE void getLeftTriVerts(EdgeId a, VertId(&v)[3]) const
Definition MRMeshTopology.h:157
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:62
bool operator==(const MeshTopology &b) const
compare that two topologies are exactly the same
void addPartByMask(const MeshTopology &from, const FaceBitSet *fromFaces, bool flipOrientation=false, const std::vector< EdgePath > &thisContours={}, const std::vector< EdgePath > &fromContours={}, const PartMapping &map={})
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:221
const Vector< EdgeId, FaceId > & edgePerFace() const
for all valid faces this vector contains an edge with that face at left
Definition MRMeshTopology.h:230
MR_BIND_IGNORE void addPartByMask(const MeshTopology &from, const FaceBitSet &fromFaces, bool flipOrientation=false, const std::vector< EdgePath > &thisContours={}, const std::vector< EdgePath > &fromContours={}, const PartMapping &map={})
This is skipped in the bindings because it conflicts with the overload taking a pointer in C#....
Definition MRMeshTopology.h:476
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:341
bool isBdVertexInOrg(EdgeId e, const FaceBitSet *region=nullptr) const
returns true if edge's origin is on (region) boundary
Definition MRMeshTopology.h:334
Expected< void > read(std::istream &s, ProgressCallback callback={})
const VertBitSet & getValidVerts() const
returns cached set of all valid vertices
Definition MRMeshTopology.h:215
size_t undirectedEdgeCapacity() const
returns the number of allocated undirected edges (pairs of half-edges)
Definition MRMeshTopology.h:50
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:284
ThreeVertIds getLeftTriVerts(EdgeId a) const
Definition MRMeshTopology.h:159
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:145
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:281
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:287
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:212
@ 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:97
Definition MRBuffer.h:144
mapping among elements of source mesh, from which a part is taken, and target mesh
Definition MRPartMapping.h:13