Exemplo n.º 1
0
def getWaterline(s, cutter, zh, sampling):
    wl = ocl.Waterline()
    #wl.setThreads(1) # single thread for easier debug
    wl.setSTL(s)
    wl.setCutter(cutter)
    wl.setZ(zh)
    wl.setSampling(sampling)
    wl.run()
    loops = wl.getLoops()
    return loops
Exemplo n.º 2
0
def oclGetWaterline(operation, chunks):
    layers = oclWaterlineLayerHeights(operation)
    oclSTL = get_oclSTL(operation)

    cutter_props = operation.getOpCuttingTool()

    op_cutter_type = cutter_props.cutter_type
    op_cutter_diameter = cutter_props.cutter_diameter
    op_minz = operation.minz
    if op_cutter_type == "VCARVE":
        op_cutter_tip_angle = cutter_props.cutter_tip_angle

    cutter = None
    cutter_length = 150  #TODO: automatically determine necessary cutter length depending on object size

    if op_cutter_type == 'END':
        cutter = ocl.CylCutter(
            (op_cutter_diameter + operation.skin * 2) * 1000, cutter_length)
    elif op_cutter_type == 'BALLNOSE':
        cutter = ocl.BallCutter(
            (op_cutter_diameter + operation.skin * 2) * 1000, cutter_length)
    elif op_cutter_type == 'VCARVE':
        cutter = ocl.ConeCutter(
            (op_cutter_diameter + operation.skin * 2) * 1000,
            op_cutter_tip_angle, cutter_length)
    else:
        print("Cutter unsupported: {0}\n".format(op_cutter_type))
        quit()

    waterline = ocl.Waterline()
    waterline.setSTL(oclSTL)
    waterline.setCutter(cutter)
    waterline.setSampling(0.1)  #TODO: add sampling setting to UI
    for height in layers:
        print(str(height) + '\n')
        waterline.reset()
        waterline.setZ(height * OCL_SCALE)
        waterline.run2()
        wl_loops = waterline.getLoops()
        for l in wl_loops:
            chunks.append(camPathChunk(inpoints=[]))
            for p in l:
                chunks[-1].points.append(
                    (p.x / OCL_SCALE, p.y / OCL_SCALE, p.z / OCL_SCALE))
            chunks[-1].append(chunks[-1].points[0])
            chunks[-1].closed = True
            chunks[-1].poly = sgeometry.Polygon(chunks[-1].points)
Exemplo n.º 3
0
def calcWaterline(zh, cutter, s):
    wl = ocl.Waterline()
    #wl = ocl.AdaptiveWaterline()
    wl.setSTL(s)
    wl.setCutter(cutter)
    wl.setZ(zh)
    wl.setSampling(0.02)
    wl.setThreads(2)
    t_before = time.time()
    wl.run()
    t_after = time.time()
    calctime = t_after - t_before
    print(" Waterline done in ", calctime, " s")
    out = []
    out.append(wl.getLoops())
    out.append(wl.getXFibers())
    out.append(wl.getYFibers())
    return out
Exemplo n.º 4
0
def waterline_time(zheights, diam, length, s, sampling):
    t_total = time.time()
    for zh in zheights:
        cutter = ocl.BallCutter(diam, length)
        wl = ocl.Waterline()
        wl.setSTL(s)
        wl.setCutter(cutter)
        wl.setZ(zh)
        wl.setSampling(sampling)
        wl.setThreads(1)

        wl.run()

        cutter_loops = wl.getLoops()
        for l in cutter_loops:
            loops.append(l)
    timeTotal = time.time() - t_total
    print " ALL Waterlines done in ", timeTotal, " s"
    return timeTotal
Exemplo n.º 5
0
def waterline(filepath,
              tool_diameter=3.0,
              corner_radius=0.0,
              step_over=1.0,
              x0=-10.0,
              x1=10.0,
              y0=-10.0,
              y1=10.0,
              mat_allowance=0.0,
              clearance=5.0,
              rapid_safety_space=2.0,
              start_depth=0.0,
              step_down=2.0,
              final_depth=-10.0,
              units=1.0,
              tolerance=0.01):
    mm = True
    if math.fabs(units) > 0.000000001:
        # ocl works in mm, so convert all values to mm
        mm = False
        tool_diameter *= units
        corner_radius *= units
        step_over *= units
        x0 *= units
        x1 *= units
        y0 *= units
        y1 *= units
        mat_allowance *= units
        clearance *= units
        rapid_safety_space *= units
        start_depth *= units
        step_down *= units
        final_depth *= units
        tolerance *= units

    # read the stl file, we know it is an ascii file because HeeksCNC made it
    s = STLSurfFromFile(filepath)

    if final_depth > start_depth:
        raise 'final_depth > start_depth'
    height = start_depth - final_depth
    zsteps = int(height / math.fabs(step_down) + 0.999999)
    zstep_down = height / zsteps
    incremental_rapid_to = rapid_safety_space - start_depth
    if incremental_rapid_to < 0: incremental_rapid_to = 0.1

    tool_location = ocl.Point(0.0, 0.0, 0.0)

    for k in range(0, zsteps):
        z = start_depth - k * zstep_down
        working_diameter = tool_diameter + mat_allowance

        room_to_expand = True
        # while (room_to_expand == True):
        cutter = cutting_tool(working_diameter, corner_radius, 10)

        waterline = ocl.Waterline()
        waterline.setSTL(s)
        waterline.setSampling(tolerance)
        waterline.setCutter(cutter)
        waterline.setZ(z)
        waterline.run()
        cutter_loops = waterline.getLoops()

        for cutter_loop in cutter_loops:
            if ((cutter_loop[0].z != tool_location.z)
                    or (tool_location.distance(cutter_loop[0]) >
                        (tool_diameter / 2.0))):
                # Move above the starting point.
                rapid(z=clearance / units)
                rapid(x=cutter_loop[0].x, y=cutter_loop[0].y)
                tool_location.x = cutter_loop[0].x
                tool_location.y = cutter_loop[0].y
                tool_location.z = clearance / units

                # Feed down to the cutting depth
                rapid(x=cutter_loop[0].x, y=cutter_loop[0].y)
                tool_location.x = cutter_loop[0].x
                tool_location.y = cutter_loop[0].y

            # Cut around the solid at this level.
            for point in cutter_loop:
                feed(x=point.x, y=point.y, z=point.z)
                tool_location = point
                #if (point.x < (x0-step_over)) or (point.x > (x1+step_over)) or (point.y < (y0-step_over)) or (point.y > (y1+step_over)):
                #   room_to_expand = False

                # And retract to the clearance height
            rapid(z=clearance / units)
            tool_location.z = clearance / units
Exemplo n.º 6
0
    def _waterline(self, obj, s, bb):
        import time
        import ocl

        def drawLoops(loops):
            nloop = 0
            pp = []
            pp.append(Path.Command("(waterline begin)" ))

            for loop in loops:
                p = loop[0]
                pp.append(Path.Command("(loop begin)" ))
                pp.append(Path.Command('G0', {"Z": obj.SafeHeight.Value, 'F': self.vertRapid}))
                pp.append(Path.Command('G0', {'X': p.x, "Y": p.y, 'F': self.horizRapid}))
                pp.append(Path.Command('G1', {"Z": p.z, 'F': self.vertFeed}))

                for p in loop[1:]:
                    pp.append(Path.Command('G1', {'X': p.x, "Y": p.y, "Z": p.z, 'F': self.horizFeed}))
                   # zheight = p.z
                p = loop[0]
                pp.append(Path.Command('G1', {'X': p.x, "Y": p.y, "Z": p.z, 'F': self.horizFeed}))
                pp.append(Path.Command("(loop end)" ))

                print("    loop ", nloop, " with ", len(loop), " points")
                nloop = nloop + 1
            pp.append(Path.Command("(waterline end)" ))

            return pp

        depthparams = PathUtils.depth_params(obj.ClearanceHeight.Value, obj.SafeHeight.Value,
                                   obj.StartDepth.Value, obj.StepDown, obj.FinishDepth.Value, obj.FinalDepth.Value)

        t_before = time.time()
        zheights = [i for i in depthparams]

        wl = ocl.Waterline()
        wl.setSTL(s)
        cutter = ocl.CylCutter(obj.ToolController.Tool.Diameter, 5)
        wl.setCutter(cutter)
        # this should be smaller than the smallest details in the STL file
        wl.setSampling(obj.SampleInterval)
        # AdaptiveWaterline() also has settings for minimum sampling interval
        # (see c++ code)
        all_loops = []
        print ("zheights: {}".format(zheights))
        for zh in zheights:
            print("calculating Waterline at z= ", zh)
            wl.reset()
            wl.setZ(zh)  # height for this waterline
            wl.run()
            all_loops.append(wl.getLoops())
        t_after = time.time()
        calctime = t_after - t_before
        n = 0
        output = []
        for loops in all_loops:  # at each z-height, we may get many loops
            print("  %d/%d:" % (n, len(all_loops)))
            output.extend(drawLoops(loops))
            n = n + 1
        print("(" + str(calctime) + ")")
        return output
Exemplo n.º 7
0
    def _waterline(self, obj, s, bb):
        import ocl
        from PathScripts.PathUtils import depth_params, fmt
        import time

        def drawLoops(loops):
            nloop = 0
            waterlinestring = ""
            waterlinestring += "(waterline begin)"
            for loop in loops:
                p = loop[0]
                loopstring = "(loop begin)" + "\n"
                loopstring += "G0 Z" + str(obj.SafeHeight.Value) + "\n"
                loopstring += "G0 X" + \
                    str(fmt(p.x)) + " Y" + str(fmt(p.y)) + "\n"
                loopstring += "G1 Z" + str(fmt(p.z)) + "\n"
                for p in loop[1:]:
                    loopstring += "G1 X" + \
                        str(fmt(p.x)) + " Y" + str(fmt(p.y)) + \
                        " Z" + str(fmt(p.z)) + "\n"
                    zheight = p.z
                p = loop[0]
                loopstring += "G1 X" + \
                    str(fmt(p.x)) + " Y" + str(fmt(p.y)) + \
                    " Z" + str(fmt(zheight)) + "\n"
                loopstring += "(loop end)" + "\n"
                print "    loop ", nloop, " with ", len(loop), " points"
                nloop = nloop + 1
                waterlinestring += loopstring
            waterlinestring += "(waterline end)" + "\n"
            return waterlinestring

        depthparams = depth_params(obj.ClearanceHeight.Value, obj.SafeHeight.Value,
                                   obj.StartDepth.Value, obj.StepDown, obj.FinishDepth.Value, obj.FinalDepth.Value)
        # stlfile = "../../stl/gnu_tux_mod.stl"
        # surface = STLSurfaceSource(stlfile)
        surface = s

        t_before = time.time()
        zheights = depthparams.get_depths()
        wl = ocl.Waterline()
        # wl = ocl.AdaptiveWaterline() # this is slower, ca 60 seconds on i7
        # CPU
        wl.setSTL(surface)
        diam = 0.5
        length = 10.0
        # any ocl MillingCutter class should work here
        cutter = ocl.BallCutter(diam, length)
        wl.setCutter(cutter)
        # this should be smaller than the smallest details in the STL file
        wl.setSampling(obj.SampleInterval)
        # AdaptiveWaterline() also has settings for minimum sampling interval
        # (see c++ code)
        all_loops = []
        for zh in zheights:
            print "calculating Waterline at z= ", zh
            wl.reset()
            wl.setZ(zh)  # height for this waterline
            wl.run()
            all_loops.append(wl.getLoops())
        t_after = time.time()
        calctime = t_after - t_before
        n = 0
        output = ""
        for loops in all_loops:  # at each z-height, we may get many loops
            print "  %d/%d:" % (n, len(all_loops))
            output += drawLoops(loops)
            n = n + 1
        print "(" + str(calctime) + ")"
        return output
Exemplo n.º 8
0
    myscreen.addActor(camvtk.Line(p1=(a.x, a.y, a.z), p2=(c.x, c.y, c.z)))
    myscreen.addActor(camvtk.Line(p1=(c.x, c.y, c.z), p2=(b.x, b.y, b.z)))
    myscreen.addActor(camvtk.Line(p1=(a.x, a.y, a.z), p2=(b.x, b.y, b.z)))
    t = ocl.Triangle(b, c, a)
    s = ocl.STLSurf()
    s.addTriangle(t)  # a one-triangle STLSurf
    zheight = 0.15  # the z-coordinate for the waterline
    diam = 0.6
    length = 5
    loops = []
    #cutter = ocl.CylCutter( 1 , 1 )

    cutter = ocl.CylCutter(diam, length)
    #cutter = ocl.BallCutter( diam , length )
    #cutter = ocl.BullCutter( diam , diam/5, length )
    wl = ocl.Waterline()
    #wl.setThreads(1)
    wl.setSTL(s)
    wl.setCutter(cutter)
    wl.setZ(zheight)
    wl.setSampling(0.1)
    t_before = time.time()
    wl.run()
    t_after = time.time()
    calctime = t_after - t_before
    print(" Waterline done in ", calctime, " s")
    cutter_loops = wl.getLoops()
    for l in cutter_loops:
        loops.append(l)
    #print loops
    print("All waterlines done. Got", len(loops), " loops in total.")
Exemplo n.º 9
0
elif op_cutter_type == 'BALL':
    cutter = ocl.BallCutter(op_cutter_diameter * 1000, cutter_length)
elif op_cutter_type == 'VCARVE':
    cutter = ocl.ConeCutter(op_cutter_diameter * 1000, 1, cutter_length)
else:
    print "Cutter unsupported: " + op_cutter_type + '\n'
    quit()
wl_height_file = open(tempfile.gettempdir() + '/ocl_wl_heights.txt', 'r')
waterline_heights = []
for line in wl_height_file:
    waterline_heights.append(float(line.split()[0]))
wl_height_file.close()
wl_index = 0
for height in waterline_heights:
    print(str(height) + '\n')
    waterline = ocl.Waterline()
    waterline.setSTL(stl_surf)
    waterline.setCutter(cutter)
    waterline.setZ(height)
    waterline.setSampling(0.3)
    waterline.run()
    wl_loops = waterline.getLoops()
    wl_file = open(
        tempfile.gettempdir() + '/oclWaterline' + str(wl_index) + '.txt', 'w')
    for l in wl_loops:
        wl_file.write('l\n')
        for p in l:
            wl_file.write(str(p.x) + ' ' + str(p.y) + ' ' + str(p.z) + '\n')
    wl_file.close()
    wl_index += 1
Exemplo n.º 10
0
        print "    loop ", nloop, " with ", len(lop), " points"
        nloop = nloop + 1


if __name__ == "__main__":
    stlfile = "../../stl/gnu_tux_mod.stl"
    surface = STLSurfaceSource(stlfile)

    t_before = time.time()

    zheights = [
        0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6
    ]
    #zheights=[float(1.0)] # for faster computation, calculate only one waterline

    wl = ocl.Waterline()  # total time 14 seconds on i7 CPU
    #wl = ocl.AdaptiveWaterline() # this is slower, ca 60 seconds on i7 CPU
    wl.setSTL(surface)
    diam = 0.5
    length = 10
    cutter = ocl.BallCutter(
        diam, length)  # any ocl MillingCutter class should work here
    wl.setCutter(cutter)
    wl.setSampling(
        0.0314
    )  # this should be smaller than the smallest details in the STL file
    # AdaptiveWaterline() also has settings for minimum sampling interval (see c++ code)
    all_loops = []
    for zh in zheights:
        print "calculating Waterline at z= ", zh
        wl.reset()
Exemplo n.º 11
0
    def generate(self):

        self.set_tool(tool=self._tool)

        stepdown = min(self.stepdown * self.material_factor,
                       2) * self.tool.diameter
        boundary = self.get_boundary()

        if isinstance(self.boundary, (tuple, list)):
            minx, miny, maxx, maxy = self.boundary
            self.boundary = Polygon((
                (minx, miny),
                (minx, maxy),
                (maxx, maxy),
                (maxy, miny),
            ))

        cutter = self.ocl_cutter()
        minz = self.minZ if self.minZ is not None else self.surface.range[2][0]
        maxz = self.maxZ if self.maxZ is not None else self.surface.range[2][1]
        clearz = self.clearZ or maxz

        if self.adaptive:
            wl = ocl.AdaptiveWaterline(
            )  # this is slower, ca 60 seconds on i7 CPU
            wl.setMinSampling(0.01)
        else:
            wl = ocl.Waterline()  # total time 14 seconds on i7 CPU

        surf = self.surface.get_ocl_stl_surf()
        wl.setSTL(surf)  # surface MUST be saved in a variable first
        wl.setCutter(cutter)
        wl.setSampling(
            0.0314
        )  # this should be smaller than the smallest details in the STL file

        for zh in frange(maxz, minz, stepdown):
            wl.reset()
            wl.setZ(zh)  # height for this waterline
            wl.run()

            for path in wl.getLoops():
                fpath = self.filter_path(path, self.tolerance)

                coords = [(a.x, a.y, a.z) for a in fpath]
                coords.append(coords[0])
                ls = LineString(coords)
                inter = boundary.intersection(ls)
                if isinstance(inter, MultiLineString):
                    print "MULTI"
                    for lx in inter:
                        self.cut_linestring(lx, zh, clearz=clearz)
                        #Line(lx.coords).graph(fig=fig)
                elif isinstance(inter, LineString):
                    print "SINGLE"
                    self.cut_linestring(inter, zh, clearz=clearz)
                    #Line(inter.coords).graph(fig=fig)
                elif isinstance(inter, GeometryCollection):
                    for foo in inter:
                        print "COLLECTION", foo.__class__
                        sys.exit(0)
                else:
                    print "WEIRD", inter.__class__
                    sys.exit(0)
Exemplo n.º 12
0
def waterline(filepath,
              tool_diameter=3.0,
              corner_radius=0.0,
              cutter_length=0.0,
              x0=-10.0,
              x1=10.0,
              y0=-10.0,
              y1=10.0,
              mat_allowance=0.0,
              clearance=5.0,
              rapid_safety_space=2.0,
              start_depth=0.0,
              step_down=2.0,
              final_depth=-10.0,
              units=1.0,
              tolerance=0.01):
    mm = True
    if math.fabs(units) > 0.000000001:
        # ocl works in mm, so convert all values to mm
        mm = False
        tool_diameter *= units
        corner_radius *= units
        cutter_length *= units
        x0 *= units
        x1 *= units
        y0 *= units
        y1 *= units
        mat_allowance *= units
        clearance *= units
        rapid_safety_space *= units
        start_depth *= units
        step_down *= units
        final_depth *= units
        tolerance *= units
        cut_flag = True
        first_move = True
    # read the stl file, we know it is an ascii file because HeeksCNC made it
    s = STLSurfFromFile(filepath)

    if final_depth > start_depth:
        raise Exception('final_depth > start_depth')
    height = start_depth - final_depth
    zsteps = int(height / math.fabs(step_down) + 0.999999)
    zstep_down = height / zsteps
    incremental_rapid_to = rapid_safety_space - start_depth
    if incremental_rapid_to < 0: incremental_rapid_to = 0.1

    tool_location = ocl.Point(0.0, 0.0, 0.0)

    for k in range(0, zsteps):
        z = start_depth - k * zstep_down
        working_diameter = tool_diameter + mat_allowance

        room_to_expand = True
        # while (room_to_expand == True):
        cutter = cutting_tool(working_diameter, corner_radius, cutter_length)

        waterline = ocl.Waterline()
        #waterline = ocl.AdaptiveWaterline()
        waterline.setSTL(s)
        waterline.setSampling(tolerance)
        waterline.setCutter(cutter)
        waterline.setZ(z)
        waterline.run()
        cutter_loops = waterline.getLoops()

        for cutter_loop in cutter_loops:
            if ((cutter_loop[0].z != tool_location.z)
                    or (tool_location.distance(cutter_loop[0]) >
                        (tool_diameter / 2.0))):
                # Move above the starting point.
                rapid(z=clearance / units)
                if (x0 <= cutter_loop[0].x / units <= x1) and (
                        y0 <= cutter_loop[0].y / units <= y1):  #boundary check
                    rapid(x=cutter_loop[0].x / units,
                          y=cutter_loop[0].y / units)
                tool_location.x = cutter_loop[0].x / units
                tool_location.y = cutter_loop[0].y / units
                tool_location.z = clearance / units
                # Feed down to the cutting depth
                if (x0 <= tool_location.x / units <= x1) and (
                        y0 <= tool_location.y / units <= y1):  #boundary check
                    feed(tool_location.x, tool_location.y, z / units)
            # Cut around the solid at this level.
            for point in cutter_loop:
                if (x0 <= point.x <= x1) and (y0 <= point.y <=
                                              y1):  #boundary check
                    if cut_flag == False:
                        rapid(x=point.x / units, y=point.y / units)
                        cut_flag = True
                    else:
                        if first_move == True:
                            rapid(x=point.x / units, y=point.y /
                                  units)  #rapid over to xy then feed down
                            feed(z=point.z / units)
                            first_move = False
                        else:
                            feed(x=point.x / units,
                                 y=point.y / units,
                                 z=point.z / units)
                            tool_location = point
                else:
                    cut_flag = False
                    # And retract to the clearance height
                    rapid(z=clearance / units)
Exemplo n.º 13
0
    def _waterline(self, obj, s, bb):
        import time
        import ocl

        def drawLoops(loops):
            nloop = 0
            pp = []
            pp.append(Path.Command("(waterline begin)"))

            for loop in loops:
                p = loop[0]
                pp.append(Path.Command("(loop begin)"))
                pp.append(
                    Path.Command('G0', {
                        "Z": obj.SafeHeight.Value,
                        'F': self.vertRapid
                    }))
                pp.append(
                    Path.Command('G0', {
                        'X': p.x,
                        "Y": p.y,
                        'F': self.horizRapid
                    }))
                pp.append(Path.Command('G1', {"Z": p.z, 'F': self.vertFeed}))
                prev = ocl.Point(float("inf"), float("inf"), float("inf"))
                next = ocl.Point(float("inf"), float("inf"), float("inf"))
                optimize = obj.Optimize
                for i in range(1, len(loop)):
                    p = loop[i]
                    if i < len(loop) - 1:
                        next.x = loop[i + 1].x
                        next.y = loop[i + 1].y
                        next.z = loop[i + 1].z
                    else:
                        optimize = False
                    if not optimize or not self.isPointOnLine(
                            FreeCAD.Vector(prev.x, prev.y, prev.z),
                            FreeCAD.Vector(next.x, next.y, next.z),
                            FreeCAD.Vector(p.x, p.y, p.z)):
                        pp.append(
                            Path.Command('G1', {
                                'X': p.x,
                                "Y": p.y,
                                "Z": p.z,
                                'F': self.horizFeed
                            }))
                    prev.x = p.x
                    prev.y = p.y
                    prev.z = p.z
                    # zheight = p.z
                p = loop[0]
                pp.append(
                    Path.Command('G1', {
                        'X': p.x,
                        "Y": p.y,
                        "Z": p.z,
                        'F': self.horizFeed
                    }))
                pp.append(Path.Command("(loop end)"))

                print("    loop ", nloop, " with ", len(loop), " points")
                nloop = nloop + 1
            pp.append(Path.Command("(waterline end)"))

            return pp

        depthparams = PathUtils.depth_params(obj.ClearanceHeight.Value,
                                             obj.SafeHeight.Value,
                                             obj.StartDepth.Value,
                                             obj.StepDown, 0.0,
                                             obj.FinalDepth.Value)

        t_before = time.time()
        zheights = [i for i in depthparams]

        wl = ocl.Waterline()
        wl.setSTL(s)

        if obj.ToolController.Tool.ToolType == 'BallEndMill':
            cutter = ocl.BallCutter(
                obj.ToolController.Tool.Diameter, 5
            )  # TODO: 5 represents cutting edge height. Should be replaced with the data from toolcontroller?
        else:
            cutter = ocl.CylCutter(obj.ToolController.Tool.Diameter, 5)

        wl.setCutter(cutter)
        # this should be smaller than the smallest details in the STL file
        wl.setSampling(obj.SampleInterval)
        # AdaptiveWaterline() also has settings for minimum sampling interval
        # (see c++ code)
        all_loops = []
        print("zheights: {}".format(zheights))
        for zh in zheights:
            print("calculating Waterline at z= ", zh)
            wl.reset()
            wl.setZ(zh)  # height for this waterline
            wl.run()
            all_loops.append(wl.getLoops())
        t_after = time.time()
        calctime = t_after - t_before
        n = 0
        output = []
        for loops in all_loops:  # at each z-height, we may get many loops
            print("  %d/%d:" % (n, len(all_loops)))
            output.extend(drawLoops(loops))
            n = n + 1
        print("(" + str(calctime) + ")")
        return output