예제 #1
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
예제 #2
0
    def gen_geoms(self, joint_def, layerdef, design):
        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

        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))

        joint_props = [(stiffness, damping, preload_angle)
                       for item in hingelines]
        return allgeoms4, buffered_split, hingelines, joint_props
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
예제 #4
0
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
예제 #5
0
 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
예제 #6
0
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 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
예제 #8
0
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
예제 #9
0
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
예제 #10
0
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
예제 #11
0
 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
예제 #12
0
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
예제 #13
0
 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
예제 #14
0
 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
예제 #15
0
    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)
예제 #16
0
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]
예제 #17
0
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
예제 #18
0
 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 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
예제 #20
0
    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
예제 #21
0
 def operate(self, design):
     laminate = Laminate(design.return_layer_definition())
     return laminate