Last active
August 29, 2015 14:02
-
-
Save VonMoustachen/819ac9e70ba0f6138399 to your computer and use it in GitHub Desktop.
FreeCAD Pseudo Milling Simulator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Pseudo Milling Simulator | |
Javier Martinez Garcia June 2014 | |
Copy and paste at FreeCAD's python terminal | |
Start with: | |
timer.start(1) | |
""" | |
from FreeCAD import Gui | |
from PyQt4 import QtCore | |
from FreeCAD import Draft, Base | |
import Part | |
import math as mt | |
# Basic definitions | |
raw_size=(30,30,10) | |
Tool_radius = 0.5 | |
Tool_heigh = 8.0 | |
feed_rate = 10.0 | |
# Path Generator # | |
Program=[(-5,0,30)] # Start position | |
""" | |
The function "pocket" creates a square pocket | |
starting at V0(x,y,z), with side L and absolute deepness H | |
""" | |
def pocket(V0,L,H): | |
global Program, Tool_radius | |
YCycles = int(mt.floor((L / (2*Tool_radius))/2)) | |
V0 = (V0[0] + Tool_radius, V0[1] + Tool_radius, Program[0][2]) | |
Program.append(V0) | |
V0 = (V0[0], V0[1], H) | |
Program.append(V0) | |
for i in range(YCycles): | |
V0 = (V0[0]+(L-2*Tool_radius), V0[1], H) | |
Program.append(V0) | |
V0 = (V0[0],(2*Tool_radius)+V0[1], H) | |
Program.append(V0) | |
V0 = (V0[0]-(L-2*Tool_radius),V0[1], H) | |
Program.append(V0) | |
V0 = (V0[0],2*Tool_radius+V0[1], H) | |
Program.append(V0) | |
V0 = (V0[0]+(L-2*Tool_radius), V0[1], H) | |
Program.append(V0) | |
V0 = (V0[0], V0[1], Program[0][2]) | |
Program.append(V0) | |
# Create several pockets | |
pocket((2,2,15),25,8) | |
pocket((4,4,10),20,6) | |
pocket((8,8,10),10,3) | |
pocket((8,20,5),5,3) | |
pocket((15,20,5),5,3) | |
pocket((21,20,5),3,3) | |
pocket((10,10,5),5,2) | |
# Return to start position | |
Program.append(Program[0]) | |
####### | |
##Internal Variables | |
ToolR = App.Rotation(App.Vector(0,0,1),0) | |
####### | |
""" | |
Create trajectory wire | |
This while loop takes the list of points "Program" and | |
creates a wire across them | |
""" | |
Wire_done = False # wire end condition | |
i=0 | |
while Wire_done == False: | |
i+=1 | |
if i == len(Program): | |
Wire_done = True | |
break | |
if i == 1: # Starts the wire by creating the first line | |
Line0 = Part.makeLine(Program[i-1], Program[i]) | |
Wire0 = Part.Wire([Line0]) | |
else: #Creates the rest of the wire | |
Line1 = Part.makeLine(Program[i-1],Program[i]) | |
Trajectory_Wire = Part.Wire([Wire0,Line1]) | |
Wire0 = Trajectory_Wire | |
TjWire = App.ActiveDocument.addObject("Part::Feature", "Trajectory") # Creates "Trajectory" object in the tree-view | |
TjWire.Shape = Trajectory_Wire # | |
TjWire_UserName = TjWire.Label | |
FreeCADGui.ActiveDocument.getObject(TjWire_UserName).LineColor = (1.00,0.67,0.00) | |
### Create workpiece | |
Raw = Part.makeBox(raw_size[0],raw_size[1],raw_size[2]) | |
Raw_shape = App.ActiveDocument.addObject("Part::Feature", "Workpiece") | |
Raw_shape.Shape = Raw | |
Gui.ActiveDocument.getObject("Workpiece").Visibility=False | |
### Create Real Tool | |
Tool = Part.makeBox(Tool_radius*2, Tool_radius*2, Tool_heigh) | |
Tool_shape = App.ActiveDocument.addObject("Part::Feature", "Tool") | |
Tool_shape.Shape = Tool | |
Tool_shape_gui = Tool_shape.Label | |
FreeCADGui.ActiveDocument.getObject(Tool_shape_gui).ShapeColor = (0.33,0.33,1.00) | |
Tool_shape.Placement = App.Placement(App.Vector(Program[0]),ToolR ) | |
Gui.ActiveDocument.getObject("Tool").Visibility=False | |
## Create animated realistic tool. | |
AnimatedTool_shape= Part.makeCylinder(Tool_radius,Tool_heigh) | |
RTTH = Part.makeBox(Tool_radius/3.0, Tool_radius*2, Tool_heigh*1.1) | |
for i in range(5): | |
alpha = i*360/5 | |
RTTH = Part.makeBox(Tool_radius/3.0, Tool_radius*2, Tool_heigh*1.1) | |
RTTH.translate(Base.Vector((2*Tool_radius*mt.cos(mt.radians(i))/3.0,2*Tool_radius*mt.sin(mt.radians(i))/3.0,0))) | |
RTTH.rotate(Base.Vector(0,0,0),Base.Vector(0,0,1), 15 + alpha) | |
AnimatedTool_shape = AnimatedTool_shape.cut(RTTH) | |
AnimatedTool= App.ActiveDocument.addObject("Part::Feature","AnimatedTool") | |
AnimatedTool.Shape = AnimatedTool_shape | |
AnimatedTool_gui = AnimatedTool.Label | |
FreeCADGui.ActiveDocument.getObject(AnimatedTool_gui).ShapeColor = (0.33,0.33,1.00) | |
AnimatedTool.Placement = App.Placement(App.Vector(Program[0]), App.Rotation(App.Vector(0,0,1),0)) | |
""" | |
Machining Function | |
This is the core of the thing. | |
Workflow is: | |
-read the Program point i | |
-create a vector (VT, VD (VT normalized)) from i-1 to i | |
-place tool at point i | |
-cut the workpiece | |
-advance n in direction VD | |
-if the current position is greater than start point + VT, read next point | |
Very dirty and brutal, I know :) | |
""" | |
L1 = Raw.cut(Tool_shape.Shape) | |
Part.show(L1) | |
i=0 | |
n=0.0 | |
swd = 3 # boolean cut refreshing interval | |
s=0 | |
def Machining(): | |
global n, i,feed_rate, L1, Tool_radius, swd, s | |
if i <= len(Program): | |
Current_position = Tool_shape.Placement.Base | |
Vector_trajectory = App.Vector(Program[i+1])-App.Vector(Program[i]) | |
Vector_direction = (App.Vector(Program[i+1])-App.Vector(Program[i])).normalize() | |
VT_modulus = Vector_trajectory.Length | |
VD_modulus = 1.0 | |
if VT_modulus > VD_modulus*n*feed_rate: | |
Next_position = App.Vector(Program[i])+Vector_direction.multiply(n*feed_rate)+App.Vector(-Tool_radius, -Tool_radius) | |
n+=0.1 | |
else: | |
Next_Position = App.Vector(Program[i+1]) | |
i+=1 | |
n=0.0 | |
s += 1 | |
if s >= swd: | |
App.ActiveDocument.removeObject("Shape") | |
L1 = L1.removeSplitter() | |
Part.show(L1) | |
s = 0 | |
Tool_shape.Placement = App.Placement(Next_position, ToolR) | |
AnimatedTool.Placement = App.Placement(Next_position+App.Vector(Tool_radius,Tool_radius,0), App.Rotation(App.Vector(0,0,1),n*43)) | |
L1 = L1.cut(Tool_shape.Shape) | |
timer = QtCore.QTimer() | |
timer.timeout.connect(Machining) | |
#timer.start(1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment