Coverage for trimesh/visual/objects.py: 97%

32 statements  

« prev     ^ index     » next       coverage.py v7.14.1, created at 2026-06-24 04:40 +0000

1""" 

2objects.py 

3-------------- 

4 

5Deal with objects which hold visual properties, like 

6ColorVisuals and TextureVisuals. 

7""" 

8 

9import numpy as np 

10 

11from .color import ColorVisuals, color_to_uv 

12from .material import pack 

13from .texture import TextureVisuals 

14 

15 

16def create_visual(**kwargs): 

17 """ 

18 Create Visuals object from keyword arguments. 

19 

20 Parameters 

21 ----------- 

22 face_colors : (n, 3|4) uint8 

23 Face colors 

24 vertex_colors : (n, 3|4) uint8 

25 Vertex colors 

26 mesh : trimesh.Trimesh 

27 Mesh object 

28 

29 Returns 

30 ---------- 

31 visuals : ColorVisuals 

32 Visual object created from arguments 

33 """ 

34 return ColorVisuals(**kwargs) 

35 

36 

37def concatenate(visuals, *args): 

38 """ 

39 Concatenate multiple visual objects. 

40 

41 Parameters 

42 ---------- 

43 visuals : ColorVisuals or list 

44 Visuals to concatenate 

45 *args : ColorVisuals or list 

46 More visuals to concatenate 

47 

48 Returns 

49 ---------- 

50 concat : Visuals 

51 If all are color 

52 """ 

53 # get a flat list of Visuals objects 

54 if len(args) > 0: 

55 visuals = np.append(visuals, args) 

56 else: 

57 visuals = np.array(visuals) 

58 

59 # if there are any texture visuals convert all to texture 

60 if any(v.kind == "texture" for v in visuals): 

61 # first collect materials and UV coordinates 

62 mats = [] 

63 uvs = [] 

64 for v in visuals: 

65 if v.kind == "texture": 

66 mats.append(v.material) 

67 if v.uv is None: 

68 # otherwise use zeros 

69 uvs.append(np.zeros((len(v.mesh.vertices), 2)) + 0.5) 

70 else: 

71 # if uvs are of correct shape use them 

72 uvs.append(v.uv) 

73 

74 else: 

75 # create a material and UV coordinates from vertex colors 

76 color_mat, color_uv = color_to_uv(vertex_colors=v.vertex_colors) 

77 mats.append(color_mat) 

78 uvs.append(color_uv) 

79 # pack the materials and UV coordinates into one 

80 new_mat, new_uv = pack(materials=mats, uvs=uvs) 

81 return TextureVisuals(material=new_mat, uv=new_uv) 

82 

83 # convert all visuals to the first valid kind 

84 kind = next((v.kind for v in visuals if v.kind is not None), None) 

85 if kind == "face": 

86 colors = np.vstack([v.face_colors for v in visuals]) 

87 return ColorVisuals(face_colors=colors) 

88 elif kind == "vertex": 

89 colors = np.vstack([v.vertex_colors for v in visuals]) 

90 return ColorVisuals(vertex_colors=colors) 

91 

92 return ColorVisuals()