@@ -190,3 +190,107 @@ def box(
190190 obj .prim_count = prim_count
191191
192192 return obj
193+
194+
195+ def cylinder (
196+ centers ,
197+ colors ,
198+ * ,
199+ height = 1 ,
200+ sectors = 36 ,
201+ radii = 0.5 ,
202+ scales = (1 , 1 , 1 ),
203+ directions = (0 , 1 , 0 ),
204+ capped = True ,
205+ opacity = None ,
206+ material = "phong" ,
207+ enable_picking = True ,
208+ ):
209+ """Visualize one or many cylinders with different features.
210+
211+ Parameters
212+ ----------
213+ centers : ndarray, shape (N, 3)
214+ Box positions.
215+ colors : ndarray (N,3) or (N, 4) or tuple (3,) or tuple (4,), optional
216+ RGB or RGBA (for opacity) R, G, B and A should be at the range [0, 1].
217+ height: float, optional
218+ The height of the cylinder. Default is 1.
219+ sectors: int, optional
220+ The number of divisions around the cylinder's circumference (like longitudinal slices).
221+ Higher values produce smoother cylinders. Default is 36.
222+ radii : float or ndarray (N,) or tuple, optional
223+ The radius of the base of the cylinders. A single value applies to all cylinders,
224+ while an array specifies a radius for each cylinder individually. Default is 0.5.
225+ scales : int or ndarray (N, 3) or tuple (3,), optional
226+ Scaling factors for the cylinders in the (x, y, z) dimensions. Default is uniform scaling (1, 1, 1).
227+ directions : ndarray, shape (N, 3), optional
228+ The orientation vector of the box.
229+ capped : bool, optional
230+ Whether to add caps (circular ends) to the cylinders. Default is True.
231+ scales : int or ndarray (N,3) or tuple (3,), optional
232+ The size of the box in each dimension. If a single value is provided,
233+ the same size will be used for all boxes.
234+ opacity : float, optional
235+ Takes values from 0 (fully transparent) to 1 (opaque).
236+ If both `opacity` and RGBA are provided, the final alpha will be:
237+ final_alpha = alpha_in_RGBA * opacity
238+ material : str, optional
239+ The material type for the boxes. Options are 'phong' and 'basic'.
240+ enable_picking : bool, optional
241+ Whether the boxes should be pickable in a 3D scene.
242+
243+ Returns
244+ -------
245+ mesh_actor : Actor
246+ A mesh actor containing the generated boxes, with the specified
247+ material and properties.
248+
249+ Examples
250+ --------
251+ >>> from fury import window, actor
252+ >>> import numpy as np
253+ >>> scene = window.Scene()
254+ >>> centers = np.random.rand(5, 3) * 10
255+ >>> colors = np.random.rand(5, 3)
256+ >>> cylinder_actor = actor.cylinder(centers=centers, colors=colors)
257+ >>> scene.add(cylinder_actor)
258+ >>> show_manager = window.ShowManager(scene=scene, size=(600, 600))
259+ >>> show_manager.start()
260+ """
261+
262+ vertices , faces = fp .prim_cylinder (radius = radii , height = height , sectors = sectors , capped = capped )
263+ res = fp .repeat_primitive (
264+ vertices ,
265+ faces ,
266+ directions = directions ,
267+ centers = centers ,
268+ colors = colors ,
269+ scales = scales ,
270+ )
271+ big_vertices , big_faces , big_colors , _ = res
272+ prim_count = len (centers )
273+ big_colors = big_colors / 255.0
274+
275+ if isinstance (opacity , (int , float )):
276+ if big_colors .shape [1 ] == 3 :
277+ big_colors = np .hstack (
278+ (big_colors , np .full ((big_colors .shape [0 ], 1 ), opacity ))
279+ )
280+ else :
281+ big_colors [:, 3 ] *= opacity
282+
283+
284+ geo = buffer_to_geometry (
285+ indices = big_faces .astype ("int32" ),
286+ positions = big_vertices .astype ("float32" ),
287+ texcoords = big_vertices .astype ("float32" ),
288+ colors = big_colors .astype ("float32" ),
289+ )
290+ mat = _create_mesh_material (material = material , enable_picking = enable_picking )
291+ obj = create_mesh (geometry = geo , material = mat )
292+ obj .local .position = centers [0 ]
293+
294+ obj .prim_count = prim_count
295+
296+ return obj
0 commit comments