Commit 860d6d07 authored by Lars Kruse's avatar Lars Kruse

fixed radius and point handling (thanks to Anders)

* added some more debug output
* scale and shift the 2D model to (0, 0)
parent a277e02c
...@@ -9,6 +9,7 @@ import pycam.Geometry.Line ...@@ -9,6 +9,7 @@ import pycam.Geometry.Line
import pycam.Geometry.Polygon import pycam.Geometry.Polygon
import pycam.Geometry.Model import pycam.Geometry.Model
from pycam.Geometry.PointUtils import pdist_sq from pycam.Geometry.PointUtils import pdist_sq
from pycam.Geometry.utils import epsilon
_log = pycam.Utils.log.get_logger() _log = pycam.Utils.log.get_logger()
...@@ -16,66 +17,76 @@ _log = pycam.Utils.log.get_logger() ...@@ -16,66 +17,76 @@ _log = pycam.Utils.log.get_logger()
def _polygon2diagram(polygon, dia): def _polygon2diagram(polygon, dia):
""" add a polygon to an existing voronoi diagram """ add a polygon to an existing voronoi diagram
""" """
points = list(polygon.get_points()) points = polygon.get_points()
_log.info("Poly2dia points: %s" % str(points))
if not points: if not points:
return return
if polygon.is_closed: # TODO: somehow this causes a hang - see below for the step-by-step loop with log output
# the last and the first point are identical for closed polygons #vpoints = [dia.addVertexSite(openvoronoi.Point(*p[:2])) for p in points]
points.pop(-1) vpoints = []
vpoints = [dia.addVertexSite(openvoronoi.Point(*p[:2])) for p in points] for p in points:
ovp = openvoronoi.Point(*p[:2])
_log.info("OVP: %s" % str(ovp))
vpoints.append(dia.addVertexSite(ovp))
_log.info("OVP added")
_log.info("all vertices added to openvoronoi!")
if polygon.is_closed: if polygon.is_closed:
# recycle the first voronoi vertex ID # recycle the first voronoi vertex ID
vpoints.append(vpoints[0]) vpoints.append(vpoints[0])
before = None before = None
for current in vpoints: for current in vpoints:
if before: if not before is None:
dia.addLineSite(before, current) dia.addLineSite(before, current)
before = current before = current
_log.info("all lines added to openvoronoi!")
def pocket_model(polygons, offset): def pocket_model(polygons, offset):
maxx = max([poly.maxx for poly in polygons]) maxx = max([poly.maxx for poly in polygons])
maxy = max([poly.maxy for poly in polygons]) maxy = max([poly.maxy for poly in polygons])
minx = min([poly.minx for poly in polygons]) minx = min([poly.minx for poly in polygons])
miny = min([poly.miny for poly in polygons]) miny = min([poly.miny for poly in polygons])
radius = max(maxx - minx, maxy - miny) / 1.8 radius = math.sqrt((maxx - minx) ** 2 + (maxy - miny) ** 2) / 1.8
bin_size = sum([len(poly.get_points()) for poly in polygons]) _log.info("Radius: %f" % radius)
dia = openvoronoi.VoronoiDiagram(radius, int(math.ceil(math.sqrt(bin_size)))) bin_size = int(math.ceil(math.sqrt(sum([len(poly.get_points()) for poly in polygons]))))
#dia.setEdgeOffset(offset) _log.info("bin_size: %f" % bin_size)
dia = openvoronoi.VoronoiDiagram(radius, bin_size)
for polygon in polygons: for polygon in polygons:
_polygon2diagram(polygon, dia) _polygon2diagram(polygon, dia)
dia.check()
offset_dia = openvoronoi.Offset(dia.getGraph())
#polygons = []
model = pycam.Geometry.Model.ContourModel() model = pycam.Geometry.Model.ContourModel()
before = None before = None
offset_dia = openvoronoi.Offset(dia.getGraph())
for loop in offset_dia.offset(offset): for loop in offset_dia.offset(offset):
#polygon = pycam.Geometry.Polygon.Polygon() lines = []
for item in loop: for item in loop:
if before is None: if before is None:
before = (item[0].x, item[0].y, 0.0) before = (item[0].x, item[0].y, 0.0)
else: else:
point, radius, center, clock_wise = item point, radius = item[:2]
point = (point.x, point.y, 0.0) point = (point.x, point.y, 0.0)
center = (center.x, center.y, 0.0) if len(item) == 2:
if radius == -1: if radius == -1:
model.append(pycam.Geometry.Line.Line(before, point)) lines.append(pycam.Geometry.Line.Line(before, point))
else:
_log.warn("Unexpected voronoi condition: too few items (%s)" % str(item))
else: else:
direction_before = (before[0] - center[0], before[1] - center[1], 0) center, clock_wise = item[2:]
direction_end = (point[0] - center[0], point[1] - center[1], 0) center = (center.x, center.y, 0.0)
angles = [180 * pycam.Geometry.get_angle_pi((1, 0, 0), (0, 0, 0), direction_before = (before[0] - center[0], before[1] - center[1], 0.0)
direction, (0, 0, 1), pi_factor=True) direction_end = (point[0] - center[0], point[1] - center[1], 0.0)
angles = [180.0 * pycam.Geometry.get_angle_pi((1.0, 0.0, 0.0), (0, 0.0, 0.0),
direction, (0.0, 0.0, 1.0), pi_factor=True)
for direction in (direction_before, direction_end)] for direction in (direction_before, direction_end)]
if not clock_wise: if clock_wise:
angles.reverse() angles.reverse()
points = pycam.Geometry.get_points_of_arc(center, radius, angles[0], angles[1], cords=64) points = pycam.Geometry.get_points_of_arc(center, radius, angles[0], angles[1])
points.pop(0) last_p = before
last_p = None
for p in points: for p in points:
if last_p: lines.append(pycam.Geometry.Line.Line(last_p, p))
model.append(pycam.Geometry.Line.Line(last_p, p))
last_p = p last_p = p
before = point before = point
#polygons.append(polygon) for line in lines:
if line.len > epsilon:
model.append(line)
return model.get_polygons() return model.get_polygons()
if __name__ == "__main__": if __name__ == "__main__":
...@@ -86,7 +97,8 @@ if __name__ == "__main__": ...@@ -86,7 +97,8 @@ if __name__ == "__main__":
else: else:
model = pycam.Geometry.Model.ContourModel() model = pycam.Geometry.Model.ContourModel()
# convert some points to a 2D model # convert some points to a 2D model
points = ((0.0, 0.0, 0.0), (10.0, 0.0, 0.0), (10.0, 10.0, 0.0), (0.0, 0.0, 0.0)) points = ((0.0, 0.0, 0.0), (0.5, 0.0, 0.0), (0.5, 0.5, 0.0), (0.0, 0.0, 0.0))
print "original points: ", points
before = None before = None
for p in points: for p in points:
if before: if before:
...@@ -95,6 +107,15 @@ if __name__ == "__main__": ...@@ -95,6 +107,15 @@ if __name__ == "__main__":
if len(sys.argv) > 2: if len(sys.argv) > 2:
offset = float(sys.argv[2]) offset = float(sys.argv[2])
else: else:
offset = 1.0 offset = 0.4
# scale model within a range of -1..1
maxdim = max(model.maxx - model.minx, model.maxy - model.miny)
# stay well below sqrt(2)/2 in all directions
model.scale(1.4 / maxdim)
shift_x = - (model.minx + (model.maxx - model.minx) / 2.0)
shift_y = - (model.miny + (model.maxy - model.miny) / 2.0)
model.shift(shift_x, shift_y, 0.0)
print "Model dimensions x: %f..%f" % (model.minx, model.maxx)
print "Model dimensions y: %f..%f" % (model.miny, model.maxy)
print pocket_model(model.get_polygons(), offset) print pocket_model(model.get_polygons(), offset)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment