Skip to content

Commit 7b56224

Browse files
committed
made attach_meshes better
1 parent 0c9c9c1 commit 7b56224

File tree

5 files changed

+62
-17
lines changed

5 files changed

+62
-17
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414
* Added `compas.data.is_sequence_of_uint`.
1515
* Added general plotter for geometry objects and data structures based on the artist registration mechanism.
1616
* Added support for multimesh files to OBJ reader/writer.
17+
* Added support for attaching and detaching meshes in `compas.robots.RobotModelArtist` and drawing them.
1718

1819
### Changed
1920

src/compas/robots/base_artist/_artist.py

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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

src/compas/robots/model/joint.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,9 @@ class Joint(Data):
460460
SUPPORTED_TYPES = ('revolute', 'continuous', 'prismatic', 'fixed',
461461
'floating', 'planar')
462462

463-
def __init__(self, name, type, parent, child, origin=None, axis=None, calibration=None, dynamics=None, limit=None, safety_controller=None, mimic=None, **kwargs):
463+
def __init__(self, name, type, parent, child, origin=None, axis=None,
464+
calibration=None, dynamics=None, limit=None,
465+
safety_controller=None, mimic=None, **kwargs):
464466
type_idx = Joint.SUPPORTED_TYPES.index(type) if isinstance(type, str) else type
465467

466468
if type_idx not in range(len(Joint.SUPPORTED_TYPES)):

src/compas_blender/artists/robotmodelartist.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,8 @@ def draw_collision(self):
5757
collisions = super(RobotModelArtist, self).draw_collision()
5858
for collision in collisions:
5959
collision.hide_set(False)
60+
61+
def draw_attached_meshes(self):
62+
meshes = super(RobotModelArtist, self).draw_attached_meshes()
63+
for mesh in meshes:
64+
mesh.hide_set(False)

src/compas_rhino/artists/robotmodelartist.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,27 @@ def draw_visual(self):
150150
self._exit_layer()
151151
return new_guids
152152

153+
def draw_attached_meshes(self):
154+
"""Draw all the geometries attached to the robot model.
155+
156+
Returns
157+
-------
158+
list
159+
The GUIDs of the created Rhino objects.
160+
"""
161+
acms = super(RobotModelArtist, self).draw_attached_meshes()
162+
acms = list(acms)
163+
164+
self._enter_layer()
165+
166+
new_guids = []
167+
for mesh in acms:
168+
guids = self._add_mesh_to_doc(mesh)
169+
new_guids.extend(guids)
170+
171+
self._exit_layer()
172+
return new_guids
173+
153174
def draw(self):
154175
"""Same as draw_visual."""
155176
return self.draw_visual()

0 commit comments

Comments
 (0)