def operate(self, design): safe_buffer1 = self.buffer_val * popupcad.csg_processing_scaling safe_buffer2 = self.buffer_val * popupcad.csg_processing_scaling safe_buffer3 = self.buffer_val * popupcad.csg_processing_scaling parent_id, parent_output_index = self.operation_links['parent'][0] parent_index = design.operation_index(parent_id) parent = design.operations[parent_index].output[ parent_output_index].csg layerdef = design.return_layer_definition() allgeoms = [] allhingelines = [] buffered_splits = [] for joint_def in self.joint_defs: allgeoms4, buffered_split, hingelines = self.gen_geoms(joint_def, layerdef, design,self.buffer_val) allgeoms.extend(allgeoms4) allhingelines.extend(hingelines) buffered_splits.append(buffered_split) safe_sections = [] for ii in range(len(allgeoms)): unsafe = Laminate.unaryoperation(allgeoms[:ii] +allgeoms[ii +1:], 'union') unsafe_buffer = unsafe.buffer(safe_buffer1,resolution=self.resolution) safe_sections.append(allgeoms[ii].difference(unsafe_buffer)) safe = Laminate.unaryoperation(safe_sections, 'union') safe_buffer = safe.buffer(safe_buffer2, resolution=self.resolution) unsafe = Laminate.unaryoperation(allgeoms,'union').difference(safe_buffer) unsafe2 = unsafe.buffer(safe_buffer3, resolution=self.resolution) split1 = parent.difference(unsafe2) return split1
def find(generic_laminate): generic = generic_laminate.geoms layerdef = generic_laminate.layerdef from popupcad.filetypes.laminate import Laminate layer_dict = dict([(geom.id, layer) for layer, geoms in generic.items() for geom in geoms]) geom_dict = dict([(geom.id, geom) for layer, geoms in generic.items() for geom in geoms]) geom_dict_whole = geom_dict.copy() laminates = [] values = [] while len(geom_dict) > 0: laminate = Laminate(layerdef) key = list(geom_dict.keys())[0] gs = findallconnectedneighborgeoms(key, generic_laminate, geom_dict, layerdef) geom_mins = numpy.array( [find_minimum_xy(geom_dict_whole[geom_id]) for geom_id in gs]) values.append(tuple(geom_mins.min(0))) for item_id in gs: geom = geom_dict_whole[item_id] if geom.is_valid_bool(): laminate.insertlayergeoms(layer_dict[item_id], [geom.to_shapely()]) laminates.append(laminate) laminates = sort_lams(laminates, values) return laminates
def to_csg(self): from popupcad.filetypes.laminate import Laminate new = Laminate(self.layerdef) for ii, layer in enumerate(self.layerdef.layers): geoms = [item.to_shapely() for item in self.geoms[layer]] new.replacelayergeoms(layer, geoms) return new
def find(generic_laminate): generic = generic_laminate.geoms layerdef = generic_laminate.layerdef from popupcad.filetypes.laminate import Laminate layer_dict = dict([(geom.id, layer) for layer, geoms in generic.items() for geom in geoms]) geom_dict = dict([(geom.id, geom) for layer, geoms in generic.items() for geom in geoms]) geom_dict_whole = geom_dict.copy() laminates = [] values = [] while len(geom_dict) > 0: laminate = Laminate(layerdef) key = list(geom_dict.keys())[0] gs = findallconnectedneighborgeoms(key,generic_laminate,geom_dict,layerdef) geom_mins = numpy.array( [find_minimum_xy(geom_dict_whole[geom_id]) for geom_id in gs]) values.append(tuple(geom_mins.min(0))) for item_id in gs: geom = geom_dict_whole[item_id] if geom.is_valid_bool(): laminate.insertlayergeoms(layer_dict[item_id], [geom.to_shapely()]) laminates.append(laminate) laminates = sort_lams(laminates, values) return laminates
def operate(self,design): sketch = design.sketches[self.sketchid] operationgeom = customshapely.unary_union_safe([item.outputshapely() for item in sketch.operationgeometry]) lsout = Laminate(design.return_layer_definition()) for layer in design.return_layer_definition().layers: lsout.replacelayergeoms(layer,customshapely.multiinit(operationgeom)) return lsout
def operate(self,design): operation_link1,outputref = self.operation_links['parent'][0] ls1 = design.op_from_ref(operation_link1).output[outputref].csg lsout = Laminate(ls1.layerdef) layers = ls1.layerdef.layers step = 1 if self.flip: step=-1 if self.rotate: for layerout,layerin in zip(layers[self.shift:]+layers[:self.shift],layers[::step]): lsout.replacelayergeoms(layerout,ls1.layer_sequence[layerin].geoms) else: if self.shift > 0: outshift = self.shift inshift = 0 elif self.shift <0: outshift = 0 inshift = -self.shift else: outshift = 0 inshift = 0 for layerout,layerin in zip(layers[outshift:],layers[::step][inshift:]): lsout.replacelayergeoms(layerout,ls1.layer_sequence[layerin].geoms) return lsout
def operate(self, design): layerdef = design.return_layer_definition() csg = Laminate(layerdef) for layer in layerdef.layers: shapelygeoms = [geom.to_shapely() for geom in self.generic.geoms[layer] if geom.is_valid_bool()] csg.insertlayergeoms(layer, shapelygeoms) return csg
def shift_flip(ls1, shift, flip, rotate): from popupcad.filetypes.laminate import Laminate lsout = Laminate(ls1.layerdef) layers = ls1.layerdef.layers step = 1 if flip: step = -1 if rotate: for layerout, layerin in zip( layers[shift:] + layers[:shift], layers[::step]): lsout.replacelayergeoms( layerout, ls1.layer_sequence[layerin].geoms) else: if shift > 0: outshift = shift inshift = 0 elif shift < 0: outshift = 0 inshift = -shift else: outshift = 0 inshift = 0 for layerout, layerin in zip( layers[outshift:], layers[::step][inshift:]): lsout.replacelayergeoms(layerout,ls1.layer_sequence[layerin].geoms) return lsout
def transform_csg(layerdef_from, layerdef_to, inshift, outshift, step, geom_from, geoms_to, csg_laminate, scale_x, scale_y): from popupcad.filetypes.laminate import Laminate import shapely.affinity as aff from popupcad.algorithms.points import calctransformfrom2lines lsout = Laminate(layerdef_to) for layer_from, layer_to in zip(layerdef_from.layers[::step][inshift:], layerdef_to.layers[outshift:]): newgeoms = [] for geom in geoms_to: for designgeom in csg_laminate.layer_sequence[layer_from].geoms: try: from_line = geom_from.exteriorpoints( scaling=popupcad.csg_processing_scaling) to_line = geom.exteriorpoints( scaling=popupcad.csg_processing_scaling) transform = calctransformfrom2lines(from_line, to_line, scale_x=scale_x, scale_y=scale_y) transformed_geom = aff.affine_transform( designgeom, transform) newgeoms.append(transformed_geom) except IndexError: pass result1 = popupcad.algorithms.csg_shapely.unary_union_safe(newgeoms) results2 = popupcad.algorithms.csg_shapely.condition_shapely_entities( result1) lsout.replacelayergeoms(layer_to, results2) return lsout
def sketch_operation(sketch, layerdef, layers): from popupcad.filetypes.laminate import Laminate operationgeom = sketch.output_csg() laminate = Laminate(layerdef) for layer in layers: laminate.replacelayergeoms(layer, operationgeom) return laminate
def generate(self,design): import popupcad_manufacturing_plugins.algorithms.bodydetection as bodydetection generic = design.op_from_ref(self.operation_link1).output[self.getoutputref()].generic_geometry_2d() layerdef = design.return_layer_definition() layer_dict = dict([(geom.id,layer) for layer,geoms in generic.items() for geom in geoms]) geom_dict = dict([(geom.id,geom) for layer,geoms in generic.items() for geom in geoms]) geom_dict_whole = geom_dict.copy() laminates = [] values = [] layerdef = design.return_layer_definition() while len(geom_dict)>0: laminate = Laminate(layerdef) key = list(geom_dict.keys())[0] gs = bodydetection.findallconnectedneighborgeoms(key,generic,geom_dict,layerdef) geom_mins = numpy.array([find_minimum_xy(geom_dict_whole[geom_id]) for geom_id in gs]) values.append(tuple(geom_mins.min(0))) for item_id in gs: geom = geom_dict_whole[item_id] laminate.insertlayergeoms(layer_dict[item_id], [geom.outputshapely()]) laminates.append(laminate) laminates = sort_lams(laminates,values) self.output = [] for ii,item in enumerate(laminates): self.output.append(OperationOutput(item,'Body {0:d}'.format(ii),self)) self.output.insert(0,self.output[0])
def operate(self,design): operationgeom = design.sketches[self.sketch_links['sketch'][0]].output_csg() # operationgeom = popupcad.geometry.customshapely.multiinit(operationgeom) layers = [design.return_layer_definition().getlayer(item) for item in self.layer_links] laminate = Laminate(design.return_layer_definition()) for layer in layers: laminate.replacelayergeoms(layer,operationgeom) return laminate
def jointholes(sketch_result,layerdef): import popupcad import operator import math from popupcad.filetypes.laminate import Laminate generic = sketch_result.genericfromls() for key,value in generic.items(): if not not value: allgeoms = value hingelayer = key allpoints = [] for geom in allgeoms: allpoints.extend(geom.exteriorpoints()) allpoints.sort() commonpoints = [] for ii,point1 in enumerate(allpoints[1:-1]): point0 = allpoints[ii] point2 = allpoints[ii+2] a = popupcad.algorithms.points.twopointsthesame(point1,point2,1e-5) b = popupcad.algorithms.points.twopointsthesame(point0,point1,1e-5) if ii==0: if b: commonpoints.append(point1) elif a: commonpoints.append(point1) else: if (a and (not b)): commonpoints.append(point1) shapelys = [] for point in commonpoints: lineset = {} for item in allgeoms: points = numpy.array(item.exteriorpoints()) points -= point l = (points[:,0]**2+points[:,1]**2)**.5 test = l<1e-5 if True in test: ii = 1-test.nonzero()[0][0] lineset[item] = math.atan2(points[ii,1],points[ii,0]) q_s = sorted(lineset.items(),key = operator.itemgetter(1)) gaps = [item1[1]-item0[1] for item0,item1 in zip(q_s[:-1],q_s[1:])] + [2*math.pi+q_s[0][1]-q_s[-1][1]] min_gap = min(gaps) bufferval = 1.1/math.sin(min_gap/2) # print(gaps,min_gap,bufferval) shapely = popupcad.geometry.vertex.DrawnPoint(position = point).outputshapely() shapely = shapely.buffer(bufferval*popupcad.internal_argument_scaling) shapelys.append(shapely) shapelys = popupcad.geometry.customshapely.multiinit(*shapelys) # generics = [popupcad.geometry.vertex.DrawnPoint(position = point) for point in commonpoints] # shapelys = [item.outputshapely() for item in generics] # layer = Layer(shapelys) holes = Laminate(layerdef) holes.replacelayergeoms(hingelayer,shapelys) return holes,allgeoms,hingelayer
def operate(self, design): sketch = design.sketches[self.sketchid] operationgeom = popupcad.algorithms.csg_shapely.unary_union_safe( [item.to_shapely() for item in sketch.operationgeometry]) lsout = Laminate(design.return_layer_definition()) for layer in design.return_layer_definition().layers: lsout.replacelayergeoms( layer, popupcad.algorithms.csg_shapely.condition_shapely_entities(operationgeom)) return lsout
def operate(self, design): layerdef = design.return_layer_definition() csg = Laminate(layerdef) for layer in layerdef.layers: shapelygeoms = [ geom.to_shapely(scaling=popupcad.csg_processing_scaling) for geom in self.generic.geoms[layer] if geom.is_valid_bool() ] csg.insertlayergeoms(layer, shapelygeoms) return csg
def gen_geoms(self,joint_def,layerdef,design): hinge_gap = joint_def.width*popupcad.internal_argument_scaling # safe_buffer1 = .5*hinge_gap # safe_buffer2 = .5*hinge_gap # safe_buffer3 = .5*hinge_gap split_buffer = .1*hinge_gap stiffness = joint_def.stiffness damping = joint_def.damping preload_angle = joint_def.preload_angle sublaminate_layers = [layerdef.getlayer(item) for item in joint_def.sublaminate_layers] hingelayer = layerdef.getlayer(joint_def.joint_layer) operationgeom = design.sketches[joint_def.sketch].output_csg() sketch_result = Laminate(design.return_layer_definition()) sketch_result.replacelayergeoms(hingelayer,operationgeom) hingelines = sketch_result.genericfromls()[hingelayer] buffered_split= sketch_result.buffer(split_buffer,resolution = self.resolution) allgeoms4 = [] for geom in hingelines: geom = geom.outputshapely() laminate = Laminate(layerdef) for layer in sublaminate_layers: laminate.replacelayergeoms(layer,[geom]) allgeoms4.append(laminate.buffer(hinge_gap,resolution = self.resolution)) joint_props = [(stiffness,damping,preload_angle) for item in hingelines] return allgeoms4, buffered_split,hingelines,joint_props
def gen_geoms(self, joint_def, layerdef, design,split_buffer): print('Generating geometry') hinge_gap = joint_def.width *popupcad.csg_processing_scaling # split_buffer = .1 * hinge_gap sublaminate_layers = [ layerdef.getlayer(item) for item in joint_def.sublaminate_layers] hingelayer = layerdef.getlayer(joint_def.joint_layer) operationgeom = design.sketches[joint_def.sketch].output_csg() sketch_result = Laminate(design.return_layer_definition()) sketch_result.replacelayergeoms(hingelayer, operationgeom) hingelines = sketch_result.to_generic_laminate().geoms[hingelayer] hingelines = [item for item in hingelines if item.is_valid_bool()] buffered_split = sketch_result.buffer(split_buffer,resolution=self.resolution) allgeoms4 = [] for geom in hingelines: geom = geom.to_shapely() laminate = Laminate(layerdef) for layer in sublaminate_layers: laminate.replacelayergeoms(layer, [geom]) allgeoms4.append( laminate.buffer(hinge_gap,resolution=self.resolution)) return allgeoms4, buffered_split, hingelines
def operate(self,design): import shapely.affinity as aff subdesign = design.subdesigns[self.subdesignid] locateline = subdesign.findlocateline() try: designgeometry = subdesign.operations[subdesign.operation_index(self.subopid)].output[self.getoutputref()].csg except AttributeError: subdesign.reprocessoperations() designgeometry = subdesign.operations[subdesign.operation_index(self.subopid)].output[self.getoutputref()].csg sketch = design.sketches[self.sketchid] if self.transformtype==self.transformtypes.place: scale_x = 1. scale_y = 1. elif self.transformtype==self.transformtypes.stretch: scale_x = None scale_y = 1. if self.transformtype==self.transformtypes.scale: scale_x = None scale_y = None if self.transformtype==self.transformtypes.custom: scale_x = self.scalex scale_y = self.scaley lsout = Laminate(design.return_layer_definition()) step = 1 if self.flip: step = -1 if self.shift > 0: outshift = self.shift inshift = 0 elif self.shift <0: outshift = 0 inshift = -self.shift else: outshift = 0 inshift = 0 for layerout,layerin in zip(design.return_layer_definition().layers[outshift:],subdesign.return_layer_definition().layers[::step][inshift:]): newgeoms = [] for geom in sketch.operationgeometry: for designgeom in designgeometry.layer_sequence[layerin].geoms: try: newgeoms.append(aff.affine_transform(designgeom,calctransformfrom2lines(locateline.exteriorpoints(),geom.exteriorpoints(),scale_x = scale_x,scale_y = scale_y))) except IndexError: pass newgeoms = customshapely.unary_union_safe(newgeoms) newgeoms = popupcad.geometry.customshapely.multiinit(newgeoms) lsout.replacelayergeoms(layerout,newgeoms) return lsout
def operate(self, design): sketchid = self.sketch_links['sketch'][0] sketch = design.sketches[sketchid] operationgeom = popupcad.algorithms.csg_shapely.unary_union_safe( [item.to_shapely() for item in sketch.operationgeometry]) lsout = Laminate(design.return_layer_definition()) for layer in design.return_layer_definition().layers: lsout.replacelayergeoms( layer, popupcad.algorithms.csg_shapely.condition_shapely_entities( operationgeom)) return lsout
def generate(self,design): operationgeom = design.sketches[self.sketch_link].output_csg() layers = [design.return_layer_definition().getlayer(item) for item in self.layer_links] support = Laminate(design.return_layer_definition()) for layer in layers: support.replacelayergeoms(layer,operationgeom) device = design.op_from_ref(self.device_link).output[self.deviceoutputref].csg modified_device,supports,cuts = algorithms.modify_device.modify_device(device,support,self.support_width*popupcad.internal_argument_scaling,self.support_out*popupcad.internal_argument_scaling,self.hole_radius*popupcad.internal_argument_scaling,self.cut_width*popupcad.internal_argument_scaling) s = OperationOutput(supports,'supports',self) c = OperationOutput(cuts,'cuts',self) d = OperationOutput(modified_device,'device',self) self.output = [d,s,c]
def operate(self,design): operationgeom = design.sketches[self.sketchid].output_csg() layers = [design.return_layer_definition().getlayer(item) for item in self.layer_links] try: laminate1 = design.op_from_ref(self.operation_link1).output[self.getoutputref()].csg except NoOperation: laminate1 = Laminate(design.return_layer_definition()) laminate2 = Laminate(design.return_layer_definition()) for layer in layers: laminate2.replacelayergeoms(layer,operationgeom) lsout = laminate1.binaryoperation(laminate2,self.function) return lsout
def cross_section(layerdef, sketch, parent, scale_value): from popupcad.filetypes.laminate import Laminate from popupcad.filetypes.genericshapes import GenericLine import shapely.affinity as aff import popupcad.algorithms.points as points import shapely.geometry as sg import numpy laminate = Laminate(layerdef) for item in sketch.operationgeometry: if isinstance(item, GenericLine): line = item b = line.exteriorpoints(scaling=popupcad.csg_processing_scaling)[0] c = numpy.array(b) + numpy.array([1, 0]) a = points.calctransformfrom2lines( line.exteriorpoints(scaling=popupcad.csg_processing_scaling), [b, c.tolist()], scale_x=1, scale_y=1) sketch_csg = sketch.output_csg() for layer in layerdef.layers: laminate.replacelayergeoms(layer, sketch_csg) result = parent.intersection(laminate) laminate2 = Laminate(layerdef) for ii, layerid in enumerate(layerdef.layers): yshift = layerdef.z_values[ layerid] * popupcad.csg_processing_scaling * scale_value layer = result.layer_sequence[layerid] thickness = layerid.thickness * popupcad.csg_processing_scaling * scale_value newgeoms = [item for item in layer.geoms] newgeoms = [aff.affine_transform(item, a) for item in newgeoms] newgeoms2 = [] for geom in newgeoms: newgeom = sg.box(geom.coords[0][0], geom.coords[0][1], geom.coords[-1][0], geom.coords[-1][1] + thickness) newgeoms2.append(newgeom) newgeoms = newgeoms2 newgeoms = [ aff.translate(item, yoff=yshift) for item in newgeoms ] newgeoms = popupcad.algorithms.csg_shapely.condition_shapely_entities( *newgeoms) laminate2[ii] = newgeoms return laminate2 return laminate
def millkeepout(laminatein): '''calculate the keepout for an input laminate assuming milling''' l = Layer([]) laminateout = Laminate(laminatein.layerdef) for ii, geoms in enumerate(laminatein[::-1]): l = l.union(geoms) laminateout[-1 - ii] = l return laminateout
def operate(self,design): from popupcad.filetypes.genericshapes import GenericLine import shapely.affinity as aff import popupcad.algorithms.points as points import popupcad import shapely.geometry as sg import numpy parent_ref,parent_index = self.operation_links['source'][0] parent = design.op_from_ref(parent_ref).output[parent_index].csg sketch = design.sketches[self.sketch_links['cross_section'][0]] layerdef = design.return_layer_definition() laminate = Laminate(layerdef) for item in sketch.operationgeometry: if isinstance(item,GenericLine): line = item b = line.exteriorpoints()[0] c = numpy.array(b)+numpy.array([1,0]) a = points.calctransformfrom2lines(line.exteriorpoints(),[b,c.tolist()],scale_x=1,scale_y=1) sketch_csg = sketch.output_csg() for layer in layerdef.layers: laminate.replacelayergeoms(layer,sketch_csg) result = parent.intersection(laminate) laminate2 = Laminate(layerdef) for ii,layerid in enumerate(layerdef.layers): # for ii,layer in enumerate(result): yshift = layerdef.zvalue[layerid] * self.scale_value layer = result.layer_sequence[layerid] thickness = layerid.thickness*popupcad.internal_argument_scaling*self.scale_value newgeoms = [item for item in layer.geoms] newgeoms = [aff.affine_transform(item,a) for item in newgeoms] # newgeoms = [item.buffer(bufferval) for item in newgeoms] newgeoms2 = [] for geom in newgeoms: newgeom = sg.box(geom.coords[0][0],geom.coords[0][1],geom.coords[-1][0],geom.coords[-1][1]+thickness) newgeoms2.append(newgeom) newgeoms = newgeoms2 newgeoms = [aff.translate(item,yoff = yshift) for item in newgeoms] newgeoms = popupcad.geometry.customshapely.multiinit(*newgeoms) laminate2[ii] = newgeoms return laminate2 return laminate
def one_way_up(laminatein): l = Layer([]) laminateout = Laminate(laminatein.layerdef) for ii, geoms in enumerate(laminatein): l = l.union(geoms) laminateout[ii] = l laminateout = modify_up(laminateout) return laminateout
def operate(self,design): if len(self.operation_links1)>0: laminates1 = [design.op_from_ref(link).output[ii].csg for link,ii in self.operation_links1] else: laminates1 = [Laminate(design.return_layer_definition())] if len(self.operation_links2)>0: laminates2 = [design.op_from_ref(link).output[ii].csg for link,ii in self.operation_links2] else: laminates2 = [Laminate(design.return_layer_definition())] if self.function in self.unaryoperationtypes: return Laminate.unaryoperation(laminates1,self.function) elif self.function in self.pairoperationtypes: laminate1 = Laminate.unaryoperation(laminates1,'union') laminate2 = Laminate.unaryoperation(laminates2,'union') return laminate1.binaryoperation(laminate2,self.function)
def supportsheet(layerdef,lsin,value): allext = [] for layer,layer_geometry in lsin.layer_sequence.items(): for geom in layer_geometry.geoms: geom2 = GenericShapeBase.genfromshapely(geom) allext.extend(geom2.exteriorpoints()) allext = numpy.array(allext) minx = allext[:,0].min()-value miny = allext[:,1].min()-value maxx = allext[:,0].max()+value maxy = allext[:,1].max()+value exterior = [[minx,miny],[maxx,miny],[maxx,maxy],[minx,maxy]] geom = GenericShapeBase.gengenericpoly(exterior,[]) geom = geom.outputshapely() ls = Laminate(layerdef) [ls.replacelayergeoms(layer,[geom]) for layer in layerdef.layers] return ls,exterior[0]
def cross_section(layerdef, sketch, parent, scale_value): from popupcad.filetypes.laminate import Laminate from popupcad.filetypes.genericshapes import GenericLine import shapely.affinity as aff import popupcad.algorithms.points as points import shapely.geometry as sg import numpy laminate = Laminate(layerdef) for item in sketch.operationgeometry: if isinstance(item, GenericLine): line = item b = line.exteriorpoints(scaling = popupcad.csg_processing_scaling)[0] c = numpy.array(b) + numpy.array([1, 0]) a = points.calctransformfrom2lines( line.exteriorpoints(scaling = popupcad.csg_processing_scaling), [ b, c.tolist()], scale_x=1, scale_y=1) sketch_csg = sketch.output_csg() for layer in layerdef.layers: laminate.replacelayergeoms(layer, sketch_csg) result = parent.intersection(laminate) laminate2 = Laminate(layerdef) for ii, layerid in enumerate(layerdef.layers): # for ii,layer in enumerate(result): yshift = layerdef.zvalue[layerid] * popupcad.csg_processing_scaling * scale_value layer = result.layer_sequence[layerid] thickness = layerid.thickness * popupcad.csg_processing_scaling * scale_value newgeoms = [item for item in layer.geoms] newgeoms = [aff.affine_transform(item, a) for item in newgeoms] # newgeoms = [item.buffer(bufferval) for item in newgeoms] newgeoms2 = [] for geom in newgeoms: newgeom = sg.box(geom.coords[0][0], geom.coords[0][1], geom.coords[-1][0], geom.coords[-1][1] + thickness) newgeoms2.append(newgeom) newgeoms = newgeoms2 newgeoms = [aff.translate(item,yoff=yshift) for item in newgeoms] newgeoms = popupcad.algorithms.csg_shapely.condition_shapely_entities(*newgeoms) laminate2[ii] = newgeoms return laminate2 return laminate
def to_foldable_robotics(self, scaling=1): from foldable_robotics.laminate import Laminate from foldable_robotics.layer import Layer layers = [] for layer in self.layers(): geoms = [item.to_shapely(scaling) for item in self.geoms[layer]] layers.append(Layer(*geoms)) lam = Laminate(*layers) return lam
def supportsheet(layerdef, lsin, value): allext = [] for layer, layer_geometry in lsin.layer_sequence.items(): for geom in layer_geometry.geoms: geom2 = popupcad.algorithms.csg_shapely.to_generic(geom) allext.extend(geom2.exteriorpoints(scaling = popupcad.csg_processing_scaling)) allext = numpy.array(allext) minx = allext[:, 0].min() - value miny = allext[:, 1].min() - value maxx = allext[:, 0].max() + value maxy = allext[:, 1].max() + value exterior = [[minx, miny], [maxx, miny], [maxx, maxy], [minx, maxy]] exterior_scaled = (numpy.array(exterior)/popupcad.csg_processing_scaling).tolist() geom = GenericPoly.gen_from_point_lists(exterior_scaled, []) geom = geom.to_shapely() ls = Laminate(layerdef) [ls.replacelayergeoms(layer, [geom]) for layer in layerdef.layers] return ls, exterior[0]
def transform( layerdef, layerdef_subdesign, inshift, outshift, step, sketch, designgeometry, locateline, scale_x, scale_y): from popupcad.filetypes.laminate import Laminate import shapely.affinity as aff from popupcad.algorithms.points import calctransformfrom2lines lsout = Laminate(layerdef) for layerout, layerin in zip( layerdef.layers[ outshift:], layerdef_subdesign.layers[ ::step][ inshift:]): newgeoms = [] for geom in sketch.operationgeometry: if not geom.is_construction(): for designgeom in designgeometry.layer_sequence[layerin].geoms: try: newgeoms.append( aff.affine_transform( designgeom, calctransformfrom2lines( locateline.exteriorpoints(scaling = popupcad.csg_processing_scaling), geom.exteriorpoints(scaling = popupcad.csg_processing_scaling), scale_x=scale_x, scale_y=scale_y))) except IndexError: pass result1 = popupcad.algorithms.csg_shapely.unary_union_safe(newgeoms) results2 = popupcad.algorithms.csg_shapely.condition_shapely_entities(result1) lsout.replacelayergeoms(layerout, results2) return lsout
def supportsheet(layerdef, lsin, value): allext = [] for layer, layer_geometry in lsin.layer_sequence.items(): for geom in layer_geometry.geoms: geom2 = popupcad.algorithms.csg_shapely.to_generic(geom) allext.extend( geom2.exteriorpoints(scaling=popupcad.csg_processing_scaling)) allext = numpy.array(allext) minx = allext[:, 0].min() - value miny = allext[:, 1].min() - value maxx = allext[:, 0].max() + value maxy = allext[:, 1].max() + value exterior = [[minx, miny], [maxx, miny], [maxx, maxy], [minx, maxy]] exterior_scaled = (numpy.array(exterior) / popupcad.csg_processing_scaling).tolist() geom = GenericPoly.gen_from_point_lists(exterior_scaled, []) geom = geom.to_shapely(scaling=popupcad.csg_processing_scaling) ls = Laminate(layerdef) [ls.replacelayergeoms(layer, [geom]) for layer in layerdef.layers] return ls, exterior[0]
def generate(self, design): devicelink, outputindex = self.operation_links['device'][0] sketch = design.sketches[self.sketch_links['sketch'][0]] operationgeom = sketch.output_csg() layers = [design.return_layer_definition().getlayer(item) for item in self.layer_links] support = Laminate(design.return_layer_definition()) for layer in layers: support.replacelayergeoms(layer, operationgeom) device = design.op_from_ref(devicelink).output[outputindex].csg modified_device, supports, cuts = algorithms.modify_device.modify_device(device, support, self.support_width * popupcad.csg_processing_scaling, self.support_out * popupcad.csg_processing_scaling, self.hole_radius * popupcad.csg_processing_scaling, self.cut_width * popupcad.csg_processing_scaling) s = OperationOutput(supports, 'supports', self) c = OperationOutput(cuts, 'cuts', self) d = OperationOutput(modified_device, 'device', self) self.output = [d, s, c]
def shift_flip_rotate(ls1, shift, flip, rotate): from popupcad.filetypes.laminate import Laminate lsout = Laminate(ls1.layerdef) layers = ls1.layerdef.layers step = 1 if flip: step = -1 if rotate: for layerout, layerin in zip( layers[shift:] + layers[:shift], layers[::step]): lsout.replacelayergeoms( layerout, ls1.layer_sequence[layerin].geoms) else: if shift > 0: outshift = shift inshift = 0 elif shift < 0: outshift = 0 inshift = -shift else: outshift = 0 inshift = 0 for layerout, layerin in zip(layers[outshift:], layers[::step][inshift:]): lsout.replacelayergeoms(layerout,ls1.layer_sequence[layerin].geoms) return lsout
def operate(self, design): if len(self.operation_links['unary']) > 0: laminates1 = [ design.op_from_ref(link).output[ii].csg for link, ii in self.operation_links['unary'] ] else: laminates1 = [Laminate(design.return_layer_definition())] if len(self.operation_links['binary']) > 0: laminates2 = [ design.op_from_ref(link).output[ii].csg for link, ii in self.operation_links['binary'] ] else: laminates2 = [Laminate(design.return_layer_definition())] if self.function in self.unaryoperationtypes: return Laminate.unaryoperation(laminates1, self.function) elif self.function in self.pairoperationtypes: laminate1 = Laminate.unaryoperation(laminates1, 'union') laminate2 = Laminate.unaryoperation(laminates2, 'union') return laminate1.binaryoperation(laminate2, self.function)
def operate(self, design): safe_buffer1 = self.buffer_val * popupcad.csg_processing_scaling safe_buffer2 = self.buffer_val * popupcad.csg_processing_scaling safe_buffer3 = self.buffer_val * popupcad.csg_processing_scaling parent_id, parent_output_index = self.operation_links['parent'][0] parent_index = design.operation_index(parent_id) parent = design.operations[parent_index].output[ parent_output_index].csg layerdef = design.return_layer_definition() allgeoms = [] allhingelines = [] buffered_splits = [] for joint_def in self.joint_defs: allgeoms4, buffered_split, hingelines = self.gen_geoms( joint_def, layerdef, design, self.buffer_val) allgeoms.extend(allgeoms4) allhingelines.extend(hingelines) buffered_splits.append(buffered_split) safe_sections = [] for ii in range(len(allgeoms)): unsafe = Laminate.unaryoperation(allgeoms[:ii] + allgeoms[ii + 1:], 'union') unsafe_buffer = unsafe.buffer(safe_buffer1, resolution=self.resolution) safe_sections.append(allgeoms[ii].difference(unsafe_buffer)) safe = Laminate.unaryoperation(safe_sections, 'union') safe_buffer = safe.buffer(safe_buffer2, resolution=self.resolution) unsafe = Laminate.unaryoperation(allgeoms, 'union').difference(safe_buffer) unsafe2 = unsafe.buffer(safe_buffer3, resolution=self.resolution) split1 = parent.difference(unsafe2) return split1
def find_outer(ls, minpoint): import popupcad.algorithms.points as points lsouter = Laminate(ls.layerdef) lsinner = Laminate(ls.layerdef) for layer, layer_geometry in ls.layer_sequence.items(): outergeoms = [] innergeoms = [] for geom in layer_geometry.geoms: if points.pointinpoints( minpoint, popupcad.algorithms.csg_shapely.to_generic(geom). exteriorpoints(scaling=popupcad.csg_processing_scaling), popupcad.distinguishable_number_difference): outergeoms.append(geom) else: innergeoms.append(geom) lsouter.replacelayergeoms(layer, outergeoms) lsinner.replacelayergeoms(layer, innergeoms) return lsouter, lsinner
def find_outer(ls,minpoint): import popupcad.algorithms.points as points lsouter = Laminate(ls.layerdef) lsinner = Laminate(ls.layerdef) for layer,layer_geometry in ls.layer_sequence.items(): outergeoms = [] innergeoms = [] for geom in layer_geometry.geoms: if points.pointinpoints(minpoint,GenericShapeBase.genfromshapely(geom).exteriorpoints(),GenericShapeBase.tolerance): outergeoms.append(geom) else: innergeoms.append(geom) lsouter.replacelayergeoms(layer,outergeoms) lsinner.replacelayergeoms(layer,innergeoms) return lsouter,lsinner
def find_outer(ls, minpoint): import popupcad.algorithms.points as points lsouter = Laminate(ls.layerdef) lsinner = Laminate(ls.layerdef) for layer, layer_geometry in ls.layer_sequence.items(): outergeoms = [] innergeoms = [] for geom in layer_geometry.geoms: if points.pointinpoints( minpoint, popupcad.algorithms.csg_shapely.to_generic(geom).exteriorpoints(scaling = popupcad.csg_processing_scaling), popupcad.distinguishable_number_difference): outergeoms.append(geom) else: innergeoms.append(geom) lsouter.replacelayergeoms(layer, outergeoms) lsinner.replacelayergeoms(layer, innergeoms) return lsouter, lsinner
def find_rigid(generic, layerdef): csg1 = generic.to_csg() laminate_results = [] for ii,layer in enumerate(layerdef.layers): if layer.is_rigid: rigid_layer_csg = csg1.layer_sequence[layer] laminate_result = Laminate(layerdef) laminate_result.replacelayergeoms(layer,rigid_layer_csg.geoms) lower_layers = layerdef.layers[ii::-1] upper_layers = layerdef.layers[ii:] for list1 in [lower_layers,upper_layers]: a = list1[:-1] b = list1[1:] c = zip(a,b) for aa,bb in c: if aa.is_adhesive or bb.is_adhesive: if bb.is_rigid: break csga = laminate_result.layer_sequence[aa] csgb = csg1.layer_sequence[bb] layer_result = csga.intersection(csgb) laminate_result.replacelayergeoms(bb,layer_result.geoms) else: break laminate_results.append(laminate_result) laminate_results = [item for item in laminate_results if not item.isEmpty()] result = Laminate.unaryoperation(laminate_results,'union') return result
def promote(self, layerdef): from popupcad.filetypes.laminate import Laminate lsout = Laminate(layerdef) for layer in layerdef.layers: lsout.replacelayergeoms(layer, self.geoms) return lsout
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
def generate(self, design): safe_buffer1 = .5 *popupcad.csg_processing_scaling safe_buffer2 = .5 *popupcad.csg_processing_scaling safe_buffer3 = .5 *popupcad.csg_processing_scaling parent_id, parent_output_index = self.operation_links['parent'][0] parent_index = design.operation_index(parent_id) parent = design.operations[parent_index].output[ parent_output_index].csg fixed_id, fixed_output_index = self.operation_links['fixed'][0] fixed_index = design.operation_index(fixed_id) fixed = design.operations[fixed_index].output[fixed_output_index].csg layerdef = design.return_layer_definition() allgeoms = [] allhingelines = [] buffered_splits = [] all_joint_props = {} for joint_def in self.joint_defs: allgeoms4, buffered_split, hingelines, joint_props = self.gen_geoms( joint_def, layerdef, design) allgeoms.extend(allgeoms4) allhingelines.extend(hingelines) buffered_splits.append(buffered_split) for jointline,jointprop in zip(hingelines,joint_props): all_joint_props[jointline]=jointprop #allhingelines, buffered_splits = zip(*sorted(zip(allhingelines, allgeoms, buffered_splits))) #allhingelines = list(allhingelines) #allgeoms = list(allgeoms) #buffered_splits = list(buffered_splits) safe_sections = [] for ii in range(len(allgeoms)): unsafe = Laminate.unaryoperation( allgeoms[ :ii] + allgeoms[ ii + 1:], 'union') unsafe_buffer = unsafe.buffer( safe_buffer1, resolution=self.resolution) safe_sections.append(allgeoms[ii].difference(unsafe_buffer)) safe = Laminate.unaryoperation(safe_sections, 'union') buffered_splits2 = Laminate.unaryoperation(buffered_splits, 'union') safe_buffer = safe.buffer(safe_buffer2, resolution=self.resolution) unsafe = Laminate.unaryoperation( allgeoms, 'union').difference(safe_buffer) unsafe2 = unsafe.buffer(safe_buffer3, resolution=self.resolution) split1 = parent.difference(unsafe2) split2 = split1.difference(buffered_splits2) bodies = popupcad.algorithms.body_detection.find( split2.to_generic_laminate()) bodies_generic = [item.to_generic_laminate() for item in bodies] connections = {} connections2 = {} for line, geom in zip(allhingelines, safe_sections): connections[line] = [] connections2[line] = [] for body, body_generic in zip(bodies, bodies_generic): if not geom.intersection(body).isEmpty(): connections[line].append(body_generic) connections2[line].append(body) for line, geoms in connections2.items(): connections2[line] = Laminate.unaryoperation(geoms, 'union') self.fixed_bodies = [] fixed_csg = [] for body, body_generic in zip(bodies, bodies_generic): if not fixed.intersection(body).isEmpty(): self.fixed_bodies.append(body_generic) fixed_csg.append(body) self.bodies_generic = bodies_generic allhingelines.sort() #Sort here to prevent interfering with geometry. We only care about order of the joint props self.connections = sorted([(key, connections[key]) for key in allhingelines if len(connections[key]) == 2]) self.all_joint_props = [all_joint_props[key] for key in allhingelines if len(connections[key]) == 2] self.output = [] self.output.append(OperationOutput(safe,'Safe',self)) self.output.append(OperationOutput(unsafe,'Unsafe',self)) self.output.append(OperationOutput(split1,'Split1',self)) self.output.append(OperationOutput(split2,'Split2',self)) #TODO Change output to match the names that get exported to Gazebo self.output.extend([OperationOutput(item,'Fixed {0:d}'.format(ii),self) for ii,item in enumerate(fixed_csg)]) self.output.extend([OperationOutput(item,'Body {0:d}'.format(ii),self) for ii,item in enumerate(bodies)]) self.output.extend([OperationOutput(item,'Connection {0:d}'.format(ii),self) for ii,item in enumerate(connections2.values())]) self.output.insert(0, self.output[3])
def operate(self, design): laminate = Laminate(design.return_layer_definition()) return laminate
def generate(self, design): layerdef = design.return_layer_definition() sublaminate_layers = layerdef.layers sketch_result = self.operate(design) hingelayer = layerdef.getlayer(self.layer_links[0]) hingelines = sketch_result.to_generic_laminate().geoms[hingelayer] hingelayer_ii = layerdef.getlayer_ii(self.layer_links[0]) safe_sections = [] allgeoms2 = [geom.to_shapely() for geom in hingelines] allgeoms3 = [Laminate(layerdef) for item in allgeoms2] allgeoms4 = [] for laminate, geom in zip(allgeoms3, allgeoms2): laminate[hingelayer_ii] = [geom] allgeoms4.append( laminate.buffer( self.hinge_gap, resolution=self.resolution)) for ii, lam in enumerate(allgeoms4): unsafe = Laminate.unaryoperation( allgeoms4[ :ii] + allgeoms4[ ii + 1:], 'union') safe_sections.append( lam.difference( unsafe.buffer( self.safe_buffer1, resolution=self.resolution))) safe = Laminate.unaryoperation(safe_sections, 'union') unsafe = Laminate.unaryoperation( allgeoms4, 'union').difference( safe.buffer( self.safe_buffer2, resolution=self.resolution)) unsafe2 = unsafe.unarylayeroperation( 'union', [hingelayer], sublaminate_layers).buffer( self.safe_buffer3, resolution=self.resolution) buffered2 = sketch_result.buffer( self.split_buffer, resolution=self.resolution) self_index = design.operation_index(self.id) last = design.operations[self_index - 1].output[0].csg split1 = last.difference(unsafe2) split2 = split1.difference(buffered2) bodies = popupcad.algorithms.body_detection.find( split2.to_generic_laminate()) bodies_generic = [item.to_generic_laminate() for item in bodies] connections = {} connections2 = {} for line, geom in zip(hingelines, safe_sections): connections[line] = [] connections2[line] = [] for body, body_generic in zip(bodies, bodies_generic): if not geom.intersection(body).isEmpty(): connections[line].append(body_generic) connections2[line].append(body) for line, geoms in connections2.items(): connections2[line] = Laminate.unaryoperation(geoms, 'union') self.connections = [(key, connections[key]) for key in hingelines] laminates = [sketch_result, safe, unsafe2, split1, split2] + bodies + list(connections2.values()) self.output = [] for ii, item in enumerate(laminates): self.output.append( OperationOutput( item, 'Body {0:d}'.format(ii), self)) self.output.insert(0, self.output[0])
def gen_geoms(self, joint_def, layerdef, design, split_buffer): print('Generating geometry') hinge_gap = joint_def.width * popupcad.csg_processing_scaling # split_buffer = .1 * hinge_gap sublaminate_layers = [ layerdef.getlayer(item) for item in joint_def.sublaminate_layers ] hingelayer = layerdef.getlayer(joint_def.joint_layer) operationgeom = design.sketches[joint_def.sketch].output_csg() sketch_result = Laminate(design.return_layer_definition()) sketch_result.replacelayergeoms(hingelayer, operationgeom) hingelines = sketch_result.to_generic_laminate().geoms[hingelayer] hingelines = [item for item in hingelines if item.is_valid_bool()] buffered_split = sketch_result.buffer(split_buffer, resolution=self.resolution) allgeoms4 = [] for geom in hingelines: geom = geom.to_shapely(scaling=popupcad.csg_processing_scaling) laminate = Laminate(layerdef) for layer in sublaminate_layers: laminate.replacelayergeoms(layer, [geom]) allgeoms4.append( laminate.buffer(hinge_gap, resolution=self.resolution)) return allgeoms4, buffered_split, hingelines
def generate(self, design): safe_buffer1 = .5 *popupcad.csg_processing_scaling safe_buffer2 = .5 *popupcad.csg_processing_scaling safe_buffer3 = .5 *popupcad.csg_processing_scaling parent_id, parent_output_index = self.operation_links['parent'][0] parent_index = design.operation_index(parent_id) parent = design.operations[parent_index].output[ parent_output_index].csg fixed_id, fixed_output_index = self.operation_links['fixed'][0] fixed_index = design.operation_index(fixed_id) fixed = design.operations[fixed_index].output[fixed_output_index].csg layerdef = design.return_layer_definition() allgeoms = [] allhingelines = [] buffered_splits = [] all_joint_props = {} for joint_def in self.joint_defs: allgeoms4, buffered_split, hingelines, joint_props = self.gen_geoms( joint_def, layerdef, design) allgeoms.extend(allgeoms4) allhingelines.extend(hingelines) buffered_splits.append(buffered_split) for jointline,jointprop in zip(hingelines,joint_props): all_joint_props[jointline]=jointprop #allhingelines, buffered_splits = zip(*sorted(zip(allhingelines, allgeoms, buffered_splits))) #allhingelines = list(allhingelines) #allgeoms = list(allgeoms) #buffered_splits = list(buffered_splits) safe_sections = [] if len(allgeoms)>1: for ii in range(len(allgeoms)): unsafe = Laminate.unaryoperation(allgeoms[:ii] +allgeoms[ii + 1:],'union') unsafe_buffer = unsafe.buffer(safe_buffer1,resolution=self.resolution) safe_sections.append(allgeoms[ii].difference(unsafe_buffer)) safe = Laminate.unaryoperation(safe_sections, 'union') else: safe_sections.append(allgeoms[0]) safe = allgeoms[0] buffered_splits2 = Laminate.unaryoperation(buffered_splits, 'union') safe_buffer = safe.buffer(safe_buffer2, resolution=self.resolution) unsafe = Laminate.unaryoperation( allgeoms, 'union').difference(safe_buffer) unsafe2 = unsafe.buffer(safe_buffer3, resolution=self.resolution) split1 = parent.difference(unsafe2) split2 = split1.difference(buffered_splits2) bodies = popupcad.algorithms.body_detection.find( split2.to_generic_laminate()) bodies_generic = [item.to_generic_laminate() for item in bodies] connections = {} connections2 = {} for line, geom in zip(allhingelines, safe_sections): connections[line] = [] connections2[line] = [] for body, body_generic in zip(bodies, bodies_generic): if not geom.intersection(body).isEmpty(): connections[line].append(body_generic) connections2[line].append(body) for line, geoms in connections2.items(): connections2[line] = Laminate.unaryoperation(geoms, 'union') self.fixed_bodies = [] fixed_csg = [] for body, body_generic in zip(bodies, bodies_generic): if not fixed.intersection(body).isEmpty(): self.fixed_bodies.append(body_generic) fixed_csg.append(body) self.bodies_generic = bodies_generic allhingelines.sort() #Sort here to prevent interfering with geometry. We only care about order of the joint props self.connections = sorted([(key, connections[key]) for key in allhingelines if len(connections[key]) == 2]) self.all_joint_props = [all_joint_props[key] for key in allhingelines if len(connections[key]) == 2] self.output = [] self.output.append(OperationOutput(safe,'Safe',self)) self.output.append(OperationOutput(unsafe,'Unsafe',self)) self.output.append(OperationOutput(split1,'Split1',self)) self.output.append(OperationOutput(split2,'Split2',self)) #TODO Change output to match the names that get exported to Gazebo self.output.extend([OperationOutput(item,'Fixed {0:d}'.format(ii),self) for ii,item in enumerate(fixed_csg)]) self.output.extend([OperationOutput(item,'Body {0:d}'.format(ii),self) for ii,item in enumerate(bodies)]) self.output.extend([OperationOutput(item,'Connection {0:d}'.format(ii),self) for ii,item in enumerate(connections2.values())]) self.output.insert(0, self.output[3])
def find_rigid(generic, layerdef): layer_dict = dict([(geom.id, layer) for layer, geoms in generic.geoms.items() for geom in geoms]) rigid_geoms = [] connections = [] source_geoms = [{'id': None, 'csg': sg.Polygon()}] for layer in layerdef.layers: if layer.is_rigid: rigid_geoms.extend(generic.geoms[layer]) while not not source_geoms: source_geom = source_geoms.pop() new_geoms = [ dict([('csg', geom.to_shapely()), ('id', geom.id)]) for geom in generic.geoms[layer] ] for new_geom in new_geoms: connection = source_geom['csg'].intersection( new_geom['csg']) if not (connection.is_empty): connections.append((source_geom['id'], new_geom['id'])) source_geoms = new_geoms else: new_source_geoms = [] while not not source_geoms: source_geom = source_geoms.pop() layer_geoms = [ geom.to_shapely() for geom in generic.geoms[layer] ] for layer_geom in layer_geoms: new_geom = source_geom['csg'].intersection(layer_geom) if not (new_geom.is_empty): new_source_geoms.append({ 'id': source_geom['id'], 'csg': new_geom }) source_geoms = new_source_geoms ids = [geom.id for geom in rigid_geoms] m = len(ids) C = numpy.zeros((m, m), dtype=bool) for id1, id2 in connections: ii = ids.index(id1) jj = ids.index(id2) C[ii, jj] = True C[jj, ii] = True done = False D_last = C.copy() while not done: D = D_last.dot(C) + C done = (D == D_last).all() D_last = D rigid_bodies = [] rigid_geoms_set = set(rigid_geoms[:]) while not not rigid_geoms_set: geom = list(rigid_geoms_set)[0] ii = ids.index(geom.id) a = list(set((D[ii, :] == True).nonzero()[0].tolist() + [ii])) b = set(numpy.array(rigid_geoms)[a]) rigid_geoms_set -= b rigid_bodies.append(list(b)) values = [ tuple((numpy.array([ popupcad.algorithms.body_detection.find_minimum_xy(geom) for geom in body ])).min(0)) for body in rigid_bodies ] rigid_bodies = popupcad.algorithms.body_detection.sort_lams( rigid_bodies, values) new_csgs = [] for rigid_body in rigid_bodies: new_csg = Laminate(layerdef) for geom in rigid_body: new_csg.insertlayergeoms(layer_dict[geom.id], [geom.to_shapely()]) new_csgs.append(new_csg) return new_csgs
def generate(self,design): from popupcad.materials.materials import Rigid generic = design.op_from_ref(self.operation_link1).output[self.getoutputref()].generic_geometry_2d() layerdef = design.return_layer_definition() layer_dict = dict([(geom.id,layer) for layer,geoms in generic.items() for geom in geoms]) geom_dict = dict([(geom.id,geom) for layer,geoms in generic.items() for geom in geoms]) # csg_dict = dict([(geom.id,geom.outputshapely()) for layer,geoms in generic.items() for geom in geoms]) layerdef = design.return_layer_definition() rigid_geoms = [] connections = [] source_geoms= [{'id':None,'csg':sg.Polygon()}] for layer in layerdef.layers: if isinstance(layer,Rigid): rigid_geoms.extend(generic[layer]) while not not source_geoms: source_geom = source_geoms.pop() new_geoms = [dict([('csg',geom.outputshapely()),('id',geom.id)]) for geom in generic[layer]] for new_geom in new_geoms: connection = source_geom['csg'].intersection(new_geom['csg']) if not (connection.is_empty): connections.append((source_geom['id'],new_geom['id'])) source_geoms = new_geoms else: new_source_geoms = [] while not not source_geoms: source_geom = source_geoms.pop() layer_geoms = [geom.outputshapely() for geom in generic[layer]] for layer_geom in layer_geoms: new_geom = source_geom['csg'].intersection(layer_geom) if not (new_geom.is_empty): new_source_geoms.append({'id':source_geom['id'],'csg':new_geom}) source_geoms = new_source_geoms # print(connections) ids = [geom.id for geom in rigid_geoms] m = len(ids) C = numpy.zeros((m,m),dtype = bool) for id1,id2 in connections: ii = ids.index(id1) jj = ids.index(id2) C[ii,jj]=True C[jj,ii]=True done = False D_last = C.copy() while not done: D = D_last.dot(C)+C done = (D==D_last).all() D_last = D # print(D) rigid_bodies = [] rigid_geoms_set = set(rigid_geoms[:]) while not not rigid_geoms_set: geom = list(rigid_geoms_set)[0] ii = ids.index(geom.id) a = list(set((D[ii,:]==True).nonzero()[0].tolist()+[ii])) b = set(numpy.array(rigid_geoms)[a]) rigid_geoms_set-=b rigid_bodies.append(list(b)) # print(rigid_bodies) values = [tuple((numpy.array([find_minimum_xy(geom) for geom in body])).min(0)) for body in rigid_bodies] rigid_bodies = sort_lams(rigid_bodies,values) new_csgs = [] for rigid_body in rigid_bodies: new_csg = Laminate(layerdef) for geom in rigid_body: new_csg.insertlayergeoms(layer_dict[geom.id],[geom.outputshapely()]) new_csgs.append(new_csg) self.output = [] for ii,item in enumerate(new_csgs): self.output.append(OperationOutput(item,'Rigid Body {0:d}'.format(ii),self)) self.output.insert(0,self.output[0]) return Laminate(design.return_layer_definition())
def gen_geoms(self, joint_def, layerdef, design): print('Generating geometry') hinge_gap = joint_def.width *popupcad.csg_processing_scaling split_buffer = .1 * hinge_gap stiffness = joint_def.stiffness damping = joint_def.damping preload_angle = joint_def.preload_angle limit_negative = joint_def.limit_negative limit_positive = joint_def.limit_positive sublaminate_layers = [ layerdef.getlayer(item) for item in joint_def.sublaminate_layers] hingelayer = layerdef.getlayer(joint_def.joint_layer) z = layerdef.z_values[hingelayer] + hingelayer.thickness/2 operationgeom = design.sketches[joint_def.sketch].output_csg() sketch_result = Laminate(design.return_layer_definition()) sketch_result.replacelayergeoms(hingelayer, operationgeom) hingelines = sketch_result.to_generic_laminate().geoms[hingelayer] hingelines = [item for item in hingelines if item.is_valid_bool()] buffered_split = sketch_result.buffer( split_buffer, resolution=self.resolution) allgeoms4 = [] for geom in hingelines: geom = geom.to_shapely() laminate = Laminate(layerdef) for layer in sublaminate_layers: laminate.replacelayergeoms(layer, [geom]) allgeoms4.append( laminate.buffer( hinge_gap, resolution=self.resolution)) joint_props = [(stiffness, damping, preload_angle, limit_negative, limit_positive,z) for item in hingelines] return allgeoms4, buffered_split, hingelines, joint_props