Example #1
0
    def generate(self,
                 board_width,
                 board_height,
                 number_of_pieces,
                 random_seed=0,
                 tap_shape='basic',
                 threshold=3.0):
        blocks = []
        block = Block(self.name)
        random.seed(random_seed)
        Arc.reset_used_arcs()
        Arc.set_diff_threshold(threshold)
        puzzle_cuts = self.__class__.make_puzzle_cuts(board_width,
                                                      board_height,
                                                      number_of_pieces,
                                                      tap_shape, threshold)

        # Draw puzzle cuts
        x = 0
        y = 0
        for i in range(0, int(self.thickness / self.step_z)):
            for cut in puzzle_cuts:
                block.append(CNC.zsafe())
                block.append(CNC.grapid(x + cut[0].x, y + cut[0].y))
                block.append(CNC.zenter(0.0))
                block.append(CNC.fmt("f", self.cut_feed))
                block.append(CNC.zenter(-(i + 1) * self.step_z))
                for arc in cut:
                    if arc.r:
                        block.append(
                            CNC.garc(arc.direction,
                                     x + arc.x,
                                     y + arc.y,
                                     r=arc.r))

        blocks.append(block)

        # Draw border
        block = Block(self.name + "_border")

        block.append(CNC.zsafe())
        block.append(CNC.grapid(x, y))

        for i in range(0, int(self.thickness / self.step_z)):
            block.append(CNC.fmt("f", self.cut_feed))
            block.append(CNC.zenter(-(i + 1) * self.step_z))
            block.append(CNC.gline(x + board_width, y))
            block.append(CNC.gline(x + board_width, y + board_height))
            block.append(CNC.gline(x, y + board_height))
            block.append(CNC.gline(x, y))

        block.append(CNC.zsafe())
        blocks.append(block)

        return blocks
Example #2
0
    def slice(self, verts, faces, z, zout=None):
        block = Block("slice %f" % (float(z)))

        #FIXME: slice along different axes
        plane_orig = (0, 0, z)  #z height to slice
        plane_norm = (0, 0, 1)

        #Crosscut
        contours = meshcut.cross_section(verts, faces, plane_orig, plane_norm)

        #Flatten contours
        if zout is not None:
            for contour in contours:
                for segment in contour:
                    segment[2] = zout

        #Contours to G-code
        for contour in contours:
            #print(contour)
            first = contour[0]
            block.append("g0 x%f y%f z%f" % (first[0], first[1], first[2]))
            for segment in contour:
                block.append("g1 x%f y%f z%f" %
                             (segment[0], segment[1], segment[2]))
            block.append("g1 x%f y%f z%f" % (first[0], first[1], segment[2]))
            block.append("( ---------- cut-here ---------- )")
        if block: del block[-1]

        if not block: block = None
        return block
Example #3
0
	def execute(self, app):
		maxseg = self.fromMm("maxseg")
		splitlines = self["splitlines"]

		#print("go!")
		blocks  = []
		for bid in app.editor.getSelectedBlocks():
			if len(app.gcode.toPath(bid)) < 1: continue

			#nblock = Block("flat "+app.gcode[bid].name())
			#for i in app.gcode[bid]:
			#	nblock.append(re.sub(r"\s?z-?[0-9\.]+","",i))
			#blocks.append(nblock)

			eblock = Block("lin "+app.gcode[bid].name())
			opath = app.gcode.toPath(bid)[0]
			npath = opath.linearize(maxseg, splitlines)
			eblock = app.gcode.fromPath(npath,eblock)
			blocks.append(eblock)



		#active = app.activeBlock()
		#if active == 0: active+=1
		active=-1 #add to end
		app.gcode.insBlocks(active, blocks, "Linearized") #<<< insert blocks over active block in the editor
		app.refresh()                                                                                           #<<< refresh editor
		app.setStatus(_("Generated: Linearize"))                           #<<< feed back result
Example #4
0
	def calc(self,x,y,depth,peck,dwell,drillFeed,safeZforG0):
		self.safeZforG0 =float(abs(safeZforG0))
		peck=abs(float(peck))
		currentz=0.0
		self.blocks = []
		self.block = Block(self.name)
		self.block.append(CNC.grapid(x=x,y=y))
		self.block.append(CNC.grapid(z=CNC.vars["safe"]))
		self.accelerateIfNeeded(0.0,drillFeed)
		self.block.append("(entered)")
		while(currentz>depth):
			currentz-=peck
			if currentz < depth:
				currentz = depth
			kwargs={"f":float(drillFeed)}
			self.block.append(CNC.gline(None,None,float(currentz),**kwargs))
			if self.safeZforG0 >0:
				self.block.append(CNC.grapid(z=0.0+self.safeZforG0))
			else :
				self.block.append(CNC.grapid(z=CNC.vars["safe"]))
			self.block.append("g4 %s"%(CNC.fmt("p",float(dwell))))
			if currentz > depth:
				self.accelerateIfNeeded(currentz,drillFeed)
		self.block.append("(exiting)")
		self.block.append(CNC.grapid(z=CNC.vars["safe"]))
		self.blocks.append(self.block)
		return self.blocks
Example #5
0
    def execute(self, app):
        preci = self.fromMm("preci")
        linpreci = self.fromMm("linpreci")
        numseg = self["numseg"]

        #print("go!")
        blocks = []
        for bid in app.editor.getSelectedBlocks():
            if len(app.gcode.toPath(bid)) < 1: continue

            #nblock = Block("flat "+app.gcode[bid].name())
            #for i in app.gcode[bid]:
            #	nblock.append(re.sub(r"\s?z-?[0-9\.]+","",i))
            #blocks.append(nblock)

            eblock = Block("fit " + app.gcode[bid].name())
            npath = app.gcode.toPath(bid)[0]
            npath = npath.mergeLines(linpreci)
            npath = npath.arcFit(preci, numseg)
            if npath.length() <= 0:
                #FIXME: not sure how this could happen
                print("Warning: ignoring zero length path!")
                continue
            eblock = app.gcode.fromPath(npath, eblock)
            blocks.append(eblock)

        #active = app.activeBlock()
        #if active == 0: active+=1
        active = -1  #add to end
        app.gcode.insBlocks(
            active, blocks,
            "Arc fit")  #<<< insert blocks over active block in the editor
        app.refresh()  #<<< refresh editor
        app.setStatus(_("Generated: Arc fit"))  #<<< feed back result
Example #6
0
	def insertBlock(self, event=None):
		active = self.index(ACTIVE)
		if self._items:
			bid, lid = self._items[active]
			bid += 1
		else:
			bid = 0

		block = Block()
		block.expand = True
		block.append("g0 x0 y0")
		block.append("g1 z0")
		block.append(CNC.zsafe())
		self.gcode.addUndo(self.gcode.addBlockUndo(bid,block))
		self.selection_clear(0,END)
		self.fill()
		# find location of new block
		while active < self.size():
			if self._items[active][0] == bid:
				break
			active += 1
		self.selection_set(active)
		self.see(active)
		self.activate(active)
		self.edit()
		self.winfo_toplevel().event_generate("<<Modified>>")
Example #7
0
    def execute(self, app):
        rdoc = self["rdoc"]
        radius = self["dia"] / 2
        cw = self["cw"]

        #print("go!")
        blocks = []
        for bid in app.editor.getSelectedBlocks():
            #print(blocks[bid])
            path = app.gcode.toPath(bid)[0]
            #print(path)

            block = Block("trochoid")

            for segment in path:
                #print(segment.A)
                #block.append("g0 x0 y0")
                #block.append("g1 x10 y10")
                #block.append("g1 x20 y10")
                #block.append("g0 x0 y0")
                block.extend(self.trochoid(segment, rdoc, radius, cw))

            blocks.append(block)

        active = app.activeBlock()
        app.gcode.insBlocks(
            active, blocks, "Trochoidal created"
        )  #<<< insert blocks over active block in the editor
        app.refresh()  #<<< refresh editor
        app.setStatus(_("Generated: Trochoidal"))  #<<< feed back result
Example #8
0
    def make(self, n=2, size=100, depth=0):
        self.n = n
        self.size = size
        self.depth = depth

        blocks = []
        block = Block(self.name)

        xi, yi = zip(*(self.hilbert(0.0, 0.0, size, 0.0, 0.0, size, n)))

        block.append(CNC.zsafe())
        block.append(CNC.grapid(xi[0], yi[0]))

        currDepth = 0.
        stepz = CNC.vars['stepz']
        if stepz == 0: stepz = 0.001  #avoid infinite while loop

        while True:
            currDepth -= stepz
            if currDepth < self.depth: currDepth = self.depth
            block.append(CNC.zenter(currDepth))
            block.append(CNC.gcode(1, [("f", CNC.vars["cutfeed"])]))
            for x, y in zip(xi, yi):
                block.append(CNC.gline(x, y))
            if currDepth <= self.depth: break

        block.append(CNC.zsafe())
        blocks.append(block)
        return blocks
Example #9
0
	def make(self, Nlines, LineLen, StartEndLen, Step, CornerRes, Depth):
		blocks = []
		block = Block(self.name)

		points = self.zigzag(Nlines, LineLen, StartEndLen, Step, CornerRes)

		block.append(CNC.zsafe())
		block.append(CNC.grapid(points[0][0],points[0][1]))

		currDepth = 0.
		stepz = CNC.vars['stepz']
		if stepz==0 : stepz=0.001  #avoid infinite while loop

		while True:
			currDepth -= stepz
			if currDepth < Depth : currDepth = Depth
			block.append(CNC.zenter(currDepth))
			block.append(CNC.gcode(1, [("f",CNC.vars["cutfeed"])]))
			for (x,y) in points:
				block.append(CNC.gline(x,y))
			if currDepth <= Depth : break

		block.append(CNC.zsafe())
		blocks.append(block)
		return blocks
Example #10
0
    def execute(self, app):
        feed = self["feed"]
        zfeed = CNC.vars["cutfeedz"]
        rpm = self["rpm"]
        if self["zfeed"]:
            zfeed = self["zfeed"]

        zup = self["zup"]

        surface = CNC.vars["surface"]
        #		zbeforecontact=surface+CNC.vars["zretract"]
        #		hardcrust = surface - CNC.vars["hardcrust"]
        #		feedbeforecontact = CNC.vars["feedbeforecontact"]/100.0
        #		hardcrustfeed = CNC.vars["hardcrustfeed"]/100.0

        # Get selected blocks from editor
        selBlocks = app.editor.getSelectedBlocks()

        if not selBlocks:
            app.setStatus(_("Scaling abort: Please select some path"))
            return

        #Get all segments from gcode
        allSegments = self.extractAllSegments(app, selBlocks)

        #Create holes locations
        #		allHoles=[]
        for bidSegment in allSegments:
            if len(bidSegment) == 0:
                continue
        blocks = []
        n = self["name"]
        #		if not n or n=="default": n="Trochoidal_3D"
        n = "Scaling"
        scal_block = Block(n)

        for idx, segm in enumerate(bidSegment):
            if idx >= 0:
                if idx == 0:
                    scal_block.append("M03")
                    scal_block.append("S " + str(rpm))
                    scal_block.append(CNC.zsafe())
                    scal_block.append("F " + str(feed))
                    scal_block.append(
                        "(--------------------------------------------------)")

                B = self.scaling(segm)

                if segm[0][2] > surface and segm[1][2] >= surface:
                    scal_block.append("g0 x " + str(B[0]) + " y " + str(B[1]) +
                                      " z " + str(B[2]))
                else:
                    scal_block.append("g1 x " + str(B[0]) + " y " + str(B[1]) +
                                      " z " + str(B[2]))
        scal_block.append(CNC.zsafe(
        ))  #<<< Move rapid Z axis to the safe height in Stock Material
        blocks.append(scal_block)
        self.finish_blocks(app, blocks)
Example #11
0
    def create_block(self, holes, name):
        targetDepth = self.fromMm("TargetDepth")
        peck = self.fromMm("Peck")
        dwell = self["Dwell"]
        block = Block(name)
        holesCount = 0

        if self.useCustom:
            block.append("M3 S0")
        else:
            block.append(CNC.zsafe())

        for bid in holes:
            for xH, yH, zH in bid:
                holesCount += 1

                if self.useCustom:
                    block.append(
                        CNC.grapid(x=xH, y=yH) + CNC.fmt(' F', self.rFeed))
                else:
                    #block.append(CNC.zsafe()) # Moved up
                    block.append(CNC.grapid(xH, yH))

                if peck != 0:
                    z = 0
                    while z > targetDepth:
                        z = max(z - peck, targetDepth)
                        if self.useCustom:
                            block.append(
                                "( --- WARNING! Peck is not setup for laser mode --- )"
                            )
                            break
                        else:
                            block.append(CNC.zenter(zH + z))
                            block.append(CNC.zsafe())

                if self.useCustom:
                    block.append("G1 S%s" % (self.spinMax))
                    block.append(CNC.gline(x=xH, y=yH))
                else:
                    block.append(CNC.zenter(zH + targetDepth))

                # Dwell time only on last pass
                if dwell != 0:
                    block.append(CNC.gcode(4, [("P", dwell)]))

                if self.useCustom:
                    block.append("G1 S%s" % (self.spinMin))
                else:
                    block.append(CNC.zsafe())

        # Gcode Zsafe on finish
        if self.useCustom:
            block.append("M5")
        else:
            block.append(CNC.zsafe())
        return (block, holesCount)
Example #12
0
    def calc(self, xstart, ystart, xend, yend, radius, cw):
        self.Points = []
        self.corners = [
            min(float(xstart), float(xend)),
            min(float(ystart), float(yend)),
            max(float(xstart), float(xend)),
            max(float(ystart), float(yend)),
        ]

        xmin, ymin, xmax, ymax = self.corners[0], self.corners[
            1], self.corners[2], self.corners[3]
        r = min(radius, (xmax - xmin) / 2, (ymax - ymin) / 2)
        blocks = []
        block = Block(self.name)
        block.append(CNC.grapid(x=xmin, y=ymin + r))
        block.append(CNC.grapid(z=0.0))
        block.append("(entered)")
        if cw:
            block.append(CNC.gline(x=xmin, y=ymax - r))
            if r > 0:
                block.append(CNC.garc(2, x=xmin + r, y=ymax, i=r, j=0))
            if (xmax - xmin) > 2 * r:
                block.append(CNC.gline(x=xmax - r, y=ymax))
            if r > 0:
                block.append(CNC.garc(2, x=xmax, y=ymax - r, i=0, j=-r))
            if (ymax - ymin) > 2 * r:
                block.append(CNC.gline(x=xmax, y=ymin + r))
            if r > 0:
                block.append(CNC.garc(2, x=xmax - r, y=ymin, i=-r, j=0))
            if (xmax - xmin) > 2 * r:
                block.append(CNC.gline(x=xmin + r, y=ymin))
            if r > 0:
                block.append(CNC.garc(2, x=xmin, y=ymin + r, i=0, j=r))
        else:
            if r > 0:
                block.append(CNC.garc(3, x=xmin + r, y=ymin, i=r, j=0))
            if (xmax - xmin) > 2 * r:
                block.append(CNC.gline(x=xmax - r, y=ymin))
            if r > 0:
                block.append(CNC.garc(3, x=xmax, y=ymin + r, i=0, j=r))
            if (ymax - ymin) > 2 * r:
                block.append(CNC.gline(x=xmax, y=ymax - r))
            if r > 0:
                block.append(CNC.garc(3, x=xmax - r, y=ymax, i=-r, j=0))
            if (xmax - xmin) > 2 * r:
                block.append(CNC.gline(x=xmin + r, y=ymax))
            if r > 0:
                block.append(CNC.garc(3, x=xmin, y=ymax - r, i=0, j=-r))
            if (ymax - ymin) > 2 * r:
                block.append(CNC.gline(x=xmin, y=ymin + r))
        block.append("(exiting)")
        block.append(CNC.grapid(z=CNC.vars["safe"]))
        blocks.append(block)
        return blocks
Example #13
0
	def execute(self, app):
		rdoc = self["rdoc"]
		radius = self["dia"]/2
		cw = self["cw"]
		circ = self["circ"]

		#print("go!")
		blocks  = []
		for bid in app.editor.getSelectedBlocks():
			#print(blocks[bid])
			path = app.gcode.toPath(bid)[0]
			#print(path)

			block = Block("trochoid")

			entry = self["entry"]
			for segment in path:
				#print(segment.A)
				#block.append("g0 x0 y0")
				#block.append("g1 x10 y10")
				#block.append("g1 x20 y10")
				#block.append("g0 x0 y0")
				if entry:
					eblock = Block("trochoid-in")
					eblock.append("G0 Z0")
					eblock.append("G0 x"+str(segment.A[0])+" y"+str(segment.A[1]-radius))
					eblock.append("G2 x"+str(segment.A[0])+" y"+str(segment.A[1]-radius)+" i"+str(0)+" j"+str(radius))
					blocks.append(eblock)
					entry = False

				block.append("G0 Z0")
				block.extend(self.trochoid(segment, rdoc, radius, cw, circ))

			blocks.append(block)


		active = app.activeBlock()
		app.gcode.insBlocks(active, blocks, "Trochoidal created") #<<< insert blocks over active block in the editor
		app.refresh()                                                                                           #<<< refresh editor
		app.setStatus(_("Generated: Trochoidal"))                           #<<< feed back result
Example #14
0
    def execute(self, app):
        #print("go!")
        blocks = []

        paths_base = []
        paths_isl = []

        for bid in app.editor.getSelectedBlocks():
            if app.gcode[bid].operationTest('island'):
                paths_isl.extend(app.gcode.toPath(bid))
            else:
                paths_base.extend(app.gcode.toPath(bid))

        for island in paths_isl:
            paths_newbase = []
            while len(paths_base) > 0:
                base = paths_base.pop()

                base.intersectPath(island)
                island.intersectPath(base)

                newbase = Path("diff")

                #Add segments from outside of islands:
                for i, seg in enumerate(base):
                    if not island.isInside(seg.midPoint()):
                        newbase.append(seg)

                #Add segments from islands to base
                for i, seg in enumerate(island):
                    if base.isInside(seg.midPoint(
                    )):  #and base.isInside(seg.A) and base.isInside(seg.B):
                        newbase.append(seg)

                #Eulerize
                paths_newbase.extend(newbase.eulerize())
                #paths_newbase.extend(newbase.split2contours())
            paths_base = paths_newbase

        for base in paths_base:
            print(base)
            #base = base.eulerize(True)
            block = Block("diff")
            block.extend(app.gcode.fromPath(base))
            blocks.append(block)

        #active = app.activeBlock()
        app.gcode.insBlocks(
            -1, blocks,
            "Diff")  #<<< insert blocks over active block in the editor
        app.refresh()  #<<< refresh editor
        app.setStatus(_("Generated: Diff"))  #<<< feed back result
Example #15
0
	def splitBlocks(self, event=None):
		if not self._items: return
		all_items = self._items
		sel_items = list(map(int,self.curselection()))
		change = True
		newblocks = []
		for bid in sel_items:
			bl = Block(self.gcode[bid].name())
			for line in self.gcode[bid]:
				if line == "( ---------- cut-here ---------- )":
					#newblocks.append(bl)
					#self.insertBlock(bl)
					self.gcode.addUndo(self.gcode.addBlockUndo(bid+1,bl))
					bl = Block(self.gcode[bid].name())
				else:
					bl.append(line)
		self.gcode.addUndo(self.gcode.addBlockUndo(bid+1,bl))
		#newblocks.append(bl)
		#self.gcode.extend(newblocks)
		if change: self.fill()
		self.deleteBlock()
		self.winfo_toplevel().event_generate("<<Modified>>")
Example #16
0
    def execute(self, app):
        name = self["name"]
        if not name or name == "default": name = "Spiral"

        #Retrive data from user imput
        Size = self.fromMm("Size")
        Rotation = self["Rot"]
        CW = self["CW"]

        #grwoth per arc
        if Rotation <= 0: Rotation = 1
        grow = Size / Rotation / 4

        #Clockwise
        g = 2 if CW else 3

        #Initialize blocks that will contain our gCode
        blocks = []
        block = Block(name)

        #use some useful bCNC functions to generate gCode movement, see CNC.py for more

        block.append(
            "G0 Z3"
        )  #<<< Move rapid Z axis to the safe height in Stock Material
        block.append("G0 X0 Y0")  #<<< Move rapid to X and Y coordinate
        block.append(
            "G1 Z0 F100"
        )  #<<< Enter in the material with Plunge Feed for current material
        block.append("F600")  #<<< Feedrate
        x, y = 0, 0
        while abs(x) < Size / 2:
            lx = x  #<<< Save last x value
            x = abs(x) + grow  #<<< Add the growing value
            if lx >= 0: x = -x  #<<< Alternate sign
            dx = x - lx  #<<< Calculate delta X (r = i = dx/2)
            block.append(CNC.garc(g=g, x=x, i=dx / 2))

        #Circle with final Size
        block.append(CNC.garc(g=g, x=-x, i=-x))
        block.append(CNC.garc(g=g, x=x, i=x))

        blocks.append(block)
        active = app.activeBlock()
        app.gcode.insBlocks(
            active, blocks, "MyPlugins inserted"
        )  #<<< insert blocks over active block in the editor
        app.refresh()  #<<< refresh editor
        app.setStatus(_("Generated: Spiral"))  #<<< feed back result
Example #17
0
	def joinBlocks(self, event=None):
		if not self._items: return
		all_items = self._items
		sel_items = list(map(int,self.curselection()))
		change = True
		bl = Block(self.gcode[sel_items[0]].name())
		for bid in sel_items:
			for line in self.gcode[bid]:
				bl.append(line)
			bl.append("( ---------- cut-here ---------- )")
		del bl[-1]
		self.gcode.addUndo(self.gcode.addBlockUndo(bid+1,bl))
		if change: self.fill()
		self.deleteBlock()
		self.winfo_toplevel().event_generate("<<Modified>>")
Example #18
0
 def calc(self, xstart, ystart, xend, yend):
     points = []
     points.append(Vector(xstart, ystart))
     points.append(Vector(xend, yend))
     first = points[0]
     last = points[1]
     blocks = []
     block = Block(self.name)
     block.append(CNC.grapid(first.x(), first.y()))
     block.append(CNC.grapid(z=0.0))
     block.append("(entered)")
     block.append(CNC.gline(last.x(), last.y()))
     block.append("(exiting)")
     block.append(CNC.grapid(z=CNC.vars["safe"]))
     blocks.append(block)
     return blocks
Example #19
0
    def execute(self, app):
        blocks = []
        for bid in app.editor.getSelectedBlocks():
            if len(app.gcode.toPath(bid)) < 1: continue

            eblock = Block("closed " + app.gcode[bid].name())
            for path in app.gcode.toPath(bid):
                if not path.isClosed():
                    path.append(Segment(Segment.LINE, path[-1].B, path[0].A))
                eblock = app.gcode.fromPath(path, eblock)
            #blocks.append(eblock)
            app.gcode[bid] = eblock

        #active=-1 #add to end
        #app.gcode.insBlocks(active, blocks, "Path closed") #<<< insert blocks over active block in the editor
        app.refresh()  #<<< refresh editor
        app.setStatus(_("Generated: Closepath"))  #<<< feed back result
Example #20
0
		def addLines(lines):
			for line in lines.splitlines():
				# Create a new block
				if self.__lid is None:
					self.__bid += 1
					self.__lid = MAXINT
					block = Block()
					undoinfo.append(self.gcode.addBlockUndo(self.__bid,block))
					selitems.append((self.__bid, None))
				else:
					block = self.gcode.blocks[self.__bid]

				if self.__lid == MAXINT:
					selitems.append((self.__bid, len(block)))
				else:
					self.__lid += 1
					selitems.append((self.__bid, self.__lid))
				undoinfo.append(self.gcode.insLineUndo(self.__bid, self.__lid, line))
Example #21
0
 def execute(self, app):
     name = self["name"]
     if not name or name == "default":
         name = "Drillmark"
     marksize = self["Mark size"]
     x0 = self.fromMm("PosX")
     y0 = self.fromMm("PosY")
     marktype = self["Mark type"]
     block = Block(name + " %s diameter %s" %
                   (marktype, CNC.fmt("", marksize)))
     self.appendBurn(app, block)
     self.appendMark(app, block)
     active = app.activeBlock()
     if active == 0:
         active = 1
     blocks = [block]
     app.gcode.insBlocks(active, blocks, _("Manual drill mark"))
     app.refresh()  # <<< refresh editor
     app.setStatus(_("Generated: MyPlugin Result"))
Example #22
0
    def make(self, RExt=50., RInt=33., ROff=13., Depth=0):
        self.RExt = RExt
        self.RInt = RInt
        self.ROff = ROff

        if RExt > RInt:
            self.Spins = self.lcm(RExt, RInt) / max(RExt, RInt)
        else:
            self.Spins = self.lcm(RExt, RInt) / min(RExt, RInt)

        self.Depth = Depth
        self.PI = math.pi
        self.theta = 0.0

        blocks = []
        block = Block(self.name)

        block.append("(External Radius = %g)" % (self.RExt))
        block.append("(Internal Radius = %g)" % (self.RInt))
        block.append("(Offset Radius = %g)" % (self.ROff))

        xi, yi = zip(*(self.calc_dots()))

        block.append(CNC.zsafe())
        block.append(CNC.grapid(xi[0], yi[0]))

        currDepth = 0.
        stepz = CNC.vars['stepz']
        if stepz == 0: stepz = 0.001  #avoid infinite while loop

        while True:
            currDepth -= stepz
            if currDepth < self.Depth: currDepth = self.Depth
            block.append(CNC.zenter(currDepth))
            block.append(CNC.gcode(1, [("f", CNC.vars["cutfeed"])]))
            for x, y in zip(xi, yi):
                block.append(CNC.gline(x, y))
            block.append(CNC.gline(xi[0], yi[0]))
            if currDepth <= self.Depth: break

        block.append(CNC.zsafe())
        blocks.append(block)
        return blocks
Example #23
0
    def make(self):
        d = self.thick

        # Convert to external dimensions
        if self.dx < 0:
            dx = -self.dx - d * 2  # external to internal
        else:
            dx = self.dx

        if self.dy < 0:
            dy = -self.dy - d * 2  # external to internal
        else:
            dy = self.dy

        if self.dz < 0:
            dz = -self.dz - d * 2  # external to internal
        else:
            dz = self.dz

        blocks = []
        block = Block("%s-Bottom" % (self.name))
        block.append("(Box: %g x %g x %g)" % (self.dx, self.dy, self.dz))
        block.append("(Fingers: %d x %d x %d)" % (self.nx, self.ny, self.nz))
        self._rectangle(block, 0., -d, dx, dy, self.nx, -self.ny, 0, d)
        blocks.append(block)

        block = Block("%s-Left" % (self.name))
        self._rectangle(block, -(dz + 5 * d), -d, dz, dy, self.nz, self.ny, d,
                        d)
        blocks.append(block)

        block = Block("%s-Right" % (self.name))
        self._rectangle(block, dx + 3 * d, -d, dz, dy, self.nz, self.ny, d, d)
        blocks.append(block)

        block = Block("%s-Front" % (self.name))
        self._rectangle(block, 0, -(dz + 4 * d), dx, dz, -self.nx, -self.nz, 0,
                        0)
        blocks.append(block)

        block = Block("%s-Back" % (self.name))
        self._rectangle(block, 0, dy + 4 * d, dx, dz, -self.nx, -self.nz, 0, 0)
        blocks.append(block)

        block = Block("%s-Top" % (self.name))
        self._rectangle(block, dx + dz + 8 * d, -d, dx, dy, self.nx, -self.ny,
                        0, d)
        blocks.append(block)
        return blocks
Example #24
0
	def execute(self, app):
		#print("go!")
		blocks  = []
		for bid in app.editor.getSelectedBlocks():
			if len(app.gcode.toPath(bid)) < 1: continue
			path = app.gcode.toPath(bid)[0]
			x,y = path.center()
			eblock = Block("center of "+app.gcode[bid].name())
			eblock.append("G0 x"+str(x)+" y"+str(y))
			eblock.append("G1 Z0 F200")
			eblock.append("G0 Z10")
			blocks.append(eblock)


		#active = app.activeBlock()
		#if active == 0: active+=1
		active=-1 #add to end
		app.gcode.insBlocks(active, blocks, "Center created") #<<< insert blocks over active block in the editor
		app.refresh()                                                                                           #<<< refresh editor
		app.setStatus(_("Generated: Center"))                           #<<< feed back result
Example #25
0
    def slice(self, verts, faces, z, zout=None, axis='z'):
        tags = '[slice]'
        if axis == 'z': tags = '[slice,minz:%f]' % (float(z))
        block = Block("slice %s%f %s" % (axis, float(z), tags))

        #FIXME: slice along different axes
        if axis == 'x':
            plane_orig = (z, 0, 0)
            plane_norm = (1, 0, 0)
        elif axis == 'y':
            plane_orig = (0, z, 0)
            plane_norm = (0, 1, 0)
        else:
            plane_orig = (0, 0, z)  #z height to slice
            plane_norm = (0, 0, 1)

        #Crosscut
        contours = meshcut.cross_section(verts, faces, plane_orig, plane_norm)

        #Flatten contours
        if zout is not None:
            for contour in contours:
                for segment in contour:
                    segment[2] = zout

        #Contours to G-code
        for contour in contours:
            #print(contour)
            gtype = 0
            for segment in contour:
                block.append("g%s x%f y%f z%f" %
                             (gtype, segment[0], segment[1], segment[2]))
                gtype = 1
            block.append(
                "g1 x%f y%f z%f" %
                (contour[0][0], contour[0][1], contour[0][2]))  #Close shape
            block.append("( ---------- cut-here ---------- )")
        if block: del block[-1]

        if not block: block = None
        return block
Example #26
0
    def execute(self, app):
        #print("go!")
        blocks = []
        for bid in app.editor.getSelectedBlocks():
            if len(app.gcode.toPath(bid)) < 1: continue

            #nblock = Block("flat "+app.gcode[bid].name())
            #for i in app.gcode[bid]:
            #	nblock.append(re.sub(r"\s?z-?[0-9\.]+","",i))
            #blocks.append(nblock)

            eblock = Block("flat " + app.gcode[bid].name())
            eblock = app.gcode.fromPath(app.gcode.toPath(bid), eblock)
            blocks.append(eblock)

        #active = app.activeBlock()
        #if active == 0: active+=1
        active = -1  #add to end
        app.gcode.insBlocks(
            active, blocks, "Shape flattened"
        )  #<<< insert blocks over active block in the editor
        app.refresh()  #<<< refresh editor
        app.setStatus(_("Generated: Flat"))  #<<< feed back result
Example #27
0
    def execute(self, app):
        #print("go!")
        blocks = []

        bid = app.editor.getSelectedBlocks()[0]
        xbasepath = app.gcode.toPath(bid)[0]

        bid = app.editor.getSelectedBlocks()[1]
        xislandpath = app.gcode.toPath(bid)[0]

        xbasepath.intersectPath(xislandpath)
        xislandpath.intersectPath(xbasepath)

        #xnewisland = self.pathBoolIntersection(xbasepath, xislandpath)
        xnewisland = self.pathBoolIntersection(xislandpath, xbasepath)

        #pth = Path("temp")
        #basepath.invert()
        #pth.extend(basepath)
        #pth.extend(basepath)
        ##pth.invert()

        block = Block("diff")
        block.extend(app.gcode.fromPath(xnewisland))
        blocks.append(block)

        #block = Block("diff")
        #block.extend(app.gcode.fromPath(pth))
        #blocks.append(block)

        active = app.activeBlock()
        app.gcode.insBlocks(
            active, blocks,
            "Diff")  #<<< insert blocks over active block in the editor
        app.refresh()  #<<< refresh editor
        app.setStatus(_("Generated: Diff"))  #<<< feed back result
Example #28
0
 def create_block(self, holes, name):
     targetDepth = self.fromMm("TargetDepth")
     peck = self.fromMm("Peck")
     dwell = self["Dwell"]
     block = Block(name)
     holesCount = 0
     for bid in holes:
         for xH, yH, zH in bid:
             holesCount += 1
             block.append(CNC.zsafe())
             block.append(CNC.grapid(xH, yH))
             if (peck != 0):
                 z = 0
                 while z > targetDepth:
                     z = max(z - peck, targetDepth)
                     block.append(CNC.zenter(zH + z))
                     block.append(CNC.zsafe())
             block.append(CNC.zenter(zH + targetDepth))
             #dwell time only on last pass
             if dwell != 0:
                 block.append(CNC.gcode(4, [("P", dwell)]))
     #Gcode Zsafe on finish
     block.append(CNC.zsafe())
     return (block, holesCount)
Example #29
0
 def calc(self, xcenter, ycenter, radius, startangle, endangle):
     self.Points = []
     xcenter, ycenter, radius, startangle, endangle = float(xcenter), float(
         ycenter), abs(float(radius)), float(startangle), float(endangle)
     xstart = xcenter + radius * math.cos(startangle * math.pi / 180.0)
     xend = xcenter + radius * math.cos(endangle * math.pi / 180.0)
     ystart = ycenter + radius * math.sin(startangle * math.pi / 180.0)
     yend = ycenter + radius * math.sin(endangle * math.pi / 180.0)
     i = xcenter - xstart
     j = ycenter - ystart
     blocks = []
     block = Block(self.name)
     block.append(CNC.grapid(x=xstart, y=ystart))
     block.append(CNC.grapid(z=0.0))
     block.append("(entered)")
     if startangle < endangle:
         direction = 3
     else:
         direction = 2
     block.append(CNC.garc(direction, x=xend, y=yend, i=i, j=j))
     block.append("(exiting)")
     block.append(CNC.grapid(z=CNC.vars["safe"]))
     blocks.append(block)
     return blocks
Example #30
0
    def execute(self, app):
        if Image is None:
            app.setStatus(
                _("Halftone abort: This plugin requires PIL/Pillow to read image data"
                  ))
            return

        n = self["name"]
        if not n or n == "default": n = "Halftone"

        # Calc desired size
        channel = self["Channel"]
        invert = self["Invert"]
        drawSize = self["DrawSize"]
        cellSize = self["CellSize"]
        dMax = self["DiameterMax"]
        dMin = self["DiameterMin"]
        angle = self["Angle"]
        drawBorder = self["DrawBorder"]
        depth = self["Depth"]
        conical = self["Conical"]

        # Check parameters
        if drawSize < 1:
            app.setStatus(
                _("Halftone abort: Size too small to draw anything!"))
            return

        if dMin > dMax:
            app.setStatus(
                _("Halftone abort: Minimum diameter must be minor then Maximum"
                  ))
            return

        if dMax < 1:
            app.setStatus(_("Halftone abort: Maximum diameter too small"))
            return

        if cellSize < 1:
            app.setStatus(_("Halftone abort: Cell size too small"))
            return

        tool = app.tools["EndMill"]
        tool_shape = tool["shape"]
        if conical:
            if tool_shape == "V-cutting":
                try:
                    v_angle = float(tool["angle"])
                except:
                    app.setStatus(
                        _("Halftone abort: Angle in V-Cutting end mill is missing"
                          ))
                    return
            else:
                app.setStatus(
                    _("Halftone abort: Conical path need V-Cutting end mill"))
                return

        # Open picture file
        fileName = self["File"]
        try:
            img = Image.open(fileName)
        except:
            app.setStatus(_("Halftone abort: Can't read image file"))
            return

        # Create a scaled image to work faster with big image and better with small ones
        squareNorm = True
        if channel == 'Blue(sqrt)':
            img = img.convert('RGB')
            img = img.split()[0]
        elif channel == 'Green(sqrt)':
            img = img.convert('RGB')
            img = img.split()[1]
        elif channel == 'Red(sqrt)':
            img = img.convert('RGB')
            img = img.split()[2]
        else:
            img = img.convert('L')  # to calculate luminance
            squareNorm = False

        # flip image to ouput correct coordinates
        img = img.transpose(Image.FLIP_TOP_BOTTOM)

        # Calc divisions for halftone
        divisions = drawSize / cellSize
        # Get image size
        self.imgWidth, self.imgHeight = img.size
        if (self.imgWidth > self.imgHeight):
            scale = drawSize / float(self.imgWidth)
            sample = int(self.imgWidth / divisions)
        else:
            scale = drawSize / float(self.imgHeight)
            sample = int(self.imgHeight / divisions)
        self.ratio = scale

        # Halftone
        circles = self.halftone(img, sample, scale, angle, squareNorm, invert)

        # Init blocks
        blocks = []

        # Border block
        if drawBorder:
            block = Block("%s-border" % (self.name))
            block.append(CNC.zsafe())
            block.append(CNC.grapid(0, 0))
            block.append(CNC.zenter(depth))
            block.append(CNC.gcode(1, [("f", CNC.vars["cutfeed"])]))
            block.append(CNC.gline(self.imgWidth * self.ratio, 0))
            block.append(
                CNC.gline(self.imgWidth * self.ratio,
                          self.imgHeight * self.ratio))
            block.append(CNC.gline(0, self.imgHeight * self.ratio))
            block.append(CNC.gline(0, 0))
            blocks.append(block)

        # Draw block
        block = Block(self.name)

        # Change color
        if channel == 'Blue(sqrt)':
            block.color = "#0000ff"
        elif channel == 'Green(sqrt)':
            block.color = "#00ff00"
        elif channel == 'Red(sqrt)':
            block.color = "#ff0000"

        block.append("(Halftone size W=%d x H=%d x D=%d ,Total points:%i)" %
                     (self.imgWidth * self.ratio, self.imgHeight * self.ratio,
                      depth, len(circles)))
        block.append("(Channel = %s)" % channel)

        for c in circles:
            x, y, r = c
            r = min(dMax / 2.0, r)
            if (r >= dMin / 2.):
                block.append(CNC.zsafe())
                block.append(CNC.grapid(x + r, y))
                block.append(CNC.zenter(depth))
                block.append(CNC.garc(
                    CW,
                    x + r,
                    y,
                    i=-r,
                ))
        block.append(CNC.zsafe())
        if conical: block.enable = False
        blocks.append(block)

        if conical:
            blockCon = Block("%s-Conical" % (self.name))
            for c in circles:
                x, y, r = c
                blockCon.append(CNC.zsafe())
                blockCon.append(CNC.grapid(x, y))
                dv = r / math.tan(math.radians(v_angle / 2.))
                blockCon.append(CNC.zenter(-dv))
            blockCon.append(CNC.zsafe())
            blocks.append(blockCon)

        # Gcode Zsafe
        active = app.activeBlock()
        app.gcode.insBlocks(active, blocks, "Halftone")
        app.refresh()
        app.setStatus(
            _("Generated Halftone size W=%d x H=%d x D=%d ,Total points:%i" %
              (self.imgWidth * self.ratio, self.imgHeight * self.ratio, depth,
               len(circles))))