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
« prev ^ index » next coverage.py v7.14.1, created at 2026-06-24 04:40 +0000
1"""
2objects.py
3--------------
5Deal with objects which hold visual properties, like
6ColorVisuals and TextureVisuals.
7"""
9import numpy as np
11from .color import ColorVisuals, color_to_uv
12from .material import pack
13from .texture import TextureVisuals
16def create_visual(**kwargs):
17 """
18 Create Visuals object from keyword arguments.
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
29 Returns
30 ----------
31 visuals : ColorVisuals
32 Visual object created from arguments
33 """
34 return ColorVisuals(**kwargs)
37def concatenate(visuals, *args):
38 """
39 Concatenate multiple visual objects.
41 Parameters
42 ----------
43 visuals : ColorVisuals or list
44 Visuals to concatenate
45 *args : ColorVisuals or list
46 More visuals to concatenate
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)
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)
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)
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)
92 return ColorVisuals()