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
18class MeshTopology
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 = {} );
458 MR_BIND_IGNORE void addPartByMask( const MeshTopology & from, const FaceBitSet & fromFaces, const PartMapping & map = {} )
459 { addPartByMask( from, &fromFaces, map ); }
460
465 MRMESH_API void addPartByMask( const MeshTopology & from, const FaceBitSet * fromFaces, bool flipOrientation = false,
466 const std::vector<EdgePath> & thisContours = {}, const std::vector<EdgePath> & fromContours = {},
467 const PartMapping & map = {} );
468
470 MR_BIND_IGNORE void addPartByMask( const MeshTopology & from, const FaceBitSet & fromFaces, bool flipOrientation = false,
471 const std::vector<EdgePath> & thisContours = {}, const std::vector<EdgePath> & fromContours = {},
472 const PartMapping & map = {} ) { addPartByMask( from, &fromFaces, flipOrientation, thisContours, fromContours, map ); }
473
476
481 MRMESH_API void pack( FaceMap * outFmap = nullptr, VertMap * outVmap = nullptr, WholeEdgeMap * outEmap = nullptr, bool rearrangeTriangles = false );
482
485 MRMESH_API void pack( const PackMapping & map );
486
490 MRMESH_API void packMinMem( const PackMapping & map );
491
492
494 MRMESH_API void write( std::ostream & s ) const;
495
498 MRMESH_API Expected<void> read( std::istream& s, ProgressCallback callback = {} );
499
501 [[nodiscard]] MRMESH_API bool operator ==( const MeshTopology & b ) const;
502
506 MRMESH_API void resizeBeforeParallelAdd( size_t edgeSize, size_t vertSize, size_t faceSize );
507
511 MRMESH_API void addPackedPart( const MeshTopology & from, EdgeId toEdgeId,
512 const FaceMap & fmap, const VertMap & vmap );
513
518 MRMESH_API bool computeValidsFromEdges( ProgressCallback cb = {} );
519
522
524 [[nodiscard]] bool updatingValids() const { return updateValids_; }
525
528 MRMESH_API void preferEdges( const UndirectedEdgeBitSet & stableEdges );
529
530 // constructs triangular grid mesh topology in parallel
531 MRMESH_API bool buildGridMesh( const GridSettings& settings, ProgressCallback cb = {} );
532
535 MRMESH_API bool checkValidity( ProgressCallback cb = {}, bool allVerts = true ) const;
536
537private:
538 friend class MeshTopologyDiff;
542 MRMESH_API void computeAllFromEdges_();
543
544private:
546 void setOrg_( EdgeId a, VertId v );
547
549 void fillOrg_();
550
552 void setLeft_( EdgeId a, FaceId f );
553
555 void fillLeft_();
556
558 struct alignas( 16 ) HalfEdgeRecord
559 {
560 EdgeId next;
561 EdgeId prev;
562 VertId org;
563 FaceId left;
564
565 bool operator ==( const HalfEdgeRecord& b ) const
566 {
567 return next == b.next && prev == b.prev && org == b.org && left == b.left;
568 }
569 HalfEdgeRecord() noexcept = default;
570 explicit HalfEdgeRecord( NoInit ) noexcept : next( noInit ), prev( noInit ), org( noInit ), left( noInit ) {}
571 };
572 static_assert( sizeof( HalfEdgeRecord ) == 16 );
573
575 template<typename FM, typename VM, typename WEM>
576 void translateNoFlip_( HalfEdgeRecord & r, const FM & fmap, const VM & vmap, const WEM & emap ) const;
577 template<typename FM, typename VM, typename WEM>
578 void translate_( HalfEdgeRecord & r, HalfEdgeRecord & rsym,
579 const FM & fmap, const VM & vmap, const WEM & emap, bool flipOrientation ) const;
580
582 Vector<HalfEdgeRecord, EdgeId> edges_;
583
585 Vector<EdgeId, VertId> edgePerVertex_;
586 VertBitSet validVerts_;
587
589 Vector<EdgeId, FaceId> edgePerFace_;
590 FaceBitSet validFaces_;
591
592 int numValidVerts_ = 0;
593 int numValidFaces_ = 0;
594
595 bool updateValids_ = true;
596};
597
598template <typename T>
599void MeshTopology::forEachVertex( const MeshTriPoint & p, T && callback ) const
600{
601 if ( auto v = p.inVertex( *this ) )
602 {
603 callback( v );
604 return;
605 }
606 if ( auto e = p.onEdge( *this ) )
607 {
608 callback( org( e.e ) );
609 callback( dest( e.e ) );
610 return;
611 }
612
613 VertId v[3];
614 getLeftTriVerts( p.e, v );
615 for ( int i = 0; i < 3; ++i )
616 callback( v[i] );
617}
618
619template<typename T>
620void MeshTopology::flipEdgesIn( const EdgeId e0, T && flipNeeded )
621{
622 EdgeId e = e0;
623 for (;;)
624 {
625 auto testEdge = prev( e.sym() );
626 if ( left( testEdge ) && right( testEdge ) && flipNeeded( testEdge ) )
627 flipEdge( testEdge );
628 else
629 {
630 e = next( e );
631 if ( e == e0 )
632 break; // full ring has been inspected
633 }
634 }
635}
636
637template<typename T>
638void MeshTopology::flipEdgesOut( EdgeId e0, T && flipNeeded )
639{
640 EdgeId e = e0;
641 for (;;)
642 {
643 if ( left( e ) && right( e ) && flipNeeded( e ) )
644 {
645 e0 = next( e );
646 flipEdge( e );
647 e = e0;
648 }
649 else
650 {
651 e = next( e );
652 if ( e == e0 )
653 break; // full ring has been inspected
654 }
655 }
656}
657
658// rearrange vector values by map (old.id -> new.id)
659template<typename T, typename I>
660[[nodiscard]] Vector<T, I> rearrangeVectorByMap( const Vector<T, I>& oldVector, const BMap<I, I>& map )
661{
662 Vector<T, I> newVector;
663 newVector.resize( map.tsize );
664
665 const auto& mData = map.b.data();
666 const auto sz = std::min( oldVector.size(), map.b.size() );
667 for ( I i = I(0); i < sz; ++i)
668 {
669 I newV = mData[i];
670 if ( newV.valid() )
671 newVector[newV] = oldVector[i];
672 }
673 return newVector;
674}
675
676} // namespace MR
#define MRMESH_API
Definition MRMeshFwd.h:80
auto size() const
Definition MRBuffer.h:66
auto data()
Definition MRBuffer.h:97
unsafe void reserve(ulong numBits)
unsafe void deleteFace(MR.FaceId f, MR.Const_UndirectedEdgeBitSet? keepEdges=null)
unsafe void splice(MR.EdgeId a, MR.EdgeId b)
unsafe MR.FaceId addFaceId()
unsafe void setLeft(MR.EdgeId a, MR.FaceId f)
unsafe void vertResizeWithReserve(ulong newSize)
unsafe void packMinMem(MR.Const_PackMapping map)
unsafe void flipEdge(MR.EdgeId e)
unsafe MeshTopology()
unsafe void rotateTriangles()
unsafe void vertResize(ulong newSize)
unsafe void resizeBeforeParallelAdd(ulong edgeSize, ulong vertSize, ulong faceSize)
unsafe void faceResizeWithReserve(ulong newSize)
unsafe void edgeReserve(ulong newCapacity)
unsafe bool buildGridMesh(MR.Const_GridSettings settings, MR.Std._ByValue_Function_BoolFuncFromFloat? cb=null)
unsafe MR.EdgeId collapseEdge(MR.EdgeId e, MR.Std.Const_Function_VoidFuncFromMREdgeIdMREdgeId onEdgeDel)
unsafe void addPartByMask(MR.Const_MeshTopology from, MR.Const_FaceBitSet? fromFaces, MR.Const_PartMapping? map=null)
unsafe void shrinkToFit()
unsafe void deleteFaces(MR.Const_FaceBitSet fs, MR.Const_UndirectedEdgeBitSet? keepEdges=null)
unsafe bool computeValidsFromEdges(MR.Std._ByValue_Function_BoolFuncFromFloat? cb=null)
unsafe void flipOrientation(MR.Const_UndirectedEdgeBitSet? fullComponents=null)
unsafe MR.VertId addVertId()
unsafe void preferEdges(MR.Const_UndirectedEdgeBitSet stableEdges)
unsafe void read(MR.Std.Istream s, MR.Std._ByValue_Function_BoolFuncFromFloat? callback=null)
unsafe void vertReserve(ulong newCapacity)
unsafe MR.EdgeId splitEdge(MR.EdgeId e, MR.FaceBitSet? region=null, MR.Phmap.FlatHashMap_MRFaceId_MRFaceId? new2Old=null)
unsafe void faceReserve(ulong newCapacity)
unsafe void addPackedPart(MR.Const_MeshTopology from, MR.EdgeId toEdgeId, MR.Const_FaceMap fmap, MR.Const_VertMap vmap)
unsafe void addPart(MR.Const_MeshTopology from, MR.Const_PartMapping? map=null, bool? rearrangeTriangles=null)
unsafe void stopUpdatingValids()
unsafe void setOrg(MR.EdgeId a, MR.VertId v)
unsafe MR.VertId splitFace(MR.FaceId f, MR.FaceBitSet? region=null, MR.Phmap.FlatHashMap_MRFaceId_MRFaceId? new2Old=null)
unsafe void faceResize(ulong newSize)
unsafe MR.EdgeId makeEdge()
unsafe void pack(MR.FaceMap? outFmap=null, MR.VertMap? outVmap=null, MR.WholeEdgeMap? outEmap=null, bool? rearrangeTriangles=null)
std::vector<T>-like container that requires specific indexing type,
Definition MRVector.h:19
std::size_t size() const
Definition MRVector.h:51
void resize(size_t newSize) MR_REQUIRES_IF_SUPPORTED(sizeof(T)>0 &&std
Definition MRVector.h:53
unsafe void reserve(ulong numBits)
bool contains(const TypedBitSet< I > *bitset, I id)
Definition MRMesh/MRBitSet.h:326
Definition MRCameraOrientationPlugin.h:8
Vector< T, I > rearrangeVectorByMap(const Vector< T, I > &oldVector, const BMap< I, I > &map)
Definition MRMesh/MRMeshTopology.h:660
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
readonly unsafe bool valid()