Commit b4a35fb3 authored by Lars Kruse's avatar Lars Kruse

added more changes made by Anders Wallin

* additionally some coding style modifications were done
parent 860d6d07
......@@ -14,61 +14,84 @@ from pycam.Geometry.utils import epsilon
_log = pycam.Utils.log.get_logger()
def _polygon2diagram(polygon, dia):
""" add a polygon to an existing voronoi diagram
"""
points = polygon.get_points()
_log.info("Poly2dia points: %s" % str(points))
if not points:
return
# TODO: somehow this causes a hang - see below for the step-by-step loop with log output
#vpoints = [dia.addVertexSite(openvoronoi.Point(*p[:2])) for p in points]
# point_set is a list of 2D points: [ [x0,y0], [x1,y1], ... , [xN,yN] ]
# NOTE: all points in point_set must be unique! i.e. no duplicate points allowed
#
# line_set is a list of line-segments, given as index-pairs into the point_set list
# [ [start0,end0] , [start1,end1], ... , [startM,endM] ]
# NOTE: intersecting line-segments are not allowed.
#
# this defines line-segments point_set[start0] - points_set[end0] and so on...
#
# NOTE: currently openvoronoi only supports vertices of degree 2 or lower.
# i.e. a "star" geometry where three or more line-segments connect to a central vertex is forbidden
# SUPPORTED: point_set = [p0,p1,p2,p3] line_set = [[0,1], [1,2], [2,3], [3,0]]
# NOT SUPPORTED: point_set = [p0,p1,p2,p3] line_set = [[0,1], [0,2], [0,3]] (three line-segments connect to p0!)
def _add_connected_point_set_to_diagram(point_set, line_set, dia):
# add all points to the diagram
vpoints = []
for p in points:
for p in point_set:
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:
# recycle the first voronoi vertex ID
vpoints.append(vpoints[0])
before = None
for current in vpoints:
if not before is None:
dia.addLineSite(before, current)
before = current
# now add all line-segments
for segment in line_set:
start_idx = vpoints[segment[0]]
end_idx = vpoints[segment[1]]
dia.addLineSite(start_idx, end_idx)
_log.info("all lines added to openvoronoi!")
def pocket_model(polygons, offset):
maxx = max([poly.maxx for poly in polygons])
maxy = max([poly.maxy for poly in polygons])
minx = min([poly.minx for poly in polygons])
miny = min([poly.miny for poly in polygons])
radius = math.sqrt((maxx - minx) ** 2 + (maxy - miny) ** 2) / 1.8
_log.info("Radius: %f" % radius)
bin_size = int(math.ceil(math.sqrt(sum([len(poly.get_points()) for poly in polygons]))))
_log.info("bin_size: %f" % bin_size)
dia = openvoronoi.VoronoiDiagram(radius, bin_size)
for polygon in polygons:
_polygon2diagram(polygon, dia)
def _polygons_to_line_set(polygons):
# all points (unique!)
point_set = []
# all line-segments (indexes into the point_set array)
line_set = []
previous_point_index = 0
point_count = 0
for polygon_index, polygon in enumerate(polygons):
_log.info("polygon #%d has %d vertices" % (polygon_index, len(polygon)))
first_point = True
poly_pts = polygon.get_points()
# if the polygon is closed, repeat the first point at the end
if polygon.is_closed and poly_pts:
poly_pts.append(poly_pts[0])
for p in poly_pts:
point_count += 1
if p not in point_set:
# this point is a new point we have not seen before
point_set.append(p)
current_point_index = point_set.index(p)
# on the first iteration we have no line-segment
if not first_point:
_log.info(" line from %s to %s" % (previous_point_index, current_point_index))
line_set.append((previous_point_index, current_point_index))
else:
first_point = False
previous_point_index = current_point_index
_log.info("point_count: %d" % len(point_set))
_log.info("point_set size: %d", len(point_set))
_log.info("number of line-segments: %d" % len(line_set))
_log.info("Point set: %s" % str(point_set))
_log.info("Line set: %s" % str(line_set))
return point_set, line_set
def _offset_loops_to_polygons(offset_loops):
model = pycam.Geometry.Model.ContourModel()
before = None
offset_dia = openvoronoi.Offset(dia.getGraph())
for loop in offset_dia.offset(offset):
for n_loop, loop in enumerate(offset_loops):
lines = []
for item in loop:
if before is None:
before = (item[0].x, item[0].y, 0.0)
else:
_log.info("loop #%d has %d lines/arcs" % (n_loop, len(loop)))
for n_segment, item in enumerate(loop):
point, radius = item[:2]
point = (point.x, point.y, 0.0)
if len(item) == 2:
if not before is None:
if radius == -1:
lines.append(pycam.Geometry.Line.Line(before, point))
_log.info("%d line %s to %s" % (n_segment, before, point))
else:
_log.warn("Unexpected voronoi condition: too few items (%s)" % str(item))
else:
_log.info("%d arc %s to %s r=%f" % (n_segment, before, point, radius))
center, clock_wise = item[2:]
center = (center.x, center.y, 0.0)
direction_before = (before[0] - center[0], before[1] - center[1], 0.0)
......@@ -89,6 +112,30 @@ def pocket_model(polygons, offset):
model.append(line)
return model.get_polygons()
def pocket_model(polygons, offset):
_log.info("number of polygons: %d" % len(polygons))
_log.info("offset distance: %f" % offset)
maxx = max([poly.maxx for poly in polygons])
maxy = max([poly.maxy for poly in polygons])
minx = min([poly.minx for poly in polygons])
miny = min([poly.miny for poly in polygons])
radius = math.sqrt((maxx - minx) ** 2 + (maxy - miny) ** 2) / 1.8
_log.info("Radius: %f" % radius)
bin_size = int(math.ceil(math.sqrt(sum([len(poly.get_points()) for poly in polygons]))))
_log.info("bin_size: %f" % bin_size)
dia = openvoronoi.VoronoiDiagram(radius, bin_size)
point_set, line_set = _polygons_to_line_set(polygons)
_add_connected_point_set_to_diagram(point_set, line_set, dia)
_log.info("diagram complete")
_log.info("diagram check: %s" % str(dia.check()))
offset_dia = openvoronoi.Offset(dia.getGraph())
_log.info("offset diagram created")
offset_loops = offset_dia.offset(offset)
_log.info("got %d loops from openvoronoi" % len(offset_loops))
return _offset_loops_to_polygons(offset_loops)
if __name__ == "__main__":
import sys
if len(sys.argv) > 1:
......@@ -111,11 +158,16 @@ if __name__ == "__main__":
# 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)
scale_value = 1.4 / maxdim
print "Scaling factor: %f" % scale_value
model.scale(scale_value)
shift_x = - (model.minx + (model.maxx - model.minx) / 2.0)
shift_y = - (model.miny + (model.maxy - model.miny) / 2.0)
print "Shifting x: ", shift_x
print "Shifting y: ", shift_y
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)
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