20 template<
typename T,
typename F1,
typename F2>
21 void buildFromContours(
const std::vector<std::vector<T>> & contours, F1 && reservePoints, F2 && addPoint );
28 template<
typename T,
typename F>
29 [[nodiscard]] std::vector<std::vector<T>> convertToContours( F&& getPoint, std::vector<std::vector<VertId>>* vertMap =
nullptr )
const;
49 [[nodiscard]]
MRMESH_API bool isLoneEdge( EdgeId a )
const;
52 [[nodiscard]]
MRMESH_API UndirectedEdgeId lastNotLoneUndirectedEdge()
const;
55 [[nodiscard]] EdgeId lastNotLoneEdge()
const {
auto ue = lastNotLoneUndirectedEdge();
return ue ? EdgeId( ue ) + 1 : EdgeId(); }
58 [[nodiscard]]
size_t edgeSize()
const {
return edges_.size(); }
61 [[nodiscard]]
size_t edgeCapacity()
const {
return edges_.capacity(); }
64 [[nodiscard]]
size_t undirectedEdgeSize()
const {
return edges_.size() >> 1; }
67 [[nodiscard]]
size_t undirectedEdgeCapacity()
const {
return edges_.capacity() >> 1; }
70 [[nodiscard]]
MRMESH_API size_t computeNotLoneUndirectedEdges()
const;
73 void edgeReserve(
size_t newCapacity ) { edges_.reserve( newCapacity ); }
76 [[nodiscard]]
bool hasEdge( EdgeId e )
const { assert( e.valid() );
return e < (int)edgeSize() && !isLoneEdge( e ); }
85 [[nodiscard]]
MRMESH_API size_t heapBytes()
const;
94 [[nodiscard]] EdgeId next( EdgeId he )
const { assert(he.valid());
return edges_[he].next; }
97 [[nodiscard]] VertId org( EdgeId he )
const { assert(he.valid());
return edges_[he].org; }
100 [[nodiscard]] VertId dest( EdgeId he )
const { assert(he.valid());
return edges_[he.sym()].org; }
107 [[nodiscard]]
const Vector<EdgeId, VertId> & edgePerVertex()
const {
return edgePerVertex_; }
110 [[nodiscard]]
MRMESH_API Vector<VertId, EdgeId> getOrgs()
const;
113 [[nodiscard]] EdgeId edgeWithOrg( VertId a )
const { assert( a.valid() );
return a < int(edgePerVertex_.size()) && edgePerVertex_[a].valid() ? edgePerVertex_[a] : EdgeId(); }
116 [[nodiscard]]
bool hasVert( VertId a )
const {
return validVerts_.test( a ); }
119 [[nodiscard]]
MRMESH_API int getVertDegree( VertId a )
const;
122 [[nodiscard]]
int numValidVerts()
const {
return numValidVerts_; }
125 [[nodiscard]]
MRMESH_API VertId lastValidVert()
const;
128 [[nodiscard]] VertId
addVertId() { edgePerVertex_.push_back( {} ); validVerts_.push_back(
false );
return VertId( (
int)edgePerVertex_.size() - 1 ); }
137 void vertReserve(
size_t newCapacity ) { edgePerVertex_.reserve( newCapacity ); validVerts_.
reserve( newCapacity ); }
140 [[nodiscard]]
size_t vertSize()
const {
return edgePerVertex_.size(); }
143 [[nodiscard]]
size_t vertCapacity()
const {
return edgePerVertex_.capacity(); }
146 [[nodiscard]]
const VertBitSet & getValidVerts()
const {
return validVerts_; }
149 [[nodiscard]]
const VertBitSet & getVertIds(
const VertBitSet * region )
const {
return region ? *region : validVerts_; }
152 [[nodiscard]]
MRMESH_API EdgeId findEdge( VertId o, VertId d )
const;
155 [[nodiscard]]
MRMESH_API VertBitSet getPathVertices(
const EdgePath & path )
const;
171 VertMap * outVmap =
nullptr, WholeEdgeMap * outEmap =
nullptr );
175 VertMap* outVmap =
nullptr, EdgeMap* outEmap =
nullptr );
179 MRMESH_API void pack( VertMap * outVmap =
nullptr, WholeEdgeMap * outEmap =
nullptr );
182 MRMESH_API void write( std::ostream & s )
const;
188 [[nodiscard]]
bool operator ==(
const PolylineTopology & b )
const {
return edges_ == b.edges_; }
189 [[nodiscard]]
bool operator !=(
const PolylineTopology & b )
const {
return edges_ != b.edges_; }
192 [[nodiscard]]
MRMESH_API bool isConsistentlyOriented()
const;
204 [[nodiscard]]
MRMESH_API bool isClosed()
const;
208 void setOrg_( EdgeId a, VertId v );
211 struct HalfEdgeRecord
216 bool operator ==(
const HalfEdgeRecord& b )
const
218 return next == b.next && org == b.org;
220 HalfEdgeRecord() noexcept = default;
221 explicit HalfEdgeRecord( NoInit ) noexcept : next( noInit ), org( noInit ) {}
225 Vector<HalfEdgeRecord, EdgeId> edges_;
228 Vector<EdgeId, VertId> edgePerVertex_;
229 VertBitSet validVerts_;
230 int numValidVerts_ = 0;
233template<
typename T,
typename F1,
typename F2>
234void PolylineTopology::buildFromContours(
const std::vector<std::vector<T>> & contours, F1 && reservePoints, F2 && addPoint )
238 std::vector<bool> closed;
239 closed.reserve( contours.size() );
241 for (
const auto& c : contours )
243 const auto csize = c.size();
246 closed.push_back( c.front() == c.back() );
250 closed.push_back(
false );
259 reservePoints(
size - numClosed );
262 for (
int i = 0; i < contours.size(); ++i )
264 const auto& c = contours[i];
268 const auto v0 = addPoint( c[0] );
271 for (
int j = 1; j + 1 < c.size(); ++j )
275 const auto vj = addPoint( c[j] );
285 const auto vx = addPoint( c.back() );
289 assert( isConsistentlyOriented() );
290 assert( edgePerVertex_.size() ==
size - numClosed );
293template<
typename T,
typename F>
294std::vector<std::vector<T>> PolylineTopology::convertToContours( F&& getPoint, std::vector<std::vector<VertId>>* vertMap )
const
296 std::vector<std::vector<T>> res;
298 UndirectedEdgeBitSet linesUsed;
299 linesUsed.autoResizeSet( UndirectedEdgeId{ undirectedEdgeSize() } );
301 for ( EdgeId e0 : linesUsed )
303 if ( isLoneEdge( e0 ) )
307 while ( curLine != next( curLine ) )
309 curLine = next( curLine ).
sym();
314 linesUsed.set( curLine.undirected(),
false );
318 std::vector<VertId> map;
319 auto orgV = org( e );
320 cont.push_back( getPoint( orgV ) );
322 map.push_back( orgV );
326 cont.push_back( getPoint( org( e ) ) );
328 if ( !linesUsed.test_set( e.undirected(),
false ) )
331 res.push_back( std::move( cont ) );
333 vertMap->push_back( std::move( map ) );
342 PolylineTopology & topology;
347 EdgeId
start( VertId v )
349 assert( !e0_ && !eLast_ );
350 e0_ = eLast_ = topology.makeEdge();
351 topology.setOrg( e0_, v );
359 const auto ej = topology.makeEdge();
360 topology.splice( ej, eLast_.
sym() );
361 topology.setOrg( ej, v );
367 assert( e0_ && eLast_ );
368 topology.splice( e0_, eLast_.
sym() );
375 topology.setOrg( eLast_.
sym(), v );
#define MRMESH_API
Definition MRMeshFwd.h:80
Edges
Definition MRObjectMeshHolder.h:16
unsafe PolylineMaker(MR.Const_PolylineMaker _other)
unsafe MR.EdgeId start(MR.VertId v)
unsafe void finishOpen(MR.VertId v)
unsafe MR.EdgeId proceed(MR.VertId v)
unsafe void pack(MR.VertMap? outVmap=null, MR.WholeEdgeMap? outEmap=null)
unsafe MR.EdgeId splitEdge(MR.EdgeId e)
unsafe void vertReserve(ulong newCapacity)
unsafe int makeEdges(MR.Const_Edges edges)
unsafe void setOrg(MR.EdgeId a, MR.VertId v)
unsafe bool read(MR.Std.Istream s)
unsafe void vertResizeWithReserve(ulong newSize)
unsafe void computeValidsFromEdges()
unsafe void buildOpenLines(MR.Std.Const_Vector_MRVertId comp2firstVert)
unsafe PolylineTopology()
unsafe MR.EdgeId makePolyline(MR.VertId? vs, ulong num)
unsafe void deleteEdge(MR.UndirectedEdgeId ue)
unsafe MR.VertId addVertId()
unsafe void addPart(MR.Const_PolylineTopology from, MR.VertMap? outVmap=null, MR.WholeEdgeMap? outEmap=null)
unsafe void vertResize(ulong newSize)
unsafe void splice(MR.EdgeId a, MR.EdgeId b)
unsafe void deleteEdges(MR.Const_UndirectedEdgeBitSet es)
unsafe void edgeReserve(ulong newCapacity)
unsafe MR.EdgeId makeEdge()
unsafe void addPartByMask(MR.Const_PolylineTopology from, MR.Const_UndirectedEdgeBitSet mask, MR.VertMap? outVmap=null, MR.EdgeMap? outEmap=null)
unsafe void reserve(ulong numBits)
Definition MRCameraOrientationPlugin.h:8
ImVec2 size(const ViewportRectangle &rect)
Definition MRViewport.h:29
readonly unsafe MR.EdgeId sym()