Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NF: Sphere, Geometry & Material #946

Merged
merged 5 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions fury/actor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import numpy as np
import fury.primitive as fp
from fury.material import _create_mesh_material
from fury.geometry import buffer_to_geometry, create_mesh


def sphere(
centers,
colors,
*,
radii=1.0,
phi=16,
theta=16,
opacity=None,
material='phong',
enable_picking=True
):
"""
Visualize one or many spheres with different colors and radii.

Parameters
----------
centers : ndarray, shape (N, 3)
Spheres positions.
colors : ndarray, shape (N, 3) or (N, 4) or tuple (3,) or tuple (4,)
RGB or RGBA (for opacity) R, G, B, and A should be in the range [0, 1].
radii : float or ndarray, shape (N,)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

, optional to add

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you just missed this one

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you update this?

Sphere radius. Can be a single value for all spheres or an array of
radii for each sphere.
phi : int, optional
The number of segments in the longitude direction. Default is 16.
skoudoro marked this conversation as resolved.
Show resolved Hide resolved
theta : int, optional
The number of segments in the latitude direction. Default is 16.
skoudoro marked this conversation as resolved.
Show resolved Hide resolved
opacity : float, optional
Takes values from 0 (fully transparent) to 1 (opaque). Default is None
skoudoro marked this conversation as resolved.
Show resolved Hide resolved
(fully opaque).
material : str, optional
The material type for the spheres. Options are 'phong' (default)
skoudoro marked this conversation as resolved.
Show resolved Hide resolved
and 'basic'.
enable_picking : bool, optional
Whether the spheres should be pickable in a 3D scene. Defaults to True.
skoudoro marked this conversation as resolved.
Show resolved Hide resolved

Returns
-------
mesh_actor : Actor
A mesh actor containing the generated spheres, with the specified
material and properties.

Examples
--------
>>> from fury import window, actor
>>> scene = window.Scene()
>>> centers = np.random.rand(5, 3)
>>> colors = np.random.rand(5, 3)
>>> sphere_actor = actor.sphere(centers, colors, radii=0.5)
>>> scene.add(sphere_actor)
>>> # window.show(scene)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this example does not work. Can you update it ? ( window.show does not exist, missing numpy import)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm on it @skoudoro

"""

scales = radii
directions = (1, 0, 0)

vertices, faces = fp.prim_sphere(phi=phi, theta=theta)

res = fp.repeat_primitive(
vertices,
faces,
directions=directions,
centers=centers,
colors=colors,
scales=scales,
)
big_vertices, big_faces, big_colors, _ = res

prim_count = len(centers)

big_colors = big_colors / 255.
skoudoro marked this conversation as resolved.
Show resolved Hide resolved

if isinstance(opacity, (int, float)):
if big_colors.shape[1] == 3:
big_colors = np.hstack(
(big_colors, np.full(
(big_colors.shape[0], 1), opacity)))
else:
big_colors[:, 3] *= opacity

geo = buffer_to_geometry(
indices=big_faces.astype('int32'),
positions=big_vertices.astype('float32'),
texcoords=big_vertices.astype('float32'),
colors=big_colors.astype('float32'),
)

mat = _create_mesh_material(
material=material,
enable_picking=enable_picking)
obj = create_mesh(geometry=geo, material=mat)
obj.local.position = centers[0]
obj.prim_count = prim_count
return obj
33 changes: 33 additions & 0 deletions fury/geometry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from pygfx import Geometry, Mesh


def buffer_to_geometry(positions, **kwargs):
"""
Convert a buffer to a geometry object.

Parameters
----------
positions : array_like
The positions buffer.
kwargs : dict
A dict of attributes to define on the geometry object. Keys can be
"colors", "normals", "texcoords",
"indices", ...
skoudoro marked this conversation as resolved.
Show resolved Hide resolved
"""
geo = Geometry(positions=positions, **kwargs)
return geo


def create_mesh(geometry, material):
"""
Create a mesh object.

Parameters
----------
geometry : Geometry
The geometry object.
material : Material
The material object.
skoudoro marked this conversation as resolved.
Show resolved Hide resolved
"""
mesh = Mesh(geometry=geometry, material=material)
return mesh
43 changes: 43 additions & 0 deletions fury/material.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import pygfx as gfx


def _create_mesh_material(

skoudoro marked this conversation as resolved.
Show resolved Hide resolved
material='phong',
enable_picking=True,
color=None,
opacity=1.0):
"""
Create a mesh material.

Parameters
----------
material : str
skoudoro marked this conversation as resolved.
Show resolved Hide resolved
The type of material to create. Options are 'phong' (default) and
skoudoro marked this conversation as resolved.
Show resolved Hide resolved
'basic'.
enable_picking : bool
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

, optional to add

Whether the material should be pickable in a scene. Defaults to True.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

default to remove

color : tuple or None
skoudoro marked this conversation as resolved.
Show resolved Hide resolved
The color of the material, represented as an RGBA tuple. If None, the
default color is used. Defaults to None.
skoudoro marked this conversation as resolved.
Show resolved Hide resolved
opacity : float
skoudoro marked this conversation as resolved.
Show resolved Hide resolved
The opacity of the material, from 0 (transparent) to 1 (opaque).
Defaults to 1.0.
skoudoro marked this conversation as resolved.
Show resolved Hide resolved

Returns
-------
gfx.MeshMaterial
A mesh material object of the specified type with the given properties.
"""
if material == 'phong':
return gfx.MeshPhongMaterial(
pick_write=enable_picking,
color_mode='vertex' if color is None else 'auto',
color=color if color is not None else (1, 1, 1, opacity),
)
elif material == 'basic':
return gfx.MeshBasicMaterial(
pick_write=enable_picking,
color_mode='vertex' if color is None else 'auto',
color=color if color is not None else (1, 1, 1, opacity),
)
skoudoro marked this conversation as resolved.
Show resolved Hide resolved
Loading