PathHelix: fix most of the PEP8 issues
Dealt with most issues expect for overly long lines
This commit is contained in:
parent
ec5faafd86
commit
0de0d8f930
|
@ -1,50 +1,56 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
#***************************************************************************
|
# ***************************************************************************
|
||||||
#* *
|
# * *
|
||||||
#* Copyright (c) 2016 Lorenz Hüdepohl <dev@stellardeath.org> *
|
# * Copyright (c) 2016 Lorenz Hüdepohl <dev@stellardeath.org> *
|
||||||
#* *
|
# * *
|
||||||
#* This program is free software; you can redistribute it and/or modify *
|
# * This program is free software; you can redistribute it and/or modify *
|
||||||
#* it under the terms of the GNU Lesser General Public License (LGPL) *
|
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||||
#* as published by the Free Software Foundation; either version 2 of *
|
# * as published by the Free Software Foundation; either version 2 of *
|
||||||
#* the License, or (at your option) any later version. *
|
# * the License, or (at your option) any later version. *
|
||||||
#* for detail see the LICENCE text file. *
|
# * for detail see the LICENCE text file. *
|
||||||
#* *
|
# * *
|
||||||
#* This program is distributed in the hope that it will be useful, *
|
# * This program is distributed in the hope that it will be useful, *
|
||||||
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
#* GNU Library General Public License for more details. *
|
# * GNU Library General Public License for more details. *
|
||||||
#* *
|
# * *
|
||||||
#* You should have received a copy of the GNU Library General Public *
|
# * You should have received a copy of the GNU Library General Public *
|
||||||
#* License along with this program; if not, write to the Free Software *
|
# * License along with this program; if not, write to the Free Software *
|
||||||
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||||
#* USA *
|
# * USA *
|
||||||
#* *
|
# * *
|
||||||
#***************************************************************************
|
# ***************************************************************************
|
||||||
|
|
||||||
import FreeCAD, Path
|
from . import PathUtils
|
||||||
|
from .PathUtils import fmt
|
||||||
|
|
||||||
|
import FreeCAD
|
||||||
|
import Path
|
||||||
if FreeCAD.GuiUp:
|
if FreeCAD.GuiUp:
|
||||||
import FreeCADGui
|
import FreeCADGui
|
||||||
from PySide import QtCore, QtGui
|
from PySide import QtCore, QtGui
|
||||||
from DraftTools import translate
|
from DraftTools import translate
|
||||||
|
|
||||||
from . import PathUtils
|
|
||||||
from .PathUtils import fmt
|
|
||||||
|
|
||||||
"""Helix Drill object and FreeCAD command"""
|
"""Helix Drill object and FreeCAD command"""
|
||||||
|
|
||||||
if FreeCAD.GuiUp:
|
if FreeCAD.GuiUp:
|
||||||
try:
|
try:
|
||||||
_encoding = QtGui.QApplication.UnicodeUTF8
|
_encoding = QtGui.QApplication.UnicodeUTF8
|
||||||
|
|
||||||
def translate(context, text, disambig=None):
|
def translate(context, text, disambig=None):
|
||||||
return QtGui.QApplication.translate(context, text, disambig, _encoding)
|
return QtGui.QApplication.translate(context, text, disambig,
|
||||||
|
_encoding)
|
||||||
|
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
|
||||||
def translate(context, text, disambig=None):
|
def translate(context, text, disambig=None):
|
||||||
return QtGui.QApplication.translate(context, text, disambig)
|
return QtGui.QApplication.translate(context, text, disambig)
|
||||||
else:
|
else:
|
||||||
def translate(context, text, disambig=None):
|
def translate(context, text, disambig=None):
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
||||||
def z_cylinder(cyl):
|
def z_cylinder(cyl):
|
||||||
""" Test if cylinder is aligned to z-Axis"""
|
""" Test if cylinder is aligned to z-Axis"""
|
||||||
if cyl.Surface.Axis.x != 0.0:
|
if cyl.Surface.Axis.x != 0.0:
|
||||||
|
@ -53,12 +59,14 @@ def z_cylinder(cyl):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def connected(edge, face):
|
def connected(edge, face):
|
||||||
for otheredge in face.Edges:
|
for otheredge in face.Edges:
|
||||||
if edge.isSame(otheredge):
|
if edge.isSame(otheredge):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def cylinders_in_selection():
|
def cylinders_in_selection():
|
||||||
from Part import Cylinder
|
from Part import Cylinder
|
||||||
selections = FreeCADGui.Selection.getSelectionEx()
|
selections = FreeCADGui.Selection.getSelectionEx()
|
||||||
|
@ -70,7 +78,7 @@ def cylinders_in_selection():
|
||||||
cylinders.append((base, []))
|
cylinders.append((base, []))
|
||||||
for feature in selection.SubElementNames:
|
for feature in selection.SubElementNames:
|
||||||
subobj = getattr(base.Shape, feature)
|
subobj = getattr(base.Shape, feature)
|
||||||
if subobj.ShapeType =='Face':
|
if subobj.ShapeType == 'Face':
|
||||||
if isinstance(subobj.Surface, Cylinder):
|
if isinstance(subobj.Surface, Cylinder):
|
||||||
if z_cylinder(subobj):
|
if z_cylinder(subobj):
|
||||||
cylinders[-1][1].append(feature)
|
cylinders[-1][1].append(feature)
|
||||||
|
@ -81,7 +89,7 @@ def cylinders_in_selection():
|
||||||
def helix_cut(center, r_out, r_in, dr, zmax, zmin, dz, safe_z, tool_diameter, vfeed, hfeed, direction, startside):
|
def helix_cut(center, r_out, r_in, dr, zmax, zmin, dz, safe_z, tool_diameter, vfeed, hfeed, direction, startside):
|
||||||
"""
|
"""
|
||||||
center: 2-tuple
|
center: 2-tuple
|
||||||
(x0,y0) coordinates of center
|
(x0, y0) coordinates of center
|
||||||
r_out, r_in: floats
|
r_out, r_in: floats
|
||||||
radial range, cut from outer radius r_out in layers of dr to inner radius r_in
|
radial range, cut from outer radius r_out in layers of dr to inner radius r_in
|
||||||
zmax, zmin: floats
|
zmax, zmin: floats
|
||||||
|
@ -118,15 +126,15 @@ def helix_cut(center, r_out, r_in, dr, zmax, zmin, dz, safe_z, tool_diameter, vf
|
||||||
return out
|
return out
|
||||||
|
|
||||||
def rapid(x=None, y=None, z=None):
|
def rapid(x=None, y=None, z=None):
|
||||||
return "G0" + xyz(x,y,z) + "\n"
|
return "G0" + xyz(x, y, z) + "\n"
|
||||||
|
|
||||||
def F(f=None):
|
def F(f=None):
|
||||||
return (" F" + fmt(f) if f else "")
|
return (" F" + fmt(f) if f else "")
|
||||||
|
|
||||||
def feed(x=None, y=None, z=None, f=None):
|
def feed(x=None, y=None, z=None, f=None):
|
||||||
return "G1" + xyz(x,y,z) + F(f) + "\n"
|
return "G1" + xyz(x, y, z) + F(f) + "\n"
|
||||||
|
|
||||||
def arc(x,y,i,j,z,f):
|
def arc(x, y, i, j, z, f):
|
||||||
if direction == "CW":
|
if direction == "CW":
|
||||||
code = "G2"
|
code = "G2"
|
||||||
elif direction == "CCW":
|
elif direction == "CCW":
|
||||||
|
@ -135,21 +143,21 @@ def helix_cut(center, r_out, r_in, dr, zmax, zmin, dz, safe_z, tool_diameter, vf
|
||||||
|
|
||||||
def helix_cut_r(r):
|
def helix_cut_r(r):
|
||||||
out = ""
|
out = ""
|
||||||
out += rapid(x=x0+r,y=y0)
|
out += rapid(x=x0+r, y=y0)
|
||||||
out += rapid(z=zmax + tool_diameter)
|
out += rapid(z=zmax + tool_diameter)
|
||||||
out += feed(z=zmax,f=vfeed)
|
out += feed(z=zmax, f=vfeed)
|
||||||
z=zmin
|
z = zmin
|
||||||
for i in range(1,nz+1):
|
for i in range(1, nz+1):
|
||||||
out += arc(x0-r, y0, i=-r, j=0.0, z = zi[2*i-1], f=hfeed)
|
out += arc(x0-r, y0, i=-r, j=0.0, z=zi[2*i-1], f=hfeed)
|
||||||
out += arc(x0+r, y0, i= r, j=0.0, z = zi[2*i], f=hfeed)
|
out += arc(x0+r, y0, i= r, j=0.0, z=zi[2*i], f=hfeed)
|
||||||
out += arc(x0-r, y0, i=-r, j=0.0, z = zmin, f=hfeed)
|
out += arc(x0-r, y0, i=-r, j=0.0, z=zmin, f=hfeed)
|
||||||
out += arc(x0+r, y0, i=r, j=0.0, z = zmin, f=hfeed)
|
out += arc(x0+r, y0, i=r, j=0.0, z=zmin, f=hfeed)
|
||||||
out += feed(z=zmax + tool_diameter, f=vfeed)
|
out += feed(z=zmax + tool_diameter, f=vfeed)
|
||||||
out += rapid(z=safe_z)
|
out += rapid(z=safe_z)
|
||||||
return out
|
return out
|
||||||
|
|
||||||
assert(r_out > 0.0)
|
assert(r_out > 0.0)
|
||||||
assert(r_in >= 0.0)
|
assert(r_in >= 0.0)
|
||||||
|
|
||||||
msg = None
|
msg = None
|
||||||
if r_out < 0.0:
|
if r_out < 0.0:
|
||||||
|
@ -158,7 +166,7 @@ def helix_cut(center, r_out, r_in, dr, zmax, zmin, dz, safe_z, tool_diameter, vf
|
||||||
msg = "r_out - r_in = {0} is < tool diameter of {1}".format(r_out - r_in, tool_diameter)
|
msg = "r_out - r_in = {0} is < tool diameter of {1}".format(r_out - r_in, tool_diameter)
|
||||||
elif r_in == 0.0 and not r_out > tool_diameter/2.:
|
elif r_in == 0.0 and not r_out > tool_diameter/2.:
|
||||||
msg = "Cannot drill a hole of diameter {0} with a tool of diameter {1}".format(2 * r_out, tool_diameter)
|
msg = "Cannot drill a hole of diameter {0} with a tool of diameter {1}".format(2 * r_out, tool_diameter)
|
||||||
elif not startside in ["inside", "outside"]:
|
elif startside not in ["inside", "outside"]:
|
||||||
msg = "Invalid value for parameter 'startside'"
|
msg = "Invalid value for parameter 'startside'"
|
||||||
|
|
||||||
if msg:
|
if msg:
|
||||||
|
@ -169,7 +177,7 @@ def helix_cut(center, r_out, r_in, dr, zmax, zmin, dz, safe_z, tool_diameter, vf
|
||||||
if r_in > 0:
|
if r_in > 0:
|
||||||
out += "(annulus mode)\n"
|
out += "(annulus mode)\n"
|
||||||
r_out = r_out - tool_diameter/2
|
r_out = r_out - tool_diameter/2
|
||||||
r_in = r_in + tool_diameter/2
|
r_in = r_in + tool_diameter/2
|
||||||
if abs((r_out - r_in) / dr) < 1e-5:
|
if abs((r_out - r_in) / dr) < 1e-5:
|
||||||
radii = [(r_out + r_in)/2]
|
radii = [(r_out + r_in)/2]
|
||||||
else:
|
else:
|
||||||
|
@ -182,7 +190,7 @@ def helix_cut(center, r_out, r_in, dr, zmax, zmin, dz, safe_z, tool_diameter, vf
|
||||||
else:
|
else:
|
||||||
out += "(full hole mode)\n"
|
out += "(full hole mode)\n"
|
||||||
r_out = r_out - tool_diameter/2
|
r_out = r_out - tool_diameter/2
|
||||||
r_in = dr/2
|
r_in = dr/2
|
||||||
|
|
||||||
nr = max(1 + int(ceil((r_out - r_in)/dr)), 2)
|
nr = max(1 + int(ceil((r_out - r_in)/dr)), 2)
|
||||||
radii = linspace(r_out, r_in, nr)
|
radii = linspace(r_out, r_in, nr)
|
||||||
|
@ -197,6 +205,7 @@ def helix_cut(center, r_out, r_in, dr, zmax, zmin, dz, safe_z, tool_diameter, vf
|
||||||
|
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
def features_by_centers(base, features):
|
def features_by_centers(base, features):
|
||||||
try:
|
try:
|
||||||
from scipy.spatial import KDTree
|
from scipy.spatial import KDTree
|
||||||
|
@ -204,11 +213,11 @@ def features_by_centers(base, features):
|
||||||
from PathScripts.kdtree import KDTree
|
from PathScripts.kdtree import KDTree
|
||||||
|
|
||||||
features = sorted(features,
|
features = sorted(features,
|
||||||
key = lambda feature : getattr(base.Shape, feature).Surface.Radius,
|
key=lambda feature: getattr(base.Shape, feature).Surface.Radius,
|
||||||
reverse = True)
|
reverse=True)
|
||||||
|
|
||||||
coordinates = [(cylinder.Surface.Center.x, cylinder.Surface.Center.y) for cylinder in
|
coordinates = [(cylinder.Surface.Center.x, cylinder.Surface.Center.y) for cylinder in
|
||||||
[getattr(base.Shape, feature) for feature in features]]
|
[getattr(base.Shape, feature) for feature in features]]
|
||||||
|
|
||||||
tree = KDTree(coordinates)
|
tree = KDTree(coordinates)
|
||||||
seen = {}
|
seen = {}
|
||||||
|
@ -221,74 +230,80 @@ def features_by_centers(base, features):
|
||||||
|
|
||||||
cylinder = getattr(base.Shape, feature)
|
cylinder = getattr(base.Shape, feature)
|
||||||
xc, yc, _ = cylinder.Surface.Center
|
xc, yc, _ = cylinder.Surface.Center
|
||||||
by_centers[xc, yc] = {cylinder.Surface.Radius : feature}
|
by_centers[xc, yc] = {cylinder.Surface.Radius: feature}
|
||||||
|
|
||||||
for coord in tree.query_ball_point((xc, yc), cylinder.Surface.Radius):
|
for coord in tree.query_ball_point((xc, yc), cylinder.Surface.Radius):
|
||||||
seen[coord] = True
|
seen[coord] = True
|
||||||
cylinder = getattr(base.Shape, features[coord])
|
cylinder = getattr(base.Shape, features[coord])
|
||||||
by_centers[xc, yc][cylinder.Surface.Radius] = features[coord]
|
by_centers[xc, yc][cylinder.Surface.Radius] = features[coord]
|
||||||
|
|
||||||
return by_centers
|
return by_centers
|
||||||
|
|
||||||
|
|
||||||
class ObjectPathHelix(object):
|
class ObjectPathHelix(object):
|
||||||
|
|
||||||
def __init__(self,obj):
|
def __init__(self, obj):
|
||||||
# Basic
|
# Basic
|
||||||
obj.addProperty("App::PropertyLinkSubList","Features","Path",translate("Features","Selected features for the drill operation"))
|
obj.addProperty("App::PropertyLinkSubList", "Features", "Path",
|
||||||
obj.addProperty("App::PropertyBool","Active","Path",translate("Active","Set to False to disable code generation"))
|
translate("Features", "Selected features for the drill operation"))
|
||||||
obj.addProperty("App::PropertyString","Comment","Path",translate("Comment","An optional comment for this profile, will appear in G-Code"))
|
obj.addProperty("App::PropertyBool", "Active", "Path",
|
||||||
|
translate("Active", "Set to False to disable code generation"))
|
||||||
|
obj.addProperty("App::PropertyString", "Comment", "Path",
|
||||||
|
translate("Comment", "An optional comment for this profile, will appear in G-Code"))
|
||||||
|
|
||||||
# Helix specific
|
# Helix specific
|
||||||
obj.addProperty("App::PropertyEnumeration", "Direction", "Helix Drill",
|
obj.addProperty("App::PropertyEnumeration", "Direction", "Helix Drill",
|
||||||
translate("Direction", "The direction of the circular cuts, clockwise (CW), or counter clockwise (CCW)"))
|
translate("Direction", "The direction of the circular cuts, clockwise (CW), or counter clockwise (CCW)"))
|
||||||
obj.Direction = ['CW','CCW']
|
obj.Direction = ['CW', 'CCW']
|
||||||
|
|
||||||
obj.addProperty("App::PropertyEnumeration", "StartSide", "Helix Drill",
|
obj.addProperty("App::PropertyEnumeration", "StartSide", "Helix Drill",
|
||||||
translate("Direction", "Start cutting from the inside or outside"))
|
translate("Direction", "Start cutting from the inside or outside"))
|
||||||
obj.StartSide = ['inside','outside']
|
obj.StartSide = ['inside', 'outside']
|
||||||
|
|
||||||
obj.addProperty("App::PropertyLength", "DeltaR", "Helix Drill",
|
obj.addProperty("App::PropertyLength", "DeltaR", "Helix Drill",
|
||||||
translate("DeltaR", "Radius increment (must be smaller than tool diameter)"))
|
translate("DeltaR", "Radius increment (must be smaller than tool diameter)"))
|
||||||
|
|
||||||
# Depth Properties
|
# Depth Properties
|
||||||
obj.addProperty("App::PropertyDistance", "Clearance", "Depths",
|
obj.addProperty("App::PropertyDistance", "Clearance", "Depths",
|
||||||
translate("Clearance","Safe distance above the top of the hole to which to retract the tool"))
|
translate("Clearance", "Safe distance above the top of the hole to which to retract the tool"))
|
||||||
obj.addProperty("App::PropertyLength", "StepDown", "Depths",
|
obj.addProperty("App::PropertyLength", "StepDown", "Depths",
|
||||||
translate("StepDown","Incremental Step Down of Tool"))
|
translate("StepDown", "Incremental Step Down of Tool"))
|
||||||
obj.addProperty("App::PropertyBool","UseStartDepth","Depths",
|
obj.addProperty("App::PropertyBool", "UseStartDepth", "Depths",
|
||||||
translate("Use Start Depth","Set to True to manually specify a start depth"))
|
translate("Use Start Depth", "Set to True to manually specify a start depth"))
|
||||||
obj.addProperty("App::PropertyDistance", "StartDepth", "Depths",
|
obj.addProperty("App::PropertyDistance", "StartDepth", "Depths",
|
||||||
translate("Start Depth","Starting Depth of Tool - first cut depth in Z"))
|
translate("Start Depth", "Starting Depth of Tool - first cut depth in Z"))
|
||||||
obj.addProperty("App::PropertyBool","UseFinalDepth","Depths",
|
obj.addProperty("App::PropertyBool", "UseFinalDepth", "Depths",
|
||||||
translate("Use Final Depth","Set to True to manually specify a final depth"))
|
translate("Use Final Depth", "Set to True to manually specify a final depth"))
|
||||||
obj.addProperty("App::PropertyDistance", "FinalDepth", "Depths",
|
obj.addProperty("App::PropertyDistance", "FinalDepth", "Depths",
|
||||||
translate("Final Depth","Final Depth of Tool - lowest value in Z"))
|
translate("Final Depth", "Final Depth of Tool - lowest value in Z"))
|
||||||
obj.addProperty("App::PropertyDistance", "ThroughDepth", "Depths",
|
obj.addProperty("App::PropertyDistance", "ThroughDepth", "Depths",
|
||||||
translate("Through Depth","Add this amount of additional cutting depth to open-ended holes. Only used if UseFinalDepth is False"))
|
translate("Through Depth", "Add this amount of additional cutting depth "
|
||||||
|
"to open-ended holes. Only used if UseFinalDepth is False"))
|
||||||
|
|
||||||
# The current tool number, read-only
|
# The current tool number, read-only
|
||||||
# this is apparently used internally, to keep track of tool chagnes
|
# this is apparently used internally, to keep track of tool chagnes
|
||||||
obj.addProperty("App::PropertyIntegerConstraint","ToolNumber","Tool",translate("PathProfile","The current tool in use"))
|
obj.addProperty("App::PropertyIntegerConstraint", "ToolNumber", "Tool",
|
||||||
obj.ToolNumber = (0,0,1000,1)
|
translate("PathProfile", "The current tool in use"))
|
||||||
obj.setEditorMode('ToolNumber',1) #make this read only
|
obj.ToolNumber = (0, 0, 1000, 1)
|
||||||
|
obj.setEditorMode('ToolNumber', 1) # make this read only
|
||||||
|
|
||||||
obj.Proxy = self
|
obj.Proxy = self
|
||||||
|
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def __setstate__(self,state):
|
def __setstate__(self, state):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def execute(self,obj):
|
def execute(self, obj):
|
||||||
from Part import Circle, Cylinder, Plane
|
from Part import Circle, Cylinder, Plane
|
||||||
from math import sqrt
|
from math import sqrt
|
||||||
|
|
||||||
output = '(helix cut operation'
|
output = '(helix cut operation'
|
||||||
if obj.Comment:
|
if obj.Comment:
|
||||||
output += ', '+ str(obj.Comment)+')\n'
|
output += ', ' + str(obj.Comment) + ')\n'
|
||||||
else:
|
else:
|
||||||
output += ')\n'
|
output += ')\n'
|
||||||
|
|
||||||
if obj.Features:
|
if obj.Features:
|
||||||
if not obj.Active:
|
if not obj.Active:
|
||||||
|
@ -332,8 +347,9 @@ class ObjectPathHelix(object):
|
||||||
r = cylinder.Surface.Radius
|
r = cylinder.Surface.Radius
|
||||||
|
|
||||||
if dz < 0:
|
if dz < 0:
|
||||||
# This is a closed hole if the face connected to the current cylinder at next_z has
|
# This is a closed hole if the face connected to
|
||||||
# the cylinder's edge as its OuterWire
|
# the current cylinder at next_z has the cylinder's
|
||||||
|
# edge as its OuterWire
|
||||||
closed = None
|
closed = None
|
||||||
for face in base.Shape.Faces:
|
for face in base.Shape.Faces:
|
||||||
if connected(other_edge, face) and not face.isSame(cylinder.Faces[0]):
|
if connected(other_edge, face) and not face.isSame(cylinder.Faces[0]):
|
||||||
|
@ -347,7 +363,9 @@ class ObjectPathHelix(object):
|
||||||
raise Exception("Cannot determine if this cylinder is closed on the z = {0} side".format(next_z))
|
raise Exception("Cannot determine if this cylinder is closed on the z = {0} side".format(next_z))
|
||||||
|
|
||||||
xc, yc, _ = cylinder.Surface.Center
|
xc, yc, _ = cylinder.Surface.Center
|
||||||
jobs.append(dict(xc=xc, yc=yc, zmin=next_z, zmax=cur_z, r_out=r, r_in=0.0, closed=closed, zsafe=zsafe))
|
jobs.append(dict(xc=xc, yc=yc,
|
||||||
|
zmin=next_z, zmax=cur_z, zsafe=zsafe,
|
||||||
|
r_out=r, r_in=0.0, closed=closed))
|
||||||
|
|
||||||
elif dz > 0:
|
elif dz > 0:
|
||||||
new_jobs = []
|
new_jobs = []
|
||||||
|
@ -388,20 +406,20 @@ class ObjectPathHelix(object):
|
||||||
output += helix_cut((job["xc"], job["yc"]), job["r_out"], job["r_in"], obj.DeltaR.Value,
|
output += helix_cut((job["xc"], job["yc"]), job["r_out"], job["r_in"], obj.DeltaR.Value,
|
||||||
job["zmax"], job["zmin"], obj.StepDown.Value,
|
job["zmax"], job["zmin"], obj.StepDown.Value,
|
||||||
job["zsafe"], tool.Diameter,
|
job["zsafe"], tool.Diameter,
|
||||||
toolload.VertFeed.Value, toolload.HorizFeed.Value, obj.Direction, obj.StartSide)
|
toolload.VertFeed.Value, toolload.HorizFeed.Value,
|
||||||
|
obj.Direction, obj.StartSide)
|
||||||
output += '\n'
|
output += '\n'
|
||||||
|
|
||||||
obj.Path = Path.Path(output)
|
obj.Path = Path.Path(output)
|
||||||
if obj.ViewObject:
|
if obj.ViewObject:
|
||||||
obj.ViewObject.Visibility = True
|
obj.ViewObject.Visibility = True
|
||||||
|
|
||||||
taskpanels = {}
|
|
||||||
|
|
||||||
class ViewProviderPathHelix(object):
|
class ViewProviderPathHelix(object):
|
||||||
def __init__(self,vobj):
|
def __init__(self, vobj):
|
||||||
vobj.Proxy = self
|
vobj.Proxy = self
|
||||||
|
|
||||||
def attach(self,vobj):
|
def attach(self, vobj):
|
||||||
self.Object = vobj.Object
|
self.Object = vobj.Object
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -412,7 +430,6 @@ class ViewProviderPathHelix(object):
|
||||||
FreeCADGui.Control.closeDialog()
|
FreeCADGui.Control.closeDialog()
|
||||||
taskpanel = TaskPanel(vobj.Object)
|
taskpanel = TaskPanel(vobj.Object)
|
||||||
FreeCADGui.Control.showDialog(taskpanel)
|
FreeCADGui.Control.showDialog(taskpanel)
|
||||||
taskpanels[0] = taskpanel
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
|
@ -421,11 +438,12 @@ class ViewProviderPathHelix(object):
|
||||||
def __setstate__(self, state):
|
def __setstate__(self, state):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
class CommandPathHelix(object):
|
class CommandPathHelix(object):
|
||||||
def GetResources(self):
|
def GetResources(self):
|
||||||
return {'Pixmap' : 'Path-Helix',
|
return {'Pixmap': 'Path-Helix',
|
||||||
'MenuText': QtCore.QT_TRANSLATE_NOOP("PathHelix","PathHelix"),
|
'MenuText': QtCore.QT_TRANSLATE_NOOP("PathHelix", "PathHelix"),
|
||||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("PathHelix","Creates a helix cut from selected circles")}
|
'ToolTip': QtCore.QT_TRANSLATE_NOOP("PathHelix", "Creates a helix cut from selected circles")}
|
||||||
|
|
||||||
def IsActive(self):
|
def IsActive(self):
|
||||||
if FreeCAD.ActiveDocument is not None:
|
if FreeCAD.ActiveDocument is not None:
|
||||||
|
@ -439,10 +457,10 @@ class CommandPathHelix(object):
|
||||||
import Path
|
import Path
|
||||||
from PathScripts import PathUtils
|
from PathScripts import PathUtils
|
||||||
|
|
||||||
FreeCAD.ActiveDocument.openTransaction(translate("PathHelix","Create a helix cut"))
|
FreeCAD.ActiveDocument.openTransaction(translate("PathHelix", "Create a helix cut"))
|
||||||
FreeCADGui.addModule("PathScripts.PathHelix")
|
FreeCADGui.addModule("PathScripts.PathHelix")
|
||||||
|
|
||||||
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython","PathHelix")
|
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", "PathHelix")
|
||||||
ObjectPathHelix(obj)
|
ObjectPathHelix(obj)
|
||||||
ViewProviderPathHelix(obj.ViewObject)
|
ViewProviderPathHelix(obj.ViewObject)
|
||||||
|
|
||||||
|
@ -477,10 +495,12 @@ class CommandPathHelix(object):
|
||||||
|
|
||||||
FreeCAD.ActiveDocument.recompute()
|
FreeCAD.ActiveDocument.recompute()
|
||||||
|
|
||||||
|
|
||||||
def print_exceptions(func):
|
def print_exceptions(func):
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
import traceback
|
import traceback
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
@wraps(func)
|
@wraps(func)
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
try:
|
try:
|
||||||
|
@ -489,8 +509,10 @@ def print_exceptions(func):
|
||||||
ex_type, ex, tb = sys.exc_info()
|
ex_type, ex, tb = sys.exc_info()
|
||||||
FreeCAD.Console.PrintError("".join(traceback.format_exception(ex_type, ex, tb)) + "\n")
|
FreeCAD.Console.PrintError("".join(traceback.format_exception(ex_type, ex, tb)) + "\n")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
def print_all_exceptions(cls):
|
def print_all_exceptions(cls):
|
||||||
for entry in dir(cls):
|
for entry in dir(cls):
|
||||||
obj = getattr(cls, entry)
|
obj = getattr(cls, entry)
|
||||||
|
@ -498,6 +520,7 @@ def print_all_exceptions(cls):
|
||||||
setattr(cls, entry, print_exceptions(obj))
|
setattr(cls, entry, print_exceptions(obj))
|
||||||
return cls
|
return cls
|
||||||
|
|
||||||
|
|
||||||
@print_all_exceptions
|
@print_all_exceptions
|
||||||
class TaskPanel(object):
|
class TaskPanel(object):
|
||||||
|
|
||||||
|
@ -594,18 +617,20 @@ class TaskPanel(object):
|
||||||
widget.setToolTip(self.obj.getDocumentationOfProperty(property))
|
widget.setToolTip(self.obj.getDocumentationOfProperty(property))
|
||||||
for option_label, option_value in options:
|
for option_label, option_value in options:
|
||||||
widget.addItem(option_label)
|
widget.addItem(option_label)
|
||||||
|
|
||||||
def change(index):
|
def change(index):
|
||||||
setattr(self.obj, property, options[index][1])
|
setattr(self.obj, property, options[index][1])
|
||||||
self.obj.Proxy.execute(self.obj)
|
self.obj.Proxy.execute(self.obj)
|
||||||
FreeCAD.ActiveDocument.recompute()
|
FreeCAD.ActiveDocument.recompute()
|
||||||
|
|
||||||
widget.currentIndexChanged.connect(change)
|
widget.currentIndexChanged.connect(change)
|
||||||
addWidgets(label, widget)
|
addWidgets(label, widget)
|
||||||
|
|
||||||
self.featureTree = QtGui.QTreeWidget()
|
self.featureTree = QtGui.QTreeWidget()
|
||||||
self.featureTree.setMinimumHeight(200)
|
self.featureTree.setMinimumHeight(200)
|
||||||
self.featureTree.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
|
self.featureTree.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
|
||||||
#self.featureTree.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
|
# self.featureTree.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
|
||||||
#self.featureTree.setDefaultDropAction(QtCore.Qt.MoveAction)
|
# self.featureTree.setDefaultDropAction(QtCore.Qt.MoveAction)
|
||||||
self.fillFeatureTree()
|
self.fillFeatureTree()
|
||||||
sm = self.featureTree.selectionModel()
|
sm = self.featureTree.selectionModel()
|
||||||
sm.selectionChanged.connect(self.selectFeatures)
|
sm.selectionChanged.connect(self.selectFeatures)
|
||||||
|
@ -622,15 +647,17 @@ class TaskPanel(object):
|
||||||
|
|
||||||
heading("Drill parameters")
|
heading("Drill parameters")
|
||||||
addCheckBox("Active", "Operation is active")
|
addCheckBox("Active", "Operation is active")
|
||||||
tool = PathUtils.getTool(self.obj,self.obj.ToolNumber)
|
tool = PathUtils.getTool(self.obj, self.obj.ToolNumber)
|
||||||
if not tool:
|
if not tool:
|
||||||
drmax = None
|
drmax = None
|
||||||
else:
|
else:
|
||||||
drmax = tool.Diameter
|
drmax = tool.Diameter
|
||||||
addQuantity("DeltaR", "Step in Radius", max=drmax)
|
addQuantity("DeltaR", "Step in Radius", max=drmax)
|
||||||
addQuantity("StepDown", "Step in Z")
|
addQuantity("StepDown", "Step in Z")
|
||||||
addEnumeration("Direction", "Cut direction", [("Clockwise", "CW"), ("Counter-Clockwise", "CCW")])
|
addEnumeration("Direction", "Cut direction",
|
||||||
addEnumeration("StartSide", "Start Side", [("Start from inside", "inside"), ("Start from outside", "outside")])
|
[("Clockwise", "CW"), ("Counter-Clockwise", "CCW")])
|
||||||
|
addEnumeration("StartSide", "Start Side",
|
||||||
|
[("Start from inside", "inside"), ("Start from outside", "outside")])
|
||||||
|
|
||||||
heading("Cutting Depths")
|
heading("Cutting Depths")
|
||||||
addQuantity("Clearance", "Clearance Distance")
|
addQuantity("Clearance", "Clearance Distance")
|
||||||
|
@ -667,7 +694,7 @@ class TaskPanel(object):
|
||||||
for base, features in cylinders_in_selection():
|
for base, features in cylinders_in_selection():
|
||||||
for feature in features:
|
for feature in features:
|
||||||
if base in features_per_base:
|
if base in features_per_base:
|
||||||
if not feature in features_per_base[base]:
|
if feature not in features_per_base[base]:
|
||||||
features_per_base[base].append(feature)
|
features_per_base[base].append(feature)
|
||||||
else:
|
else:
|
||||||
features_per_base[base] = [feature]
|
features_per_base[base] = [feature]
|
||||||
|
@ -721,7 +748,7 @@ class TaskPanel(object):
|
||||||
delete_hole(item)
|
delete_hole(item)
|
||||||
if parent.childCount() == 0:
|
if parent.childCount() == 0:
|
||||||
self.featureTree.takeTopLevelItem(self.featureTree.indexOfTopLevelItem(parent))
|
self.featureTree.takeTopLevelItem(self.featureTree.indexOfTopLevelItem(parent))
|
||||||
elif kind =="feature":
|
elif kind == "feature":
|
||||||
parent = item.parent()
|
parent = item.parent()
|
||||||
delete_feature(item)
|
delete_feature(item)
|
||||||
if parent.childCount() == 0:
|
if parent.childCount() == 0:
|
||||||
|
@ -745,7 +772,7 @@ class TaskPanel(object):
|
||||||
|
|
||||||
def fillFeatureTree(self):
|
def fillFeatureTree(self):
|
||||||
for base, features in self.obj.Features:
|
for base, features in self.obj.Features:
|
||||||
base_item = QtGui.QTreeWidgetItem()
|
base_item = QtGui.QTreeWidgetItem()
|
||||||
base_item.setText(0, base.Name)
|
base_item.setText(0, base.Name)
|
||||||
base_item.setData(0, QtCore.Qt.UserRole, ("base", base))
|
base_item.setData(0, QtCore.Qt.UserRole, ("base", base))
|
||||||
self.featureTree.addTopLevelItem(base_item)
|
self.featureTree.addTopLevelItem(base_item)
|
||||||
|
@ -758,12 +785,14 @@ class TaskPanel(object):
|
||||||
feature = by_radius[radius]
|
feature = by_radius[radius]
|
||||||
cylinder = getattr(base.Shape, feature)
|
cylinder = getattr(base.Shape, feature)
|
||||||
cyl_item = QtGui.QTreeWidgetItem()
|
cyl_item = QtGui.QTreeWidgetItem()
|
||||||
cyl_item.setText(0, "Diameter {0:.2f}, {1}".format(2 * cylinder.Surface.Radius, feature))
|
cyl_item.setText(0, "Diameter {0:.2f}, {1}".format(
|
||||||
|
2 * cylinder.Surface.Radius, feature))
|
||||||
cyl_item.setData(0, QtCore.Qt.UserRole, ("feature", feature))
|
cyl_item.setData(0, QtCore.Qt.UserRole, ("feature", feature))
|
||||||
hole_item.addChild(cyl_item)
|
hole_item.addChild(cyl_item)
|
||||||
|
|
||||||
def selectFeatures(self, selected, deselected):
|
def selectFeatures(self, selected, deselected):
|
||||||
FreeCADGui.Selection.clearSelection()
|
FreeCADGui.Selection.clearSelection()
|
||||||
|
|
||||||
def select_feature(item, base=None):
|
def select_feature(item, base=None):
|
||||||
kind, feature = item.data(0, QtCore.Qt.UserRole)
|
kind, feature = item.data(0, QtCore.Qt.UserRole)
|
||||||
assert(kind == "feature")
|
assert(kind == "feature")
|
||||||
|
@ -819,4 +848,4 @@ class TaskPanel(object):
|
||||||
|
|
||||||
if FreeCAD.GuiUp:
|
if FreeCAD.GuiUp:
|
||||||
import FreeCADGui
|
import FreeCADGui
|
||||||
FreeCADGui.addCommand('Path_Helix',CommandPathHelix())
|
FreeCADGui.addCommand('Path_Helix', CommandPathHelix())
|
||||||
|
|
Loading…
Reference in New Issue
Block a user