2424
2525class SceneObjectFactory :
2626 """Factory class for creating appropriate SceneObject instances based on input item type.
27-
27+
2828 This factory encapsulates the logic for selecting the right SceneObject subclass
2929 for a given data item, making the creation process more explicit and easier to understand.
3030 """
31-
31+
3232 @staticmethod
33- def create (item = None , ** kwargs ):
33+ def create (item = None , scene = None , ** kwargs ):
3434 """Create appropriate SceneObject instance based on item type.
35-
35+
3636 Parameters
3737 ----------
3838 item : :class:`compas.data.Data`
3939 The data item to create a scene object for.
4040 **kwargs : dict
4141 Additional keyword arguments to pass to the SceneObject constructor.
42-
42+
4343 Returns
4444 -------
4545 :class:`compas.scene.SceneObject`
4646 A SceneObject instance of the appropriate subclass for the given item.
47-
47+
4848 Raises
4949 ------
5050 ValueError
@@ -55,13 +55,16 @@ def create(item=None, **kwargs):
5555 if item is None :
5656 raise ValueError ("Cannot create a scene object for None. Please ensure you pass an instance of a supported class." )
5757
58+ if scene is None :
59+ raise ValueError ("Cannot create a scene object without a scene." )
60+
5861 sceneobject_cls = get_sceneobject_cls (item , ** kwargs )
59-
62+
6063 # Create and return an instance of the appropriate scene object class
61- return sceneobject_cls (item = item , ** kwargs )
64+ return sceneobject_cls (item = item , scene = scene , ** kwargs )
6265
6366
64- class SceneObject (TreeNode ):
67+ class SceneObject (Data ):
6568 """Base class for all scene objects.
6669
6770 Parameters
@@ -130,9 +133,9 @@ def __init__(
130133 color = None , # type: compas.colors.Color | None
131134 opacity = 1.0 , # type: float
132135 show = True , # type: bool
133- frame = None , # type: compas.geometry.Frame | None
134136 transformation = None , # type: compas.geometry.Transformation | None
135137 context = None , # type: str | None
138+ scene = None , # type: compas.scene.Scene | None
136139 ** kwargs # type: dict
137140 ): # fmt: skip
138141 # type: (...) -> None
@@ -145,7 +148,8 @@ def __init__(
145148 # because it has no access to the tree and/or the scene before it is added
146149 # which means that adding child objects will be added in context "None"
147150 self .context = context
148- self ._item = item
151+ self ._scene = scene
152+ self ._item = item .guid
149153 self ._guids = []
150154 self ._node = None
151155 self ._transformation = transformation
@@ -158,29 +162,32 @@ def __init__(
158162 def __data__ (self ):
159163 # type: () -> dict
160164 return {
161- "item" : str (self .item .guid ),
162- "settings" : self .settings ,
163- "children" : [child .__data__ for child in self .children ],
165+ "item" : str (self ._item ),
166+ "name" : self .name ,
167+ "color" : self .color ,
168+ "opacity" : self .opacity ,
169+ "show" : self .show ,
170+ "transformation" : self .transformation ,
164171 }
165172
166- @classmethod
167- def __from_data__ (cls , data ):
168- # type: (dict) -> None
169- raise TypeError ("Serialisation outside Scene not allowed." )
170-
171173 def __repr__ (self ):
172174 # type: () -> str
173175 return "<{}: {}>" .format (self .__class__ .__name__ , self .name )
174176
175177 @property
176178 def scene (self ):
177179 # type: () -> compas.scene.Scene | None
178- return self .tree
180+ return self ._scene
179181
180182 @property
181183 def item (self ):
182184 # type: () -> compas.data.Data
183- return self ._item
185+ return self .scene .items [self ._item ]
186+
187+ @property
188+ def node (self ):
189+ # type: () -> compas.datastructures.TreeNode
190+ return self .scene .tree .get_object_node (self .guid )
184191
185192 @property
186193 def guids (self ):
@@ -234,58 +241,6 @@ def contrastcolor(self, color):
234241 # type: (compas.colors.Color) -> None
235242 self ._contrastcolor = Color .coerce (color )
236243
237- @property
238- def settings (self ):
239- # type: () -> dict
240- settings = {
241- "name" : self .name ,
242- "color" : self .color ,
243- "opacity" : self .opacity ,
244- "show" : self .show ,
245- }
246-
247- if self .frame :
248- settings ["frame" ] = self .frame
249- if self .transformation :
250- settings ["transformation" ] = self .transformation
251-
252- return settings
253-
254- def add (self , item , ** kwargs ):
255- # type: (compas.data.Data, dict) -> SceneObject
256- """Add a child item to the scene object.
257-
258- Parameters
259- ----------
260- item : :class:`compas.data.Data`
261- The item to add.
262- **kwargs : dict
263- Additional keyword arguments to create the scene object for the item.
264-
265- Returns
266- -------
267- :class:`compas.scene.SceneObject`
268- The scene object associated with the added item.
269-
270- Raises
271- ------
272- ValueError
273- If the scene object does not have an associated scene node.
274- """
275- if isinstance (item , SceneObject ):
276- sceneobject = item
277- else :
278- if "context" in kwargs :
279- if kwargs ["context" ] != self .context :
280- raise Exception ("Child context should be the same as parent context: {} != {}" .format (kwargs ["context" ], self .context ))
281- del kwargs ["context" ] # otherwist the SceneObject receives "context" twice, which results in an error
282-
283- # Use the factory to create the scene object
284- sceneobject = SceneObjectFactory .create (item = item , context = self .context , ** kwargs )
285-
286- super (SceneObject , self ).add (sceneobject )
287- return sceneobject
288-
289244 def draw (self ):
290245 """The main drawing method."""
291246 raise NotImplementedError
0 commit comments