diff options
author | Simon Edwards <s.edwards@ultimaker.com> | 2016-05-26 15:39:22 +0300 |
---|---|---|
committer | Simon Edwards <s.edwards@ultimaker.com> | 2016-05-26 15:39:22 +0300 |
commit | 5f638f6e69b85d64d1904bac8c4c25417294e209 (patch) | |
tree | ca69b73234cf6b0db593bb79fda782b515a5941d /cura/ConvexHullDecorator.py | |
parent | 7e3dd3d443dfbda122bd14f0c2b73ba6f6831e13 (diff) |
Better handling of degenerate convex hull cases.
Contributes to CURA-1504
Diffstat (limited to 'cura/ConvexHullDecorator.py')
-rw-r--r-- | cura/ConvexHullDecorator.py | 82 |
1 files changed, 42 insertions, 40 deletions
diff --git a/cura/ConvexHullDecorator.py b/cura/ConvexHullDecorator.py index c42ab4f339..2a8f55d09e 100644 --- a/cura/ConvexHullDecorator.py +++ b/cura/ConvexHullDecorator.py @@ -130,46 +130,48 @@ class ConvexHullDecorator(SceneNodeDecorator): return rounded_hull else: - if not self._node.getMeshData(): - return None - mesh = self._node.getMeshData() - world_transform = self._node.getWorldTransformation() - - # Check the cache - if mesh is self._2d_convex_hull_mesh and world_transform == self._2d_convex_hull_mesh_world_transform: - # Logger.log('d', 'Cache hit in _compute2DConvexHull mesh path') - return self._2d_convex_hull_mesh_result - - vertex_data = mesh.getConvexHullTransformedVertices(world_transform) - # Don't use data below 0. - # TODO; We need a better check for this as this gives poor results for meshes with long edges. - vertex_data = vertex_data[vertex_data[:,1] >= 0] - - # Round the vertex data to 1/10th of a mm, then remove all duplicate vertices - # This is done to greatly speed up further convex hull calculations as the convex hull - # becomes much less complex when dealing with highly detailed models. - vertex_data = numpy.round(vertex_data, 1) - - vertex_data = vertex_data[:, [0, 2]] # Drop the Y components to project to 2D. - - # Grab the set of unique points. - # - # This basically finds the unique rows in the array by treating them as opaque groups of bytes - # which are as long as the 2 float64s in each row, and giving this view to numpy.unique() to munch. - # See http://stackoverflow.com/questions/16970982/find-unique-rows-in-numpy-array - vertex_byte_view = numpy.ascontiguousarray(vertex_data).view( - numpy.dtype((numpy.void, vertex_data.dtype.itemsize * vertex_data.shape[1]))) - _, idx = numpy.unique(vertex_byte_view, return_index=True) - vertex_data = vertex_data[idx] # Select the unique rows by index. - - hull = Polygon(vertex_data) - - # First, calculate the normal convex hull around the points - convex_hull = hull.getConvexHull() - - # Then, do a Minkowski hull with a simple 1x1 quad to outset and round the normal convex hull. - # This is done because of rounding errors. - rounded_hull = convex_hull.getMinkowskiHull(Polygon(numpy.array([[-0.5, -0.5], [-0.5, 0.5], [0.5, 0.5], [0.5, -0.5]], numpy.float32))) + rounded_hull = None + if self._node.getMeshData(): + mesh = self._node.getMeshData() + world_transform = self._node.getWorldTransformation() + + # Check the cache + if mesh is self._2d_convex_hull_mesh and world_transform == self._2d_convex_hull_mesh_world_transform: + # Logger.log('d', 'Cache hit in _compute2DConvexHull mesh path') + return self._2d_convex_hull_mesh_result + + vertex_data = mesh.getConvexHullTransformedVertices(world_transform) + # Don't use data below 0. + # TODO; We need a better check for this as this gives poor results for meshes with long edges. + vertex_data = vertex_data[vertex_data[:,1] >= 0] + + if len(vertex_data) >= 4: + # Round the vertex data to 1/10th of a mm, then remove all duplicate vertices + # This is done to greatly speed up further convex hull calculations as the convex hull + # becomes much less complex when dealing with highly detailed models. + vertex_data = numpy.round(vertex_data, 1) + + vertex_data = vertex_data[:, [0, 2]] # Drop the Y components to project to 2D. + + # Grab the set of unique points. + # + # This basically finds the unique rows in the array by treating them as opaque groups of bytes + # which are as long as the 2 float64s in each row, and giving this view to numpy.unique() to munch. + # See http://stackoverflow.com/questions/16970982/find-unique-rows-in-numpy-array + vertex_byte_view = numpy.ascontiguousarray(vertex_data).view( + numpy.dtype((numpy.void, vertex_data.dtype.itemsize * vertex_data.shape[1]))) + _, idx = numpy.unique(vertex_byte_view, return_index=True) + vertex_data = vertex_data[idx] # Select the unique rows by index. + + hull = Polygon(vertex_data) + + if len(vertex_data) >= 4: + # First, calculate the normal convex hull around the points + convex_hull = hull.getConvexHull() + + # Then, do a Minkowski hull with a simple 1x1 quad to outset and round the normal convex hull. + # This is done because of rounding errors. + rounded_hull = convex_hull.getMinkowskiHull(Polygon(numpy.array([[-0.5, -0.5], [-0.5, 0.5], [0.5, 0.5], [0.5, -0.5]], numpy.float32))) # Store the result in the cache self._2d_convex_hull_mesh = mesh |