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 <fstream>
12
13namespace MR
14{
17
18
22{
23public:
25 [[nodiscard]] MRMESH_API EdgeId makeEdge();
26
28 [[nodiscard]] MRMESH_API bool isLoneEdge( EdgeId a ) const;
29
31 [[nodiscard]] MRMESH_API UndirectedEdgeId lastNotLoneUndirectedEdge() const;
32
34 [[nodiscard]] EdgeId lastNotLoneEdge() const { auto ue = lastNotLoneUndirectedEdge(); return ue ? EdgeId( ue ) + 1 : EdgeId(); }
35
37 MRMESH_API void excludeLoneEdges( UndirectedEdgeBitSet & edges ) const;
38
40 [[nodiscard]] size_t edgeSize() const { return edges_.size(); }
41
43 [[nodiscard]] size_t edgeCapacity() const { return edges_.capacity(); }
44
46 [[nodiscard]] size_t undirectedEdgeSize() const { return edges_.size() >> 1; }
47
49 [[nodiscard]] size_t undirectedEdgeCapacity() const { return edges_.capacity() >> 1; }
50
52 [[nodiscard]] MRMESH_API size_t computeNotLoneUndirectedEdges() const;
53
55 [[nodiscard]] MRMESH_API UndirectedEdgeBitSet findNotLoneUndirectedEdges() const;
56
58 void edgeReserve( size_t newCapacity ) { edges_.reserve( newCapacity ); }
59
61 [[nodiscard]] bool hasEdge( EdgeId e ) const { assert( e.valid() ); return e < (int)edgeSize() && !isLoneEdge( e ); }
62
64 [[nodiscard]] MRMESH_API size_t heapBytes() const;
65
67 MRMESH_API void shrinkToFit();
68
69
74 MRMESH_API void splice( EdgeId a, EdgeId b );
75
83 MRMESH_API EdgeId collapseEdge( EdgeId e, const std::function<void( EdgeId del, EdgeId rem )> & onEdgeDel );
84
85
87 [[nodiscard]] EdgeId next( EdgeId he ) const { assert(he.valid()); return edges_[he].next; }
88
90 [[nodiscard]] EdgeId prev( EdgeId he ) const { assert(he.valid()); return edges_[he].prev; }
91
93 [[nodiscard]] VertId org( EdgeId he ) const { assert(he.valid()); return edges_[he].org; }
94
96 [[nodiscard]] VertId dest( EdgeId he ) const { assert(he.valid()); return edges_[he.sym()].org; }
97
99 [[nodiscard]] FaceId left( EdgeId he ) const { assert(he.valid()); return edges_[he].left; }
100
102 [[nodiscard]] FaceId right( EdgeId he ) const { assert(he.valid()); return edges_[he.sym()].left; }
103
104
107 MRMESH_API void setOrg( EdgeId a, VertId v );
108
111 MRMESH_API void setLeft( EdgeId a, FaceId f );
112
113
115 [[nodiscard]] MRMESH_API bool fromSameOriginRing( EdgeId a, EdgeId b ) const;
116
118 [[nodiscard]] MRMESH_API bool fromSameLeftRing( EdgeId a, EdgeId b ) const;
119
120
122 [[nodiscard]] MRMESH_API int getOrgDegree( EdgeId a ) const;
123
125 [[nodiscard]] int getVertDegree( VertId v ) const { return getOrgDegree( edgeWithOrg( v ) ); }
126
128 [[nodiscard]] MRMESH_API int getLeftDegree( EdgeId a ) const;
129
131 [[nodiscard]] int getFaceDegree( FaceId f ) const { return getLeftDegree( edgeWithLeft( f ) ); }
132
134 [[nodiscard]] MRMESH_API bool isLeftTri( EdgeId a ) const;
135
138 void getTriVerts( FaceId f, VertId & v0, VertId & v1, VertId & v2 ) const { getLeftTriVerts( edgeWithLeft( f ), v0, v1, v2 ); }
139 MR_BIND_IGNORE void getTriVerts( FaceId f, VertId (&v)[3] ) const { getLeftTriVerts( edgeWithLeft( f ), v ); }
140 void getTriVerts( FaceId f, ThreeVertIds & v ) const { getLeftTriVerts( edgeWithLeft( f ), v ); }
141 [[nodiscard]] ThreeVertIds getTriVerts( FaceId f ) const { return getLeftTriVerts( edgeWithLeft( f ) ); }
142
144 [[nodiscard]] bool isTriVert( FaceId f, VertId v ) const { auto vs = getTriVerts( f ); return v == vs[0] || v == vs[1] || v == vs[2]; }
145
147 [[nodiscard]] MRMESH_API std::vector<ThreeVertIds> getAllTriVerts() const;
148
151 [[nodiscard]] MRMESH_API Triangulation getTriangulation() const;
152
155 MRMESH_API void getLeftTriVerts( EdgeId a, VertId & v0, VertId & v1, VertId & v2 ) const;
156 MR_BIND_IGNORE void getLeftTriVerts( EdgeId a, VertId (&v)[3] ) const { getLeftTriVerts( a, v[0], v[1], v[2] ); }
157 void getLeftTriVerts( EdgeId a, ThreeVertIds & v ) const { getLeftTriVerts( a, v[0], v[1], v[2] ); }
158 [[nodiscard]] ThreeVertIds getLeftTriVerts( EdgeId a ) const { ThreeVertIds v; getLeftTriVerts( a, v[0], v[1], v[2] ); return v; }
159
164 template <typename T>
165 void forEachVertex( const MeshTriPoint & p, T && callback ) const;
166
170 MRMESH_API void getLeftTriEdges( EdgeId e0, EdgeId & e1, EdgeId & e2 ) const;
171
174 void getTriEdges( FaceId f, EdgeId & e0, EdgeId & e1, EdgeId & e2 ) const { getLeftTriEdges( e0 = edgeWithLeft( f ), e1, e2 ); }
175 MR_BIND_IGNORE void getTriEdges( FaceId f, EdgeId (&e)[3] ) const { getLeftTriEdges( e[0] = edgeWithLeft( f ), e[1], e[2] ); }
176
178 [[nodiscard]] MRMESH_API bool isLeftQuad( EdgeId a ) const;
179
181 [[nodiscard]] const Vector<EdgeId, VertId> & edgePerVertex() const { return edgePerVertex_; }
182
184 [[nodiscard]] EdgeId edgeWithOrg( VertId a ) const { assert( a.valid() ); return a < int(edgePerVertex_.size()) ? edgePerVertex_[a] : EdgeId(); }
185
187 [[nodiscard]] bool hasVert( VertId a ) const { assert( updateValids_ ); return validVerts_.test( a ); }
188
190 [[nodiscard]] int numValidVerts() const { assert( updateValids_ ); return numValidVerts_; }
191
193 [[nodiscard]] MRMESH_API VertId lastValidVert() const;
194
196 [[nodiscard]] VertId addVertId() { edgePerVertex_.emplace_back(); if ( updateValids_ ) { validVerts_.push_back( false ); } return edgePerVertex_.backId(); }
197
199 MRMESH_API void vertResize( size_t newSize );
200
202 MRMESH_API void vertResizeWithReserve( size_t newSize );
203
205 void vertReserve( size_t newCapacity ) { edgePerVertex_.reserve( newCapacity ); if ( updateValids_ ) { validVerts_.reserve( newCapacity ); } }
206
208 [[nodiscard]] size_t vertSize() const { return edgePerVertex_.size(); }
209
211 [[nodiscard]] size_t vertCapacity() const { return edgePerVertex_.capacity(); }
212
214 [[nodiscard]] const VertBitSet & getValidVerts() const { assert( updateValids_ ); return validVerts_; }
215
217 void flip( VertBitSet & vs ) const { vs = getValidVerts() - vs; }
218
220 [[nodiscard]] const VertBitSet & getVertIds( const VertBitSet * region ) const
221 {
222 assert( region || updateValids_ );
223 assert( !updateValids_ || !region || region->is_subset_of( validVerts_ ) );
224 return region ? *region : validVerts_;
225 }
226
227
229 [[nodiscard]] const Vector<EdgeId, FaceId> & edgePerFace() const { return edgePerFace_; }
230
232 [[nodiscard]] EdgeId edgeWithLeft( FaceId a ) const { assert( a.valid() ); return a < int(edgePerFace_.size()) ? edgePerFace_[a] : EdgeId(); }
233
235 [[nodiscard]] bool hasFace( FaceId a ) const { assert( updateValids_ ); return validFaces_.test( a ); }
236
238 [[nodiscard]] MRMESH_API EdgeId sharedEdge( FaceId l, FaceId r ) const;
239
241 [[nodiscard]] MRMESH_API EdgeId sharedVertInOrg( EdgeId a, EdgeId b ) const;
242
244 [[nodiscard]] MRMESH_API EdgeId sharedVertInOrg( FaceId l, FaceId r ) const;
245
247 [[nodiscard]] MRMESH_API FaceId sharedFace( EdgeId a, EdgeId b ) const;
248
250 [[nodiscard]] int numValidFaces() const { assert( updateValids_ ); return numValidFaces_; }
251
253 [[nodiscard]] MRMESH_API FaceId lastValidFace() const;
254
256 [[nodiscard]] FaceId addFaceId() { edgePerFace_.emplace_back(); if ( updateValids_ ) { validFaces_.push_back( false ); } return edgePerFace_.backId(); }
257
259 MRMESH_API void deleteFace( FaceId f, const UndirectedEdgeBitSet * keepEdges = nullptr );
260
262 MRMESH_API void deleteFaces( const FaceBitSet & fs, const UndirectedEdgeBitSet * keepEdges = nullptr );
263
265 MRMESH_API void faceResize( size_t newSize );
266
268 MRMESH_API void faceResizeWithReserve( size_t newSize );
269
271 void faceReserve( size_t newCapacity ) { edgePerFace_.reserve( newCapacity ); if ( updateValids_ ) { validFaces_.reserve( newCapacity ); } }
272
274 [[nodiscard]] size_t faceSize() const { return edgePerFace_.size(); }
275
277 [[nodiscard]] size_t faceCapacity() const { return edgePerFace_.capacity(); }
278
280 [[nodiscard]] const FaceBitSet & getValidFaces() const { assert( updateValids_ ); return validFaces_; }
281
283 void flip( FaceBitSet & fs ) const { fs = getValidFaces() - fs; }
284
286 [[nodiscard]] const FaceBitSet & getFaceIds( const FaceBitSet * region ) const
287 {
288 assert( region || updateValids_ );
289 assert( !updateValids_ || !region || region->is_subset_of( validFaces_ ) );
290 return region ? *region : validFaces_;
291 }
292
295 [[nodiscard]] MRMESH_API EdgeId bdEdgeSameLeft( EdgeId e, const FaceBitSet * region = nullptr ) const;
296
299 [[nodiscard]] bool isLeftBdFace( EdgeId e, const FaceBitSet * region = nullptr ) const { return contains( region, left( e ) ) && bdEdgeSameLeft( e, region ).valid(); }
300
303 [[nodiscard]] EdgeId bdEdgeWithLeft( FaceId f, const FaceBitSet * region = nullptr ) const { return bdEdgeSameLeft( edgeWithLeft( f ), region ); }
304
306 [[nodiscard]] bool isBdFace( FaceId f, const FaceBitSet * region = nullptr ) const { return isLeftBdFace( edgeWithLeft( f ), region ); }
307
309 [[nodiscard]] MRMESH_API FaceBitSet findBdFaces( const FaceBitSet * region = nullptr ) const;
310
311
313 [[nodiscard]] bool isLeftInRegion( EdgeId e, const FaceBitSet * region = nullptr ) const { return contains( region, left( e ) ); }
314
316 [[nodiscard]] bool isInnerEdge( EdgeId e, const FaceBitSet * region = nullptr ) const { return isLeftInRegion( e, region ) && isLeftInRegion( e.sym(), region ); }
317
323 [[nodiscard]] MRMESH_API bool isBdEdge( EdgeId e, const FaceBitSet * region = nullptr ) const;
324
326 [[nodiscard]] MRMESH_API EdgeBitSet findLeftBdEdges( const FaceBitSet * region = nullptr, const EdgeBitSet * test = nullptr ) const;
327
330 [[nodiscard]] MRMESH_API EdgeId bdEdgeSameOrigin( EdgeId e, const FaceBitSet * region = nullptr ) const;
331
333 [[nodiscard]] bool isBdVertexInOrg( EdgeId e, const FaceBitSet * region = nullptr ) const { return bdEdgeSameOrigin( e, region ).valid(); }
334
337 [[nodiscard]] EdgeId bdEdgeWithOrigin( VertId v, const FaceBitSet * region = nullptr ) const { return bdEdgeSameOrigin( edgeWithOrg( v ), region ); }
338
340 [[nodiscard]] bool isBdVertex( VertId v, const FaceBitSet * region = nullptr ) const { return isBdVertexInOrg( edgeWithOrg( v ), region ); }
341
343 [[nodiscard]] MRMESH_API VertBitSet findBdVerts( const FaceBitSet * region = nullptr, const VertBitSet * test = nullptr ) const;
344
346 [[nodiscard]] MRMESH_API bool isInnerOrBdVertex( VertId v, const FaceBitSet * region = nullptr ) const;
347
349 [[nodiscard]] bool isLeftBdEdge( EdgeId e, const FaceBitSet * region = nullptr ) const { return region ? ( isLeftInRegion( e, region ) && !isLeftInRegion( e.sym(), region ) ) : !right( e ); }
350
352 [[nodiscard]] bool isInnerOrBdEdge( EdgeId e, const FaceBitSet * region = nullptr ) const { return isLeftInRegion( e, region ) || isLeftInRegion( e.sym(), region ); }
353
355 [[nodiscard]] MRMESH_API EdgeId nextLeftBd( EdgeId e, const FaceBitSet * region = nullptr ) const;
356
358 [[nodiscard]] MRMESH_API EdgeId prevLeftBd( EdgeId e, const FaceBitSet * region = nullptr ) const;
359
360
362 [[nodiscard]] MRMESH_API EdgeId findEdge( VertId o, VertId d ) const;
363
365 [[nodiscard]] MRMESH_API bool isClosed( const FaceBitSet * region = nullptr ) const;
366
369 [[nodiscard]] MRMESH_API std::vector<EdgeId> findHoleRepresentiveEdges( const FaceBitSet * region = nullptr ) const;
370
373 [[nodiscard]] MRMESH_API int findNumHoles( EdgeBitSet * holeRepresentativeEdges = nullptr ) const;
374
376 [[nodiscard]] MRMESH_API EdgeLoop getLeftRing( EdgeId e ) const;
377
380 [[nodiscard]] MRMESH_API std::vector<EdgeLoop> getLeftRings( const std::vector<EdgeId> & es ) const;
381
383 [[nodiscard]] [[deprecated( "Use findLeftBdEdges")]] MRMESH_API MR_BIND_IGNORE EdgeBitSet findBoundaryEdges() const;
384
387 [[nodiscard]] [[deprecated( "Use findBdFaces")]] MRMESH_API MR_BIND_IGNORE FaceBitSet findBoundaryFaces( const FaceBitSet * region = nullptr ) const;
388
391 [[nodiscard]] [[deprecated( "Use findBdVerts")]] MRMESH_API MR_BIND_IGNORE VertBitSet findBoundaryVerts( const VertBitSet * region = nullptr ) const;
392
393
395 [[nodiscard]] MRMESH_API VertBitSet getPathVertices( const EdgePath & path ) const;
396
398 [[nodiscard]] MRMESH_API FaceBitSet getPathLeftFaces( const EdgePath & path ) const;
399
401 [[nodiscard]] MRMESH_API FaceBitSet getPathRightFaces( const EdgePath & path ) const;
402
403
406 MRMESH_API void flipEdge( EdgeId e );
407
410 template<typename T>
411 void flipEdgesIn( EdgeId e0, T && flipNeeded );
412
415 template<typename T>
416 void flipEdgesIn( VertId v, T && flipNeeded ) { flipEdgesIn( edgeWithOrg( v ), std::forward<T>( flipNeeded ) ); }
417
420 template<typename T>
421 void flipEdgesOut( EdgeId e0, T && flipNeeded );
422
425 template<typename T>
426 void flipEdgesOut( VertId v, T && flipNeeded ) { flipEdgesOut( edgeWithOrg( v ), std::forward<T>( flipNeeded ) ); }
427
436 MRMESH_API EdgeId splitEdge( EdgeId e, FaceBitSet * region = nullptr, FaceHashMap * new2Old = nullptr );
437
441 MRMESH_API VertId splitFace( FaceId f, FaceBitSet * region = nullptr, FaceHashMap * new2Old = nullptr );
442
447 MRMESH_API void flipOrientation( const UndirectedEdgeBitSet * fullComponents = nullptr );
448
449
453 MRMESH_API void addPart( const MeshTopology & from, const PartMapping & map = {}, bool rearrangeTriangles = false );
454 MRMESH_API void addPart( const MeshTopology & from,
455 FaceMap * outFmap = nullptr, VertMap * outVmap = nullptr, WholeEdgeMap * outEmap = nullptr,
456 bool rearrangeTriangles = false );
457
459 MRMESH_API void addPartByMask( const MeshTopology & from, const FaceBitSet * fromFaces, const PartMapping & map = {} );
461 MR_BIND_IGNORE void addPartByMask( const MeshTopology & from, const FaceBitSet & fromFaces, const PartMapping & map = {} )
462 { addPartByMask( from, &fromFaces, map ); }
463
468 MRMESH_API void addPartByMask( const MeshTopology & from, const FaceBitSet * fromFaces, bool flipOrientation = false,
469 const std::vector<EdgePath> & thisContours = {}, const std::vector<EdgePath> & fromContours = {},
470 const PartMapping & map = {} );
471
473 MR_BIND_IGNORE void addPartByMask( const MeshTopology & from, const FaceBitSet & fromFaces, bool flipOrientation = false,
474 const std::vector<EdgePath> & thisContours = {}, const std::vector<EdgePath> & fromContours = {},
475 const PartMapping & map = {} ) { addPartByMask( from, &fromFaces, flipOrientation, thisContours, fromContours, map ); }
476
478 MRMESH_API void rotateTriangles();
479
484 MRMESH_API void pack( FaceMap * outFmap = nullptr, VertMap * outVmap = nullptr, WholeEdgeMap * outEmap = nullptr, bool rearrangeTriangles = false );
485
488 MRMESH_API void pack( const PackMapping & map );
489
493 MRMESH_API void packMinMem( const PackMapping & map );
494
495
497 MRMESH_API void write( std::ostream & s ) const;
498
501 MRMESH_API Expected<void> read( std::istream& s, ProgressCallback callback = {} );
502
504 [[nodiscard]] MRMESH_API bool operator ==( const MeshTopology & b ) const;
505
509 MRMESH_API void resizeBeforeParallelAdd( size_t edgeSize, size_t vertSize, size_t faceSize );
510
514 MRMESH_API void addPackedPart( const MeshTopology & from, EdgeId toEdgeId,
515 const FaceMap & fmap, const VertMap & vmap );
516
521 MRMESH_API bool computeValidsFromEdges( ProgressCallback cb = {} );
522
524 MRMESH_API void stopUpdatingValids();
525
527 [[nodiscard]] bool updatingValids() const { return updateValids_; }
528
531 MRMESH_API void preferEdges( const UndirectedEdgeBitSet & stableEdges );
532
534 MRMESH_API bool buildGridMesh( const GridSettings& settings, ProgressCallback cb = {} );
535
538 MRMESH_API bool checkValidity( ProgressCallback cb = {}, bool allVerts = true ) const;
539
540private:
541 friend class MeshTopologyDiff;
545 MRMESH_API void computeAllFromEdges_();
546
547private:
549 void setOrg_( EdgeId a, VertId v );
550
552 void fillOrg_();
553
555 void setLeft_( EdgeId a, FaceId f );
556
558 void fillLeft_();
559
561 struct alignas( 16 ) HalfEdgeRecord
562 {
563 EdgeId next;
564 EdgeId prev;
565 VertId org;
566 FaceId left;
567
568 bool operator ==( const HalfEdgeRecord& b ) const
569 {
570 return next == b.next && prev == b.prev && org == b.org && left == b.left;
571 }
572 HalfEdgeRecord() noexcept = default;
573 explicit HalfEdgeRecord( NoInit ) noexcept : next( noInit ), prev( noInit ), org( noInit ), left( noInit ) {}
574 };
575 static_assert( sizeof( HalfEdgeRecord ) == 16 );
576
578 template<typename FM, typename VM, typename WEM>
579 void translateNoFlip_( HalfEdgeRecord & r, const FM & fmap, const VM & vmap, const WEM & emap ) const;
580 template<typename FM, typename VM, typename WEM>
581 void translate_( HalfEdgeRecord & r, HalfEdgeRecord & rsym,
582 const FM & fmap, const VM & vmap, const WEM & emap, bool flipOrientation ) const;
583
586
588 Vector<EdgeId, VertId> edgePerVertex_;
589 VertBitSet validVerts_;
590
592 Vector<EdgeId, FaceId> edgePerFace_;
593 FaceBitSet validFaces_;
594
595 int numValidVerts_ = 0;
596 int numValidFaces_ = 0;
597
598 bool updateValids_ = true;
599};
600
601template <typename T>
602void MeshTopology::forEachVertex( const MeshTriPoint & p, T && callback ) const
603{
604 if ( auto v = p.inVertex( *this ) )
605 {
606 callback( v );
607 return;
608 }
609 if ( auto e = p.onEdge( *this ) )
610 {
611 callback( org( e.e ) );
612 callback( dest( e.e ) );
613 return;
614 }
615
616 VertId v[3];
617 getLeftTriVerts( p.e, v );
618 for ( int i = 0; i < 3; ++i )
619 callback( v[i] );
620}
621
622template<typename T>
623void MeshTopology::flipEdgesIn( const EdgeId e0, T && flipNeeded )
624{
625 EdgeId e = e0;
626 for (;;)
627 {
628 auto testEdge = prev( e.sym() );
629 if ( left( testEdge ) && right( testEdge ) && flipNeeded( testEdge ) )
630 flipEdge( testEdge );
631 else
632 {
633 e = next( e );
634 if ( e == e0 )
635 break;
636 }
637 }
638}
639
640template<typename T>
641void MeshTopology::flipEdgesOut( EdgeId e0, T && flipNeeded )
642{
643 EdgeId e = e0;
644 for (;;)
645 {
646 if ( left( e ) && right( e ) && flipNeeded( e ) )
647 {
648 e0 = next( e );
649 flipEdge( e );
650 e = e0;
651 }
652 else
653 {
654 e = next( e );
655 if ( e == e0 )
656 break;
657 }
658 }
659}
660
662template<typename T, typename I>
663[[nodiscard]] Vector<T, I> rearrangeVectorByMap( const Vector<T, I>& oldVector, const BMap<I, I>& map )
664{
665 Vector<T, I> newVector;
666 newVector.resize( map.tsize );
667
668 const auto& mData = map.b.data();
669 const auto sz = std::min( oldVector.size(), map.b.size() );
670 for ( I i = I(0); i < sz; ++i)
671 {
672 I newV = mData[i];
673 if ( newV.valid() )
674 newVector[newV] = oldVector[i];
675 }
676 return newVector;
677}
678
679}
Definition MRMeshTopologyDiff.h:16
Definition MRMeshTopology.h:22
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:341
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 MRMeshTopology.h:623
MRMESH_API MR_BIND_IGNORE FaceBitSet findBoundaryFaces(const FaceBitSet *region=nullptr) const
MR_BIND_IGNORE void getTriVerts(FaceId f, VertId(&v)[3]) const
Definition MRMeshTopology.h:139
size_t faceCapacity() const
returns the number of allocated face records
Definition MRMeshTopology.h:277
VertId addVertId()
creates new vert-id not associated with any edge yet
Definition MRMeshTopology.h:196
MRMESH_API void splice(EdgeId a, EdgeId b)
Buffer< T, I > b
Definition MRBuffer.h:148
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 MRMeshTopology.h:138
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 MRMeshTopology.h:641
VertId org
vertex at the origin of the edge
Definition MRMeshTopology.h:565
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 MRMeshTopology.h:271
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:313
std::size_t size() const
Definition MRVector.h:55
std::size_t capacity() const
Definition MRVector.h:63
size_t vertSize() const
returns the number of vertex records including invalid ones
Definition MRMeshTopology.h:208
MRMESH_API void pack(FaceMap *outFmap=nullptr, VertMap *outVmap=nullptr, WholeEdgeMap *outEmap=nullptr, bool rearrangeTriangles=false)
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:87
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 MRMeshTopology.h:125
EdgeId bdEdgeWithOrigin(VertId v, const FaceBitSet *region=nullptr) const
Definition MRMeshTopology.h:337
bool hasVert(VertId a) const
returns true if given vertex is present in the mesh
Definition MRMeshTopology.h:187
FaceId left(EdgeId he) const
returns left face of half-edge
Definition MRMeshTopology.h:99
const Vector< EdgeId, VertId > & edgePerVertex() const
for all valid vertices this vector contains an edge with the origin there
Definition MRMeshTopology.h:181
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 MRMeshTopology.h:303
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 MeshEdgePoint onEdge(const MeshTopology &topology) const
MRMESH_API void flipEdge(EdgeId e)
auto size() const
Definition MRBuffer.h:70
MRMESH_API int findNumHoles(EdgeBitSet *holeRepresentativeEdges=nullptr) const
VertId dest(EdgeId he) const
returns destination vertex of half-edge
Definition MRMeshTopology.h:96
MRMESH_API bool isLeftQuad(EdgeId a) const
This one is not in the bindings because of the reference-to-array parameter.
bool updatingValids() const
returns whether the methods validVerts(), validFaces(), numValidVerts(), numValidFaces() can be calle...
Definition MRMeshTopology.h:527
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 MRMeshTopology.h:174
bool operator==(const HalfEdgeRecord &b) const
Definition MRMeshTopology.h:568
MRMESH_API size_t heapBytes() const
returns the amount of memory this object occupies on heap
HalfEdgeRecord() noexcept=default
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 MRMeshTopology.h:235
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 MRMeshTopology.h:40
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 MRMeshTopology.h:299
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:352
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 MRMeshTopology.h:131
tl::expected< T, E > Expected
Definition MRExpected.h:31
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:306
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:349
int numValidVerts() const
returns the number of valid vertices
Definition MRMeshTopology.h:190
EdgeId prev
next clock wise half-edge in the origin ring
Definition MRMeshTopology.h:564
VertId org(EdgeId he) const
returns origin vertex of half-edge
Definition MRMeshTopology.h:93
MRMESH_API std::vector< EdgeLoop > getLeftRings(const std::vector< EdgeId > &es) const
void reserve(size_t capacity)
Definition MRVector.h:65
EdgeId edgeWithLeft(FaceId a) const
returns valid edge if given vertex is present in the mesh
Definition MRMeshTopology.h:232
auto data() MR_LIFETIMEBOUND
Definition MRBuffer.h:101
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 MRMeshTopology.h:416
EdgeId prev(EdgeId he) const
previous (clock wise) half-edge in the origin ring
Definition MRMeshTopology.h:90
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
size_t tsize
target size, all values inside b must be less than this value
Definition MRBuffer.h:149
ThreeVertIds getTriVerts(FaceId f) const
Definition MRMeshTopology.h:141
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 MRMeshTopology.h:34
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 ...
I backId() const
returns the identifier of the back() element
Definition MRVector.h:148
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 MRMeshTopology.h:316
size_t edgeCapacity() const
returns the number of allocated edge records
Definition MRMeshTopology.h:43
int numValidFaces() const
returns the number of valid faces
Definition MRMeshTopology.h:250
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 MRMeshTopology.h:184
size_t faceSize() const
returns the number of face records including invalid ones
Definition MRMeshTopology.h:274
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:461
MR_BIND_IGNORE void getTriEdges(FaceId f, EdgeId(&e)[3]) const
Definition MRMeshTopology.h:175
void edgeReserve(size_t newCapacity)
sets the capacity of half-edges vector
Definition MRMeshTopology.h:58
void getLeftTriVerts(EdgeId a, ThreeVertIds &v) const
This one is not in the bindings because of the reference-to-array parameter.
Definition MRMeshTopology.h:157
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
EdgeId next
next counter clock wise half-edge in the origin ring
Definition MRMeshTopology.h:563
MRMESH_API VertId inVertex(const MeshTopology &topology) const
returns valid vertex id if the point is in vertex, otherwise returns invalid id
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 MRMeshTopology.h:602
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:663
MRMESH_API void getLeftTriEdges(EdgeId e0, EdgeId &e1, EdgeId &e2) const
FaceId addFaceId()
creates new face-id not associated with any edge yet
Definition MRMeshTopology.h:256
void flipEdgesOut(VertId v, T &&flipNeeded)
Definition MRMeshTopology.h:426
FaceId left
face at the left of the edge
Definition MRMeshTopology.h:566
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)
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:46
void vertReserve(size_t newCapacity)
sets the capacity of vertices vector
Definition MRMeshTopology.h:205
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:217
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
This one is not in the bindings because of the reference-to-array parameter.
Definition MRMeshTopology.h:140
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 MRMeshTopology.h:102
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 MRMeshTopology.h:156
bool hasEdge(EdgeId e) const
returns true if given edge is within valid range and not-lone
Definition MRMeshTopology.h:61
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:220
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 MRMeshTopology.h:229
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:473
bool isBdVertex(VertId v, const FaceBitSet *region=nullptr) const
returns true if given vertex is on (region) boundary
Definition MRMeshTopology.h:340
bool isBdVertexInOrg(EdgeId e, const FaceBitSet *region=nullptr) const
returns true if edge's origin is on (region) boundary
Definition MRMeshTopology.h:333
const VertBitSet & getValidVerts() const
returns cached set of all valid vertices
Definition MRMeshTopology.h:214
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 MRMeshTopology.h:49
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:283
ThreeVertIds getLeftTriVerts(EdgeId a) const
Definition MRMeshTopology.h:158
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 MRMeshTopology.h:144
MRMESH_API bool buildGridMesh(const GridSettings &settings, ProgressCallback cb={})
constructs triangular grid mesh topology in parallel
const FaceBitSet & getValidFaces() const
returns cached set of all valid faces
Definition MRMeshTopology.h:280
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:286
EdgeId e
Definition MRMeshTriPoint.h:27
size_t vertCapacity() const
returns the number of allocated vert records
Definition MRMeshTopology.h:211
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,...
only for bindings generation
Definition MRCameraOrientationPlugin.h:8
flat map: I -> T
Definition MRBuffer.h:147
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 MRBuffer.h:155
mapping among elements of source mesh, from which a part is taken, and target mesh
Definition MRPartMapping.h:13