@@ -117,44 +117,60 @@ def detach_tool_model(self):
117117 """
118118 self .attached_tool_model = None
119119
120- def attach_mesh (self , mesh , link = None ):
120+ def attach_mesh (self , mesh , name , link = None , frame = None ):
121121 """Rigidly attaches a compas mesh to a given link.
122122
123123 Parameters
124124 ----------
125125 mesh : :class:`compas.datastructures.Mesh`
126126 The mesh to attach to the robot model.
127+ name : :obj:`str`
128+ The identifier of the mesh.
127129 link : :class:`compas.robots.Link`
128130 The link within the robot model or tool model to attach the mesh to. Optional.
129131 Defaults to the model's end effector link.
132+ frame : :class:`compas.geometry.Frame`
133+ The frame of the mesh. Defaults to :meth:`compas.geometry.Frame.worldXY`.
130134
131135 Returns
132136 -------
133137 ``None``
134138 """
135139 if not link :
136140 link = self .model .get_end_effector_link ()
141+ transformation = Transformation .from_frame (frame ) if frame else Transformation ()
137142
138- frame = link .parent_joint .origin .copy ()
139- initial_transformation = Transformation .from_frame_to_frame (Frame .worldXY (), frame )
143+ sample_geometry = None
140144
141- sample_geometry = link .collision [0 ] if link .collision else link .visual [0 ] if link .visual else None
142-
143- if hasattr (sample_geometry , 'current_transformation' ):
144- relative_transformation = sample_geometry .current_transformation
145- else :
146- relative_transformation = Transformation ()
145+ while sample_geometry is None :
146+ sample_geometry = link .collision [0 ] if link .collision else link .visual [0 ] if link .visual else None
147+ link = self .model .get_link_by_name (link .parent_joint .parent .link )
147148
148- transformation = relative_transformation .concatenated (initial_transformation )
149149 native_mesh = self .create_geometry (mesh )
150- self .transform (native_mesh , transformation )
150+ init_transformation = transformation * sample_geometry .init_transformation
151+ self .transform (native_mesh , sample_geometry .current_transformation * init_transformation )
151152
152153 item = Item ()
153154 item .native_geometry = [native_mesh ]
154- item .init_transformation = transformation # !!!
155- item .current_transformation = Transformation () # !!!
155+ item .init_transformation = init_transformation
156+ item .current_transformation = sample_geometry .current_transformation
157+
158+ self .attached_items .setdefault (link .name , {})[name ] = item
156159
157- self .attached_items .setdefault (link .name , []).append (item )
160+ def detach_mesh (self , name ):
161+ """Removes attached collision meshes with a given name.
162+
163+ Parameters
164+ ----------
165+ name : :obj:`str`
166+ The identifier of the mesh.
167+
168+ Returns
169+ -------
170+ ``None``
171+ """
172+ for _ , items in self .attached_items :
173+ items .pop (name , None )
158174
159175 def create (self , link = None , context = None ):
160176 """Recursive function that triggers the drawing of the robot model's geometry.
@@ -300,7 +316,7 @@ def _transform_link_geometry(self, link, transformation, collision=True):
300316 # some links have only collision geometry, not visual. These meshes have not been loaded.
301317 if item .native_geometry :
302318 self ._apply_transformation_on_transformed_link (item , transformation )
303- for item in self .attached_items .get (link .name , [] ):
319+ for item in self .attached_items .get (link .name , {}). values ( ):
304320 self ._apply_transformation_on_transformed_link (item , transformation )
305321
306322 def update_tool (self , joint_state = None , visual = True , collision = True , transformation = None ):
@@ -349,7 +365,7 @@ def draw_collision(self):
349365 def draw_attached_meshes (self ):
350366 """Draws all meshes attached to the robot model."""
351367 for items in self .attached_items .values ():
352- for item in items :
368+ for item in items . values () :
353369 for native_mesh in item .native_geometry :
354370 yield native_mesh
355371
0 commit comments