Cleanup. Make surface, drilling, and engrave work with preselect

This commit is contained in:
sliptonic 2016-05-16 10:24:14 -05:00 committed by Yorik van Havre
parent d3ba507847
commit 7436a5e397
5 changed files with 575 additions and 460 deletions

View File

@ -24,6 +24,7 @@
import FreeCAD
import Path
import Part
from PySide import QtCore, QtGui
from PathScripts import PathUtils
@ -99,14 +100,22 @@ class ObjectDrilling:
else:
s = loc[0].Shape
if s.ShapeType in ['Face', 'Wire', 'Edge']:
X = s.Edges[0].Curve.Center.x
Y = s.Edges[0].Curve.Center.y
Z = s.Edges[0].Curve.Center.z
elif s.ShapeType == 'Vertex':
X = s.Point.x
Y = s.Point.y
Z = s.Point.z
if s.ShapeType in ['Wire', 'Edge']:
X = s.Edges[0].Curve.Center.x
Y = s.Edges[0].Curve.Center.y
Z = s.Edges[0].Curve.Center.z
elif s.ShapeType in ['Vertex']:
X = s.Point.x
Y = s.Point.y
Z = s.Point.z
elif s.ShapeType in ['Face']:
#if abs(s.normalAt(0, 0).z) == 1: # horizontal face
X = s.CenterOfMass.x
Y = s.CenterOfMass.y
Z = s.CenterOfMass.z
locations.append(FreeCAD.Vector(X, Y, Z))
@ -137,6 +146,24 @@ class ObjectDrilling:
path = Path.Path(output)
obj.Path = path
def checkdrillable(self, obj, sub):
print "in checkdrillable"
drillable = False
if obj.ShapeType == 'Vertex':
drillable = True
elif obj.ShapeType == 'Solid':
if sub[0:4] == 'Face':
subobj = obj.getElement(sub)
drillable = isinstance(subobj.Edges[0].Curve, Part.Circle)
if str(subobj.Surface) == "<Cylinder object>":
drillable = True
if sub[0:4] == 'Edge':
o = obj.getElement(sub)
drillable = isinstance(o.Curve, Part.Circle)
return drillable
def addDrillableLocation(self, obj, ss, sub=""):
baselist = obj.Base
item = (ss, sub)
@ -159,13 +186,14 @@ class ObjectDrilling:
obj.ClearanceHeight = 10.0
obj.SafeHeight = 8.0
obj.RetractHeight = 6.0
if self.checkdrillable(ss.Shape,sub):
if item in baselist:
FreeCAD.Console.PrintWarning("Drillable location already in the list" + "\n")
else:
baselist.append(item)
obj.Base = baselist
self.execute(obj)
if item in baselist:
FreeCAD.Console.PrintWarning("Drillable location already in the list" + "\n")
else:
baselist.append(item)
obj.Base = baselist
self.execute(obj)
class _ViewProviderDrill:
@ -269,6 +297,19 @@ class TaskPanel:
self.obj.Proxy.execute(self.obj)
def setFields(self):
self.form.startDepth.setText(str(self.obj.StartDepth.Value))
self.form.finalDepth.setText(str(self.obj.FinalDepth.Value))
self.form.peckDepth.setText(str(self.obj.PeckDepth.Value))
self.form.safeHeight.setText(str(self.obj.SafeHeight.Value))
self.form.clearanceHeight.setText(str(self.obj.ClearanceHeight.Value))
self.form.retractHeight.setText(str(self.obj.RetractHeight.Value))
self.form.baseList.clear()
for i in self.obj.Base:
self.form.baseList.addItem(i[0].Name + "." + i[1])
def open(self):
self.s = SelObserver()
FreeCADGui.Selection.addObserver(self.s)
@ -287,10 +328,9 @@ class TaskPanel:
else:
self.obj.Proxy.addDrillableLocation(self.obj, s.Object)
self.setupUi() # defaults may have changed. Reload.
self.form.baseList.clear()
for i in self.obj.Base:
self.form.baseList.addItem(i[0].Name + "." + i[1])
self.setFields() # defaults may have changed. Reload.
# for i in self.obj.Base:
# self.form.baseList.addItem(i[0].Name + "." + i[1])
def deleteBase(self):
dlist = self.form.baseList.selectedItems()
@ -336,15 +376,6 @@ class TaskPanel:
return int(QtGui.QDialogButtonBox.Ok)
def setupUi(self):
self.form.startDepth.setText(str(self.obj.StartDepth.Value))
self.form.finalDepth.setText(str(self.obj.FinalDepth.Value))
self.form.peckDepth.setText(str(self.obj.PeckDepth.Value))
self.form.safeHeight.setText(str(self.obj.SafeHeight.Value))
self.form.clearanceHeight.setText(str(self.obj.ClearanceHeight.Value))
self.form.retractHeight.setText(str(self.obj.RetractHeight.Value))
for i in self.obj.Base:
self.form.baseList.addItem(i[0].Name + "." + i[1])
# Connect Signals and Slots
self.form.startDepth.editingFinished.connect(self.getFields)
@ -358,6 +389,11 @@ class TaskPanel:
self.form.baseList.itemSelectionChanged.connect(self.itemActivated)
sel = FreeCADGui.Selection.getSelectionEx()
if len(sel) != 0 and sel[0].HasSubObjects:
self.addBase()
self.setFields()
class SelObserver:
def __init__(self):

View File

@ -45,7 +45,7 @@ except AttributeError:
class ObjectPathEngrave:
def __init__(self,obj):
def __init__(self, obj):
obj.addProperty("App::PropertyLinkSubList", "Base", "Path", "The base geometry of this object")
obj.addProperty("App::PropertyBool", "Active", "Path", translate("Path", "Make False, to prevent operation from generating code"))
obj.addProperty("App::PropertyString", "Comment", "Path", translate("Path", "An optional comment for this profile"))
@ -166,16 +166,10 @@ class ObjectPathEngrave:
if len(baselist) == 0: # When adding the first base object, guess at heights
try:
bb = ss.Shape.BoundBox # parent boundbox
subobj = ss.Shape.getElement(sub)
fbb = subobj.BoundBox # feature boundbox
obj.StartDepth = bb.ZMax
obj.ClearanceHeight = bb.ZMax + 5.0
obj.SafeHeight = bb.ZMax + 3.0
if fbb.ZMax < bb.ZMax:
obj.FinalDepth = fbb.ZMax
else:
obj.FinalDepth = bb.ZMin
obj.FinalDepth = bb.ZMin
except:
obj.StartDepth = 5.0
obj.ClearanceHeight = 10.0
@ -278,6 +272,16 @@ class TaskPanel:
self.obj.Proxy.execute(self.obj)
def setFields(self):
self.form.startDepth.setText(str(self.obj.StartDepth.Value))
self.form.finalDepth.setText(str(self.obj.FinalDepth.Value))
self.form.safeHeight.setText(str(self.obj.SafeHeight.Value))
self.form.clearanceHeight.setText(str(self.obj.ClearanceHeight.Value))
self.form.baseList.clear()
for i in self.obj.Base:
self.form.baseList.addItem(i[0].Name)
def open(self):
self.s = SelObserver()
# install the function mode resident
@ -296,9 +300,7 @@ class TaskPanel:
return
self.obj.Proxy.addShapeString(self.obj, s.Object)
self.form.baseList.clear()
for i in self.obj.Base:
self.form.baseList.addItem(i[0].Name)
self.setFields()
def deleteBase(self):
dlist = self.form.baseList.selectedItems()
@ -332,13 +334,6 @@ class TaskPanel:
return int(QtGui.QDialogButtonBox.Ok)
def setupUi(self):
self.form.startDepth.setText(str(self.obj.StartDepth.Value))
self.form.finalDepth.setText(str(self.obj.FinalDepth.Value))
self.form.safeHeight.setText(str(self.obj.SafeHeight.Value))
self.form.clearanceHeight.setText(str(self.obj.ClearanceHeight.Value))
for i in self.obj.Base:
self.form.baseList.addItem(i[0].Name)
# Connect Signals and Slots
self.form.startDepth.editingFinished.connect(self.getFields)
@ -352,6 +347,12 @@ class TaskPanel:
self.form.baseList.itemSelectionChanged.connect(self.itemActivated)
sel = FreeCADGui.Selection.getSelectionEx()
if len(sel) != 0:
self.addBase()
self.setFields()
class SelObserver:
def __init__(self):

View File

@ -21,7 +21,7 @@
# * USA *
# * *
# ***************************************************************************
'''Path selection function select a face or faces, two edges, etc to get a dictionary with what was selected in order '''
'''Selection gates and observers to control selectability while building Path operations '''
import FreeCAD
import FreeCADGui
@ -72,7 +72,6 @@ class EGate:
class MESHGate:
def allow(self, doc, obj, sub):
print obj.TypeId[0:4] == 'Mesh'
return (obj.TypeId[0:4] == 'Mesh')
@ -91,19 +90,13 @@ class DRILLGate:
return False
if obj.ShapeType == 'Vertex':
drillable = True
elif obj.ShapeType == 'Edge':
if isinstance(obj.Curve, Part.Circle):
drillable = True
elif obj.ShapeType == 'Face':
if isinstance(obj.Edges[0].Curve, Part.Circle):
drillable = True
elif obj.ShapeType == 'Wire':
if isinstance(obj.Edges[0].Curve, Part.Circle):
drillable = True
elif obj.ShapeType == 'Solid':
if sub[0:4] == 'Face':
o = obj.getElement(sub)
drillable = isinstance(o.Edges[0].Curve, Part.Circle)
subobj = obj.getElement(sub)
drillable = isinstance(subobj.Edges[0].Curve, Part.Circle)
if str(subobj.Surface) == "<Cylinder object>":
drillable = True
if sub[0:4] == 'Edge':
o = obj.getElement(sub)
drillable = isinstance(o.Curve, Part.Circle)
@ -169,15 +162,6 @@ class POCKETGate:
if sub[0:4] == 'Face':
pocketable = True
# if sub[0:4] == 'Edge':
# pocketable = True
# elif obj.ShapeType == 'Wire':
# pocketable = True
# if sub[0:6] == 'Vertex':
# print "might be fun to try to derive the loop by hovering near a vertex"
return pocketable

View File

@ -1,40 +1,40 @@
# -*- coding: utf-8 -*-
#***************************************************************************
#* *
#* Copyright (c) 2016 sliptonic <shopinthewoods@gmail.com> *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#***************************************************************************
# ***************************************************************************
# * *
# * Copyright (c) 2016 sliptonic <shopinthewoods@gmail.com> *
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) *
# * as published by the Free Software Foundation; either version 2 of *
# * the License, or (at your option) any later version. *
# * for detail see the LICENCE text file. *
# * *
# * This program is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU Library General Public License for more details. *
# * *
# * You should have received a copy of the GNU Library General Public *
# * License along with this program; if not, write to the Free Software *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * *
# ***************************************************************************
import FreeCAD,Path
import FreeCAD
import Path
from PathScripts import PathUtils
if FreeCAD.GuiUp:
import FreeCADGui
from PySide import QtCore, QtGui
from DraftTools import translate
from pivy import coin
else:
def translate(ctxt,txt):
def translate(ctxt, txt):
return txt
__title__="Path Surface Operation"
__title__ = "Path Surface Operation"
__author__ = "sliptonic (Brad Collette)"
__url__ = "http://www.freecadweb.org"
@ -43,6 +43,7 @@ __url__ = "http://www.freecadweb.org"
# Qt tanslation handling
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def translate(context, text, disambig=None):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
@ -52,42 +53,53 @@ except AttributeError:
class ObjectSurface:
def __init__(self,obj):
obj.addProperty("App::PropertyLinkSubList","Base","Path",translate("Parent Object(s)","The base geometry of this toolpath"))
obj.addProperty("App::PropertyBool","Active","Path",translate("Active","Make False, to prevent operation from generating code"))
obj.addProperty("App::PropertyString","Comment","Path",translate("PathProject","An optional comment for this profile"))
def __init__(self, obj):
obj.addProperty("App::PropertyLinkSubList", "Base", "Path", translate(
"Parent Object(s)", "The base geometry of this toolpath"))
obj.addProperty("App::PropertyBool", "Active", "Path", translate(
"Active", "Make False, to prevent operation from generating code"))
obj.addProperty("App::PropertyString", "Comment", "Path", translate(
"PathProject", "An optional comment for this profile"))
obj.addProperty("App::PropertyEnumeration", "Algorithm", "Algorithm",translate("PathProject", "The library to use to generate the path"))
obj.addProperty("App::PropertyEnumeration", "Algorithm", "Algorithm", translate(
"PathProject", "The library to use to generate the path"))
obj.Algorithm = ['OCL Dropcutter', 'OCL Waterline']
#Tool Properties
obj.addProperty("App::PropertyIntegerConstraint","ToolNumber","Tool",translate("PathProfile","The tool number in use"))
# Tool Properties
obj.addProperty("App::PropertyIntegerConstraint", "ToolNumber",
"Tool", translate("PathProfile", "The tool number in use"))
obj.ToolNumber = (0, 0, 1000, 0)
obj.setEditorMode('ToolNumber',1) #make this read only
obj.setEditorMode('ToolNumber', 1) # make this read only
#Surface Properties
obj.addProperty("App::PropertyFloatConstraint", "SampleInterval", "Surface", translate("PathSurface","The Sample Interval. Small values cause long wait"))
obj.SampleInterval = (0,0,1,0)
# Surface Properties
obj.addProperty("App::PropertyFloatConstraint", "SampleInterval", "Surface", translate(
"PathSurface", "The Sample Interval. Small values cause long wait"))
obj.SampleInterval = (0, 0, 1, 0)
#Depth Properties
obj.addProperty("App::PropertyDistance", "ClearanceHeight", "Depth", translate("PathProject","The height needed to clear clamps and obstructions"))
obj.addProperty("App::PropertyDistance", "SafeHeight", "Depth", translate("PathProject","Rapid Safety Height between locations."))
obj.addProperty("App::PropertyFloatConstraint", "StepDown", "Depth", translate("PathProject","Incremental Step Down of Tool"))
# Depth Properties
obj.addProperty("App::PropertyDistance", "ClearanceHeight", "Depth", translate(
"PathProject", "The height needed to clear clamps and obstructions"))
obj.addProperty("App::PropertyDistance", "SafeHeight", "Depth", translate(
"PathProject", "Rapid Safety Height between locations."))
obj.addProperty("App::PropertyFloatConstraint", "StepDown", "Depth", translate(
"PathProject", "Incremental Step Down of Tool"))
obj.StepDown = (0.0, 0.01, 100.0, 0.5)
obj.addProperty("App::PropertyDistance", "StartDepth", "Depth", translate("PathProject","Starting Depth of Tool- first cut depth in Z"))
obj.addProperty("App::PropertyDistance", "FinalDepth", "Depth", translate("PathProject","Final Depth of Tool- lowest value in Z"))
obj.addProperty("App::PropertyDistance", "FinishDepth", "Depth", translate("PathProject","Maximum material removed on final pass."))
obj.addProperty("App::PropertyDistance", "StartDepth", "Depth", translate(
"PathProject", "Starting Depth of Tool- first cut depth in Z"))
obj.addProperty("App::PropertyDistance", "FinalDepth", "Depth", translate(
"PathProject", "Final Depth of Tool- lowest value in Z"))
obj.addProperty("App::PropertyDistance", "FinishDepth", "Depth", translate(
"PathProject", "Maximum material removed on final pass."))
obj.Proxy = self
def addsurfacebase(self, obj, ss, sub=""):
baselist = obj.Base
if len(baselist) == 0: #When adding the first base object, guess at heights
if len(baselist) == 0: # When adding the first base object, guess at heights
try:
bb = ss.Shape.BoundBox #parent boundbox
bb = ss.Shape.BoundBox # parent boundbox
subobj = ss.Shape.getElement(sub)
fbb = subobj.BoundBox #feature boundbox
fbb = subobj.BoundBox # feature boundbox
obj.StartDepth = bb.ZMax
obj.ClearanceHeight = bb.ZMax + 5.0
obj.SafeHeight = bb.ZMax + 3.0
@ -103,20 +115,20 @@ class ObjectSurface:
item = (ss, sub)
if item in baselist:
FreeCAD.Console.PrintWarning("this object already in the list"+ "\n")
FreeCAD.Console.PrintWarning(
"this object already in the list" + "\n")
else:
baselist.append (item)
baselist.append(item)
obj.Base = baselist
self.execute(obj)
def __getstate__(self):
return None
def __setstate__(self,state):
def __setstate__(self, state):
return None
def _waterline(self,obj, s, bb):
def _waterline(self, obj, s, bb):
import ocl
from PathScripts.PathUtils import depth_params, fmt
import time
@ -127,62 +139,71 @@ class ObjectSurface:
waterlinestring += "(waterline begin)"
for loop in loops:
p = loop[0]
loopstring = "(loop begin)" +"\n"
loopstring += "G0 Z" + str(obj.SafeHeight.Value) +"\n"
loopstring += "G0 X" + str(fmt(p.x)) + " Y" + str(fmt(p.y)) +"\n"
loopstring += "G1 Z" + str(fmt(p.z)) +"\n"
loopstring = "(loop begin)" + "\n"
loopstring += "G0 Z" + str(obj.SafeHeight.Value) + "\n"
loopstring += "G0 X" + \
str(fmt(p.x)) + " Y" + str(fmt(p.y)) + "\n"
loopstring += "G1 Z" + str(fmt(p.z)) + "\n"
for p in loop[1:]:
loopstring += "G1 X" + str(fmt(p.x)) + " Y" + str(fmt(p.y)) + " Z" + str(fmt(p.z)) +"\n"
loopstring += "G1 X" + \
str(fmt(p.x)) + " Y" + str(fmt(p.y)) + \
" Z" + str(fmt(p.z)) + "\n"
zheight = p.z
p = loop[0]
loopstring += "G1 X" + str(fmt(p.x)) + " Y" + str(fmt(p.y)) + " Z" + str(fmt(zheight)) +"\n"
loopstring += "(loop end)" +"\n"
print " loop ",nloop, " with ", len(loop), " points"
nloop = nloop+1
loopstring += "G1 X" + \
str(fmt(p.x)) + " Y" + str(fmt(p.y)) + \
" Z" + str(fmt(zheight)) + "\n"
loopstring += "(loop end)" + "\n"
print " loop ", nloop, " with ", len(loop), " points"
nloop = nloop + 1
waterlinestring += loopstring
waterlinestring += "(waterline end)" +"\n"
waterlinestring += "(waterline end)" + "\n"
return waterlinestring
depthparams = depth_params (obj.ClearanceHeight.Value, obj.SafeHeight.Value, obj.StartDepth.Value, obj.StepDown, obj.FinishDepth.Value, obj.FinalDepth.Value)
depthparams = depth_params(obj.ClearanceHeight.Value, obj.SafeHeight.Value,
obj.StartDepth.Value, obj.StepDown, obj.FinishDepth.Value, obj.FinalDepth.Value)
# stlfile = "../../stl/gnu_tux_mod.stl"
# surface = STLSurfaceSource(stlfile)
surface = s
t_before = time.time()
zheights= depthparams.get_depths()
zheights = depthparams.get_depths()
wl = ocl.Waterline()
#wl = ocl.AdaptiveWaterline() # this is slower, ca 60 seconds on i7 CPU
# wl = ocl.AdaptiveWaterline() # this is slower, ca 60 seconds on i7
# CPU
wl.setSTL(surface)
diam = 0.5
length= 10.0
cutter = ocl.BallCutter( diam , length ) # any ocl MillingCutter class should work here
length = 10.0
# any ocl MillingCutter class should work here
cutter = ocl.BallCutter(diam, length)
wl.setCutter(cutter)
wl.setSampling(obj.SampleInterval) # this should be smaller than the smallest details in the STL file
# AdaptiveWaterline() also has settings for minimum sampling interval (see c++ code)
all_loops=[]
# this should be smaller than the smallest details in the STL file
wl.setSampling(obj.SampleInterval)
# AdaptiveWaterline() also has settings for minimum sampling interval
# (see c++ code)
all_loops = []
for zh in zheights:
print "calculating Waterline at z= ", zh
wl.reset()
wl.setZ(zh) # height for this waterline
wl.setZ(zh) # height for this waterline
wl.run()
all_loops.append( wl.getLoops() )
all_loops.append(wl.getLoops())
t_after = time.time()
calctime = t_after-t_before
n=0
calctime = t_after - t_before
n = 0
output = ""
for loops in all_loops: # at each z-height, we may get many loops
print " %d/%d:" % (n,len(all_loops))
for loops in all_loops: # at each z-height, we may get many loops
print " %d/%d:" % (n, len(all_loops))
output += drawLoops(loops)
n=n+1
n = n + 1
print "(" + str(calctime) + ")"
return output
def _dropcutter(self,obj, s, bb):
def _dropcutter(self, obj, s, bb):
import ocl
import time
cutter = ocl.CylCutter(self.radius*2, 5)
cutter = ocl.CylCutter(self.radius * 2, 5)
pdc = ocl.PathDropCutter() # create a pdc
pdc.setSTL(s)
pdc.setCutter(cutter)
@ -190,72 +211,75 @@ class ObjectSurface:
pdc.setSampling(obj.SampleInterval)
# some parameters for this "zigzig" pattern
xmin=bb.XMin - cutter.getDiameter()
xmax=bb.XMax + cutter.getDiameter()
ymin=bb.YMin - cutter.getDiameter()
ymax=bb.YMax + cutter.getDiameter()
xmin = bb.XMin - cutter.getDiameter()
xmax = bb.XMax + cutter.getDiameter()
ymin = bb.YMin - cutter.getDiameter()
ymax = bb.YMax + cutter.getDiameter()
Ny=int(bb.YLength/cutter.getDiameter()) # number of lines in the y-direction
dy = float(ymax-ymin)/Ny # the y step-over
# number of lines in the y-direction
Ny = int(bb.YLength / cutter.getDiameter())
dy = float(ymax - ymin) / Ny # the y step-over
path = ocl.Path() # create an empty path object
# add Line objects to the path in this loop
for n in xrange(0,Ny):
y = ymin+n*dy
p1 = ocl.Point(xmin,y,0) # start-point of line
p2 = ocl.Point(xmax,y,0) # end-point of line
if (n % 2 == 0): #even
l = ocl.Line(p1,p2) # line-object
else: #odd
l = ocl.Line(p2,p1) # line-object
for n in xrange(0, Ny):
y = ymin + n * dy
p1 = ocl.Point(xmin, y, 0) # start-point of line
p2 = ocl.Point(xmax, y, 0) # end-point of line
if (n % 2 == 0): # even
l = ocl.Line(p1, p2) # line-object
else: # odd
l = ocl.Line(p2, p1) # line-object
path.append( l ) # add the line to the path
path.append(l) # add the line to the path
pdc.setPath( path )
pdc.setPath(path)
# run drop-cutter on the path
t_before = time.time()
pdc.run()
t_after = time.time()
print "calculation took ", t_after-t_before," s"
print "calculation took ", t_after - t_before, " s"
#retrieve the points
# retrieve the points
clp = pdc.getCLPoints()
print "points received: " + str(len(clp))
#generate the path commands
# generate the path commands
output = ""
output += "G0 Z" + str(obj.ClearanceHeight.Value) + "\n"
output += "G0 X" + str(clp[0].x) +" Y" + str(clp[0].y) + "\n"
output += "G0 X" + str(clp[0].x) + " Y" + str(clp[0].y) + "\n"
output += "G1 Z" + str(clp[0].z) + " F" + str(self.vertFeed) + "\n"
for c in clp:
output += "G1 X" + str(c.x) +" Y" + str(c.y) +" Z" + str(c.z)+ "\n"
output += "G1 X" + str(c.x) + " Y" + \
str(c.y) + " Z" + str(c.z) + "\n"
return output
def execute(self,obj):
def execute(self, obj):
import MeshPart
FreeCAD.Console.PrintWarning(translate("PathSurface","Hold on. This might take a minute.\n"))
FreeCAD.Console.PrintWarning(
translate("PathSurface", "Hold on. This might take a minute.\n"))
output = ""
toolLoad = PathUtils.getLastToolLoad(obj)
if toolLoad == None or toolLoad.ToolNumber == 0:
if toolLoad is None or toolLoad.ToolNumber == 0:
self.vertFeed = 100
self.horizFeed = 100
self.radius = 0.25
obj.ToolNumber= 0
obj.ToolNumber = 0
else:
self.vertFeed = toolLoad.VertFeed.Value
self.horizFeed = toolLoad.HorizFeed.Value
obj.ToolNumber= toolLoad.ToolNumber
obj.ToolNumber = toolLoad.ToolNumber
tool = PathUtils.getTool(obj, toolLoad.ToolNumber)
if tool == None:
if tool is None:
self.radius = 0.25
else:
self.radius = tool.Diameter/2
self.radius = tool.Diameter / 2
if obj.Base:
for b in obj.Base:
@ -264,7 +288,8 @@ class ObjectSurface:
try:
import ocl
except:
FreeCAD.Console.PrintError(translate("PathSurface","This operation requires OpenCamLib to be installed.\n"))
FreeCAD.Console.PrintError(translate(
"PathSurface", "This operation requires OpenCamLib to be installed.\n"))
return
mesh = b[0]
@ -273,12 +298,15 @@ class ObjectSurface:
bb = mesh.BoundBox
else:
bb = mesh.Shape.BoundBox
mesh = MeshPart.meshFromShape(mesh.Shape,MaxLength=2)
mesh = MeshPart.meshFromShape(mesh.Shape, MaxLength=2)
s= ocl.STLSurf()
s = ocl.STLSurf()
for f in mesh.Facets:
p = f.Points[0];q=f.Points[1];r=f.Points[2]
t= ocl.Triangle(ocl.Point(p[0],p[1],p[2]),ocl.Point(q[0],q[1],q[2]),ocl.Point(r[0],r[1],r[2]))
p = f.Points[0]
q = f.Points[1]
r = f.Points[2]
t = ocl.Triangle(ocl.Point(p[0], p[1], p[2]), ocl.Point(
q[0], q[1], q[2]), ocl.Point(r[0], r[1], r[2]))
s.addTriangle(t)
if obj.Algorithm == 'OCL Dropcutter':
@ -290,30 +318,30 @@ class ObjectSurface:
obj.Path = path
class ViewProviderSurface:
def __init__(self,obj): #mandatory
# obj.addProperty("App::PropertyFloat","SomePropertyName","PropertyGroup","Description of this property")
def __init__(self, obj): # mandatory
# obj.addProperty("App::PropertyFloat","SomePropertyName","PropertyGroup","Description of this property")
obj.Proxy = self
def __getstate__(self): #mandatory
def __getstate__(self): # mandatory
return None
def __setstate__(self,state): #mandatory
def __setstate__(self, state): # mandatory
return None
def getIcon(self): #optional
def getIcon(self): # optional
return ":/icons/Path-Surfacing.svg"
def onChanged(self,obj,prop): #optional
def onChanged(self, obj, prop): # optional
# this is executed when a property of the VIEW PROVIDER changes
pass
def updateData(self,obj,prop): #optional
def updateData(self, obj, prop): # optional
# this is executed when a property of the APP OBJECT changes
pass
def setEdit(self,vobj,mode=0):
def setEdit(self, vobj, mode=0):
FreeCADGui.Control.closeDialog()
taskd = TaskPanel()
taskd.obj = vobj.Object
@ -321,76 +349,41 @@ class ViewProviderSurface:
taskd.setupUi()
return True
def unsetEdit(self,vobj,mode): #optional
def unsetEdit(self, vobj, mode): # optional
# this is executed when the user cancels or terminates edit mode
pass
class CommandPathSurfacing:
def GetResources(self):
return {'Pixmap' : 'Path-Surfacing',
'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Surface","Surfacing"),
return {'Pixmap': 'Path-3DSurface',
'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Surface", "Surfacing"),
'Accel': "P, D",
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Surface","Creates a Path Surfacing object")}
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Surface", "Creates a Path Surfacing object")}
def IsActive(self):
return not FreeCAD.ActiveDocument is None
return FreeCAD.ActiveDocument is not None
def Activated(self):
# check that the selection contains exactly what we want
# selection = FreeCADGui.Selection.getSelectionEx()
# if len(selection) != 1:
# FreeCAD.Console.PrintError(translate("PathSurface","Please select a single solid object from the project tree\n"))
# return
# if not len(selection[0].SubObjects) == 0:
# FreeCAD.Console.PrintError(translate("PathSurface","Please select a single solid object from the project tree\n"))
# return
# for s in selection[0].SubObjects:
# if s.ShapeType != "Edge":
# if (s.ShapeType != "Face") or (len(selection[0].SubObjects) != 1):
# FreeCAD.Console.PrintError(translate("PathSurface","Please select only edges or a single face\n"))
# return
# sel = selection[0].Object
# #get type of object
# if sel.TypeId.startswith('Mesh'):
# #it is a mesh already
# print 'was already mesh'
# ztop = sel.Mesh.BoundBox.ZMax
# zbottom = sel.Mesh.BoundBox.ZMin
# #mesh = sel
# elif sel.TypeId.startswith('Part') and \
# (sel.Shape.BoundBox.XLength > 0) and \
# (sel.Shape.BoundBox.YLength > 0) and \
# (sel.Shape.BoundBox.ZLength > 0):
# ztop = sel.Shape.BoundBox.ZMax
# zbottom = sel.Shape.BoundBox.ZMin
# print 'this is a solid Part object'
# else:
# FreeCAD.Console.PrintError(translate("PathSurface","Cannot work with this object\n"))
# return
# if everything is ok, execute and register the transaction in the undo/redo stack
ztop = 10
zbottom = 0
FreeCAD.ActiveDocument.openTransaction(translate("Path_Surfacing","Create Surface"))
FreeCAD.ActiveDocument.openTransaction(
translate("Path_Surfacing", "Create Surface"))
FreeCADGui.addModule("PathScripts.PathSurface")
FreeCADGui.doCommand('obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython","Surface")')
FreeCADGui.doCommand(
'obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython","Surface")')
FreeCADGui.doCommand('PathScripts.PathSurface.ObjectSurface(obj)')
FreeCADGui.doCommand('obj.Active = True')
FreeCADGui.doCommand('PathScripts.PathSurface.ViewProviderSurface(obj.ViewObject)')
FreeCADGui.doCommand(
'PathScripts.PathSurface.ViewProviderSurface(obj.ViewObject)')
FreeCADGui.doCommand('from PathScripts import PathUtils')
FreeCADGui.doCommand('obj.ClearanceHeight = ' + str(ztop + 2))
FreeCADGui.doCommand('obj.StartDepth = ' + str(ztop))
FreeCADGui.doCommand('obj.SafeHeight = ' + str(ztop + 2))
FreeCADGui.doCommand('obj.StepDown = ' + str((ztop-zbottom)/8))
FreeCADGui.doCommand('obj.StepDown = ' + str((ztop - zbottom) / 8))
FreeCADGui.doCommand('obj.SampleInterval = 0.4')
FreeCADGui.doCommand('obj.FinalDepth=' + str(zbottom))
@ -402,9 +395,12 @@ class CommandPathSurfacing:
class TaskPanel:
def __init__(self):
#self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/SurfaceEdit.ui")
# self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/SurfaceEdit.ui")
self.form = FreeCADGui.PySideUic.loadUi(":/panels/SurfaceEdit.ui")
FreeCAD.Console.PrintWarning("Surface calculations can be slow. Don't Panic.\n")
def accept(self):
self.getFields()
@ -421,57 +417,69 @@ class TaskPanel:
def getFields(self):
if self.obj:
if hasattr(self.obj,"StartDepth"):
if hasattr(self.obj, "StartDepth"):
self.obj.StartDepth = self.form.startDepth.text()
if hasattr(self.obj,"FinalDepth"):
if hasattr(self.obj, "FinalDepth"):
self.obj.FinalDepth = self.form.finalDepth.text()
if hasattr(self.obj,"SafeHeight"):
if hasattr(self.obj, "SafeHeight"):
self.obj.SafeHeight = self.form.safeHeight.text()
if hasattr(self.obj,"ClearanceHeight"):
if hasattr(self.obj, "ClearanceHeight"):
self.obj.ClearanceHeight = self.form.clearanceHeight.text()
if hasattr(self.obj,"StepDown"):
if hasattr(self.obj, "StepDown"):
self.obj.StepDown = self.form.stepDown.value()
if hasattr(self.obj,"Algorithm"):
self.obj.Algorithm = str(self.form.algorithmSelect.currentText())
if hasattr(self.obj, "Algorithm"):
self.obj.Algorithm = str(
self.form.algorithmSelect.currentText())
self.obj.Proxy.execute(self.obj)
def setFields(self):
self.form.startDepth.setText(str(self.obj.StartDepth.Value))
self.form.finalDepth.setText(str(self.obj.FinalDepth.Value))
self.form.safeHeight.setText(str(self.obj.SafeHeight.Value))
self.form.clearanceHeight.setText(str(self.obj.ClearanceHeight.Value))
for i in self.obj.Base:
self.form.baseList.addItem(i[0].Name)
def open(self):
self.s =SelObserver()
self.s = SelObserver()
# install the function mode resident
FreeCADGui.Selection.addObserver(self.s)
def addBase(self):
#check that the selection contains exactly what we want
# check that the selection contains exactly what we want
selection = FreeCADGui.Selection.getSelectionEx()
if len(selection) != 1:
FreeCAD.Console.PrintError(translate("PathSurface","Please select a single solid object from the project tree\n"))
FreeCAD.Console.PrintError(translate(
"PathSurface", "Please select a single solid object from the project tree\n"))
return
if not len(selection[0].SubObjects) == 0:
FreeCAD.Console.PrintError(translate("PathSurface","Please select a single solid object from the project tree\n"))
FreeCAD.Console.PrintError(translate(
"PathSurface", "Please select a single solid object from the project tree\n"))
return
sel = selection[0].Object
#get type of object
# get type of object
if sel.TypeId.startswith('Mesh'):
#it is a mesh already
# it is a mesh already
print 'was already mesh'
#mesh = sel
elif sel.TypeId.startswith('Part') and \
(sel.Shape.BoundBox.XLength > 0) and \
(sel.Shape.BoundBox.YLength > 0) and \
(sel.Shape.BoundBox.ZLength > 0):
(sel.Shape.BoundBox.XLength > 0) and \
(sel.Shape.BoundBox.YLength > 0) and \
(sel.Shape.BoundBox.ZLength > 0):
print 'this is a solid Part object'
else:
FreeCAD.Console.PrintError(translate("PathSurface","Cannot work with this object\n"))
FreeCAD.Console.PrintError(
translate("PathSurface", "Cannot work with this object\n"))
return
self.obj.Proxy.addsurfacebase(self.obj, sel)
self.setupUi() #defaults may have changed. Reload.
self.setFields() # defaults may have changed. Reload.
self.form.baseList.clear()
for i in self.obj.Base:
self.form.baseList.addItem(i[0].Name)
@ -482,7 +490,7 @@ class TaskPanel:
newlist = []
for i in self.obj.Base:
if not i[0].Name == d.text():
newlist.append (i)
newlist.append(i)
self.obj.Base = newlist
self.form.baseList.takeItem(self.form.baseList.row(d))
self.obj.Proxy.execute(self.obj)
@ -499,10 +507,10 @@ class TaskPanel:
def reorderBase(self):
newlist = []
for i in range(self.form.baseList.count()):
s = self.form.baseList.item(i).text()
s = self.form.baseList.item(i).text()
obj = FreeCAD.ActiveDocument.getObject(s)
newlist.append(obj)
self.obj.Base=newlist
self.obj.Base = newlist
self.obj.Proxy.execute(self.obj)
FreeCAD.ActiveDocument.recompute()
@ -510,15 +518,8 @@ class TaskPanel:
return int(QtGui.QDialogButtonBox.Ok)
def setupUi(self):
self.form.startDepth.setText(str(self.obj.StartDepth.Value))
self.form.finalDepth.setText(str(self.obj.FinalDepth.Value))
self.form.safeHeight.setText(str(self.obj.SafeHeight.Value))
self.form.clearanceHeight.setText(str(self.obj.ClearanceHeight.Value))
for i in self.obj.Base:
self.form.baseList.addItem(i[0].Name)
#Connect Signals and Slots
# Connect Signals and Slots
self.form.startDepth.editingFinished.connect(self.getFields)
self.form.finalDepth.editingFinished.connect(self.getFields)
self.form.safeHeight.editingFinished.connect(self.getFields)
@ -530,7 +531,15 @@ class TaskPanel:
self.form.baseList.itemSelectionChanged.connect(self.itemActivated)
sel = FreeCADGui.Selection.getSelectionEx()
self.setFields()
if len(sel) != 0:
self.addBase()
class SelObserver:
def __init__(self):
import PathScripts.PathSelection as PST
PST.surfaceselect()
@ -539,13 +548,14 @@ class SelObserver:
import PathScripts.PathSelection as PST
PST.clear()
def addSelection(self,doc,obj,sub,pnt): # Selection object
FreeCADGui.doCommand('Gui.Selection.addSelection(FreeCAD.ActiveDocument.' + obj +')')
def addSelection(self, doc, obj, sub, pnt): # Selection object
FreeCADGui.doCommand(
'Gui.Selection.addSelection(FreeCAD.ActiveDocument.' + obj + ')')
FreeCADGui.updateGui()
if FreeCAD.GuiUp:
# register the FreeCAD command
FreeCADGui.addCommand('Path_Surfacing',CommandPathSurfacing())
FreeCADGui.addCommand('Path_Surfacing', CommandPathSurfacing())
FreeCAD.Console.PrintLog("Loading PathSurfacing... done\n")

View File

@ -1,29 +1,32 @@
# -*- coding: utf-8 -*-
#***************************************************************************
#* *
#* Copyright (c) 2014 Yorik van Havre <yorik@uncreated.net> *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#***************************************************************************
# ***************************************************************************
# * *
# * Copyright (c) 2014 Yorik van Havre <yorik@uncreated.net> *
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) *
# * as published by the Free Software Foundation; either version 2 of *
# * the License, or (at your option) any later version. *
# * for detail see the LICENCE text file. *
# * *
# * This program is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU Library General Public License for more details. *
# * *
# * You should have received a copy of the GNU Library General Public *
# * License along with this program; if not, write to the Free Software *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * *
# ***************************************************************************
import FreeCAD,Path, xml.sax, os
import FreeCAD
import Path
import xml.sax
import os
from PySide import QtCore, QtGui
import DraftGui
@ -37,6 +40,7 @@ except AttributeError:
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
@ -47,8 +51,9 @@ except AttributeError:
# Tooltable XML readers
class FreeCADTooltableHandler( xml.sax.ContentHandler ):
class FreeCADTooltableHandler(xml.sax.ContentHandler):
# http://www.tutorialspoint.com/python/python_xml_processing.htm
def __init__(self):
self.tooltable = None
self.tool = None
@ -58,14 +63,14 @@ class FreeCADTooltableHandler( xml.sax.ContentHandler ):
def startElement(self, tag, attributes):
if tag == "Tooltable":
self.tooltable = Path.Tooltable()
elif tag == "Toolslot":
elif tag == "Toolslot":
self.number = int(attributes["number"])
elif tag == "Tool":
self.tool = Path.Tool()
self.tool.Name = str(attributes["name"])
self.tool.ToolType = str(attributes["type"])
self.tool.Material = str(attributes["mat"])
# for some reason without the following line I get an error
# for some reason without the following line I get an error
print attributes["diameter"]
self.tool.Diameter = float(attributes["diameter"])
self.tool.LengthOffset = float(attributes["length"])
@ -73,17 +78,18 @@ class FreeCADTooltableHandler( xml.sax.ContentHandler ):
self.tool.CornerRadius = float(attributes["corner"])
self.tool.CuttingEdgeAngle = float(attributes["angle"])
self.tool.CuttingEdgeHeight = float(attributes["height"])
# Call when an elements ends
def endElement(self, tag):
if tag == "Toolslot":
if self.tooltable and self.tool and self.number:
self.tooltable.setTool(self.number,self.tool)
self.tooltable.setTool(self.number, self.tool)
self.number = None
self.tool = None
class HeeksTooltableHandler( xml.sax.ContentHandler ):
class HeeksTooltableHandler(xml.sax.ContentHandler):
def __init__(self):
self.tooltable = Path.Tooltable()
self.tool = None
@ -91,8 +97,8 @@ class HeeksTooltableHandler( xml.sax.ContentHandler ):
# Call when an element is found
def startElement(self, tag, attributes):
if tag == "Tool":
self.tool = Path.Tool()
if tag == "Tool":
self.tool = Path.Tool()
self.number = int(attributes["tool_number"])
self.tool.Name = str(attributes["title"])
elif tag == "params":
@ -116,31 +122,33 @@ class HeeksTooltableHandler( xml.sax.ContentHandler ):
self.tool.Material = "HighSpeedSteel"
elif m == "1":
self.tool.Material = "Carbide"
# for some reason without the following line I get an error
# for some reason without the following line I get an error
print attributes["diameter"]
self.tool.Diameter = float(attributes["diameter"])
self.tool.LengthOffset = float(attributes["tool_length_offset"])
self.tool.FlatRadius = float(attributes["flat_radius"])
self.tool.CornerRadius = float(attributes["corner_radius"])
self.tool.CuttingEdgeAngle = float(attributes["cutting_edge_angle"])
self.tool.CuttingEdgeHeight = float(attributes["cutting_edge_height"])
self.tool.CuttingEdgeAngle = float(
attributes["cutting_edge_angle"])
self.tool.CuttingEdgeHeight = float(
attributes["cutting_edge_height"])
# Call when an elements ends
def endElement(self, tag):
if tag == "Tool":
if self.tooltable and self.tool and self.number:
self.tooltable.setTool(self.number,self.tool)
self.tooltable.setTool(self.number, self.tool)
self.number = None
self.tool = None
# Tooltable Editor
class Editor(QtGui.QDialog):
def __init__(self,obj):
def __init__(self, obj):
QtGui.QDialog.__init__(self)
self.setObjectName(_fromUtf8("TooltableEditor"))
self.resize(468, 476)
@ -148,42 +156,45 @@ class Editor(QtGui.QDialog):
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
self.DECIMALS = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Units").GetInt("Decimals",2)
self.FORMAT = DraftGui.makeFormatSpec(self.DECIMALS,'Length')
self.DECIMALS = FreeCAD.ParamGet(
"User parameter:BaseApp/Preferences/Units").GetInt("Decimals", 2)
self.FORMAT = DraftGui.makeFormatSpec(self.DECIMALS, 'Length')
# left groupbox
self.groupBox = QtGui.QGroupBox(self)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum)
sizePolicy = QtGui.QSizePolicy(
QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.groupBox.sizePolicy().hasHeightForWidth())
sizePolicy.setHeightForWidth(
self.groupBox.sizePolicy().hasHeightForWidth())
self.groupBox.setSizePolicy(sizePolicy)
self.groupBox.setObjectName(_fromUtf8("groupBox"))
self.verticalLayout_2 = QtGui.QVBoxLayout(self.groupBox)
self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
self.horizontalLayout_9 = QtGui.QHBoxLayout()
self.horizontalLayout_9.setObjectName(_fromUtf8("horizontalLayout_9"))
# import button
self.ButtonImport = QtGui.QPushButton(self.groupBox)
icon = QtGui.QIcon.fromTheme(_fromUtf8("document-import"))
self.ButtonImport.setIcon(icon)
self.ButtonImport.setObjectName(_fromUtf8("ButtonImport"))
self.horizontalLayout_9.addWidget(self.ButtonImport)
# export button
self.ButtonExport = QtGui.QPushButton(self.groupBox)
icon = QtGui.QIcon.fromTheme(_fromUtf8("document-export"))
self.ButtonExport.setIcon(icon)
self.ButtonExport.setObjectName(_fromUtf8("ButtonExport"))
self.horizontalLayout_9.addWidget(self.ButtonExport)
# tools list
self.verticalLayout_2.addLayout(self.horizontalLayout_9)
self.ToolsList = QtGui.QTreeWidget(self.groupBox)
self.ToolsList.setObjectName(_fromUtf8("ToolsList"))
self.ToolsList.header().setDefaultSectionSize(40)
self.verticalLayout_2.addWidget(self.ToolsList)
# add button
self.horizontalLayout_8 = QtGui.QHBoxLayout()
self.horizontalLayout_8.setObjectName(_fromUtf8("horizontalLayout_8"))
@ -192,7 +203,7 @@ class Editor(QtGui.QDialog):
self.ButtonAdd.setIcon(icon)
self.ButtonAdd.setObjectName(_fromUtf8("ButtonAdd"))
self.horizontalLayout_8.addWidget(self.ButtonAdd)
# delete button
self.ButtonDelete = QtGui.QPushButton(self.groupBox)
icon = QtGui.QIcon.fromTheme(_fromUtf8("edit-delete"))
@ -206,7 +217,7 @@ class Editor(QtGui.QDialog):
self.ButtonUp.setIcon(icon)
self.ButtonDelete.setObjectName(_fromUtf8("ButtonUp"))
self.horizontalLayout_8.addWidget(self.ButtonUp)
# down button
self.ButtonDown = QtGui.QPushButton(self.groupBox)
icon = QtGui.QIcon.fromTheme(_fromUtf8("go-down"))
@ -221,7 +232,7 @@ class Editor(QtGui.QDialog):
self.groupBox_2.setObjectName(_fromUtf8("groupBox_2"))
self.verticalLayout_3 = QtGui.QVBoxLayout(self.groupBox_2)
self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3"))
# name
self.label = QtGui.QLabel(self.groupBox_2)
self.label.setObjectName(_fromUtf8("label"))
@ -229,7 +240,7 @@ class Editor(QtGui.QDialog):
self.NameField = QtGui.QLineEdit(self.groupBox_2)
self.NameField.setObjectName(_fromUtf8("NameField"))
self.verticalLayout_3.addWidget(self.NameField)
# type
self.label_2 = QtGui.QLabel(self.groupBox_2)
self.label_2.setObjectName(_fromUtf8("label_2"))
@ -250,7 +261,7 @@ class Editor(QtGui.QDialog):
self.TypeField.addItem(_fromUtf8(""))
self.TypeField.addItem(_fromUtf8(""))
self.verticalLayout_3.addWidget(self.TypeField)
# material
self.label_3 = QtGui.QLabel(self.groupBox_2)
self.label_3.setObjectName(_fromUtf8("label_3"))
@ -269,7 +280,7 @@ class Editor(QtGui.QDialog):
self.label_4 = QtGui.QLabel(self.groupBox_2)
self.label_4.setObjectName(_fromUtf8("label_4"))
self.verticalLayout_3.addWidget(self.label_4)
# diameter
self.horizontalLayout_2 = QtGui.QHBoxLayout()
self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2"))
@ -278,11 +289,12 @@ class Editor(QtGui.QDialog):
self.horizontalLayout_2.addWidget(self.label_5)
self.DiameterField = QtGui.QDoubleSpinBox(self.groupBox_2)
self.DiameterField.setMaximum(9999)
self.DiameterField.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.DiameterField.setAlignment(
QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter)
self.DiameterField.setObjectName(_fromUtf8("DiameterField"))
self.horizontalLayout_2.addWidget(self.DiameterField)
self.verticalLayout_3.addLayout(self.horizontalLayout_2)
# length offset
self.horizontalLayout_3 = QtGui.QHBoxLayout()
self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3"))
@ -291,11 +303,12 @@ class Editor(QtGui.QDialog):
self.horizontalLayout_3.addWidget(self.label_6)
self.LengthOffsetField = QtGui.QDoubleSpinBox(self.groupBox_2)
self.LengthOffsetField.setMaximum(9999)
self.LengthOffsetField.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.LengthOffsetField.setAlignment(
QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter)
self.LengthOffsetField.setObjectName(_fromUtf8("LengthOffsetField"))
self.horizontalLayout_3.addWidget(self.LengthOffsetField)
self.verticalLayout_3.addLayout(self.horizontalLayout_3)
# flat radius
self.horizontalLayout_4 = QtGui.QHBoxLayout()
self.horizontalLayout_4.setObjectName(_fromUtf8("horizontalLayout_4"))
@ -304,11 +317,12 @@ class Editor(QtGui.QDialog):
self.horizontalLayout_4.addWidget(self.label_7)
self.FlatRadiusField = QtGui.QDoubleSpinBox(self.groupBox_2)
self.FlatRadiusField.setMaximum(9999)
self.FlatRadiusField.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.FlatRadiusField.setAlignment(
QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter)
self.FlatRadiusField.setObjectName(_fromUtf8("FlatRadiusField"))
self.horizontalLayout_4.addWidget(self.FlatRadiusField)
self.verticalLayout_3.addLayout(self.horizontalLayout_4)
# corner radius
self.horizontalLayout_5 = QtGui.QHBoxLayout()
self.horizontalLayout_5.setObjectName(_fromUtf8("horizontalLayout_5"))
@ -317,11 +331,12 @@ class Editor(QtGui.QDialog):
self.horizontalLayout_5.addWidget(self.label_8)
self.CornerRadiusField = QtGui.QDoubleSpinBox(self.groupBox_2)
self.CornerRadiusField.setMaximum(9999)
self.CornerRadiusField.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.CornerRadiusField.setAlignment(
QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter)
self.CornerRadiusField.setObjectName(_fromUtf8("CornerRadiusField"))
self.horizontalLayout_5.addWidget(self.CornerRadiusField)
self.verticalLayout_3.addLayout(self.horizontalLayout_5)
# cutting edge angle
self.horizontalLayout_6 = QtGui.QHBoxLayout()
self.horizontalLayout_6.setObjectName(_fromUtf8("horizontalLayout_6"))
@ -330,11 +345,13 @@ class Editor(QtGui.QDialog):
self.horizontalLayout_6.addWidget(self.label_9)
self.CuttingEdgeAngleField = QtGui.QDoubleSpinBox(self.groupBox_2)
self.CuttingEdgeAngleField.setMaximum(360)
self.CuttingEdgeAngleField.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.CuttingEdgeAngleField.setObjectName(_fromUtf8("CuttingEdgeAngleField"))
self.CuttingEdgeAngleField.setAlignment(
QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter)
self.CuttingEdgeAngleField.setObjectName(
_fromUtf8("CuttingEdgeAngleField"))
self.horizontalLayout_6.addWidget(self.CuttingEdgeAngleField)
self.verticalLayout_3.addLayout(self.horizontalLayout_6)
# cutting edge height
self.horizontalLayout_7 = QtGui.QHBoxLayout()
self.horizontalLayout_7.setObjectName(_fromUtf8("horizontalLayout_7"))
@ -343,41 +360,62 @@ class Editor(QtGui.QDialog):
self.horizontalLayout_7.addWidget(self.label_10)
self.CuttingEdgeHeightField = QtGui.QDoubleSpinBox(self.groupBox_2)
self.CuttingEdgeHeightField.setMaximum(9999)
self.CuttingEdgeHeightField.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.CuttingEdgeHeightField.setObjectName(_fromUtf8("CuttingEdgeHeightField"))
self.CuttingEdgeHeightField.setAlignment(
QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter)
self.CuttingEdgeHeightField.setObjectName(
_fromUtf8("CuttingEdgeHeightField"))
self.horizontalLayout_7.addWidget(self.CuttingEdgeHeightField)
self.verticalLayout_3.addLayout(self.horizontalLayout_7)
self.horizontalLayout.addWidget(self.groupBox_2)
self.verticalLayout.addLayout(self.horizontalLayout)
# ok / cancel box
self.buttonBox = QtGui.QDialogButtonBox(self)
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
self.buttonBox.setStandardButtons(
QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.Ok)
self.buttonBox.setObjectName(_fromUtf8("buttonBox"))
self.verticalLayout.addWidget(self.buttonBox)
self.retranslateUi()
# connect buttons
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), self.accept)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), self.reject)
QtCore.QObject.connect(self.ButtonImport, QtCore.SIGNAL(_fromUtf8("clicked()")), self.read)
QtCore.QObject.connect(self.ButtonExport, QtCore.SIGNAL(_fromUtf8("clicked()")), self.write)
QtCore.QObject.connect(self.ButtonAdd, QtCore.SIGNAL(_fromUtf8("clicked()")), self.addnew)
QtCore.QObject.connect(self.ButtonDelete, QtCore.SIGNAL(_fromUtf8("clicked()")), self.delete)
QtCore.QObject.connect(self.ButtonUp, QtCore.SIGNAL(_fromUtf8("clicked()")), self.moveup)
QtCore.QObject.connect(self.ButtonDown, QtCore.SIGNAL(_fromUtf8("clicked()")), self.movedown)
QtCore.QObject.connect(self.ToolsList, QtCore.SIGNAL(_fromUtf8("currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)")), self.selectTool)
QtCore.QObject.connect(self.NameField, QtCore.SIGNAL(_fromUtf8("textEdited(QString)")), self.changeName)
QtCore.QObject.connect(self.TypeField, QtCore.SIGNAL(_fromUtf8("currentIndexChanged(int)")), self.changeType)
QtCore.QObject.connect(self.MaterialField, QtCore.SIGNAL(_fromUtf8("currentIndexChanged(int)")), self.changeMaterial)
QtCore.QObject.connect(self.DiameterField, QtCore.SIGNAL(_fromUtf8("valueChanged(double)")), self.changeDiameter)
QtCore.QObject.connect(self.LengthOffsetField, QtCore.SIGNAL(_fromUtf8("valueChanged(double)")), self.changeLengthOffset)
QtCore.QObject.connect(self.FlatRadiusField, QtCore.SIGNAL(_fromUtf8("valueChanged(double)")), self.changeFlatRadius)
QtCore.QObject.connect(self.CornerRadiusField, QtCore.SIGNAL(_fromUtf8("valueChanged(double)")), self.changeCornerRadius)
QtCore.QObject.connect(self.CuttingEdgeAngleField, QtCore.SIGNAL(_fromUtf8("valueChanged(double)")), self.changeCuttingEdgeAngle)
QtCore.QObject.connect(self.CuttingEdgeHeightField, QtCore.SIGNAL(_fromUtf8("valueChanged(double)")), self.changeCuttingEdgeHeight)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(
_fromUtf8("accepted()")), self.accept)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(
_fromUtf8("rejected()")), self.reject)
QtCore.QObject.connect(self.ButtonImport, QtCore.SIGNAL(
_fromUtf8("clicked()")), self.read)
QtCore.QObject.connect(self.ButtonExport, QtCore.SIGNAL(
_fromUtf8("clicked()")), self.write)
QtCore.QObject.connect(self.ButtonAdd, QtCore.SIGNAL(
_fromUtf8("clicked()")), self.addnew)
QtCore.QObject.connect(self.ButtonDelete, QtCore.SIGNAL(
_fromUtf8("clicked()")), self.delete)
QtCore.QObject.connect(self.ButtonUp, QtCore.SIGNAL(
_fromUtf8("clicked()")), self.moveup)
QtCore.QObject.connect(self.ButtonDown, QtCore.SIGNAL(
_fromUtf8("clicked()")), self.movedown)
QtCore.QObject.connect(self.ToolsList, QtCore.SIGNAL(_fromUtf8(
"currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)")), self.selectTool)
QtCore.QObject.connect(self.NameField, QtCore.SIGNAL(
_fromUtf8("textEdited(QString)")), self.changeName)
QtCore.QObject.connect(self.TypeField, QtCore.SIGNAL(
_fromUtf8("currentIndexChanged(int)")), self.changeType)
QtCore.QObject.connect(self.MaterialField, QtCore.SIGNAL(
_fromUtf8("currentIndexChanged(int)")), self.changeMaterial)
QtCore.QObject.connect(self.DiameterField, QtCore.SIGNAL(
_fromUtf8("valueChanged(double)")), self.changeDiameter)
QtCore.QObject.connect(self.LengthOffsetField, QtCore.SIGNAL(
_fromUtf8("valueChanged(double)")), self.changeLengthOffset)
QtCore.QObject.connect(self.FlatRadiusField, QtCore.SIGNAL(
_fromUtf8("valueChanged(double)")), self.changeFlatRadius)
QtCore.QObject.connect(self.CornerRadiusField, QtCore.SIGNAL(
_fromUtf8("valueChanged(double)")), self.changeCornerRadius)
QtCore.QObject.connect(self.CuttingEdgeAngleField, QtCore.SIGNAL(
_fromUtf8("valueChanged(double)")), self.changeCuttingEdgeAngle)
QtCore.QObject.connect(self.CuttingEdgeHeightField, QtCore.SIGNAL(
_fromUtf8("valueChanged(double)")), self.changeCuttingEdgeHeight)
QtCore.QMetaObject.connectSlotsByName(self)
self.tooltable = obj.Tooltable.copy()
self.tool = None
@ -385,64 +423,104 @@ class Editor(QtGui.QDialog):
self.reset()
def retranslateUi(self):
self.setWindowTitle(_translate("TooltableEditor", "Tooltable editor", None))
self.groupBox.setTitle(_translate("TooltableEditor", "Tools list", None))
self.ButtonImport.setText(_translate("TooltableEditor", "Import...", None))
self.ButtonExport.setText(_translate("TooltableEditor", "Export...", None))
self.ToolsList.headerItem().setText(0, _translate("TooltableEditor", "Slot", None))
self.ToolsList.headerItem().setText(1, _translate("TooltableEditor", "Tool", None))
self.setWindowTitle(_translate(
"TooltableEditor", "Tooltable editor", None))
self.groupBox.setTitle(_translate(
"TooltableEditor", "Tools list", None))
self.ButtonImport.setText(_translate(
"TooltableEditor", "Import...", None))
self.ButtonExport.setText(_translate(
"TooltableEditor", "Export...", None))
self.ToolsList.headerItem().setText(
0, _translate("TooltableEditor", "Slot", None))
self.ToolsList.headerItem().setText(
1, _translate("TooltableEditor", "Tool", None))
self.ButtonAdd.setText(_translate("TooltableEditor", "Add new", None))
self.ButtonDelete.setText(_translate("TooltableEditor", "Delete", None))
self.ButtonDelete.setText(_translate(
"TooltableEditor", "Delete", None))
self.ButtonUp.setText(_translate("TooltableEditor", "Move up", None))
self.ButtonDown.setText(_translate("TooltableEditor", "Move down", None))
self.groupBox_2.setTitle(_translate("TooltableEditor", "Tool properties", None))
self.ButtonDown.setText(_translate(
"TooltableEditor", "Move down", None))
self.groupBox_2.setTitle(_translate(
"TooltableEditor", "Tool properties", None))
self.label.setText(_translate("TooltableEditor", "Name", None))
self.label_2.setText(_translate("TooltableEditor", "Type", None))
self.TypeField.setItemText(0, _translate("TooltableEditor", "Undefined", None))
self.TypeField.setItemText(1, _translate("TooltableEditor", "Drill", None))
self.TypeField.setItemText(2, _translate("TooltableEditor", "Center Drill", None))
self.TypeField.setItemText(3, _translate("TooltableEditor", "Counter Sink", None))
self.TypeField.setItemText(4, _translate("TooltableEditor", "Counter Bore", None))
self.TypeField.setItemText(5, _translate("TooltableEditor", "Reamer", None))
self.TypeField.setItemText(6, _translate("TooltableEditor", "Tap", None))
self.TypeField.setItemText(7, _translate("TooltableEditor", "End Mill", None))
self.TypeField.setItemText(8, _translate("TooltableEditor", "Slot Cutter", None))
self.TypeField.setItemText(9, _translate("TooltableEditor", "Ball End Mill", None))
self.TypeField.setItemText(10, _translate("TooltableEditor", "Chamfer Mill", None))
self.TypeField.setItemText(11, _translate("TooltableEditor", "Corner Round", None))
self.TypeField.setItemText(12, _translate("TooltableEditor", "Engraver", None))
self.TypeField.setItemText(0, _translate(
"TooltableEditor", "Undefined", None))
self.TypeField.setItemText(1, _translate(
"TooltableEditor", "Drill", None))
self.TypeField.setItemText(2, _translate(
"TooltableEditor", "Center Drill", None))
self.TypeField.setItemText(3, _translate(
"TooltableEditor", "Counter Sink", None))
self.TypeField.setItemText(4, _translate(
"TooltableEditor", "Counter Bore", None))
self.TypeField.setItemText(5, _translate(
"TooltableEditor", "Reamer", None))
self.TypeField.setItemText(
6, _translate("TooltableEditor", "Tap", None))
self.TypeField.setItemText(7, _translate(
"TooltableEditor", "End Mill", None))
self.TypeField.setItemText(8, _translate(
"TooltableEditor", "Slot Cutter", None))
self.TypeField.setItemText(9, _translate(
"TooltableEditor", "Ball End Mill", None))
self.TypeField.setItemText(10, _translate(
"TooltableEditor", "Chamfer Mill", None))
self.TypeField.setItemText(11, _translate(
"TooltableEditor", "Corner Round", None))
self.TypeField.setItemText(12, _translate(
"TooltableEditor", "Engraver", None))
self.label_3.setText(_translate("TooltableEditor", "Material", None))
self.MaterialField.setItemText(0, _translate("TooltableEditor", "Undefined", None))
self.MaterialField.setItemText(1, _translate("TooltableEditor", "High Speed Steel", None))
self.MaterialField.setItemText(2, _translate("TooltableEditor", "High Carbon Tool Steel", None))
self.MaterialField.setItemText(3, _translate("TooltableEditor", "Cast Alloy", None))
self.MaterialField.setItemText(4, _translate("TooltableEditor", "Carbide", None))
self.MaterialField.setItemText(5, _translate("TooltableEditor", "Ceramics", None))
self.MaterialField.setItemText(6, _translate("TooltableEditor", "Diamond", None))
self.MaterialField.setItemText(7, _translate("TooltableEditor", "Sialon", None))
self.MaterialField.setItemText(0, _translate(
"TooltableEditor", "Undefined", None))
self.MaterialField.setItemText(1, _translate(
"TooltableEditor", "High Speed Steel", None))
self.MaterialField.setItemText(2, _translate(
"TooltableEditor", "High Carbon Tool Steel", None))
self.MaterialField.setItemText(3, _translate(
"TooltableEditor", "Cast Alloy", None))
self.MaterialField.setItemText(
4, _translate("TooltableEditor", "Carbide", None))
self.MaterialField.setItemText(
5, _translate("TooltableEditor", "Ceramics", None))
self.MaterialField.setItemText(
6, _translate("TooltableEditor", "Diamond", None))
self.MaterialField.setItemText(
7, _translate("TooltableEditor", "Sialon", None))
self.label_4.setText(_translate("TooltableEditor", "Properties", None))
self.label_5.setText(_translate("TooltableEditor", "Diameter", None))
# self.DiameterField.setSuffix(_translate("TooltableEditor", "mm", None))
self.label_6.setText(_translate("TooltableEditor", "Length offset", None))
self.LengthOffsetField.setSuffix(_translate("TooltableEditor", "mm", None))
self.label_7.setText(_translate("TooltableEditor", "Flat radius", None))
self.FlatRadiusField.setSuffix(_translate("TooltableEditor", "mm", None))
self.label_8.setText(_translate("TooltableEditor", "Corner radius", None))
self.CornerRadiusField.setSuffix(_translate("TooltableEditor", "mm", None))
self.label_9.setText(_translate("TooltableEditor", "Cutting edge angle", None))
self.CuttingEdgeAngleField.setSuffix(_translate("TooltableEditor", "°", None))
self.label_10.setText(_translate("TooltableEditor", "Cutting edge height", None))
self.CuttingEdgeHeightField.setSuffix(_translate("TooltableEditor", "mm", None))
self.label_6.setText(_translate(
"TooltableEditor", "Length offset", None))
self.LengthOffsetField.setSuffix(
_translate("TooltableEditor", "mm", None))
self.label_7.setText(_translate(
"TooltableEditor", "Flat radius", None))
self.FlatRadiusField.setSuffix(
_translate("TooltableEditor", "mm", None))
self.label_8.setText(_translate(
"TooltableEditor", "Corner radius", None))
self.CornerRadiusField.setSuffix(
_translate("TooltableEditor", "mm", None))
self.label_9.setText(_translate(
"TooltableEditor", "Cutting edge angle", None))
self.CuttingEdgeAngleField.setSuffix(
_translate("TooltableEditor", "°", None))
self.label_10.setText(_translate(
"TooltableEditor", "Cutting edge height", None))
self.CuttingEdgeHeightField.setSuffix(
_translate("TooltableEditor", "mm", None))
def reset(self):
"resets the editor with the contents of the current internal tooltable"
self.tool = None
self.number = None
self.ToolsList.clear()
for number,tool in self.tooltable.Tools.iteritems():
for number, tool in self.tooltable.Tools.iteritems():
item = QtGui.QTreeWidgetItem(self.ToolsList)
item.setText(0,str(number))
item.setText(1,tool.Name)
item.setText(0, str(number))
item.setText(1, tool.Name)
self.NameField.setText("")
self.TypeField.setCurrentIndex(-1)
self.MaterialField.setCurrentIndex(-1)
@ -452,8 +530,8 @@ class Editor(QtGui.QDialog):
self.CornerRadiusField.setValue(0)
self.CuttingEdgeAngleField.setValue(0)
self.CuttingEdgeHeightField.setValue(0)
def selectTool(self,current,previous):
def selectTool(self, current, previous):
"fills the data of the currently selected tool"
if current:
number = int(current.text(0))
@ -463,108 +541,110 @@ class Editor(QtGui.QDialog):
self.tool = tool
self.NameField.setText(tool.Name)
self.TypeField.setCurrentIndex(self.getType(tool.ToolType))
self.MaterialField.setCurrentIndex(self.getMaterial(tool.Material))
self.MaterialField.setCurrentIndex(
self.getMaterial(tool.Material))
self.DiameterField.setValue(tool.Diameter)
self.LengthOffsetField.setValue(tool.LengthOffset)
self.FlatRadiusField.setValue(tool.FlatRadius)
self.CornerRadiusField.setValue(tool.CornerRadius)
self.CuttingEdgeAngleField.setValue(tool.CuttingEdgeAngle)
self.CuttingEdgeHeightField.setValue(tool.CuttingEdgeHeight)
def getType(self,tooltype):
def getType(self, tooltype):
"gets a combobox index number for a given type or viceversa"
toolslist = ["Drill","CenterDrill","CounterSink","CounterBore",
"Reamer","Tap","EndMill","SlotCutter","BallEndMill",
"ChamferMill","CornerRound","Engraver"]
if isinstance(tooltype,str):
toolslist = ["Drill", "CenterDrill", "CounterSink", "CounterBore",
"Reamer", "Tap", "EndMill", "SlotCutter", "BallEndMill",
"ChamferMill", "CornerRound", "Engraver"]
if isinstance(tooltype, str):
if tooltype in toolslist:
return toolslist.index(tooltype)+1
return toolslist.index(tooltype) + 1
else:
return 0
else:
if tooltype == 0:
return "Undefined"
else:
return toolslist[tooltype-1]
def getMaterial(self,material):
return toolslist[tooltype - 1]
def getMaterial(self, material):
"gets a combobox index number for a given material or viceversa"
matslist = ["HighSpeedSteel","HighCarbonToolSteel","CastAlloy",
"Carbide","Ceramics","Diamond","Sialon"]
if isinstance(material,str):
matslist = ["HighSpeedSteel", "HighCarbonToolSteel", "CastAlloy",
"Carbide", "Ceramics", "Diamond", "Sialon"]
if isinstance(material, str):
if material in matslist:
return matslist.index(material)+1
return matslist.index(material) + 1
else:
return 0
else:
if material == 0:
return "Undefined"
else:
return matslist[material-1]
def changeName(self,text):
return matslist[material - 1]
def changeName(self, text):
"called when the corresponding field has changed (needed for nasty pyside bug)"
if self.tool:
self.tool.Name = str(text)
self.changeTool()
if self.number:
l = self.ToolsList.findItems(str(self.number),QtCore.Qt.MatchExactly,0)
l = self.ToolsList.findItems(
str(self.number), QtCore.Qt.MatchExactly, 0)
if len(l) == 1:
l[0].setText(1,text)
def changeType(self,num):
l[0].setText(1, text)
def changeType(self, num):
"called when the corresponding field has changed (needed for nasty pyside bug)"
if self.tool:
self.tool.ToolType = self.getType(num)
self.changeTool()
def changeMaterial(self,num):
def changeMaterial(self, num):
"called when the corresponding field has changed (needed for nasty pyside bug)"
if self.tool:
self.tool.Material = self.getMaterial(num)
self.changeTool()
def changeDiameter(self,value):
def changeDiameter(self, value):
"called when the corresponding field has changed (needed for nasty pyside bug)"
if self.tool:
self.tool.Diameter = value
self.changeTool()
def changeLengthOffset(self,value):
def changeLengthOffset(self, value):
"called when the corresponding field has changed (needed for nasty pyside bug)"
if self.tool:
self.tool.LengthOffset = value
self.changeTool()
def changeFlatRadius(self,value):
def changeFlatRadius(self, value):
"called when the corresponding field has changed (needed for nasty pyside bug)"
if self.tool:
self.tool.FlatRadius = value
self.changeTool()
def changeCornerRadius(self,value):
def changeCornerRadius(self, value):
"called when the corresponding field has changed (needed for nasty pyside bug)"
if self.tool:
self.tool.CornerRadius = value
self.changeTool()
def changeCuttingEdgeAngle(self,value):
def changeCuttingEdgeAngle(self, value):
"called when the corresponding field has changed (needed for nasty pyside bug)"
if self.tool:
self.tool.CuttingEdgeAngle = value
self.changeTool()
def changeCuttingEdgeHeight(self,value):
def changeCuttingEdgeHeight(self, value):
"called when the corresponding field has changed (needed for nasty pyside bug)"
if self.tool:
self.tool.CuttingEdgeHeight = value
self.changeTool()
def changeTool(self):
"changes a given tool"
if self.number and self.tool:
self.tooltable.setTool(self.number,self.tool)
self.tooltable.setTool(self.number, self.tool)
def delete(self):
"deletes the current tool"
if self.number:
@ -587,10 +667,11 @@ class Editor(QtGui.QDialog):
tool.CuttingEdgeHeight = self.CuttingEdgeHeightField.value()
self.tooltable.addTools(tool)
self.reset()
def read(self):
"imports a tooltable from a file"
filename = QtGui.QFileDialog.getOpenFileName(self, _translate("TooltableEditor","Open tooltable",None),None, _translate("TooltableEditor","Tooltable XML (*.xml);;HeeksCAD tooltable (*.tooltable)",None))
filename = QtGui.QFileDialog.getOpenFileName(self, _translate("TooltableEditor", "Open tooltable", None), None, _translate(
"TooltableEditor", "Tooltable XML (*.xml);;HeeksCAD tooltable (*.tooltable)", None))
if filename:
parser = xml.sax.make_parser()
parser.setFeature(xml.sax.handler.feature_namespaces, 0)
@ -598,23 +679,24 @@ class Editor(QtGui.QDialog):
Handler = HeeksTooltableHandler()
else:
Handler = FreeCADTooltableHandler()
parser.setContentHandler( Handler )
parser.setContentHandler(Handler)
parser.parse(str(filename[0]))
if Handler.tooltable:
self.tooltable = Handler.tooltable
self.reset()
def write(self):
"exports the tooltable to a file"
if self.tooltable:
filename = QtGui.QFileDialog.getSaveFileName(self, _translate("TooltableEditor","Save tooltable",None),None, _translate("TooltableEditor","Tooltable XML (*.xml)",None))
filename = QtGui.QFileDialog.getSaveFileName(self, _translate(
"TooltableEditor", "Save tooltable", None), None, _translate("TooltableEditor", "Tooltable XML (*.xml)", None))
if filename:
fil = open(str(filename[0]),"wb")
fil = open(str(filename[0]), "wb")
fil.write('<?xml version="1.0" encoding="UTF-8"?>\n')
fil.write(self.tooltable.Content)
fil.close()
print "Written ",filename[0]
print "Written ", filename[0]
def moveup(self):
"moves a tool to a lower number, if possible"
if self.number:
@ -626,10 +708,10 @@ class Editor(QtGui.QDialog):
if target in self.tooltable.Tools.keys():
t2 = self.tooltable.getTool(target).copy()
self.tooltable.deleteTool(target)
self.tooltable.setTool(self.number,t2)
self.tooltable.setTool(target,t1)
self.tooltable.setTool(self.number, t2)
self.tooltable.setTool(target, t1)
self.reset()
def movedown(self):
"moves a tool to a higher number, if possible"
if self.number:
@ -639,18 +721,21 @@ class Editor(QtGui.QDialog):
if target in self.tooltable.Tools.keys():
t2 = self.tooltable.getTool(target).copy()
self.tooltable.deleteTool(target)
self.tooltable.setTool(self.number,t2)
self.tooltable.setTool(target,t1)
self.tooltable.setTool(self.number, t2)
self.tooltable.setTool(target, t1)
self.reset()
def edit(objectname):
"""edit(objectname): this is the main function of this module.
opens an editor dialog to edit the Tooltable of the given object"""
obj = FreeCAD.ActiveDocument.getObject(objectname)
if not obj:
raise Exception(_translate("TooltableEditor","Object not found",None))
if not hasattr(obj,"Tooltable"):
raise Exception(_translate("TooltableEditor","Object doesn't have a tooltable property",None))
raise Exception(_translate(
"TooltableEditor", "Object not found", None))
if not hasattr(obj, "Tooltable"):
raise Exception(_translate("TooltableEditor",
"Object doesn't have a tooltable property", None))
dialog = Editor(obj)
r = dialog.exec_()
if r:
@ -660,4 +745,3 @@ def edit(objectname):
FreeCAD.ActiveDocument.commitTransaction()
obj.ViewObject.finishEditing()