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

displaying 3D objects #54

Merged
merged 4 commits into from
Aug 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
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
38 changes: 27 additions & 11 deletions bioviz/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from packaging.version import parse as parse_version
import numpy as np
import scipy

try:
import biorbd
except ImportError:
Expand Down Expand Up @@ -279,6 +280,7 @@ def __init__(
show_wrappings=True,
show_analyses_panel=True,
background_color=(0.5, 0.5, 0.5),
force_wireframe=False,
**kwargs,
):
"""
Expand All @@ -305,7 +307,8 @@ def __init__(
markers_color=(0, 0, 1),
markers_size=markers_size,
contacts_size=contacts_size,
segments_center_of_mass_size=segments_center_of_mass_size
segments_center_of_mass_size=segments_center_of_mass_size,
force_wireframe=force_wireframe,
)
self.is_executing = False
self.animation_warning_already_shown = False
Expand Down Expand Up @@ -355,8 +358,11 @@ def __init__(
self.mesh = []
self.meshPointsInMatrix = InterfacesCollections.MeshPointsInMatrix(self.model)
for i, vertices in enumerate(self.meshPointsInMatrix.get_data(Q=self.Q, compute_kin=False)):
triangles = np.array([p.face() for p in self.model.meshFaces()[i]], dtype="int32") \
if len(self.model.meshFaces()[i]) else np.ndarray((0, 3), dtype="int32")
triangles = (
np.array([p.face() for p in self.model.meshFaces()[i]], dtype="int32")
if len(self.model.meshFaces()[i])
else np.ndarray((0, 3), dtype="int32")
)
self.mesh.append(Mesh(vertex=vertices, triangles=triangles.T))
if self.show_muscles:
self.model.updateMuscles(self.Q, True)
Expand Down Expand Up @@ -391,13 +397,20 @@ def __init__(
res = 11 # resolution
x = np.sin(np.linspace(0, np.pi, res)) * wrap_cylinder.radius()
y = np.cos(np.linspace(0, np.pi, res)) * wrap_cylinder.radius()
z = np.ones((res, )) * wrap_cylinder.length()
vertices = np.concatenate([np.array([0, 0, z[0]])[:, np.newaxis], [x, y, z],
np.array([0, 0, -z[0]])[:, np.newaxis], [x, y, -z]], axis=1)
z = np.ones((res,)) * wrap_cylinder.length()
vertices = np.concatenate(
[
np.array([0, 0, z[0]])[:, np.newaxis],
[x, y, z],
np.array([0, 0, -z[0]])[:, np.newaxis],
[x, y, -z],
],
axis=1,
)

tri_0_0 = np.zeros((res-1, 1))
tri_0_0 = np.zeros((res - 1, 1))
tri_1_0 = np.arange(1, res)[:, np.newaxis]
tri_2_0 = np.arange(2, res+1)[:, np.newaxis]
tri_2_0 = np.arange(2, res + 1)[:, np.newaxis]
tri_0 = np.concatenate([tri_0_0, tri_1_0, tri_2_0], axis=1)
tri_1 = tri_0 + res + 1
tri_2 = np.concatenate([tri_1_0, tri_2_0, tri_1_0 + res + 1], axis=1)
Expand Down Expand Up @@ -451,7 +464,7 @@ def reset_q(self):
self.__update_muscle_analyses_graphs(False, False, False, False)

def copy_q_to_clipboard(self):
pandas.DataFrame(self.Q[np.newaxis, :]).to_clipboard(sep=',', index=False, header=False)
pandas.DataFrame(self.Q[np.newaxis, :]).to_clipboard(sep=",", index=False, header=False)

def set_q(self, Q, refresh_window=True):
"""
Expand Down Expand Up @@ -916,7 +929,11 @@ def __set_wrapping_from_q(self):
for i, wraps in enumerate(self.wraps_base):
for j, wrap in enumerate(wraps):
if self.model.muscle(i).pathModifier().object(j).typeOfNode() == biorbd.WRAPPING_HALF_CYLINDER:
rt = biorbd.WrappingHalfCylinder(self.model.muscle(i).pathModifier().object(j)).RT(self.model, self.Q).to_array()
rt = (
biorbd.WrappingHalfCylinder(self.model.muscle(i).pathModifier().object(j))
.RT(self.model, self.Q)
.to_array()
)
self.wraps_current[i][j][0:3, :, 0] = np.dot(rt, wrap[:, :, 0])[0:3, :]
else:
raise NotImplementedError("__set_wrapping_from_q is not ready for these wrapping object")
Expand All @@ -926,4 +943,3 @@ def __set_rt_from_q(self):
for k, rt in enumerate(self.allGlobalJCS.get_data(Q=self.Q, compute_kin=False)):
self.rt[k] = Rototrans(rt)
self.vtk_model.update_rt(self.rt)

2 changes: 1 addition & 1 deletion bioviz/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "2.1.2"
__version__ = "2.1.3"
59 changes: 42 additions & 17 deletions bioviz/biorbd_vtk.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
vtkUnsignedCharArray,
vtkOggTheoraWriter,
vtkWindowToImageFilter,
vtkPolygon,
vtkExtractEdges,
)
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor

Expand Down Expand Up @@ -157,7 +159,9 @@ def __init__(
segments_center_of_mass_color=(0, 0, 0),
segments_center_of_mass_opacity=1.0,
mesh_color=(0, 0, 0),
mesh_opacity=1.0,
patch_color=(0.89, 0.855, 0.788),
mesh_opacity=0.8,
force_wireframe=False,
wrapping_color=(0, 0, 1),
wrapping_opacity=1.0,
muscle_color=(150 / 255, 15 / 255, 15 / 255),
Expand Down Expand Up @@ -225,6 +229,8 @@ def __init__(

self.all_meshes = []
self.mesh_color = mesh_color
self.force_wireframe = force_wireframe
self.patch_color = patch_color
self.mesh_opacity = mesh_opacity
self.mesh_actors = list()

Expand Down Expand Up @@ -681,29 +687,45 @@ def new_mesh_set(self, all_meshes):

points = vtkPoints()
for j in range(mesh.channel.size):
points.InsertNextPoint([0, 0, 0])
# points.InsertNextPoint([0, 0, 0])
points.InsertNextPoint(mesh.data[:3, j, 0].tolist())

# Create an array for each triangle
cell = vtkCellArray()
for j in range(mesh.triangles.shape[1]): # For each triangle
line = vtkPolyLine()
line.GetPointIds().SetNumberOfIds(4)
for k in range(len(mesh.triangles[:, j])): # For each index
line.GetPointIds().SetId(k, mesh.triangles[k, j])
line.GetPointIds().SetId(3, mesh.triangles[0, j]) # Close the triangle
cell.InsertNextCell(line)
poly_line = vtkPolyData()
poly_line.SetPoints(points)
poly_line.SetLines(cell)
draw_patch = not mesh.automatic_triangles and not self.force_wireframe
if draw_patch:
poly_type = vtkPolygon
n_ids = 3
color = self.patch_color
else:
poly_type = vtkPolyLine
n_ids = 4
color = self.mesh_color
cells = vtkCellArray()

# Create the polygons
for j in range(mesh.triangles.shape[1]):
poly = poly_type()
poly.GetPointIds().SetNumberOfIds(n_ids) # make a tri
for k in range(len(mesh.triangles[:, j])):
poly.GetPointIds().SetId(k, mesh.triangles[k, j])
if not draw_patch:
poly.GetPointIds().SetId(3, mesh.triangles[0, j]) # Close the triangle
cells.InsertNextCell(poly)

poly_data = vtkPolyData()
poly_data.SetPoints(points)
if draw_patch:
poly_data.SetPolys(cells)
else:
poly_data.SetLines(cells)

# Create a mapper
mapper = vtkPolyDataMapper()
mapper.SetInputData(poly_line)
mapper.SetInputData(poly_data)

# Create an actor
self.mesh_actors.append(vtkActor())
self.mesh_actors[i].SetMapper(mapper)
self.mesh_actors[i].GetProperty().SetColor(self.mesh_color)
self.mesh_actors[i].GetProperty().SetColor(color)
self.mesh_actors[i].GetProperty().SetOpacity(self.mesh_opacity)

self.parent_window.ren.AddActor(self.mesh_actors[i])
Expand Down Expand Up @@ -977,7 +999,10 @@ def update_wrapping(self, all_wrappings):
if wrapping.time.size != 1:
raise IndexError("Mesh should be from one frame only")

if len(self.all_wrappings[seg]) <= i or wrapping.channel.size != self.all_wrappings[seg][i].channel.size:
if (
len(self.all_wrappings[seg]) <= i
or wrapping.channel.size != self.all_wrappings[seg][i].channel.size
):
self.new_wrapping_set(wrappings, seg)
# return # Prevent calling update_markers recursively

Expand Down
4 changes: 3 additions & 1 deletion bioviz/mesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ def __new__(
raise NotImplementedError("Mesh only implements triangle connections")

# If triangle is empty, join lines in order
automatic_triangles = False
if s[1] == 0 and vertex.shape[1] > 0:
automatic_triangles = True
triangles = np.ndarray((3, vertex.shape[1] - 1), dtype="int")
for i in range(vertex.shape[1] - 1):
triangles[:, i] = [i, i + 1, i]

attrs = {'triangles': triangles}
attrs = {"triangles": triangles, "automatic_triangles": automatic_triangles}
return Markers.__new__(cls, vertex, None, None, attrs=attrs, **kwargs)
9 changes: 7 additions & 2 deletions examples/3d_viz.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,13 @@
)

# Create some Rototrans attached to the second model
one_rt = Rototrans.from_markers(origin=d[:, [3, 5], :].mean("channel", keepdims=True),
axis_1=d[:, [4, 3], :], axis_2=d[:, [4, 5], :], axes_name="zx", axis_to_recalculate="z")
one_rt = Rototrans.from_markers(
origin=d[:, [3, 5], :].mean("channel", keepdims=True),
axis_1=d[:, [4, 3], :],
axis_2=d[:, [4, 5], :],
axes_name="zx",
axis_to_recalculate="z",
)

# Create some mesh (could be from any mesh source)
meshes = []
Expand Down
5 changes: 4 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,8 @@
packages=["bioviz"],
package_data={"": ["ressources/*.png"]},
keywords="bioviz",
classifiers=["Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7",],
classifiers=[
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
],
)