Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_contour(self):
path = get_model('wrench.dxf')
poly = path.polygons_full[0]
# generate tool paths
toolpaths = pocketing.contour.contour_parallel(poly, .05)
assert all(trimesh.util.is_shape(i, (-1, 2))
for i in toolpaths)
def check_arcs(arcs):
# arcs should be 2D or 2D 3-point arcs
assert trimesh.util.is_shape(arcs, (-1, 3, (3, 2)))
# make sure arcs start where previous arc begins
for a, b in zip(arcs[:-1], arcs[1:]):
assert np.allclose(a[2], b[0])
Parameters
-----------
points : (n,3) float, list of points in space
directions : (n,3) float, directions of rays
Returns
----------
signed_distance : (n,) float, length of rays
"""
points = np.asanyarray(points, dtype=np.float64)
if not util.is_shape(points, (-1, 3)):
raise ValueError('points must be (n,3)!')
directions = np.asanyarray(directions, dtype=np.float64)
if not util.is_shape(directions, (-1, 3)):
raise ValueError('directions must be (n,3)!')
if len(points) != len(directions):
raise ValueError('number of points must equal number of directions!')
faces, rays, locations = mesh.ray.intersects_id(points, directions,
return_locations=True,
multiple_hits=True)
if len(rays) > 0:
distances = np.linalg.norm(locations - points[rays],
axis=1)
else:
distances = np.array([])
# Reject intersections at distance less than tol.planar
rays = rays[distances > tol.planar]
mesh : trimesh.Trimesh
Mesh to query
points : (m, 3) float
Points in space
Returns
----------
closest : (m, 3) float
Closest point on triangles for each point
distance : (m,) float
Distance
triangle_id : (m,) int
Index of triangle containing closest point
"""
points = np.asanyarray(points, dtype=np.float64)
if not util.is_shape(points, (-1, 3)):
raise ValueError('points must be (n,3)!')
# do a tree- based query for faces near each point
candidates = nearby_faces(mesh, points)
# view triangles as an ndarray so we don't have to recompute
# the MD5 during all of the subsequent advanced indexing
triangles = mesh.triangles.view(np.ndarray)
# create the corresponding list of triangles
# and query points to send to the closest_point function
query_point = deque()
query_tri = deque()
for triangle_ids, point in zip(candidates, points):
query_point.append(np.tile(point, (len(triangle_ids), 1)))
query_tri.append(triangles[triangle_ids])
polygon : shapely.geometry.Polygon
Profile to sweep along path
path : (n, 3) float
A path in 3D
angles : (n,) float
Optional rotation angle relative to prior vertex
at each vertex
Returns
-------
mesh : trimesh.Trimesh
Geometry of result
"""
path = np.asanyarray(path, dtype=np.float64)
if not util.is_shape(path, (-1, 3)):
raise ValueError('Path must be (n, 3)!')
# Extract 2D vertices and triangulation
verts_2d = np.array(polygon.exterior)[:-1]
base_verts_2d, faces_2d = triangulate_polygon(polygon, **kwargs)
n = len(verts_2d)
# Create basis for first planar polygon cap
x, y, z = util.generate_basis(path[0] - path[1])
tf_mat = np.ones((4, 4))
tf_mat[:3, :3] = np.c_[x, y, z]
tf_mat[:3, 3] = path[0]
# Compute 3D locations of those vertices
verts_3d = np.c_[verts_2d, np.zeros(n)]
verts_3d = tf.transform_points(verts_3d, tf_mat)
-------------
points : (n, 3) float
Points to be rendered
colors : (n, 3) or (n, 4) float
Colors for each point
group : str
Rendering group for the vertex list
Returns
--------------
args : (7,) tuple
Args for vertex list constructor
"""
points = np.asanyarray(points, dtype=np.float64)
if util.is_shape(points, (-1, 2)):
points = np.column_stack((points, np.zeros(len(points))))
elif not util.is_shape(points, (-1, 3)):
raise ValueError('Pointcloud must be (n,3)!')
index = np.arange(len(points)).tolist()
args = (len(points), # number of vertices
GL_POINTS, # mode
group, # group
index, # indices
('v3f/static', points.reshape(-1)),
colors_to_gl(colors, len(points)))
return args
If the point is on the surface of the mesh, behavior is
undefined.
Parameters
---------
mesh: Trimesh object
points: (n,3) points in space
Returns
---------
contains : (n) bool
Whether point is inside mesh or not
"""
# convert points to float and make sure they are 3D
points = np.asanyarray(points, dtype=np.float64)
if not util.is_shape(points, (-1, 3)):
raise ValueError('points must be (n,3)')
# placeholder result with no hits we'll fill in later
contains = np.zeros(len(points), dtype=np.bool)
# cull points outside of the axis aligned bounding box
# this avoids running ray tests unless points are close
inside_aabb = bounds.contains(intersector.mesh.bounds,
points)
# if everything is outside the AABB, exit early
if not inside_aabb.any():
return contains
# default ray direction is random, but we are not generating
# uniquely each time so the behavior of this function is easier to debug
# extract a set of convex hull vertices and normals from the input
# we bother to do this to avoid recomputing the full convex hull if
# possible
if hasattr(obj, 'convex_hull'):
# if we have been passed a mesh, use its existing convex hull to pull from
# cache rather than recomputing. This version of the cached convex hull has
# normals pointing in arbitrary directions (straight from qhull)
# using this avoids having to compute the expensive corrected normals
# that mesh.convex_hull uses since normal directions don't matter here
vertices = obj.convex_hull.vertices
hull_normals = obj.convex_hull.face_normals
elif util.is_sequence(obj):
# we've been passed a list of points
points = np.asanyarray(obj)
if util.is_shape(points, (-1, 2)):
return oriented_bounds_2D(points)
elif util.is_shape(points, (-1, 3)):
hull_obj = spatial.ConvexHull(points)
vertices = hull_obj.points[hull_obj.vertices]
hull_normals, valid = triangles.normals(
hull_obj.points[hull_obj.simplices])
else:
raise ValueError('Points are not (n,3) or (n,2)!')
else:
raise ValueError(
'Oriented bounds must be passed a mesh or a set of points!')
# convert face normals to spherical coordinates on the upper hemisphere
# the vector_hemisphere call effectivly merges negative but otherwise
# identical vectors
spherical_coords = util.vector_to_spherical(
Return the 2D bounding box size of each triangle.
Parameters
----------
triangles : (n, 3, 3) float
Triangles in space
areas : (n,) float
Optional area of input triangles
Returns
----------
box : (n, 2) float
The size of each triangle's 2D oriented bounding box
"""
triangles = np.asanyarray(triangles, dtype=np.float64)
if not util.is_shape(triangles, (-1, 3, 3)):
raise ValueError('Triangles must be (n, 3, 3)!')
if areas is None:
areas = area(triangles=triangles,
sum=False)
# the edge vectors which define the triangle
a = triangles[:, 1] - triangles[:, 0]
b = triangles[:, 2] - triangles[:, 0]
# length of the edge vectors
length_a = (a**2).sum(axis=1)**.5
length_b = (b**2).sum(axis=1)**.5
# which edges are acceptable length
nonzero_a = length_a > tol.merge