MeshLib
 
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
68
69
71 [[nodiscard]] EdgeId next( EdgeId he ) const { assert(he.valid()); return edges_[he].next; }
72
74 [[nodiscard]] EdgeId prev( EdgeId he ) const { assert(he.valid()); return edges_[he].prev; }
75
77 [[nodiscard]] VertId org( EdgeId he ) const { assert(he.valid()); return edges_[he].org; }
78
80 [[nodiscard]] VertId dest( EdgeId he ) const { assert(he.valid()); return edges_[he.sym()].org; }
81
83 [[nodiscard]] FaceId left( EdgeId he ) const { assert(he.valid()); return edges_[he].left; }
84
86 [[nodiscard]] FaceId right( EdgeId he ) const { assert(he.valid()); return edges_[he.sym()].left; }
87
88
92
96
97
99 [[nodiscard]] MRMESH_API bool fromSameOriginRing( EdgeId a, EdgeId b ) const;
100
102 [[nodiscard]] MRMESH_API bool fromSameLeftRing( EdgeId a, EdgeId b ) const;
103
104
106 [[nodiscard]] MRMESH_API int getOrgDegree( EdgeId a ) const;
107
109 [[nodiscard]] int getVertDegree( VertId v ) const { return getOrgDegree( edgeWithOrg( v ) ); }
110
112 [[nodiscard]] MRMESH_API int getLeftDegree( EdgeId a ) const;
113
115 [[nodiscard]] int getFaceDegree( FaceId f ) const { return getLeftDegree( edgeWithLeft( f ) ); }
116
118 [[nodiscard]] MRMESH_API bool isLeftTri( EdgeId a ) const;
119
122 void getTriVerts( FaceId f, VertId & v0, VertId & v1, VertId & v2 ) const { getLeftTriVerts( edgeWithLeft( f ), v0, v1, v2 ); }
123 void getTriVerts( FaceId f, VertId (&v)[3] ) const { getLeftTriVerts( edgeWithLeft( f ), v ); }
124 void getTriVerts( FaceId f, ThreeVertIds & v ) const { getLeftTriVerts( edgeWithLeft( f ), v ); }
125 [[nodiscard]] ThreeVertIds getTriVerts( FaceId f ) const { return getLeftTriVerts( edgeWithLeft( f ) ); }
126
128 [[nodiscard]] MRMESH_API std::vector<ThreeVertIds> getAllTriVerts() const;
129
133
136 MRMESH_API void getLeftTriVerts( EdgeId a, VertId & v0, VertId & v1, VertId & v2 ) const;
137 void getLeftTriVerts( EdgeId a, VertId (&v)[3] ) const { getLeftTriVerts( a, v[0], v[1], v[2] ); }
138 void getLeftTriVerts( EdgeId a, ThreeVertIds & v ) const { getLeftTriVerts( a, v[0], v[1], v[2] ); }
139 [[nodiscard]] ThreeVertIds getLeftTriVerts( EdgeId a ) const { ThreeVertIds v; getLeftTriVerts( a, v[0], v[1], v[2] ); return v; }
140
145 template <typename T>
146 void forEachVertex( const MeshTriPoint & p, T && callback ) const;
147
150 MRMESH_API void getTriEdges( FaceId f, EdgeId & e0, EdgeId & e1, EdgeId & e2 ) const;
151 void getTriEdges( FaceId f, EdgeId (&e)[3] ) const { getTriEdges( f, e[0], e[1], e[2] ); }
152
154 [[nodiscard]] MRMESH_API bool isLeftQuad( EdgeId a ) const;
155
157 [[nodiscard]] const Vector<EdgeId, VertId> & edgePerVertex() const { return edgePerVertex_; }
158
160 [[nodiscard]] EdgeId edgeWithOrg( VertId a ) const { assert( a.valid() ); return a < int(edgePerVertex_.size()) ? edgePerVertex_[a] : EdgeId(); }
161
163 [[nodiscard]] bool hasVert( VertId a ) const { assert( updateValids_ ); return validVerts_.test( a ); }
164
166 [[nodiscard]] int numValidVerts() const { assert( updateValids_ ); return numValidVerts_; }
167
169 [[nodiscard]] MRMESH_API VertId lastValidVert() const;
170
172 [[nodiscard]] VertId addVertId() { edgePerVertex_.emplace_back(); if ( updateValids_ ) { validVerts_.push_back( false ); } return edgePerVertex_.backId(); }
173
175 MRMESH_API void vertResize( size_t newSize );
176
178 MRMESH_API void vertResizeWithReserve( size_t newSize );
179
181 void vertReserve( size_t newCapacity ) { edgePerVertex_.reserve( newCapacity ); if ( updateValids_ ) { validVerts_.reserve( newCapacity ); } }
182
184 [[nodiscard]] size_t vertSize() const { return edgePerVertex_.size(); }
185
187 [[nodiscard]] size_t vertCapacity() const { return edgePerVertex_.capacity(); }
188
190 [[nodiscard]] const VertBitSet & getValidVerts() const { assert( updateValids_ ); return validVerts_; }
191
193 void flip( VertBitSet & vs ) const { vs = getValidVerts() - vs; }
194
196 [[nodiscard]] const VertBitSet & getVertIds( const VertBitSet * region ) const
197 {
198 assert( region || updateValids_ ); // region shall be either given on input or maintained in validVerts_
199 assert( !updateValids_ || !region || ( *region - validVerts_ ).none() ); // if region is given and all valid vertices are known, then region must be a subset of them
200 return region ? *region : validVerts_;
201 }
202
203
205 [[nodiscard]] const Vector<EdgeId, FaceId> & edgePerFace() const { return edgePerFace_; }
206
208 [[nodiscard]] EdgeId edgeWithLeft( FaceId a ) const { assert( a.valid() ); return a < int(edgePerFace_.size()) ? edgePerFace_[a] : EdgeId(); }
209
211 [[nodiscard]] bool hasFace( FaceId a ) const { assert( updateValids_ ); return validFaces_.test( a ); }
212
214 [[nodiscard]] MRMESH_API EdgeId sharedEdge( FaceId l, FaceId r ) const;
215
217 [[nodiscard]] MRMESH_API EdgeId sharedVertInOrg( EdgeId a, EdgeId b ) const;
218
220 [[nodiscard]] MRMESH_API EdgeId sharedVertInOrg( FaceId l, FaceId r ) const;
221
223 [[nodiscard]] MRMESH_API FaceId sharedFace( EdgeId a, EdgeId b ) const;
224
226 [[nodiscard]] int numValidFaces() const { assert( updateValids_ ); return numValidFaces_; }
227
229 [[nodiscard]] MRMESH_API FaceId lastValidFace() const;
230
232 [[nodiscard]] FaceId addFaceId() { edgePerFace_.emplace_back(); if ( updateValids_ ) { validFaces_.push_back( false ); } return edgePerFace_.backId(); }
233
235 MRMESH_API void deleteFace( FaceId f, const UndirectedEdgeBitSet * keepEdges = nullptr );
236
238 MRMESH_API void deleteFaces( const FaceBitSet & fs, const UndirectedEdgeBitSet * keepEdges = nullptr );
239
241 MRMESH_API void faceResize( size_t newSize );
242
244 MRMESH_API void faceResizeWithReserve( size_t newSize );
245
247 void faceReserve( size_t newCapacity ) { edgePerFace_.reserve( newCapacity ); if ( updateValids_ ) { validFaces_.reserve( newCapacity ); } }
248
250 [[nodiscard]] size_t faceSize() const { return edgePerFace_.size(); }
251
253 [[nodiscard]] size_t faceCapacity() const { return edgePerFace_.capacity(); }
254
256 [[nodiscard]] const FaceBitSet & getValidFaces() const { assert( updateValids_ ); return validFaces_; }
257
259 void flip( FaceBitSet & fs ) const { fs = getValidFaces() - fs; }
260
262 [[nodiscard]] const FaceBitSet & getFaceIds( const FaceBitSet * region ) const
263 {
264 assert( region || updateValids_ ); // region shall be either given on input or maintained in validFaces_
265 assert( !updateValids_ || !region || ( *region - validFaces_ ).none() ); // if region is given and all valid faces are known, then region must be a subset of them
266 return region ? *region : validFaces_;
267 }
268
271 [[nodiscard]] MRMESH_API EdgeId bdEdgeSameLeft( EdgeId e, const FaceBitSet * region = nullptr ) const;
272
274 [[nodiscard]] bool isBdVertexInLeft( EdgeId e, const FaceBitSet * region = nullptr ) const { return bdEdgeSameLeft( e, region ).valid(); }
275
278 [[nodiscard]] EdgeId bdEdgeWithLeft( FaceId f, const FaceBitSet * region = nullptr ) const { return bdEdgeSameLeft( edgeWithLeft( f ), region ); }
279
281 [[nodiscard]] bool isBdFace( FaceId f, const FaceBitSet * region = nullptr ) const { return isBdVertexInLeft( edgeWithLeft( f ), region ); }
282
283
285 [[nodiscard]] bool isLeftInRegion( EdgeId e, const FaceBitSet * region = nullptr ) const { return contains( region, left( e ) ); }
286
288 [[nodiscard]] bool isInnerEdge( EdgeId e, const FaceBitSet * region = nullptr ) const { return isLeftInRegion( e, region ) && isLeftInRegion( e.sym(), region ); }
289
291 [[nodiscard]] bool isBdEdge( EdgeId e, const FaceBitSet * region = nullptr ) const { return isLeftInRegion( e, region ) != isLeftInRegion( e.sym(), region ); }
292
295 [[nodiscard]] MRMESH_API EdgeId bdEdgeSameOrigin( EdgeId e, const FaceBitSet * region = nullptr ) const;
296
298 [[nodiscard]] bool isBdVertexInOrg( EdgeId e, const FaceBitSet * region = nullptr ) const { return bdEdgeSameOrigin( e, region ).valid(); }
299
302 [[nodiscard]] EdgeId bdEdgeWithOrigin( VertId v, const FaceBitSet * region = nullptr ) const { return bdEdgeSameOrigin( edgeWithOrg( v ), region ); }
303
305 [[nodiscard]] bool isBdVertex( VertId v, const FaceBitSet * region = nullptr ) const { return isBdVertexInOrg( edgeWithOrg( v ), region ); }
306
308 [[nodiscard]] MRMESH_API bool isInnerOrBdVertex( VertId v, const FaceBitSet * region = nullptr ) const;
309
311 [[nodiscard]] bool isLeftBdEdge( EdgeId e, const FaceBitSet * region = nullptr ) const { return region ? ( isLeftInRegion( e, region ) && !isLeftInRegion( e.sym(), region ) ) : !right( e ); }
312
314 [[nodiscard]] bool isInnerOrBdEdge( EdgeId e, const FaceBitSet * region = nullptr ) const { return isLeftInRegion( e, region ) || isLeftInRegion( e.sym(), region ); }
315
317 [[nodiscard]] MRMESH_API EdgeId nextLeftBd( EdgeId e, const FaceBitSet * region = nullptr ) const;
318
320 [[nodiscard]] MRMESH_API EdgeId prevLeftBd( EdgeId e, const FaceBitSet * region = nullptr ) const;
321
322
324 [[nodiscard]] MRMESH_API EdgeId findEdge( VertId o, VertId d ) const;
325
327 [[nodiscard]] MRMESH_API bool isClosed( const FaceBitSet * region = nullptr ) const;
328
330 [[nodiscard]] MRMESH_API std::vector<EdgeId> findHoleRepresentiveEdges() const;
331
334 [[nodiscard]] MRMESH_API int findNumHoles( EdgeBitSet * holeRepresentativeEdges = nullptr ) const;
335
337 [[nodiscard]] MRMESH_API EdgeLoop getLeftRing( EdgeId e ) const;
338
341 [[nodiscard]] MRMESH_API std::vector<EdgeLoop> getLeftRings( const std::vector<EdgeId> & es ) const;
342
344 [[nodiscard]] MRMESH_API EdgeBitSet findBoundaryEdges() const;
345
348
351
352
354 [[nodiscard]] MRMESH_API VertBitSet getPathVertices( const EdgePath & path ) const;
355
357 [[nodiscard]] MRMESH_API FaceBitSet getPathLeftFaces( const EdgePath & path ) const;
358
360 [[nodiscard]] MRMESH_API FaceBitSet getPathRightFaces( const EdgePath & path ) const;
361
362
366
369 template<typename T>
370 void flipEdgesIn( EdgeId e0, T && flipNeeded );
371
374 template<typename T>
375 void flipEdgesIn( VertId v, T && flipNeeded ) { flipEdgesIn( edgeWithOrg( v ), std::forward<T>( flipNeeded ) ); }
376
379 template<typename T>
380 void flipEdgesOut( EdgeId e0, T && flipNeeded );
381
384 template<typename T>
385 void flipEdgesOut( VertId v, T && flipNeeded ) { flipEdgesOut( edgeWithOrg( v ), std::forward<T>( flipNeeded ) ); }
386
395 MRMESH_API EdgeId splitEdge( EdgeId e, FaceBitSet * region = nullptr, FaceHashMap * new2Old = nullptr );
396
400 MRMESH_API VertId splitFace( FaceId f, FaceBitSet * region = nullptr, FaceHashMap * new2Old = nullptr );
401
406 MRMESH_API void flipOrientation( const UndirectedEdgeBitSet * fullComponents = nullptr );
407
408
413 MRMESH_API void addPart( const MeshTopology & from,
414 FaceMap * outFmap = nullptr, VertMap * outVmap = nullptr, WholeEdgeMap * outEmap = nullptr, bool rearrangeTriangles = false );
415
417 MRMESH_API void addPartByMask( const MeshTopology & from, const FaceBitSet & fromFaces, const PartMapping & map );
418
423 MRMESH_API void addPartByMask( const MeshTopology & from, const FaceBitSet & fromFaces, bool flipOrientation = false,
424 const std::vector<EdgePath> & thisContours = {}, const std::vector<EdgePath> & fromContours = {},
425 const PartMapping & map = {} );
426
428 MRMESH_API void addPartByFaceMap( const MeshTopology & from, const FaceMap & fromFaces, bool flipOrientation = false,
429 const std::vector<EdgePath> & thisContours = {}, const std::vector<EdgePath> & fromContours = {},
430 const PartMapping & map = {} );
431
433 template<typename I>
434 MRMESH_API void addPartBy( const MeshTopology & from, I fbegin, I fend, size_t fcount, bool flipOrientation = false,
435 const std::vector<EdgePath> & thisContours = {},
436 const std::vector<EdgePath> & fromContours = {},
437 const PartMapping & map = {} );
438
439
442
447 MRMESH_API void pack( FaceMap * outFmap = nullptr, VertMap * outVmap = nullptr, WholeEdgeMap * outEmap = nullptr, bool rearrangeTriangles = false );
448
451 MRMESH_API void pack( const PackMapping & map );
452
456 MRMESH_API void packMinMem( const PackMapping & map );
457
458
460 MRMESH_API void write( std::ostream & s ) const;
461
464 MRMESH_API VoidOrErrStr read( std::istream& s, ProgressCallback callback = {} );
465
467 [[nodiscard]] MRMESH_API bool operator ==( const MeshTopology & b ) const;
468
473
477 MRMESH_API void addPackedPart( const MeshTopology & from, EdgeId toEdgeId,
478 const FaceMap & fmap, const VertMap & vmap );
479
485
488
490 [[nodiscard]] bool updatingValids() const { return updateValids_; }
491
494 MRMESH_API void preferEdges( const UndirectedEdgeBitSet & stableEdges );
495
496 // constructs triangular grid mesh topology in parallel
497 MRMESH_API bool buildGridMesh( const GridSettings& settings, ProgressCallback cb = {} );
498
501 MRMESH_API bool checkValidity( ProgressCallback cb = {}, bool allVerts = true ) const;
502
503private:
504 friend class MeshDiff;
508 MRMESH_API void computeAllFromEdges_();
509
510private:
512 void setOrg_( EdgeId a, VertId v );
513
515 void setLeft_( EdgeId a, FaceId f );
516
518 struct HalfEdgeRecord
519 {
520 EdgeId next;
521 EdgeId prev;
522 VertId org;
523 FaceId left;
524
525 bool operator ==( const HalfEdgeRecord& b ) const
526 {
527 return next == b.next && prev == b.prev && org == b.org && left == b.left;
528 }
529 HalfEdgeRecord() noexcept = default;
530 explicit HalfEdgeRecord( NoInit ) noexcept : next( noInit ), prev( noInit ), org( noInit ), left( noInit ) {}
531 };
533 void translateNoFlip_( HalfEdgeRecord & r,
534 const FaceMap & fmap, const VertMap & vmap, const WholeEdgeMap & emap ) const;
535 void translate_( HalfEdgeRecord & r, HalfEdgeRecord & rsym,
536 const FaceMap & fmap, const VertMap & vmap, const WholeEdgeMap & emap, bool flipOrientation ) const;
537 void translateNoFlip_( HalfEdgeRecord & r,
538 const FaceHashMap & fmap, const VertHashMap & vmap, const WholeEdgeHashMap & emap ) const;
539 void translate_( HalfEdgeRecord & r, HalfEdgeRecord & rsym,
540 const FaceHashMap & fmap, const VertHashMap & vmap, const WholeEdgeHashMap & emap, bool flipOrientation ) const;
541
543 Vector<HalfEdgeRecord, EdgeId> edges_;
544
546 Vector<EdgeId, VertId> edgePerVertex_;
547 VertBitSet validVerts_;
548
550 Vector<EdgeId, FaceId> edgePerFace_;
551 FaceBitSet validFaces_;
552
553 int numValidVerts_ = 0;
554 int numValidFaces_ = 0;
555
556 bool updateValids_ = true;
557};
558
559template <typename T>
560void MeshTopology::forEachVertex( const MeshTriPoint & p, T && callback ) const
561{
562 if ( auto v = p.inVertex( *this ) )
563 {
564 callback( v );
565 return;
566 }
567 if ( auto e = p.onEdge( *this ) )
568 {
569 callback( org( e.e ) );
570 callback( dest( e.e ) );
571 return;
572 }
573
574 VertId v[3];
575 getLeftTriVerts( p.e, v );
576 for ( int i = 0; i < 3; ++i )
577 callback( v[i] );
578}
579
580template<typename T>
581void MeshTopology::flipEdgesIn( const EdgeId e0, T && flipNeeded )
582{
583 EdgeId e = e0;
584 for (;;)
585 {
586 auto testEdge = prev( e.sym() );
587 if ( left( testEdge ) && right( testEdge ) && flipNeeded( testEdge ) )
588 flipEdge( testEdge );
589 else
590 {
591 e = next( e );
592 if ( e == e0 )
593 break; // full ring has been inspected
594 }
595 }
596}
597
598template<typename T>
599void MeshTopology::flipEdgesOut( EdgeId e0, T && flipNeeded )
600{
601 EdgeId e = e0;
602 for (;;)
603 {
604 if ( left( e ) && right( e ) && flipNeeded( e ) )
605 {
606 e0 = next( e );
607 flipEdge( e );
608 e = e0;
609 }
610 else
611 {
612 e = next( e );
613 if ( e == e0 )
614 break; // full ring has been inspected
615 }
616 }
617}
618
619// rearrange vector values by map (old.id -> new.id)
620template<typename T, typename I>
621[[nodiscard]] Vector<T, I> rearrangeVectorByMap( const Vector<T, I>& oldVector, const BMap<I, I>& map )
622{
623 Vector<T, I> newVector;
624 newVector.resize( map.tsize );
625
626 const auto& mData = map.b.data();
627 const auto sz = std::min( oldVector.size(), map.b.size() );
628 for ( I i = I(0); i < sz; ++i)
629 {
630 I newV = mData[i];
631 if ( newV.valid() )
632 newVector[newV] = oldVector[i];
633 }
634 return newVector;
635}
636
638
639} // namespace MR
int VertId
Definition MRDotNet/MRMeshFwd.h:51
List< VertId > VertMap
Definition MRDotNet/MRMeshFwd.h:84
int FaceId
Definition MRDotNet/MRMeshFwd.h:53
int EdgeId
Definition MRDotNet/MRMeshFwd.h:52
List< FaceId > FaceMap
Definition MRDotNet/MRMeshFwd.h:87
#define MRMESH_API
Definition MRMesh/MRMeshFwd.h:46
Definition MRDotNet/MRBitSet.h:39
auto size() const
Definition MRBuffer.h:66
auto data()
Definition MRBuffer.h:97
Definition MRMeshDiff.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:581
size_t faceCapacity() const
returns the number of allocated face records
Definition MRMesh/MRMeshTopology.h:253
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:172
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:122
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 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:137
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:599
void faceReserve(size_t newCapacity)
sets the capacity of faces vector
Definition MRMesh/MRMeshTopology.h:247
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:285
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:184
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:71
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:109
EdgeId bdEdgeWithOrigin(VertId v, const FaceBitSet *region=nullptr) const
Definition MRMesh/MRMeshTopology.h:302
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:291
bool hasVert(VertId a) const
returns true if given vertex is present in the mesh
Definition MRMesh/MRMeshTopology.h:163
FaceId left(EdgeId he) const
returns left face of half-edge
Definition MRMesh/MRMeshTopology.h:83
const Vector< EdgeId, VertId > & edgePerVertex() const
for all valid vertices this vector contains an edge with the origin there
Definition MRMesh/MRMeshTopology.h:157
MRMESH_API void setLeft(EdgeId a, FaceId f)
MRMESH_API void getTriEdges(FaceId f, EdgeId &e0, EdgeId &e1, EdgeId &e2) 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:278
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:80
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:490
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:274
MRMESH_API void preferEdges(const UndirectedEdgeBitSet &stableEdges)
MRMESH_API void stopUpdatingValids()
stops updating validVerts(), validFaces(), numValidVerts(), numValidFaces() for parallel processing o...
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:211
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
MRMESH_API FaceBitSet findBoundaryFaces() const
returns all boundary faces, having at least one boundary edge
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:314
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:115
bool isBdFace(FaceId f, const FaceBitSet *region=nullptr) const
returns true if given face is on (region) boundary
Definition MRMesh/MRMeshTopology.h:281
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:311
int numValidVerts() const
returns the number of valid vertices
Definition MRMesh/MRMeshTopology.h:166
VertId org(EdgeId he) const
returns origin vertex of half-edge
Definition MRMesh/MRMeshTopology.h:77
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:208
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:375
EdgeId prev(EdgeId he) const
previous (clock wise) half-edge in the origin ring
Definition MRMesh/MRMeshTopology.h:74
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:151
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:125
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:288
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:226
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 VoidOrErrStr read(std::istream &s, ProgressCallback callback={})
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:160
size_t faceSize() const
returns the number of face records including invalid ones
Definition MRMesh/MRMeshTopology.h:250
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:138
MRMESH_API VertBitSet findBoundaryVerts() const
returns all boundary vertices, incident to at least one boundary edge
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 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:560
FaceId addFaceId()
creates new face-id not associated with any edge yet
Definition MRMesh/MRMeshTopology.h:232
void flipEdgesOut(VertId v, T &&flipNeeded)
Definition MRMesh/MRMeshTopology.h:385
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)
MRMESH_API std::vector< EdgeId > findHoleRepresentiveEdges() const
returns one edge with no valid left face for every boundary in the mesh
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:181
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:193
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:124
FaceId right(EdgeId he) const
returns right face of half-edge
Definition MRMesh/MRMeshTopology.h:86
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:196
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:205
bool isBdVertex(VertId v, const FaceBitSet *region=nullptr) const
returns true if given vertex is on (region) boundary
Definition MRMesh/MRMeshTopology.h:305
bool isBdVertexInOrg(EdgeId e, const FaceBitSet *region=nullptr) const
returns true if edge's origin is on (region) boundary
Definition MRMesh/MRMeshTopology.h:298
const VertBitSet & getValidVerts() const
returns cached set of all valid vertices
Definition MRMesh/MRMeshTopology.h:190
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:259
ThreeVertIds getLeftTriVerts(EdgeId a) const
Definition MRMesh/MRMeshTopology.h:139
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:256
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:262
void getTriVerts(FaceId f, VertId(&v)[3]) const
Definition MRMesh/MRMeshTopology.h:123
size_t vertCapacity() const
returns the number of allocated vert records
Definition MRMesh/MRMeshTopology.h:187
std::vector<T>-like container that requires specific indexing type,
Definition MRMesh/MRVector.h:19
std::size_t size() const
Definition MRMesh/MRVector.h:40
std::size_t capacity() const
Definition MRMesh/MRVector.h:57
void resize(size_t newSize) MR_REQUIRES_IF_SUPPORTED(std
Definition MRMesh/MRVector.h:42
void reserve(size_t capacity)
Definition MRMesh/MRVector.h:58
I backId() const
returns the identifier of the back() element
Definition MRMesh/MRVector.h:123
T & emplace_back(Args &&... args)
Definition MRMesh/MRVector.h:114
bool contains(const TaggedBitSet< T > *bitset, Id< T > id)
Definition MRMesh/MRBitSet.h:203
std::function< bool(float)> ProgressCallback
Definition MRMesh/MRMeshFwd.h:589
Definition MRCameraOrientationPlugin.h:7
std::vector< EdgeId > EdgeLoop
Definition MRMesh/MRMeshFwd.h:99
struct MRMESH_CLASS PartMapping
Definition MRMesh/MRMeshFwd.h:473
HashMap< VertId, VertId > VertHashMap
Definition MRMesh/MRMeshFwd.h:455
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:459
HashMap< FaceId, FaceId > FaceHashMap
Definition MRMesh/MRMeshFwd.h:454
std::vector< EdgeId > EdgePath
Definition MRMesh/MRMeshFwd.h:98
constexpr NoInit noInit
Definition MRMesh/MRMeshFwd.h:57
I
Definition MRMesh/MRMeshFwd.h:88
Vector< T, I > rearrangeVectorByMap(const Vector< T, I > &oldVector, const BMap< I, I > &map)
Definition MRMesh/MRMeshTopology.h:621
Expected< void > VoidOrErrStr
return type for a void function that can produce an error string
Definition MRExpected.h:60
Definition Triangulation.dox.py:1
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:56
Definition MRBuffer.h:151
Definition MRPartMapping.h:10
Definition MRDotNet/MRMeshFwd.h:56