|
1 | 1 | from typing import List, Tuple
|
| 2 | +import numpy as np |
2 | 3 | from pyrep.backend import sim
|
3 | 4 | from pyrep.objects.object import Object, object_type_to_class
|
4 | 5 | from pyrep.const import ObjectType, PrimitiveShape, TextureMappingMode
|
5 | 6 | from pyrep.textures.texture import Texture
|
6 | 7 | import os
|
| 8 | +import collections |
| 9 | + |
| 10 | + |
| 11 | +SShapeVizInfo = collections.namedtuple( |
| 12 | + 'SShapeVizInfo', |
| 13 | + [ |
| 14 | + 'vertices', |
| 15 | + 'indices', |
| 16 | + 'normals', |
| 17 | + 'shading_angle', |
| 18 | + 'colors', |
| 19 | + 'texture', |
| 20 | + 'texture_id', |
| 21 | + 'texture_coords', |
| 22 | + 'texture_apply_mode', |
| 23 | + 'texture_options', |
| 24 | + ], |
| 25 | +) |
7 | 26 |
|
8 | 27 |
|
9 | 28 | class Shape(Object):
|
@@ -357,5 +376,83 @@ def ungroup(self) -> List['Shape']:
|
357 | 376 | handles = sim.simUngroupShape(self.get_handle())
|
358 | 377 | return [Shape(handle) for handle in handles]
|
359 | 378 |
|
| 379 | + def apply_texture(self, texture_coords: np.ndarray, texture: np.ndarray, |
| 380 | + interpolate: bool = True, decal_mode: bool = False, |
| 381 | + is_rgba: bool = False, fliph: bool = False, |
| 382 | + flipv: bool = False) -> None: |
| 383 | + """Apply texture to the shape. |
| 384 | +
|
| 385 | + :param texture_coords: A list of (u, v) values that indicate the |
| 386 | + vertex position on the shape. For each of the shape's triangle, |
| 387 | + there should be exactly 3 UV texture coordinate pairs |
| 388 | + :param texture: The RGB or RGBA texture. |
| 389 | + :param interpolate: A flag to interpolate adjacent texture pixels. |
| 390 | + :param decal_mode: Texture is applied as a decal (its appearance |
| 391 | + won't be influenced by light conditions). |
| 392 | + :param is_rgba: A flag to use RGBA texture. |
| 393 | + :param fliph: A flag to flip texture horizontally. |
| 394 | + :param flipv: A flag to flip texture vertically. Note that CoppeliaSim |
| 395 | + texture coordinates are flipped vertically compared with Pillow |
| 396 | + and OpenCV and this flag must be true in general. |
| 397 | + """ |
| 398 | + texture_coords = np.asarray(texture_coords) |
| 399 | + if not isinstance(texture, np.ndarray): |
| 400 | + raise TypeError('texture must be np.ndarray type') |
| 401 | + height, width = texture.shape[:2] |
| 402 | + |
| 403 | + options = 0 |
| 404 | + if not interpolate: |
| 405 | + options |= 1 |
| 406 | + if decal_mode: |
| 407 | + options |= 2 |
| 408 | + if is_rgba: |
| 409 | + options |= 16 |
| 410 | + if fliph: |
| 411 | + options |= 32 |
| 412 | + if flipv: |
| 413 | + options |= 64 |
| 414 | + |
| 415 | + sim.simApplyTexture( |
| 416 | + self._handle, |
| 417 | + textureCoordinates=texture_coords.flatten().tolist(), |
| 418 | + textCoordSize=texture_coords.size, |
| 419 | + texture=texture.flatten().tolist(), |
| 420 | + textureResolution=(width, height), |
| 421 | + options=options, |
| 422 | + ) |
| 423 | + |
| 424 | + def get_shape_viz(self, index): |
| 425 | + """Retrieves a shape's visual information. |
| 426 | +
|
| 427 | + :param index: 0-based index of the shape element to retrieve |
| 428 | + (compound shapes contain more than one shape element) |
| 429 | +
|
| 430 | + :return: SShapeVizInfo. |
| 431 | + """ |
| 432 | + info = sim.simGetShapeViz(shapeHandle=self._handle, index=index) |
| 433 | + |
| 434 | + vertices = np.array(info.vertices, dtype=float).reshape(-1, 3) |
| 435 | + indices = np.array(info.indices, dtype=float).reshape(-1, 3) |
| 436 | + normals = np.array(info.normals, dtype=float).reshape(-1, 3) |
| 437 | + colors = np.array(info.colors, dtype=float) |
| 438 | + texture = np.array(info.texture, dtype=np.uint8).reshape( |
| 439 | + info.textureRes[1], info.textureRes[0], 4) |
| 440 | + textureCoords = np.array(info.textureCoords, dtype=float).reshape( |
| 441 | + -1, 2) |
| 442 | + |
| 443 | + res = SShapeVizInfo( |
| 444 | + vertices=vertices, |
| 445 | + indices=indices, |
| 446 | + normals=normals, |
| 447 | + shading_angle=info.shadingAngle, |
| 448 | + colors=colors, |
| 449 | + texture=texture, |
| 450 | + texture_id=info.textureId, |
| 451 | + texture_coords=textureCoords, |
| 452 | + texture_apply_mode=info.textureApplyMode, |
| 453 | + texture_options=info.textureOptions, |
| 454 | + ) |
| 455 | + return res |
| 456 | + |
360 | 457 |
|
361 | 458 | object_type_to_class[ObjectType.SHAPE] = Shape
|
0 commit comments