def add_roll_on(curve, roll_on_curve, direction, roll_radius, offset_extra, roll_on): if direction == "on": roll_on = None if curve.NumVertices() <= 1: return first_span = curve.GetFirstSpan() if roll_on == None: rollstart = first_span.p elif roll_on == 'auto': if roll_radius < 0.0000000001: rollstart = first_span.p v = first_span.GetVector(0.0) if direction == 'right': off_v = geom.Point(v.y, -v.x) else: off_v = geom.Point(-v.y, v.x) rollstart = first_span.p + off_v * roll_radius else: rollstart = roll_on rvertex = geom.Vertex(first_span.p) if first_span.p == rollstart: rvertex.type = 0 else: v = first_span.GetVector(0.0) # get start direction rvertex.c, rvertex.type = geom.TangentialArc(first_span.p, rollstart, -v) rvertex.type = -rvertex.type # because TangentialArc was used in reverse # add a start roll on point roll_on_curve.Append(rollstart) # add the roll on arc roll_on_curve.Append(rvertex)
def add_roll_off(curve, roll_off_curve, direction, roll_radius, offset_extra, roll_off): if direction == "on": return if roll_off == None: return if curve.NumVertices() <= 1: return last_span = curve.GetLastSpan() if roll_off == 'auto': if roll_radius < 0.0000000001: return v = last_span.GetVector(1.0) # get end direction if direction == 'right': off_v = geom.Point(v.y, -v.x) else: off_v = geom.Point(-v.y, v.x) rollend = last_span.v.p + off_v * roll_radius; else: rollend = roll_off # add the end of the original kurve roll_off_curve.Append(last_span.v.p) if rollend == last_span.v.p: return rvertex = geom.Vertex(rollend) v = last_span.GetVector(1.0) # get end direction rvertex.c, rvertex.type = geom.TangentialArc(last_span.v.p, rollend, v) # add the roll off arc roll_off_curve.Append(rvertex)
def add_CRC_end_line(curve,roll_on_curve,roll_off_curve,radius,direction,crc_end_point,lead_out_line_len): last_span = curve.GetLastSpan() v = last_span.GetVector(1.0) if direction == 'right': off_v = geom.Point(v.y, -v.x) else: off_v = geom.Point(-v.y, v.x) endpoint_roll_off = roll_off_curve.LastVertex().p crc_end = endpoint_roll_off + off_v * lead_out_line_len crc_end_point.x = crc_end.x crc_end_point.y = crc_end.y
def add_CRC_start_line(curve,roll_on_curve,roll_off_curve,radius,direction,crc_start_point,lead_in_line_len): first_span = curve.GetFirstSpan() v = first_span.GetVector(0.0) if direction == 'right': off_v = geom.Point(v.y, -v.x) else: off_v = geom.Point(-v.y, v.x) startpoint_roll_on = roll_on_curve.FirstVertex().p crc_start = startpoint_roll_on + off_v * lead_in_line_len crc_start_point.x = crc_start.x crc_start_point.y = crc_start.y
def GetAngle(self, fraction): if self.curves[4] == None: return 0.0 box = self.curves[4].GetBox() x = box.MinX() + box.Width() * fraction curve = geom.Curve() curve.Append(geom.Point(x, box.MinY() - 1.0)) curve.Append(geom.Point(x, box.MaxY() + 1.0)) pts = curve.Intersections(self.curves[4]) if len(pts) == 0: return 0.0 angle = pts[0].y - box.MinY() return angle
def GetUnitizedPoint(curve, fraction, invtm, centre_straight): if curve == None: return xdist = curve.LastVertex().p.Dist(curve.FirstVertex().p) if xdist < 0.00001: return geom.Point(0, 0) scale = 1.0 / xdist p = curve.PerimToPoint(curve.Perim() * fraction) p.Transform(invtm) pu = geom.Point(p.x * scale, p.y * scale) if centre_straight: pu.y = 0 return pu
def LineLineIntof(self, span): v0 = geom.Point(self.p, self.v.p) v1 = geom.Point(span.p, span.v.p) v2 = geom.Point(self.p, span.p) cp = v1 ^ v0 if math.fabs(cp) < geom.UNIT_VECTOR_TOLERANCE: return [] t = (v1 ^ v2) / cp intersections = [] intersections.append(v0 * t + self.p) return intersections
def best_angle_to_pos(pos): angle_points = [ get_next_point(extension_vertex.point, angle_bucket, segment_length) for angle_bucket in range(64) ] distances = [ angle_point.distance(pos.point()) for angle_point in angle_points ] point_angle = numpy.argmin(distances) * math.pi * 2 / 64.0 - math.pi edge_angle = geom.Point(1, 0).signed_angle(pos.edge.segment().vector()) avg_vector = vector_from_angle(point_angle).add( vector_from_angle(edge_angle)) avg_angle = geom.Point(1, 0).signed_angle(avg_vector) return int((avg_angle + math.pi) * 64.0 / math.pi / 2)
def GetVector(self, fraction): """ returns the direction vector at point which is 0-1 along span """ if self.v.type == 0: v = geom.Point(self.p, self.v.p) v.Normalize() return v p = self.MidParam(fraction) v = geom.Point(self.v.c, p) v.Normalize() if self.v.type == 1: return geom.Point(-v.y, v.x) else: return geom.Point(v.y, -v.x)
def zigzag(a, stepover, zig_unidirectional): if a.NumCurves() == 0: return global rightward_for_zigs global curve_list_for_zigs global sin_angle_for_zigs global cos_angle_for_zigs global sin_minus_angle_for_zigs global cos_minus_angle_for_zigs global one_over_units one_over_units = 1 / geom.get_units() a = rotated_area(a) b = a.GetBox() x0 = b.MinX() - 1.0 x1 = b.MaxX() + 1.0 height = b.MaxY() - b.MinY() num_steps = int(height / stepover + 1) y = b.MinY() + 0.1 * one_over_units null_point = geom.Point(0, 0) rightward_for_zigs = True curve_list_for_zigs = [] for i in range(0, num_steps): y0 = y y = y + stepover p0 = geom.Point(x0, y0) p1 = geom.Point(x0, y) p2 = geom.Point(x1, y) p3 = geom.Point(x1, y0) c = geom.Curve() c.Append(geom.Vertex(0, p0, null_point, 0)) c.Append(geom.Vertex(0, p1, null_point, 0)) c.Append(geom.Vertex(0, p2, null_point, 1)) c.Append(geom.Vertex(0, p3, null_point, 0)) c.Append(geom.Vertex(0, p0, null_point, 1)) a2 = geom.Area() a2.Append(c) a2.Intersect(a) make_zig(a2, y0, y, zig_unidirectional) if zig_unidirectional == False: rightward_for_zigs = (rightward_for_zigs == False) reorder_zigs()
def circleControl(self, event): if self.parent.pointCoords == []: self.parent.pointCoords = [event.x(), event.y()] else: firstPointCoords = self.parent.pointCoords self.parent.pointCoords = [event.x(), event.y()] center = geometry.Point(firstPointCoords[0], firstPointCoords[1]) pointOnCircle = geometry.Point(self.parent.pointCoords[0], self.parent.pointCoords[1]) self.circleWithRadiusCreating(center, pointOnCircle) self.update() self.parent.pointCoords = []
def segmentContol(self, event): if not self.parent.pointCoords: self.parent.pointCoords = [event.x(), event.y()] else: if self.parent.pointCoords == [event.x(), event.y()]: self.parent.messageSend("Error") else: pointCoords = self.parent.pointCoords self.parent.pointCoords = [event.x(), event.y()] point1 = geometry.Point(pointCoords[0], pointCoords[1]) point2 = geometry.Point(self.parent.pointCoords[0], self.parent.pointCoords[1]) if self.parent.brushundertype == "segment": self.segmentCreating(point1, point2) self.update() self.parent.pointCoords = []
def LineArcIntof(self, arc_span): v0 = geom.Point(arc_span.v.c, self.p) v1 = geom.Point(self.p, self.v.p) s = v1.x * v1.x + v1.y * v1.y s0 = v0.x * v0.x + v0.y * v0.y roots = quadratic(s, 2 * (v0 * v1), s0 - arc_span.Radius() * arc_span.Radius()) intersections = [] if len(roots) > 0: toler = geom.tolerance / math.sqrt(s) for root in roots: if root > -toler and root < 1.0 + toler: p = v1 * root + self.p if arc_span.On(p): intersections.append(p) return intersections
def get_starting_locations(gcs, segment_length, region=None): all_starting_locations = {} with open(startlocs_path, 'r', encoding="utf-8") as f: # top-level is dict from tile to starting location lists for tile, locs in json.load(f).items(): tile_region = tile.split('_')[0] if region is not None and tile_region != region: continue elif tile_region not in gcs: continue starting_locations = [] # each loc is a dict with keys 'x', 'y', 'edge_id' for loc in locs: point = geom.Point(int(loc['x']), int(loc['y'])) edge_pos = gcs[tile_region].graph.edges[int( loc['edge_id'])].closest_pos(point) next_positions = graph.follow_graph(edge_pos, segment_length) if not next_positions: continue starting_locations.append([{ 'point': point, 'edge_pos': edge_pos, }, { 'point': next_positions[0].point(), 'edge_pos': next_positions[0], }]) all_starting_locations[tile] = starting_locations return all_starting_locations
def calculate_span_cylinders(self, span, color): sz = span.p.y * toolpath.coords.voxels_per_mm ez = span.v.p.y * toolpath.coords.voxels_per_mm z = sz while z < ez: # make a line at this z intersection_line = area.Span( area.Point(0, z), area.Vertex(0, area.Point(300, z), area.Point(0, 0)), False) intersections = span.Intersect(intersection_line) if len(intersections): radius = intersections[0].x * toolpath.coords.voxels_per_mm self.cylinders.append( VoxelCyl(radius, z * toolpath.coords.voxels_per_mm, color)) z += 1 / toolpath.coords.voxels_per_mm
def read_graph(fname, merge_duplicates=False): graph = Graph() with open(fname, 'r') as f: vertex_section = True vertices = {} next_vertex_id = 0 seen_points = {} for line in f: parts = line.strip().split(' ') if vertex_section: if len(parts) >= 2: point = geom.Point(float(parts[0]), float(parts[1])) if point in seen_points and merge_duplicates: print 'merging duplicate vertex at {}'.format(point) vertices[next_vertex_id] = seen_points[point] else: vertex = graph.add_vertex(point) vertices[next_vertex_id] = vertex seen_points[point] = vertex next_vertex_id += 1 else: vertex_section = False elif len(parts) >= 2: src = vertices[int(parts[0])] dst = vertices[int(parts[1])] if src == dst and merge_duplicates: print 'ignoring self edge at {}'.format(src.point) continue graph.add_edge(src, dst) return graph
def Intof(self, c1): # intersection with another circle # returns a list of intersections v = geom.Point(self.p, c1.p) d = v.Normalize() if d < geom.tolerance: return [] sum = math.fabs(self.r) + math.fabs(c1.r) diff = math.fabs(math.fabs(self.r) - math.fabs(c1.r)) if d > sum + geom.tolerance or d < diff - geom.tolerance: return [] # dist from centre of this circle to mid intersection d0 = 0.5 * (d + (self.r + c1.r) * (self.r - c1.r) / d) if d0 - self.r > geom.tolerance: return [] # circles don't intersect intersections = [] h = (self.r - d0) * (self.r + d0 ) # half distance between intersects squared if h < 0: d0 = c0.radius # tangent intersections.append(v * d0 + self.p) if h < geom.TOLERANCE_SQ: return intersections h = math.sqrt(h) v = ~v intersections.append(v * h + intersections[0]) v = -v intersections[0] = v * h + intersections[0] return intersections
def GetTrailingEdgePoint(self, leading_edge_point): backward_curve = geom.Curve() backward_curve.Append(leading_edge_point) backward_curve.Append(leading_edge_point + geom.Point(0, -1000.0)) pts = backward_curve.Intersections(self.curves[1]) if len(pts) == 0: return None return pts[0]
def GetUnitizedPoint(curve, fraction, invtm, centre_straight): if curve == None: return ps = GetMinXPoint(curve) pe = GetMaxXPoint(curve) xdist = ps.Dist(pe) if xdist < 0.00001: return geom.Point(0, 0) scale = 1.0 / xdist p = curve.PerimToPoint(curve.Perim() * fraction) p.Transform(invtm) pu = geom.Point(p.x * scale, p.y * scale) if centre_straight: pu.y = 0 return pu
def get_tile_list(): tiles = [] with open(pytiles_path, 'r') as f: for json_tile in json.load(f): tile = geom.Point(int(json_tile['x']), int(json_tile['y'])) tile.region = json_tile['region'] tiles.append(tile) return tiles
def make_obround(p0, p1, radius): dir = p1 - p0 d = dir.Length() dir.Normalize() right = geom.Point(dir.y, -dir.x) obround = geom.Area() c = geom.Curve() vt0 = p0 + right * radius vt1 = p1 + right * radius vt2 = p1 - right * radius vt3 = p0 - right * radius c.Append(geom.Vertex(0, vt0, geom.Point(0, 0))) c.Append(geom.Vertex(0, vt1, geom.Point(0, 0))) c.Append(geom.Vertex(1, vt2, p1)) c.Append(geom.Vertex(0, vt3, geom.Point(0, 0))) c.Append(geom.Vertex(1, vt0, p0)) obround.Append(c) return obround
def pointControl(self, event): if self.parent.brushundertype == "point": self.pointCreating(event.x(), event.y()) elif self.parent.brushundertype == "pointinobject": point = self.parent.model.correctingPoints(geometry.Point(event.x(), event.y()), \ self.parent.model.segments, self.parent.model.circles) self.pointInObjectCreating(point.x, point.y) self.update()
def CheckForArc(prev_vt, might_be_an_arc, arc_returned): # this examines the vertices in might_be_an_arc # if they do fit an arc, set arc to be the arc that they fit and return true # returns true, if arc added if len(might_be_an_arc) < 2: return False # find middle point num = len(might_be_an_arc) i = 0 mid_vt = None mid_i = (num - 1) / 2 for vt in might_be_an_arc: if i == mid_i: mid_vt = vt break # create a circle to test p0 = geom.Point(prev_vt.p) p1 = geom.Point(mid_vt.p)
def load_rect(region, rect, load_func=load_tile, mode='all'): # special case for fast load: rect is single tile if rect.start.x % tile_size == 0 and rect.start.y % tile_size == 0 and rect.end.x % tile_size == 0 and rect.end.y % tile_size == 0 and rect.end.x - rect.start.x == tile_size and rect.end.y - rect.start.y == tile_size: return load_func(region, rect.start.x / tile_size, rect.start.y / tile_size, mode=mode) tile_rect = geom.Rectangle( geom.Point(rect.start.x / tile_size, rect.start.y / tile_size), geom.Point((rect.end.x - 1) / tile_size + 1, (rect.end.y - 1) / tile_size + 1)) full_rect = geom.Rectangle(tile_rect.start.scale(tile_size), tile_rect.end.scale(tile_size)) full_ims = {} for i in range(tile_rect.start.x, tile_rect.end.x): for j in range(tile_rect.start.y, tile_rect.end.y): p = geom.Point(i - tile_rect.start.x, j - tile_rect.start.y).scale(tile_size) tile_ims = load_func(region, i, j, mode=mode) for k, im in tile_ims.items(): scale = tile_size / im.shape[0] if k not in full_ims: full_ims[k] = numpy.zeros( (int(full_rect.lengths().x / scale), int(full_rect.lengths().y / scale), im.shape[2]), dtype='uint8') full_ims[k][int(p.x / scale):int((p.x + tile_size) / scale), int(p.y / scale):int((p.y + tile_size) / scale), :] = im crop_rect = geom.Rectangle(rect.start.sub(full_rect.start), rect.end.sub(full_rect.start)) for k in full_ims: scale = (full_rect.end.x - full_rect.start.x) / full_ims[k].shape[0] full_ims[k] = full_ims[k][int(crop_rect.start.x / scale):int(crop_rect.end.x / scale), int(crop_rect.start.y / scale):int(crop_rect.end.y / scale), :] return full_ims
def tile_filter(tile): # find starting points in different tiles if tile.region not in REGIONS: return False rect = geom.Rectangle(tile.scale(tile_size), tile.add(geom.Point(1, 1)).scale(tile_size)) starting_locations = self.all_starting_locations['{}_{}_{}'.format( tile.region, tile.x, tile.y)] starting_locations = [ loc for loc in starting_locations if rect.add_tol(-window_size).contains(loc[0]['point']) ] return len(starting_locations) > 0
def congruencyControl(self, event): newPoint = geometry.Point(event.x(), event.y()) for segment in self.parent.model.segments.values(): if segment.pointBelongs(newPoint): print(segment, 'belongs') if segment not in self.parent.select: if not self.parent.pointCoords: self.parent.pointCoords = [event.x(), event.y()] self.parent.select.append(segment) print(self.parent.select) self.parent.messageSend("Segment selected") else: self.parent.messageSend("Error")
def zip_frame_info(detections, label, frame_idx): if not detections: return [] frame_path = FRAME_PATH.format(label) im = skimage.io.imread('{}/{}'.format(frame_path, get_frame_fname(frame_idx))) im_bounds = geom.Rectangle(geom.Point(0, 0), geom.Point(im.shape[0], im.shape[1])) info = [] for idx, detection in enumerate(detections): rect = geom.Rectangle( geom.Point(detection['top'] // FRAME_SCALE, detection['left'] // FRAME_SCALE), geom.Point(detection['bottom'] // FRAME_SCALE, detection['right'] // FRAME_SCALE)) rect = im_bounds.clip_rect(rect) if rect.lengths().x < 4 or rect.lengths().y < 4: continue crop = im[rect.start.x:rect.end.x, rect.start.y:rect.end.y, :] resize_factor = min([ float(CROP_SIZE) / crop.shape[0], float(CROP_SIZE) / crop.shape[1] ]) resize_shape = [ int(crop.shape[0] * resize_factor), int(crop.shape[1] * resize_factor) ] if resize_shape[0] == 0 or resize_shape[1] == 0: continue crop = (skimage.transform.resize(crop, resize_shape) * 255).astype('uint8') fix_crop = numpy.zeros((CROP_SIZE, CROP_SIZE, 3), dtype='uint8') fix_crop[0:crop.shape[0], 0:crop.shape[1], :] = crop detection['width'] = float(detection['right'] - detection['left']) / ORIG_WIDTH detection['height'] = float(detection['bottom'] - detection['top']) / ORIG_HEIGHT info.append((detection, fix_crop, idx)) return info
def cut_curvelist2(curve_list, rapid_safety_space, current_start_depth, depth, clearance_height, keep_tool_down_if_poss, start_point): p = geom.Point(0, 0) start_x, start_y = start_point first = True for curve in curve_list: need_rapid = True if first == True: direction = "on" radius = 0.0 offset_extra = 0.0 roll_radius = 0.0 roll_on = 0.0 roll_off = 0.0 rapid_safety_space step_down = math.fabs(depth) extend_at_start = 0.0 extend_at_end = 0.0 kurve_funcs.make_smaller(curve, start=geom.Point(start_x, start_y)) kurve_funcs.profile(curve, direction, radius, offset_extra, roll_radius, roll_on, roll_off, rapid_safety_space, clearance_height, current_start_depth, step_down, depth, extend_at_start, extend_at_end) else: s = curve.FirstVertex().p if keep_tool_down_if_poss == True: # see if we can feed across if feed_possible(p, s): need_rapid = False elif s.x == p.x and s.y == p.y: need_rapid = False cut_curve(curve, need_rapid, p, rapid_safety_space, current_start_depth, depth) first = False #change to True if you want to rapid back to start side before zigging again with unidirectional set rapid(z=clearance_height)
def get_test_tile_data(self): if 'd' not in REGIONS: print("d is not in regions") return None rect = geom.Rectangle( geom.Point(-4096, -4096), geom.Point(4096, 4096), ) starting_locations = self.all_starting_locations['d_0_-1'] starting_locations = [ loc for loc in starting_locations if rect.add_tol(-window_size).contains(loc[0]['point']) ] return { 'region': 'd', 'rect': rect, 'search_rect': rect.add_tol(-window_size / 2), 'cache': self.cache, 'starting_locations': starting_locations, 'gc': self.gcs['d'], }
def Offset(self, leftwards_value): if self.v.type == 0: v = geom.Point(self.p, self.v.p) v.Normalize() vp = ~v self.p = self.p + vp * leftwards_value self.v.p = self.v.p + vp * leftwards_value else: vs = self.GetVector(0.0) ve = self.GetVector(1.0) vsp = ~vs vse = ~ve self.p = self.p + vsp * leftwards_value self.v.p = self.v.p + vse * leftwards_value