MeshLib C++ Docs
Loading...
Searching...
No Matches
MRMesh/MRMeshTopology.h
Go to the documentation of this file.
1#pragma once
2
3#include "MRId.h"
4#include "MRVector.h"
5#include "MRBitSet.h"
6#include "MRPartMapping.h"
7#include "MRMeshTriPoint.h"
9#include "MRExpected.h"
10#include <fstream>
11
12namespace MR
13{
14
18{
19public:
21 [[nodiscard]] MRMESH_API EdgeId makeEdge();
22
24 [[nodiscard]] MRMESH_API bool isLoneEdge( EdgeId a ) const;
25
27 [[nodiscard]] MRMESH_API EdgeId lastNotLoneEdge() const;
28
30 MRMESH_API void excludeLoneEdges( UndirectedEdgeBitSet & edges ) const;
31
33 [[nodiscard]] size_t edgeSize() const { return edges_.size(); }
34
36 [[nodiscard]] size_t edgeCapacity() const { return edges_.capacity(); }
37
39 [[nodiscard]] size_t undirectedEdgeSize() const { return edges_.size() >> 1; }
40
42 [[nodiscard]] size_t undirectedEdgeCapacity() const { return edges_.capacity() >> 1; }
43
45 [[nodiscard]] MRMESH_API size_t computeNotLoneUndirectedEdges() const;
46
48 [[nodiscard]] MRMESH_API UndirectedEdgeBitSet findNotLoneUndirectedEdges() const;
49
51 void edgeReserve( size_t newCapacity ) { edges_.reserve( newCapacity ); }
52
54 [[nodiscard]] bool hasEdge( EdgeId e ) const { assert( e.valid() ); return e < (int)edgeSize() && !isLoneEdge( e ); }
55
57 [[nodiscard]] MRMESH_API size_t heapBytes() const;
58
61
62
67 MRMESH_API void splice( EdgeId a, EdgeId b );
68
76 MRMESH_API EdgeId collapseEdge( EdgeId e, const std::function<void( EdgeId del, EdgeId rem )> & onEdgeDel );
77
78
80 [[nodiscard]] EdgeId next( EdgeId he ) const { assert(he.valid()); return edges_[he].next; }
81
83 [[nodiscard]] EdgeId prev( EdgeId he ) const { assert(he.valid()); return edges_[he].prev; }
84
86 [[nodiscard]] VertId org( EdgeId he ) const { assert(he.valid()); return edges_[he].org; }
87
89 [[nodiscard]] VertId dest( EdgeId he ) const { assert(he.valid()); return edges_[he.sym()].org; }
90
92 [[nodiscard]] FaceId left( EdgeId he ) const { assert(he.valid()); return edges_[he].left; }
93
95 [[nodiscard]] FaceId right( EdgeId he ) const { assert(he.valid()); return edges_[he.sym()].left; }
96
97
100 MRMESH_API void setOrg( EdgeId a, VertId v );
101
104 MRMESH_API void setLeft( EdgeId a, FaceId f );
105
106
108 [[nodiscard]] MRMESH_API bool fromSameOriginRing( EdgeId a, EdgeId b ) const;
109
111 [[nodiscard]] MRMESH_API bool fromSameLeftRing( EdgeId a, EdgeId b ) const;
112
113
115 [[nodiscard]] MRMESH_API int getOrgDegree( EdgeId a ) const;
116
118 [[nodiscard]] int getVertDegree( VertId v ) const { return getOrgDegree( edgeWithOrg( v ) ); }
119
121 [[nodiscard]] MRMESH_API int getLeftDegree( EdgeId a ) const;
122
124 [[nodiscard]] int getFaceDegree( FaceId f ) const { return getLeftDegree( edgeWithLeft( f ) ); }
125
127 [[nodiscard]] MRMESH_API bool isLeftTri( EdgeId a ) const;
128
131 void getTriVerts( FaceId f, VertId & v0, VertId & v1, VertId & v2 ) const { getLeftTriVerts( edgeWithLeft( f ), v0, v1, v2 ); }
132 void getTriVerts( FaceId f, VertId (&v)[3] ) const { getLeftTriVerts( edgeWithLeft( f ), v ); }
133 void getTriVerts( FaceId f, ThreeVertIds & v ) const { getLeftTriVerts( edgeWithLeft( f ), v ); }
134 [[nodiscard]] ThreeVertIds getTriVerts( FaceId f ) const { return getLeftTriVerts( edgeWithLeft( f ) ); }
135
137 [[nodiscard]] MRMESH_API std::vector<ThreeVertIds> getAllTriVerts() const;
138
141 [[nodiscard]] MRMESH_API Triangulation getTriangulation() const;
142
145 MRMESH_API void getLeftTriVerts( EdgeId a, VertId & v0, VertId & v1, VertId & v2 ) const;
146 void getLeftTriVerts( EdgeId a, VertId (&v)[3] ) const { getLeftTriVerts( a, v[0], v[1], v[2] ); }
147 void getLeftTriVerts( EdgeId a, ThreeVertIds & v ) const { getLeftTriVerts( a, v[0], v[1], v[2] ); }
148 [[nodiscard]] ThreeVertIds getLeftTriVerts( EdgeId a ) const { ThreeVertIds v; getLeftTriVerts( a, v[0], v[1], v[2] ); return v; }
149
154 template <typename T>
155 void forEachVertex( const MeshTriPoint & p, T && callback ) const;
156
160 MRMESH_API void getLeftTriEdges( EdgeId e0, EdgeId & e1, EdgeId & e2 ) const;
161
164 void getTriEdges( FaceId f, EdgeId & e0, EdgeId & e1, EdgeId & e2 ) const { getLeftTriEdges( e0 = edgeWithLeft( f ), e1, e2 ); }
165 void getTriEdges( FaceId f, EdgeId (&e)[3] ) const { getLeftTriEdges( e[0] = edgeWithLeft( f ), e[1], e[2] ); }
166
168 [[nodiscard]] MRMESH_API bool isLeftQuad( EdgeId a ) const;
169
171 [[nodiscard]] const Vector<EdgeId, VertId> & edgePerVertex() const { return edgePerVertex_; }
172
174 [[nodiscard]] EdgeId edgeWithOrg( VertId a ) const { assert( a.valid() ); return a < int(edgePerVertex_.size()) ? edgePerVertex_[a] : EdgeId(); }
175
177 [[nodiscard]] bool hasVert( VertId a ) const { assert( updateValids_ ); return validVerts_.test( a ); }
178
180 [[nodiscard]] int numValidVerts() const { assert( updateValids_ ); return numValidVerts_; }
181
183 [[nodiscard]] MRMESH_API VertId lastValidVert() const;
184
186 [[nodiscard]] VertId addVertId() { edgePerVertex_.emplace_back(); if ( updateValids_ ) { validVerts_.push_back( false ); } return edgePerVertex_.backId(); }
187
189 MRMESH_API void vertResize( size_t newSize );
190
192 MRMESH_API void vertResizeWithReserve( size_t newSize );
193
195 void vertReserve( size_t newCapacity ) { edgePerVertex_.reserve( newCapacity ); if ( updateValids_ ) { validVerts_.reserve( newCapacity ); } }
196
198 [[nodiscard]] size_t vertSize() const { return edgePerVertex_.size(); }
199
201 [[nodiscard]] size_t vertCapacity() const { return edgePerVertex_.capacity(); }
202
204 [[nodiscard]] const VertBitSet & getValidVerts() const { assert( updateValids_ ); return validVerts_; }
205
207 void flip( VertBitSet & vs ) const { vs = getValidVerts() - vs; }
208
210 [[nodiscard]] const VertBitSet & getVertIds( const VertBitSet * region ) const
211 {
212 assert( region || updateValids_ ); // region shall be either given on input or maintained in validVerts_
213 assert( !updateValids_ || !region || ( *region - validVerts_ ).none() ); // if region is given and all valid vertices are known, then region must be a subset of them
214 return region ? *region : validVerts_;
215 }
216
217
219 [[nodiscard]] const Vector<EdgeId, FaceId> & edgePerFace() const { return edgePerFace_; }
220
222 [[nodiscard]] EdgeId edgeWithLeft( FaceId a ) const { assert( a.valid() ); return a < int(edgePerFace_.size()) ? edgePerFace_[a] : EdgeId(); }
223
225 [[nodiscard]] bool hasFace( FaceId a ) const { assert( updateValids_ ); return validFaces_.test( a ); }
226
228 [[nodiscard]] MRMESH_API EdgeId sharedEdge( FaceId l, FaceId r ) const;
229
231 [[nodiscard]] MRMESH_API EdgeId sharedVertInOrg( EdgeId a, EdgeId b ) const;
232
234 [[nodiscard]] MRMESH_API EdgeId sharedVertInOrg( FaceId l, FaceId r ) const;
235
237 [[nodiscard]] MRMESH_API FaceId sharedFace( EdgeId a, EdgeId b ) const;
238
240 [[nodiscard]] int numValidFaces() const { assert( updateValids_ ); return numValidFaces_; }
241
243 [[nodiscard]] MRMESH_API FaceId lastValidFace() const;
244
246 [[nodiscard]] FaceId addFaceId() { edgePerFace_.emplace_back(); if ( updateValids_ ) { validFaces_.push_back( false ); } return edgePerFace_.backId(); }
247
249 MRMESH_API void deleteFace( FaceId f, const UndirectedEdgeBitSet * keepEdges = nullptr );
250
252 MRMESH_API void deleteFaces( const FaceBitSet & fs, const UndirectedEdgeBitSet * keepEdges = nullptr );
253
255 MRMESH_API void faceResize( size_t newSize );
256
258 MRMESH_API void faceResizeWithReserve( size_t newSize );
259
261 void faceReserve( size_t newCapacity ) { edgePerFace_.reserve( newCapacity ); if ( updateValids_ ) { validFaces_.reserve( newCapacity ); } }
262
264 [[nodiscard]] size_t faceSize() const { return edgePerFace_.size(); }
265
267 [[nodiscard]] size_t faceCapacity() const { return edgePerFace_.capacity(); }
268
270 [[nodiscard]] const FaceBitSet & getValidFaces() const { assert( updateValids_ ); return validFaces_; }
271
273 void flip( FaceBitSet & fs ) const { fs = getValidFaces() - fs; }
274
276 [[nodiscard]] const FaceBitSet & getFaceIds( const FaceBitSet * region ) const
277 {
278 assert( region || updateValids_ ); // region shall be either given on input or maintained in validFaces_
279 assert( !updateValids_ || !region || ( *region - validFaces_ ).none() ); // if region is given and all valid faces are known, then region must be a subset of them
280 return region ? *region : validFaces_;
281 }
282
285 [[nodiscard]] MRMESH_API EdgeId bdEdgeSameLeft( EdgeId e, const FaceBitSet * region = nullptr ) const;
286
288 [[nodiscard]] bool isBdVertexInLeft( EdgeId e, const FaceBitSet * region = nullptr ) const { return bdEdgeSameLeft( e, region ).valid(); }
289
292 [[nodiscard]] EdgeId bdEdgeWithLeft( FaceId f, const FaceBitSet * region = nullptr ) const { return bdEdgeSameLeft( edgeWithLeft( f ), region ); }
293
295 [[nodiscard]] bool isBdFace( FaceId f, const FaceBitSet * region = nullptr ) const { return isBdVertexInLeft( edgeWithLeft( f ), region ); }
296
297
299 [[nodiscard]] bool isLeftInRegion( EdgeId e, const FaceBitSet * region = nullptr ) const { return contains( region, left( e ) ); }
300
302 [[nodiscard]] bool isInnerEdge( EdgeId e, const FaceBitSet * region = nullptr ) const { return isLeftInRegion( e, region ) && isLeftInRegion( e.sym(), region ); }
303
305 [[nodiscard]] bool isBdEdge( EdgeId e, const FaceBitSet * region = nullptr ) const { return isLeftInRegion( e, region ) != isLeftInRegion( e.sym(), region ); }
306
309 [[nodiscard]] MRMESH_API EdgeId bdEdgeSameOrigin( EdgeId e, const FaceBitSet * region = nullptr ) const;
310
312 [[nodiscard]] bool isBdVertexInOrg( EdgeId e, const FaceBitSet * region = nullptr ) const { return bdEdgeSameOrigin( e, region ).valid(); }
313
316 [[nodiscard]] EdgeId bdEdgeWithOrigin( VertId v, const FaceBitSet * region = nullptr ) const { return bdEdgeSameOrigin( edgeWithOrg( v ), region ); }
317
319 [[nodiscard]] bool isBdVertex( VertId v, const FaceBitSet * region = nullptr ) const { return isBdVertexInOrg( edgeWithOrg( v ), region ); }
320
322 [[nodiscard]] MRMESH_API bool isInnerOrBdVertex( VertId v, const FaceBitSet * region = nullptr ) const;
323
325 [[nodiscard]] bool isLeftBdEdge( EdgeId e, const FaceBitSet * region = nullptr ) const { return region ? ( isLeftInRegion( e, region ) && !isLeftInRegion( e.sym(), region ) ) : !right( e ); }
326
328 [[nodiscard]] bool isInnerOrBdEdge( EdgeId e, const FaceBitSet * region = nullptr ) const { return isLeftInRegion( e, region ) || isLeftInRegion( e.sym(), region ); }
329
331 [[nodiscard]] MRMESH_API EdgeId nextLeftBd( EdgeId e, const FaceBitSet * region = nullptr ) const;
332
334 [[nodiscard]] MRMESH_API EdgeId prevLeftBd( EdgeId e, const FaceBitSet * region = nullptr ) const;
335
336
338 [[nodiscard]] MRMESH_API EdgeId findEdge( VertId o, VertId d ) const;
339
341 [[nodiscard]] MRMESH_API bool isClosed( const FaceBitSet * region = nullptr ) const;
342
345 [[nodiscard]] MRMESH_API std::vector<EdgeId> findHoleRepresentiveEdges( const FaceBitSet * region = nullptr ) const;
346
349 [[nodiscard]] MRMESH_API int findNumHoles( EdgeBitSet * holeRepresentativeEdges = nullptr ) const;
350
352 [[nodiscard]] MRMESH_API EdgeLoop getLeftRing( EdgeId e ) const;
353
356 [[nodiscard]] MRMESH_API std::vector<EdgeLoop> getLeftRings( const std::vector<EdgeId> & es ) const;
357
359 [[nodiscard]] MRMESH_API EdgeBitSet findBoundaryEdges() const;
360
363 [[nodiscard]] MRMESH_API FaceBitSet findBoundaryFaces( const FaceBitSet * region = nullptr ) const;
364
367 [[nodiscard]] MRMESH_API VertBitSet findBoundaryVerts( const VertBitSet * region = nullptr ) const;
368
369
371 [[nodiscard]] MRMESH_API VertBitSet getPathVertices( const EdgePath & path ) const;
372
374 [[nodiscard]] MRMESH_API FaceBitSet getPathLeftFaces( const EdgePath & path ) const;
375
377 [[nodiscard]] MRMESH_API FaceBitSet getPathRightFaces( const EdgePath & path ) const;
378
379
382 MRMESH_API void flipEdge( EdgeId e );
383
386 template<typename T>
387 void flipEdgesIn( EdgeId e0, T && flipNeeded );
388
391 template<typename T>
392 void flipEdgesIn( VertId v, T && flipNeeded ) { flipEdgesIn( edgeWithOrg( v ), std::forward<T>( flipNeeded ) ); }
393
396 template<typename T>
397 void flipEdgesOut( EdgeId e0, T && flipNeeded );
398
401 template<typename T>
402 void flipEdgesOut( VertId v, T && flipNeeded ) { flipEdgesOut( edgeWithOrg( v ), std::forward<T>( flipNeeded ) ); }
403
412 MRMESH_API EdgeId splitEdge( EdgeId e, FaceBitSet * region = nullptr, FaceHashMap * new2Old = nullptr );
413
417 MRMESH_API VertId splitFace( FaceId f, FaceBitSet * region = nullptr, FaceHashMap * new2Old = nullptr );
418
423 MRMESH_API void flipOrientation( const UndirectedEdgeBitSet * fullComponents = nullptr );
424
425
430 MRMESH_API void addPart( const MeshTopology & from,
431 FaceMap * outFmap = nullptr, VertMap * outVmap = nullptr, WholeEdgeMap * outEmap = nullptr, bool rearrangeTriangles = false );
432
434 MRMESH_API void addPartByMask( const MeshTopology & from, const FaceBitSet & fromFaces, const PartMapping & map );
435
440 MRMESH_API void addPartByMask( const MeshTopology & from, const FaceBitSet & fromFaces, bool flipOrientation = false,
441 const std::vector<EdgePath> & thisContours = {}, const std::vector<EdgePath> & fromContours = {},
442 const PartMapping & map = {} );
443
445 MRMESH_API void addPartByFaceMap( const MeshTopology & from, const FaceMap & fromFaces, bool flipOrientation = false,
446 const std::vector<EdgePath> & thisContours = {}, const std::vector<EdgePath> & fromContours = {},
447 const PartMapping & map = {} );
448
450 template<typename I>
451 MRMESH_API void addPartBy( const MeshTopology & from, I fbegin, I fend, size_t fcount, bool flipOrientation = false,
452 const std::vector<EdgePath> & thisContours = {},
453 const std::vector<EdgePath> & fromContours = {},
454 const PartMapping & map = {} );
455
456
459
464 MRMESH_API void pack( FaceMap * outFmap = nullptr, VertMap * outVmap = nullptr, WholeEdgeMap * outEmap = nullptr, bool rearrangeTriangles = false );
465
468 MRMESH_API void pack( const PackMapping & map );
469
473 MRMESH_API void packMinMem( const PackMapping & map );
474
475
477 MRMESH_API void write( std::ostream & s ) const;
478
481 MRMESH_API Expected<void> read( std::istream& s, ProgressCallback callback = {} );
482
484 [[nodiscard]] MRMESH_API bool operator ==( const MeshTopology & b ) const;
485
490
494 MRMESH_API void addPackedPart( const MeshTopology & from, EdgeId toEdgeId,
495 const FaceMap & fmap, const VertMap & vmap );
496
502
505
507 [[nodiscard]] bool updatingValids() const { return updateValids_; }
508
511 MRMESH_API void preferEdges( const UndirectedEdgeBitSet & stableEdges );
512
513 // constructs triangular grid mesh topology in parallel
514 MRMESH_API bool buildGridMesh( const GridSettings& settings, ProgressCallback cb = {} );
515
518 MRMESH_API bool checkValidity( ProgressCallback cb = {}, bool allVerts = true ) const;
519
520private:
521 friend class MeshTopologyDiff;
525 MRMESH_API void computeAllFromEdges_();
526
527private:
529 void setOrg_( EdgeId a, VertId v );
530
532 void setLeft_( EdgeId a, FaceId f );
533
535 struct HalfEdgeRecord
536 {
537 EdgeId next;
538 EdgeId prev;
539 VertId org;
540 FaceId left;
541
542 bool operator ==( const HalfEdgeRecord& b ) const
543 {
544 return next == b.next && prev == b.prev && org == b.org && left == b.left;
545 }
546 HalfEdgeRecord() noexcept = default;
547 explicit HalfEdgeRecord( NoInit ) noexcept : next( noInit ), prev( noInit ), org( noInit ), left( noInit ) {}
548 };
550 void translateNoFlip_( HalfEdgeRecord & r,
551 const FaceMap & fmap, const VertMap & vmap, const WholeEdgeMap & emap ) const;
552 void translate_( HalfEdgeRecord & r, HalfEdgeRecord & rsym,
553 const FaceMap & fmap, const VertMap & vmap, const WholeEdgeMap & emap, bool flipOrientation ) const;
554 void translateNoFlip_( HalfEdgeRecord & r,
555 const FaceHashMap & fmap, const VertHashMap & vmap, const WholeEdgeHashMap & emap ) const;
556 void translate_( HalfEdgeRecord & r, HalfEdgeRecord & rsym,
557 const FaceHashMap & fmap, const VertHashMap & vmap, const WholeEdgeHashMap & emap, bool flipOrientation ) const;
558
560 Vector<HalfEdgeRecord, EdgeId> edges_;
561
563 Vector<EdgeId, VertId> edgePerVertex_;
564 VertBitSet validVerts_;
565
567 Vector<EdgeId, FaceId> edgePerFace_;
568 FaceBitSet validFaces_;
569
570 int numValidVerts_ = 0;
571 int numValidFaces_ = 0;
572
573 bool updateValids_ = true;
574};
575
576template <typename T>
577void MeshTopology::forEachVertex( const MeshTriPoint & p, T && callback ) const
578{
579 if ( auto v = p.inVertex( *this ) )
580 {
581 callback( v );
582 return;
583 }
584 if ( auto e = p.onEdge( *this ) )
585 {
586 callback( org( e.e ) );
587 callback( dest( e.e ) );
588 return;
589 }
590
591 VertId v[3];
592 getLeftTriVerts( p.e, v );
593 for ( int i = 0; i < 3; ++i )
594 callback( v[i] );
595}
596
597template<typename T>
598void MeshTopology::flipEdgesIn( const EdgeId e0, T && flipNeeded )
599{
600 EdgeId e = e0;
601 for (;;)
602 {
603 auto testEdge = prev( e.sym() );
604 if ( left( testEdge ) && right( testEdge ) && flipNeeded( testEdge ) )
605 flipEdge( testEdge );
606 else
607 {
608 e = next( e );
609 if ( e == e0 )
610 break; // full ring has been inspected
611 }
612 }
613}
614
615template<typename T>
616void MeshTopology::flipEdgesOut( EdgeId e0, T && flipNeeded )
617{
618 EdgeId e = e0;
619 for (;;)
620 {
621 if ( left( e ) && right( e ) && flipNeeded( e ) )
622 {
623 e0 = next( e );
624 flipEdge( e );
625 e = e0;
626 }
627 else
628 {
629 e = next( e );
630 if ( e == e0 )
631 break; // full ring has been inspected
632 }
633 }
634}
635
636// rearrange vector values by map (old.id -> new.id)
637template<typename T, typename I>
638[[nodiscard]] Vector<T, I> rearrangeVectorByMap( const Vector<T, I>& oldVector, const BMap<I, I>& map )
639{
640 Vector<T, I> newVector;
641 newVector.resize( map.tsize );
642
643 const auto& mData = map.b.data();
644 const auto sz = std::min( oldVector.size(), map.b.size() );
645 for ( I i = I(0); i < sz; ++i)
646 {
647 I newV = mData[i];
648 if ( newV.valid() )
649 newVector[newV] = oldVector[i];
650 }
651 return newVector;
652}
653
655
656} // namespace MR
#define MRMESH_API
Definition MRMesh/MRMeshFwd.h:79
auto size() const
Definition MRBuffer.h:66
auto data()
Definition MRBuffer.h:97
Definition MRMeshTopologyDiff.h:13
Definition MRMesh/MRMeshTopology.h:18
MRMESH_API EdgeLoop getLeftRing(EdgeId e) const
returns full edge-loop of left face from (e) starting from (e) itself
void flipEdgesIn(EdgeId e0, T &&flipNeeded)
Definition MRMesh/MRMeshTopology.h:598
size_t faceCapacity() const
returns the number of allocated face records
Definition MRMesh/MRMeshTopology.h:267
MRMESH_API void addPartByFaceMap(const MeshTopology &from, const FaceMap &fromFaces, bool flipOrientation=false, const std::vector< EdgePath > &thisContours={}, const std::vector< EdgePath > &fromContours={}, const PartMapping &map={})
fromFaces contains mapping from this-topology (considering it is empty) to from-topology
VertId addVertId()
creates new vert-id not associated with any edge yet
Definition MRMesh/MRMeshTopology.h:186
MRMESH_API void splice(EdgeId a, EdgeId b)
MRMESH_API bool fromSameLeftRing(EdgeId a, EdgeId b) const
returns true if a and b are both from the same left face ring
MRMESH_API std::vector< ThreeVertIds > getAllTriVerts() const
returns three vertex ids for valid triangles, invalid triangles are skipped
MRMESH_API EdgeId bdEdgeSameLeft(EdgeId e, const FaceBitSet *region=nullptr) const
void getTriVerts(FaceId f, VertId &v0, VertId &v1, VertId &v2) const
Definition MRMesh/MRMeshTopology.h:131
MRMESH_API void resizeBeforeParallelAdd(size_t edgeSize, size_t vertSize, size_t faceSize)
MRMESH_API 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...
MRMESH_API FaceBitSet findBoundaryFaces(const FaceBitSet *region=nullptr) const
MRMESH_API void getLeftTriVerts(EdgeId a, VertId &v0, VertId &v1, VertId &v2) const
MRMESH_API EdgeId lastNotLoneEdge() const
returns last not lone edge id, or invalid id if no such edge exists
MRMESH_API void faceResizeWithReserve(size_t newSize)
explicitly increases the size of faces vector, doubling the current capacity if it was not enough
MRMESH_API 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(&v)[3]) const
Definition MRMesh/MRMeshTopology.h:146
MRMESH_API EdgeId prevLeftBd(EdgeId e, const FaceBitSet *region=nullptr) const
given a (region) boundary edge with no right face in given region, returns previous boundary edge for...
void flipEdgesOut(EdgeId e0, T &&flipNeeded)
Definition MRMesh/MRMeshTopology.h:616
void faceReserve(size_t newCapacity)
sets the capacity of faces vector
Definition MRMesh/MRMeshTopology.h:261
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 MRMesh/MRMeshTopology.h:299
MRMESH_API EdgeBitSet findBoundaryEdges() const
returns all boundary edges, where each edge does not have valid left face
size_t vertSize() const
returns the number of vertex records including invalid ones
Definition MRMesh/MRMeshTopology.h:198
MRMESH_API void pack(FaceMap *outFmap=nullptr, VertMap *outVmap=nullptr, WholeEdgeMap *outEmap=nullptr, bool rearrangeTriangles=false)
EdgeId next(EdgeId he) const
next (counter clock wise) half-edge in the origin ring
Definition MRMesh/MRMeshTopology.h:80
MRMESH_API FaceId sharedFace(EdgeId a, EdgeId b) const
if two valid edges belong to same valid face then it is found and returned
int getVertDegree(VertId v) const
returns the number of edges around the given vertex
Definition MRMesh/MRMeshTopology.h:118
EdgeId bdEdgeWithOrigin(VertId v, const FaceBitSet *region=nullptr) const
Definition MRMesh/MRMeshTopology.h:316
bool isBdEdge(EdgeId e, const FaceBitSet *region=nullptr) const
return true if given edge is boundary for given region (or for whole mesh if region is nullptr)
Definition MRMesh/MRMeshTopology.h:305
bool hasVert(VertId a) const
returns true if given vertex is present in the mesh
Definition MRMesh/MRMeshTopology.h:177
FaceId left(EdgeId he) const
returns left face of half-edge
Definition MRMesh/MRMeshTopology.h:92
const Vector< EdgeId, VertId > & edgePerVertex() const
for all valid vertices this vector contains an edge with the origin there
Definition MRMesh/MRMeshTopology.h:171
MRMESH_API void setLeft(EdgeId a, FaceId f)
MRMESH_API VertBitSet findBoundaryVerts(const VertBitSet *region=nullptr) const
MRMESH_API void vertResize(size_t newSize)
explicitly increases the size of vertices vector
EdgeId bdEdgeWithLeft(FaceId f, const FaceBitSet *region=nullptr) const
Definition MRMesh/MRMeshTopology.h:292
MRMESH_API bool isLeftTri(EdgeId a) const
returns true if the cell to the left of a is triangular
MRMESH_API void flipEdge(EdgeId e)
MRMESH_API int findNumHoles(EdgeBitSet *holeRepresentativeEdges=nullptr) const
VertId dest(EdgeId he) const
returns destination vertex of half-edge
Definition MRMesh/MRMeshTopology.h:89
MRMESH_API bool isLeftQuad(EdgeId a) const
returns true if the cell to the left of a is quadrangular
bool updatingValids() const
returns whether the methods validVerts(), validFaces(), numValidVerts(), numValidFaces() can be calle...
Definition MRMesh/MRMeshTopology.h:507
MRMESH_API 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...
bool isBdVertexInLeft(EdgeId e, const FaceBitSet *region=nullptr) const
returns true if edge's left is on (region) boundary
Definition MRMesh/MRMeshTopology.h:288
MRMESH_API void preferEdges(const UndirectedEdgeBitSet &stableEdges)
MRMESH_API void stopUpdatingValids()
stops updating validVerts(), validFaces(), numValidVerts(), numValidFaces() for parallel processing o...
void getTriEdges(FaceId f, EdgeId &e0, EdgeId &e1, EdgeId &e2) const
Definition MRMesh/MRMeshTopology.h:164
MRMESH_API size_t heapBytes() const
returns the amount of memory this object occupies on heap
MRMESH_API EdgeId findEdge(VertId o, VertId d) const
finds and returns edge from o to d in the mesh; returns invalid edge otherwise
MRMESH_API bool operator==(const MeshTopology &b) const
compare that two topologies are exactly the same
MRMESH_API void rotateTriangles()
for each triangle selects edgeWithLeft with minimal origin vertex
bool hasFace(FaceId a) const
returns true if given face is present in the mesh
Definition MRMesh/MRMeshTopology.h:225
MRMESH_API void shrinkToFit()
requests the removal of unused capacity
MRMESH_API VertId lastValidVert() const
returns last valid vertex id, or invalid id if no single valid vertex exists
size_t edgeSize() const
returns the number of half-edge records including lone ones
Definition MRMesh/MRMeshTopology.h:33
MRMESH_API bool computeValidsFromEdges(ProgressCallback cb={})
MRMESH_API EdgeId makeEdge()
creates an edge not associated with any vertex or face
MRMESH_API void flipOrientation(const UndirectedEdgeBitSet *fullComponents=nullptr)
MRMESH_API EdgeId bdEdgeSameOrigin(EdgeId e, const FaceBitSet *region=nullptr) const
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 MRMesh/MRMeshTopology.h:328
MRMESH_API void write(std::ostream &s) const
saves in binary stream
int getFaceDegree(FaceId f) const
returns the number of edges around the given face: 3 for triangular faces, ...
Definition MRMesh/MRMeshTopology.h:124
bool isBdFace(FaceId f, const FaceBitSet *region=nullptr) const
returns true if given face is on (region) boundary
Definition MRMesh/MRMeshTopology.h:295
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 MRMesh/MRMeshTopology.h:325
int numValidVerts() const
returns the number of valid vertices
Definition MRMesh/MRMeshTopology.h:180
VertId org(EdgeId he) const
returns origin vertex of half-edge
Definition MRMesh/MRMeshTopology.h:86
MRMESH_API std::vector< EdgeLoop > getLeftRings(const std::vector< EdgeId > &es) const
EdgeId edgeWithLeft(FaceId a) const
returns valid edge if given vertex is present in the mesh
Definition MRMesh/MRMeshTopology.h:222
MRMESH_API bool isLoneEdge(EdgeId a) const
checks whether the edge is disconnected from all other edges and disassociated from all vertices and ...
void flipEdgesIn(VertId v, T &&flipNeeded)
Definition MRMesh/MRMeshTopology.h:392
EdgeId prev(EdgeId he) const
previous (clock wise) half-edge in the origin ring
Definition MRMesh/MRMeshTopology.h:83
MRMESH_API FaceId lastValidFace() const
returns last valid face id, or invalid id if no single valid face exists
MRMESH_API VertId splitFace(FaceId f, FaceBitSet *region=nullptr, FaceHashMap *new2Old=nullptr)
void getTriEdges(FaceId f, EdgeId(&e)[3]) const
Definition MRMesh/MRMeshTopology.h:165
MRMESH_API void addPartBy(const MeshTopology &from, I fbegin, I fend, size_t fcount, bool flipOrientation=false, const std::vector< EdgePath > &thisContours={}, const std::vector< EdgePath > &fromContours={}, const PartMapping &map={})
both addPartByMask and addPartByFaceMap call this general implementation
MRMESH_API bool checkValidity(ProgressCallback cb={}, bool allVerts=true) const
ThreeVertIds getTriVerts(FaceId f) const
Definition MRMesh/MRMeshTopology.h:134
MRMESH_API int getLeftDegree(EdgeId a) const
returns the number of edges around the left face: 3 for triangular faces, ...
MRMESH_API void pack(const PackMapping &map)
MRMESH_API EdgeId splitEdge(EdgeId e, FaceBitSet *region=nullptr, FaceHashMap *new2Old=nullptr)
MRMESH_API 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 ant not ...
MRMESH_API UndirectedEdgeBitSet findNotLoneUndirectedEdges() const
finds and returns all not-lone (valid) undirected edges
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 MRMesh/MRMeshTopology.h:302
size_t edgeCapacity() const
returns the number of allocated edge records
Definition MRMesh/MRMeshTopology.h:36
int numValidFaces() const
returns the number of valid faces
Definition MRMesh/MRMeshTopology.h:240
MRMESH_API void setOrg(EdgeId a, VertId v)
MRMESH_API FaceBitSet getPathLeftFaces(const EdgePath &path) const
returns all valid left faces of path edges
MRMESH_API EdgeId sharedEdge(FaceId l, FaceId r) const
if two valid faces share the same edge then it is found and returned
MRMESH_API void addPartByMask(const MeshTopology &from, const FaceBitSet &fromFaces, bool flipOrientation=false, const std::vector< EdgePath > &thisContours={}, const std::vector< EdgePath > &fromContours={}, const PartMapping &map={})
EdgeId edgeWithOrg(VertId a) const
returns valid edge if given vertex is present in the mesh
Definition MRMesh/MRMeshTopology.h:174
size_t faceSize() const
returns the number of face records including invalid ones
Definition MRMesh/MRMeshTopology.h:264
void edgeReserve(size_t newCapacity)
sets the capacity of half-edges vector
Definition MRMesh/MRMeshTopology.h:51
void getLeftTriVerts(EdgeId a, ThreeVertIds &v) const
Definition MRMesh/MRMeshTopology.h:147
MRMESH_API void vertResizeWithReserve(size_t newSize)
explicitly increases the size of vertices vector, doubling the current capacity if it was not enough
MRMESH_API void addPackedPart(const MeshTopology &from, EdgeId toEdgeId, const FaceMap &fmap, const VertMap &vmap)
MRMESH_API std::vector< EdgeId > findHoleRepresentiveEdges(const FaceBitSet *region=nullptr) const
MRMESH_API FaceBitSet getPathRightFaces(const EdgePath &path) const
returns all valid right faces of path edges
MRMESH_API VertBitSet getPathVertices(const EdgePath &path) const
returns all vertices incident to path edges
MRMESH_API Triangulation getTriangulation() const
void forEachVertex(const MeshTriPoint &p, T &&callback) const
Definition MRMesh/MRMeshTopology.h:577
MRMESH_API void getLeftTriEdges(EdgeId e0, EdgeId &e1, EdgeId &e2) const
FaceId addFaceId()
creates new face-id not associated with any edge yet
Definition MRMesh/MRMeshTopology.h:246
void flipEdgesOut(VertId v, T &&flipNeeded)
Definition MRMesh/MRMeshTopology.h:402
MRMESH_API void addPart(const MeshTopology &from, FaceMap *outFmap=nullptr, VertMap *outVmap=nullptr, WholeEdgeMap *outEmap=nullptr, bool rearrangeTriangles=false)
MRMESH_API bool isClosed(const FaceBitSet *region=nullptr) const
returns true if the mesh (region) does not have any neighboring holes
MRMESH_API void addPartByMask(const MeshTopology &from, const FaceBitSet &fromFaces, const PartMapping &map)
the same but copies only portion of (from) specified by fromFaces,
MRMESH_API void deleteFaces(const FaceBitSet &fs, const UndirectedEdgeBitSet *keepEdges=nullptr)
deletes multiple given faces by calling deleteFace for each
MRMESH_API EdgeId nextLeftBd(EdgeId e, const FaceBitSet *region=nullptr) const
given a (region) boundary edge with no right face in given region, returns next boundary edge for the...
MRMESH_API void packMinMem(const PackMapping &map)
size_t undirectedEdgeSize() const
returns the number of undirected edges (pairs of half-edges) including lone ones
Definition MRMesh/MRMeshTopology.h:39
void vertReserve(size_t newCapacity)
sets the capacity of vertices vector
Definition MRMesh/MRMeshTopology.h:195
void flip(VertBitSet &vs) const
sets in (vs) all valid vertices that were not selected before the call, and resets other bits
Definition MRMesh/MRMeshTopology.h:207
MRMESH_API 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...
void getTriVerts(FaceId f, ThreeVertIds &v) const
Definition MRMesh/MRMeshTopology.h:133
MRMESH_API Expected< void > read(std::istream &s, ProgressCallback callback={})
MRMESH_API EdgeId collapseEdge(EdgeId e, const std::function< void(EdgeId del, EdgeId rem)> &onEdgeDel)
FaceId right(EdgeId he) const
returns right face of half-edge
Definition MRMesh/MRMeshTopology.h:95
MRMESH_API size_t computeNotLoneUndirectedEdges() const
computes the number of not-lone (valid) undirected edges
bool hasEdge(EdgeId e) const
returns true if given edge is within valid range and not-lone
Definition MRMesh/MRMeshTopology.h:54
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 MRMesh/MRMeshTopology.h:210
MRMESH_API void excludeLoneEdges(UndirectedEdgeBitSet &edges) const
remove all lone edges from given set
const Vector< EdgeId, FaceId > & edgePerFace() const
for all valid faces this vector contains an edge with that face at left
Definition MRMesh/MRMeshTopology.h:219
bool isBdVertex(VertId v, const FaceBitSet *region=nullptr) const
returns true if given vertex is on (region) boundary
Definition MRMesh/MRMeshTopology.h:319
bool isBdVertexInOrg(EdgeId e, const FaceBitSet *region=nullptr) const
returns true if edge's origin is on (region) boundary
Definition MRMesh/MRMeshTopology.h:312
const VertBitSet & getValidVerts() const
returns cached set of all valid vertices
Definition MRMesh/MRMeshTopology.h:204
MRMESH_API int getOrgDegree(EdgeId a) const
returns the number of edges around the origin vertex, returns 1 for lone edges
size_t undirectedEdgeCapacity() const
returns the number of allocated undirected edges (pairs of half-edges)
Definition MRMesh/MRMeshTopology.h:42
void flip(FaceBitSet &fs) const
sets in (fs) all valid faces that were not selected before the call, and resets other bits
Definition MRMesh/MRMeshTopology.h:273
ThreeVertIds getLeftTriVerts(EdgeId a) const
Definition MRMesh/MRMeshTopology.h:148
MRMESH_API void faceResize(size_t newSize)
explicitly increases the size of faces vector
MRMESH_API bool buildGridMesh(const GridSettings &settings, ProgressCallback cb={})
const FaceBitSet & getValidFaces() const
returns cached set of all valid faces
Definition MRMesh/MRMeshTopology.h:270
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 MRMesh/MRMeshTopology.h:276
void getTriVerts(FaceId f, VertId(&v)[3]) const
Definition MRMesh/MRMeshTopology.h:132
size_t vertCapacity() const
returns the number of allocated vert records
Definition MRMesh/MRMeshTopology.h:201
std::vector<T>-like container that requires specific indexing type,
Definition MRMesh/MRVector.h:20
std::size_t size() const
Definition MRMesh/MRVector.h:42
std::size_t capacity() const
Definition MRMesh/MRVector.h:59
void reserve(size_t capacity)
Definition MRMesh/MRVector.h:60
I backId() const
returns the identifier of the back() element
Definition MRMesh/MRVector.h:132
void resize(size_t newSize)
Definition MRMesh/MRVector.h:44
T & emplace_back(Args &&... args)
Definition MRMesh/MRVector.h:123
bool contains(const TaggedBitSet< T > *bitset, Id< T > id)
Definition MRMesh/MRBitSet.h:235
std::function< bool(float)> ProgressCallback
Definition MRMesh/MRMeshFwd.h:641
std::vector< EdgeId > EdgeLoop
Definition MRMesh/MRMeshFwd.h:132
struct MRMESH_CLASS PartMapping
Definition MRMesh/MRMeshFwd.h:539
HashMap< VertId, VertId > VertHashMap
Definition MRMesh/MRMeshFwd.h:521
tl::expected< T, E > Expected
Definition MRExpected.h:59
MRMESH_API void loadMeshDll()
HashMap< UndirectedEdgeId, EdgeId > WholeEdgeHashMap
mapping of whole edges: map[e]->f, map[e.sym()]->f.sym(), where only map[e] for even edges is stored
Definition MRMesh/MRMeshFwd.h:525
HashMap< FaceId, FaceId > FaceHashMap
Definition MRMesh/MRMeshFwd.h:520
std::vector< EdgeId > EdgePath
Definition MRMesh/MRMeshFwd.h:131
std::array< VertId, 3 > ThreeVertIds
three vertex ids describing a triangle topology
Definition MRMesh/MRMeshFwd.h:438
constexpr NoInit noInit
Definition MRMesh/MRMeshFwd.h:90
I
Definition MRMesh/MRMeshFwd.h:121
Vector< T, I > rearrangeVectorByMap(const Vector< T, I > &oldVector, const BMap< I, I > &map)
Definition MRMesh/MRMeshTopology.h:638
flat map: I -> T
Definition MRBuffer.h:143
Buffer< T, I > b
Definition MRBuffer.h:144
size_t tsize
target size, all values inside b must be less than this value
Definition MRBuffer.h:145
settings defining regular grid, where each quadrangular cell is split on two triangles in one of two ...
Definition MRGridSettings.h:11
Definition MRMesh/MRMeshTriPoint.h:23
MRMESH_API MeshEdgePoint onEdge(const MeshTopology &topology) const
MRMESH_API VertId inVertex(const MeshTopology &topology) const
returns valid vertex id if the point is in vertex, otherwise returns invalid id
EdgeId e
Definition MRMesh/MRMeshTriPoint.h:24
Definition MRMesh/MRMeshFwd.h:89
Definition MRBuffer.h:151
Definition MRPartMapping.h:10