Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Michiel Cottaar
fslpy
Commits
4a38ff04
Commit
4a38ff04
authored
Jan 11, 2018
by
Paul McCarthy
🚵
Browse files
A big rough and ready - TriangleMesh.rayIntersection method wraps
trimesh ray.intersect_id function.
parent
8cc7d096
Changes
1
Hide whitespace changes
Inline
Side-by-side
fsl/data/mesh.py
View file @
4a38ff04
...
...
@@ -27,8 +27,7 @@ import numpy as np
import
six
import
trimesh
import
fsl.utils.memoize
as
memoize
import
fsl.utils.transform
as
transform
from
.
import
image
as
fslimage
...
...
@@ -123,11 +122,6 @@ class TriangleMesh(object):
if
fixWinding
:
self
.
__fixWindingOrder
()
self
.
__trimesh
=
trimesh
.
Trimesh
(
self
.
__vertices
,
self
.
__indices
,
process
=
False
,
validate
=
False
)
def
__repr__
(
self
):
"""Returns a string representation of this ``TriangleMesh`` instance.
...
...
@@ -142,26 +136,6 @@ class TriangleMesh(object):
return
self
.
__repr__
()
@
property
def
vertices
(
self
):
"""The ``(N, 3)`` vertices of this mesh. """
return
self
.
__vertices
@
property
def
indices
(
self
):
"""The ``(M, 3)`` triangles of this mesh. """
return
self
.
__indices
@
property
def
trimesh
(
self
):
"""Reference to a ``trimesh.Trimesh`` object which can be used for
geometric operations on the mesh.
"""
return
self
.
__trimesh
def
__fixWindingOrder
(
self
):
"""Called by :meth:`__init__` if ``fixWinding is True``. Fixes the
mesh triangle winding order so that all face normals are facing
...
...
@@ -195,6 +169,18 @@ class TriangleMesh(object):
self
.
__faceNormals
*=
-
1
@
property
def
vertices
(
self
):
"""The ``(N, 3)`` vertices of this mesh. """
return
self
.
__vertices
@
property
def
indices
(
self
):
"""The ``(M, 3)`` triangles of this mesh. """
return
self
.
__indices
@
property
def
normals
(
self
):
"""A ``(M, 3)`` array containing surface normals for every
...
...
@@ -245,6 +231,101 @@ class TriangleMesh(object):
return
self
.
__vertNormals
@
memoize
.
Instanceify
(
memoize
.
memoize
)
def
trimesh
(
self
):
"""Reference to a ``trimesh.Trimesh`` object which can be used for
geometric operations on the mesh.
If the ``trimesh`` or ``rtree`` libraries are not available, this
function returns ``None``
"""
# trimesh is an optional dependency - rtree
# is a depedendency of trimesh which is a
# wrapper around libspatialindex, without
# which trimesh can't be used for calculating
# ray-mesh intersections.
try
:
import
trimesh
import
rtree
# noqa
except
ImportError
:
log
.
warning
(
'trimesh is not available'
)
return
None
if
hasattr
(
self
,
'__trimesh'
):
return
self
.
__trimesh
self
.
__trimesh
=
trimesh
.
Trimesh
(
self
.
__vertices
,
self
.
__indices
,
process
=
False
,
validate
=
False
)
return
self
.
__trimesh
def
rayIntersection
(
self
,
origins
,
directions
,
sort
=
False
,
vertices
=
False
):
"""Calculate the intersection between the mesh, and the rays defined by
``origins`` and ``directions``.
:arg origins: Sequence of ray origins
:arg directions: Sequence of ray directions
:arg sort: By default, the calculated intersection coordinates
are not sorted. If ``sort`` is set to ``True`` will
be sorted according to increasing distance from the
ray origin.
:arg vertices: By default, the returned coordinates are where the
ray intersects with triangles of the mesh. If
``vertices`` is set to ``True``, the returned
coordinates will be the vertices that were nearest
to the ray intersection points.
:returns: A list-of-lists, one for each input ray, containing
the points where the ray intersected the mesh.
"""
hits
=
[[]
for
o
in
origins
]
trimesh
=
self
.
trimesh
()
if
trimesh
is
None
:
return
hits
tris
,
rays
,
locs
=
self
.
trimesh
().
ray
.
intersects_id
(
origins
,
directions
,
return_locations
=
True
,
mulltiple_hits
=
False
)
# group by input ray
dists
=
[[]
for
o
in
origins
]
for
tri
,
ray
,
loc
in
zip
(
tris
,
rays
,
locs
):
hits
[
ray
].
append
(
loc
)
if
sort
:
dists
[
ray
].
append
(
transform
.
veclength
(
loc
-
origins
[
ray
]))
# returned locations are not
# sorted, so we need to sort
# them by distance from the
# origin
if
sort
:
for
i
in
range
(
len
(
hits
)):
rayHits
=
hits
[
i
]
rayDists
=
dists
[
i
]
if
len
(
rayHits
)
>
0
:
rayDists
,
rayHits
=
zip
(
*
sorted
(
zip
(
rayDists
,
rayHits
)))
hits
[
i
]
=
rayHits
dists
[
i
]
=
rayDists
# TODO
if
vertices
:
pass
return
hits
def
getBounds
(
self
):
"""Returns a tuple of values which define a minimal bounding box that
will contain all vertices in this ``TriangleMesh`` instance. The
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment