Esempio n. 1
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
Esempio n. 2
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)
Esempio n. 3
0
 def appendCross(block):
     block.append("m5")
     block.append(CNC.grapid(x=x0, y=y0 + marksizehalf, f=movefeed))
     block.append(self.getPowerLine(app))
     block.append(CNC.gline(y=y0 - marksizehalf, f=drawfeed))
     block.append("m5")
     block.append(CNC.grapid(x=x0 + marksizehalf, y=y0, f=movefeed))
     block.append(self.getPowerLine(app))
     block.append(CNC.gline(x=x0 - marksizehalf, f=drawfeed))
     block.append("m5")
Esempio n. 4
0
		def appendCross(block):
			block.append("m5")
			block.append(CNC.grapid(x=x0, y=y0 + marksizehalf, f=movefeed))
			block.append(self.getPowerLine(app))
			block.append(CNC.gline(y=y0 - marksizehalf, f=drawfeed))
			block.append("m5")
			block.append(CNC.grapid(x=x0 + marksizehalf, y=y0, f=movefeed))
			block.append(self.getPowerLine(app))
			block.append(CNC.gline(x=x0 - marksizehalf, f=drawfeed))
			block.append("m5")
Esempio n. 5
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
Esempio n. 6
0
		def appendCross45(block):
			msh = marksizehalf * self.sin45
			block.append("m5")
			block.append(CNC.grapid(x=x0 - msh, y=y0 + msh, f=movefeed))
			block.append(self.getPowerLine(app))
			block.append(CNC.gline(x=x0 + msh, y=y0 - msh, f=drawfeed))
			block.append("m5")
			block.append(CNC.grapid(x=x0 + msh, y=y0 + msh, f=movefeed))
			block.append(self.getPowerLine(app))
			block.append(CNC.gline(x=x0 - msh, y=y0 - msh, f=drawfeed))
			block.append("m5")
Esempio n. 7
0
 def appendCross45(block):
     msh = marksizehalf * self.sin45
     block.append("m5")
     block.append(CNC.grapid(x=x0 - msh, y=y0 + msh, f=movefeed))
     block.append(self.getPowerLine(app))
     block.append(CNC.gline(x=x0 + msh, y=y0 - msh, f=drawfeed))
     block.append("m5")
     block.append(CNC.grapid(x=x0 + msh, y=y0 + msh, f=movefeed))
     block.append(self.getPowerLine(app))
     block.append(CNC.gline(x=x0 - msh, y=y0 - msh, f=drawfeed))
     block.append("m5")
Esempio n. 8
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
Esempio n. 9
0
 def appendSpikes45(block):
     sinSpike = math.sin(math.atan(1.0 / math.sqrt(3)))
     cosSpike = math.cos(math.atan(1.0 / math.sqrt(3)))
     block.append("m5")
     block.append(CNC.grapid(x=x0, y=y0, f=movefeed))
     block.append(self.getPowerLine(app))
     block.append(
         CNC.gline(x=x0 + marksizehalf * sinSpike,
                   y=y0 - marksizehalf * cosSpike,
                   f=drawfeed))
     block.append(
         CNC.gline(x=x0 + marksizehalf * cosSpike,
                   y=y0 - marksizehalf * sinSpike,
                   f=drawfeed))
     block.append(
         CNC.gline(x=x0 - marksizehalf * cosSpike,
                   y=y0 + marksizehalf * sinSpike,
                   f=drawfeed))
     block.append(
         CNC.gline(x=x0 - marksizehalf * sinSpike,
                   y=y0 + marksizehalf * cosSpike,
                   f=drawfeed))
     block.append(CNC.gline(x=x0, y=y0, f=drawfeed))
     block.append(
         CNC.gline(x=x0 - marksizehalf * sinSpike,
                   y=y0 - marksizehalf * cosSpike,
                   f=drawfeed))
     block.append(
         CNC.gline(x=x0 - marksizehalf * cosSpike,
                   y=y0 - marksizehalf * sinSpike,
                   f=drawfeed))
     block.append(
         CNC.gline(x=x0 + marksizehalf * cosSpike,
                   y=y0 + marksizehalf * sinSpike,
                   f=drawfeed))
     block.append(
         CNC.gline(x=x0 + marksizehalf * sinSpike,
                   y=y0 + marksizehalf * cosSpike,
                   f=drawfeed))
     block.append(CNC.gline(x=x0, y=y0, f=drawfeed))
     block.append("m5")
     block.append(
         CNC.grapid(x=x0 + marksizehalf / 2,
                    y=y0 + marksizehalf / 2,
                    f=movefeed))
     block.append(self.getPowerLine(app))
     block.append(CNC.gline(x=x0 - marksizehalf / 2, f=drawfeed))
     block.append(CNC.gline(y=y0 - marksizehalf / 2, f=drawfeed))
     block.append(CNC.gline(x=x0 + marksizehalf / 2, f=drawfeed))
     block.append(CNC.gline(y=y0 + marksizehalf / 2, f=drawfeed))
     block.append("m5")
Esempio n. 10
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
Esempio n. 11
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
Esempio n. 12
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
Esempio n. 13
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
Esempio n. 14
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
Esempio n. 15
0
File: bowl.py Progetto: asm7100/bCNC
		def addSingleCircle(radius, depth):
			if pocket:
				block.append(CNC.grapid(0., 0.))
				block.append(CNC.zenter(depth))
				setCutFeedrate()
				currRadius = 0.
				while radius > currRadius+stepxy:
					currRadius += stepxy
					block.append(CNC.gline(currRadius, 0))
					addCircumference(currRadius)
				if radius-currRadius > 0:
					block.append(CNC.gline(radius, 0))
					addCircumference(radius)
			else:
				block.append(CNC.grapid(radius, 0.))
				block.append(CNC.zenter(depth))
				setCutFeedrate()
				addCircumference(radius)
Esempio n. 16
0
		def addSingleCircle(radius, depth):
			if pocket:
				block.append(CNC.grapid(0., 0.))
				block.append(CNC.zenter(depth))
				setCutFeedrate()
				currRadius = 0.
				while radius > currRadius+stepxy:
					currRadius += stepxy
					block.append(CNC.gline(currRadius, 0))
					addCircumference(currRadius)
				if radius-currRadius > 0:
					block.append(CNC.gline(radius, 0))
					addCircumference(radius)
			else:
				block.append(CNC.grapid(radius, 0.))
				block.append(CNC.zenter(depth))
				setCutFeedrate()
				addCircumference(radius)
Esempio n. 17
0
	def appendBurn(self, app, block):
		x0 = self.fromMm("PosX")
		y0 = self.fromMm("PosY")
		movefeed = app.cnc["cutfeed"]
		burntime = self["Burn time"]
		burnpower = self["Burn power"]
		block.append(CNC.grapid(x=x0, y=y0))
		block.append("g1 m3 %s" % (CNC.fmt('s', burnpower)))
		block.append("g4 %s" % (CNC.fmt('p', burntime)))
		block.append("m5")
Esempio n. 18
0
 def appendBurn(self, app, block):
     x0 = self.fromMm("PosX")
     y0 = self.fromMm("PosY")
     movefeed = app.cnc["cutfeed"]
     burntime = self["Burn time"]
     burnpower = self["Burn power"]
     block.append(CNC.grapid(x=x0, y=y0))
     block.append("g1 m3 %s" % (CNC.fmt('s', burnpower)))
     block.append("g4 %s" % (CNC.fmt('p', burntime)))
     block.append("m5")
Esempio n. 19
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
Esempio n. 20
0
 def appendCircle(block):
     block.append("m5")
     block.append(CNC.grapid(x=x0, y=y0 + marksizehalf / 2, f=movefeed))
     block.append(self.getPowerLine(app))
     block.append(
         CNC.garc(2,
                  x=x0,
                  y=y0 + marksizehalf / 2,
                  j=-marksizehalf / 2,
                  i=0,
                  f=drawfeed))
     block.append("m5")
Esempio n. 21
0
	def writeGlyphContour(self,block,font,contours,fontSize,depth,xO, yO):
		width = font.header.x_max - font.header.x_min
		height = font.header.y_max - font.header.y_min
		scale = fontSize / font.header.units_per_em
		xO = xO * fontSize
		yO = yO * fontSize
		for cont in contours:
			block.append(CNC.zsafe())
			block.append(CNC.grapid(xO + cont[0].x * scale , yO + cont[0].y * scale))
			block.append(CNC.zenter(depth))
			block.append(CNC.gcode(1, [("f",CNC.vars["cutfeed"])]))
			for p in cont:
				block.append(CNC.gline(xO + p.x * scale, yO + p.y * scale))
Esempio n. 22
0
	def writeGlyphContour(self,block,font,contours,fontSize,depth,xO, yO):
		width = font.header.x_max - font.header.x_min
		height = font.header.y_max - font.header.y_min
		scale = fontSize / font.header.units_per_em
		xO = xO * fontSize
		yO = yO * fontSize
		for cont in contours:
			block.append(CNC.zsafe())
			block.append(CNC.grapid(xO + cont[0].x * scale , yO + cont[0].y * scale))
			block.append(CNC.zenter(depth))
			block.append(CNC.gcode(1, [("f",CNC.vars["cutfeed"])]))
			for p in cont:
				block.append(CNC.gline(xO + p.x * scale, yO + p.y * scale))
Esempio n. 23
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
Esempio n. 24
0
		def appendSpikes45(block):
			sinSpike = math.sin(math.atan(1.0 / math.sqrt(3)))
			cosSpike = math.cos(math.atan(1.0 / math.sqrt(3)))
			block.append("m5")
			block.append(CNC.grapid(x=x0, y=y0, f=movefeed))
			block.append(self.getPowerLine(app))
			block.append(CNC.gline(x=x0 + marksizehalf * sinSpike, y=y0 - marksizehalf * cosSpike, f=drawfeed))
			block.append(CNC.gline(x=x0 + marksizehalf * cosSpike, y=y0 - marksizehalf * sinSpike, f=drawfeed))
			block.append(CNC.gline(x=x0 - marksizehalf * cosSpike, y=y0 + marksizehalf * sinSpike, f=drawfeed))
			block.append(CNC.gline(x=x0 - marksizehalf * sinSpike, y=y0 + marksizehalf * cosSpike, f=drawfeed))
			block.append(CNC.gline(x=x0, y=y0, f=drawfeed))
			block.append(CNC.gline(x=x0 - marksizehalf * sinSpike, y=y0 - marksizehalf * cosSpike, f=drawfeed))
			block.append(CNC.gline(x=x0 - marksizehalf * cosSpike, y=y0 - marksizehalf * sinSpike, f=drawfeed))
			block.append(CNC.gline(x=x0 + marksizehalf * cosSpike, y=y0 + marksizehalf * sinSpike, f=drawfeed))
			block.append(CNC.gline(x=x0 + marksizehalf * sinSpike, y=y0 + marksizehalf * cosSpike, f=drawfeed))
			block.append(CNC.gline(x=x0, y=y0, f=drawfeed))
			block.append("m5")
			block.append(CNC.grapid(x=x0 + marksizehalf / 2, y=y0 + marksizehalf / 2, f=movefeed))
			block.append(self.getPowerLine(app))
			block.append(CNC.gline(x=x0 - marksizehalf / 2, f=drawfeed))
			block.append(CNC.gline(y=y0 - marksizehalf / 2, f=drawfeed))
			block.append(CNC.gline(x=x0 + marksizehalf / 2, f=drawfeed))
			block.append(CNC.gline(y=y0 + marksizehalf / 2, f=drawfeed))
			block.append("m5")
Esempio n. 25
0
    def make(self, RExt=50.0, RInt=33.0, ROff=13.0, 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.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
Esempio n. 26
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
Esempio n. 27
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)
Esempio n. 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)
Esempio n. 29
0
File: gear.py Progetto: multpix/bCNC
	def calc(self, N, phi, Pc):
		N = abs(N)
		# Pitch Circle
		D = N * Pc / math.pi
		R = D / 2.0

		# Diametrical pitch
		Pd = N / D

		# Base Circle
		Db = D * math.cos(phi)
		Rb = Db / 2.0

		# Addendum
		a = 1.0 / Pd

		# Outside Circle
		Ro = R + a
		Do = 2.0 * Ro

		# Tooth thickness
		T = math.pi*D / (2*N)

		# undercut?
		U = 2.0 / (math.sin(phi) * (math.sin(phi)))
		needs_undercut = N < U
		# sys.stderr.write("N:%s R:%s Rb:%s\n" % (N,R,Rb))

		# Clearance
		c = 0.0
		# Dedendum
		b = a + c

		# Root Circle
		Rr = R - b
		Dr = 2.0*Rr

		two_pi = 2.0*math.pi
		half_thick_angle = two_pi / (4.0*N)
		pitch_to_base_angle = self.involute_intersect_angle(Rb, R)
		pitch_to_outer_angle = self.involute_intersect_angle(Rb, Ro) # pitch_to_base_angle

		points = []
		for x in range(1,N+1):
			c = x * two_pi / N

			# angles
			pitch1 = c - half_thick_angle
			base1  = pitch1 - pitch_to_base_angle
			outer1 = pitch1 + pitch_to_outer_angle

			pitch2 = c + half_thick_angle
			base2  = pitch2 + pitch_to_base_angle
			outer2 = pitch2 - pitch_to_outer_angle

			# points
			b1 = self.point_on_circle(Rb, base1)
			p1 = self.point_on_circle(R,  pitch1)
			o1 = self.point_on_circle(Ro, outer1)
			o2 = self.point_on_circle(Ro, outer2)
			p2 = self.point_on_circle(R,  pitch2)
			b2 = self.point_on_circle(Rb, base2)

			if Rr >= Rb:
				pitch_to_root_angle = pitch_to_base_angle - self.involute_intersect_angle(Rb, Rr)
				root1 = pitch1 - pitch_to_root_angle
				root2 = pitch2 + pitch_to_root_angle
				r1 = self.point_on_circle(Rr, root1)
				r2 = self.point_on_circle(Rr, root2)

				points.append(r1)
				points.append(p1)
				points.append(o1)
				points.append(o2)
				points.append(p2)
				points.append(r2)
			else:
				r1 = self.point_on_circle(Rr, base1)
				r2 = self.point_on_circle(Rr, base2)
				points.append(r1)
				points.append(b1)
				points.append(p1)
				points.append(o1)
				points.append(o2)
				points.append(p2)
				points.append(b2)
				points.append(r2)

		first = points[0]
		del points[0]

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

		block.append(CNC.grapid(first.x(), first.y()))
		block.append(CNC.zenter(0.0))
		#print first.x(), first.y()
		for v in points:
			block.append(CNC.gline(v.x(), v.y()))
			#print v.x(), v.y()
		#print first.x(), first.y()
		block.append(CNC.gline(first.x(), first.y()))
		block.append(CNC.zsafe())

		#block = Block("%s-center"%(self.name))
		block = Block("%s-basecircle"%(self.name))
		block.enable = False
		block.append(CNC.grapid(Db/2, 0.))
		block.append(CNC.zenter(0.0))
		block.append(CNC.garc(CW, Db/2, 0., i=-Db/2))
		block.append(CNC.zsafe())
		blocks.append(block)
		return blocks
Esempio n. 30
0
	def execute(self, app):
#		ae = self.fromMm("ae")
		if self["splicesteps"] =="" or self["splicesteps"]<4:
			steps=4/(2*pi)
		else:
			steps=self["splicesteps"]/(2*pi)

#		manualsetting = self["manualsetting"]
		manualsetting = 1
#=========== Converted to comment and changed for current compatibility ==============================
#		cutradius = CNC.vars["trochcutdiam"]/2.0
		cutradius = self["diam"]/2.0
#		cutradius = CNC.vars["trochcutdiam"]/2.0
#=========================================================================================
		zfeed = CNC.vars["cutfeedz"]
		feed =CNC.vars["cutfeed"]
		minimfeed =CNC.vars["cutfeed"]
		if manualsetting:
			if self["diam"]:
				cutradius = self["diam"]/2.0

			if self["zfeed"] and self["zfeed"]!="":
				zfeed = self["zfeed"]

#			if self["minimfeed"] and self["minimfeed"]!="":
#				minimfeed = min (self["minimfeed"],feed)

			if self["feed"] and self["feed"]!="":
				feed = self["feed"]
	
			if self["endmill"]:
				self.master["endmill"].makeCurrent(self["endmill"])



#		radius = CNC.vars["cutdiam"]/2.0
#		radius = self["diam"]/2.0
		toolRadius = CNC.vars["diameter"]/2.0
		radius = max(0,cutradius-toolRadius)
		oldradius=radius
#-----------------------------------------------------------
#		helicalRadius = self["helicalDiam"]/2.0
#		if helicalRadius=="":
#			helicalRadius=radius
#		else:
#			helicalRadius=max(0,helicalRadius- toolRadius)
		helicalRadius=radius
#-----------------------------------------------------------

#		helicalRadius=min(0.99*toolRadius,helicalRadius)
#		if radius!=0:
#			helicalRadius= min(helicalRadius,radius)
		helicalPerimeter=pi*2.0*helicalRadius		
	
	#	helicalangle = self["helicalangle"]
	#	if helicalangle>89.5:
	#		helicalangle=89.5
	#	if helicalangle<0.01:
	#		helicalangle=0.01
	#	downPecking=helicalPerimeter*tan(radians(helicalangle))

		cw = self["cw"]
		surface = CNC.vars["surface"]
#=========== Converted to comment and changed for current compatibility ==============================
#		zbeforecontact=surface+CNC.vars["zretract"]
#		zbeforecontact=surface+CNC.vars["zretract"]
#		hardcrust = surface - CNC.vars["hardcrust"]
#		feedbeforecontact = CNC.vars["feedbeforecontact"]/100.0
#		hardcrustfeed = CNC.vars["hardcrustfeed"]/100.0

		zbeforecontact=surface
		zbeforecontact=surface
		hardcrust = surface
		feedbeforecontact = zfeed
		hardcrustfeed = feed
#=====================================================================================================

		t_splice = self["TypeSplice"]
		dtadaptative = 0.0001
		adaptativepolice=0
#		minimradius = min(radius, toolRadius*self["MinTrochDiam"]/(100))
#		minimradius = min(radius, toolRadius*self["MinTrochDiam"]/(100))
#		minimradius = min(radius, toolRadius*CNC.vars["mintrochdiam"]/(100))
		atot = self.fromMm("ae")
#		spiral_twists=(radius-helicalRadius)/atot#<<spiral ae smaller than ae (aprox 50%)
#		if (radius-helicalRadius)%atot: spiral_twists=1+(radius-helicalRadius)//atot
		spiral_twists=ceil(radius-helicalRadius)/atot#<<spiral ae smaller than ae (aprox 50%)

		rpm = self["rpm"]

		downPecking=helicalPerimeter*zfeed/feed
		helicalangle=degrees(atan2(downPecking,helicalPerimeter))

#		steps=self["splicesteps"]/2*pi

#		K_Z = self["K_Z"]
#		if K_Z == "":
#			K_Z = 1.0
#		K_XY = self["K_XY"]
#		if K_XY == "": 
#			K_XY = 1.0
#		s_z = self["S_z"]
#		s_xy = self["S_xy"]
#		xyfeed = CNC.vars["cutfeed"]
#		zfeed *= K_Z
#		xyfeed *=K_XY		


		# Get selected blocks from editor
#	def trochprofile_bcnc(self, cutDiam=0.0, direction=None, offset=0.0, overcut=False,adaptative=False, adaptedRadius=0.0, tooldiameter=0.0, name=None):

#		app.trochprofile_bcnc(trochcutdiam, direction, self["offset"], self["overcut"], self["adaptative"], cornerradius, CNC.vars["diameter"], name) #<< diameter only to information
	#	cornerradius = (cutradius - CNC.vars["diameter"]/2.0
		direction=self["direction"]
		if direction!="on (3d Path)":
			targetDepth=self["targetDepth"]
			depthIncrement=self["depthIncrement"]
#			tabsnumber=self["tabsnumber"]
#			tabsWidth=self["tabsWidth"]
#			tabsHeight=self["tabsHeight"]
			tabsnumber=tabsWidth=tabsHeight=0

			app.trochprofile_bcnc(2*cutradius, direction,self["offset"], self["overcut"], self["adaptative"], radius, CNC.vars["diameter"],\
				targetDepth, depthIncrement, tabsnumber, tabsWidth, tabsHeight)
			app.refresh()
#		app.editor.selectAll()

		selBlocks = app.editor.getSelectedBlocks()
#		if not selBlocks:
#			app.editor.selectAll()
#			selBlocks = app.editor.getSelectedBlocks()

		if not selBlocks:
			app.setStatus(_("Trochoid abort: Please select some path"))
			return 
		#Check inputs
		if cutradius <= toolRadius:
				app.setStatus(_("Trochoid Cut Diameter has to be greater than End mill"))
				return

		if helicalRadius <= 0.0:
				app.setStatus(_("Helical Descent Diameter has to be greater than End mill"))
				return

		if feed <= 0:
				app.setStatus(_("Feed has to be greater than 0"))
				return

		if zfeed <= 0:
				app.setStatus(_("Plunge Feed has to be greater than 0"))
				return

		if minimfeed <= 0:
				app.setStatus(_("Minimum Adaptative Feed has to be greater than 0"))
				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"
#		newname = Block.operationName(path.name)
		n="Troch3d"
		tr_block = Block(n)
		phi=oldphi=0# oldadaptativephi=0
		oldsegm=[[0,0,0],[0,0,0]]

#		segments ---------------------------------------------
		for idx, segm in enumerate(bidSegment):
			if idx >= 0:
				if cw:
					u = 1
					arc = "G2"
				else:
					u = -1
					arc = "G3"				
#		////////////---------------------------------------------------------------------
#		information: ---------------------------------------------------------------------
				segLength = self.calcSegmentLength(segm)
	#			    ---------------------------------------------
	#				tr_block.append("(seg length "+str(round(segLength,4))+" )")
	#				-----------------------------------------------------------------------------
	#				////////----------------------------------------------------------------------
				if idx == 0:
#					tr_block.append("(--------------   PARAMETERS   ------------------------)")
					tr_block.append("(Cut diam "+str( cutradius*2 )+" (troch "+str(radius*2.0)+"+End mill "+str(toolRadius*2.0)+" ) Advance "+str(atot)+" )")
#					tr_block.append("(Cut diam "+str(CNC.vars["trochcutdiam"])+" (troch "+str(radius*2.0)+" + End mill " + str(toolRadius*2.0)+" ) Advance "+str(atot)+" )")
#					tr_block.append("(Min troch "+str(int(CNC.vars["mintrochdiam"]))+"%  = "+str(minimradius*2.0)+"mm , min cut diam "+str(2*(minimradius+toolRadius))+"mm )")
					tr_block.append("(Feed "+str(feed)+" Plunge feed "+ str(zfeed)+" )")
					#tr_block.append("(Helical diam "+str(round((helicalRadius+toolRadius)*2,2))+" ( helical diam "+str(helicalRadius*2.0)+"+End mill "+str(toolRadius*2.0)+" )")
					tr_block.append("(Helical descent angle " + str(round(helicalangle,2)) +" cut diam " + str(round(helicalRadius*2.0,3))+"  drop by lap "\
										+ str(round(downPecking,2)) + " )")
					tr_block.append("(--------------------------------------------------)")
					tr_block.append("(M06 T0 "+str(toolRadius*2.0)+" mm)")
					tr_block.append("M03")
					tr_block.append("S "+str(rpm))
					tr_block.append("F "+str(feed))
#					phi = atan2(segm[1][1]-segm[0][1], segm[1][0]-segm[0][0])
#					oldphi=phi #<< declare initial angle
#					l = self.pol2car(radius, phi+radians(90*u))
#					r = self.pol2car(radius, phi+radians(-90*u))
#					B = segm[1][0],segm[1][1],segm[1][2]
#					bl = self.pol2car(radius, phi+radians(90*u), B)
#					br = self.pol2car(radius, phi+radians(-90*u), B)
					tr_block.append("( Seg: "+str(idx)+"   length "+str(round(segLength,4))+"  phi "+str(round(degrees(phi),2))+" )")#+ "  oldphi  "+str(round(oldphi*57.29,2))+"   )")
					tr_block.append("(Starting point)")
					if (round(segm[1][1]-segm[0][1],4)==0 and round(segm[1][0]-segm[0][0],4)==0):
						phi=1234567890
						tr_block.append("(The original first movement is vertical)")
					else:
						tr_block.append("(The original first movement is not vertical)")
					tr_block.append(CNC.zsafe())
#					tr_block.append("g0 x "+str(B[0])+" y"+str(B[1])+" )")#" z "+str(B[2])+" )")
#							tr_block.append(arc+" x"+str(bl[0])+" y"+str(bl[1])+" R "+str(radius/2.0)+" z"+str(B[2]))
#					tr_block.append(arc+" x"+str(br[0])+" y"+str(br[1])+" i"+str(r[0]/2.0)+" j"+str(r[1]/2.0))	#<< as cutting					
#					tr_block.append(("g1 x "+str(br[0])+" y"+str(br[1])+" z"+str(B[2])))
#						tr_block.append(arc+" x"+str(bl[0])+" y"+str(bl[1])+" i"+str(l[0])+" j"+str(l[1]))						
#						tr_block.append(arc+" x"+str(br[0])+" y"+str(br[1])+" i"+str(r[0])+" j"+str(r[1])+" z"+str(round(B[2],5)))	#<< as cutting
#					if t_splice=="Circular both sides rectified":
#						tr_block.append(arc+" x"+str(bl[0])+" y"+str(bl[1])+" i"+str(-r[0])+" j"+str(-r[1]))						
					tr_block.append("(--------------------------------------------------)")

#						tr_block.append(CNC.grapid(br[0],br[1],B[2]))
#						tr_block.append(CNC.zsafe()) 			#<<< Move rapid Z axis to the safe height in Stock Material
#						tr_block.append(CNC.zenter(surface)) # <<< TROCHOID CENTER
#						tr_block.append(CNC.grapid(segm[1][0],segm[1][1],segm[1][2]))
#						tr_block.append(CNC.zbeforecontact()) # <<< TROCHOID CENTER
#						tr_block.append(CNC.xyslowentersurface(0,-45.0)) # <<< TROCHOID CENTER
#						tr_block.append(("g0 z "+str(zbeforecontact)))
#				tr_block.append("( new segment begins )")
	#					distance to trochoid center

					# if there is movement in xy plane phi calculate
				if (segm[1][1]-segm[0][1]!=0 or segm[1][0]-segm[0][0]!=0):
					phi = atan2(segm[1][1]-segm[0][1], segm[1][0]-segm[0][0])
#					On surface
#					if segm[0][2]>zbeforecontact and segm[1][2]>zbeforecontact:
					if segm[0][2]>surface and segm[1][2]>surface:
						tr_block.append("(Seg: "+str(idx)+" length "+str(round(segLength,4))+" phi "+str(round(degrees(phi),2))+ " On Surface)" )
						tr_block.append(CNC.grapid(segm[1][0],segm[1][1],segm[1][2]))
					else:
						tr_distance = self.center_distance(segm,atot)
						A = segm[0][0],segm[0][1],segm[0][2]
						d=segLength
						ae = tr_distance[4]
	#				////////////---------------------------------------------------------------------
	#				information: ---------------------------------------------------------------------
						adv = tr_distance[3] #<<< 
						ap = tr_distance[2] # << =zadd
	#			    ---------------------------------------------
						tr_block.append("(-----------------------------------------)")
						control_cameback = self.came_back(segm, oldsegm)
						if control_cameback:
							tr_block.append("(-------------> Came back !! <------------- )")#+str(control_cameback)+" )")
	#						tr_block.append("( old  Ax "+str(round(oldsegm[0][0],3))+" Ay "+str(round(oldsegm[0][1],3))+" Bx "+ str(round(oldsegm[1][0],3))+" By "+ str(round(oldsegm[1][1],3))+" )")
	#						tr_block.append("( curr Ax "+str(round(segm[0][0],3))+" Ay "+str(round(segm[0][1],3))+" Bx "+ str(round(segm[1][0],3))+" By "+ str(round(segm[1][1],3))+" )")
						if round(segLength,5) <= dtadaptative:
							adaptativepolice+=1.0
							tr_block.append("(Seg "+str(idx)+" adaptativepolice " +str(adaptativepolice)+" length "+str(round(segLength,5))+" )")
#	///////////	Trochoid method //////////////////////////////////////////////////////////////////////////////
						if adaptativepolice==0 or adaptativepolice >2.5:

							tr_block.append("( Seg: "+str(idx)+" phi "+str(round(degrees(phi),2))+ " oldphi "+str(round(degrees(oldphi),2))+" length "+str(round(segLength,5))+" )")
							tr_block.append("(ae: "+str(round(ae,5))+" dz: "+str(round(ap,4))+"adv: "+str(round(adv,4))+" )")
		#					tr_block.append("( Bx "+str(round(segm[1][0],2))+ " By "+ str(round(segm[1][1],2)))
		#					-----------------------------------------------------------------------------
		#					////////----------------------------------------------------------------------
							if control_cameback:
		#						adaptativepolice+=0.5
								B = segm[1][0],segm[1][1],segm[1][2]
		#								tr_block.append(CNC.gline(segm[1][0],segm[1][1],segm[1][2]))
								t_splice="came_back"
#								tr_block.extend(self.trochoid(t_splice,A,B,minimradius,radius,oldphi,phi,cw))
								tr_block.extend(self.trochoid(t_splice,A,B,0.0,radius,oldphi,phi,cw))
								tr_block.append("F "+ str(feed))
								t_splice = self["TypeSplice"]

							else:
								# from POINT A -- to ---> POINT B
								if segLength<=adv:
									tr_block.append("(Only one trochoid, oldphi "+str(round(degrees(oldphi),2))+" )")
									tr_block.extend(self.trochoid(t_splice,A,B,oldradius,radius,oldphi,phi,cw))
								while d >adv:
			#					first trochoid
			#						tr_block.append("d "+ str(d))
									B = A[0]+tr_distance[0], A[1]+tr_distance[1], A[2]+tr_distance[2]
								# intermediates points = trochoids points 
			#						tr_block.append(CNC.gline(B[0],B[1],B[2])) # <<< TROCHOID CENTER
		#							tr_block.extend(self.trochoid(A,B,radius,phi,oldphi,cw))

									tr_block.append("(distance to end segment "+str(round(d,4))+" )")
									tr_block.extend(self.trochoid(t_splice,A,B,oldradius,radius,oldphi,phi,cw))
									A=B
									d-=adv
									oldphi=phi
			#					last point
								if  B[0] != segm[1][0] or B[1] != segm[1][1] or B[2] != segm[1][2]:
									B = segm[1][0],segm[1][1],segm[1][2]
			#						tr_block.append(CNC.gline(B[0],B[1],B[2]))  # <<< TROCHOID CENTER
									tr_block.append("(---last trochoid, distance to end segment "+str(round(d,4))+" ---)")
									tr_block.extend(self.trochoid(t_splice,A,B,oldradius,radius,phi,phi,cw))
							adaptativepolice=0

		#	///////	Adapative method //////////////////////////////////////////////////////////////////////////////////////////////////////////
#						if oldphi==3600:
						else:
							if adaptativepolice==1:
								#goes to de two warning movements 
								lastphi=oldphi
								tr_block.append("( Alarm "+ str(adaptativepolice)+"  Seg: "+str(idx)+" phi " + str(round(degrees(phi),2))\
												 + "oldphi "+str(round(degrees(oldphi),2))+ " )")
	#							difangle=(phi-oldadaptativephi)
	#							tr_block.append("(dif angle:"+str(round(difangle,4))+" )")
	#							oldadaptativephi=oldphi=phi
								# round(difangle,5)==round(pi,5):
							elif adaptativepolice==2:
								phi=lastphi
								if control_cameback:# abs(round(difangle,6)) == (round(pi,6)):
									tr_block.append("(Starts adaptative trochoids"+" adaptativepolice "+str(adaptativepolice) )
									adaptativepolice +=0.5
							elif adaptativepolice==2.5:
#								tr_block.append("(-----------------------------------------)")
#								adaptradius=minimradius
								tr_block.append("(Adaptative Seg: "+str(idx)+"   length "+str(round(segLength,5))+"  phi "+str(round(degrees(phi),2))\
												+" oldphi "+str(round(degrees(oldphi),2))+" )")
#								tr_block.append("( Ax "+str(round(segm[0][0],2))+ " Ay "+ str(round(segm[0][1],2)))

#								tr_block.append(CNC.gline(segm[1][0],segm[1][1],segm[1][2]))
								# from POINT A -- to ---> POINT B
#								if adaptativepolice==1:
								tr_distance = self.center_distance(segm,atot/3.0) #<<< short advanc distances 

								A = segm[0][0],segm[0][1],segm[0][2]
								d=segLength
								ae = tr_distance[4]
								adv = tr_distance[3] #<<< 
								d-=adv
								while d >0:#adv:
			#					first trochoid
									if d!=segLength-adv:
										oldphi=phi
			#						tr_block.append("d "+ str(d))
									B = A[0]+tr_distance[0], A[1]+tr_distance[1], A[2]+tr_distance[2]
									#------------------------------
									# adaptradius= a*d + minimradius
									# if d=0 : adaptradius=minimradius
									# if d=seglength : adaptradius=radius
#									a=(radius-minimradius)/segLength
#									adaptradius=a*d+minimradius
									a=radius/segLength
									adaptradius=(self.roundup(a*d,4))#+minimradius
												#------------------------------
									if t_splice!="Splices":
										t_splice="Warpedarc"
									tr_block.append("(from trochoid distance to end segment "+str(round(d,4))+" )")
									tr_block.append("(adaptradius "+ str(round(adaptradius,4))+" radius " + str(radius)+" )")
#									tr_block.append("F "+ str(feed*adaptradius//radius))
									tr_block.append("F "+ str(minimfeed+(feed-minimfeed) *adaptradius//radius))
									if adaptradius>0.0:
										tr_block.extend(self.trochoid(t_splice,A,B,oldradius,adaptradius,oldphi,phi,cw))
									else:
										tr_block.append("(R= "+str(adaptradius)+ "not sent )")
#										tr_block.append("G1 x"+str(round(B[0],4))+" y "+str(round(B[1],4))+" z "+str(round(B[2],4)))
									A=B
									d-=adv
									oldradius=adaptradius
#										oldadaptativephi=0
			#REVISAR, A COMENTADO
			#					last point
					#			d=0
					#			oldradius=adaptradius
					#			adaptradius=minimradius
					#			if  B[0] != segm[1][0] or B[1] != segm[1][1] or B[2] != segm[1][2]:
					#				B = segm[1][0],segm[1][1],segm[1][2]
			#						tr_block.append(CNC.gline(B[0],B[1],B[2]))  # <<< TROCHOID CENTER
					#				tr_block.append("(last trochoid, from trochoid distance to end segment "+str(round(d,4))+" )")
					#				tr_block.append("(adaptradius "+ str(adaptradius)+" )")
					#				tr_block.append("F "+ str(feed*adaptradius//radius))
					#				tr_block.extend(self.trochoid(t_splice,A,B,oldradius,adaptradius,phi,phi,cw))

								adaptativepolice=0
								tr_block.append("(Adaptative Completed)")
								tr_block.append("F "+ str(feed//3))

#								if adaptativepolice>1:
							t_splice = self["TypeSplice"]
#							adaptativepolice=0
							oldradius=radius
						oldsegm=segm
					oldphi=phi
#	///////	Vertical movement ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
				elif idx!=0:	
					tr_block.append("(Seg: "+str(idx)+" length "+str(round(segLength,4))+" phi "+str(round(degrees(phi),2))+" oldphi "+str(round(degrees(oldphi),2))+" )" )
					tr_block.append("(Helical descent")
#						descent
					A=segm[0][0],segm[0][1],segm[0][2]
					if segm[0][2] > segm[1][2]:
						if segm[0][2] >zbeforecontact:# and segm[1][2]<=surface:
							if segm[1][2]<=zbeforecontact:
								B = segm[1][0],segm[1][1],max(segm[1][2],zbeforecontact)
								tr_block.append("(Rapid helical to z before contact "+"helicalRadius "+str(helicalRadius)+" )")
								if idx==1 and oldphi==1234567890:
									tr_block.append("g0 x "+str(B[0])+" y"+str(B[1])+" )")#" z "+str(B[2])+" )")
								tr_block.extend(self.helical(A,B,helicalRadius,phi,u))

	#						Instead of decreasing the speed, to avoid the jerkl, decrease the drop by lap
						if segm[0][2] >surface:# and segm[1][2]<=surface:
							if segm[1][2]<=surface:
								tr_block.append("(Slow helical to surface )" )
								A=A[0],A[1],zbeforecontact
								d=A[2]-surface
								adv=downPecking * feedbeforecontact
								while d > adv:
									B = segm[1][0],segm[1][1],max(segm[1][2],A[2]-adv)
									tr_block.extend(self.helical(A,B,helicalRadius,phi,u))
									A=A[0],A[1],B[2]
									d-=adv
								B = segm[1][0],segm[1][1],surface
								tr_block.extend(self.helical(A,B,helicalRadius,phi,u))

						if segm[0][2] >hardcrust:# and segm[1][2]<=surface:
							if hardcrust< surface:
								if segm[1][2]<=hardcrust:	
									tr_block.append("(Helical in hard crust)" )
									A=A[0],A[1],surface
									d=A[2]-hardcrust
									adv=downPecking * hardcrustfeed
									while d > adv:
										B = segm[1][0],segm[1][1],max(segm[1][2],A[2]-adv)
										tr_block.extend(self.helical(A,B,helicalRadius,phi,u))
										A=A[0],A[1],B[2]
										d-=adv
									B = segm[1][0],segm[1][1],hardcrust
									tr_block.extend(self.helical(A,B,helicalRadius,phi,u))
						
						tr_block.append("(Helical to target )" )
						A=A[0],A[1],hardcrust
						d=A[2]-segm[1][2]
						adv=downPecking
						while d > adv:
							B = segm[1][0],segm[1][1],A[2]-adv
							tr_block.extend(self.helical(A,B,helicalRadius,phi,u))
							A=A[0],A[1],B[2]
							d-=adv
						B = segm[1][0],segm[1][1],segm[1][2]
						tr_block.extend(self.helical(A,B,helicalRadius,phi,u))
						tr_block.append("(Flatten)")
						tr_block.extend(self.helical(B,B,helicalRadius,phi,u))
						if round(helicalRadius,4)!=round(radius,4):
							tr_block.append("(Spiral adjustement)")
	#								tr_block.extend(self.trochoid(t_splice,B,B,radius,helicalRadius,phi,phi+4*pi,cw))
	#						steps=max(1,int(steps*radius*(spiral_twists)/2.0))
	#						steps=min(steps, 12*spiral_twists)
	#						steps*=spiral_twists
#							tr_block.append("(Spiral steps "+str(steps)+" in "+str(int((spiral_twists/2.)+1))+" twists)")
#							tr_block.append("(Spiral "+str(int((spiral_twists/2.)+1))+" twists)")
							tr_block.append("(Spiral "+str(spiral_twists)+" twists)")
							tr_block.extend(self.splice_generator(B,B,helicalRadius,radius,phi,phi-spiral_twists*2*pi, radians(-90),radians(-90),u,1.2*steps))
							tr_block.append("(Target diameter)")
#							tr_block.extend(self.helical(B,B,radius,phi,u))
							tr_block.extend(self.trochoid(t_splice,B,B,radius,radius,phi,phi,cw))

#						ascent
					elif segm[1][2] > segm[0][2]:
						tr_block.append("(Helical rapid ascentt "+"helicalRadius "+str(helicalRadius)+" )" )
						B = segm[1][0],segm[1][1],segm[1][2]
						tr_block.extend(self.helical(A,B,helicalRadius,phi,u))
	#					tr_block.append(CNC.grapid(center[0],center[1],center[2]))
	#					tr_block.extend(CNC.grapid(center))
	#					end of segment
	#					tr_block.append(CNC.gline(segm[1][0],segm[1][1],segm[1][2]))
#					oldsegm=segm
		tr_block.append("(-----------------------------------------)")
		tr_block.append(CNC.zsafe()) 			#<<< Move rapid Z axis to the safe height in Stock Material
		blocks.append(tr_block)
		self.finish_blocks(app, blocks)
Esempio n. 31
0
	def execute(self, app):
		#Get inputs
		holesDistance = self.fromMm("HolesDistance")
		targetDepth = self.fromMm("TargetDepth")
		peck = self.fromMm("Peck")
		dwell = self["Dwell"]

		zSafe = CNC.vars["safe"]

		#Check inputs
		if holesDistance <=0:
			app.setStatus(_("Driller abort: Distance must be > 0"))
			return

		if peck <0:
			app.setStatus(_("Driller abort: Peck must be >= 0"))
			return

		if dwell <0:
			app.setStatus(_("Driller abort: Dwell time >= 0, here time runs only forward!"))
			return

		# Get selected blocks from editor
		selBlocks = app.editor.getSelectedBlocks()
		if not selBlocks:
			app.editor.selectAll()
			selBlocks = app.editor.getSelectedBlocks()

		if not selBlocks:
			app.setStatus(_("Driller 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

			#Summ all path length
			fullPathLength = 0.0
			for s in bidSegment:
				fullPathLength += s[3]

			#Calc rest
			holes = fullPathLength // holesDistance
			rest = fullPathLength - (holesDistance * (holes))
			#Travel along the path
			elapsedLength = rest / 2.0 #equaly distribute rest, as option???
			bidHoles = []
			while elapsedLength <= fullPathLength:
				#Search best segment to apply line interpolation
				bestSegment = bidSegment[0]
				segmentsSum = 0.0
				perc = 0.0
				for s in bidSegment:
					bestSegment = s
					segmentLength = bestSegment[3]
					perc = (elapsedLength-segmentsSum) / segmentLength
					segmentsSum += segmentLength
					if segmentsSum > elapsedLength : break

				#Fist point
				x1 = bestSegment[0][0]
				y1 = bestSegment[0][1]
				z1 = bestSegment[0][2]
				#Last point
				x2 = bestSegment[1][0]
				y2 = bestSegment[1][1]
				z2 = bestSegment[1][2]

				#Check if segment is not excluded
				if not bestSegment[2]:
					newHolePoint = (x1 + perc*(x2-x1) ,
						y1 + perc*(y2-y1),
						z1 + perc*(z2-z1))
					bidHoles.append(newHolePoint)

				#Go to next hole
				elapsedLength += holesDistance

			#Add bidHoles to allHoles
			allHoles.append(bidHoles)

		#Write gcommands from allSegments to the drill block
		n = self["name"]
		if not n or n=="default": n="Driller"
		blocks = []
		block = Block(self.name)

		holesCount = 0
		for bid in allHoles:

			for xH,yH,zH in bid:
				holesCount += 1
				block.append(CNC.grapid(None,None,zH + 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.grapid(None,None,zH + 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())
		blocks.append(block)

		#Insert created block
		active = app.activeBlock()
		if active==0: active=1
		app.gcode.insBlocks(active, blocks, "Driller")
		app.refresh()
		app.setStatus(_("Generated Driller: %d holes")%holesCount)
Esempio n. 32
0
    def execute(self, app):
        name = self['name']

        if not name or name == 'default':
            name = 'Function'

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

        #Variable definitions
        formula = self['form']
        res = self['res']  # X resolution
        ran = [self['ranX'], self['ranY']]  # Range of X,Y, from -10, to 10 range is 20
        cent = [self['centX'], self['centY']]  # Coordinates X,Y of the center from bottom left of the coordinate system
        dim = [self['dimX'], self['dimY']]  # Real dimensions in gcode units
        spacX = self['spacX']  # Spacing of X axis lines
        spacY = self['spacY']  # Spacing of Y axis lines
        lin = self['lin']  # Small value - length of a line in gcode units
        draw = self['draw']  # Draw the coordinate system

        block.append("(Generated with a script by kswiorek)\n")
        block.append("(Equation: " + formula +")\n")
        block.append("(Resolution: " + str(res) +")\n")
        block.append("(Range: " + str(ran) +")\n")
        block.append("(Center: " + str(cent) +")\n")
        block.append("(Dimensions: " + str(dim) +")\n")
        block.append("(SpacingXY: " + str(spacX) +", " + str(spacY) +")\n")

        def mapc(var, axis): #Map coordinate systems
            return (var * (dim[axis]/ran[axis]))

        #Define coordinate system mins and maxes
        minX = -cent[0]
        maxX = ran[0]-cent[0]

        minY = -cent[1]
        maxY = ran[1]-cent[1]

        #Define domain and codomain
        X = []
        Y = []

        e_old = "" #Store old exception to comapre

        #Calculate values for arguments with a resolution
        for i in range(0, int(ran[0]/res+1)): #Complaints about values beeing floats
            x = i*res + minX #Iterate x
            X.append(x)
            try:
                Y.append(eval(formula))

            except Exception as exc: #Append None, not to loose sync with X
                Y.append(None)
                e = str(exc)
                if e != e_old: #If there is a different exception - display it
                    print("Warning: " + str(e))
                    app.setStatus(_("Warning: " + str(e)))
                    e_old = e

        raised = True # Z axis is raised at start

        #Clip values out of bounds, replace with None, not to loose sync with X
        for i, item in enumerate(Y):
            y = Y[i]
            if not y is None and (y < minY or y > maxY):
                Y[i] = None

        #Y without "None", min() and max() can't compare them
        Ynn = [] #Y no Nones
        for i, item in enumerate(Y):
            if not Y[i] is None:
                Ynn.append(Y[i])

        block.append(CNC.gcode(1, [("f",CNC.vars["cutfeed"])])) #Set feedrate

        if draw: #If the user selected to draw the coordinate system
            #X axis
            block.append(CNC.grapid(z=3))
            block.append(CNC.grapid(0, mapc(cent[1], 1))) #1st point of X axis line
            block.append(CNC.grapid(z=0))

            block.append(CNC.gline(dim[0] + lin*1.2, mapc(cent[1], 1))) #End of X axis line + a bit more for the arrow

            block.append(CNC.gline(dim[0] - lin/2, mapc(cent[1], 1) - lin / 2)) #bottom part of the arrow

            block.append(CNC.grapid(z=3))
            block.append(CNC.grapid(dim[0] + lin*1.2, mapc(cent[1], 1), 0)) #End of X axis line
            block.append(CNC.grapid(z=0))

            block.append(CNC.gline(dim[0] - lin/2, mapc(cent[1], 1) + lin / 2)) #top part of the arrow
            block.append(CNC.grapid(z=3))

            #Y axis, just inverted x with y
            block.append(CNC.grapid(z=3))
            block.append(CNC.grapid(mapc(cent[0], 0), 0)) #1st point of Y axis line
            block.append(CNC.grapid(z=0))

            block.append(CNC.gline(mapc(cent[0], 0), dim[1] + lin*1.2)) #End of Y axis line + a bit more for the arrow

            block.append(CNC.gline(mapc(cent[0], 0) - lin / 2, dim[1] - lin/2)) #left part of the arrow

            block.append(CNC.grapid(z=3))
            block.append(CNC.grapid(mapc(cent[0], 0), dim[1] + lin*1.2)) #End of Y axis line
            block.append(CNC.grapid(z=0))

            block.append(CNC.gline(mapc(cent[0], 0) + lin / 2, dim[1] - lin/2)) #right part of the arrow
            block.append(CNC.grapid(z=3))

            #X axis number lines
            i = 0
            while i < ran[0] - cent[0]: #While i is on the left of the arrow
                i +=spacX #Add line spacing

                #Draw lines right of the center
                block.append(CNC.grapid(mapc(i+cent[0],0), mapc(cent[1], 1) + lin/2))
                block.append(CNC.grapid(z=0))
                block.append(CNC.gline(mapc(i+cent[0],0), mapc(cent[1], 1) - lin/2))
                block.append(CNC.grapid(z=3))

            i = 0
            while i > -cent[0]: #While i is lower than center coordinate, inverted for easier math
                i -=spacX #Add line spacing

                #Draw lines left of the center
                block.append(CNC.grapid(mapc(i+cent[0],0), mapc(cent[1], 1) + lin/2))
                block.append(CNC.grapid(z=0))
                block.append(CNC.gline(mapc(i+cent[0],0), mapc(cent[1], 1) - lin/2))
                block.append(CNC.grapid(z=3))

            #Y axis number lines
            i = 0
            while i < ran[1] - cent[1]: #While i is between the center and the arrow
                i +=spacX #Add line spacing

                #Draw lines top of the center (everything just inverted)
                block.append(CNC.grapid(mapc(cent[0], 0) + lin/2, mapc(i+cent[1],1)))
                block.append(CNC.grapid(z=0))
                block.append(CNC.gline(mapc(cent[0], 0) - lin/2, mapc(i+cent[1],1)))
                block.append(CNC.grapid(z=3))

            i = 0
            while i > -1*cent[1]:
                i -=spacX #Add line spacing

                #Draw lines bottom of the center
                block.append(CNC.grapid(mapc(cent[0], 0) + lin/2, mapc(i+cent[1],1)))
                block.append(CNC.grapid(z=0))
                block.append(CNC.gline(mapc(cent[0], 0) - lin/2, mapc(i+cent[1],1)))
                block.append(CNC.grapid(z=3))

            raised = True #Z was raised

        #Draw graph
        for i, item in enumerate(Y):
            if not Y[i] is None:
                x = mapc(X[i]+cent[0], 0) #Take an argument
                y = mapc(Y[i]+cent[1], 1) #Take a value
            else:
                y = Y[i] #only for tne None checks next

            if y is None and not raised: #If a None "period" just started raise Z
                raised = True
                block.append(CNC.grapid(z=3))
            elif not y is None and raised: #If Z was raised and the None "period" ended move to new coordinates
                block.append(CNC.grapid(round(x, 2),round(y, 2)))
                block.append(CNC.grapid(z=0)) #Lower Z
                raised = False
            elif not y is None and not raised: #Nothing to do with Nones? Just draw
                block.append(CNC.gline(round(x, 2),round(y, 2)))

        block.append(CNC.grapid(z=3)) #Raise on the end

        blocks.append(block)
        active = app.activeBlock()
        app.gcode.insBlocks(active, blocks, 'Function inserted')  #insert blocks over active block in the editor
        app.refresh()  #refresh editor
        app.setStatus(_('Generated function graph'))  #feed back result
        print()
Esempio n. 33
0
	def execute(self, app):
		try:
			from PIL import Image
		except:
			app.setStatus(_("Sketch abort: This plugin requires PIL/Pillow to read image data"))
			return

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

		#Calc desired size
		grundgy =self["Grundgy"]
		maxSize = self["MaxSize"]
		squiggleTotal  = self["SquiggleTotal"]
		squiggleLength = self["SquiggleLength"]
		depth = self["Depth"]
		drawBorder = self["DrawBorder"]
		channel = self["Channel"]

		radius = 1
		if grundgy == "Low":
			radius = 2
		elif grundgy == "Medium":
			radius = 3
		elif grundgy == "High":
			radius = 6
		elif grundgy == "Very High":
			radius = 9

		#Check parameters
		if maxSize < 1:
			app.setStatus(_("Sketch abort: Too small to draw anything!"))
			return

		if squiggleTotal < 1:
			app.setStatus(_("Sketch abort: Please let me draw at least 1 squiggle"))
			return
			
		if squiggleLength <= 0:
			app.setStatus(_("Sketch abort: Squiggle Length must be > 0"))
			return

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

		#Create a scaled image to work faster with big image and better with small ones
		iWidth,iHeight = img.size
		resampleRatio = 800.0 / iHeight
		img = img.resize((int(iWidth *resampleRatio) ,int(iHeight * resampleRatio)), Image.ANTIALIAS)
		if channel == 'Blue':
			img = img.convert('RGB')
			img = img.split()[0]
		elif channel == 'Green':
			img = img.convert('RGB')
			img = img.split()[1]
		elif channel == 'Red':
			img = img.convert('RGB')
			img = img.split()[2]
		else:
			img = img.convert ('L') #to calculate luminance

		img = img.transpose(Image.FLIP_TOP_BOTTOM) #ouput correct image
		pix = img.load()

		#Get image size
		self.imgWidth, self.imgHeight =  img.size
		self.ratio = 1
		if (iWidth > iHeight):
			self.ratio = maxSize / float(self.imgWidth)
		else:
			self.ratio = maxSize / float(self.imgHeight)

		#Init blocks
		blocks = []

		#Border block
		block = Block("%s-border"%(self.name))
		block.enable = drawBorder
		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)
		block.append("(Sketch size W=%d x H=%d x distance=%d)" %
			 (self.imgWidth * self.ratio  , self.imgHeight * self.ratio  , depth))
		block.append("(Channel = %s)" %(channel))
		#choose a nice starting point
		x = self.imgWidth / 4.
		y = self.imgHeight / 4.

		#First round search in all image
		self.mostest = 256
		x,y = self.findFirst(pix, True)

		#startAll = time.time()
		for c in range(squiggleTotal):
			#print c,x,y
			#start = time.time()
			x,y = self.findFirst(pix, False)
			#print 'Find mostest: %f' % (time.time() - start)
			#move there
			block.append(CNC.zsafe())
			block.append(CNC.grapid(x*self.ratio, y*self.ratio))
			#tool down
			block.append(CNC.zenter(depth))
			#restore cut/draw feed
			block.append(CNC.gcode(1, [("f",CNC.vars["cutfeed"])]))

			#start = time.time()
			s = 0
			while (s < squiggleLength):
				x,y,distance = self.findInRange(x, y, pix, radius)
				s+= max(1,distance*self.ratio)  #add traveled distance
				#move there
				block.append(CNC.gline(x*self.ratio,y*self.ratio))
				self.fadePixel(x, y, pix) #adjustbrightness int the bright map
			#tool up
			block.append(CNC.zsafe())
			#print 'Squiggle: %f' % (time.time() - start)

		#Gcode Zsafe
		block.append(CNC.zsafe())
		blocks.append(block)
		active = app.activeBlock()
		app.gcode.insBlocks(active, blocks, "Sketch")
		app.refresh()
		app.setStatus(_("Generated Sketch size W=%d x H=%d x distance=%d, Total length:%d") %
			(self.imgWidth*self.ratio  , self.imgHeight*self.ratio , depth, squiggleTotal*squiggleLength))
Esempio n. 34
0
    def execute(self, app):
        try:
            import midiparser as midiparser
        except:
            app.setStatus(_("Error: This plugin requires midiparser.py"))
            return

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

        fileName = self["File"]

        x = 0.0
        y = 0.0
        z = 0.0

        x_dir = 1.0
        y_dir = 1.0
        z_dir = 1.0

        # List of MIDI channels (instruments) to import.
        # Channel 10 is percussion, so better to omit it
        channels = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

        axes = self["AxisUsed"]
        active_axes = len(axes)

        transpose = (0, 0, 0)
        ppu = [200, 200, 200]
        ppu[0] = self["ppu_X"]
        ppu[1] = self["ppu_X"]
        ppu[2] = self["ppu_X"]

        safemin = [0, 0, 0]
        safemax = [100, 100, 50]
        safemax[0] = self["max_X"]
        safemax[1] = self["max_Y"]
        safemax[2] = self["max_Z"]

        try:
            midi = midiparser.File(fileName)
        except:
            app.setStatus(_("Error: Sorry can't parse the Midi file."))
            return

        noteEventList = []
        all_channels = set()

        for track in midi.tracks:
            #channels=set()
            for event in track.events:
                if event.type == midiparser.meta.SetTempo:
                    tempo = event.detail.tempo

                # filter undesired instruments
                if ((event.type == midiparser.voice.NoteOn)
                        and (event.channel in channels)):

                    if event.channel not in channels:
                        channels.add(event.channel)

                    # NB: looks like some use "note on (vel 0)" as equivalent to note off, so check for vel=0 here and treat it as a note-off.
                    if event.detail.velocity > 0:
                        noteEventList.append([
                            event.absolute, 1, event.detail.note_no,
                            event.detail.velocity
                        ])
                    else:
                        noteEventList.append([
                            event.absolute, 0, event.detail.note_no,
                            event.detail.velocity
                        ])

                if (event.type == midiparser.voice.NoteOff) and (event.channel
                                                                 in channels):
                    if event.channel not in channels:
                        channels.add(event.channel)
                    noteEventList.append([
                        event.absolute, 0, event.detail.note_no,
                        event.detail.velocity
                    ])

            # Finished with this track
            if len(channels) > 0:
                msg = ', '.join(['%2d' % ch for ch in sorted(channels)])
                #print 'Processed track %d, containing channels numbered: [%s ]' % (track.number, msg)
                all_channels = all_channels.union(channels)

        # List all channels encountered
        if len(all_channels) > 0:
            msg = ', '.join(['%2d' % ch for ch in sorted(all_channels)])
            #print 'The file as a whole contains channels numbered: [%s ]' % msg

        # We now have entire file's notes with abs time from all channels
        # We don't care which channel/voice is which, but we do care about having all the notes in order
        # so sort event list by abstime to dechannelify

        noteEventList.sort()
        # print noteEventList
        # print len(noteEventList)

        last_time = -0
        active_notes = {
        }  # make this a dict so we can add and remove notes by name

        # Start the output
        #Init blocks
        blocks = []
        block = Block(self.name)
        block.append("(Midi2CNC)")
        block.append("(Midi:%s)" % fileName)
        block.append(CNC.zsafe())
        block.append(CNC.grapid(0, 0))
        block.append(CNC.zenter(0))

        for note in noteEventList:
            # note[timestamp, note off/note on, note_no, velocity]
            if last_time < note[0]:

                freq_xyz = [0, 0, 0]
                feed_xyz = [0, 0, 0]
                distance_xyz = [0, 0, 0]
                duration = 0

                # "i" ranges from 0 to "the number of active notes *or* the number of active axes,
                # whichever is LOWER". Note that the range operator stops
                # short of the maximum, so this means 0 to 2 at most for a 3-axis machine.
                # E.g. only look for the first few active notes to play despite what
                # is going on in the actual score.

                for i in range(0, min(len(active_notes.values()),
                                      active_axes)):

                    # Which axis are should we be writing to?
                    #
                    j = self.axes_dict.get(axes)[i]

                    # Debug
                    # print"Axes %s: item %d is %d" % (axes_dict.get(args.axes), i, j)

                    # Sound higher pitched notes first by sorting by pitch then indexing by axis
                    #
                    nownote = sorted(active_notes.values(), reverse=True)[i]

                    # MIDI note 69	 = A4(440Hz)
                    # 2 to the power (69-69) / 12 * 440 = A4 440Hz
                    # 2 to the power (64-69) / 12 * 440 = E4 329.627Hz
                    #
                    freq_xyz[j] = pow(
                        2.0, (nownote - 69 + transpose[j]) / 12.0) * 440.0

                    # Here is where we need smart per-axis feed conversions
                    # to enable use of X/Y *and* Z on a Makerbot
                    #
                    # feed_xyz[0] = X; feed_xyz[1] = Y; feed_xyz[2] = Z;
                    #
                    # Feed rate is expressed in mm / minutes so 60 times
                    # scaling factor is required.

                    feed_xyz[j] = (freq_xyz[j] * 60.0) / ppu[j]

                    # Get the duration in seconds from the MIDI values in divisions, at the given tempo
                    duration = (((note[0] - last_time) + 0.0) /
                                (midi.division + 0.0) * (tempo / 1000000.0))

                    # Get the actual relative distance travelled per axis in mm
                    distance_xyz[j] = (feed_xyz[j] * duration) / 60.0

                # Now that axes can be addressed in any order, need to make sure
                # that all of them are silent before declaring a rest is due.
                if distance_xyz[0] + distance_xyz[1] + distance_xyz[2] > 0:
                    # At least one axis is playing, so process the note into
                    # movements
                    combined_feedrate = math.sqrt(feed_xyz[0]**2 +
                                                  feed_xyz[1]**2 +
                                                  feed_xyz[2]**2)

                    # Turn around BEFORE crossing the limits of the
                    # safe working envelope
                    if self.reached_limit(x, distance_xyz[0], x_dir,
                                          safemin[0], safemax[0]):
                        x_dir = x_dir * -1
                    x = (x + (distance_xyz[0] * x_dir))

                    if self.reached_limit(y, distance_xyz[1], y_dir,
                                          safemin[1], safemax[1]):
                        y_dir = y_dir * -1
                    y = (y + (distance_xyz[1] * y_dir))

                    if self.reached_limit(z, distance_xyz[2], z_dir,
                                          safemin[2], safemax[2]):
                        z_dir = z_dir * -1
                    z = (z + (distance_xyz[2] * z_dir))

                    v = (x, y, z)
                    block.append(CNC.glinev(1, v, combined_feedrate))

                else:
                    # Handle 'rests' in addition to notes.
                    duration = (((note[0] - last_time) + 0.0) /
                                (midi.division + 0.0)) * (tempo / 1000000.0)
                    block.append(CNC.gcode(4, [("P", duration)]))

                # finally, set this absolute time as the new starting time
                last_time = note[0]

            if note[1] == 1:  # Note on
                if active_notes.has_key(note[2]):
                    pass
                else:
                    # key and value are the same, but we don't really care.
                    active_notes[note[2]] = note[2]
            elif note[1] == 0:  # Note off
                if (active_notes.has_key(note[2])):
                    active_notes.pop(note[2])

        blocks.append(block)
        active = app.activeBlock()
        if active == 0: active = 1
        app.gcode.insBlocks(active, blocks, "Midi2CNC")
        app.refresh()
        app.setStatus(_("Generated Midi2CNC, ready to play?"))
Esempio n. 35
0
	def execute(self, app):
		try:
			import midiparser as midiparser
		except:
			app.setStatus(_("Error: This plugin requires midiparser.py"))
			return

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

		fileName = self["File"]

		x=0.0
		y=0.0
		z=0.0

		x_dir=1.0;
		y_dir=1.0;
		z_dir=1.0;

		# List of MIDI channels (instruments) to import.
		# Channel 10 is percussion, so better to omit it
		channels = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] 

		axes = self["AxisUsed"]
		active_axes = len(axes)

		transpose = (0,0,0)
		ppu = [ 200, 200, 200 ]
		ppu[0] = self["ppu_X"]
		ppu[1] = self["ppu_X"]
		ppu[2] = self["ppu_X"]

		safemin = [ 0, 0, 0 ]
		safemax = [ 100, 100, 50 ]
		safemax[0] = self["max_X"]
		safemax[1] = self["max_Y"]
		safemax[2] = self["max_Z"]

		try:
			midi = midiparser.File(fileName)
		except:
			app.setStatus(_("Error: Sorry can't parse the Midi file."))
			return

		noteEventList=[]
		all_channels=set()

		for track in midi.tracks:
			#channels=set()
			for event in track.events:
				if event.type == midiparser.meta.SetTempo:
					tempo=event.detail.tempo

				# filter undesired instruments
				if ((event.type == midiparser.voice.NoteOn) and (event.channel in channels)):

					if event.channel not in channels:
						channels.add(event.channel)

					# NB: looks like some use "note on (vel 0)" as equivalent to note off, so check for vel=0 here and treat it as a note-off.
					if event.detail.velocity > 0:
						noteEventList.append([event.absolute, 1, event.detail.note_no, event.detail.velocity])
					else:
						noteEventList.append([event.absolute, 0, event.detail.note_no, event.detail.velocity])

				if (event.type == midiparser.voice.NoteOff) and (event.channel in channels):
					if event.channel not in channels:
						channels.add(event.channel)
					noteEventList.append([event.absolute, 0, event.detail.note_no, event.detail.velocity])

			# Finished with this track
			if len(channels) > 0:
				msg=', ' . join(['%2d' % ch for ch in sorted(channels)])
				#print 'Processed track %d, containing channels numbered: [%s ]' % (track.number, msg)
				all_channels = all_channels.union(channels)

		# List all channels encountered
		if len(all_channels) > 0:
			msg=', ' . join(['%2d' % ch for ch in sorted(all_channels)])
			#print 'The file as a whole contains channels numbered: [%s ]' % msg

		# We now have entire file's notes with abs time from all channels
		# We don't care which channel/voice is which, but we do care about having all the notes in order
		# so sort event list by abstime to dechannelify

		noteEventList.sort()
		# print noteEventList
		# print len(noteEventList)

		last_time=-0
		active_notes={} # make this a dict so we can add and remove notes by name

		# Start the output
		#Init blocks
		blocks = []
		block = Block(self.name)
		block.append("(Midi2CNC)")
		block.append("(Midi:%s)" % fileName)
		block.append(CNC.zsafe())
		block.append(CNC.grapid(0,0))
		block.append(CNC.zenter(0))

		for note in noteEventList:
			# note[timestamp, note off/note on, note_no, velocity]
			if last_time < note[0]:

				freq_xyz=[0,0,0]
				feed_xyz=[0,0,0]
				distance_xyz=[0,0,0]
				duration=0

				# "i" ranges from 0 to "the number of active notes *or* the number of active axes,
				# whichever is LOWER". Note that the range operator stops
				# short of the maximum, so this means 0 to 2 at most for a 3-axis machine.
				# E.g. only look for the first few active notes to play despite what
				# is going on in the actual score.

				for i in range(0, min(len(active_notes.values()), active_axes)):

					# Which axis are should we be writing to?
					#
					j = self.axes_dict.get(axes)[i]

					# Debug
					# print"Axes %s: item %d is %d" % (axes_dict.get(args.axes), i, j)

					# Sound higher pitched notes first by sorting by pitch then indexing by axis
					#
					nownote=sorted(active_notes.values(), reverse=True)[i]

					# MIDI note 69	 = A4(440Hz)
					# 2 to the power (69-69) / 12 * 440 = A4 440Hz
					# 2 to the power (64-69) / 12 * 440 = E4 329.627Hz
					#
					freq_xyz[j] = pow(2.0, (nownote-69 + transpose[j])/12.0)*440.0

					# Here is where we need smart per-axis feed conversions
					# to enable use of X/Y *and* Z on a Makerbot
					#
					# feed_xyz[0] = X; feed_xyz[1] = Y; feed_xyz[2] = Z;
					#
					# Feed rate is expressed in mm / minutes so 60 times
					# scaling factor is required.

					feed_xyz[j] = ( freq_xyz[j] * 60.0 ) / ppu[j]

					# Get the duration in seconds from the MIDI values in divisions, at the given tempo
					duration = ( ( ( note[0] - last_time ) + 0.0 ) / ( midi.division + 0.0 ) * ( tempo / 1000000.0 ) )

					# Get the actual relative distance travelled per axis in mm
					distance_xyz[j] = ( feed_xyz[j] * duration ) / 60.0

				# Now that axes can be addressed in any order, need to make sure
				# that all of them are silent before declaring a rest is due.
				if distance_xyz[0] + distance_xyz[1] + distance_xyz[2] > 0:
					# At least one axis is playing, so process the note into
					# movements
					combined_feedrate = math.sqrt(feed_xyz[0]**2 + feed_xyz[1]**2 + feed_xyz[2]**2)

					# Turn around BEFORE crossing the limits of the
					# safe working envelope
					if self.reached_limit( x, distance_xyz[0], x_dir, safemin[0], safemax[0] ):
						x_dir = x_dir * -1
					x = (x + (distance_xyz[0] * x_dir))

					if self.reached_limit( y, distance_xyz[1], y_dir, safemin[1], safemax[1] ):
						y_dir = y_dir * -1
					y = (y + (distance_xyz[1] * y_dir))

					if self.reached_limit( z, distance_xyz[2], z_dir, safemin[2], safemax[2] ):
						z_dir = z_dir * -1
					z = (z + (distance_xyz[2] * z_dir))

					v = (x,y,z)
					block.append(CNC.glinev(1,v,combined_feedrate))

				else:
					# Handle 'rests' in addition to notes.
					duration = (((note[0]-last_time)+0.0)/(midi.division+0.0)) * (tempo/1000000.0)
					block.append(CNC.gcode(4, [("P",duration)]))

				# finally, set this absolute time as the new starting time
				last_time = note[0]

			if note[1]==1: # Note on
				if active_notes.has_key(note[2]):
					pass
				else:
					# key and value are the same, but we don't really care.
					active_notes[note[2]]=note[2]
			elif note[1]==0: # Note off
				if(active_notes.has_key(note[2])):
					active_notes.pop(note[2])

		blocks.append(block)
		active = app.activeBlock()
		if active==0: active=1
		app.gcode.insBlocks(active, blocks, "Midi2CNC")
		app.refresh()
		app.setStatus(_("Generated Midi2CNC, ready to play?"))
Esempio n. 36
0
    def execute(self, app):
        #Get inputs
        holesDistance = self.fromMm("HolesDistance")
        targetDepth = self.fromMm("TargetDepth")
        peck = self.fromMm("Peck")
        dwell = self["Dwell"]

        zSafe = CNC.vars["safe"]

        #Check inputs
        if holesDistance <= 0:
            app.setStatus(_("Driller abort: Distance must be > 0"))
            return

        if peck < 0:
            app.setStatus(_("Driller abort: Peck must be >= 0"))
            return

        if dwell < 0:
            app.setStatus(
                _("Driller abort: Dwell time >= 0, here time runs only forward!"
                  ))
            return

        # Get selected blocks from editor
        selBlocks = app.editor.getSelectedBlocks()
        if not selBlocks:
            app.editor.selectAll()
            selBlocks = app.editor.getSelectedBlocks()

        if not selBlocks:
            app.setStatus(_("Driller 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

            #Summ all path length
            fullPathLength = 0.0
            for s in bidSegment:
                fullPathLength += s[3]

            #Calc rest
            holes = fullPathLength // holesDistance
            rest = fullPathLength - (holesDistance * (holes))
            #Travel along the path
            elapsedLength = rest / 2.0  #equaly distribute rest, as option???
            bidHoles = []
            while elapsedLength <= fullPathLength:
                #Search best segment to apply line interpolation
                bestSegment = bidSegment[0]
                segmentsSum = 0.0
                perc = 0.0
                for s in bidSegment:
                    bestSegment = s
                    segmentLength = bestSegment[3]
                    perc = (elapsedLength - segmentsSum) / segmentLength
                    segmentsSum += segmentLength
                    if segmentsSum > elapsedLength: break

                #Fist point
                x1 = bestSegment[0][0]
                y1 = bestSegment[0][1]
                z1 = bestSegment[0][2]
                #Last point
                x2 = bestSegment[1][0]
                y2 = bestSegment[1][1]
                z2 = bestSegment[1][2]

                #Check if segment is not excluded
                if not bestSegment[2]:
                    newHolePoint = (x1 + perc * (x2 - x1),
                                    y1 + perc * (y2 - y1),
                                    z1 + perc * (z2 - z1))
                    bidHoles.append(newHolePoint)

                #Go to next hole
                elapsedLength += holesDistance

            #Add bidHoles to allHoles
            allHoles.append(bidHoles)

        #Write gcommands from allSegments to the drill block
        n = self["name"]
        if not n or n == "default": n = "Driller"
        blocks = []
        block = Block(self.name)

        holesCount = 0
        for bid in allHoles:

            for xH, yH, zH in bid:
                holesCount += 1
                block.append(CNC.grapid(None, None, zH + 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.grapid(None, None, zH + 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())
        blocks.append(block)

        #Insert created block
        active = app.activeBlock()
        if active == 0: active = 1
        app.gcode.insBlocks(active, blocks, "Driller")
        app.refresh()
        app.setStatus(_("Generated Driller: %d holes") % holesCount)
Esempio n. 37
0
		def appendCircle(block):
			block.append("m5")
			block.append(CNC.grapid(x=x0, y=y0 + marksizehalf / 2, f=movefeed))
			block.append(self.getPowerLine(app))
			block.append(CNC.garc(2, x=x0, y=y0 + marksizehalf / 2, j=-marksizehalf / 2, i=0, f=drawfeed))
			block.append("m5")
Esempio n. 38
0
    def execute(self, app):
        try:
            from PIL import Image
        except:
            app.setStatus(
                _("Sketch abort: This plugin requires PIL/Pillow to read image data"
                  ))
            return

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

        #Calc desired size
        grundgy = self["Grundgy"]
        maxSize = self["MaxSize"]
        squiggleTotal = self["SquiggleTotal"]
        squiggleLength = self["SquiggleLength"]
        depth = self["Depth"]
        drawBorder = self["DrawBorder"]
        channel = self["Channel"]
        casual = self["Casual"]
        fading = self["Fading"]
        max_light = self["Max_light"]
        repetition = self["Repetition"]

        radius = 1
        if grundgy == "Low":
            radius = 2
        elif grundgy == "Medium":
            radius = 3
        elif grundgy == "High":
            radius = 6
        elif grundgy == "Very High":
            radius = 9

        #Check parameters
        if maxSize < 1:
            app.setStatus(_("Sketch abort: Too small to draw anything!"))
            return

        if max_light > 256:
            app.setStatus(
                _("The maximum illumination shouldn't be more than 250!"))
            return

        if squiggleTotal < 1:
            app.setStatus(
                _("Sketch abort: Please let me draw at least 1 squiggle"))
            return

        if squiggleLength <= 0:
            app.setStatus(_("Sketch abort: Squiggle Length must be > 0"))
            return

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

        #Create a scaled image to work faster with big image and better with small ones
        iWidth, iHeight = img.size
        resampleRatio = 800.0 / iHeight
        img = img.resize(
            (int(iWidth * resampleRatio), int(iHeight * resampleRatio)),
            Image.ANTIALIAS)
        if channel == 'Blue':
            img = img.convert('RGB')
            img = img.split()[0]
        elif channel == 'Green':
            img = img.convert('RGB')
            img = img.split()[1]
        elif channel == 'Red':
            img = img.convert('RGB')
            img = img.split()[2]
        else:
            img = img.convert('L')  #to calculate luminance

        img = img.transpose(Image.FLIP_TOP_BOTTOM)  #ouput correct image
        pix = img.load()
        #Get image size
        self.imgWidth, self.imgHeight = img.size
        self.ratio = 1
        if (iWidth > iHeight):
            self.ratio = maxSize / float(self.imgWidth)
        else:
            self.ratio = maxSize / float(self.imgHeight)

        #Init blocks
        blocks = []

        #Info block
        block = Block("Info")
        block.append(
            "(Sketch size W=%d x H=%d x distance=%d)" %
            (self.imgWidth * self.ratio, self.imgHeight * self.ratio, depth))
        block.append("(Channel = %s)" % (channel))
        blocks.append(block)

        #Border block
        block = Block("%s-border" % (self.name))
        block.enable = drawBorder
        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)

        #choose a nice starting point
        x = self.imgWidth / 4.
        y = self.imgHeight / 4.

        #First round search in all image
        self.mostest = 256
        x, y = self.findFirst(pix, True, casual)

        #startAll = time.time()
        total_line = 0
        total_length = 0
        for c in range(squiggleTotal):
            x, y = self.findFirst(pix, False, casual)
            if pix[x, y] > max_light:
                continue
            block = Block(self.name)
            #print c,x,y
            #start = time.time()

            total_line += 1
            total_length += 1
            #move there
            block.append(CNC.zsafe())
            block.append(CNC.grapid(x * self.ratio, y * self.ratio))
            #tool down
            block.append(CNC.zenter(depth))
            #restore cut/draw feed
            block.append(CNC.gcode(1, [("f", CNC.vars["cutfeed"])]))

            #start = time.time()
            s = 0
            while (s < squiggleLength):
                x, y, distance = self.findInRange(x, y, pix, radius)
                if pix[x, y] > max_light:
                    break
                s += max(1, distance * self.ratio)  #add traveled distance
                total_length += 1
                #move there
                block.append(CNC.gline(x * self.ratio, y * self.ratio))
                self.fadePixel(
                    x, y, pix, fading,
                    repetition)  #adjustbrightness int the bright map
            #tool up
            #print 'Squiggle: %f' % (time.time() - start)
            #Gcode Zsafe
            block.append(CNC.zsafe())
            blocks.append(block)
        active = app.activeBlock()
        app.gcode.insBlocks(active, blocks, "Sketch")
        app.refresh()
        app.setStatus(
            _("Generated Sketch size W=%d x H=%d x distance=%d, Total line:%i, Total length:%d"
              ) % (self.imgWidth * self.ratio, self.imgHeight * self.ratio,
                   depth, total_line, total_length))
Esempio n. 39
0
def mop(self, app, mem_0, mem_1, mop_type):
    """create GCode for a pocket
    Values are stored in OCV.mop_vars as a dictionary"""

    end_depth = OCV.mop_vars["tdp"]
    x_start = min(OCV.WK_mems[mem_0][0], OCV.WK_mems[mem_1][0])
    y_start = min(OCV.WK_mems[mem_0][1], OCV.WK_mems[mem_1][1])

    x_end = max(OCV.WK_mems[mem_0][0], OCV.WK_mems[mem_1][0])
    y_end = max(OCV.WK_mems[mem_0][1], OCV.WK_mems[mem_1][1])

    z_start = OCV.WK_mems[mem_1][2]

    tool_dia = OCV.mop_vars["tdia"]
    tool_rad = tool_dia / 2.

    xy_stepover = OCV.mop_vars["mso"]

    z_stepover = OCV.mop_vars["msd"]

    # avoid infinite while loop
    if z_stepover == 0:
        z_stepover = 0.001

    if mop_type == "PK":
        # Pocketing
        isSpiral = OCV.mop_vars["pks"]

        isInt = OCV.mop_vars["sin"]

        if isSpiral is True:
            op_name = "Spiral Pocket"
        else:
            op_name = "Rectangular Pocket"

    elif mop_type == "LN":
        op_name = "Line"


    """
    cut_dir passed to the calculation method depends on starting point,
    If we cut from internal we minimize "full stock" cut
    in which the endmill is 'surrounded' by the material.
    For calculation these assumptions are done, maybe is wrong

    Conventionl cut is when piece is cut on left side of the cutter

    Climb cut is when piece is cut on right side
    """

    if mop_type == "PK":
        # Pocketing
        if isInt is True:
            cut_dir = 1
            reverse = True
        else:
            cut_dir = 0
            reverse = False

    msg = (
        "{} Operation: \n\n".format(op_name),
        "Start: \n\n{0}\n\n".format(OCV.showC(x_start, y_start, z_start)),
        "End: \n\n{0}\n\n".format(OCV.showC(x_end, y_end, end_depth)),
        "Tool diameter: {0:.{1}f} \n\n".format(tool_dia, OCV.digits),
        "StepDown: {0:.{1}f} \n\n".format(z_stepover, OCV.digits),
        "StepOver: {0:.{1}f} \n\n".format(xy_stepover, OCV.digits))

    retval = tkMessageBox.askokcancel(
        "MOP {} Cut".format(op_name), "".join(msg))

    if retval is False:
        return

    # Start Calculations

    start = (x_start, y_start)
    end = (x_end, y_end)

    if mop_type == "PK":
            # Pocketing
        # Assign points here
        if isSpiral is True:
            msg,x_p,y_p = spiral_pocket(start, end, tool_rad, xy_stepover, cut_dir)
        else:
            msg,x_p,y_p = spiral_pocket(start, end, tool_rad, xy_stepover, cut_dir)

        if msg != "OK":
            retval = tkMessageBox.askokcancel(op_name, msg)
            return

        if reverse is True:
            x_p.reverse()
            y_p.reverse()

    # Reset the editor and write the Gcode generated Here
    OCV.TK_MAIN.clear_gcode()
    OCV.TK_MAIN.clear_editor()
    OCV.TK_MAIN.reset_canvas()
    blocks = []
    block = Block.Block("Init")
    # Get the current WCS as the mem are related to it
    block.append(OCV.CD['WCS'])
    blocks.append(block)

    block = Block.Block(op_name)
    block.append("({})".format(op_name))
    block.append("(Tool diameter = {0:.{1}f})".format(tool_dia, OCV.digits))
    block.append("(Start: {0})".format(OCV.gcodeCC(x_start, y_start, z_start)))
    block.append("(End: {0})".format(OCV.gcodeCC(x_end, y_end, end_depth)))
    block.append("(StepDown: {0:.{1}f} )".format(z_stepover, OCV.digits))
    block.append("(StepOver: {0:.{1}f} )".format(xy_stepover, OCV.digits))

    if mop_type == "PK":
            # Pocketing
            # Move safe to first point
        block.append(CNC.zsafe())
        block.append(CNC.grapid(x_p[0], y_p[0]))
    elif mop_type == "LN":
        # Move safe to first point
        block.append(CNC.zsafe())
        block.append(CNC.grapid(x_start, y_start))
    else:
        return

    # the check is done at the final depth
    curr_depth = z_start

    print("curr_depth, z_start", curr_depth, z_start)
    # Create GCode from points
    while True:
        curr_depth -= z_stepover

        if curr_depth < end_depth:
            curr_depth = end_depth

        block.append(CNC.zenter(curr_depth))
        block.append(CNC.gcode_string(1, [("F", OCV.CD["cutfeed"])]))

        if mop_type == "PK":
            # Pocketing
            for x_l, y_l in zip(x_p, y_p):
                block.append(CNC.gline(x_l, y_l))

            # Move to the begin in a safe way
            block.append(CNC.zsafe())
            block.append(CNC.grapid(x_p[0], y_p[0]))

        elif mop_type == "LN":
            block.append(CNC.gline(x_end, y_end))
            # Move to the begin in a safe way
            block.append(CNC.zsafe())
            block.append(CNC.grapid(x_start, y_start))

        # Verify exit condition
        if curr_depth <= end_depth:
            break

    # end of the loop
    # return to z_safe
    block.append(CNC.zsafe())
    blocks.append(block)

    if blocks is not None:
        active = OCV.TK_MAIN.activeBlock()

        if active == 0:
            active = 1

        OCV.TK_MAIN.gcode.insBlocks(active, blocks, op_name)
        OCV.TK_MAIN.refresh()
        OCV.TK_MAIN.setStatus(_("{}: GCode Generated".format(op_name)))
Esempio n. 40
0
	def make(self,app, XStart=0.0, YStart=0.0, FlatWidth=10., FlatHeight=10., \
			FlatDepth=0, BorderPass=False, CutDirection="Climb", PocketType="Raster"):

		#GCode Blocks
		blocks = []

		#Check parameters
		if CutDirection is "":
			app.setStatus(_("Flatten abort: Cut Direction is undefined"))
			return

		if PocketType is "":
			app.setStatus(_("Flatten abort: Pocket Type is undefined"))
			return

		if FlatWidth <= 0 or FlatHeight <= 0 :
			app.setStatus(_("Flatten abort: Flatten Area dimensions must be > 0"))
			return

		if FlatDepth > 0 :
			app.setStatus(_("Flatten abort: Hey this is only for subtractive machine! Check depth!"))
			return

		#Add Region disabled to show worked area
		block = Block(self.name + " Outline")
		block.enable = False
		block.append(CNC.zsafe())
		xR,yR = self.RectPath(XStart,YStart,FlatWidth,FlatHeight)
		for x,y in zip(xR,yR):
			block.append(CNC.gline(x,y))
		blocks.append(block)

		# Load tool and material settings
		toolDiam = CNC.vars['diameter']
		toolRadius = toolDiam / 2.

		#Calc tool diameter with Maximum Step Over allowed
		StepOverInUnitMax = toolDiam * CNC.vars['stepover'] / 100.0

		#Offset for Border Cut
		BorderXStart = XStart + toolRadius
		BorderYStart = YStart + toolRadius
		BorderWidth = FlatWidth - toolDiam
		BorderHeight = FlatHeight - toolDiam
		BorderXEnd = XStart + FlatWidth - toolRadius
		BorderYEnd = YStart + FlatHeight - toolRadius

		PocketXStart = BorderXStart
		PocketYStart = BorderYStart
		PocketXEnd = BorderXEnd
		PocketYEnd = BorderYEnd

		#Calc space to work with/without border cut
		WToWork = FlatWidth - toolDiam
		HToWork = FlatHeight - toolDiam

		if(WToWork < toolRadius or HToWork < toolRadius):
			app.setStatus(_("Flatten abort: Flatten area is too small for this End Mill."))
			return

		#Prepare points for pocketing
		xP=[]
		yP=[]
        #and border
		xB=[]
		yB=[]

        #---------------------------------------------------------------------
        #Raster approach
		if PocketType == "Raster":
			#Correct sizes if border is used
			if(BorderPass):
				PocketXStart += StepOverInUnitMax
				PocketYStart += StepOverInUnitMax
				PocketXEnd -= StepOverInUnitMax
				PocketYEnd -= StepOverInUnitMax
				WToWork -= (StepOverInUnitMax)
				HToWork -= (StepOverInUnitMax)

			#Calc number of pass
			VerticalCount = (int)(HToWork / StepOverInUnitMax)
			#Calc step minor of Max step
			StepOverInUnit = HToWork / (VerticalCount +1)
			flip = False
			ActualY = PocketYStart
			#Zig zag
			if StepOverInUnit==0 : StepOverInUnit=0.001  #avoid infinite while loop
			while (True):
				#Zig
				xP.append(self.ZigZag(flip,PocketXStart,PocketXEnd))
				yP.append(ActualY)
				flip = not flip
				#Zag
				xP.append(self.ZigZag(flip,PocketXStart,PocketXEnd))
				yP.append(ActualY)
				if(ActualY >= PocketYEnd - StepOverInUnitMax + StepOverInUnit):
					break
				#Up
				ActualY += StepOverInUnit
				xP.append(self.ZigZag(flip,PocketXStart,PocketXEnd))
				yP.append(ActualY)

			#Points for border cut depends on Zig/Zag end
			if(BorderPass):
				if flip:
					xB,yB = self.RectPath(BorderXStart,BorderYEnd,BorderWidth,-BorderHeight)
				else:
					xB,yB = self.RectPath(BorderXEnd,BorderYEnd,-BorderWidth,-BorderHeight)

				#Reverse in case of Climb
				if CutDirection == "Climb":
					xB = xB[::-1]
					yB = yB[::-1]

		#---------------------------------------------------------------------
        #Offset approach
		if PocketType == "Offset":
			#Calc number of pass
			VerticalCount = (int)(HToWork / StepOverInUnitMax)
			HorrizontalCount = (int)(WToWork / StepOverInUnitMax)
			#Make them odd
			if VerticalCount%2 == 0 : VerticalCount += 1
			if HorrizontalCount%2 == 0 : HorrizontalCount += 1
			#Calc step minor of Max step
			StepOverInUnitH = HToWork / (VerticalCount)
			StepOverInUnitW = WToWork / (HorrizontalCount)

			#Start from border to center
			xS = PocketXStart
			yS = PocketYStart
			wS = WToWork
			hS = HToWork
			xC = 0
			yC = 0
			while (xC<=HorrizontalCount/2 and yC<=VerticalCount/2):
				#Pocket offset points
				xO,yO = self.RectPath(xS, yS, wS, hS)
				if CutDirection == "Conventional":
					xO = xO[::-1]
					yO = yO[::-1]

				xP = xP + xO
				yP = yP + yO
				xS+=StepOverInUnitH
				yS+=StepOverInUnitW
				hS-=2.0*StepOverInUnitH
				wS-=2.0*StepOverInUnitW
				xC += 1
				yC += 1

			#Reverse point to start from inside (less stres on the tool)
			xP = xP[::-1]
			yP = yP[::-1]

		#Blocks for pocketing
		block = Block(self.name)
		block.append("(Flatten from X=%g Y=%g)"%(XStart,YStart))
		block.append("(W=%g x H=%g x D=%g)"%(FlatWidth,FlatHeight,FlatDepth))
		block.append("(Approach: %s %s)" % (PocketType,CutDirection))
		if BorderPass : block.append("(with border)")

		#Move safe to first point
		block.append(CNC.zsafe())
		block.append(CNC.grapid(xP[0],yP[0]))
		#Init Depth
		currDepth = 0.
		stepz = CNC.vars['stepz']
		if stepz==0 : stepz=0.001  #avoid infinite while loop

		#Create GCode from points
		while True:
			currDepth -= stepz
			if currDepth < FlatDepth : currDepth = FlatDepth
			block.append(CNC.zenter(currDepth))
			block.append(CNC.gcode(1, [("f",CNC.vars["cutfeed"])]))

			#Pocketing
			for x,y in zip(xP,yP):
				block.append(CNC.gline(x,y))

			#Border cut if request
			for x,y in zip(xB,yB):
				block.append(CNC.gline(x,y))

			#Verify exit condition
			if currDepth <= FlatDepth : break

			#Move to the begin in a safe way
			block.append(CNC.zsafe())
			block.append(CNC.grapid(xP[0],yP[0]))

		#Zsafe
		block.append(CNC.zsafe())
		blocks.append(block)
		return blocks
Esempio n. 41
0
    def execute(self, app):
        name = self['name']

        if not name or name == 'default':
            name = 'Function'

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

        #Variable definitions
        formula = self['form']
        res = self['res']  # X resolution
        ran = [self['ranX'],
               self['ranY']]  # Range of X,Y, from -10, to 10 range is 20
        cent = [
            self['centX'], self['centY']
        ]  # Coordinates X,Y of the center from bottom left of the coordinate system
        dim = [self['dimX'], self['dimY']]  # Real dimensions in gcode units
        spacX = self['spacX']  # Spacing of X axis lines
        spacY = self['spacY']  # Spacing of Y axis lines
        lin = self['lin']  # Small value - length of a line in gcode units
        draw = self['draw']  # Draw the coordinate system

        block.append("(Generated with a script by kswiorek)\n")
        block.append("(Equation: " + formula + ")\n")
        block.append("(Resolution: " + str(res) + ")\n")
        block.append("(Range: " + str(ran) + ")\n")
        block.append("(Center: " + str(cent) + ")\n")
        block.append("(Dimensions: " + str(dim) + ")\n")
        block.append("(SpacingXY: " + str(spacX) + ", " + str(spacY) + ")\n")

        def mapc(var, axis):  #Map coordinate systems
            return (var * (dim[axis] / ran[axis]))

        #Define coordinate system mins and maxes
        minX = -cent[0]
        maxX = ran[0] - cent[0]

        minY = -cent[1]
        maxY = ran[1] - cent[1]

        #Define domain and codomain
        X = []
        Y = []

        e_old = ""  #Store old exception to comapre

        #Calculate values for arguments with a resolution
        for i in range(0, int(ran[0] / res +
                              1)):  #Complaints about values beeing floats
            x = i * res + minX  #Iterate x
            X.append(x)
            try:
                Y.append(eval(formula))

            except Exception as exc:  #Append None, not to loose sync with X
                Y.append(None)
                e = str(exc)
                if e != e_old:  #If there is a different exception - display it
                    print("Warning: " + str(e))
                    app.setStatus(_("Warning: " + str(e)))
                    e_old = e

        raised = True  # Z axis is raised at start

        #Clip values out of bounds, replace with None, not to loose sync with X
        for i, item in enumerate(Y):
            y = Y[i]
            if not y is None and (y < minY or y > maxY):
                Y[i] = None

        #Y without "None", min() and max() can't compare them
        Ynn = []  #Y no Nones
        for i, item in enumerate(Y):
            if not Y[i] is None:
                Ynn.append(Y[i])

        block.append(CNC.gcode(1, [("f", CNC.vars["cutfeed"])]))  #Set feedrate

        if draw:  #If the user selected to draw the coordinate system
            #X axis
            block.append(CNC.grapid(z=3))
            block.append(CNC.grapid(0, mapc(cent[1],
                                            1)))  #1st point of X axis line
            block.append(CNC.grapid(z=0))

            block.append(CNC.gline(dim[0] + lin * 1.2, mapc(
                cent[1], 1)))  #End of X axis line + a bit more for the arrow

            block.append(
                CNC.gline(dim[0] - lin / 2,
                          mapc(cent[1], 1) -
                          lin / 2))  #bottom part of the arrow

            block.append(CNC.grapid(z=3))
            block.append(CNC.grapid(dim[0] + lin * 1.2, mapc(cent[1], 1),
                                    0))  #End of X axis line
            block.append(CNC.grapid(z=0))

            block.append(
                CNC.gline(dim[0] - lin / 2,
                          mapc(cent[1], 1) + lin / 2))  #top part of the arrow
            block.append(CNC.grapid(z=3))

            #Y axis, just inverted x with y
            block.append(CNC.grapid(z=3))
            block.append(CNC.grapid(mapc(cent[0], 0),
                                    0))  #1st point of Y axis line
            block.append(CNC.grapid(z=0))

            block.append(CNC.gline(
                mapc(cent[0], 0), dim[1] +
                lin * 1.2))  #End of Y axis line + a bit more for the arrow

            block.append(
                CNC.gline(mapc(cent[0], 0) - lin / 2,
                          dim[1] - lin / 2))  #left part of the arrow

            block.append(CNC.grapid(z=3))
            block.append(CNC.grapid(mapc(cent[0], 0),
                                    dim[1] + lin * 1.2))  #End of Y axis line
            block.append(CNC.grapid(z=0))

            block.append(
                CNC.gline(mapc(cent[0], 0) + lin / 2,
                          dim[1] - lin / 2))  #right part of the arrow
            block.append(CNC.grapid(z=3))

            #X axis number lines
            i = 0
            while i < ran[0] - cent[0]:  #While i is on the left of the arrow
                i += spacX  #Add line spacing

                #Draw lines right of the center
                block.append(
                    CNC.grapid(mapc(i + cent[0], 0),
                               mapc(cent[1], 1) + lin / 2))
                block.append(CNC.grapid(z=0))
                block.append(
                    CNC.gline(mapc(i + cent[0], 0),
                              mapc(cent[1], 1) - lin / 2))
                block.append(CNC.grapid(z=3))

            i = 0
            while i > -cent[
                    0]:  #While i is lower than center coordinate, inverted for easier math
                i -= spacX  #Add line spacing

                #Draw lines left of the center
                block.append(
                    CNC.grapid(mapc(i + cent[0], 0),
                               mapc(cent[1], 1) + lin / 2))
                block.append(CNC.grapid(z=0))
                block.append(
                    CNC.gline(mapc(i + cent[0], 0),
                              mapc(cent[1], 1) - lin / 2))
                block.append(CNC.grapid(z=3))

            #Y axis number lines
            i = 0
            while i < ran[1] - cent[
                    1]:  #While i is between the center and the arrow
                i += spacX  #Add line spacing

                #Draw lines top of the center (everything just inverted)
                block.append(
                    CNC.grapid(
                        mapc(cent[0], 0) + lin / 2, mapc(i + cent[1], 1)))
                block.append(CNC.grapid(z=0))
                block.append(
                    CNC.gline(
                        mapc(cent[0], 0) - lin / 2, mapc(i + cent[1], 1)))
                block.append(CNC.grapid(z=3))

            i = 0
            while i > -1 * cent[1]:
                i -= spacX  #Add line spacing

                #Draw lines bottom of the center
                block.append(
                    CNC.grapid(
                        mapc(cent[0], 0) + lin / 2, mapc(i + cent[1], 1)))
                block.append(CNC.grapid(z=0))
                block.append(
                    CNC.gline(
                        mapc(cent[0], 0) - lin / 2, mapc(i + cent[1], 1)))
                block.append(CNC.grapid(z=3))

            raised = True  #Z was raised

        #Draw graph
        for i, item in enumerate(Y):
            if not Y[i] is None:
                x = mapc(X[i] + cent[0], 0)  #Take an argument
                y = mapc(Y[i] + cent[1], 1)  #Take a value
            else:
                y = Y[i]  #only for tne None checks next

            if y is None and not raised:  #If a None "period" just started raise Z
                raised = True
                block.append(CNC.grapid(z=3))
            elif not y is None and raised:  #If Z was raised and the None "period" ended move to new coordinates
                block.append(CNC.grapid(round(x, 2), round(y, 2)))
                block.append(CNC.grapid(z=0))  #Lower Z
                raised = False
            elif not y is None and not raised:  #Nothing to do with Nones? Just draw
                block.append(CNC.gline(round(x, 2), round(y, 2)))

        block.append(CNC.grapid(z=3))  #Raise on the end

        blocks.append(block)
        active = app.activeBlock()
        app.gcode.insBlocks(active, blocks, 'Function inserted'
                            )  #insert blocks over active block in the editor
        app.refresh()  #refresh editor
        app.setStatus(_('Generated function graph'))  #feed back result
        print()
Esempio n. 42
0
    def execute(self, app):

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

        #Import parameters
        toolSize = self.fromMm("ToolSize")

        if toolSize <= 0:
            app.setStatus(_("Pyrograph abort: Tool Size must be > 0"))
            return

        filename = self["File"]

        #Open gcode file
        if not (filename == ""):
            app.load(filename)

        inOut = self["In-Out"]
        xadd = self["xAdd"]
        yadd = self["yAdd"]
        if xadd == "": xadd = 1
        if yadd == "": yadd = 1

        #Create the external box
        if inOut == "Out":
            box = Block("Box")
            external_box = []
            box.append(
                CNC.grapid(CNC.vars["xmin"] - xadd, CNC.vars["ymin"] - yadd))
            box.append(
                CNC.gline(CNC.vars["xmin"] - xadd, CNC.vars["ymax"] + yadd))
            box.append(
                CNC.gline(CNC.vars["xmax"] + xadd, CNC.vars["ymax"] + yadd))
            box.append(
                CNC.gline(CNC.vars["xmax"] + xadd, CNC.vars["ymin"] - yadd))
            box.append(
                CNC.gline(CNC.vars["xmin"] - xadd, CNC.vars["ymin"] - yadd))

            #Insert the external block
            external_box.append(box)
            app.gcode.insBlocks(1, external_box, "External_Box")
            app.refresh()

        #Value for creating an offset from the margins of the gcode
        margin = self.fromMm(
            "Margin"
        )  #GIVING RANDOM DECIMALS SHOULD AVOID COINCIDENT SEGMENTS BETWEEN ISLAND AND BASE PATHS THAT CONFUSE THE ALGORITHM. WORKS IN MOST CASES.

        #Add and subtract the margin
        max_x = CNC.vars["xmax"] + margin
        min_x = CNC.vars["xmin"] - margin
        max_y = CNC.vars["ymax"] + margin
        min_y = CNC.vars["ymin"] - margin

        #Difference between offtset margins
        dx = max_x - min_x
        dy = max_y - min_y

        #Number of vertical divisions according to the toolsize
        divisions = dy / toolSize

        #Distance between horizontal lines
        step_y = toolSize
        n_steps_y = int(divisions) + 1

        #Create the snake pattern according to the number of divisions
        pattern = Block(self.name)
        pattern_base = []

        for n in range(n_steps_y):
            if n == 0:
                pattern.append(CNC.grapid(min_x, min_y))  #go to bottom left
            else:
                y0 = min_y + step_y * (n - 1)
                y1 = min_y + step_y * (n)
                if not (n % 2 == 0):
                    pattern.append(CNC.glinev(
                        1, [max_x, y0]))  #write odd lines from left to right
                    pattern.append(CNC.grapid(max_x, y1))
                else:
                    pattern.append(CNC.glinev(
                        1, [min_x, y0]))  #write even lines from right to left
                    pattern.append(CNC.grapid(min_x, y1))

        #Insert the pattern block
        pattern_base.append(pattern)
        app.gcode.insBlocks(1, pattern_base, "pattern")
        app.refresh()

        #Mark pattern as island
        for bid in pattern_base:
            app.gcode.island([1])

        #Select all blocks
        app.editor.selectAll()

        paths_base = []
        paths_isl = []

        points = []

        #Compare blocks to separate island from other blocks
        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))

        #Make intersection between blocks
        while len(paths_base) > 0:
            base = paths_base.pop()
            for island in paths_isl:
                #points.extend(base.intersectPath(island))
                points.extend(island.intersectPath(base))

###SORTING POINTS###
        x = []
        y = []

        #Get (x,y) intersection points
        for i in range(len(points)):
            x.append(points[i][2][0])
            y.append(points[i][2][1])

        #Save (x,y) intersection points in a matrix
        matrix = [[0 for i in range(2)] for j in range(len(x))]

        for i in range(len(x)):
            matrix[i][0] = x[i]
            matrix[i][1] = y[i]

        # for i in range(len(x)):
        # 	print('puntos',points[i][0],points[i][1],matrix[i][0], matrix[i][1])

        #print(matrix)

        #Sort points in increasing y coordinate
        matrix.sort(key=itemgetter(1, 0), reverse=False)

        # for i in range(len(x)):
        # 	print('puntos',points[i][0],points[i][1],matrix[i][0], matrix[i][1])
        #print(matrix)

        index = 0
        pair = 0
        new_matrix = []
        for i in range(len(x)):
            if i == 0:
                index = index + 1
            elif i < len(x) - 1:
                if matrix[i][1] == matrix[i - 1][1]:
                    index = index + 1
                else:
                    if pair % 2 == 0:
                        logic = False
                    else:
                        logic = True
                    submatrix = matrix[i - index:i]
                    submatrix.sort(key=itemgetter(0, 1), reverse=logic)
                    new_matrix.extend(submatrix)
                    index = 1
                    pair = pair + 1
            else:
                #print('entered')
                if pair % 2 == 0:
                    logic = False
                else:
                    logic = True
                if matrix[i][1] == matrix[i - 1][1]:
                    submatrix = matrix[i - index:]
                    submatrix.sort(key=itemgetter(0, 1), reverse=logic)
                    new_matrix.extend(submatrix)
                else:
                    index = 1
                    submatrix = matrix[-1]
                    new_matrix.extend(submatrix)

        # for i in range(len(x)):
        # 	print('puntos',new_matrix[i][0], new_matrix[i][1])

        # for i in range(len(x)):
        # 	print('puntos',new_matrix[i][0], new_matrix[i][1])
        #print(x, y)

###SORTING POINTS END###

#Generate the gcode from points obtained
        blocks = []
        block = Block(self.name)

        for i in range(len(x)):
            if i == 0:
                block.append(CNC.grapid(new_matrix[0][0], new_matrix[0][1]))
                inside = 0
            else:
                if inside == 0:
                    block.append(CNC.gline(new_matrix[i][0], new_matrix[i][1]))
                    inside = 1
                else:
                    block.append(CNC.grapid(new_matrix[i][0],
                                            new_matrix[i][1]))
                    inside = 0

        # for i in range(len(x)):
        # 	print('puntos',x[i], y[i])

        blocks.append(block)
        app.gcode.delBlockUndo(1)
        app.gcode.insBlocks(1, blocks, "Line to Line Burning")

        app.editor.disable()

        for block in blocks:
            block.enable = 1

        #app.editor.enable()
        #app.editor.unselectAll()
        app.refresh()
        app.setStatus(_("Generated Line to Line Burning"))
Esempio n. 43
0
    def execute(self, app):
        try:
            from PIL import Image
        except:
            app.setStatus(
                _("Pyrograph abort: This plugin requires PIL/Pillow"))
            return

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

        #Calc desired size
        toolSize = self.fromMm("ToolSize")
        maxSize = self.fromMm("MaxSize")
        feedMin = self["FeedMin"]
        feedMax = self["FeedMax"]
        depth = self.fromMm("Depth")
        direction = self["Direction"]
        drawBorder = self["DrawBorder"]

        #Check parameters
        if direction is "":
            app.setStatus(_("Pyrograph abort: please define a scan Direction"))
            return

        if toolSize <= 0:
            app.setStatus(_("Pyrograph abort: Tool Size must be > 0"))
            return

        if feedMin <= 0 or feedMax <= 0:
            app.setStatus(
                _("Pyrograph abort: Please check feed rate parameters"))
            return

        #divisions
        divisions = maxSize / toolSize

        fileName = self["File"]
        try:
            img = Image.open(fileName)
            img = img.convert(
                'RGB')  #be sure to have color to calculate luminance
        except:
            app.setStatus(_("Pyrograph abort: Can't read image file"))
            return

        iWidth, iHeight = img.size
        newWidth = iWidth
        newHeight = iHeight

        ratio = 1
        if (iWidth > iHeight):
            ratio = float(iWidth) / float(iHeight)
            newWidth = int(divisions)
            newHeight = int(divisions / ratio)
        else:
            ratio = float(iHeight) / float(iWidth)
            newWidth = int(divisions / ratio)
            newHeight = int(divisions)

        #Create a thumbnail image to work faster
        img.thumbnail((newWidth, newHeight), Image.ANTIALIAS)
        newWidth, newHeight = img.size
        #img.save("thumb.png")
        pixels = list(img.getdata())

        #Extract luminance
        gMap = []
        for x in range(0, newWidth):
            gRow = []
            for y in range(0, newHeight):
                R, G, B = pixels[(y * newWidth) + x]
                L = (0.299 * R + 0.587 * G + 0.114 * B
                     )  #Luminance (Rec. 601 standard)
                gRow.append(L)
            gMap.append(gRow)

        #Init blocks
        blocks = []
        block = Block(self.name)
        block.append("(Pyrograph W=%g x H=%g x D=%g)" %
                     (newWidth * toolSize, newHeight * toolSize, depth))

        #Create points for vertical scan
        xH = []
        yH = []
        fH = []
        if (direction == "Vertical" or direction == "Both"):
            r = range(0, newHeight)
            for x in range(0, newWidth):
                r = r[::-1]
                fPrec = -1
                for y in r:
                    f = int(feedMin +
                            ((feedMax - feedMin) * gMap[x][y] / 255.0))
                    if (f != fPrec or y == 0 or y == newHeight - 1):
                        xH.append(x * toolSize)
                        yH.append((newHeight - y) * toolSize)
                        fH.append(f)
                    fPrec = f

        #Create points for horizontal scan
        xV = []
        yV = []
        fV = []
        if (direction == "Horizontal" or direction == "Both"):
            r = range(0, newWidth)
            for y in reversed(range(0, newHeight)):
                fPrec = -1
                for x in r:
                    f = int(feedMin +
                            ((feedMax - feedMin) * gMap[x][y] / 255.0))
                    if (f != fPrec or x == 0 or x == newWidth - 1):
                        xV.append(x * toolSize)
                        yV.append((newHeight - y) * toolSize)
                        fV.append(f)
                    fPrec = f
                r = r[::-1]

        #Gcode Horizontal
        if (len(xH) > 1 and len(yH) > 1):
            block.append(CNC.zsafe())
            block.append(CNC.grapid(xH[0], yH[0]))
            block.append(CNC.zenter(depth))
            for x, y, f in zip(xH, yH, fH):
                v = (x, y, depth)
                block.append(CNC.glinev(1, v, f))

        #Gcode Vertical
        if (len(xV) > 1 and len(yV) > 1):
            block.append(CNC.zsafe())
            block.append(CNC.grapid(xV[0], yV[0]))
            block.append(CNC.zenter(depth))
            for x, y, f in zip(xV, yV, fV):
                v = (x, y, depth)
                block.append(CNC.glinev(1, v, f))

        #Draw Border if required
        if drawBorder:
            block.append(CNC.zsafe())
            block.append(CNC.grapid(0, 0))
            block.append(CNC.zenter(depth))
            block.append(CNC.gcode(1, [("f", feedMin)]))
            block.append(CNC.gline(newWidth * toolSize - toolSize, 0))
            block.append(
                CNC.gline(newWidth * toolSize - toolSize,
                          newHeight * toolSize))
            block.append(CNC.gline(0, newHeight * toolSize))
            block.append(CNC.gline(0, 0))

        #Gcode Zsafe
        block.append(CNC.zsafe())

        blocks.append(block)
        active = app.activeBlock()
        if active == 0: active = 1
        app.gcode.insBlocks(active, blocks, "Pyrograph")
        app.refresh()
        app.setStatus(
            _("Generated Pyrograph W=%g x H=%g x D=%g") %
            (newWidth * toolSize, newHeight * toolSize, depth))
Esempio n. 44
0
	def execute(self, app):
		name = self["name"]
		if not name or name=="default": name="Default Name"
		sel_Blocks = self["Sel_Blocks"]
		#Get inputs
		x = self["X"]
		y = self["Y"]
		z = self["Z"]
		if z == "":
			z=CNC.vars["surface"]

		cutDiam = self["CutDiam"]
		cutRadius = cutDiam/2.0
		if self["endmill"]:
			self.master["endmill"].makeCurrent(self["endmill"])
		toolDiam = CNC.vars["diameter"]
		#Radio = self["RadioHelix"]
		pitch = self["Pitch"]
		Depth = self["Depth"]
		Mult_F_Z = self["Mult_Feed_Z"]
		helicalCut = self["HelicalCut"]
		clearanceEntry = self["ClearanceEntry"]
		clearanceExit = self["ClearanceExit"]
		clearance = clearanceEntry
		entry = self["Entry"]
		returnToSafeZ = self["ReturnToSafeZ"]

		toolDiam = CNC.vars['diameter']
		toolRadius = toolDiam/2.0
		Radio = cutRadius - toolRadius
		if(Radio < 0): Radio = 0

		toolDiam = CNC.vars['diameter']
		toolRadius = toolDiam/2.0
		Radio = cutRadius - toolRadius

		if clearanceEntry =="":
			clearanceEntry =0 
		if clearanceExit =="":
			clearanceExit =0 

		if helicalCut == "Helical Cut":
			turn = 2
			p="HelicalCut "
		elif helicalCut == "Internal Right Thread":
			turn = 2
			p= "IntRightThread "
		elif helicalCut == "Internal Left Thread":
			turn = 3
			p= "IntLeftThread "
		elif helicalCut == "External Right Thread":
			Radio = cutRadius + toolRadius
			turn = 2
			p= "ExtRightThread "
		elif helicalCut == "External Left Thread":
			Radio = cutRadius + toolRadius
			turn = 3
			p= "ExtLeftThread "

# 		------------------------------------------------------------------------------------------------------------------		
		#Check inputs
		if sel_Blocks == 0:
			if x == "" or y == "" :
				app.setStatus(_("If block selected false, please make a value of x"))
				return

		elif helicalCut == "":
			app.setStatus(_("Helical Abort: Please select helical type"))
			return

		elif cutDiam < toolDiam or cutDiam == "":
			app.setStatus(_("Helical Abort: Helix diameter must be greater than the end mill"))
			return

		elif cutDiam <= 0:
			app.setStatus(_("Helical Abort: Helix diameter must be positive"))
			return

		elif pitch <= 0 or pitch =="":
			app.setStatus(_("Helical Abort: Drop must be greater than 0"))
			return

		elif Mult_F_Z <= 0 or Mult_F_Z == "":
			app.setStatus(_("Helical Abort: Z Feed Multiplier must be greater than 0"))
			return

		elif entry == "":
			app.setStatus(_("Helical Abort: Please selecte Entry and Exit type"))
			return

		elif clearanceEntry < 0 or clearanceEntry == "":
			app.setStatus(_("Helical Abort: Entry Edge Clearence may be positive"))
			return

		elif clearanceExit < 0 or clearanceExit == "":
			app.setStatus(_("Helical Abort: Exit Edge Clearence may be positive"))
			return
# 		------------------------------------------------------------------------------------------------------------------		
		#Initialize blocks that will contain our gCode
		blocks = []
		#block = Block(name)
		block = Block( p + str(cutDiam) + " Pitch " + str(pitch) + " Bit " + str(toolDiam) + " depth " + str(Depth))
		
		cutFeed = CNC.vars["cutfeedz"]	#<<< Get cut feed Z for the current material
		cutFeedMax = CNC.vars["cutfeed"] #<<< Get cut feed XY for the current material
# 		------------------------------------------------------------------------------------------------------------------
		# Get selected blocks from editor
		selBlocks = app.editor.getSelectedBlocks()
		if not selBlocks:
			app.editor.selectAll()
			selBlocks = app.editor.getSelectedBlocks()

		if not selBlocks:
			if sel_Blocks == 1:
				app.setStatus(_("Helical abort: Please select some path"))
				return
# 		------------------------------------------------------------------------------------------------------------------
		# Get selected blocks from editor
		if sel_Blocks == 1:
			selBlocks = app.editor.getSelectedBlocks()
			if not selBlocks:
				app.editor.selectAll()
				selBlocks = app.editor.getSelectedBlocks()

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

			#Create holes locations
			allHoles=[]
			for bidSegment in allSegments:
				if len(bidSegment)==0:
					continue

				bidHoles = []
				for idx, anchor in enumerate(bidSegment):
					if idx ==2:
						newHolePoint = (anchor[0][0],anchor[0][1],anchor[0][2])
						bidHoles.append(newHolePoint)


				#Add bidHoles to allHoles
				allHoles.append(bidHoles)

# 		------------------------------------------------------------------------------------------------------------------
			holesCount = 0
			for bid in allHoles:
				for xH,yH,zH in bid:
					x = xH
					y = yH

# 		------------------------------------------------------------------------------------------------------------------
#		 Init: Adjust feed and rapid move to Z safe 
		
		if Mult_F_Z is"":
			Mult_F_Z = 1

		if Mult_F_Z == 0:
			Mult_F_Z = 1
	
		if Mult_F_Z * cutFeed > cutFeedMax:
			cutFeed = cutFeedMax
		else:
			cutFeed = cutFeed*Mult_F_Z

		block.append(CNC.zsafe()) 			#<<< Move rapid Z axis to the safe height in Stock Material

#		 Move rapid to X and Y coordinate
		if helicalCut == "Helical Cut" or helicalCut == "Internal Right Thread" or helicalCut == "Internal Left Thread":
			if entry == "Center":
				block.append(CNC.grapid(x,y))
			else:
				block.append(CNC.grapid(x-Radio+clearance ,y))

		if helicalCut == "External Right Thread" or helicalCut == "External Left Thread":
			if entry == "Center":
				clearance = 0.0
			block.append(CNC.grapid(x-Radio-clearance ,y))

		#cutFeed = int(cutFeed)
		block.append(CNC.fmt("f",cutFeed))	#<<< Set cut feed
	#	block.append(CNC.gline(x,y)
	#    while (z < 1):
		block.append(CNC.zenter(z))
		block.append(CNC.gline(x-Radio,y))
	#	cutFeed = int((CNC.vars["cutfeed"]	+ CNC.vars["cutfeedz"])/2)	#<<< Get cut feed for the current material

		#cutFeed = int(cutFeed)
		block.append(CNC.fmt("F",cutFeed))	#<<< Set cut feed
		

#-----------------------------------------------------------------------------------------------------
	#	Uncomment for first flat pass
		if helicalCut == "Helical Cut":
			block.append(CNC.gcode(turn, [("X",x-Radio),("Y",y),("Z", z),("I",Radio), ("J",0)]))
#-----------------------------------------------------------------------------------------------------
		if (z < Depth):
			pitch = -pitch

			while ((z-pitch) < Depth) :
				z = z-pitch
				block.append(CNC.gcode(turn, [("X",x-Radio),("Y",y),("Z", z),("I",Radio), ("J",0)]))

		else:
			while ((z-pitch) >= Depth) :
				z = z-pitch
				block.append(CNC.gcode(turn, [("X",x-Radio),("Y",y),("Z", z),("I",Radio), ("J",0)]))

		#Target Level
		if entry == "Center":
			clearanceExit = 0.0	
		clearance = clearanceExit
		alpha= round(Depth / pitch, 4 ) - round(Depth / pitch, 0)
		alpha = alpha * 2*pi 
		Radiox = Radio * cos(alpha)
		Radioy = Radio * sin(alpha)
		xsi = Radiox - clearance* cos(alpha)
		ysi =Radioy - clearance* sin(alpha)
		xse = Radiox + clearance* cos(alpha)
		yse =Radioy + clearance* sin(alpha)
		z = Depth



		if helicalCut == "Helical Cut":
			block.append(CNC.gcode(turn, [("X",x-Radio),("Y",y),("Z", z),("I",Radio), ("J",0)]))
			#Last flat pass
			block.append(CNC.gcode(turn, [("X",x-Radio),("Y",y),("Z", z),("I",Radio), ("J",0)]))
		elif helicalCut == 	"Internal Right Thread" or helicalCut == "External Right Thread":
			block.append(CNC.gcode(turn, [("X",x-Radiox),("Y",y-Radioy),("Z", z),("I",Radio), ("J",0)]))

		elif helicalCut == 	"Internal Left Thread" or helicalCut ==	"External Left Thread":
			block.append(CNC.gcode(turn, [("X",x-Radiox),("Y",y+Radioy),("Z", z),("I",Radio), ("J",0)]))

		# Exit clearance 
		if helicalCut == "Internal Right Thread":
			block.append(CNC.gline(x-xsi,y-ysi))
		elif helicalCut == "Internal Left Thread":
			block.append(CNC.gline(x-xsi,y+ysi))
		if helicalCut == "External Right Thread":
			block.append(CNC.gline(x-xse,y-yse))
		elif helicalCut == "External Left Thread":
			block.append(CNC.gline(x-xse,y+yse))

		# Return to Z Safe
		if returnToSafeZ == 1: 
			if helicalCut == "Helical Cut" or helicalCut == "Internal Right Thread" or helicalCut == "Internal Left Thread":
				if entry == "Center":
					block.append(CNC.gline(x,y))
			block.append(CNC.zsafe())

		blocks.append(block)
		active = app.activeBlock()
		app.gcode.insBlocks(active, blocks, "Helical_Descent inserted")	#<<< insert blocks over active block in the editor
		app.refresh()												#<<< refresh editor
		app.setStatus(_("Generated: Helical_Descent Result"))				#<<< feed back result
Esempio n. 45
0
	def make(self,app, XStart=0.0, YStart=0.0, ZStart=30., AlignAxis="Y", \
			RotAxis="A", StockLeng=20, ReduceDepth=-1, PassDepth=1, \
			Stepover=1, ZApproach=35, SpiralType="Spiral", CutBoth="True", LiftPass="******"):

		#GCode Blocks
		blocks = []
		
		# Load tool and material settings
		toolDiam = CNC.vars['diameter']
		toolRadius = toolDiam / 2.

		#Calc tool diameter with Maximum Step Over allowed
		StepOverInUnitMax = toolDiam * CNC.vars['stepover'] / 100.0		

		#Check parameters
		if RotAxis == "":
			app.setStatus(_("Spiral abort: Rotary Axis is undefined"))
			return

		if SpiralType == "":
			app.setStatus(_("Spiral abort: Spiral Type is undefined"))
			return

		if ZApproach <= ZStart :
			app.setStatus(_("Spiral abort: Approach height must be greater than Z Start"))
			return

		if ReduceDepth > 0 :
			app.setStatus(_("Spiral abort: Depth Reduction must be negative"))
			return

		if Stepover > StepOverInUnitMax and SpiralType == "Spiral":  #if Type is Lines then stepover is degrees not mm
			app.setStatus(_("Spiral abort: Step Over exceeds tool limits"))
			return 
		elif Stepover > StepOverInUnitMax and SpiralType == "Lines":  # This could cause a tool crash, but could also be used to make faceted shapes.
			dr=tkMessageBox.askyesno("Crash Risk","WARNING: Using a larger stepover value than tool's maximum with lines operation may result in a tool crash. Do you want to continue?")
			sys.stdout.write("%s"%(dr))
			if dr == True or dr == "yes" :
				app.setStatus(_("Risk Accepted")) #Using positive logic, if python returns ANYTHING other than True/yes this will not make g-code.  Incase Python uses No instead of False
			else:
				return
		if StockLeng <= 0 :
			app.setStatus(_("Spiral abort: Stock Length to cut must be positive"))
			return
			

		#Add Region disabled to show worked area
		block = Block(self.name + " Outline")
		block.enable = False
		block.append(CNC.grapid(CNC.vars["wx"],CNC.vars["wy"],ZApproach))  ## Cannot trust Safe-Z with 4th axis!!
		if AlignAxis == "X":
			outlineWidth = StockLeng
		else:
			outlineWidth = 0
		if AlignAxis == "Y":
			outlineHeight = StockLeng
		else:
			outlineHeight = 0
		xR,yR = self.RectPath(XStart,YStart,outlineWidth,outlineHeight)
		for x,y in zip(xR,yR):
			block.append(CNC.gline(x,y))
		blocks.append(block)

		
		if StockLeng < toolDiam :
			app.setStatus(_("Spiral abort: Stock Length is too small for this End Mill."))
			return

		#Prepare points for pocketing
		xP=[]
		yP=[]
		rP=[]
		zP=[]
		gP=[]
        

        #---------------------------------------------------------------------
        #Line approach
		if SpiralType == "Lines":
			#Calc number of indexes
			IndexNum = math.ceil(360/Stepover) # Using the step over as Degrees 
						

			#Calc number of pass
			VerticalCount = math.ceil(abs(ReduceDepth) / PassDepth)
			#Calc even depths of cut
			EvenCutDepths = ReduceDepth / VerticalCount
			
			currentR = 0
			currentZ = ZStart - EvenCutDepths
			direction = 1
			if AlignAxis == "X" :
				currentX = XStart + toolRadius
				currentY = YStart
			elif AlignAxis == "Y":
				currentX = XStart
				currentY = YStart + toolRadius
			else:
				app.setStatus(_("Spiral abort: Rotary Axis Not Assigned."))
				return			
			
			while (currentZ >= (ZStart + ReduceDepth)):
				#sys.stdout.write("~~~~~%s,%s,%s,%s,%s!"%(currentZ,ZStart,ReduceDepth,EvenCutDepths,VerticalCount))
				while (currentR < 360):
					#sys.stdout.write("~~~~~%s,%s,%s,%s,%s!"%(currentR,Stepover,currentX,currentY,VerticalCount))

					#Plunge in
					gP.append(1)
					rP.append(currentR)
					zP.append(currentZ)			
					xP.append(currentX)
					yP.append(currentY)
					if direction == 1:
						if AlignAxis == "X" :
							currentX = StockLeng - toolRadius
							currentY = YStart
						elif AlignAxis == "Y":
							currentX = XStart
							currentY = StockLeng - toolRadius
						else:
							app.setStatus(_("Spiral abort: Rotary Axis Not Assigned."))
							return
						if CutBoth == "True" :
							direction = -1
					else :
						if AlignAxis == "X" :
							currentX = XStart + toolRadius
							currentY = YStart
						elif AlignAxis == "Y":
							currentX = XStart
							currentY = YStart + toolRadius
						else:
							app.setStatus(_("Spiral abort: Rotary Axis Not Assigned."))
							return
						direction = 1
					gP.append(1)
					zP.append(currentZ)			
					xP.append(currentX)
					yP.append(currentY)
					rP.append(currentR)
					# Lift before rotating if required, useful to make non-round shape

					if CutBoth == "False" : # Return to start
					
						#Lift Before return
						gP.append(0)
						rP.append(currentR)
						zP.append(ZApproach)
						xP.append(currentX)
						yP.append(currentY)

						#Return to start
						if AlignAxis == "X" :
							currentX = XStart + toolRadius
							currentY = YStart
						elif AlignAxis == "Y":
							currentX = XStart
							currentY = YStart + toolRadius
						else:
							app.setStatus(_("Spiral abort: Rotary Axis Not Assigned."))
							return
						gP.append(0)
						xP.append(currentX)
						yP.append(currentY)
						rP.append(currentR)
						zP.append(ZApproach)
						#Rotate
						currentR += Stepover
						gP.append(0)
						xP.append(currentX)
						yP.append(currentY)
						rP.append(currentR)
						zP.append(ZApproach)
					elif LiftPass == "True" and CutBoth == "True" :
						gP.append(0)
						rP.append(currentR)
						zP.append(ZApproach)
						xP.append(currentX)
						yP.append(currentY)
						currentR += Stepover
						gP.append(0)
						xP.append(currentX)
						yP.append(currentY)
						rP.append(currentR)
						zP.append(ZApproach)
					elif LiftPass == "False" and CutBoth == "True" :
						currentR += Stepover
				gP.append(0)
				xP.append(currentX)
				yP.append(currentY)
				rP.append(currentR)
				zP.append(ZApproach)
				currentR=0
				gP.append(0)
				xP.append(currentX)
				yP.append(currentY)
				rP.append(currentR)
				zP.append(ZApproach)		

					
					
					
				#Step Down
				currentZ += EvenCutDepths			

		#---------------------------------------------------------------------
        #Spiral approach
		if SpiralType == "Spiral":
			#Calc number of pass
			StepsPerRot = math.ceil(StockLeng/Stepover)
			TotalRot = 360 * StepsPerRot
			
			#Calc steps in depth
			VerticalCount = math.ceil(abs(ReduceDepth) / PassDepth)
			#Calc even depths of cut
			EvenCutDepths = ReduceDepth / VerticalCount			
			
			direction = 1
			currentZ = ZStart - EvenCutDepths
			if AlignAxis == "X" :
				currentX = XStart + toolRadius
				currentY = YStart
			elif AlignAxis == "Y":
				currentX = XStart
				currentY = YStart + toolRadius
			else:
				app.setStatus(_("Spiral abort: Rotary Axis Not Assigned."))
				return
			currentR = 0
			while (currentZ >= (ZStart + ReduceDepth)):
				
				# Plunge to depth
				currentR += 90 # Ramp the Plunge
				gP.append(1)
				rP.append(currentR)
				zP.append(currentZ)			
				xP.append(currentX)
				yP.append(currentY)
				
				# One Full Rotation for a clean shoulder
				currentR += 360
				gP.append(1)
				rP.append(currentR)
				zP.append(currentZ)			
				xP.append(currentX)
				yP.append(currentY)
				
				
				if AlignAxis == "X" :
					if direction == 1:
						currentX = StockLeng - toolRadius
					else:
						currentX = XStart + toolRadius
					currentY = YStart
				elif AlignAxis == "Y":
					currentX = XStart
					if direction == 1:
						currentY = StockLeng - toolRadius
					else:
						currentY = YStart + toolRadius
				else:
					app.setStatus(_("Spiral abort: Rotary Axis Not Assigned."))
					return
					
				currentR += TotalRot
				gP.append(1)
				rP.append(currentR)
				zP.append(currentZ)			
				xP.append(currentX)
				yP.append(currentY)
				
				# One Full Rotation for a clean shoulder
				currentR += 360
				gP.append(1)
				rP.append(currentR)
				zP.append(currentZ)			
				xP.append(currentX)
				yP.append(currentY)
				
				if CutBoth == "True" : 
					direction *=  - 1
				else:
					#Retract
					gP.append(0)
					rP.append(currentR)
					zP.append(ZApproach)			
					xP.append(currentX)
					yP.append(currentY)
					# Return and Rewind
					gP.append(0)
					rP.append(currentR)
					zP.append(ZApproach)
					if AlignAxis == "X" :
						currentX = XStart + toolRadius
						currentY = YStart
					elif AlignAxis == "Y":
						currentX = XStart
						currentY = YStart + toolRadius
					else:
						app.setStatus(_("Spiral abort: Rotary Axis Not Assigned."))
						return
					xP.append(currentX)
					yP.append(currentY)
				
				
				currentZ += EvenCutDepths
				

#Start G-Code Processes
		#Blocks for pocketing
		block = Block(self.name)
		block.append("(Reduce Rotary by Y=%g)"%(ReduceDepth))
		block.append("(Approach: %s )" % (SpiralType))

		#Move safe to first point
		block.append(CNC.grapid(CNC.vars["mx"],CNC.vars["my"],ZApproach))  ## Cannot trust Safe-Z with 4th axis!!
		if AlignAxis == "X" :
			block.append(CNC.grapid(XStart + toolRadius,YStart))
		elif AlignAxis == "Y":
			block.append(CNC.grapid(XStart,YStart + toolRadius))
		else:
			app.setStatus(_("Spiral abort: Rotary Axis Not Assigned."))
			return
		
		block.append(CNC.zenter(ZApproach))
		block.append(CNC.gcode(1, [("f",CNC.vars["cutfeed"])]))
		
		for g,x,y,z,r in zip(gP, xP,yP,zP, rP):
			if RotAxis == "A" :
				if g==0:
					block.append(CNC.grapidABC(x,y,z,r,CNC.vars["wb"],CNC.vars["wc"]))
					#sys.stdout.write("%s,%s,%s,%s,%s"%(g,x,y,z,r))
				else:
					block.append(CNC.glineABC(x,y,z,r,CNC.vars["wb"],CNC.vars["wc"]))
					#sys.stdout.write("%s,%s,%s,%s,%s"%(g,x,y,z,r))
			elif RotAxis == "B" :
				if g==0:
					block.append(CNC.grapidABC(x,y,z,CNC.vars["wa"],r,CNC.vars["wc"]))
				else:
					block.append(CNC.glineABC(x,y,z,CNC.vars["wa"],r,CNC.vars["wc"]))
			elif RotAxis == "C" :
				if g==0:
					block.append(CNC.grapidABC(x,y,z,CNC.vars["wa"],CNC.vars["wb"],r))
				else:
					block.append(CNC.glineABC(x,y,z,CNC.vars["wa"],CNC.vars["wb"],r))

			
		block.append(CNC.grapid(CNC.vars["wx"],CNC.vars["wy"],ZApproach))  ## Cannot trust Safe-Z with 4th axis!!
		if AlignAxis == "X" :
			block.append(CNC.grapid(XStart + toolRadius,YStart))
		elif AlignAxis == "Y":
			block.append(CNC.grapid(XStart,YStart + toolRadius))
		else:
			app.setStatus(_("Spiral abort: Rotary Axis Not Assigned."))
			return
		block.append(CNC.zexit(ZApproach))
		blocks.append(block)
		tkMessageBox.showinfo("Crash Risk","WARNING: Check CAM file Header for Z move. If it exists, remove it to prevent tool crash.")

		return blocks
Esempio n. 46
0
	def execute(self, app):
		try:
			from PIL import Image
		except:
			app.setStatus(_("Pyrograph abort: This plugin requires PIL/Pillow"))
			return

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

		#Calc desired size
		toolSize = self.fromMm("ToolSize")
		maxSize = self.fromMm("MaxSize")
		feedMin = self["FeedMin"]
		feedMax = self["FeedMax"]
		depth = self.fromMm("Depth")
		direction = self["Direction"]
		drawBorder = self["DrawBorder"]

		#Check parameters
		if direction is "":
			app.setStatus(_("Pyrograph abort: please define a scan Direction"))
			return

		if toolSize <=0:
			app.setStatus(_("Pyrograph abort: Tool Size must be > 0"))
			return

		if feedMin <=0 or feedMax <=0 :
			app.setStatus(_("Pyrograph abort: Please check feed rate parameters"))
			return

		#divisions
		divisions = maxSize / toolSize

		fileName = self["File"]
		try:
			img = Image.open(fileName)
			img = img.convert ('RGB') #be sure to have color to calculate luminance
		except:
			app.setStatus(_("Pyrograph abort: Can't read image file"))
			return

		iWidth,iHeight =  img.size
		newWidth = iWidth
		newHeight = iHeight

		ratio = 1
		if (iWidth > iHeight):
			ratio = float(iWidth) / float(iHeight)
			newWidth = int(divisions)
			newHeight = int(divisions / ratio)
		else:
			ratio = float(iHeight) / float(iWidth)
			newWidth = int(divisions / ratio)
			newHeight = int(divisions)

		#Create a thumbnail image to work faster
		img.thumbnail((newWidth,newHeight), Image.ANTIALIAS)
		newWidth,newHeight =  img.size
		#img.save("thumb.png")
		pixels = list(img.getdata())

		#Extract luminance
		gMap = []
		for x in range(0,newWidth):
			gRow = []
			for y in range(0,newHeight):
				R,G,B = pixels[(y * newWidth) + x ]
				L = (0.299*R + 0.587*G + 0.114*B) #Luminance (Rec. 601 standard)
				gRow.append(L)
			gMap.append(gRow)

		#Init blocks
		blocks = []
		block = Block(self.name)
		block.append("(Pyrograph W=%g x H=%g x D=%g)" %
		(newWidth * toolSize , newHeight * toolSize , depth))

		#Create points for vertical scan
		xH = []
		yH = []
		fH = []
		if (direction=="Vertical" or direction=="Both"):
			r = range(0,newHeight)
			for x in range(0,newWidth):
				r = r[::-1]
				fPrec = -1
				for y in r:
					f = int(feedMin + ((feedMax - feedMin) * gMap[x][y] / 255.0))
					if(f != fPrec or y==0 or  y==newHeight-1):
						xH.append(x * toolSize)
						yH.append((newHeight-y) * toolSize)
						fH.append(f)
					fPrec = f

		#Create points for horizontal scan
		xV = []
		yV = []
		fV = []
		if (direction=="Horizontal" or direction=="Both"):
			r = range(0,newWidth)
			for y in reversed(range(0,newHeight)):
				fPrec = -1
				for x in r:
					f = int(feedMin + ((feedMax - feedMin) * gMap[x][y] / 255.0))
					if(f != fPrec or x==0 or x==newWidth-1):
						xV.append(x * toolSize)
						yV.append((newHeight-y) * toolSize)
						fV.append(f)
					fPrec = f
				r = r[::-1]

		#Gcode Horizontal
		if (len(xH)>1 and len(yH)>1):
			block.append(CNC.zsafe())
			block.append(CNC.grapid(xH[0],yH[0]))
			block.append(CNC.zenter(depth))
			for x,y,f in zip(xH,yH,fH):
					v = (x,y,depth)
					block.append(CNC.glinev(1,v,f))

		#Gcode Vertical
		if (len(xV)>1 and len(yV)>1):
			block.append(CNC.zsafe())
			block.append(CNC.grapid(xV[0],yV[0]))
			block.append(CNC.zenter(depth))
			for x,y,f in zip(xV,yV,fV):
					v = (x,y,depth)
					block.append(CNC.glinev(1,v,f))

		#Draw Border if required
		if drawBorder:
			block.append(CNC.zsafe())
			block.append(CNC.grapid(0,0))
			block.append(CNC.zenter(depth))
			block.append(CNC.gcode(1, [("f",feedMin)]))
			block.append(CNC.gline(newWidth * toolSize - toolSize,0))
			block.append(CNC.gline(newWidth * toolSize - toolSize ,newHeight* toolSize))
			block.append(CNC.gline(0,newHeight* toolSize ))
			block.append(CNC.gline(0,0))

		#Gcode Zsafe
		block.append(CNC.zsafe())

		blocks.append(block)
		active = app.activeBlock()
		if active==0: active=1
		app.gcode.insBlocks(active, blocks, "Pyrograph")
		app.refresh()
		app.setStatus(_("Generated Pyrograph W=%g x H=%g x D=%g") %
		(newWidth * toolSize , newHeight * toolSize , depth))
Esempio n. 47
0
    def execute(self, app):
        name = self["name"]
        if not name or name == "default": name = "Default Name"
        sel_Blocks = self["Sel_Blocks"]
        #Get inputs
        x = self["X"]
        y = self["Y"]
        z = self["Z"]
        if z == "":
            z = CNC.vars["surface"]

        cutDiam = self["CutDiam"]
        cutRadius = cutDiam / 2.0
        if self["endmill"]:
            self.master["endmill"].makeCurrent(self["endmill"])
        toolDiam = CNC.vars["diameter"]
        #Radio = self["RadioHelix"]
        pitch = self["Pitch"]
        Depth = self["Depth"]
        Mult_F_Z = self["Mult_Feed_Z"]
        helicalCut = self["HelicalCut"]
        clearanceEntry = self["ClearanceEntry"]
        clearanceExit = self["ClearanceExit"]
        clearance = clearanceEntry
        entry = self["Entry"]
        returnToSafeZ = self["ReturnToSafeZ"]

        toolDiam = CNC.vars['diameter']
        toolRadius = toolDiam / 2.0
        Radio = cutRadius - toolRadius
        if (Radio < 0): Radio = 0

        toolDiam = CNC.vars['diameter']
        toolRadius = toolDiam / 2.0
        Radio = cutRadius - toolRadius

        if clearanceEntry == "":
            clearanceEntry = 0
        if clearanceExit == "":
            clearanceExit = 0

        if helicalCut == "Helical Cut":
            turn = 2
            p = "HelicalCut "
        elif helicalCut == "Internal Right Thread":
            turn = 2
            p = "IntRightThread "
        elif helicalCut == "Internal Left Thread":
            turn = 3
            p = "IntLeftThread "
        elif helicalCut == "External Right Thread":
            Radio = cutRadius + toolRadius
            turn = 2
            p = "ExtRightThread "
        elif helicalCut == "External Left Thread":
            Radio = cutRadius + toolRadius
            turn = 3
            p = "ExtLeftThread "

# 		------------------------------------------------------------------------------------------------------------------
#Check inputs
        if sel_Blocks == 0:
            if x == "" or y == "":
                app.setStatus(
                    _("If block selected false, please make a value of x"))
                return

        elif helicalCut == "":
            app.setStatus(_("Helical Abort: Please select helical type"))
            return

        elif cutDiam < toolDiam or cutDiam == "":
            app.setStatus(
                _("Helical Abort: Helix diameter must be greater than the end mill"
                  ))
            return

        elif cutDiam <= 0:
            app.setStatus(_("Helical Abort: Helix diameter must be positive"))
            return

        elif pitch <= 0 or pitch == "":
            app.setStatus(_("Helical Abort: Drop must be greater than 0"))
            return

        elif Mult_F_Z <= 0 or Mult_F_Z == "":
            app.setStatus(
                _("Helical Abort: Z Feed Multiplier must be greater than 0"))
            return

        elif entry == "":
            app.setStatus(
                _("Helical Abort: Please selecte Entry and Exit type"))
            return

        elif clearanceEntry < 0 or clearanceEntry == "":
            app.setStatus(
                _("Helical Abort: Entry Edge Clearence may be positive"))
            return

        elif clearanceExit < 0 or clearanceExit == "":
            app.setStatus(
                _("Helical Abort: Exit Edge Clearence may be positive"))
            return
# 		------------------------------------------------------------------------------------------------------------------
#Initialize blocks that will contain our gCode
        blocks = []
        #block = Block(name)
        block = Block(p + str(cutDiam) + " Pitch " + str(pitch) + " Bit " +
                      str(toolDiam) + " depth " + str(Depth))

        cutFeed = CNC.vars[
            "cutfeedz"]  #<<< Get cut feed Z for the current material
        cutFeedMax = CNC.vars[
            "cutfeed"]  #<<< Get cut feed XY for the current material
        # 		------------------------------------------------------------------------------------------------------------------
        # Get selected blocks from editor
        selBlocks = app.editor.getSelectedBlocks()
        if not selBlocks:
            app.editor.selectAll()
            selBlocks = app.editor.getSelectedBlocks()

        if not selBlocks:
            if sel_Blocks == 1:
                app.setStatus(_("Helical abort: Please select some path"))
                return
# 		------------------------------------------------------------------------------------------------------------------
# Get selected blocks from editor
        if sel_Blocks == 1:
            selBlocks = app.editor.getSelectedBlocks()
            if not selBlocks:
                app.editor.selectAll()
                selBlocks = app.editor.getSelectedBlocks()

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

            #Create holes locations
            allHoles = []
            for bidSegment in allSegments:
                if len(bidSegment) == 0:
                    continue

                bidHoles = []
                for idx, anchor in enumerate(bidSegment):
                    if idx == 2:
                        newHolePoint = (anchor[0][0], anchor[0][1],
                                        anchor[0][2])
                        bidHoles.append(newHolePoint)

                #Add bidHoles to allHoles
                allHoles.append(bidHoles)

# 		------------------------------------------------------------------------------------------------------------------
            holesCount = 0
            for bid in allHoles:
                for xH, yH, zH in bid:
                    x = xH
                    y = yH

# 		------------------------------------------------------------------------------------------------------------------
#		 Init: Adjust feed and rapid move to Z safe

        if Mult_F_Z is "":
            Mult_F_Z = 1

        if Mult_F_Z == 0:
            Mult_F_Z = 1

        if Mult_F_Z * cutFeed > cutFeedMax:
            cutFeed = cutFeedMax
        else:
            cutFeed = cutFeed * Mult_F_Z

        block.append(CNC.zsafe(
        ))  #<<< Move rapid Z axis to the safe height in Stock Material

        #		 Move rapid to X and Y coordinate
        if helicalCut == "Helical Cut" or helicalCut == "Internal Right Thread" or helicalCut == "Internal Left Thread":
            if entry == "Center":
                block.append(CNC.grapid(x, y))
            else:
                block.append(CNC.grapid(x - Radio + clearance, y))

        if helicalCut == "External Right Thread" or helicalCut == "External Left Thread":
            if entry == "Center":
                clearance = 0.0
            block.append(CNC.grapid(x - Radio - clearance, y))

        #cutFeed = int(cutFeed)
        block.append(CNC.fmt("f", cutFeed))  #<<< Set cut feed
        #	block.append(CNC.gline(x,y)
        #    while (z < 1):
        block.append(CNC.zenter(z))
        block.append(CNC.gline(x - Radio, y))
        #	cutFeed = int((CNC.vars["cutfeed"]	+ CNC.vars["cutfeedz"])/2)	#<<< Get cut feed for the current material

        #cutFeed = int(cutFeed)
        block.append(CNC.fmt("F", cutFeed))  #<<< Set cut feed

        #-----------------------------------------------------------------------------------------------------
        #	Uncomment for first flat pass
        if helicalCut == "Helical Cut":
            block.append(
                CNC.gcode(turn, [("X", x - Radio), ("Y", y), ("Z", z),
                                 ("I", Radio), ("J", 0)]))
#-----------------------------------------------------------------------------------------------------
        if (z < Depth):
            pitch = -pitch

            while ((z - pitch) < Depth):
                z = z - pitch
                block.append(
                    CNC.gcode(turn, [("X", x - Radio), ("Y", y), ("Z", z),
                                     ("I", Radio), ("J", 0)]))

        else:
            while ((z - pitch) >= Depth):
                z = z - pitch
                block.append(
                    CNC.gcode(turn, [("X", x - Radio), ("Y", y), ("Z", z),
                                     ("I", Radio), ("J", 0)]))

        #Target Level
        if entry == "Center":
            clearanceExit = 0.0
        clearance = clearanceExit
        alpha = round(Depth / pitch, 4) - round(Depth / pitch, 0)
        alpha = alpha * 2 * pi
        Radiox = Radio * cos(alpha)
        Radioy = Radio * sin(alpha)
        xsi = Radiox - clearance * cos(alpha)
        ysi = Radioy - clearance * sin(alpha)
        xse = Radiox + clearance * cos(alpha)
        yse = Radioy + clearance * sin(alpha)
        z = Depth

        if helicalCut == "Helical Cut":
            block.append(
                CNC.gcode(turn, [("X", x - Radio), ("Y", y), ("Z", z),
                                 ("I", Radio), ("J", 0)]))
            #Last flat pass
            block.append(
                CNC.gcode(turn, [("X", x - Radio), ("Y", y), ("Z", z),
                                 ("I", Radio), ("J", 0)]))
        elif helicalCut == "Internal Right Thread" or helicalCut == "External Right Thread":
            block.append(
                CNC.gcode(turn, [("X", x - Radiox), ("Y", y - Radioy),
                                 ("Z", z), ("I", Radio), ("J", 0)]))

        elif helicalCut == "Internal Left Thread" or helicalCut == "External Left Thread":
            block.append(
                CNC.gcode(turn, [("X", x - Radiox), ("Y", y + Radioy),
                                 ("Z", z), ("I", Radio), ("J", 0)]))

        # Exit clearance
        if helicalCut == "Internal Right Thread":
            block.append(CNC.gline(x - xsi, y - ysi))
        elif helicalCut == "Internal Left Thread":
            block.append(CNC.gline(x - xsi, y + ysi))
        if helicalCut == "External Right Thread":
            block.append(CNC.gline(x - xse, y - yse))
        elif helicalCut == "External Left Thread":
            block.append(CNC.gline(x - xse, y + yse))

        # Return to Z Safe
        if returnToSafeZ == 1:
            if helicalCut == "Helical Cut" or helicalCut == "Internal Right Thread" or helicalCut == "Internal Left Thread":
                if entry == "Center":
                    block.append(CNC.gline(x, y))
            block.append(CNC.zsafe())

        blocks.append(block)
        active = app.activeBlock()
        app.gcode.insBlocks(
            active, blocks, "Helical_Descent inserted"
        )  #<<< insert blocks over active block in the editor
        app.refresh()  #<<< refresh editor
        app.setStatus(
            _("Generated: Helical_Descent Result"))  #<<< feed back result
Esempio n. 48
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))))
Esempio n. 49
0
    def calc(self, N, phi, Pc):
        N = abs(N)
        # Pitch Circle
        D = N * Pc / math.pi
        R = D / 2.0

        # Diametrical pitch
        Pd = N / D

        # Base Circle
        Db = D * math.cos(phi)
        Rb = Db / 2.0

        # Addendum
        a = 1.0 / Pd

        # Outside Circle
        Ro = R + a
        Do = 2.0 * Ro

        # Tooth thickness
        T = math.pi * D / (2 * N)

        # undercut?
        U = 2.0 / (math.sin(phi) * (math.sin(phi)))
        needs_undercut = N < U
        # sys.stderr.write("N:%s R:%s Rb:%s\n" % (N,R,Rb))

        # Clearance
        c = 0.0
        # Dedendum
        b = a + c

        # Root Circle
        Rr = R - b
        Dr = 2.0 * Rr

        two_pi = 2.0 * math.pi
        half_thick_angle = two_pi / (4.0 * N)
        pitch_to_base_angle = self.involute_intersect_angle(Rb, R)
        pitch_to_outer_angle = self.involute_intersect_angle(
            Rb, Ro)  # pitch_to_base_angle

        points = []
        for x in range(1, N + 1):
            c = x * two_pi / N

            # angles
            pitch1 = c - half_thick_angle
            base1 = pitch1 - pitch_to_base_angle
            outer1 = pitch1 + pitch_to_outer_angle

            pitch2 = c + half_thick_angle
            base2 = pitch2 + pitch_to_base_angle
            outer2 = pitch2 - pitch_to_outer_angle

            # points
            b1 = self.point_on_circle(Rb, base1)
            p1 = self.point_on_circle(R, pitch1)
            o1 = self.point_on_circle(Ro, outer1)
            o2 = self.point_on_circle(Ro, outer2)
            p2 = self.point_on_circle(R, pitch2)
            b2 = self.point_on_circle(Rb, base2)

            if Rr >= Rb:
                pitch_to_root_angle = pitch_to_base_angle - self.involute_intersect_angle(
                    Rb, Rr)
                root1 = pitch1 - pitch_to_root_angle
                root2 = pitch2 + pitch_to_root_angle
                r1 = self.point_on_circle(Rr, root1)
                r2 = self.point_on_circle(Rr, root2)

                points.append(r1)
                points.append(p1)
                points.append(o1)
                points.append(o2)
                points.append(p2)
                points.append(r2)
            else:
                r1 = self.point_on_circle(Rr, base1)
                r2 = self.point_on_circle(Rr, base2)
                points.append(r1)
                points.append(b1)
                points.append(p1)
                points.append(o1)
                points.append(o2)
                points.append(p2)
                points.append(b2)
                points.append(r2)

        first = points[0]
        del points[0]

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

        block.append(CNC.grapid(first.x(), first.y()))
        block.append(CNC.zenter(0.0))
        #print first.x(), first.y()
        for v in points:
            block.append(CNC.gline(v.x(), v.y()))
            #print v.x(), v.y()
        #print first.x(), first.y()
        block.append(CNC.gline(first.x(), first.y()))
        block.append(CNC.zsafe())

        #block = Block("%s-center"%(self.name))
        block = Block("%s-basecircle" % (self.name))
        block.enable = False
        block.append(CNC.grapid(Db / 2, 0.))
        block.append(CNC.zenter(0.0))
        block.append(CNC.garc(CW, Db / 2, 0., i=-Db / 2))
        block.append(CNC.zsafe())
        blocks.append(block)
        return blocks
Esempio n. 50
0
    def make(self,app, XStart=0.0, YStart=0.0, FlatWidth=10., FlatHeight=10., \
      FlatDepth=0, BorderPass=False, CutDirection="Climb", PocketType="Raster"):

        #GCode Blocks
        blocks = []

        #Check parameters
        if CutDirection == "":
            app.setStatus(_("Flatten abort: Cut Direction is undefined"))
            return

        if PocketType == "":
            app.setStatus(_("Flatten abort: Pocket Type is undefined"))
            return

        if FlatWidth <= 0 or FlatHeight <= 0:
            app.setStatus(
                _("Flatten abort: Flatten Area dimensions must be > 0"))
            return

        if FlatDepth > 0:
            app.setStatus(
                _("Flatten abort: Hey this is only for subtractive machine! Check depth!"
                  ))
            return

        #Add Region disabled to show worked area
        block = Block(self.name + " Outline")
        block.enable = False
        block.append(CNC.zsafe())
        xR, yR = self.RectPath(XStart, YStart, FlatWidth, FlatHeight)
        for x, y in zip(xR, yR):
            block.append(CNC.gline(x, y))
        blocks.append(block)

        # Load tool and material settings
        toolDiam = CNC.vars['diameter']
        toolRadius = toolDiam / 2.

        #Calc tool diameter with Maximum Step Over allowed
        StepOverInUnitMax = toolDiam * CNC.vars['stepover'] / 100.0

        #Offset for Border Cut
        BorderXStart = XStart + toolRadius
        BorderYStart = YStart + toolRadius
        BorderWidth = FlatWidth - toolDiam
        BorderHeight = FlatHeight - toolDiam
        BorderXEnd = XStart + FlatWidth - toolRadius
        BorderYEnd = YStart + FlatHeight - toolRadius

        PocketXStart = BorderXStart
        PocketYStart = BorderYStart
        PocketXEnd = BorderXEnd
        PocketYEnd = BorderYEnd

        #Calc space to work with/without border cut
        WToWork = FlatWidth - toolDiam
        HToWork = FlatHeight - toolDiam

        if (WToWork < toolRadius or HToWork < toolRadius):
            app.setStatus(
                _("Flatten abort: Flatten area is too small for this End Mill."
                  ))
            return

        #Prepare points for pocketing
        xP = []
        yP = []
        #and border
        xB = []
        yB = []

        #---------------------------------------------------------------------
        #Raster approach
        if PocketType == "Raster":
            #Correct sizes if border is used
            if (BorderPass):
                PocketXStart += StepOverInUnitMax
                PocketYStart += StepOverInUnitMax
                PocketXEnd -= StepOverInUnitMax
                PocketYEnd -= StepOverInUnitMax
                WToWork -= (StepOverInUnitMax)
                HToWork -= (StepOverInUnitMax)

            #Calc number of pass
            VerticalCount = (int)(HToWork / StepOverInUnitMax)
            #Calc step minor of Max step
            StepOverInUnit = HToWork / (VerticalCount + 1)
            flip = False
            ActualY = PocketYStart
            #Zig zag
            if StepOverInUnit == 0:
                StepOverInUnit = 0.001  #avoid infinite while loop
            while (True):
                #Zig
                xP.append(self.ZigZag(flip, PocketXStart, PocketXEnd))
                yP.append(ActualY)
                flip = not flip
                #Zag
                xP.append(self.ZigZag(flip, PocketXStart, PocketXEnd))
                yP.append(ActualY)
                if (ActualY >=
                        PocketYEnd - StepOverInUnitMax + StepOverInUnit):
                    break
                #Up
                ActualY += StepOverInUnit
                xP.append(self.ZigZag(flip, PocketXStart, PocketXEnd))
                yP.append(ActualY)

            #Points for border cut depends on Zig/Zag end
            if (BorderPass):
                if flip:
                    xB, yB = self.RectPath(BorderXStart, BorderYEnd,
                                           BorderWidth, -BorderHeight)
                else:
                    xB, yB = self.RectPath(BorderXEnd, BorderYEnd,
                                           -BorderWidth, -BorderHeight)

                #Reverse in case of Climb
                if CutDirection == "Climb":
                    xB = xB[::-1]
                    yB = yB[::-1]

        #---------------------------------------------------------------------
        #Offset approach
        if PocketType == "Offset":
            #Calc number of pass
            VerticalCount = (int)(HToWork / StepOverInUnitMax)
            HorrizontalCount = (int)(WToWork / StepOverInUnitMax)
            #Make them odd
            if VerticalCount % 2 == 0: VerticalCount += 1
            if HorrizontalCount % 2 == 0: HorrizontalCount += 1
            #Calc step minor of Max step
            StepOverInUnitH = HToWork / (VerticalCount)
            StepOverInUnitW = WToWork / (HorrizontalCount)

            #Start from border to center
            xS = PocketXStart
            yS = PocketYStart
            wS = WToWork
            hS = HToWork
            xC = 0
            yC = 0
            while (xC <= HorrizontalCount / 2 and yC <= VerticalCount / 2):
                #Pocket offset points
                xO, yO = self.RectPath(xS, yS, wS, hS)
                if CutDirection == "Conventional":
                    xO = xO[::-1]
                    yO = yO[::-1]

                xP = xP + xO
                yP = yP + yO
                xS += StepOverInUnitH
                yS += StepOverInUnitW
                hS -= 2.0 * StepOverInUnitH
                wS -= 2.0 * StepOverInUnitW
                xC += 1
                yC += 1

            #Reverse point to start from inside (less stress on the tool)
            xP = xP[::-1]
            yP = yP[::-1]

        #Blocks for pocketing
        block = Block(self.name)
        block.append("(Flatten from X=%g Y=%g)" % (XStart, YStart))
        block.append("(W=%g x H=%g x D=%g)" %
                     (FlatWidth, FlatHeight, FlatDepth))
        block.append("(Approach: %s %s)" % (PocketType, CutDirection))
        if BorderPass: block.append("(with border)")

        #Move safe to first point
        block.append(CNC.zsafe())
        block.append(CNC.grapid(xP[0], yP[0]))
        #Init Depth
        currDepth = 0.
        stepz = CNC.vars['stepz']
        if stepz == 0: stepz = 0.001  #avoid infinite while loop

        #Create GCode from points
        while True:
            currDepth -= stepz
            if currDepth < FlatDepth: currDepth = FlatDepth
            block.append(CNC.zenter(currDepth))
            block.append(CNC.gcode(1, [("f", CNC.vars["cutfeed"])]))

            #Pocketing
            lastxy = None
            for x, y in zip(xP, yP):
                #				block.append(CNC.gline(x,y))
                if lastxy != CNC.gline(x, y) or None:
                    block.append(CNC.gline(x, y))
                lastxy = CNC.gline(x, y)

            #Border cut if request
            for x, y in zip(xB, yB):
                block.append(CNC.gline(x, y))

            #Verify exit condition
            if currDepth <= FlatDepth: break

            #Move to the begin in a safe way
            block.append(CNC.zsafe())
            block.append(CNC.grapid(xP[0], yP[0]))

        #Zsafe
        block.append(CNC.zsafe())
        blocks.append(block)
        return blocks
Esempio n. 51
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))))
Esempio n. 52
0
	def accelerateIfNeeded(self,ztogo,drillfeed):
		if self.safeZforG0>0:
			self.block.append(CNC.grapid(z=ztogo+self.safeZforG0))
			kwargs={"f":float(drillfeed)}
			self.block.append(CNC.gline(None,None,ztogo,**kwargs))