MeshLib C++ Docs
Loading...
Searching...
No Matches
MRMesh/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 <fstream>
12
13namespace MR
14{
15
19{
20public:
22 [[nodiscard]] MRMESH_API EdgeId makeEdge();
23
25 [[nodiscard]] MRMESH_API bool isLoneEdge( EdgeId a ) const;
26
28 [[nodiscard]] MRMESH_API UndirectedEdgeId lastNotLoneUndirectedEdge() const;
29
31 [[nodiscard]] EdgeId lastNotLoneEdge() const { auto ue = lastNotLoneUndirectedEdge(); return ue ? EdgeId( ue ) + 1 : EdgeId(); }
32
34 MRMESH_API void excludeLoneEdges( UndirectedEdgeBitSet & edges ) const;
35
37 [[nodiscard]] size_t edgeSize() const { return edges_.size(); }
38
40 [[nodiscard]] size_t edgeCapacity() const { return edges_.capacity(); }
41
43 [[nodiscard]] size_t undirectedEdgeSize() const { return edges_.size() >> 1; }
44
46 [[nodiscard]] size_t undirectedEdgeCapacity() const { return edges_.capacity() >> 1; }
47
49 [[nodiscard]] MRMESH_API size_t computeNotLoneUndirectedEdges() const;
50
52 [[nodiscard]] MRMESH_API UndirectedEdgeBitSet findNotLoneUndirectedEdges() const;
53
55 void edgeReserve( size_t newCapacity ) { edges_.reserve( newCapacity ); }
56
58 [[nodiscard]] bool hasEdge( EdgeId e ) const { assert( e.valid() ); return e < (int)edgeSize() && !isLoneEdge( e ); }
59
61 [[nodiscard]] MRMESH_API size_t heapBytes() const;
62
65
66
71 MRMESH_API void splice( EdgeId a, EdgeId b );
72
80 MRMESH_API EdgeId collapseEdge( EdgeId e, const std::function<void( EdgeId del, EdgeId rem )> & onEdgeDel );
81
82
84 [[nodiscard]] EdgeId next( EdgeId he ) const { assert(he.valid()); return edges_[he].next; }
85
87 [[nodiscard]] EdgeId prev( EdgeId he ) const { assert(he.valid()); return edges_[he].prev; }
88
90 [[nodiscard]] VertId org( EdgeId he ) const { assert(he.valid()); return edges_[he].org; }
91
93 [[nodiscard]] VertId dest( EdgeId he ) const { assert(he.valid()); return edges_[he.sym()].org; }
94
96 [[nodiscard]] FaceId left( EdgeId he ) const { assert(he.valid()); return edges_[he].left; }
97
99 [[nodiscard]] FaceId right( EdgeId he ) const { assert(he.valid()); return edges_[he.sym()].left; }
100
101
104 MRMESH_API void setOrg( EdgeId a, VertId v );
105
108 MRMESH_API void setLeft( EdgeId a, FaceId f );
109
110
112 [[nodiscard]] MRMESH_API bool fromSameOriginRing( EdgeId a, EdgeId b ) const;
113
115 [[nodiscard]] MRMESH_API bool fromSameLeftRing( EdgeId a, EdgeId b ) const;
116
117
119 [[nodiscard]] MRMESH_API int getOrgDegree( EdgeId a ) const;
120
122 [[nodiscard]] int getVertDegree( VertId v ) const { return getOrgDegree( edgeWithOrg( v ) ); }
123
125 [[nodiscard]] MRMESH_API int getLeftDegree( EdgeId a ) const;
126
128 [[nodiscard]] int getFaceDegree( FaceId f ) const { return getLeftDegree( edgeWithLeft( f ) ); }
129
131 [[nodiscard]] MRMESH_API bool isLeftTri( EdgeId a ) const;
132
135 void getTriVerts( FaceId f, VertId & v0, VertId & v1, VertId & v2 ) const { getLeftTriVerts( edgeWithLeft( f ), v0, v1, v2 ); }
136 MR_BIND_IGNORE void getTriVerts( FaceId f, VertId (&v)[3] ) const { getLeftTriVerts( edgeWithLeft( f ), v ); } // This one is not in the bindings because of the reference-to-array parameter.
137 void getTriVerts( FaceId f, ThreeVertIds & v ) const { getLeftTriVerts( edgeWithLeft( f ), v ); }
138 [[nodiscard]] ThreeVertIds getTriVerts( FaceId f ) const { return getLeftTriVerts( edgeWithLeft( f ) ); }
139
141 [[nodiscard]] bool isTriVert( FaceId f, VertId v ) const { auto vs = getTriVerts( f ); return v == vs[0] || v == vs[1] || v == vs[2]; }
142
144 [[nodiscard]] MRMESH_API std::vector<ThreeVertIds> getAllTriVerts() const;
145
148 [[nodiscard]] MRMESH_API Triangulation getTriangulation() const;
149
152 MRMESH_API void getLeftTriVerts( EdgeId a, VertId & v0, VertId & v1, VertId & v2 ) const;
153 MR_BIND_IGNORE void getLeftTriVerts( EdgeId a, VertId (&v)[3] ) const { getLeftTriVerts( a, v[0], v[1], v[2] ); } // This one is not in the bindings because of the reference-to-array parameter.
154 void getLeftTriVerts( EdgeId a, ThreeVertIds & v ) const { getLeftTriVerts( a, v[0], v[1], v[2] ); }
155 [[nodiscard]] ThreeVertIds getLeftTriVerts( EdgeId a ) const { ThreeVertIds v; getLeftTriVerts( a, v[0], v[1], v[2] ); return v; }
156
161 template <typename T>
162 void forEachVertex( const MeshTriPoint & p, T && callback ) const;
163
167 MRMESH_API void getLeftTriEdges( EdgeId e0, EdgeId & e1, EdgeId & e2 ) const;
168
171 void getTriEdges( FaceId f, EdgeId & e0, EdgeId & e1, EdgeId & e2 ) const { getLeftTriEdges( e0 = edgeWithLeft( f ), e1, e2 ); }
172 MR_BIND_IGNORE void getTriEdges( FaceId f, EdgeId (&e)[3] ) const { getLeftTriEdges( e[0] = edgeWithLeft( f ), e[1], e[2] ); } // This one is not in the bindings because of the reference-to-array parameter.
173
175 [[nodiscard]] MRMESH_API bool isLeftQuad( EdgeId a ) const;
176
178 [[nodiscard]] const Vector<EdgeId, VertId> & edgePerVertex() const { return edgePerVertex_; }
179
181 [[nodiscard]] EdgeId edgeWithOrg( VertId a ) const { assert( a.valid() ); return a < int(edgePerVertex_.size()) ? edgePerVertex_[a] : EdgeId(); }
182
184 [[nodiscard]] bool hasVert( VertId a ) const { assert( updateValids_ ); return validVerts_.test( a ); }
185
187 [[nodiscard]] int numValidVerts() const { assert( updateValids_ ); return numValidVerts_; }
188
190 [[nodiscard]] MRMESH_API VertId lastValidVert() const;
191
193 [[nodiscard]] VertId addVertId() { edgePerVertex_.emplace_back(); if ( updateValids_ ) { validVerts_.push_back( false ); } return edgePerVertex_.backId(); }
194
196 MRMESH_API void vertResize( size_t newSize );
197
199 MRMESH_API void vertResizeWithReserve( size_t newSize );
200
202 void vertReserve( size_t newCapacity ) { edgePerVertex_.reserve( newCapacity ); if ( updateValids_ ) { validVerts_.reserve( newCapacity ); } }
203
205 [[nodiscard]] size_t vertSize() const { return edgePerVertex_.size(); }
206
208 [[nodiscard]] size_t vertCapacity() const { return edgePerVertex_.capacity(); }
209
211 [[nodiscard]] const VertBitSet & getValidVerts() const { assert( updateValids_ ); return validVerts_; }
212
214 void flip( VertBitSet & vs ) const { vs = getValidVerts() - vs; }
215
217 [[nodiscard]] const VertBitSet & getVertIds( const VertBitSet * region ) const
218 {
219 assert( region || updateValids_ ); // region shall be either given on input or maintained in validVerts_
220 assert( !updateValids_ || !region || region->is_subset_of( validVerts_ ) ); // if region is given and all valid vertices are known, then region must be a subset of them
221 return region ? *region : validVerts_;
222 }
223
224
226 [[nodiscard]] const Vector<EdgeId, FaceId> & edgePerFace() const { return edgePerFace_; }
227
229 [[nodiscard]] EdgeId edgeWithLeft( FaceId a ) const { assert( a.valid() ); return a < int(edgePerFace_.size()) ? edgePerFace_[a] : EdgeId(); }
230
232 [[nodiscard]] bool hasFace( FaceId a ) const { assert( updateValids_ ); return validFaces_.test( a ); }
233
235 [[nodiscard]] MRMESH_API EdgeId sharedEdge( FaceId l, FaceId r ) const;
236
238 [[nodiscard]] MRMESH_API EdgeId sharedVertInOrg( EdgeId a, EdgeId b ) const;
239
241 [[nodiscard]] MRMESH_API EdgeId sharedVertInOrg( FaceId l, FaceId r ) const;
242
244 [[nodiscard]] MRMESH_API FaceId sharedFace( EdgeId a, EdgeId b ) const;
245
247 [[nodiscard]] int numValidFaces() const { assert( updateValids_ ); return numValidFaces_; }
248
250 [[nodiscard]] MRMESH_API FaceId lastValidFace() const;
251
253 [[nodiscard]] FaceId addFaceId() { edgePerFace_.emplace_back(); if ( updateValids_ ) { validFaces_.push_back( false ); } return edgePerFace_.backId(); }
254
256 MRMESH_API void deleteFace( FaceId f, const UndirectedEdgeBitSet * keepEdges = nullptr );
257
259 MRMESH_API void deleteFaces( const FaceBitSet & fs, const UndirectedEdgeBitSet * keepEdges = nullptr );
260
262 MRMESH_API void faceResize( size_t newSize );
263
265 MRMESH_API void faceResizeWithReserve( size_t newSize );
266
268 void faceReserve( size_t newCapacity ) { edgePerFace_.reserve( newCapacity ); if ( updateValids_ ) { validFaces_.reserve( newCapacity ); } }
269
271 [[nodiscard]] size_t faceSize() const { return edgePerFace_.size(); }
272
274 [[nodiscard]] size_t faceCapacity() const { return edgePerFace_.capacity(); }
275
277 [[nodiscard]] const FaceBitSet & getValidFaces() const { assert( updateValids_ ); return validFaces_; }
278
280 void flip( FaceBitSet & fs ) const { fs = getValidFaces() - fs; }
281
283 [[nodiscard]] const FaceBitSet & getFaceIds( const FaceBitSet * region ) const
284 {
285 assert( region || updateValids_ ); // region shall be either given on input or maintained in validFaces_
286 assert( !updateValids_ || !region || region->is_subset_of( validFaces_ ) ); // if region is given and all valid faces are known, then region must be a subset of them
287 return region ? *region : validFaces_;
288 }
289
292 [[nodiscard]] MRMESH_API EdgeId bdEdgeSameLeft( EdgeId e, const FaceBitSet * region = nullptr ) const;
293
296 [[nodiscard]] bool isLeftBdFace( EdgeId e, const FaceBitSet * region = nullptr ) const { return contains( region, left( e ) ) && bdEdgeSameLeft( e, region ).valid(); }
297
300 [[nodiscard]] EdgeId bdEdgeWithLeft( FaceId f, const FaceBitSet * region = nullptr ) const { return bdEdgeSameLeft( edgeWithLeft( f ), region ); }
301
303 [[nodiscard]] bool isBdFace( FaceId f, const FaceBitSet * region = nullptr ) const { return isLeftBdFace( edgeWithLeft( f ), region ); }
304
306 [[nodiscard]] MRMESH_API FaceBitSet findBdFaces( const FaceBitSet * region = nullptr ) const;
307
308
310 [[nodiscard]] bool isLeftInRegion( EdgeId e, const FaceBitSet * region = nullptr ) const { return contains( region, left( e ) ); }
311
313 [[nodiscard]] bool isInnerEdge( EdgeId e, const FaceBitSet * region = nullptr ) const { return isLeftInRegion( e, region ) && isLeftInRegion( e.sym(), region ); }
314
320 [[nodiscard]] MRMESH_API bool isBdEdge( EdgeId e, const FaceBitSet * region = nullptr ) const;
321
323 [[nodiscard]] MRMESH_API EdgeBitSet findLeftBdEdges( const FaceBitSet * region = nullptr, const EdgeBitSet * test = nullptr ) const;
324
327 [[nodiscard]] MRMESH_API EdgeId bdEdgeSameOrigin( EdgeId e, const FaceBitSet * region = nullptr ) const;
328
330 [[nodiscard]] bool isBdVertexInOrg( EdgeId e, const FaceBitSet * region = nullptr ) const { return bdEdgeSameOrigin( e, region ).valid(); }
331
334 [[nodiscard]] EdgeId bdEdgeWithOrigin( VertId v, const FaceBitSet * region = nullptr ) const { return bdEdgeSameOrigin( edgeWithOrg( v ), region ); }
335
337 [[nodiscard]] bool isBdVertex( VertId v, const FaceBitSet * region = nullptr ) const { return isBdVertexInOrg( edgeWithOrg( v ), region ); }
338
340 [[nodiscard]] MRMESH_API VertBitSet findBdVerts( const FaceBitSet * region = nullptr, const VertBitSet * test = nullptr ) const;
341
343 [[nodiscard]] MRMESH_API bool isInnerOrBdVertex( VertId v, const FaceBitSet * region = nullptr ) const;
344
346 [[nodiscard]] bool isLeftBdEdge( EdgeId e, const FaceBitSet * region = nullptr ) const { return region ? ( isLeftInRegion( e, region ) && !isLeftInRegion( e.sym(), region ) ) : !right( e ); }
347
349 [[nodiscard]] bool isInnerOrBdEdge( EdgeId e, const FaceBitSet * region = nullptr ) const { return isLeftInRegion( e, region ) || isLeftInRegion( e.sym(), region ); }
350
352 [[nodiscard]] MRMESH_API EdgeId nextLeftBd( EdgeId e, const FaceBitSet * region = nullptr ) const;
353
355 [[nodiscard]] MRMESH_API EdgeId prevLeftBd( EdgeId e, const FaceBitSet * region = nullptr ) const;
356
357
359 [[nodiscard]] MRMESH_API EdgeId findEdge( VertId o, VertId d ) const;
360
362 [[nodiscard]] MRMESH_API bool isClosed( const FaceBitSet * region = nullptr ) const;
363
366 [[nodiscard]] MRMESH_API std::vector<EdgeId> findHoleRepresentiveEdges( const FaceBitSet * region = nullptr ) const;
367
370 [[nodiscard]] MRMESH_API int findNumHoles( EdgeBitSet * holeRepresentativeEdges = nullptr ) const;
371
373 [[nodiscard]] MRMESH_API EdgeLoop getLeftRing( EdgeId e ) const;
374
377 [[nodiscard]] MRMESH_API std::vector<EdgeLoop> getLeftRings( const std::vector<EdgeId> & es ) const;
378
380 [[nodiscard]] [[deprecated( "Use findLeftBdEdges")]] MRMESH_API MR_BIND_IGNORE EdgeBitSet findBoundaryEdges() const;
381
384 [[nodiscard]] [[deprecated( "Use findBdFaces")]] MRMESH_API MR_BIND_IGNORE FaceBitSet findBoundaryFaces( const FaceBitSet * region = nullptr ) const;
385
388 [[nodiscard]] [[deprecated( "Use findBdVerts")]] MRMESH_API MR_BIND_IGNORE VertBitSet findBoundaryVerts( const VertBitSet * region = nullptr ) const;
389
390
392 [[nodiscard]] MRMESH_API VertBitSet getPathVertices( const EdgePath & path ) const;
393
395 [[nodiscard]] MRMESH_API FaceBitSet getPathLeftFaces( const EdgePath & path ) const;
396
398 [[nodiscard]] MRMESH_API FaceBitSet getPathRightFaces( const EdgePath & path ) const;
399
400
403 MRMESH_API void flipEdge( EdgeId e );
404
407 template<typename T>
408 void flipEdgesIn( EdgeId e0, T && flipNeeded );
409
412 template<typename T>
413 void flipEdgesIn( VertId v, T && flipNeeded ) { flipEdgesIn( edgeWithOrg( v ), std::forward<T>( flipNeeded ) ); }
414
417 template<typename T>
418 void flipEdgesOut( EdgeId e0, T && flipNeeded );
419
422 template<typename T>
423 void flipEdgesOut( VertId v, T && flipNeeded ) { flipEdgesOut( edgeWithOrg( v ), std::forward<T>( flipNeeded ) ); }
424
433 MRMESH_API EdgeId splitEdge( EdgeId e, FaceBitSet * region = nullptr, FaceHashMap * new2Old = nullptr );
434
438 MRMESH_API VertId splitFace( FaceId f, FaceBitSet * region = nullptr, FaceHashMap * new2Old = nullptr );
439
444 MRMESH_API void flipOrientation( const UndirectedEdgeBitSet * fullComponents = nullptr );
445
446
450 MRMESH_API void addPart( const MeshTopology & from, const PartMapping & map = {}, bool rearrangeTriangles = false );
451 MRMESH_API void addPart( const MeshTopology & from,
452 FaceMap * outFmap = nullptr, VertMap * outVmap = nullptr, WholeEdgeMap * outEmap = nullptr,
453 bool rearrangeTriangles = false );
454
456 MRMESH_API void addPartByMask( const MeshTopology & from, const FaceBitSet * fromFaces, const PartMapping & map = {} );
457 void addPartByMask( const MeshTopology & from, const FaceBitSet & fromFaces, const PartMapping & map = {} )
458 { addPartByMask( from, &fromFaces, map ); }
459
464 MRMESH_API void addPartByMask( const MeshTopology & from, const FaceBitSet * fromFaces, bool flipOrientation = false,
465 const std::vector<EdgePath> & thisContours = {}, const std::vector<EdgePath> & fromContours = {},
466 const PartMapping & map = {} );
467 void addPartByMask( const MeshTopology & from, const FaceBitSet & fromFaces, bool flipOrientation = false,
468 const std::vector<EdgePath> & thisContours = {}, const std::vector<EdgePath> & fromContours = {},
469 const PartMapping & map = {} ) { addPartByMask( from, &fromFaces, flipOrientation, thisContours, fromContours, map ); }
470
473
478 MRMESH_API void pack( FaceMap * outFmap = nullptr, VertMap * outVmap = nullptr, WholeEdgeMap * outEmap = nullptr, bool rearrangeTriangles = false );
479
482 MRMESH_API void pack( const PackMapping & map );
483
487 MRMESH_API void packMinMem( const PackMapping & map );
488
489
491 MRMESH_API void write( std::ostream & s ) const;
492
495 MRMESH_API Expected<void> read( std::istream& s, ProgressCallback callback = {} );
496
498 [[nodiscard]] MRMESH_API bool operator ==( const MeshTopology & b ) const;
499
504
508 MRMESH_API void addPackedPart( const MeshTopology & from, EdgeId toEdgeId,
509 const FaceMap & fmap, const VertMap & vmap );
510
516
519
521 [[nodiscard]] bool updatingValids() const { return updateValids_; }
522
525 MRMESH_API void preferEdges( const UndirectedEdgeBitSet & stableEdges );
526
527 // constructs triangular grid mesh topology in parallel
528 MRMESH_API bool buildGridMesh( const GridSettings& settings, ProgressCallback cb = {} );
529
532 MRMESH_API bool checkValidity( ProgressCallback cb = {}, bool allVerts = true ) const;
533
534private:
535 friend class MeshTopologyDiff;
539 MRMESH_API void computeAllFromEdges_();
540
541private:
543 void setOrg_( EdgeId a, VertId v );
544
546 void setLeft_( EdgeId a, FaceId f );
547
549 struct HalfEdgeRecord
550 {
551 EdgeId next;
552 EdgeId prev;
553 VertId org;
554 FaceId left;
555
556 bool operator ==( const HalfEdgeRecord& b ) const
557 {
558 return next == b.next && prev == b.prev && org == b.org && left == b.left;
559 }
560 HalfEdgeRecord() noexcept = default;
561 explicit HalfEdgeRecord( NoInit ) noexcept : next( noInit ), prev( noInit ), org( noInit ), left( noInit ) {}
562 };
564 template<typename FM, typename VM, typename WEM>
565 void translateNoFlip_( HalfEdgeRecord & r, const FM & fmap, const VM & vmap, const WEM & emap ) const;
566 template<typename FM, typename VM, typename WEM>
567 void translate_( HalfEdgeRecord & r, HalfEdgeRecord & rsym,
568 const FM & fmap, const VM & vmap, const WEM & emap, bool flipOrientation ) const;
569
571 Vector<HalfEdgeRecord, EdgeId> edges_;
572
574 Vector<EdgeId, VertId> edgePerVertex_;
575 VertBitSet validVerts_;
576
578 Vector<EdgeId, FaceId> edgePerFace_;
579 FaceBitSet validFaces_;
580
581 int numValidVerts_ = 0;
582 int numValidFaces_ = 0;
583
584 bool updateValids_ = true;
585};
586
587template <typename T>
588void MeshTopology::forEachVertex( const MeshTriPoint & p, T && callback ) const
589{
590 if ( auto v = p.inVertex( *this ) )
591 {
592 callback( v );
593 return;
594 }
595 if ( auto e = p.onEdge( *this ) )
596 {
597 callback( org( e.e ) );
598 callback( dest( e.e ) );
599 return;
600 }
601
602 VertId v[3];
603 getLeftTriVerts( p.e, v );
604 for ( int i = 0; i < 3; ++i )
605 callback( v[i] );
606}
607
608template<typename T>
609void MeshTopology::flipEdgesIn( const EdgeId e0, T && flipNeeded )
610{
611 EdgeId e = e0;
612 for (;;)
613 {
614 auto testEdge = prev( e.sym() );
615 if ( left( testEdge ) && right( testEdge ) && flipNeeded( testEdge ) )
616 flipEdge( testEdge );
617 else
618 {
619 e = next( e );
620 if ( e == e0 )
621 break; // full ring has been inspected
622 }
623 }
624}
625
626template<typename T>
627void MeshTopology::flipEdgesOut( EdgeId e0, T && flipNeeded )
628{
629 EdgeId e = e0;
630 for (;;)
631 {
632 if ( left( e ) && right( e ) && flipNeeded( e ) )
633 {
634 e0 = next( e );
635 flipEdge( e );
636 e = e0;
637 }
638 else
639 {
640 e = next( e );
641 if ( e == e0 )
642 break; // full ring has been inspected
643 }
644 }
645}
646
647// rearrange vector values by map (old.id -> new.id)
648template<typename T, typename I>
649[[nodiscard]] Vector<T, I> rearrangeVectorByMap( const Vector<T, I>& oldVector, const BMap<I, I>& map )
650{
651 Vector<T, I> newVector;
652 newVector.resize( map.tsize );
653
654 const auto& mData = map.b.data();
655 const auto sz = std::min( oldVector.size(), map.b.size() );
656 for ( I i = I(0); i < sz; ++i)
657 {
658 I newV = mData[i];
659 if ( newV.valid() )
660 newVector[newV] = oldVector[i];
661 }
662 return newVector;
663}
664
666
667} // namespace MR
#define MRMESH_API
Definition MRMesh/MRMeshFwd.h:80
auto size() const
Definition MRBuffer.h:66
auto data()
Definition MRBuffer.h:97
Definition MRMeshTopologyDiff.h:13
Definition MRMesh/MRMeshTopology.h:19
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:609
MRMESH_API MR_BIND_IGNORE FaceBitSet findBoundaryFaces(const FaceBitSet *region=nullptr) const
MR_BIND_IGNORE void getTriVerts(FaceId f, VertId(&v)[3]) const
Definition MRMesh/MRMeshTopology.h:136
size_t faceCapacity() const
returns the number of allocated face records
Definition MRMesh/MRMeshTopology.h:274
VertId addVertId()
creates new vert-id not associated with any edge yet
Definition MRMesh/MRMeshTopology.h:193
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 void addPart(const MeshTopology &from, const PartMapping &map={}, bool rearrangeTriangles=false)
MRMESH_API MR_BIND_IGNORE EdgeBitSet findBoundaryEdges() const
returns all boundary edges, where each edge does not have valid left face
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:135
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 void getLeftTriVerts(EdgeId a, VertId &v0, VertId &v1, VertId &v2) const
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
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:627
MRMESH_API VertBitSet findBdVerts(const FaceBitSet *region=nullptr, const VertBitSet *test=nullptr) const
returns all (test) vertices for which isBdVertex(v, region) is true
void faceReserve(size_t newCapacity)
sets the capacity of faces vector
Definition MRMesh/MRMeshTopology.h:268
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:310
size_t vertSize() const
returns the number of vertex records including invalid ones
Definition MRMesh/MRMeshTopology.h:205
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:84
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:122
EdgeId bdEdgeWithOrigin(VertId v, const FaceBitSet *region=nullptr) const
Definition MRMesh/MRMeshTopology.h:334
bool hasVert(VertId a) const
returns true if given vertex is present in the mesh
Definition MRMesh/MRMeshTopology.h:184
FaceId left(EdgeId he) const
returns left face of half-edge
Definition MRMesh/MRMeshTopology.h:96
const Vector< EdgeId, VertId > & edgePerVertex() const
for all valid vertices this vector contains an edge with the origin there
Definition MRMesh/MRMeshTopology.h:178
MRMESH_API void setLeft(EdgeId a, FaceId f)
MRMESH_API void vertResize(size_t newSize)
explicitly increases the size of vertices vector
MRMESH_API MR_BIND_IGNORE VertBitSet findBoundaryVerts(const VertBitSet *region=nullptr) const
EdgeId bdEdgeWithLeft(FaceId f, const FaceBitSet *region=nullptr) const
Definition MRMesh/MRMeshTopology.h:300
MRMESH_API bool isLeftTri(EdgeId a) const
returns true if the cell to the left of a is triangular
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 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:93
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:521
MRMESH_API FaceBitSet findBdFaces(const FaceBitSet *region=nullptr) const
returns all faces for which isBdFace(f, region) is true
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...
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:171
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:232
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:37
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={})
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 isLeftBdFace(EdgeId e, const FaceBitSet *region=nullptr) const
Definition MRMesh/MRMeshTopology.h:296
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:349
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:128
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 MRMesh/MRMeshTopology.h:303
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:346
int numValidVerts() const
returns the number of valid vertices
Definition MRMesh/MRMeshTopology.h:187
VertId org(EdgeId he) const
returns origin vertex of half-edge
Definition MRMesh/MRMeshTopology.h:90
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:229
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:413
EdgeId prev(EdgeId he) const
previous (clock wise) half-edge in the origin ring
Definition MRMesh/MRMeshTopology.h:87
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)
MRMESH_API bool checkValidity(ProgressCallback cb={}, bool allVerts=true) const
ThreeVertIds getTriVerts(FaceId f) const
Definition MRMesh/MRMeshTopology.h:138
MRMESH_API int getLeftDegree(EdgeId a) const
returns the number of edges around the left face: 3 for triangular faces, ...
EdgeId lastNotLoneEdge() const
returns last not lone edge id, or invalid id if no such edge exists
Definition MRMesh/MRMeshTopology.h:31
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 and not ...
void addPartByMask(const MeshTopology &from, const FaceBitSet &fromFaces, const PartMapping &map={})
Definition MRMesh/MRMeshTopology.h:457
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:313
size_t edgeCapacity() const
returns the number of allocated edge records
Definition MRMesh/MRMeshTopology.h:40
int numValidFaces() const
returns the number of valid faces
Definition MRMesh/MRMeshTopology.h:247
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 UndirectedEdgeId lastNotLoneUndirectedEdge() const
returns last not lone undirected edge id, or invalid id if no such edge exists
EdgeId edgeWithOrg(VertId a) const
returns valid edge if given vertex is present in the mesh
Definition MRMesh/MRMeshTopology.h:181
size_t faceSize() const
returns the number of face records including invalid ones
Definition MRMesh/MRMeshTopology.h:271
MR_BIND_IGNORE void getTriEdges(FaceId f, EdgeId(&e)[3]) const
Definition MRMesh/MRMeshTopology.h:172
void edgeReserve(size_t newCapacity)
sets the capacity of half-edges vector
Definition MRMesh/MRMeshTopology.h:55
void getLeftTriVerts(EdgeId a, ThreeVertIds &v) const
Definition MRMesh/MRMeshTopology.h:154
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:588
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:253
void flipEdgesOut(VertId v, T &&flipNeeded)
Definition MRMesh/MRMeshTopology.h:423
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 deleteFaces(const FaceBitSet &fs, const UndirectedEdgeBitSet *keepEdges=nullptr)
deletes multiple given faces by calling deleteFace for each
MRMESH_API bool isBdEdge(EdgeId e, const FaceBitSet *region=nullptr) const
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:43
void vertReserve(size_t newCapacity)
sets the capacity of vertices vector
Definition MRMesh/MRMeshTopology.h:202
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:214
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:137
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:99
MRMESH_API size_t computeNotLoneUndirectedEdges() const
computes the number of not-lone (valid) undirected edges
MR_BIND_IGNORE void getLeftTriVerts(EdgeId a, VertId(&v)[3]) const
Definition MRMesh/MRMeshTopology.h:153
bool hasEdge(EdgeId e) const
returns true if given edge is within valid range and not-lone
Definition MRMesh/MRMeshTopology.h:58
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:217
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:226
bool isBdVertex(VertId v, const FaceBitSet *region=nullptr) const
returns true if given vertex is on (region) boundary
Definition MRMesh/MRMeshTopology.h:337
bool isBdVertexInOrg(EdgeId e, const FaceBitSet *region=nullptr) const
returns true if edge's origin is on (region) boundary
Definition MRMesh/MRMeshTopology.h:330
const VertBitSet & getValidVerts() const
returns cached set of all valid vertices
Definition MRMesh/MRMeshTopology.h:211
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:46
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:280
ThreeVertIds getLeftTriVerts(EdgeId a) const
Definition MRMesh/MRMeshTopology.h:155
MRMESH_API void faceResize(size_t newSize)
explicitly increases the size of faces vector
bool isTriVert(FaceId f, VertId v) const
return true if triangular face (f) has (v) as one of its vertices
Definition MRMesh/MRMeshTopology.h:141
void addPartByMask(const MeshTopology &from, const FaceBitSet &fromFaces, bool flipOrientation=false, const std::vector< EdgePath > &thisContours={}, const std::vector< EdgePath > &fromContours={}, const PartMapping &map={})
Definition MRMesh/MRMeshTopology.h:467
MRMESH_API bool buildGridMesh(const GridSettings &settings, ProgressCallback cb={})
const FaceBitSet & getValidFaces() const
returns cached set of all valid faces
Definition MRMesh/MRMeshTopology.h:277
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:283
size_t vertCapacity() const
returns the number of allocated vert records
Definition MRMesh/MRMeshTopology.h:208
MRMESH_API 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,...
std::vector<T>-like container that requires specific indexing type,
Definition MRMesh/MRVector.h:19
std::size_t size() const
Definition MRMesh/MRVector.h:51
std::size_t capacity() const
Definition MRMesh/MRVector.h:59
void resize(size_t newSize) MR_REQUIRES_IF_SUPPORTED(sizeof(T)>0 &&std
Definition MRMesh/MRVector.h:53
void reserve(size_t capacity)
Definition MRMesh/MRVector.h:61
I backId() const
returns the identifier of the back() element
Definition MRMesh/MRVector.h:144
bool contains(const TypedBitSet< I > *bitset, I id)
Definition MRMesh/MRBitSet.h:254
std::function< bool(float)> ProgressCallback
Definition MRMesh/MRMeshFwd.h:728
Definition MRCameraOrientationPlugin.h:8
std::vector< EdgeId > EdgeLoop
Definition MRMesh/MRMeshFwd.h:141
struct MRMESH_CLASS PartMapping
Definition MRMesh/MRMeshFwd.h:626
tl::expected< T, E > Expected
Definition MRExpected.h:25
MRMESH_API void loadMeshDll()
HashMap< FaceId, FaceId > FaceHashMap
Definition MRMesh/MRMeshFwd.h:596
std::vector< EdgeId > EdgePath
Definition MRMesh/MRMeshFwd.h:140
std::array< VertId, 3 > ThreeVertIds
three vertex ids describing a triangle with the corners in vertices given by their ids
Definition MRMesh/MRMeshFwd.h:511
constexpr NoInit noInit
Definition MRMesh/MRMeshFwd.h:91
I
Definition MRMesh/MRMeshFwd.h:130
Vector< T, I > rearrangeVectorByMap(const Vector< T, I > &oldVector, const BMap< I, I > &map)
Definition MRMesh/MRMeshTopology.h:649
std::array< Vector3f, 3 > MR_BIND_IGNORE
Definition MRMeshBuilderTypes.h:10
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:90
Definition MRBuffer.h:151
mapping among elements of source mesh, from which a part is taken, and target mesh
Definition MRPartMapping.h:11