MeshLib C++ Docs
Loading...
Searching...
No Matches
MRObject.h
Go to the documentation of this file.
1#pragma once
2
3#include "MRAffineXf3.h"
4#include "MRBitSet.h"
5#include "MRBox.h"
6#include "MRExpected.h"
8#include "MRSignal.h"
10
11#include <array>
12#include <filesystem>
13#include <future>
14#include <memory>
15#include <set>
16#include <vector>
17
18namespace Json
19{
20class Value;
21}
22
23namespace MR
24{
25
36class ObjectChildrenHolder
37{
38public:
39 ObjectChildrenHolder() = default;
40 ObjectChildrenHolder( const ObjectChildrenHolder & ) noexcept {}
41 ObjectChildrenHolder & operator = ( const ObjectChildrenHolder & ) noexcept { return *this; }
43 MRMESH_API ObjectChildrenHolder & operator = ( ObjectChildrenHolder && ) noexcept;
45
46 // returns this Object as shared_ptr
47 // finds it among its parent's recognized children
48 [[nodiscard]] MRMESH_API std::shared_ptr<Object> getSharedPtr() const;
49
52 [[nodiscard]] MRMESH_API size_t heapBytes() const;
53
54protected:
55 ObjectChildrenHolder * parent_ = nullptr;
56 std::vector< std::shared_ptr< Object > > children_;
57 std::vector< std::weak_ptr< Object > > bastards_;
58};
59
61class MRMESH_CLASS Object : public ObjectChildrenHolder
62{
63public:
64 Object() = default;
65 Object( Object && ) noexcept = default;
66 Object & operator = ( Object && ) noexcept = default;
67 virtual ~Object() = default;
68
69 // return name of subtype for serialization purposes
70 constexpr static const char* StaticTypeName() noexcept { return "Object"; }
71 virtual const char* typeName() const { return StaticTypeName(); }
72
74 constexpr static const char* StaticClassName() noexcept { return "Object"; }
75 virtual std::string className() const { return StaticClassName(); }
76
78 constexpr static const char* StaticClassNameInPlural() noexcept { return "Objects"; }
79 virtual std::string classNameInPlural() const { return StaticClassNameInPlural(); }
80
81 template <typename T>
82 T * asType() { return dynamic_cast<T*>( this ); }
83 template <typename T>
84 const T * asType() const { return dynamic_cast<const T*>( this ); }
85
86 const std::string & name() const { return name_; }
87 virtual void setName( std::string name ) { name_ = std::move( name ); }
88
90 MRMESH_API std::shared_ptr<const Object> find( const std::string_view & name ) const;
91 std::shared_ptr<Object> find( const std::string_view & name ) { return std::const_pointer_cast<Object>( const_cast<const Object*>( this )->find( name ) ); }
92
94 template <typename T>
95 std::shared_ptr<const T> find() const;
96 template <typename T>
97 std::shared_ptr<T> find() { return std::const_pointer_cast<T>( const_cast<const Object*>( this )->find<T>() ); }
98
100 template <typename T>
101 std::shared_ptr<const T> find( const std::string_view & name ) const;
102 template <typename T>
103 std::shared_ptr<T> find( const std::string_view & name ) { return std::const_pointer_cast<T>( const_cast<const Object*>( this )->find<T>( name ) ); }
104
107 const AffineXf3f & xf( ViewportId id = {}, bool * isDef = nullptr ) const { return xf_.get( id, isDef ); }
108 MRMESH_API virtual void setXf( const AffineXf3f& xf, ViewportId id = {} );
110 MRMESH_API virtual void resetXf( ViewportId id = {} );
111
113 const ViewportProperty<AffineXf3f> & xfsForAllViewports() const { return xf_; }
115 virtual void setXfsForAllViewports( ViewportProperty<AffineXf3f> xf ) { xf_ = std::move( xf ); }
116
119 MRMESH_API AffineXf3f worldXf( ViewportId id = {}, bool * isDef = nullptr ) const;
120 MRMESH_API void setWorldXf( const AffineXf3f& xf, ViewportId id = {} );
121
123 MRMESH_API virtual void applyScale( float scaleFactor );
124
126 MRMESH_API ViewportMask globalVisibilityMask() const;
128 bool globalVisibility( ViewportMask viewportMask = ViewportMask::any() ) const { return !( globalVisibilityMask() & viewportMask ).empty(); }
130 MRMESH_API void setGlobalVisibility( bool on, ViewportMask viewportMask = ViewportMask::any() );
131
133 bool isLocked() const { return locked_; }
134 virtual void setLocked( bool on ) { locked_ = on; }
135
138 [[nodiscard]] bool isParentLocked() const { return parentLocked_; }
139 virtual void setParentLocked( bool lock ) { parentLocked_ = lock; }
140
142 const Object * parent() const { return static_cast<const Object *>( parent_ ); }
143 Object * parent() { return static_cast<Object *>( parent_ ); }
144
146 MRMESH_API bool isAncestor( const Object* ancestor ) const;
147
151 [[nodiscard]] MRMESH_API Object* findCommonAncestor( Object& other );
152 [[nodiscard]] const Object* findCommonAncestor( const Object& other ) const
153 {
154 return const_cast<Object &>( *this ).findCommonAncestor( const_cast<Object &>( other ) );
155 }
156
159 MRMESH_API virtual bool detachFromParent();
161 const std::vector<std::shared_ptr<Object>>& children() { return children_; }
162
163 #ifdef __GNUC__
164 #pragma GCC diagnostic push
165 #pragma GCC diagnostic ignored "-Wstrict-aliasing" // Fingers crossed.
166 #endif
167 const std::vector<std::shared_ptr<const Object>>& children() const { return reinterpret_cast<const std::vector< std::shared_ptr< const Object > > &>( children_ ); }
168 #ifdef __GNUC__
169 #pragma GCC diagnostic pop
170 #endif
171
176 MRMESH_API virtual bool addChild( std::shared_ptr<Object> child, bool recognizedChild = true );
180 MRMESH_API virtual bool addChildBefore( std::shared_ptr<Object> newChild, const std::shared_ptr<Object> & existingChild );
182 bool removeChild( const std::shared_ptr<Object>& child ) { return removeChild( child.get() ); }
183 MRMESH_API virtual bool removeChild( Object* child );
185 MRMESH_API virtual void removeAllChildren();
187 MRMESH_API void sortChildren();
188
190 MRMESH_API virtual bool select( bool on );
191 virtual bool isSelected() const { return selected_; }
192
195 MRMESH_API virtual void setAncillary( bool ancillary );
196 bool isAncillary() const { return ancillary_; }
198 MRMESH_API bool isGlobalAncillary() const;
199
201 MRMESH_API void setVisible( bool on, ViewportMask viewportMask = ViewportMask::all() );
203 bool isVisible( ViewportMask viewportMask = ViewportMask::any() ) const { return !( visibilityMask() & viewportMask ).empty(); }
205 MRMESH_API virtual void setVisibilityMask( ViewportMask viewportMask );
207 virtual ViewportMask visibilityMask() const { return visibilityMask_; }
208
210 virtual bool getRedrawFlag( ViewportMask ) const { return needRedraw_; }
211 void resetRedrawFlag() const { needRedraw_ = false; }
212
214 MRMESH_API std::shared_ptr<Object> cloneTree() const;
216 MRMESH_API virtual std::shared_ptr<Object> clone() const;
219 MRMESH_API std::shared_ptr<Object> shallowCloneTree() const;
222 MRMESH_API virtual std::shared_ptr<Object> shallowClone() const;
223
225 MRMESH_API virtual std::vector<std::string> getInfoLines() const;
226
231 // This would be automatically skipped in the bindings anyway because of the `Json::Value` parameter.
232 // But skipping it here prevents the vector-of-futures type from being registered, which is helpful.
233 // TODO: figure out how to automate this (add a flag to the parser to outright reject functions based on their parameter and return types).
234 MRMESH_API MR_BIND_IGNORE Expected<std::vector<std::future<Expected<void>>>> serializeRecursive( const std::filesystem::path& path, Json::Value& root, int childId ) const;
235
239 MRMESH_API Expected<void> deserializeRecursive( const std::filesystem::path& path, const Json::Value& root,
240 ProgressCallback progressCb = {}, int* objCounter = nullptr );
241
245 MRMESH_API void swap( Object& other );
246
248 virtual Box3f getWorldBox( ViewportId = {} ) const { return {}; }
250 MRMESH_API Box3f getWorldTreeBox( ViewportId = {} ) const;
251
253 [[nodiscard]] virtual bool hasVisualRepresentation() const { return false; }
254
257 [[nodiscard]] virtual bool hasModel() const { return false; }
258
261 const std::set<std::string>& tags() const { return tags_; }
265 MRMESH_API bool addTag( std::string tag );
268 MRMESH_API bool removeTag( const std::string& tag );
269
271 [[nodiscard]] MRMESH_API virtual size_t heapBytes() const;
272
273 // return true if model of current object equals to model (the same) of other
274 MRMESH_API virtual bool sameModels( const Object& other ) const;
275 // return hash of model (or hash object pointer if object has no model)
276 MRMESH_API virtual size_t getModelHash() const;
277
281 using XfChangedSignal = Signal<void()>;
282 XfChangedSignal worldXfChangedSignal;
283protected:
284 struct ProtectedStruct{ explicit ProtectedStruct() = default; };
285public:
287 Object( ProtectedStruct, const Object& obj ) : Object( obj ) {}
288
289protected:
291 Object( const Object& obj ) = default;
292
294 MRMESH_API virtual void swapBase_( Object& other );
297 MRMESH_API virtual void swapSignals_( Object& other );
298
301 MRMESH_API virtual Expected<std::future<Expected<void>>> serializeModel_( const std::filesystem::path& path ) const;
302
305 MRMESH_API virtual void serializeFields_( Json::Value& root ) const;
306
308 MRMESH_API virtual Expected<void> deserializeModel_( const std::filesystem::path& path, ProgressCallback progressCb = {} );
310 MRMESH_API virtual Expected<void> setSharedModel_( const Object& other );
311
314 MRMESH_API virtual void deserializeFields_( const Json::Value& root );
315
316 std::string name_;
317 ViewportProperty<AffineXf3f> xf_;
318 ViewportMask visibilityMask_ = ViewportMask::all(); // Prefer to not read directly. Use the getter, as it can be overridden.
319 bool locked_ = false;
320 bool parentLocked_ = false;
321 bool selected_{ false };
322 bool ancillary_{ false };
323 mutable bool needRedraw_{false};
324 std::set<std::string> tags_;
325
326 // This calls `onWorldXfChanged_()` for all children recursively, which in turn emits `worldXfChangedSignal`.
327 // This isn't virtual because it wouldn't be very useful, because it doesn't call itself on the children
328 // (it doesn't use a true recursion, instead imitating one, presumably to save stack space, though this is unlikely to be an issue).
329 MRMESH_API void sendWorldXfChangedSignal_();
330
331 // Emits `worldXfChangedSignal`, but derived classes can add additional behavior to it.
332 MRMESH_API virtual void onWorldXfChanged_();
333
334private:
335 struct MapSharedObjects;
336 Expected<std::vector<std::future<Expected<void>>>> serializeRecursive_( const std::filesystem::path& path, Json::Value& root,
337 int childId, MapSharedObjects* mapSharedObjects ) const;
338
340 struct MapLinkToSharedObjectModel;
341 Expected<void> deserializeRecursive_( const std::filesystem::path& path, const Json::Value& root,
342 int* objCounter, MapLinkToSharedObjectModel& mapLinkToSharedObjectModel, const ProgressCallback& progressCb );
343};
344
345template <typename T>
346std::shared_ptr<const T> Object::find() const
347{
348 for ( const auto & child : children_ )
349 if ( auto res = std::dynamic_pointer_cast<T>( child ) )
350 return res;
351 return {}; // not found
352}
353
354template <typename T>
355std::shared_ptr<const T> Object::find( const std::string_view & name ) const
356{
357 for ( const auto & child : children_ )
358 if ( child->name() == name )
359 if ( auto res = std::dynamic_pointer_cast<T>( child ) )
360 return res;
361 return {}; // not found
362}
363
365
366}
#define MRMESH_API
Definition MRMeshFwd.h:80
#define MRMESH_CLASS
Definition MRMeshFwd.h:87
Definition MRObject.h:62
std::shared_ptr< const T > find() const
finds a direct child by type
Definition MRObject.h:346
std::string name(const T &primitive)
Definition MRFeatures.h:309
MRVOXELS_API double find(const Mesh &mesh, const FindParams &params, FaceBitSet &outUndercuts, const UndercutMetric &metric={})
Definition MRCameraOrientationPlugin.h:8
Definition MRObject.h:284