diff --git a/src/Mod/PartDesign/CMakeLists.txt b/src/Mod/PartDesign/CMakeLists.txt index 70be47ecd2..a2324aba55 100644 --- a/src/Mod/PartDesign/CMakeLists.txt +++ b/src/Mod/PartDesign/CMakeLists.txt @@ -201,20 +201,3 @@ if(BUILD_FEM) Mod/PartDesign/WizardShaft ) endif(BUILD_FEM) - -SET(FeatureHole_SRCS - FeatureHole/__init__.py - FeatureHole/HoleGui.py - FeatureHole/FeatureHole.py - FeatureHole/TaskHole.py - FeatureHole/ViewProviderHole.py - FeatureHole/Standards.py - FeatureHole/PartDesign_Hole.svg -) -SOURCE_GROUP("featurehole" FILES ${FeatureHole_SRCS}) - -SET(FeatureHole_UI - FeatureHole/TaskHole.ui -) - -SET(all_featurehole_files ${FeatureHole_SRCS} ${FeatureHole_UI}) diff --git a/src/Mod/PartDesign/FeatureHole/FeatureHole.py b/src/Mod/PartDesign/FeatureHole/FeatureHole.py deleted file mode 100644 index f4345aac07..0000000000 --- a/src/Mod/PartDesign/FeatureHole/FeatureHole.py +++ /dev/null @@ -1,483 +0,0 @@ -#/****************************************************************************** -# * Copyright (c) 2012 Jan Rheinländer * -# * * -# * This file is part of the FreeCAD CAx development system. * -# * * -# * This library is free software; you can redistribute it and/or * -# * modify it under the terms of the GNU Library General Public * -# * License as published by the Free Software Foundation; either * -# * version 2 of the License, or (at your option) any later version. * -# * * -# * This library 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 library; see the file COPYING.LIB. If not, * -# * write to the Free Software Foundation, Inc., 59 Temple Place, * -# * Suite 330, Boston, MA 02111-1307, USA * -# * * -# ******************************************************************************/ - -import FreeCAD, FreeCADGui -import Part, Sketcher, PartDesignGui -import math - -def makeVector(point): - if point.__class__ == FreeCAD.Vector: - return point - return FreeCAD.Vector(point.X, point.Y, point.Z) - -class Hole(): - "Hole feature" - App = FreeCAD - Gui = FreeCADGui - - def __init__(self, feature): - self.feature = feature - self.feature.addProperty("App::PropertyString","HoleType","Hole","Type of hole").HoleType="Depth" - self.feature.addProperty("App::PropertyBool","Threaded","Hole","Threaded hole").Threaded=False - self.feature.addProperty("App::PropertyBool","Counterbore","Hole","Counterbore hole").Counterbore=False - self.feature.addProperty("App::PropertyBool","Countersink","Hole","Countersink hole").Countersink=False - self.feature.addProperty("App::PropertyString","Norm","Hole","Name of norm").Norm="Custom" - self.feature.addProperty("App::PropertyString","NormTolerance","Hole","Tolerance field of norm").NormTolerance="medium" - self.feature.addProperty("App::PropertyLength","NormDiameter","Hole","Nominal diameter of hole").NormDiameter=4.0 - self.feature.addProperty("App::PropertyString", "ExtraNorm", "Hole", "Norm of bolt or washer used in hole").ExtraNorm="ISO 4762" - self.feature.addProperty("App::PropertyString", "NormThread", "Hole", "Norm of thread").NormThread="DIN 13-1" - self.feature.addProperty("App::PropertyString", "NormThreadFinish", "Hole", "Norm defining thread finish length").NormThreadFinish="DIN 76-2" - self.feature.addProperty("App::PropertyLength","Diameter","Hole","Diameter of hole").Diameter=5.0 - self.feature.addProperty("App::PropertyLength","Depth","Hole","Depth of hole").Depth=8.0 - self.feature.addProperty("App::PropertyLength","CounterboreDiameter","Hole","Diameter of counterbore").CounterboreDiameter=10.0 - self.feature.addProperty("App::PropertyLength","CounterboreDepth","Hole","Depth of counterbore").CounterboreDepth=4.0 - self.feature.addProperty("App::PropertyLength","CountersinkAngle","Hole","Angle of countersink").CountersinkAngle=45.0 - self.feature.addProperty("App::PropertyLength","ThreadLength","Hole","Length of thread").ThreadLength=5.0 - self.feature.addProperty("App::PropertyString","PositionType","Hole","Type of position references").PositionType="Linear" - self.feature.addProperty("App::PropertyLinkSub","Support","Hole","Support of hole feature").Support=None - self.feature.addProperty("App::PropertyLink","HoleGroove","Hole","Revolution feature creating the hole").HoleGroove=None - # Create new HoleGroove feature - body = FreeCADGui.activeView().getActiveObject("pdbody") - self.sketchaxis = self.feature.Document.addObject("PartDesign::Line", "HoleSketchAxis") - body.addFeature(self.sketchaxis) - self.Gui.ActiveDocument.hide(self.sketchaxis.Name) - self.sketchplane = self.feature.Document.addObject("PartDesign::Plane", "HoleSketchPlane") - self.sketchplane.References = (self.sketchaxis, "") - body.addFeature(self.sketchplane) - self.Gui.ActiveDocument.hide(self.sketchplane.Name) - self.sketch = self.feature.Document.addObject("Sketcher::SketchObject","HoleSketch") - self.sketch.Support = (self.sketchplane, ["front"]) - body.addFeature(self.sketch) - self.Gui.ActiveDocument.hide(self.sketch.Name) - feature.HoleGroove = feature.Document.addObject("PartDesign::Groove","HoleGroove") - feature.HoleGroove.Angle = 360.0 - feature.HoleGroove.Sketch = self.sketch - body.addFeature(feature.HoleGroove) - self.Gui.ActiveDocument.hide(feature.HoleGroove.Name) - self.feature.Proxy = self - self.oldCounterbore = False - self.oldCountersink = False - - def execute(self, feature): - if feature.Support is not None: - (support, element) = feature.Support - feature.Placement = feature.HoleGroove.Placement - shape = feature.HoleGroove.Shape.copy() - shape.Placement = FreeCAD.Placement() - feature.Shape = shape - - self.Gui.ActiveDocument.hide(support.Name) - # Copy display properties from support - featview = feature.ViewObject - suppview = support.ViewObject - for p in suppview.PropertiesList: - if not p in ["DisplayMode","BoundingBox","Proxy","RootNode","Visibility"]: - if p in featview.PropertiesList: - val = getattr(suppview,p) - setattr(featview,p,val) - if suppview.DisplayMode in featview.listDisplayModes(): - featview.DisplayMode = suppview.DisplayMode - if hasattr(suppview,"DiffuseColor") and hasattr(featview,"DiffuseColor"): - featview.DiffuseColor = suppview.DiffuseColor - - def onChanged(self, fp, prop): - #self.App.Console.PrintMessage("Change property: " + str(prop) + "\n") - if fp is None or fp.Support is None: - return - - if (prop == "HoleType" or prop == "Threaded" or prop == "Counterbore" or prop == "Countersink" - or prop == "Diameter" or prop == "Depth" - or prop == "CounterboreDiameter" or prop == "CounterboreDepth" - or prop == "CountersinkAngle"): - self.executeSketchChanged(fp) - fp.Document.recompute() - elif prop == "Support": - self.executePositionChanged(fp) - fp.Document.recompute() - - def executePositionChanged(self, fp): - "Change the position of the hole" - if fp.Support is None: - return - plane = self.feature.HoleGroove.Sketch.Support[0] - # Get support (face) - (support, elementList) = fp.Support - face = eval("support.Shape." + elementList[0]) - refs = plane.References - if len(refs) == 0: - return - - axis = plane.References[0][0] - firstTime = (len(axis.References) == 0) - if firstTime: - # Try to guess some references (using arcs or lines of the outer wire of the support face) - wire = face.OuterWire - firstLine = None - for e in wire.Edges: - if type(e.Curve) == Part.LineSegment: - if firstLine is None: - firstLine = e - firstDirection = e.Curve.EndPoint - e.Curve.StartPoint - else: - if firstDirection == e.Curve.EndPoint - e.Curve.StartPoint or firstDirection == e.Curve.StartPoint - e.Curve.EndPoint: - continue # Parallel edges - allEdges = support.Shape.Edges - firstLineIndex = -1 - secondLineIndex = -1 - for i in range(len(allEdges)): - try: - if type(allEdges[i].Curve) != Part.LineSegment: - continue - if (allEdges[i].Curve.StartPoint == firstLine.Curve.StartPoint and allEdges[i].Curve.EndPoint == firstLine.Curve.EndPoint) or (allEdges[i].Curve.EndPoint == firstLine.Curve.StartPoint and allEdges[i].Curve.StartPoint == firstLine.Curve.EndPoint): - firstLineIndex = i - elif (allEdges[i].Curve.StartPoint == e.Curve.StartPoint and allEdges[i].Curve.EndPoint == e.Curve.EndPoint) or (allEdges[i].Curve.EndPoint == e.Curve.StartPoint and allEdges[i].Curve.StartPoint == e.Curve.EndPoint): - secondLineIndex = i - if (firstLineIndex > -1) and (secondLineIndex > -1): - break - except Exception: - # Unknown curvetype GeomAbs_OtherCurve - continue - axis.References = [(support, elementList[0]), (support, "Edge" + str(firstLineIndex+1)), (support, "Edge" + str(secondLineIndex+1))] - axis.Offset = 1.0 - axis.Offset2 = 1.0 - self.feature.PositionType = "Linear" - # Place the axis approximately in the center of the face - #p = face.CenterOfMass - #l1 = Part.LineSegment(firstLine.Curve) - #l2 = Part.LineSegment(e.Curve) - #axis.Offset = p.distanceToLine(l1.StartPoint, l1.EndPoint - l1.StartPoint) - #axis.Offset2 = p.distanceToLine(l1.StartPoint, l2.EndPoint - l2.StartPoint) - # TODO: Ensure that the hole is inside the face! - break - elif type(e.Curve) == Part.Circle: - allEdges = support.Shape.Edges - for i in range(len(allEdges)): - try: - if type(allEdges[i].Curve) != Part.Circle: - continue - c = allEdges[i].Curve - if c.Center == e.Curve.Center and c.Axis == e.Curve.Axis and c.Radius == e.Curve.Radius: - axis.References = [(support, "Edge" + str(i+1))] - self.feature.PositionType = "Coaxial" - break - except: - # Unknown curvetype - continue - elif type(e.Curve) == Part.ArcOfCircle: - allEdges = support.Shape.Edges - for i in range(len(allEdges)): - try: - if type(allEdges[i].Curve) != Part.ArcOfCircle: - continue - a = allEdges[i].Curve - if a.Center == e.Curve.Center and a.Axis == e.Curve.Axis and a.Radius == e.Curve.Radius and a.FirstParameter == e.Curve.FirstParameter and a.LastParameter == e.Curve.LastParameter: - axis.References = [(support, "Edge" + str(i+1))] - self.feature.PositionType = "Coaxial" - break - except: - continue - break - - # Grab a point from the wire of the support face - axisbase = axis.Shape.Curve.StartPoint - axisdir = axis.Shape.Curve.EndPoint - axisbase - found = False - if not firstTime and len(refs) > 1: - # Try to keep the old point, to avoid the sketch plane jumping around - (obj, sub) = refs[1] - point = eval("support.Shape." + sub) - if point.Point.distanceToLine(axisbase, axisdir) > 1E-10: # TODO: Precision::Confusion() - found = True - if not found: - for p in face.OuterWire.Vertexes: - if p.Point.distanceToLine(axisbase, axisdir) > 1E-10: # TODO: Precision::Confusion() - point = p - found = True - break - if not found: - point = face.OuterWire.Vertexes[0] # Better this than nothing... and it can't actually happen, can it? - - # Find the index of the point in the support shape - allVertexes = support.Shape.Vertexes - for v in range(len(allVertexes)): - if allVertexes[v].Point == point.Point: - # Use this point and the axis to define the sketch plane - if len(refs) < 2: - refs.append((support, "Vertex" + str(v+1))) - else: - refs[1] = (support, "Vertex" + str(v+1)) - break - plane.References = refs - if firstTime: - fp.Document.recompute() # Update the Sketch Placement property - self.executeSketchChanged(fp) # Build the sketch of the hole - fp.Document.recompute() - else: - self.executeSketchChanged(fp) # Update the sketch of the hole - self.setHoleDirection(fp) - - def setHoleDirection(self, feature): - # Make sure the hole goes into the material, not out of it - sketch = feature.HoleGroove.Sketch - axis = sketch.Support[0].References[0][0] - axisbase = axis.Shape.Curve.StartPoint - axisdir = axis.Shape.Curve.EndPoint - axisbase - p1 = None - p2 = None - for v in sketch.Shape.Vertexes: - # Find the two sketch vertices that are on the sketch axis - if v.Point.distanceToLine(axisbase, axisdir) < 1E-10: # TODO: use Precision::Confusion() - if p1 is None: - p1 = v.Point - else: - p2 = v.Point - break - if p1 is not None and p2 is not None: - (support, elementList) = feature.Support - face = eval("support.Shape." + elementList[0]) - plane = face.Surface - if type(plane) != Part.Plane: - return - # Find the vertex that is on the top of the hole - if p1.distanceToPlane(plane.Position, plane.Axis) < 1E-10: - top = p1 - dir = p2 - p1 - else: - top = p2 - dir = p1 - p2 - if not support.Shape.isInside(top + dir.multiply(1E-8), 1E-10, False): - # Toggle the angle - angle = sketch.Constraints[12].Value - if angle == math.pi: - sketch.setDatum(12, 0.0) - else: - sketch.setDatum(12, math.pi) - - def executeSketchChanged(self, fp): - "Change the sketch shape of the hole" - if self.feature.HoleGroove is None: - return - if fp.HoleType == "Thru": - # TODO: Make this more stable - length = 1E+4 - else: - length = fp.Depth - radius = fp.Diameter / 2.0 - - if fp.Counterbore: - self.createOrUpdateCounterboreSketch(fp, length, radius) - elif fp.Countersink: - self.createOrUpdateCountersinkSketch(fp, length, radius) - else: - self.createOrUpdateStandardSketch(fp, length, radius) - - def createOrUpdateStandardSketch(self, fp, depth, radius): - (support, elements) = fp.Support - if fp.HoleGroove.Sketch.GeometryCount == 0: - #FreeCAD.Console.PrintMessage("Standard sketch\n") - # New sketch - sketch = fp.HoleGroove.Sketch - axis = sketch.Support[0].References[0][0] - # Geo -1,1 is the origin (Point) - # Geo -1 is the X-axis - # Geo -2 is the Y-axis - # First external geometry is -3 - sketch.addExternal(axis.Name,"LineSegment") # Geo -3: Datum axis - sketch.addExternal(support.Name, elements[0]) # Geo -4: Support face - # Note: Creating the sketch first with depth = 100.0 and then changing the constraint later seems to be more stable - tempDepth = 100.0 - # Build the sketch - sketch.addGeometry(Part.LineSegment(self.App.Vector(10.0,50.0,0),self.App.Vector(10.0,-50.0,0))) # Geo0: Rotation axis - sketch.toggleConstruction(0) - sketch.addGeometry(Part.LineSegment(self.App.Vector(10.0,-10.0,0),self.App.Vector(10.0,-30.0,0))) # Geo1: Vertical axis of hole - sketch.addConstraint(Sketcher.Constraint('PointOnObject',1,1,0))# Datum0 - sketch.addConstraint(Sketcher.Constraint('PointOnObject',1,2,0))# Datum1 - sketch.addGeometry(Part.LineSegment(self.App.Vector(10.0,-10.0,0),self.App.Vector(20.0,-10.0,0))) # Geo2: Top of hole - sketch.addConstraint(Sketcher.Constraint('Coincident',1,1,2,1)) # Datum2 - sketch.addConstraint(Sketcher.Constraint('Perpendicular',2, 1)) # Datum3 - sketch.addGeometry(Part.LineSegment(self.App.Vector(20.0,-10.0,0),self.App.Vector(20.0,-25.0,0))) # Geo3: Vertical mantle of hole - sketch.addConstraint(Sketcher.Constraint('Coincident',2,2,3,1)) # temporary - sketch.addConstraint(Sketcher.Constraint('Parallel',3, 1)) # Datum4 - sketch.addConstraint(Sketcher.Constraint('Distance',3,2,1, 10.0)) # Datum5: Radius - sketch.addConstraint(Sketcher.Constraint('Distance',3,2,2, 15.0)) # Datum6: Depth - sketch.addGeometry(Part.LineSegment(self.App.Vector(10.0,-30.0,0),self.App.Vector(20.0,-25.0,0))) # Geo4: 118 degree tip angle - sketch.addConstraint(Sketcher.Constraint('Coincident',4,1,1,2)) # Datum7 - sketch.addConstraint(Sketcher.Constraint('Coincident',4,2,3,2)) # Datum8 - # TODO: The tip angle of 118 degrees is for steel only. It should be taken from Part material data - # (as soon as that is implemented) - sketch.addConstraint(Sketcher.Constraint('Angle',4,1,1,2, 118.0/2.0 * math.pi / 180.0)) # Datum9 - # Locate at the intersection of the two external geometries - sketch.addConstraint(Sketcher.Constraint('PointOnObject',1,1,-3))# Datum10 - sketch.addConstraint(Sketcher.Constraint('PointOnObject',1,1,-4))# Datum11 - sketch.addConstraint(Sketcher.Constraint('Angle',0,1,-3, 1, 0.0))# Datum12 - # This datum is specific for this holetype, so move it to the last position - sketch.delConstraint(4) - sketch.addConstraint(Sketcher.Constraint('Coincident',2,2,3,1)) # Datum13 - fp.HoleGroove.ReferenceAxis = (sketch,['Axis0']) - if self.oldCounterbore == True: - # Remove counterbore from existing sketch - #FreeCAD.Console.PrintMessage("Counter to Standard sketch\n") - sketch = fp.HoleGroove.Sketch - sketch.delConstraint(19) - sketch.delConstraint(18) - sketch.delConstraint(17) - sketch.delConstraint(16) - sketch.delConstraint(15) - sketch.delConstraint(14) - sketch.delConstraint(13) - sketch.delGeometry(6) - sketch.delGeometry(5) - sketch.addConstraint(Sketcher.Constraint('Coincident',2,2,3,1)) # Datum13 - elif self.oldCountersink == True: - # Remove countersink from existing sketch - #FreeCAD.Console.PrintMessage("Sink to Standard sketch\n") - sketch = fp.HoleGroove.Sketch - sketch.delConstraint(16) - sketch.delConstraint(15) - sketch.delConstraint(14) - sketch.delConstraint(13) - sketch.delGeometry(5) - sketch.addConstraint(Sketcher.Constraint('Coincident',2,2,3,1)) # Datum13 - else: - # Update existing standard sketch - #FreeCAD.Console.PrintMessage("Update Standard sketch\n") - sketch = fp.HoleGroove.Sketch - sketch.setDatum(5, radius) - sketch.setDatum(6, depth) - if sketch.ExternalGeometry[1] != (support, elements[0]): - # Update the external geometry references - angle = sketch.Constraints[12].Value - sketch.delConstraint(13) - sketch.delConstraint(12) - sketch.delConstraint(11) - sketch.delExternal(1) - sketch.addExternal(support.Name, elements[0]) # Geo -4: Support face - sketch.addConstraint(Sketcher.Constraint('PointOnObject',1,1,-4))# Datum11 - sketch.addConstraint(Sketcher.Constraint('Angle',0,1,-3, 1, angle))# Datum12 - sketch.addConstraint(Sketcher.Constraint('Coincident',2,2,3,1)) # Datum13 - - self.setHoleDirection(fp) - self.oldCounterbore = False - self.oldCountersink = False - - def createOrUpdateCounterboreSketch(self, fp, depth, radius): - cradius = fp.CounterboreDiameter / 2.0 - cdepth = fp.CounterboreDepth - (support, elements) = fp.Support - - if self.oldCounterbore == True: - # Update properties of existing counterbore sketch - #FreeCAD.Console.PrintMessage("Update to Counterbore sketch\n") - sketch = fp.HoleGroove.Sketch - sketch.setDatum(5, radius) - sketch.setDatum(6, depth) - sketch.setDatum(13, cradius) - sketch.setDatum(15, cdepth) - if sketch.ExternalGeometry[1] != (support, elements[0]): - # Update the external geometry references - angle = sketch.Constraints[12].Value - sketch.delConstraint(19) - sketch.delConstraint(18) - sketch.delConstraint(17) - sketch.delConstraint(16) - sketch.delConstraint(15) - sketch.delConstraint(14) - sketch.delConstraint(13) - sketch.delConstraint(12) - sketch.delConstraint(11) - sketch.delExternal(1) - sketch.addExternal(support.Name, elements[0]) # Geo -4: Support face - sketch.addConstraint(Sketcher.Constraint('PointOnObject',1,1,-4))# Datum11 - sketch.addConstraint(Sketcher.Constraint('Angle',0,1,-3, 1, angle))# Datum12 - sketch.addConstraint(Sketcher.Constraint('Distance',2, cradius)) # Datum13 - sketch.addConstraint(Sketcher.Constraint('Coincident',2,2,5,1)) # Datum14 - sketch.addConstraint(Sketcher.Constraint('Distance',3, 1, 2, cdepth)) # Datum15 - sketch.addConstraint(Sketcher.Constraint('Parallel',5, 1)) # Datum16 - sketch.addConstraint(Sketcher.Constraint('Coincident',5,2,6,1)) # Datum17 - sketch.addConstraint(Sketcher.Constraint('Perpendicular',6, -3)) # Datum18 - sketch.addConstraint(Sketcher.Constraint('Coincident',6,2,3,1)) # Datum19 - else: - # Change standard to counterbore in existing sketch - #FreeCAD.Console.PrintMessage("Standard to Counterbore sketch\n") - sketch = fp.HoleGroove.Sketch - sketch.delConstraint(13) - sketch.addConstraint(Sketcher.Constraint('Distance',2, cradius)) # Datum13 - p2 = sketch.Geometry[2].EndPoint - sketch.addGeometry(Part.LineSegment(p2,self.App.Vector(p2.x,p2.y-20.0,0))) # Geo5: Vertical mantle of counterbore - sketch.addConstraint(Sketcher.Constraint('Coincident',2,2,5,1)) # Datum14 - sketch.addConstraint(Sketcher.Constraint('Distance',3, 1, 2, cdepth)) # Datum15 - sketch.addConstraint(Sketcher.Constraint('Parallel',5, 1)) # Datum16 - p3 = sketch.Geometry[3].StartPoint - sketch.addGeometry(Part.LineSegment(self.App.Vector(p2.x,p2.y-20.0, 0),p3)) # Geo6: bottom of counterbore - sketch.addConstraint(Sketcher.Constraint('Coincident',5,2,6,1)) # Datum17 - sketch.addConstraint(Sketcher.Constraint('Perpendicular',6, -3)) # Datum18 - sketch.addConstraint(Sketcher.Constraint('Coincident',6,2,3,1)) # Datum19 - - self.setHoleDirection(fp) - self.oldCounterbore = True - self.oldCountersink = False - - def createOrUpdateCountersinkSketch(self, fp, depth, radius): - sradius = fp.CounterboreDiameter / 2.0 - sangle = fp.CountersinkAngle * math.pi / 180.0 - (support, elements) = fp.Support - - if self.oldCountersink == True: - # Update properties of existing countersink sketch - #FreeCAD.Console.PrintMessage("Update to Countersink sketch\n") - sketch = fp.HoleGroove.Sketch - sketch.setDatum(5, radius) - sketch.setDatum(6, depth) - sketch.setDatum(13, sradius) - sketch.setDatum(15, sangle) - if sketch.ExternalGeometry[1] != (support, elements[0]): - # Update the external geometry references - angle = sketch.Constraints[12].Value - sketch.delConstraint(16) - sketch.delConstraint(15) - sketch.delConstraint(14) - sketch.delConstraint(13) - sketch.delConstraint(12) - sketch.delConstraint(11) - sketch.delExternal(1) - sketch.addExternal(support.Name, elements[0]) # Geo -4: Support face - sketch.addConstraint(Sketcher.Constraint('PointOnObject',1,1,-4))# Datum11 - sketch.addConstraint(Sketcher.Constraint('Angle',0,1,-3, 1, angle))# Datum12 - sketch.addConstraint(Sketcher.Constraint('Distance',2, sradius)) # Datum13 - sketch.addConstraint(Sketcher.Constraint('Coincident',2,2,5,1)) # Datum14 - sketch.addConstraint(Sketcher.Constraint('Angle',5,2, 1,2, sangle)) # Datum15 - sketch.addConstraint(Sketcher.Constraint('Coincident',3,1,5,2)) # Datum16 - else: - # Change standard to countersink in existing sketch - #FreeCAD.Console.PrintMessage("Standard to Countersink sketch\n") - sketch = fp.HoleGroove.Sketch - sketch.delConstraint(13) - sketch.addConstraint(Sketcher.Constraint('Distance',2, sradius)) # Datum13 - p2 = sketch.Geometry[2].EndPoint - sketch.addGeometry(Part.LineSegment(p2,self.App.Vector(p2.x,p2.y-20.0,0))) # Geo5: Chamfer of countersink - sketch.addConstraint(Sketcher.Constraint('Coincident',2,2,5,1)) # Datum14 - sketch.addConstraint(Sketcher.Constraint('Angle',5,2, 1,2, sangle)) # Datum15 - sketch.addConstraint(Sketcher.Constraint('Coincident',3,1,5,2)) # Datum16 - - self.setHoleDirection(fp) - self.oldCounterbore = False - self.oldCountersink = True diff --git a/src/Mod/PartDesign/FeatureHole/HoleGui.py b/src/Mod/PartDesign/FeatureHole/HoleGui.py deleted file mode 100644 index 55538ad2a4..0000000000 --- a/src/Mod/PartDesign/FeatureHole/HoleGui.py +++ /dev/null @@ -1,88 +0,0 @@ -#/****************************************************************************** -# * Copyright (c) 2012 Jan Rheinländer * -# * * -# * This file is part of the FreeCAD CAx development system. * -# * * -# * This library is free software; you can redistribute it and/or * -# * modify it under the terms of the GNU Library General Public * -# * License as published by the Free Software Foundation; either * -# * version 2 of the License, or (at your option) any later version. * -# * * -# * This library 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 library; see the file COPYING.LIB. If not, * -# * write to the Free Software Foundation, Inc., 59 Temple Place, * -# * Suite 330, Boston, MA 02111-1307, USA * -# * * -# ******************************************************************************/ - -import FreeCAD, FreeCADGui -import PartDesignGui -from PySide import QtCore, QtGui -from TaskHole import TaskHole -from FeatureHole import Hole -from ViewProviderHole import ViewProviderHole - -class HoleGui: - def getMainWindow(self): - "returns the main window" - # using QtGui.QApplication.activeWindow() isn't very reliable because if another - # widget than the mainwindow is active (e.g. a dialog) the wrong widget is - # returned - toplevel = QtGui.QApplication.topLevelWidgets() - for i in toplevel: - if i.metaObject().className() == "Gui::MainWindow": - return i - raise Exception("No main window found") - - "Create a new hole feature" - def Activated(self): - # Get main window - mw = self.getMainWindow() - - # Get active document - doc = FreeCAD.activeDocument() - if doc is None: - QtGui.QMessageBox.critical(mw, "No document", "A document must be open in order to create a hole feature") - return - - # Check for valid position selection - selection = FreeCADGui.Selection.getSelectionEx() - if len(selection) != 1: - QtGui.QMessageBox.critical(mw, "No position defined", "Please select a face to create the hole feature on") - return - if selection[0].DocumentName != doc.Name: - QtGui.QMessageBox.critical(mw, "Wrong document", "Please select a face in the active document") - return - # Note: For some reason setting the Support property here breaks all sorts of things. - # It is done in TaskHole.updateUI() instead - - # Show feature preview - body = FreeCADGui.activeView().getActiveObject("pdbody"); - if body is None: - QtGui.QMessageBox.critical(mw, "No active body", "Please create a body or make a body active") - return - - feature = doc.addObject("Part::FeaturePython","Hole") - hole = Hole(feature) - body.addFeature(feature) - - vp = ViewProviderHole(feature.ViewObject) - feature.touch() - FreeCAD.ActiveDocument.recompute() - # Fit view (remove after the testing phase) - FreeCADGui.SendMsgToActiveView("ViewFit") - - vp.setEdit(vp, 1) - - def GetResources(self): - IconPath = FreeCAD.ConfigGet("AppHomePath") + "Mod/PartDesign/FeatureHole/PartDesign_Hole.svg" - MenuText = 'Create a hole feature' - ToolTip = 'Create a hole feature' - return {'Pixmap' : IconPath, 'MenuText': MenuText, 'ToolTip': ToolTip} - -FreeCADGui.addCommand('PartDesign_Hole', HoleGui()) diff --git a/src/Mod/PartDesign/FeatureHole/PartDesign_Hole.svg b/src/Mod/PartDesign/FeatureHole/PartDesign_Hole.svg deleted file mode 100644 index 8d25b0919c..0000000000 --- a/src/Mod/PartDesign/FeatureHole/PartDesign_Hole.svg +++ /dev/null @@ -1,646 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - diff --git a/src/Mod/PartDesign/FeatureHole/Standards.py b/src/Mod/PartDesign/FeatureHole/Standards.py deleted file mode 100644 index 7ead8748df..0000000000 --- a/src/Mod/PartDesign/FeatureHole/Standards.py +++ /dev/null @@ -1,450 +0,0 @@ -# -*- coding: iso-8859-15 -*- -#/****************************************************************************** -# * Copyright (c) 2012 Jan Rheinländer * -# * * -# * This file is part of the FreeCAD CAx development system. * -# * * -# * This library is free software; you can redistribute it and/or * -# * modify it under the terms of the GNU Library General Public * -# * License as published by the Free Software Foundation; either * -# * version 2 of the License, or (at your option) any later version. * -# * * -# * This library 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 library; see the file COPYING.LIB. If not, * -# * write to the Free Software Foundation, Inc., 59 Temple Place, * -# * Suite 330, Boston, MA 02111-1307, USA * -# * * -# ******************************************************************************/ - -import FreeCAD - -"Standards for bore hole feature" -sources = { - "inet_arcor" : "http://home.arcor.de/maschinenelemente2-din/DIN%20EN%2020273_Durchgangsl%F6cher%20fuer%20Schrauben.PDF", - "inet_duckma" : "http://www.duckma.de/mb14/SiteDocs/DIN%20Grundlagen%20Maschinenbau.pdf", - "klein_14" : "Klein: Einführung in die DIN-Normen, 14. Auflage. Stuttgart, Teubner 2008" -} - -StandardYear = 0 -StandardTitle = 1 -StandardSource = 2 -StandardType = 3 - -standards = { -# "Standard name" : ("Year", "Title", "Source", "Type") - "DIN 13-1" : ("1999", "Metrisches ISO-Gewinde allgemeiner Anwendung (Auszug); Nennmaße für Regelgewinde", "klein_14", "thread"), - "DIN 74-A" : ("2003", "Senkungen fur Senkschrauben, ausgenommen Senkschrauben mit Kopfen nach DIN EN 27721; Form A", "klein_14", "countersink"), - "DIN 74-E" : ("2003", "Senkungen fur Senkschrauben, ausgenommen Senkschrauben mit Kopfen nach DIN EN 27721; Form E", "klein_14", "countersink"), - "DIN 74-F" : ("2003", "Senkungen fur Senkschrauben, ausgenommen Senkschrauben mit Kopfen nach DIN EN 27721; Form F", "klein_14", "countersink"), - "DIN 76-2" : ("1984", "Gewindeausläufe und Gewindefreistiche (Auszug); für Metrisches ISO-Gewinde nach DIN 13; Innengewinde (Gewindegrundlöcher)", "klein_14", "threaded"), - "DIN 974-1" : ("1991", "Senkdurchmesser für Schrauben mit Zylinderkopf; Konstruktionsmaße (Auszug)", "klein_14", "counterbore"), - "DIN 974-2" : ("1991", "Senkdurchmesser fur Sechskantschrauben und Sechskantmuttern; Konstruktionsmaße(Auszug)", "klein_14", "counterbore"), - "ISO 273" : ("1979", "Fasteners; Clearance holes for bolts and screws", "inet_arcor", "through"), - "ISO 15065" : ("2005", "Senkungen fur Senkschrauben mit Kopfform nach ISO 7721", "klein_14", "countersink") -} - -aliases = { - "ISO 273" : ("ISO 273:1979", "EN 20273:1991", "DIN EN 20273:1992", "DIN ISO 273", "DIN ISO 273/09.79"), - "ISO 15065" : ("ISO 15065:2005", "EN ISO 15065", "EN ISO 15065:2005", "DIN EN ISO 15065") -} - -standards_tolerance = ("fine", "medium", "coarse") - -standards_through = { -# "Standard name" : (Thread_dia : Hole_dia(Fine, Medium, Coarse)) - "ISO 273" : { - 1.0 : (1.1, 1.2, 1.3), - 1.2 : (1.3, 1.4, 1.5), - 1.4 : (1.5, 1.6, 1.8), - 1.6 : (1.7, 1.8, 2.0), - 1.8 : (2.0, 2.1, 2.2), - 2.0 : (2.2, 2.4, 2.6), - 2.5 : (2.7, 2.9, 3.1), - 3.0 : (3.2, 3.4, 3.6), - 3.5 : (3.7, 3.9, 4.2), - 4.0 : (4.3, 4.5, 4.8), - 4.5 : (4.8, 5.0, 5.3), - 5.0 : (5.3, 5.5, 5.8), - 6.0 : (6.4, 6.6, 7.0), - 7.0 : (7.4, 7.6, 8.0), - 8.0 : (8.4, 9.0, 10), - 10.0: (10.5, 11, 12), - 12.0: (13, 13.5, 14.5), - 14.0: (15, 15.5, 16.5), - 16.0: (17, 17.5, 18.5), - 18.0: (19, 20, 21), - 20.0: (21, 22, 24), - 22.0: (23, 24, 26), - 24.0: (25, 26, 28), - 27.0: (28, 30, 32), - 30.0: (31, 33, 35), - 33.0: (34, 36, 38), - 36.0: (37, 39, 42), - 39.0: (40, 42, 45), - 42.0: (43, 45, 48), - 45.0: (46, 48, 52), - 48.0: (50, 52, 56), - 52.0: (54, 56, 62), - 56.0: (58, 62, 66), - 60.0: (62, 66, 70), - 64.0: (66, 70, 74), - 68.0: (70, 74, 80), - 72.0: (74, 78, 82), - 76.0: (78, 82, 86), - 80.0: (82, 86, 91), - 85.0: (87, 91, 96), - 90.0: (93, 96, 101), - 95.0: (98, 101, 107), - 100.0: (104, 107, 112), - 105.0: (109, 112, 117), - 110.0: (114, 117, 121), - 115.0: (119, 122, 127), - 120.0: (124, 127, 132), - 125.0: (129, 132, 137), - 130.0: (134, 137, 144), - 140.0: (144, 147, 155), - 150.0: (155, 158, 165) - } -} - -standards_counterbore = { -# "Standard name" : {Thread_dia : counterboredia(row1, row2, row3, row4, row5, row6)} - "DIN 974-1" : { - 1.0 : (2.2, None, None, None, None, None), - 1.2 : (2.5, None, None, None, None, None), - 1.4 : (3.0, None, None, None, None, None), - 1.6 : (3.5, 3.5, None, None, None, None), - 1.8 : (3.8, None, None, None, None, None), - 2.0 : (4.4, 5.0, None, 5.5, 6, 6), - 2.5 : (5.5, 6, None, 6, 7, 7), - 3.0 : (6.5, 7, 6.5, 7, 9, 8), - 3.5 : (6.5, 8, 6.5, 8, 9, 9), - 4.0 : (8, 9, 8, 9, 10, 10), - 5.0 : (10, 11, 10, 11, 13, 13), - 6.0 : (11, 13, 11, 13, 15, 15), - 8.0 : (15, 18, 15, 16, 18, 20), - 10.0 : (18, 24, 18, 20, 24, 24), - 12.0 : (20, None, 20, 24, 26, 33), - 14.0 : (24, None, 24, 26, 30, 40), - 16.0 : (26, None, 26, 30, 33, 43), - 18.0 : (30, None, 30, 33, 36, 46), - 20.0 : (33, None, 33, 36, 40, 48), - 22.0 : (36, None, 36, 40, 43, 54), - 24.0 : (40, None, 40, 43, 48, 58), - 27.0 : (46, None, 46, 46, 54, 63), - 30.0 : (50, None, 50, 54, 61, 73), - 33.0 : (54, None, 54, None, 63, None), - 36.0 : (58, None, 58, 63, 69, None), - 42.0 : (69, None, 69, 73, 82, None), - 48.0 : (78, None, 78, 82, 98, None), - 56.0 : (93, None, 93, 93, 112, None), - 64.0 : (107, None, 107, 107, 125, None), - 72.0 : (118, None, 118, 118, 132, None), - 80.0 : (132, None, 132, 132, 150, None), - 90.0 : (145, None, 145, 145, 170, None), - 100.0:(160, None, 160, 160, 182, None) - }, - "DIN 974-2" : { - 3.0 : (11, 11, 9), - 4.0 : (13, 15, 10), - 5.0 : (15, 18, 11), - 6.0 : (18, 20, 13), - 8.0 : (24, 26, 18), - 10.0:(28, 33, 22), - 12.0:(33, 36, 26), - 14.0:(36, 43, 30), - 16.0:(40, 46, 33), - 18.0:(43, 50, 36), - 20.0:(46, 54, 40), - 22.0:(54, 61, 46), - 24.0:(58, 73, 48), - 27.0:(61, 76, 54), - 30.0:(73, 82, 61), - 33.0:(76, 89, 69), - 36.0:(82, 93, 73), - 39.0:(89, 98, 76), - 42.0:(98, 107, 82), - 45.0:(107, 112, 89) - } -} - -standards_counterbore_through = { -# Standard name : Through hole standard name - "DIN 74-A" : "ISO 273", - "DIN 74-E" : "ISO 273", # Note that the standards seems to allow tolerance class "fine" only - "DIN 74-F" : "ISO 273", - "DIN 974-1" : "ISO 273", - "DIN 974-2" : "ISO 273", - "ISO 15065" : "ISO 273" -} - -standards_counterbore_rows = { -# Row index : ( extra standards e.g. bolt used or washer used ) -# Note that DIN 7980 has been cancelled, therefore row three should not be used any more - "DIN 974-1" : { - 1 : ("ISO 1207", "ISO 4762", "DIN 6912", "DIN 7984"), - 2 : ("ISO 1580", "ISO 7045"), - 3 : ("DIN 7980", ""), # single value gives wrong iteration when collecting the standards - 4 : ("ISO 10673 type C", "DIN 6798", "DIN 6907"), - 5 : ("ISO 7089", "ISO 7090", "ISO 10673 type A"), - 6 : ("DIN 6796", "DIN 6908") - }, - "DIN 974-2" : { - 1 : ("DIN 659", "DIN 896", "DIN 3112", "DIN 3124"), - 2 : ("DIN 838", "DIN 897", "DIN 3129"), - 3 : ("tight", "") - } -} - -standards_counterbore_extradepth = { -# max Thread diameter : extra depth - 1.4 : 0.2, - 6.0 : 0.4, - 20.0 : 0.6, - 27.0 : 0.8, - 100.0 : 1.0 -} - -standards_countersink_dia = 0 -standards_countersink_angle = 1 - -standards_countersink = { -# "Standard name" : {Thread_dia : (countersinkdia, head angle)} - "DIN 74-A" : { - 1.6 : (3.7, 90.0), - 2.0 : (4.6, 90.0), - 2.5 : (5.7, 90.0), - 3.0 : (6.5, 90.0), - 3.5 : (7.6, 90.0), - 4.0 : (8.6, 90.0), - 4.5 : (9.5, 90.0), - 5.0 : (10.4, 90.0), - 5.5 : (11.4, 90.0), - 6.0 : (12.4, 90.0), - 7.0 : (14.4, 90.0), - 8.0 : (16.4, 90.0) - }, - "DIN 74-E" : { - 10.0 : (19.0, 75.0), - 12.0 : (24.0, 75.0), - 16.0 : (31.0, 75.0), - 20.0 : (34.0, 60.0), - 22.0 : (37.0, 60.0), - 24.0 : (40.0, 60.0) - }, - "DIN 74-F" : { - 3.0 : (6.94, 90.0), - 4.0 : (9.18, 90.0), - 5.0 : (11.47, 90.0), - 6.0 : (13.71, 90.0), - 8.0 : (18.25, 90.0), - 10.0 : (22.73, 90.0), - 12.0 : (27.21, 90.0), - 14.0 : (31.19, 90.0), - 16.0 : (33.39, 90.0), - 20.0 : (40.71, 90.0) - }, - "ISO 15065" : { - 2.0 : (4.4, 90.0), - 3.0 : (6.3, 90.0), - 4.0 : (9.4, 90.0), - 5.0 : (0.4, 90.0), - 6.0 : (12.6, 90.0), - 8.0 : (17.3, 90.0), - 10.0 : (20.0, 90.0) - } -} - -standards_threaded_types = ("normal", "short", "long") - -standards_threaded = { -# Standard name : { Tread pitch : threadFinish(normal, short, long) } - "DIN 76-2" : { - 0.20 : (1.3, 0.8, 2.0), - 0.25 : (1.5, 1.0, 2.4), - 0.30 : (1.8, 1.2, 2.9), - 0.35 : (2.1, 1.3, 3.3), - 0.40 : (2.3, 1.5, 3.7), - 0.45 : (2.6, 1.6, 4.1), - 0.50 : (2.8, 1.8, 4.5), - 0.60 : (3.4, 2.1, 5.4), - 0.70 : (3.8, 2.4, 6.1), - 0.75 : (4.0 , 2.5, 6.4), - 0.80 : (4.2, 2.7, 6.8), - 1.00 : (5.1, 3.2, 8.2), - 1.25 : (6.2, 3.9, 10), - 1.5 : (7.3, 4.6, 11.6), - 1.75 : (8.3, 5.2, 13.3), - 2.0 : (9.3, 5.8, 14.8), - 2.5 : (11.2, 7.0, 17.9), - 3.0 : (13.1, 8.2, 21.0), - 3.5 : (15.2, 9.5, 24.3), - 4.0 : (16.8, 10.5, 26.9), - 4.5 : (18.4, 11.5, 29.4), - 5.0 : (20.8, 13.0, 33.3), - 5.5 : (22.4, 14.0, 35.8), - 6.0 : (24.0, 15, 38.4) - } -} - -standards_threaded_thread = { -# Standard name for thread attribute : standard name for thread } - "DIN 76-2" : "DIN 13-1" -} - -standards_thread_pitch = 0 -standards_thread_flankdia = 1 -standards_thread_outercoredia = 2 -standards_thread_innercoredia = 3 -standards_thread_outerdepth = 4 -standards_thread_innerdepth = 5 -standards_thread_round = 6 - -standards_thread = { -# Standard name : { Thread diameter : (pitch, flank diameter, core diameter, thread depth outer, thread depth inner, round) } -# Note: This table only has the most common thread diameters - "DIN 13-1" : { - 1.0 : (0.25, 0.838, 0.693, 0.729, 0.153, 0.135, 0.036), - 1.1 : (0.25, 0.938, 0.793, 0.829, 0.153, 0.135, 0.036), - 1.2 : (0.25, 1.038, 0.893, 0.929, 0.153, 0.135, 0.036), - 2.0 : (0.4, 1.740, 1.509, 1.567, 0.245, 0.217, 0.058), - 3.0 : (0.5, 2.675, 2.387, 2.459, 0.307, 0.271, 0.072), - 4.0 : (0.7, 3.545, 3.141, 3.242, 0.429, 0.379, 0.101 ), - 5.0 : (0.8, 4.480, 4.019, 4.134, 0.491, 0.433, 0.115), - 6.0 : (1.0, 5.350, 4.773, 4.917, 0.613, 0.541, 0.144), - 7.0 : (1.0, 6.350, 5.773, 5.917, 0.613, 0.541, 0.144), - 8.0 : (1.25, 7.188, 6.466, 6.647, 0.767, 0.677, 0.180), - 10.0 : (1.5, 9.026, 8.160, 8.376, 0.920, 0.812, 0.217), - 12.0 : (1.75, 10.863, 9.853, 10.106, 1.074, 0.947, 0.253), - 14.0 : (2.0, 12.701, 11.546, 11.835, 1.227, 1.083, 0.289), - 16.0 : (2.0, 14.701, 13.546, 13.835, 1.227, 1.083, 0.289), - 18.0 : (2.5, 16.376, 14.933, 15.294, 1.534, 1.353, 0.361), - 20.0 : (2.5, 18.376, 16.933, 17.294, 1.534, 1.353, 0.361), - 22.0 : (2.5, 20.376, 18.933, 19.294, 1.534, 1.353, 0.361), - 24.0 : (3.0, 22.051, 20.319, 20.752, 1.840, 1.624, 0.433), - 27.0 : (3.0, 25.051, 23.319, 23.752, 1.840, 1.624, 0.433), - 30.0 : (3.5, 27.727, 25.706, 26.211, 2.147, 1.894, 0.505), - 33.0 : (3.5, 30.727, 28.706, 29.211, 2.147, 1.894, 0.505), - 36.0 : (4.0, 33.402, 31.093, 31.670, 2.454, 2.165, 0.577), - 39.0 : (4.0, 36.402, 34.093, 34.670, 2.454, 2.165, 0.577), - 42.0 : (4.5 , 39.077, 36.479, 37.129, 2.760, 2.436, 0.650), - 45.0 : (4.5, 42.077, 39.479, 40.129, 2.760, 2.436, 0.650) - } -} - -def getStandards(holetype): - "Return the names of all available standards for the given hole type" - result = [] - for key, value in standards.items(): - if value[StandardType] == holetype: - result.append(key) - - #FreeCAD.Console.PrintMessage("Number of matching standards: " + str(len(result)) + "\n") - return sorted(result) - -def getBaseDiameters(standard): - "Return the base diameters of all holes defined in the given norm" - if not standard in standards: - return [] - #FreeCAD.Console.PrintMessage("Getting diameters for " + standard + "\n") - if standards[standard][StandardType] == "through": - return standards_through[standard].keys() - elif standards[standard][StandardType] == "counterbore": - return standards_counterbore[standard].keys() - elif standards[standard][StandardType] == "countersink": - return standards_countersink[standard].keys() - elif standards[standard][StandardType] == "thread": - return standards_thread[standard].keys() - return [] - -def getThroughHoleDia(standard, threadDia, tolerance = "medium"): - if not standard in standards_through: - raise Exception("No such standard exists") - values = standards_through[standard] - if not threadDia in values: - FreeCAD.Console.PrintMessage("Warning: Diameter %f is not in %s" % (threadDia, standard)) - return values[values.keys()[0]][standards_tolerance.index(tolerance)] - return values[threadDia][standards_tolerance.index(tolerance)] - -def getThroughHoleStandard(standard): - if not standard in standards_counterbore_through: - raise Exception("No such standard exists") - return standards_counterbore_through[standard] - -def getCounterboreDia(standard, threadDia, extraStandard = ""): - if not standard in standards_counterbore: - raise Exception("No such standard exists") - values = standards_counterbore[standard] - if not threadDia in values: - FreeCAD.Console.PrintMessage("Warning: Diameter %f is not in %s" % (threadDia, standard)) - return values[values.keys()[0]][0] - row = 1 # Use row 1 by default - for r in standards_counterbore_rows[standard].keys(): - if extraStandard in standards_counterbore_rows[standard][r]: - row = r - break - return values[threadDia][row-1] - -def calcCounterboreDepth(standard, threadDia, standardBolt, standardsWashers = []): - headHeight = getBoltHead(standardBolt) - washerHeight = 0.0 - for standard in standardsWashers: - washerHeight = washerHeight + getWasherHeight(standard) - for maxThread in reverse(standards_counterbore_extradepth.keys()): - if threadDia <= maxThread: - extraDepth = standards_counterbore_extradepth[maxThread] - return headHeight + washerHeight + extraDepth - -def getRowStandards(standard): - if not standard in standards_counterbore_rows: - raise Exception("No such standard exists") - result = [] - rowdict = standards_counterbore_rows[standard] - for stds in rowdict.values(): - for std in stds: - if std != "": - result.append(std) - return result - -def getCountersinkDia(standard, threadDia): - if not standard in standards_countersink: - raise Exception("No such standard exists") - values = standards_countersink[standard] - if not threadDia in values: - FreeCAD.Console.PrintMessage("Warning: Diameter %f is not in %s" % (threadDia, standard)) - return values[values.keys()[0]][standards_countersink_dia] - return values[threadDia][standards_countersink_dia] - -def getCountersinkAngle(standard, threadDia): - if not standard in standards_countersink: - raise Exception("No such standard exists") - values = standards_countersink[standard] - if not threadDia in values: - FreeCAD.Console.PrintMessage("Warning: Diameter %f is not in %s" % (threadDia, standard)) - return values[values.keys()[0]][standards_countersink_angle] - return values[threadDia][standards_countersink_angle] - -def getThreadCoreDiameter(standard, threadDia): - if not standard in standards_thread: - raise Exception("No such standard exists") - values = standards_thread[standard] - if not threadDia in values: - FreeCAD.Console.PrintMessage("Warning: Diameter %f is not in %s" % (threadDia, standard)) - return values[values.keys()[0]][standards_thread_innercoredia] - return values[threadDia][standards_thread_innercoredia] - -def getThreadFinishLength(standard, threadDia, length = "normal"): - if not standard in standards_threaded: - raise Exception("No such standard exists") - stdThread = standards_threaded_thread[standard] - values = standards_thread[stdThread] - if not threadDia in values: - FreeCAD.Console.PrintMessage("Warning: Diameter %f is not in %s" % (threadDia, standard)) - return values[values.keys()[0]][standards_thread_pitch] - pitch = values[threadDia][standards_thread_pitch] - return standards_threaded[standard][pitch][standards_threaded_types.index(length)] diff --git a/src/Mod/PartDesign/FeatureHole/TaskHole.py b/src/Mod/PartDesign/FeatureHole/TaskHole.py deleted file mode 100644 index b519dafeaa..0000000000 --- a/src/Mod/PartDesign/FeatureHole/TaskHole.py +++ /dev/null @@ -1,660 +0,0 @@ -#/****************************************************************************** -# * Copyright (c) 2012 Jan Rheinländer * -# * * -# * This file is part of the FreeCAD CAx development system. * -# * * -# * This library is free software; you can redistribute it and/or * -# * modify it under the terms of the GNU Library General Public * -# * License as published by the Free Software Foundation; either * -# * version 2 of the License, or (at your option) any later version. * -# * * -# * This library 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 library; see the file COPYING.LIB. If not, * -# * write to the Free Software Foundation, Inc., 59 Temple Place, * -# * Suite 330, Boston, MA 02111-1307, USA * -# * * -# ******************************************************************************/ - -import FreeCAD, FreeCADGui -import Part, PartDesignGui -from PySide import QtCore, QtGui -import Standards -import os - -class TaskHole: - "Hole hole feature" - types = ["Linear", "Coaxial"] - typestr = ["Linear to two lines/planes", "Coaxial to a circle/cylinder"] - - def __init__(self, feature): - self.form = None - self.extraStandards = [] - self.feature = feature - p=os.path.realpath(__file__) - p=os.path.dirname(p) - self.ui = os.path.join(p, "TaskHole.ui") - - def accept(self): - self.feature.touch() - FreeCAD.ActiveDocument.recompute() - FreeCADGui.ActiveDocument.resetEdit() - return True - - def reject(self): - if (self.feature is not None): - self.hideFeature() # Show the support again - document = self.feature.Document - body = FreeCADGui.activeView().getActiveObject("pdbody"); - groove = self.feature.HoleGroove - sketch = groove.Sketch - plane = sketch.Support[0] - axis = plane.References[0][0] - body.removeObject(self.feature) - document.removeObject(self.feature.Name) - body.removeObject(groove) - document.removeObject(groove.Name) - body.removeObject(sketch) - try: - document.removeObject(sketch.Name) - except Exception: - pass # This always throws an exception: "Sketch support has been deleted" from SketchObject::execute() - body.removeObject(plane) - document.removeObject(plane.Name) - body.removeObject(axis) - document.removeObject(axis.Name) - FreeCADGui.ActiveDocument.resetEdit() - FreeCADGui.Control.closeDialog(self) - return True - - def isAllowedAlterDocument(self): - return False - - def isAllowedAlterView(self): - return False - - def isAllowedAlterSelection(self): - return True - - def getMainWindow(self): - "returns the main window" - # using QtGui.QApplication.activeWindow() isn't very reliable because if another - # widget than the mainwindow is active (e.g. a dialog) the wrong widget is - # returned - toplevel = QtGui.QApplication.topLevelWidgets() - for i in toplevel: - if i.metaObject().className() == "Gui::MainWindow": - return i - raise Exception("No main window found") - - def setupUi(self): - mw = self.getMainWindow() - form = mw.findChild(QtGui.QWidget, "TaskHole") - if form is None: - return - form.tabWidget = form.findChild(QtGui.QTabWidget, "tabWidget") - # Type - form.tabType = form.tabWidget.findChild(QtGui.QWidget, "tab_type") - form.buttonThru = form.tabType.findChild(QtGui.QRadioButton, "buttonThru") - form.buttonDepth = form.tabType.findChild(QtGui.QRadioButton, "buttonDepth") - form.checkThreaded = form.tabType.findChild(QtGui.QCheckBox, "checkThreaded") - form.checkCounterbore = form.tabType.findChild(QtGui.QCheckBox, "checkCounterbore") - form.checkCountersink = form.tabType.findChild(QtGui.QCheckBox, "checkCountersink") - # Norm - form.tabNorm = form.tabWidget.findChild(QtGui.QWidget, "tab_norm") - form.checkCustom = form.tabNorm.findChild(QtGui.QCheckBox, "checkCustom") - form.comboNorm = form.tabNorm.findChild(QtGui.QComboBox, "comboNorm") - for std in Standards.getStandards("through"): - form.comboNorm.addItem(std) - form.comboTolerance = form.tabNorm.findChild(QtGui.QComboBox, "comboTolerance") - for tol in Standards.standards_tolerance: - form.comboTolerance.addItem(tol) - form.comboNormDia = form.tabNorm.findChild(QtGui.QComboBox, "comboNormDia") - form.comboNormBoltWasher = form.tabNorm.findChild(QtGui.QComboBox, "comboNormBoltWasher") - # Thread - form.tabThread = form.tabWidget.findChild(QtGui.QWidget, "tab_thread") - form.comboThreadNorm = form.tabThread.findChild(QtGui.QComboBox, "comboThreadNorm") - for std in Standards.getStandards("thread"): - form.comboThreadNorm.addItem(std) - form.comboThreadDia = form.tabThread.findChild(QtGui.QComboBox, "comboThreadDia") - form.checkCustomThreadLength = form.tabThread.findChild(QtGui.QCheckBox, "checkCustomThreadLength") - form.comboFinishNorm = form.tabThread.findChild(QtGui.QComboBox, "comboFinishNorm") - for std in Standards.getStandards("threaded"): - form.comboFinishNorm.addItem(std) - # Data - form.tabData = form.tabWidget.findChild(QtGui.QWidget, "tab_data") - form.spinDiameter = form.tabData.findChild(QtGui.QDoubleSpinBox, "spinDiameter") - form.spinDepth = form.tabData.findChild(QtGui.QDoubleSpinBox, "spinDepth") - form.spinCounterboreDiameter = form.tabData.findChild(QtGui.QDoubleSpinBox, "spinCounterboreDiameter") - form.spinCounterboreDepth = form.tabData.findChild(QtGui.QDoubleSpinBox, "spinCounterboreDepth") - form.spinCountersinkAngle = form.tabData.findChild(QtGui.QDoubleSpinBox, "spinCountersinkAngle") - form.spinThreadLength = form.tabData.findChild(QtGui.QDoubleSpinBox, "spinThreadLength") - # Position - form.tabPosition = form.tabWidget.findChild(QtGui.QWidget, "tab_position") - form.comboType = form.tabPosition.findChild(QtGui.QComboBox, "comboType") - for i in self.typestr: - form.comboType.addItem(i) - form.buttonSupport = form.tabPosition.findChild(QtGui.QPushButton, "buttonSupport") - form.lineSupport = form.tabPosition.findChild(QtGui.QLineEdit, "lineSupport") - form.buttonRef1 = form.tabPosition.findChild(QtGui.QPushButton, "buttonRef1") - form.lineRef1 = form.tabPosition.findChild(QtGui.QLineEdit, "lineRef1") - form.labelRef1 = form.tabPosition.findChild(QtGui.QLabel, "labelRef1") - form.spinRef1 = form.tabPosition.findChild(QtGui.QDoubleSpinBox, "spinRef1") - form.buttonRef2 = form.tabPosition.findChild(QtGui.QPushButton, "buttonRef2") - form.lineRef2 = form.tabPosition.findChild(QtGui.QLineEdit, "lineRef2") - form.labelRef2 = form.tabPosition.findChild(QtGui.QLabel, "labelRef2") - form.spinRef2 = form.tabPosition.findChild(QtGui.QDoubleSpinBox, "spinRef2") - self.form = form - - # Connect Signals and Slots - # Type - self.form.buttonThru.toggled.connect(self.buttonThru) - self.form.buttonDepth.toggled.connect(self.buttonDepth) - self.form.checkThreaded.toggled.connect(self.checkThreaded) - self.form.checkCounterbore.toggled.connect(self.checkCounterbore) - self.form.checkCountersink.toggled.connect(self.checkCountersink) - # Norm - self.form.checkCustom.toggled.connect(self.checkCustom) - self.form.comboNorm.currentIndexChanged.connect(self.comboNorm) - self.form.comboTolerance.currentIndexChanged.connect(self.comboTolerance) - self.form.comboNormDia.currentIndexChanged.connect(self.comboNormDia) - self.form.comboNormBoltWasher.currentIndexChanged.connect(self.comboNormBoltWasher) - # Thread - self.form.comboThreadNorm.currentIndexChanged.connect(self.comboThreadNorm) - self.form.comboThreadDia.currentIndexChanged.connect(self.comboThreadDia) - self.form.checkCustomThreadLength.toggled.connect(self.checkCustomThreadLength) - self.form.comboFinishNorm.currentIndexChanged.connect(self.comboFinishNorm) - # Data - self.form.spinDiameter.valueChanged.connect(self.spinDiameter) - self.form.spinDepth.valueChanged.connect(self.spinDepth) - self.form.spinCounterboreDiameter.valueChanged.connect(self.spinCounterboreDiameter) - self.form.spinCounterboreDepth.valueChanged.connect(self.spinCounterboreDepth) - self.form.spinCountersinkAngle.valueChanged.connect(self.spinCountersinkAngle) - self.form.spinThreadLength.valueChanged.connect(self.spinThreadLength) - # Position - self.form.comboType.currentIndexChanged.connect(self.comboType) - self.form.buttonSupport.clicked.connect(self.buttonSupport) - self.form.buttonRef1.clicked.connect(self.buttonRef1) - self.form.spinRef1.valueChanged.connect(self.spinRef1) - self.form.buttonRef2.clicked.connect(self.buttonRef2) - self.form.spinRef2.valueChanged.connect(self.spinRef2) - - # Update the UI - self.updateUI() - return True - - def getRefText(self, ref): - (obj, element) = ref - if isinstance(element, basestring): - return obj.Name + ":" + element - elif isinstance(element, list): - return obj.Name + ":" + element[0] - else: - return obj.Name - - def updateUI(self): - # Type - self.form.buttonThru.setChecked(self.feature.HoleType == "Thru") - self.form.buttonDepth.setChecked(self.feature.HoleType == "Depth") - self.form.checkThreaded.setChecked(self.feature.Threaded == True) - self.form.checkCounterbore.setChecked(self.feature.Counterbore == True) - self.form.checkCountersink.setChecked(self.feature.Countersink == True) - # Norm - if self.feature.Norm == "Custom": - self.form.checkCustom.setChecked(True) - self.form.comboNorm.setEnabled(False) - self.form.comboTolerance.setEnabled(False) - self.form.comboNormDia.setEnabled(False) - self.form.comboNormBoltWasher.setEnabled(False) - else: - if self.feature.Counterbore == True: - holetype = "counterbore" - elif self.feature.Countersink == True: - holetype = "countersink" - elif self.feature.Threaded == True: - holetype = "threaded" - else: - holetype = "through" - self.form.comboNorm.setEnabled(True) - self.form.comboTolerance.setEnabled(True) - self.form.comboNormDia.setEnabled(True) - if holetype == "counterbore": - self.form.comboNormBoltWasher.setEnabled(True) - else: - self.form.comboNormBoltWasher.setEnabled(False) - # comboNorm - standards = Standards.getStandards(holetype) - self.form.comboNorm.blockSignals(True) - self.form.comboNorm.clear() - for std in standards: - self.form.comboNorm.addItem(std) - if not self.feature.Norm in standards: - self.feature.Norm = standards[0] - else: - self.form.comboNorm.setCurrentIndex(standards.index(self.feature.Norm)) - self.form.comboNorm.blockSignals(False) - # comboTolerance - self.form.comboTolerance.blockSignals(True) - self.form.comboTolerance.setCurrentIndex(Standards.standards_tolerance.index(self.feature.NormTolerance)) - self.form.comboTolerance.blockSignals(False) - # comboNormDia - diameters = sorted(Standards.getBaseDiameters(self.feature.Norm)) - self.form.comboNormDia.blockSignals(True) - self.form.comboNormDia.clear() - for dia in diameters: - self.form.comboNormDia.addItem("M%g" % dia) - if self.feature.NormDiameter in diameters: - self.form.comboNormDia.setCurrentIndex(diameters.index(self.feature.NormDiameter)) - self.form.comboNormDia.blockSignals(False) - # comboNormBoltWasher - if holetype == "counterbore": - rowStandards = sorted(Standards.getRowStandards(self.feature.Norm)) - self.form.comboNormBoltWasher.blockSignals(True) - self.form.comboNormBoltWasher.clear() - for std in rowStandards: - self.form.comboNormBoltWasher.addItem(std) - if self.feature.ExtraNorm in rowStandards: - self.form.comboNormBoltWasher.setCurrentIndex(rowStandards.index(self.feature.ExtraNorm)) - self.form.comboNormBoltWasher.blockSignals(False) - # Dependent values - if holetype == "through": - self.feature.Diameter = Standards.getThroughHoleDia(self.feature.Norm, self.feature.NormDiameter, self.feature.NormTolerance) - elif holetype == "counterbore": - throughStandard = Standards.getThroughHoleStandard(self.feature.Norm) - self.feature.Diameter = Standards.getThroughHoleDia(throughStandard, self.feature.NormDiameter, self.feature.NormTolerance) - self.feature.CounterboreDiameter = Standards.getCounterboreDia(self.feature.Norm, self.feature.NormDiameter, self.feature.ExtraNorm) - # TODO: Calculate counter bore depth from standard for bolt and washer(s) - # Requires accessing all the norms for bolts - # self.feature.CounterboreDepth = calcCounterboreDepth(...) - elif holetype == "countersink": - throughStandard = Standards.getThroughHoleStandard(self.feature.Norm) - self.feature.Diameter = Standards.getThroughHoleDia(throughStandard, self.feature.NormDiameter, self.feature.NormTolerance) - self.feature.CounterboreDiameter = Standards.getCountersinkDia(self.feature.Norm, self.feature.NormDiameter) - self.feature.CountersinkAngle = Standards.getCountersinkAngle(self.feature.Norm, self.feature.NormDiameter) / 2.0 - # Thread - if self.feature.Threaded == True: - if not self.feature.Counterbore and not self.feature.Countersink: - self.form.comboTolerance.setEnabled(False) - else: - self.form.tabNorm.setEnabled(True) - self.form.comboTolerance.setEnabled(False) - self.form.tabThread.setEnabled(True) - self.form.comboThreadNorm.blockSignals(True) - standards = Standards.getStandards("thread") - if not self.feature.NormThread in standards: - self.feature.NormThread = standards[0] - else: - self.form.comboThreadNorm.setCurrentIndex(standards.index(self.feature.NormThread)) - self.form.comboThreadNorm.blockSignals(False) - threadDiameters = sorted(Standards.getBaseDiameters(self.feature.NormThread)) - self.form.comboThreadDia.blockSignals(True) - self.form.comboThreadDia.clear() - for dia in threadDiameters: - self.form.comboThreadDia.addItem("M%g" % dia) - if self.feature.NormDiameter in threadDiameters: - self.form.comboThreadDia.setCurrentIndex(threadDiameters.index(self.feature.NormDiameter)) - self.form.comboThreadDia.blockSignals(False) - if self.feature.NormThreadFinish == "Custom": - self.form.checkCustomThreadLength.setChecked(True) - self.form.comboFinishNorm.setEnabled(False) - else: - self.form.checkCustomThreadLength.setChecked(False) - self.form.comboFinishNorm.setEnabled(True) - self.form.comboFinishNorm.blockSignals(True) - standards = Standards.getStandards("threaded") - if not self.feature.NormThreadFinish in standards: - self.feature.NormThreadFinish = standards[0] - else: - self.form.comboFinishNorm.setCurrentIndex(standards.index(self.feature.NormThreadFinish)) - self.form.comboFinishNorm.blockSignals(False) - flength = Standards.getThreadFinishLength(self.feature.NormThreadFinish, self.feature.NormDiameter) - tlength = self.feature.Depth - flength - if tlength > 0: - self.feature.ThreadLength = tlength # TODO: Warning message - # Dependents - self.feature.Diameter = Standards.getThreadCoreDiameter(self.feature.NormThread, self.feature.NormDiameter) - else: - self.form.tabThread.setEnabled(False) - # Dependents - self.form.spinDiameter.setEnabled(True) - # Data - self.form.spinDiameter.setValue(self.feature.Diameter) - self.form.spinDepth.setValue(self.feature.Depth) - if self.feature.HoleType == "Thru": - self.form.spinDepth.setEnabled(False) - else: - self.form.spinDepth.setEnabled(True) - if self.feature.Threaded == True: - self.form.spinThreadLength.setEnabled(True) - else: - self.form.spinThreadLength.setEnabled(False) - if self.feature.Counterbore == True: - self.form.spinCounterboreDiameter.setEnabled(True) - self.form.spinCounterboreDiameter.setValue(self.feature.CounterboreDiameter) - self.form.spinCounterboreDepth.setEnabled(True) - self.form.spinCounterboreDepth.setValue(self.feature.CounterboreDepth) - self.form.spinCountersinkAngle.setEnabled(False) - elif self.feature.Countersink == True: - self.form.spinCounterboreDiameter.setEnabled(True) - self.form.spinCounterboreDiameter.setValue(self.feature.CounterboreDiameter) - self.form.spinCounterboreDepth.setEnabled(False) - self.form.spinCountersinkAngle.setEnabled(True) - self.form.spinCountersinkAngle.setValue(self.feature.CountersinkAngle) - else: - self.form.spinCounterboreDiameter.setEnabled(False) - self.form.spinCounterboreDepth.setEnabled(False) - self.form.spinCountersinkAngle.setEnabled(False) - if self.feature.Norm == "Custom": - self.form.spinDiameter.setEnabled(True) - else: - self.form.spinDiameter.setEnabled(False) - if holetype == "counterbore": - # Diameter is taken from Norm - self.form.spinCounterboreDiameter.setEnabled(False) - elif holetype == "countersink": - # Values are taken from Norm - self.form.spinCounterboreDiameter.setEnabled(False) - self.form.spinCounterboreDepth.setEnabled(False) - self.form.spinCountersinkAngle.setEnabled(False) - if self.feature.Threaded == True: - self.form.spinDiameter.setEnabled(False) - if self.feature.NormThreadFinish != "Custom": - self.form.spinThreadLength.setEnabled(False) - self.form.spinThreadLength.setValue(self.feature.ThreadLength) - # Position - self.form.buttonSupport.setText("Face") - if self.feature.Support is None: - # First-time initialization - selection = FreeCADGui.Selection.getSelectionEx() - self.feature.Support = (selection[0].Object, selection[0].SubElementNames) - self.form.lineSupport.setText(self.getRefText(self.feature.Support)) - if self.feature.PositionType == self.types[0]: - # Linear - self.form.buttonRef1.setText("Line/Plane") - self.form.buttonRef1.setEnabled(True) - self.form.buttonRef2.setText("Line/Plane") - self.form.buttonRef2.setEnabled(True) - self.form.lineRef1.setEnabled(True) - self.form.lineRef2.setEnabled(True) - self.form.labelRef1.setEnabled(True) - self.form.labelRef1.setText("Distance") - axis = self.feature.HoleGroove.Sketch.Support[0].References[0][0] - if len(axis.References) > 0 and axis.References[0] is not None: - if (len(axis.References) == 3): - self.form.lineRef1.setText(self.getRefText(axis.References[1])) - else: - self.form.lineRef1.setText(self.getRefText(axis.References[0])) - self.form.spinRef1.setEnabled(True) - self.form.spinRef1.setValue(axis.Offset) - self.form.labelRef2.setEnabled(True) - self.form.labelRef2.setText("Distance") - if len(axis.References) > 1 and axis.References[1] is not None: - if (len(axis.References) == 3): - self.form.lineRef2.setText(self.getRefText(axis.References[2])) - else: - self.form.lineRef2.setText(self.getRefText(axis.References[1])) - self.form.spinRef2.setEnabled(True) - self.form.spinRef2.setValue(axis.Offset2) - elif self.feature.PositionType == self.types[1]: - # Coaxial - self.form.buttonRef1.setText("Circle/Cylinder") - self.form.buttonRef1.setEnabled(True) - self.form.buttonRef2.setEnabled(False) - self.form.lineRef1.setEnabled(True) - axis = self.feature.HoleGroove.Sketch.Support[0].References[0][0] - if len(axis.References) > 0 and axis.References[0] is not None: - self.form.lineRef1.setText(self.getRefText(axis.References[0])) - self.form.lineRef2.setEnabled(False) - self.form.labelRef1.setEnabled(False) - self.form.spinRef1.setEnabled(False) - self.form.labelRef2.setEnabled(False) - self.form.spinRef2.setEnabled(False) - else: - # Nothing else defined yet - pass - - def getStandardButtons(self): - return int(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) - - def accept(self): - return True - - def buttonThru(self, toggle): - if toggle == True: - self.feature.HoleType = "Thru" - - def buttonDepth(self, toggle): - if toggle == True: - self.feature.HoleType = "Depth" - - def checkThreaded(self, checked): - self.feature.Threaded = checked - self.updateUI() - - def checkCounterbore(self, checked): - if checked == True: - self.feature.Countersink = False - self.feature.Counterbore = checked - self.updateUI() - - def checkCountersink(self, checked): - if checked == True: - self.feature.Counterbore = False - self.feature.Countersink = checked - self.updateUI() - - def checkCustom(self, checked): - if checked == True: - self.feature.Norm = "Custom" - else: - self.feature.Norm = str(self.form.comboNorm.currentText()) - self.updateUI() - - def comboNorm(self, index): - self.feature.Norm = str(self.form.comboNorm.itemText(index)) - self.updateUI() - - def comboTolerance(self, index): - self.feature.NormTolerance = str(self.form.comboTolerance.itemText(index)) - self.updateUI() - - def comboNormDia(self, index): - diameter = str(self.form.comboNormDia.itemText(index)) - self.feature.NormDiameter = float(diameter[1:]) - self.updateUI() - - def comboNormBoltWasher(self, index): - self.feature.ExtraNorm = str(self.form.comboNormBoltWasher.itemText(index)) - self.updateUI() - - def comboThreadNorm(self, index): - self.feature.NormThread = str(self.form.comboThreadNorm.itemText(index)) - self.updateUI() - - def comboThreadDia(self, index): - diameter = str(self.form.comboThreadDia.itemText(index)) - self.feature.NormDiameter = float(diameter[1:]) - self.updateUI() - - def checkCustomThreadLength(self, checked): - if checked == True: - self.feature.NormThreadFinish = "Custom" - else: - self.feature.NormThreadFinish = str(self.form.comboFinishNorm.currentText()) - self.updateUI() - - def comboFinishNorm(self, index): - self.feature.NormThreadFinish = str(self.form.comboFinishNorm.itemText(index)) - self.updateUI() - - def spinDiameter(self, val): - if (val > 0.0): - self.feature.Diameter = val - - def spinDepth(self, val): - if (val > 0.0): - self.feature.Depth = val - self.updateUI() # required to update the thread length - - def spinCounterboreDiameter(self, val): - if (val > self.feature.Diameter): - self.feature.CounterboreDiameter = val - - def spinCounterboreDepth(self, val): - if (val > 0.0): - self.feature.CounterboreDepth = val - - def spinCountersinkAngle(self, val): - if (val > 0.0): - self.feature.CountersinkAngle = val - - def spinThreadLength(self, val): - if (val > 0.0): - self.feature.ThreadLength = val - - def comboType(self, index): - self.feature.PositionType = self.types[index] - self.updateUI() - - def addSelection(self, document, obj, element, position): - #FreeCAD.Console.PrintMessage("AddSelection() for " + document + "." + obj + "." + element + "\n") - # TODO: What is the position parameter? - if document == self.feature.Document.Name: - axis = self.feature.HoleGroove.Sketch.Support[0].References[0][0] - refs = axis.References - feature = eval("FreeCAD.getDocument('" + document + "')." + obj) - shape = eval("feature.Shape." + element) - if self.selectionMode == "Plane": - if shape.Surface.__class__ != Part.Plane: - FreeCAD.Console.PrintMessage("Selected face must be planar\n") - return - if self.feature.PositionType == self.types[0]: - # The Hole support is also the first reference of the sketch axis in Linear mode with edges selected - if len(refs) == 3: - refs[0] = (feature, element) - axis.References = refs - self.feature.Support = (feature, [element]) - elif self.selectionMode == "LinearReference": - if shape.ShapeType == "Edge": - if shape.Curve.__class__ != Part.LineSegment: - FreeCAD.Console.PrintMessage("Selected edge must be linear\n") - return - if len(refs) > 1: - refs[1] = (feature, element) - else: - refs.append((feature, element)) - elif shape.ShapeType == "Face": - if shape.Surface.__class__ != Part.Plane: - FreeCAD.Console.PrintMessage("Selected face must be planar\n") - return - if len(refs) > 0: - if len(refs) > 2: - refs = [(feature, element)] - else: - refs[0] = (feature, element) - else: - refs = [(feature, element)] - else: - FreeCAD.Console.PrintMessage("Wrong shape type selected\n") - return - axis.References = refs - axis.Document.recompute() - elif self.selectionMode == "LinearReference2": - if shape.ShapeType == "Edge": - if shape.Curve.__class__ != Part.LineSegment: - FreeCAD.Console.PrintMessage("Selected edge must be linear\n") - return - if len(refs) > 2: - refs[2] = (feature, element) - else: - refs.append((feature, element)) - elif shape.ShapeType == "Face": - if shape.Surface.__class__ != Part.Plane: - FreeCAD.Console.PrintMessage("Selected face must be planar\n") - return - if len(refs) > 1: - if len(refs) > 2: - del refs[2] - refs[1] = (feature, element) - else: - refs.append((feature, element)) - else: - FreeCAD.Console.PrintMessage("Wrong shape type selected\n") - return - axis.References = refs - axis.Document.recompute() - elif self.selectionMode == "CircularReference": - if shape.ShapeType == "Edge": - if shape.Curve.__class__ != Part.Circle: - FreeCAD.Console.PrintMessage("Selected edge must be arc or circle\n") - return - elif shape.ShapeType == "Face": - if shape.Surface.__class__ != Part.Cylinder: - FreeCAD.Console.PrintMessage("Selected face must be cylindrical\n") - return - else: - FreeCAD.Console.PrintMessage("Wrong shape type selected\n") - return - refs = [(feature, element)] - axis.References = refs - axis.Document.recompute() - else: - FreeCAD.Console.PrintMessage("Unknown selection mode: " + self.selectionMode + "\n") - self.selectionMode = "" - return - - FreeCADGui.Selection.removeObserver(self) - FreeCADGui.Selection.clearSelection() - FreeCADGui.Selection.removeSelectionGate() - self.selectionMode = "" - self.updateUI() - self.showFeature() - - def hideFeature(self): - # Make sure selection takes place on support, not on hole feature - if self.feature.Support is not None: - FreeCADGui.ActiveDocument.hide(self.feature.Name) - (support, elements) = self.feature.Support - FreeCADGui.ActiveDocument.show(support.Name) - - def showFeature(self): - if self.feature.Support is not None: - FreeCADGui.ActiveDocument.show(self.feature.Name) - (support, elements) = self.feature.Support - FreeCADGui.ActiveDocument.hide(support.Name) - - def buttonSupport(self): - FreeCADGui.Selection.addSelectionGate("SELECT Part::Feature SUBELEMENT Face COUNT 1") - FreeCADGui.Selection.addObserver(self) - # Currently support must be a planar face (but could also be a point or a construction plane in the future) - self.selectionMode = "Plane" - self.hideFeature() - - def buttonRef1(self): - FreeCADGui.Selection.addSelectionGate("SELECT Part::Feature SUBELEMENT Edge COUNT 1 SELECT Part::Feature SUBELEMENT Face COUNT 1") - FreeCADGui.Selection.addObserver(self) - if self.feature.PositionType == self.types[0]: - self.selectionMode = "LinearReference" - elif self.feature.PositionType == self.types[1]: - self.selectionMode = "CircularReference" - self.hideFeature() - - def buttonRef2(self): - FreeCADGui.Selection.addSelectionGate("SELECT Part::Feature SUBELEMENT Edge COUNT 1 SELECT Part::Feature SUBELEMENT Face COUNT 1") - FreeCADGui.Selection.addObserver(self) - self.selectionMode = "LinearReference2" - self.hideFeature() - - def spinRef1(self, val): - axis = self.feature.HoleGroove.Sketch.Support[0].References[0][0] - axis.Offset = val - axis.Document.recompute() - - def spinRef2(self, val): - axis = self.feature.HoleGroove.Sketch.Support[0].References[0][0] - axis.Offset2 = val - axis.Document.recompute() diff --git a/src/Mod/PartDesign/FeatureHole/TaskHole.ui b/src/Mod/PartDesign/FeatureHole/TaskHole.ui deleted file mode 100644 index 97fa846e85..0000000000 --- a/src/Mod/PartDesign/FeatureHole/TaskHole.ui +++ /dev/null @@ -1,598 +0,0 @@ - - - TaskHole - - - - 0 - 0 - 327 - 315 - - - - Form - - - - - - 0 - - - - Position - - - - - - - - - - - Face - - - - - - - - - - - - - - Edge - - - - - - - - - - - - - - Distance - - - - - - - -99999.000000000000000 - - - 99999.000000000000000 - - - 5.000000000000000 - - - - - - - - - - - Edge - - - - - - - - - - - - - - Distance - - - - - - - -99999.000000000000000 - - - 99999.000000000000000 - - - 5.000000000000000 - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - Type - - - - - - - - Through - - - - - - - Depth - - - - - - - - - Threaded - - - - - - - Countersink - - - - - - - Counterbore - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - Hole norm - - - - - - Custom dimensions - - - - - - - false - - - - - - - - - Tolerance - - - - - - - false - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - Diameter - - - - - - - false - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - Bolt/Washer - - - - - - - - 150 - 0 - - - - false - - - - - - - Qt::Horizontal - - - - 20 - 20 - - - - - - - - - - Qt::Vertical - - - - 20 - 125 - - - - - - - - - Thread norm - - - - - - - - Thread norm - - - - - - - false - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - Diameter - - - - - - - false - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - Custom thread length - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - Finish depth - - - - - - - false - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Qt::Vertical - - - - 20 - 81 - - - - - - - - - Data - - - - - - - - Diameter - - - - - - - 8.000000000000000 - - - - - - - - - - - Depth - - - - - - - 20.000000000000000 - - - - - - - - - - - Counterbore/sink dia - - - - - - - 15.000000000000000 - - - - - - - - - - - Counterbore depth - - - - - - - 7.000000000000000 - - - - - - - - - - - Countersink angle - - - - - - - 15.000000000000000 - - - - - - - - - - - Thread length - - - - - - - 5.000000000000000 - - - - - - - - - Qt::Vertical - - - - 20 - 3 - - - - - - - - - - - - - diff --git a/src/Mod/PartDesign/FeatureHole/ViewProviderHole.py b/src/Mod/PartDesign/FeatureHole/ViewProviderHole.py deleted file mode 100644 index 2c6b83fd7b..0000000000 --- a/src/Mod/PartDesign/FeatureHole/ViewProviderHole.py +++ /dev/null @@ -1,97 +0,0 @@ -#/****************************************************************************** -# * Copyright (c) 2012 Jan Rheinländer * -# * * -# * This file is part of the FreeCAD CAx development system. * -# * * -# * This library is free software; you can redistribute it and/or * -# * modify it under the terms of the GNU Library General Public * -# * License as published by the Free Software Foundation; either * -# * version 2 of the License, or (at your option) any later version. * -# * * -# * This library 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 library; see the file COPYING.LIB. If not, * -# * write to the Free Software Foundation, Inc., 59 Temple Place, * -# * Suite 330, Boston, MA 02111-1307, USA * -# * * -# ******************************************************************************/ - -import FreeCAD, FreeCADGui -from TaskHole import TaskHole - -class ViewProviderHole: - def __init__(self, obj): - ''' Set this object to the proxy object of the actual view provider ''' - obj.Proxy = self - self.Object = obj.Object - - def attach(self, obj): - ''' Setup the scene sub-graph of the view provider, this method is mandatory ''' - return - - def claimChildren(self): - if self is None: - return - # The following statement leads to the error: - # : PyCXX: Error creating object of type N2Py7SeqBaseINS_6ObjectEEE from None - if not hasattr(self, "Object"): - return - - if self.Object is not None: - return [self.Object.HoleGroove, # the groove feature - self.Object.HoleGroove.Sketch.Support[0], # the groove sketchplane (datum plane) feature - self.Object.HoleGroove.Sketch.Support[0].References[0][0]] # the sketchplane first reference (datum line) - - def updateData(self, fp, prop): - ''' If a property of the handled feature has changed we have the chance to handle this here ''' - return - - def getDisplayModes(self,obj): - ''' Return a list of display modes. ''' - modes=[] - return modes - - def getDefaultDisplayMode(self): - ''' Return the name of the default display mode. It must be defined in getDisplayModes. ''' - return "Shaded" - - def onChanged(self, vp, prop): - ''' Print the name of the property that has changed ''' - #FreeCAD.Console.PrintMessage("Change property: " + str(prop) + "\n") - pass - - def setEdit(self,vp,mode): - panel = TaskHole(self.Object) - - FreeCADGui.Control.showDialog(panel) - if not panel.setupUi(): - FreeCADGui.Control.closeDialog(panel) - return False - - return True - - def unsetEdit(self,vp,mode): - return - - def getIcon(self): - ''' Return the icon in XMP format which will appear in the tree view. This method is optional - and if not defined a default icon is shown. - ''' - return "" - - def __getstate__(self): - ''' When saving the document this object gets stored using Python's cPickle module. - Since we have some un-pickable here -- the Coin stuff -- we must define this method - to return a tuple of all pickable objects or None. - ''' - return None - - def __setstate__(self,state): - ''' When restoring the pickled object from document we have the chance to set some - internals here. Since no data were pickled nothing needs to be done here. - ''' - return None diff --git a/src/Mod/PartDesign/FeatureHole/__init__.py b/src/Mod/PartDesign/FeatureHole/__init__.py deleted file mode 100644 index 42b9e7d623..0000000000 --- a/src/Mod/PartDesign/FeatureHole/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -""" -Hole Feature -""" - -#/****************************************************************************** -# * Copyright (c) 2012 Jan Rheinländer * -# * * -# * This file is part of the FreeCAD CAx development system. * -# * * -# * This library is free software; you can redistribute it and/or * -# * modify it under the terms of the GNU Library General Public * -# * License as published by the Free Software Foundation; either * -# * version 2 of the License, or (at your option) any later version. * -# * * -# * This library 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 library; see the file COPYING.LIB. If not, * -# * write to the Free Software Foundation, Inc., 59 Temple Place, * -# * Suite 330, Boston, MA 02111-1307, USA * -# * * -# ******************************************************************************/ - -# Empty file to treat the folder as a package -# Initialize eric to do code completion for freecad libs -# import sys -# sys.path.append("/home/jan/freizeit/freecad-build-dbg/lib")