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 ...@@ -14,61 +14,84 @@ from pycam.Geometry.utils import epsilon
_log = pycam.Utils.log.get_logger() _log = pycam.Utils.log.get_logger()
def _polygon2diagram(polygon, dia): # point_set is a list of 2D points: [ [x0,y0], [x1,y1], ... , [xN,yN] ]
""" add a polygon to an existing voronoi diagram # NOTE: all points in point_set must be unique! i.e. no duplicate points allowed
""" #
points = polygon.get_points() # line_set is a list of line-segments, given as index-pairs into the point_set list
_log.info("Poly2dia points: %s" % str(points)) # [ [start0,end0] , [start1,end1], ... , [startM,endM] ]
if not points: # NOTE: intersecting line-segments are not allowed.
return #
# TODO: somehow this causes a hang - see below for the step-by-step loop with log output # this defines line-segments point_set[start0] - points_set[end0] and so on...
#vpoints = [dia.addVertexSite(openvoronoi.Point(*p[:2])) for p in points] #
# 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 = [] vpoints = []
for p in points: for p in point_set:
ovp = openvoronoi.Point(*p[:2]) ovp = openvoronoi.Point(*p[:2])
_log.info("OVP: %s" % str(ovp))
vpoints.append(dia.addVertexSite(ovp)) vpoints.append(dia.addVertexSite(ovp))
_log.info("OVP added")
_log.info("all vertices added to openvoronoi!") _log.info("all vertices added to openvoronoi!")
if polygon.is_closed: # now add all line-segments
# recycle the first voronoi vertex ID for segment in line_set:
vpoints.append(vpoints[0]) start_idx = vpoints[segment[0]]
before = None end_idx = vpoints[segment[1]]
for current in vpoints: dia.addLineSite(start_idx, end_idx)
if not before is None:
dia.addLineSite(before, current)
before = current
_log.info("all lines added to openvoronoi!") _log.info("all lines added to openvoronoi!")
def pocket_model(polygons, offset):
maxx = max([poly.maxx for poly in polygons]) def _polygons_to_line_set(polygons):
maxy = max([poly.maxy for poly in polygons]) # all points (unique!)
minx = min([poly.minx for poly in polygons]) point_set = []
miny = min([poly.miny for poly in polygons]) # all line-segments (indexes into the point_set array)
radius = math.sqrt((maxx - minx) ** 2 + (maxy - miny) ** 2) / 1.8 line_set = []
_log.info("Radius: %f" % radius) previous_point_index = 0
bin_size = int(math.ceil(math.sqrt(sum([len(poly.get_points()) for poly in polygons])))) point_count = 0
_log.info("bin_size: %f" % bin_size) for polygon_index, polygon in enumerate(polygons):
dia = openvoronoi.VoronoiDiagram(radius, bin_size) _log.info("polygon #%d has %d vertices" % (polygon_index, len(polygon)))
for polygon in polygons: first_point = True
_polygon2diagram(polygon, dia) 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() model = pycam.Geometry.Model.ContourModel()
before = None before = None
offset_dia = openvoronoi.Offset(dia.getGraph()) for n_loop, loop in enumerate(offset_loops):
for loop in offset_dia.offset(offset):
lines = [] lines = []
for item in loop: _log.info("loop #%d has %d lines/arcs" % (n_loop, len(loop)))
if before is None: for n_segment, item in enumerate(loop):
before = (item[0].x, item[0].y, 0.0) point, radius = item[:2]
else: point = (point.x, point.y, 0.0)
point, radius = item[:2] if not before is None:
point = (point.x, point.y, 0.0) if radius == -1:
if len(item) == 2: lines.append(pycam.Geometry.Line.Line(before, point))
if radius == -1: _log.info("%d line %s to %s" % (n_segment, before, point))
lines.append(pycam.Geometry.Line.Line(before, point))
else:
_log.warn("Unexpected voronoi condition: too few items (%s)" % str(item))
else: else:
_log.info("%d arc %s to %s r=%f" % (n_segment, before, point, radius))
center, clock_wise = item[2:] center, clock_wise = item[2:]
center = (center.x, center.y, 0.0) center = (center.x, center.y, 0.0)
direction_before = (before[0] - center[0], before[1] - center[1], 0.0) direction_before = (before[0] - center[0], before[1] - center[1], 0.0)
...@@ -83,12 +106,36 @@ def pocket_model(polygons, offset): ...@@ -83,12 +106,36 @@ def pocket_model(polygons, offset):
for p in points: for p in points:
lines.append(pycam.Geometry.Line.Line(last_p, p)) lines.append(pycam.Geometry.Line.Line(last_p, p))
last_p = p last_p = p
before = point before = point
for line in lines: for line in lines:
if line.len > epsilon: if line.len > epsilon:
model.append(line) model.append(line)
return model.get_polygons() 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__": if __name__ == "__main__":
import sys import sys
if len(sys.argv) > 1: if len(sys.argv) > 1:
...@@ -111,11 +158,16 @@ if __name__ == "__main__": ...@@ -111,11 +158,16 @@ if __name__ == "__main__":
# scale model within a range of -1..1 # scale model within a range of -1..1
maxdim = max(model.maxx - model.minx, model.maxy - model.miny) maxdim = max(model.maxx - model.minx, model.maxy - model.miny)
# stay well below sqrt(2)/2 in all directions # 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_x = - (model.minx + (model.maxx - model.minx) / 2.0)
shift_y = - (model.miny + (model.maxy - model.miny) / 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) model.shift(shift_x, shift_y, 0.0)
print "Model dimensions x: %f..%f" % (model.minx, model.maxx) print "Model dimensions x: %f..%f" % (model.minx, model.maxx)
print "Model dimensions y: %f..%f" % (model.miny, model.maxy) 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