@@ -1008,48 +1008,47 @@ def _check_link_name(self, name):
10081008 # Methods for accessing the visual and collision geometry
10091009 # --------------------------------------------------------------------------
10101010
1011- def _extract_link_meshes (self , link_elements , meshes_at_link_origin = True ):
1012- # type: (List[Visual] | List[Collision], Optional[bool] ) -> List[Mesh]
1011+ def _extract_link_meshes (self , link_elements ):
1012+ # type: (List[Visual] | List[Collision]) -> List[Mesh]
10131013 """Extracts the list of compas meshes from a link's Visual or Collision elements.
10141014
1015+ Note that each link may have multiple visual or collision nodes, each can have
1016+ a different origin frame. Therefore, the returned meshes are transformed
1017+ according to the ``.origin`` frame of each visual or collision element.
1018+
1019+ This transformation is time consuming for large meshes and should be done only once.
1020+ This transformation is automatically skipped if the origin is None or the identity frame.
1021+
10151022 Parameters
10161023 ----------
10171024 link_elements : list of :class:`~compas_robots.model.Visual` or :class:`~compas_robots.model.Collision`
10181025 The list of Visual or Collision elements of a link.
1019- meshes_at_link_origin : bool, optional
1020- Defaults to True, which means that the meshes will be transformed according to
1021- `element.origin`, such that the mesh origin matches with the link's origin frame.
1022- If False, the meshes will be extracted as it is loaded from the
1023- robot model package. Note that the `.origin` for each element is not necessarily
1024- the same.
10251026
10261027 Returns
10271028 -------
10281029 list of :class:`~compas.datastructures.Mesh`
10291030 A list of meshes belonging to the link elements.
10301031 If there are no meshes, an empty list is returned.
10311032
1032- Notes
1033- -----
1034- Only MeshDescriptor in `element.geometry.shape` is supported. Other shapes are ignored.
1035-
10361033 """
10371034 meshes = []
10381035 # Note: Each Link can have multiple visual nodes
10391036 for element in link_elements :
10401037 # Some elements may have a non-identity origin frame
1041- t_origin = Transformation .from_frame (element .origin or Frame .worldXY ())
1042- # If `meshes_at_link_origin` is False, we use an identity transformation
1043- t_origin = t_origin if meshes_at_link_origin else Transformation ()
1038+ t_origin = None
1039+ if element .origin :
1040+ origin = element .origin if isinstance (element .origin , Frame ) else element .origin ._proxied_object
1041+ if Frame .worldXY () != origin :
1042+ t_origin = Transformation .from_frame (element .origin )
10441043
1045- shape = element .geometry .shape
10461044 # Note: the MeshDescriptor.meshes object supports a list of compas meshes.
1047- if isinstance ( shape , MeshDescriptor ):
1048- # There can be multiple mesh in a single MeshDescriptor
1049- for mesh in shape . meshes :
1050- # Transform the mesh (even if t_origin is identity) so we always get a new mesh object
1045+ # There can be multiple mesh in a single MeshDescriptor
1046+ for mesh in LinkGeometry . _get_item_meshes ( element ):
1047+ # Transform the mesh
1048+ if t_origin :
10511049 meshes .append (mesh .transformed (t_origin ))
1052- # Add support for other shapes here if needed, e.g. Box, Cylinder, Sphere, Capsule etc.
1050+ else :
1051+ meshes .append (mesh )
10531052
10541053 return meshes
10551054
0 commit comments