def load_item(self): from popupcad.filetypes.sketch import Sketch newitem = Sketch.open() if newitem is not None: self.items[newitem.id] = newitem self.refresh_list(newitem) self.items_updated.emit()
def new_method(self): from popupcad.guis.sketcher import Sketcher from popupcad.filetypes.sketch import Sketch def accept_method(sketch): self.design.sketches[sketch.id] = sketch self.refresh_list(sketch) self.items_updated.emit() sketcher = Sketcher(None, Sketch.new(), self.design, accept_method=accept_method, selectops=True) sketcher.show() sketcher.move_center() sketcher.graphicsview.zoomToFit()
def new_method(self): from popupcad.guis.sketcher import Sketcher from popupcad.filetypes.sketch import Sketch def accept_method(sketch): self.design.sketches[sketch.id] = sketch self.refresh_list(sketch) self.items_updated.emit() sketcher = Sketcher( None, Sketch.new(), self.design, accept_method=accept_method, selectops=True) sketcher.show() sketcher.move_center() sketcher.graphicsview.zoomToFit()
def load_item(self): from popupcad.filetypes.sketch import Sketch newitem = Sketch.open() self.items[newitem.id] = newitem self.refresh_list(newitem)
def operate(self, design): design_copy = design # design_copy.reprocessoperations() part_to_insert = design_copy.operations[design_copy.operation_index(self.part_opref)] sheet_to_insert_into = design_copy.operations[design_copy.operation_index(self.sheet_opref)] release_to_insert_into = design_copy.operations[design_copy.operation_index(self.release_opref)] # build the op_links, then auto make the operation op = part_to_insert op_ref = op.id op_links = {'parent': [(op_ref, op.getoutputref())]} new_web = AutoWeb4(op_links,[self.support_offset,0],MultiValueOperation3.keepout_types.laser_keepout) new_web.setcustomname(op.name) # support = OperationOutput(new_web.output[1], "support", self) design_copy.addoperation(new_web) new_web.generate(design_copy) ######################## generate the same size construction line somewhere in the sheet file # get geom for line parts_bounding_box = new_web.output[1].generic_laminate().getBoundingBox() # parts_bounding_box = support.generic_laminate().getBoundingBox() # make the sketch construction_geom_hinge = Sketch.new() tmp_geom = [(parts_bounding_box[0],parts_bounding_box[1]), (parts_bounding_box[0],parts_bounding_box[3])] construction_line = GenericLine.gen_from_point_lists(tmp_geom,[],construction=False) construction_geom_hinge.addoperationgeometries([construction_line]) # add sketch to sketch list design_copy.sketches[construction_geom_hinge.id] = construction_geom_hinge ######################## generate the external transform geometry in the sheet # center the locate line top left as origin position_hinge = (-tmp_geom[0][0],-tmp_geom[0][1]) locate_lines = [(x + position_hinge[0], y + position_hinge[1]) for (x,y) in tmp_geom] # lets make 4x4 width = (parts_bounding_box[2] - parts_bounding_box[0])*self.sc + self.x_gap height = (parts_bounding_box[3] - parts_bounding_box[1])*self.sc + self.y_gap # check if will all fit in one window, if not fill first and check if remainder will fit in second window max_num_cols = divmod(self.sketch_bounding_box[2] - self.sketch_bounding_box[0], width)[0] max_num_rows = divmod(self.sketch_bounding_box[3] - self.sketch_bounding_box[1], height)[0] if max_num_cols == 0 or max_num_rows == 0: print('Cannot tile into this area') design.remove_operation(new_web) return Laminate() # check if can fit in one # if N <= max_num_rows*max_num_cols: rows = math.ceil(self.N / max_num_cols) cols = math.ceil(self.N / rows) # spread across the two windows upper_right_origin_bounding_box = (self.sketch_bounding_box[0], self.sketch_bounding_box[3]) n_count = 0 arrayed_reference_lines = [] for row in range(rows): for col in range(cols): if n_count >= self.N or n_count >= max_num_rows*max_num_cols*2: break newx = upper_right_origin_bounding_box[0] + locate_lines[0][0] + col*width newy = upper_right_origin_bounding_box[1] - locate_lines[1][1] - row*height arrayed_reference_lines.append([(newx, newy), (newx, newy + height)]) n_count = n_count + 1 construction_geom_sheet = Sketch.new() construction_line = [GenericLine.gen_from_point_lists(line,[],construction=False) for line in arrayed_reference_lines] construction_geom_sheet.addoperationgeometries(construction_line) # add sketch to sketch list design_copy.sketches[construction_geom_sheet.id] = construction_geom_sheet ######################## External transform the hinge onto the sheet construction line # # insert hinge into sheet as subdesign # sheet.subdesigns[hinge.id] = hinge # # make design links operation_links = {} operation_links['from'] = [(part_to_insert.id,0)] sketch_links = {} sketch_links['sketch_to'] = [construction_geom_sheet.id] sketch_links['sketch_from'] = [construction_geom_hinge.id] insert_part = TransformInternal(sketch_links, operation_links, 'scale', 'scale', 0, False, 1., 1.) insert_part.customname = 'Inserted part' design_copy.addoperation(insert_part) insert_part.generate(design_copy) insert_part_id = design_copy.operations[-1].id # save for later ######################## External transform the web.sheet to the construction line # # make design links operation_links = {} operation_links['from'] = [(new_web.id,1)] sketch_links = {} sketch_links['sketch_to'] = [construction_geom_sheet.id] sketch_links['sketch_from'] = [construction_geom_hinge.id] insert_webs = TransformInternal(sketch_links, operation_links, 'scale', 'scale', 0, False, 1., 1.) insert_webs.customname = 'Inserted part webs' design_copy.addoperation(insert_webs) insert_webs.generate(design_copy) ######################## Remove web.sheet from sheet, union external transform + generateed sheet with hole + web # first the difference # link 1 is the sheet sheet_with_hole = LaminateOperation2({'unary': [(sheet_to_insert_into.id,0)], 'binary': [(insert_webs.id,0)]},'difference') sheet_with_hole.customname = 'Sheet with hole' design_copy.addoperation(sheet_with_hole) sheet_with_hole.generate(design_copy) sheet_with_part = LaminateOperation2({'unary': [(sheet_with_hole.id,0), (insert_part_id,0)], 'binary':[]},'union') sheet_with_part.customname = 'First pass cuts' design_copy.addoperation(sheet_with_part) sheet_with_part.generate(design_copy) # ######################## Make release cut laminate operation operation_links = {} operation_links['from'] = [(release_to_insert_into.id,0)] sketch_links = {} sketch_links['sketch_to'] = [construction_geom_sheet.id] sketch_links['sketch_from'] = [construction_geom_hinge.id] insert_release = TransformInternal(sketch_links, operation_links, 'scale', 'scale', 0, False, 1., 1.) design.addoperation(insert_release) insert_release.generate(design) ######################################### prepare outputs # delete the intermediate layers design.remove_operation(sheet_with_hole) design.remove_operation(insert_webs) design.remove_operation(insert_part) design.remove_operation(new_web) design.remove_operation(sheet_with_part) design.remove_operation(insert_release) self.output = [OperationOutput(sheet_with_part.output[0].csg, 'FirstCuts', self), OperationOutput(sheet_with_part.output[0].csg, 'FirstCuts', self), OperationOutput(insert_release.output[0].csg, 'Release', self)] return sheet_with_part.output[0].csg
sheet_links= {'unary': [], 'binary': []} first_cut_links= {'unary': [], 'binary': []} second_cut_links= {'unary': [], 'binary': []} ii = 0 while ii<5: points = numpy.random.rand(5,2)*20+[ii*20,0] body_polygon = popupcad.algorithms.triangulate.convex_hull(points) area,centroid,volume,mass,tris = body_polygon.mass_properties(1,-1,1,popupcad.SI_length_scaling) centroid = centroid[:2].tolist() # points = numpy.array(body_polygon.exteriorpoints()+[centroid]) body_triangles= popupcad.algorithms.triangulate.triangulate(points) generic_lines = popupcad.algorithms.getjoints.getjoints(body_triangles,5) body_sketch = Sketch() body_sketch.addoperationgeometries([body_polygon]) joints_sketch = Sketch() joints_sketch.addoperationgeometries(generic_lines) top_design.subdesigns[single_layer_joint_manufacturing.id] = single_layer_joint_manufacturing top_design.sketches[body_sketch.id] = body_sketch top_design.sketches[joints_sketch.id] = joints_sketch design_links = {} design_links['source'] = single_layer_joint_manufacturing.id sketch_list = [] sketch_list.append(popupcad.manufacturing.sub_operation2.SketchData(sub_body_sketch.id,body_sketch.id)) sketch_list.append(popupcad.manufacturing.sub_operation2.SketchData(sub_joint_sketch.id,joints_sketch.id)) input_list = []
sheet_links= {'unary': [], 'binary': []} first_cut_links= {'unary': [], 'binary': []} second_cut_links= {'unary': [], 'binary': []} ii = 0 while ii<5: points = numpy.random.rand(5,2)*20+[ii*20,0] body_polygon = popupcad.algorithms.triangulate.convex_hull(points) area,centroid,volume,mass,tris = body_polygon.mass_properties(1,-1,1,popupcad.SI_length_scaling) centroid = centroid[:2].tolist() # points = numpy.array(body_polygon.exteriorpoints()+[centroid]) body_triangles= popupcad.algorithms.triangulate.triangulate(points) generic_lines = popupcad.algorithms.getjoints.getjoints(body_triangles,5) body_sketch = Sketch.new() body_sketch.addoperationgeometries([body_polygon]) joints_sketch = Sketch.new() joints_sketch.addoperationgeometries(generic_lines) top_design.subdesigns[single_layer_joint_manufacturing.id] = single_layer_joint_manufacturing top_design.sketches[body_sketch.id] = body_sketch top_design.sketches[joints_sketch.id] = joints_sketch design_links = {} design_links['source'] = [single_layer_joint_manufacturing.id] sketch_list = [] sketch_list.append(popupcad.manufacturing.sub_operation2.SketchData(sub_body_sketch.id,body_sketch.id)) sketch_list.append(popupcad.manufacturing.sub_operation2.SketchData(sub_joint_sketch.id,joints_sketch.id)) input_list = []
self.add_constraint(constraints.FixedConstraint) def add_constraint_angle(self): self.add_constraint(constraints.AngleConstraint) def add_constraint_parallel(self): self.add_constraint(constraints.ParallelLinesConstraint) def add_constraint_perpendicular(self): self.add_constraint(constraints.PerpendicularLinesConstraint) def add_constraint_equal(self): self.add_constraint(constraints.EqualLengthLinesConstraint) def add_constraint_horizontal(self): self.add_constraint(constraints.HorizontalConstraint) def add_constraint_vertical(self): self.add_constraint(constraints.VerticalConstraint) def add_constraint_point_line_distance(self): self.add_constraint(constraints.PointLineDistanceConstraint) def add_constraint_line_midpoint(self): self.add_constraint(constraints.LineMidpointConstraint) if __name__ == "__main__": app = qg.QApplication(sys.argv) mw = Sketcher(None, Sketch.new()) mw.show() sys.exit(app.exec_())
def add_constraint_distance(self): self.add_constraint(constraints.DistanceConstraint) def add_constraint_x_distance(self): self.add_constraint(constraints.XDistanceConstraint) def add_constraint_y_distance(self): self.add_constraint(constraints.YDistanceConstraint) def add_constraint_fixed(self): self.add_constraint(constraints.FixedConstraint) def add_constraint_angle(self): self.add_constraint(constraints.AngleConstraint) def add_constraint_parallel(self): self.add_constraint(constraints.ParallelLinesConstraint) def add_constraint_perpendicular(self): self.add_constraint(constraints.PerpendicularLinesConstraint) def add_constraint_equal(self): self.add_constraint(constraints.EqualLengthLinesConstraint) def add_constraint_horizontal(self): self.add_constraint(constraints.HorizontalConstraint) def add_constraint_vertical(self): self.add_constraint(constraints.VerticalConstraint) def add_constraint_point_line_distance(self): self.add_constraint(constraints.PointLineDistanceConstraint) def add_constraint_line_midpoint(self): self.add_constraint(constraints.LineMidpointConstraint) if __name__ == "__main__": app = qg.QApplication(sys.argv) mw = Sketcher(None, Sketch.new()) mw.show() sys.exit(app.exec_())
second_cut_links = {'unary': [], 'binary': []} ii = 0 while ii < 5: points = numpy.random.rand(5, 2) * 20 + [ii * 20, 0] body_polygon = popupcad.algorithms.triangulate.convex_hull(points) area, centroid, volume, mass, tris = body_polygon.mass_properties( 1, -1, 1) centroid = centroid[:2].tolist() # points = numpy.array(body_polygon.exteriorpoints() + [centroid]) body_triangles = popupcad.algorithms.triangulate.triangulate(points) generic_lines = popupcad.algorithms.getjoints.getjoints( body_triangles, 5) body_sketch = Sketch.new() body_sketch.addoperationgeometries([body_polygon]) joints_sketch = Sketch.new() joints_sketch.addoperationgeometries(generic_lines) top_design.subdesigns[single_layer_joint_manufacturing. id] = single_layer_joint_manufacturing top_design.sketches[body_sketch.id] = body_sketch top_design.sketches[joints_sketch.id] = joints_sketch design_links = {} design_links['source'] = [single_layer_joint_manufacturing.id] sketch_list = [] sketch_list.append( popupcad.manufacturing.sub_operation2.SketchData( sub_body_sketch.id, body_sketch.id))
def operate(self, design): """ Return a generic_laminate ref of a layup laminate with all the layers of the part and with the appropriate 25x25mm alignment features compatible with the Wood lab micro-robotics manufacturing process. Input: Design -> a popupcad design file Output: layup -> A handle to the layup design file subop -> A subop which is inserted into the input design file to reduce the number of operations """ #### general geometry constants that most layups will have sheet_width = self.values[0] # mm hole_offset = self.values[1] # location of hole in from corner hole_rad = self.values[2] # alignment pin geoms cross_len = .75 # tick length cross_horiz = sheet_width/2 - 2*cross_len # horizontal dimension from center crosshair dt = 0.001 # small thickness for crosshair buff_x = 5 # for window sizes buff_y = 1 wind_h = 1 space_x = 1.3 # window width, maximum of 1 mm wind_w = lambda N: max(min((sheet_width - 2*buff_x)/(N + 1.3*N - 1.3), 1),0.01) # the laminate design layup = design # popupcad.filetypes.design.Design.new() layer_list = design.return_layer_definition().layers # initiate the sketches ############# sheet first sheet = Sketch.new() tmp_geom = [(-sheet_width/2., -sheet_width/2.), (-sheet_width/2., sheet_width/2.), ( sheet_width/2., sheet_width/2.), ( sheet_width/2., -sheet_width/2.)] sheet_poly = popupcad.filetypes.genericshapes.GenericPoly.gen_from_point_lists(tmp_geom,[]) sheet.addoperationgeometries([sheet_poly]) ############# holes second holes = Sketch.new() tmp_geom = [(-sheet_width/2. + hole_offset, -sheet_width/2. + hole_offset), (-sheet_width/2. + hole_offset, sheet_width/2. - hole_offset), ( sheet_width/2. - hole_offset, sheet_width/2. - hole_offset), ( sheet_width/2. - hole_offset, -sheet_width/2. + hole_offset)] # make list of hole geometry holes_poly = [popupcad.filetypes.genericshapes.GenericCircle.gen_from_point_lists([pt, (pt[0]+hole_rad, pt[1])],[]) for pt in tmp_geom] holes.addoperationgeometries(holes_poly) ############# upper triangle left_tri = Sketch.new() tmp_geom = [(-sheet_width/2. + hole_offset/4, sheet_width/2. - hole_offset*(2/3)), (-sheet_width/2. + hole_offset/4 + hole_rad, sheet_width/2. - hole_offset*(2/3)), (-sheet_width/2. + hole_offset/4 + 0.5*hole_rad, sheet_width/2. - hole_offset*(2/3) + 1.2*hole_rad*.75)] # make list of hole geometry sheet_poly = popupcad.filetypes.genericshapes.GenericPoly.gen_from_point_lists(tmp_geom,[]) left_tri.addoperationgeometries([sheet_poly]) ############# crosshairs cross_hairs = Sketch.new() tmp_geom_horiz = [(0,-cross_len), (0,cross_len)] tmp_geom_vert = [(-cross_len,0), (cross_len,0)] shift = [-cross_horiz, 0, cross_horiz] cross_poly_horiz = [popupcad.filetypes.genericshapes.GenericPoly.gen_from_point_lists([(tmp_geom_horiz[0][0] + c - dt/2., tmp_geom_horiz[0][1] - dt/2.), (tmp_geom_horiz[1][0] + c - dt/2., tmp_geom_horiz[1][1] - dt/2.), (tmp_geom_horiz[1][0] + c + dt/2., tmp_geom_horiz[1][1] + dt/2.), (tmp_geom_horiz[0][0] + c + dt/2., tmp_geom_horiz[0][1] - dt/2.)], []) for c in shift] cross_poly_vert = [popupcad.filetypes.genericshapes.GenericPoly.gen_from_point_lists([(tmp_geom_vert[0][0] + c - dt/2., tmp_geom_vert[0][1] - dt/2.), (tmp_geom_vert[1][0] + c - dt/2., tmp_geom_vert[1][1] + dt/2.), (tmp_geom_vert[1][0] + c + dt/2., tmp_geom_vert[1][1] + dt/2.), (tmp_geom_vert[0][0] + c + dt/2., tmp_geom_vert[0][1] - dt/2.)], []) for c in shift] cross_hairs.addoperationgeometries(cross_poly_horiz + cross_poly_vert) # Build the sheet with holes # Add the sketches to the sketch list layup.sketches[sheet.id] = sheet layup.sketches[holes.id] = holes layup.sketches[cross_hairs.id] = cross_hairs layup.sketches[left_tri.id] = left_tri # get the layer links for making sketch ops layer_links = [layer.id for layer in layer_list] holes_sketch = popupcad.manufacturing.simplesketchoperation.SimpleSketchOp({'sketch': [holes.id]},layer_links) holes_sketch .name = "Holes" trian_sketch = popupcad.manufacturing.simplesketchoperation.SimpleSketchOp({'sketch': [left_tri.id]},layer_links) trian_sketch .name = "Left triangle" sheet_sketch = popupcad.manufacturing.simplesketchoperation.SimpleSketchOp({'sketch': [sheet.id]},layer_links) sheet_sketch.name = "sheet" cross_sketch = popupcad.manufacturing.simplesketchoperation.SimpleSketchOp({'sketch': [cross_hairs.id]},layer_links) cross_sketch.name = "Crosshairs" # laminate operation to combine cross hairs and holes sheet_with_holes = popupcad.manufacturing.laminateoperation2.LaminateOperation2({'unary': [(sheet_sketch.id,0)], 'binary': [(holes_sketch.id,0), (cross_sketch.id,0), (trian_sketch.id,0)]}, 'difference') sheet_with_holes.name = "Sheet with holes" ############# rectangle windows windows = [Sketch.new() for _ in layer_list] windows_sketchop = [] # make windows, center on middle of sheet at bottom window_width = wind_w(len(windows)) window_coords = np.array([round(kk*(1 + space_x)*window_width,4) for kk in range(len(windows))]) window_coords = list(window_coords - np.mean(window_coords)) # center is 0 for kk, (layer, window, x_coord) in enumerate(zip(layer_list, windows, window_coords)): window.name = layer.name + '_window' tmp_geom = [(x_coord, -sheet_width/2. + buff_y), (x_coord, -sheet_width/2. + buff_y + wind_h), (x_coord + window_width, -sheet_width/2. + buff_y + wind_h), (x_coord + window_width, -sheet_width/2. + buff_y)] sheet_poly = popupcad.filetypes.genericshapes.GenericPoly.gen_from_point_lists(tmp_geom,[]) window.addoperationgeometries([sheet_poly]) layup.sketches[window.id] = window # make a sketch op on all layers above the current layer, this will be removed with a difference from the sheet windows_sketchop.append(popupcad.manufacturing.simplesketchoperation.SimpleSketchOp({'sketch': [window.id]}, layer_links[kk+1:])) windows_sketchop[-1].name = "Window_" + layer.name # laminate operation to remove windows from sheet with holes sheet_with_windows = popupcad.manufacturing.laminateoperation2.LaminateOperation2({'unary': [(sheet_with_holes.id,0)], 'binary': [(sktch.id,0) for sktch in windows_sketchop]}, 'difference') sheet_with_windows.name = "Final sheet" # add the sketch ops to the design and generate the sketch op other_ops = windows_sketchop + [trian_sketch, holes_sketch, sheet_sketch, cross_sketch, sheet_with_holes, sheet_with_windows] [layup.addoperation(item) for item in other_ops] [item.generate(layup) for item in other_ops] [layup.remove_operation(item) for item in other_ops] self.output = [OperationOutput(sheet_with_windows.output[0], "OutputLaminate", self)] return sheet_with_windows.output[0].csg
def operate(self, design): """ Return a generic_laminate ref of a layup laminate with all the layers of the part and with the appropriate 25x25mm alignment features compatible with the Wood lab micro-robotics manufacturing process. Input: Design -> a popupcad design file Output: layup -> A handle to the layup design file subop -> A subop which is inserted into the input design file to reduce the number of operations """ #### general geometry constants that most layups will have sheet_width = self.values[0] # mm hole_offset = self.values[1] # location of hole in from corner hole_rad = self.values[2] # alignment pin geoms cross_len = .75 # tick length cross_horiz = sheet_width / 2 - 2 * cross_len # horizontal dimension from center crosshair dt = 0.001 # small thickness for crosshair buff_x = 5 # for window sizes buff_y = 1 wind_h = 1 space_x = 1.3 # window width, maximum of 1 mm wind_w = lambda N: max( min((sheet_width - 2 * buff_x) / (N + 1.3 * N - 1.3), 1), 0.01) # the laminate design layup = design # popupcad.filetypes.design.Design.new() layer_list = design.return_layer_definition().layers # initiate the sketches ############# sheet first sheet = Sketch.new() tmp_geom = [(-sheet_width / 2., -sheet_width / 2.), (-sheet_width / 2., sheet_width / 2.), (sheet_width / 2., sheet_width / 2.), (sheet_width / 2., -sheet_width / 2.)] sheet_poly = popupcad.filetypes.genericshapes.GenericPoly.gen_from_point_lists( tmp_geom, []) sheet.addoperationgeometries([sheet_poly]) ############# holes second holes = Sketch.new() tmp_geom = [ (-sheet_width / 2. + hole_offset, -sheet_width / 2. + hole_offset), (-sheet_width / 2. + hole_offset, sheet_width / 2. - hole_offset), (sheet_width / 2. - hole_offset, sheet_width / 2. - hole_offset), (sheet_width / 2. - hole_offset, -sheet_width / 2. + hole_offset) ] # make list of hole geometry holes_poly = [ popupcad.filetypes.genericshapes.GenericCircle. gen_from_point_lists([pt, (pt[0] + hole_rad, pt[1])], []) for pt in tmp_geom ] holes.addoperationgeometries(holes_poly) ############# upper triangle left_tri = Sketch.new() tmp_geom = [ (-sheet_width / 2. + hole_offset / 4, sheet_width / 2. - hole_offset * (2 / 3)), (-sheet_width / 2. + hole_offset / 4 + hole_rad, sheet_width / 2. - hole_offset * (2 / 3)), (-sheet_width / 2. + hole_offset / 4 + 0.5 * hole_rad, sheet_width / 2. - hole_offset * (2 / 3) + 1.2 * hole_rad * .75) ] # make list of hole geometry sheet_poly = popupcad.filetypes.genericshapes.GenericPoly.gen_from_point_lists( tmp_geom, []) left_tri.addoperationgeometries([sheet_poly]) ############# crosshairs cross_hairs = Sketch.new() tmp_geom_horiz = [(0, -cross_len), (0, cross_len)] tmp_geom_vert = [(-cross_len, 0), (cross_len, 0)] shift = [-cross_horiz, 0, cross_horiz] cross_poly_horiz = [ popupcad.filetypes.genericshapes.GenericPoly.gen_from_point_lists( [(tmp_geom_horiz[0][0] + c - dt / 2., tmp_geom_horiz[0][1] - dt / 2.), (tmp_geom_horiz[1][0] + c - dt / 2., tmp_geom_horiz[1][1] - dt / 2.), (tmp_geom_horiz[1][0] + c + dt / 2., tmp_geom_horiz[1][1] + dt / 2.), (tmp_geom_horiz[0][0] + c + dt / 2., tmp_geom_horiz[0][1] - dt / 2.)], []) for c in shift ] cross_poly_vert = [ popupcad.filetypes.genericshapes.GenericPoly.gen_from_point_lists( [(tmp_geom_vert[0][0] + c - dt / 2., tmp_geom_vert[0][1] - dt / 2.), (tmp_geom_vert[1][0] + c - dt / 2., tmp_geom_vert[1][1] + dt / 2.), (tmp_geom_vert[1][0] + c + dt / 2., tmp_geom_vert[1][1] + dt / 2.), (tmp_geom_vert[0][0] + c + dt / 2., tmp_geom_vert[0][1] - dt / 2.)], []) for c in shift ] cross_hairs.addoperationgeometries(cross_poly_horiz + cross_poly_vert) # Build the sheet with holes # Add the sketches to the sketch list layup.sketches[sheet.id] = sheet layup.sketches[holes.id] = holes layup.sketches[cross_hairs.id] = cross_hairs layup.sketches[left_tri.id] = left_tri # get the layer links for making sketch ops layer_links = [layer.id for layer in layer_list] holes_sketch = popupcad.manufacturing.simplesketchoperation.SimpleSketchOp( {'sketch': [holes.id]}, layer_links) holes_sketch.name = "Holes" trian_sketch = popupcad.manufacturing.simplesketchoperation.SimpleSketchOp( {'sketch': [left_tri.id]}, layer_links) trian_sketch.name = "Left triangle" sheet_sketch = popupcad.manufacturing.simplesketchoperation.SimpleSketchOp( {'sketch': [sheet.id]}, layer_links) sheet_sketch.name = "sheet" cross_sketch = popupcad.manufacturing.simplesketchoperation.SimpleSketchOp( {'sketch': [cross_hairs.id]}, layer_links) cross_sketch.name = "Crosshairs" # laminate operation to combine cross hairs and holes sheet_with_holes = popupcad.manufacturing.laminateoperation2.LaminateOperation2( { 'unary': [(sheet_sketch.id, 0)], 'binary': [(holes_sketch.id, 0), (cross_sketch.id, 0), (trian_sketch.id, 0)] }, 'difference') sheet_with_holes.name = "Sheet with holes" ############# rectangle windows windows = [Sketch.new() for _ in layer_list] windows_sketchop = [] # make windows, center on middle of sheet at bottom window_width = wind_w(len(windows)) window_coords = np.array([ round(kk * (1 + space_x) * window_width, 4) for kk in range(len(windows)) ]) window_coords = list(window_coords - np.mean(window_coords)) # center is 0 for kk, (layer, window, x_coord) in enumerate(zip(layer_list, windows, window_coords)): window.name = layer.name + '_window' tmp_geom = [(x_coord, -sheet_width / 2. + buff_y), (x_coord, -sheet_width / 2. + buff_y + wind_h), (x_coord + window_width, -sheet_width / 2. + buff_y + wind_h), (x_coord + window_width, -sheet_width / 2. + buff_y)] sheet_poly = popupcad.filetypes.genericshapes.GenericPoly.gen_from_point_lists( tmp_geom, []) window.addoperationgeometries([sheet_poly]) layup.sketches[window.id] = window # make a sketch op on all layers above the current layer, this will be removed with a difference from the sheet windows_sketchop.append( popupcad.manufacturing.simplesketchoperation.SimpleSketchOp( {'sketch': [window.id]}, layer_links[kk + 1:])) windows_sketchop[-1].name = "Window_" + layer.name # laminate operation to remove windows from sheet with holes sheet_with_windows = popupcad.manufacturing.laminateoperation2.LaminateOperation2( { 'unary': [(sheet_with_holes.id, 0)], 'binary': [(sktch.id, 0) for sktch in windows_sketchop] }, 'difference') sheet_with_windows.name = "Final sheet" # add the sketch ops to the design and generate the sketch op other_ops = windows_sketchop + [ trian_sketch, holes_sketch, sheet_sketch, cross_sketch, sheet_with_holes, sheet_with_windows ] [layup.addoperation(item) for item in other_ops] [item.generate(layup) for item in other_ops] [layup.remove_operation(item) for item in other_ops] self.output = [ OperationOutput(sheet_with_windows.output[0], "OutputLaminate", self) ] return sheet_with_windows.output[0].csg