Download src/Mod/PartDesign/PartDesignTests/TestHole.py from AbdulElahGwaith/FreeCAD: direct link, hf CLI and curl.
- Browser
- Download file 20.9 kB
-
https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/PartDesign/PartDesignTests/TestHole.py
- Command line
-
hf download hf://AbdulElahGwaith/FreeCAD/src/Mod/PartDesign/PartDesignTests/TestHole.py
-
curl -L -o TestHole.py https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/PartDesign/PartDesignTests/TestHole.py
20.9 kB
| # ************************************************************************** | |
| # Copyright (c) 2017 Kurt Kremitzki <kkremitzki@gmail.com> * | |
| # * | |
| # This file is part of the FreeCAD CAx development system. * | |
| # * | |
| # This program is free software; you can redistribute it and/or modify * | |
| # it under the terms of the GNU Lesser General Public License (LGPL) * | |
| # as published by the Free Software Foundation; either version 2 of * | |
| # the License, or (at your option) any later version. * | |
| # for detail see the LICENCE text file. * | |
| # * | |
| # FreeCAD 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 FreeCAD; if not, write to the Free Software * | |
| # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * | |
| # USA * | |
| # ************************************************************************** | |
| from math import pi | |
| import unittest | |
| import FreeCAD | |
| import TestSketcherApp | |
| App = FreeCAD | |
| class TestHole(unittest.TestCase): | |
| def setUp(self): | |
| self.Doc = FreeCAD.newDocument("PartDesignTestHole") | |
| self.Body = self.Doc.addObject("PartDesign::Body", "Body") | |
| self.Box = self.Doc.addObject("PartDesign::AdditiveBox", "Box") | |
| self.Box.Length = 10 | |
| self.Box.Width = 10 | |
| self.Box.Height = 10 | |
| self.Body.addObject(self.Box) | |
| self.Doc.recompute() | |
| self.HoleSketch = self.Doc.addObject("Sketcher::SketchObject", "SketchHole") | |
| self.HoleSketch.AttachmentSupport = (self.Doc.XY_Plane, [""]) | |
| self.HoleSketch.MapMode = "FlatFace" | |
| self.HoleSketch.MapReversed = True | |
| self.Body.addObject(self.HoleSketch) | |
| TestSketcherApp.CreateCircleSketch(self.HoleSketch, (-5, 5), 1) | |
| self.Doc.recompute() | |
| self.Hole = self.Doc.addObject("PartDesign::Hole", "Hole") | |
| self.Hole.Profile = self.HoleSketch | |
| self.Body.addObject(self.Hole) | |
| self.Doc.recompute() | |
| def testPlainHole(self): | |
| self.Hole.Diameter = 6 | |
| self.Hole.Depth = 10 | |
| # self.Hole.DrillPointAngle = 118.000000 | |
| # self.Hole.TaperedAngle = 90 | |
| self.Hole.ThreadType = 0 | |
| self.Hole.HoleCutType = 0 # 1 = Counterbore, 2 = Countersink | |
| # self.Hole.HoleCutDiameter = 5 | |
| # self.Hole.HoleCutCountersinkAngle = 90 | |
| # self.Hole.HoleCutDepth = 2 # Counterbore | |
| self.Hole.DepthType = 0 # 1 = Through all | |
| self.Hole.DrillPoint = 0 # 1 = Angled | |
| self.Hole.Tapered = 0 # On/off | |
| self.Doc.recompute() | |
| self.assertAlmostEqual(self.Hole.Shape.Volume, 10**3 - pi * 3**2 * 10) | |
| def testTaperedHole(self): | |
| self.Hole.Diameter = 6 | |
| self.Hole.Depth = 5 | |
| self.Hole.TaperedAngle = 60 | |
| self.Hole.ThreadType = 0 | |
| self.Hole.HoleCutType = 0 | |
| self.Hole.DepthType = 0 | |
| self.Hole.DrillPoint = 0 | |
| self.Hole.Tapered = 1 | |
| self.Doc.recompute() | |
| self.assertEqual(len(self.Hole.Shape.Faces), 8) | |
| def testAngledDrillHole(self): | |
| self.Hole.Diameter = 6 | |
| self.Hole.Depth = 10 | |
| self.Hole.DrillPointAngle = 118 | |
| self.Hole.ThreadType = 0 | |
| self.Hole.HoleCutType = 0 | |
| self.Hole.DepthType = 0 | |
| self.Hole.DrillPoint = 1 | |
| self.Hole.Tapered = 0 | |
| self.Hole.DrillForDepth = 1 | |
| self.Doc.recompute() | |
| self.assertEqual(len(self.Hole.Shape.Faces), 8) | |
| def testCounterboreHole(self): | |
| self.Hole.Diameter = 6 | |
| self.Hole.Depth = 10 | |
| self.Hole.ThreadType = 0 | |
| self.Hole.HoleCutType = 1 | |
| self.Hole.HoleCutDiameter = 8 | |
| self.Hole.HoleCutDepth = 5 | |
| self.Hole.DepthType = 0 | |
| self.Hole.DrillPoint = 0 | |
| self.Hole.Tapered = 0 | |
| self.Doc.recompute() | |
| self.assertAlmostEqual(self.Hole.Shape.Volume, 10**3 - pi * 3**2 * 5 - pi * 4**2 * 5) | |
| def testCountersinkHole(self): | |
| self.Hole.Diameter = 6 | |
| self.Hole.Depth = 10 | |
| self.Hole.ThreadType = 0 | |
| self.Hole.HoleCutType = 2 | |
| self.Hole.HoleCutDiameter = 9 | |
| self.Hole.HoleCutCountersinkAngle = 90 | |
| self.Hole.DepthType = 0 | |
| self.Hole.DrillPoint = 0 | |
| self.Hole.Tapered = 0 | |
| self.Doc.recompute() | |
| self.assertAlmostEqual(self.Hole.Shape.Volume, 10**3 - pi * 3**2 * 10 - 24.7400421) | |
| def testNoRefineHole(self): | |
| # Add a second box to get a shape with more faces | |
| self.Box2 = self.Doc.addObject("PartDesign::AdditiveBox", "Box") | |
| self.Box2.Length = 10 | |
| self.Box2.Width = 10 | |
| self.Box2.Height = 10 | |
| self.Box2.AttacherEngine = "Engine 3D" | |
| self.Box2.AttachmentOffset = App.Placement( | |
| App.Vector(1.0000000000, 0.0000000000, 0.0000000000), | |
| App.Rotation(0.0000000000, 0.0000000000, 0.0000000000), | |
| ) | |
| self.Box2.MapReversed = False | |
| self.Box2.AttachmentSupport = self.Doc.getObject("XY_Plane") | |
| self.Box2.MapPathParameter = 0.000000 | |
| self.Box2.MapMode = "FlatFace" | |
| # Set the Refine option to False, otherwise adding the second box would be useless | |
| self.Box2.Refine = False | |
| self.Body.addObject(self.Box2) | |
| self.Doc.recompute() | |
| # Move the Hole on top of the Body | |
| self.Body.removeObject(self.Hole) | |
| self.Body.insertObject(self.Hole, self.Box2, True) | |
| self.Body.Tip = self.Hole | |
| self.Hole.Diameter = 6 | |
| self.Hole.Depth = 10 | |
| self.Hole.ThreadType = 0 | |
| self.Hole.HoleCutType = 0 | |
| self.Hole.DepthType = 0 | |
| self.Hole.DrillPoint = 0 | |
| self.Hole.Tapered = 0 | |
| self.Hole.Visibility = True | |
| # Test the number of faces with the Refine option set to False | |
| self.Hole.Refine = False | |
| self.Doc.recompute() | |
| self.assertEqual(len(self.Hole.Shape.Faces), 15) | |
| def testRefineHole(self): | |
| # Add a second box to get a shape with more faces | |
| self.Box2 = self.Doc.addObject("PartDesign::AdditiveBox", "Box") | |
| self.Box2.Length = 10 | |
| self.Box2.Width = 10 | |
| self.Box2.Height = 10 | |
| self.Box2.AttacherEngine = "Engine 3D" | |
| self.Box2.AttachmentOffset = App.Placement( | |
| App.Vector(1.0000000000, 0.0000000000, 0.0000000000), | |
| App.Rotation(0.0000000000, 0.0000000000, 0.0000000000), | |
| ) | |
| self.Box2.MapReversed = False | |
| self.Box2.AttachmentSupport = self.Doc.getObject("XY_Plane") | |
| self.Box2.MapPathParameter = 0.000000 | |
| self.Box2.MapMode = "FlatFace" | |
| # Set the Refine option to False, otherwise adding the second box would be useless | |
| self.Box2.Refine = False | |
| self.Body.addObject(self.Box2) | |
| self.Doc.recompute() | |
| # Move the Hole on top of the Body | |
| self.Body.removeObject(self.Hole) | |
| self.Body.insertObject(self.Hole, self.Box2, True) | |
| self.Body.Tip = self.Hole | |
| self.Hole.Diameter = 6 | |
| self.Hole.Depth = 10 | |
| self.Hole.ThreadType = 0 | |
| self.Hole.HoleCutType = 0 | |
| self.Hole.DepthType = 0 | |
| self.Hole.DrillPoint = 0 | |
| self.Hole.Tapered = 0 | |
| self.Hole.Visibility = True | |
| # Test the number of faces with the Refine option set to True | |
| self.Hole.Refine = True | |
| self.Doc.recompute() | |
| self.assertEqual(len(self.Hole.Shape.Faces), 7) | |
| def testThreadEnums(self): | |
| """Test thread enums for correct order""" | |
| # Due to the savefile use of indexes and not strings | |
| # The correct mapping needs to be ensured to not break savefiles | |
| # The order of the arrays and elements is critical | |
| thread_types = { | |
| "ISOMetricProfile": [ | |
| "M1x0.25", | |
| "M1.1x0.25", | |
| "M1.2x0.25", | |
| "M1.4x0.3", | |
| "M1.6x0.35", | |
| "M1.8x0.35", | |
| "M2x0.4", | |
| "M2.2x0.45", | |
| "M2.5x0.45", | |
| "M3x0.5", | |
| "M3.5x0.6", | |
| "M4x0.7", | |
| "M4.5x0.75", | |
| "M5x0.8", | |
| "M6x1.0", | |
| "M7x1.0", | |
| "M8x1.25", | |
| "M9x1.25", | |
| "M10x1.5", | |
| "M11x1.5", | |
| "M12x1.75", | |
| "M14x2.0", | |
| "M16x2.0", | |
| "M18x2.5", | |
| "M20x2.5", | |
| "M22x2.5", | |
| "M24x3.0", | |
| "M27x3.0", | |
| "M30x3.5", | |
| "M33x3.5", | |
| "M36x4.0", | |
| "M39x4.0", | |
| "M42x4.5", | |
| "M45x4.5", | |
| "M48x5.0", | |
| "M52x5.0", | |
| "M56x5.5", | |
| "M60x5.5", | |
| "M64x6.0", | |
| "M68x6.0", | |
| ], | |
| "ISOMetricFineProfile": [ | |
| "M1x0.2", | |
| "M1.1x0.2", | |
| "M1.2x0.2", | |
| "M1.4x0.2", | |
| "M1.6x0.2", | |
| "M1.8x0.2", | |
| "M2x0.25", | |
| "M2.2x0.25", | |
| "M2.5x0.35", | |
| "M3x0.35", | |
| "M3.5x0.35", | |
| "M4x0.5", | |
| "M4.5x0.5", | |
| "M5x0.5", | |
| "M5.5x0.5", | |
| "M6x0.75", | |
| "M7x0.75", | |
| "M8x0.75", | |
| "M8x1.0", | |
| "M9x0.75", | |
| "M9x1.0", | |
| "M10x0.75", | |
| "M10x1.0", | |
| "M10x1.25", | |
| "M11x0.75", | |
| "M11x1.0", | |
| "M12x1.0", | |
| "M12x1.25", | |
| "M12x1.5", | |
| "M14x1.0", | |
| "M14x1.25", | |
| "M14x1.5", | |
| "M15x1.0", | |
| "M15x1.5", | |
| "M16x1.0", | |
| "M16x1.5", | |
| "M17x1.0", | |
| "M17x1.5", | |
| "M18x1.0", | |
| "M18x1.5", | |
| "M18x2.0", | |
| "M20x1.0", | |
| "M20x1.5", | |
| "M20x2.0", | |
| "M22x1.0", | |
| "M22x1.5", | |
| "M22x2.0", | |
| "M24x1.0", | |
| "M24x1.5", | |
| "M24x2.0", | |
| "M25x1.0", | |
| "M25x1.5", | |
| "M25x2.0", | |
| "M27x1.0", | |
| "M27x1.5", | |
| "M27x2.0", | |
| "M28x1.0", | |
| "M28x1.5", | |
| "M28x2.0", | |
| "M30x1.0", | |
| "M30x1.5", | |
| "M30x2.0", | |
| "M30x3.0", | |
| "M32x1.5", | |
| "M32x2.0", | |
| "M33x1.5", | |
| "M33x2.0", | |
| "M33x3.0", | |
| "M35x1.5", | |
| "M35x2.0", | |
| "M36x1.5", | |
| "M36x2.0", | |
| "M36x3.0", | |
| "M39x1.5", | |
| "M39x2.0", | |
| "M39x3.0", | |
| "M40x1.5", | |
| "M40x2.0", | |
| "M40x3.0", | |
| "M42x1.5", | |
| "M42x2.0", | |
| "M42x3.0", | |
| "M42x4.0", | |
| "M45x1.5", | |
| "M45x2.0", | |
| "M45x3.0", | |
| "M45x4.0", | |
| "M48x1.5", | |
| "M48x2.0", | |
| "M48x3.0", | |
| "M48x4.0", | |
| "M50x1.5", | |
| "M50x2.0", | |
| "M50x3.0", | |
| "M52x1.5", | |
| "M52x2.0", | |
| "M52x3.0", | |
| "M52x4.0", | |
| "M55x1.5", | |
| "M55x2.0", | |
| "M55x3.0", | |
| "M55x4.0", | |
| "M56x1.5", | |
| "M56x2.0", | |
| "M56x3.0", | |
| "M56x4.0", | |
| "M58x1.5", | |
| "M58x2.0", | |
| "M58x3.0", | |
| "M58x4.0", | |
| "M60x1.5", | |
| "M60x2.0", | |
| "M60x3.0", | |
| "M60x4.0", | |
| "M62x1.5", | |
| "M62x2.0", | |
| "M62x3.0", | |
| "M62x4.0", | |
| "M64x1.5", | |
| "M64x2.0", | |
| "M64x3.0", | |
| "M64x4.0", | |
| "M65x1.5", | |
| "M65x2.0", | |
| "M65x3.0", | |
| "M65x4.0", | |
| "M68x1.5", | |
| "M68x2.0", | |
| "M68x3.0", | |
| "M68x4.0", | |
| "M70x1.5", | |
| "M70x2.0", | |
| "M70x3.0", | |
| "M70x4.0", | |
| "M70x6.0", | |
| "M72x1.5", | |
| "M72x2.0", | |
| "M72x3.0", | |
| "M72x4.0", | |
| "M72x6.0", | |
| "M75x1.5", | |
| "M75x2.0", | |
| "M75x3.0", | |
| "M75x4.0", | |
| "M75x6.0", | |
| "M76x1.5", | |
| "M76x2.0", | |
| "M76x3.0", | |
| "M76x4.0", | |
| "M76x6.0", | |
| "M80x1.5", | |
| "M80x2.0", | |
| "M80x3.0", | |
| "M80x4.0", | |
| "M80x6.0", | |
| "M85x2.0", | |
| "M85x3.0", | |
| "M85x4.0", | |
| "M85x6.0", | |
| "M90x2.0", | |
| "M90x3.0", | |
| "M90x4.0", | |
| "M90x6.0", | |
| "M95x2.0", | |
| "M95x3.0", | |
| "M95x4.0", | |
| "M95x6.0", | |
| "M100x2.0", | |
| "M100x3.0", | |
| "M100x4.0", | |
| "M100x6.0", | |
| ], | |
| "UNC": [ | |
| "#1", | |
| "#2", | |
| "#3", | |
| "#4", | |
| "#5", | |
| "#6", | |
| "#8", | |
| "#10", | |
| "#12", | |
| "1/4", | |
| "5/16", | |
| "3/8", | |
| "7/16", | |
| "1/2", | |
| "9/16", | |
| "5/8", | |
| "3/4", | |
| "7/8", | |
| "1", | |
| "1 1/8", | |
| "1 1/4", | |
| "1 3/8", | |
| "1 1/2", | |
| "1 3/4", | |
| "2", | |
| "2 1/4", | |
| "2 1/2", | |
| "2 3/4", | |
| "3", | |
| "3 1/4", | |
| "3 1/2", | |
| "3 3/4", | |
| "4", | |
| ], | |
| "UNF": [ | |
| "#0", | |
| "#1", | |
| "#2", | |
| "#3", | |
| "#4", | |
| "#5", | |
| "#6", | |
| "#8", | |
| "#10", | |
| "#12", | |
| "1/4", | |
| "5/16", | |
| "3/8", | |
| "7/16", | |
| "1/2", | |
| "9/16", | |
| "5/8", | |
| "3/4", | |
| "7/8", | |
| "1", | |
| "1 1/8", | |
| "1 3/16", | |
| "1 1/4", | |
| "1 3/8", | |
| "1 1/2", | |
| ], | |
| "UNEF": [ | |
| "#12", | |
| "1/4", | |
| "5/16", | |
| "3/8", | |
| "7/16", | |
| "1/2", | |
| "9/16", | |
| "5/8", | |
| "11/16", | |
| "3/4", | |
| "13/16", | |
| "7/8", | |
| "15/16", | |
| "1", | |
| "1 1/16", | |
| "1 1/8", | |
| "1 1/4", | |
| "1 5/16", | |
| "1 3/8", | |
| "1 7/16", | |
| "1 1/2", | |
| "1 9/16", | |
| "1 5/8", | |
| "1 11/16", | |
| ], | |
| "NPT": [ | |
| "1/16", | |
| "1/8", | |
| "1/4", | |
| "3/8", | |
| "1/2", | |
| "3/4", | |
| "1", | |
| "1 1/4", | |
| "1 1/2", | |
| "2", | |
| "2 1/2", | |
| "3", | |
| "3 1/2", | |
| "4", | |
| "5", | |
| "6", | |
| "8", | |
| "10", | |
| "12", | |
| ], | |
| "BSP": [ | |
| "1/16", | |
| "1/8", | |
| "1/4", | |
| "3/8", | |
| "1/2", | |
| "5/8", | |
| "3/4", | |
| "7/8", | |
| "1", | |
| "1 1/8", | |
| "1 1/4", | |
| "1 1/2", | |
| "1 3/4", | |
| "2", | |
| "2 1/4", | |
| "2 1/2", | |
| "2 3/4", | |
| "3", | |
| "3 1/2", | |
| "4", | |
| "4 1/2", | |
| "5", | |
| "5 1/2", | |
| "6", | |
| ], | |
| "BSW": [ | |
| "1/8", | |
| "3/16", | |
| "1/4", | |
| "5/16", | |
| "3/8", | |
| "7/16", | |
| "1/2", | |
| "9/16", | |
| "5/8", | |
| "11/16", | |
| "3/4", | |
| "7/8", | |
| "1", | |
| "1 1/8", | |
| "1 1/4", | |
| "1 1/2", | |
| "1 3/4", | |
| "2", | |
| "2 1/4", | |
| "2 1/2", | |
| "2 3/4", | |
| "3", | |
| "3 1/4", | |
| "3 1/2", | |
| "3 3/4", | |
| "4", | |
| "4 1/2", | |
| "5", | |
| "5 1/2", | |
| "6", | |
| ], | |
| "BSF": [ | |
| "3/16", | |
| "7/32", | |
| "1/4", | |
| "9/32", | |
| "5/16", | |
| "3/8", | |
| "7/16", | |
| "1/2", | |
| "9/16", | |
| "5/8", | |
| "11/16", | |
| "3/4", | |
| "7/8", | |
| "1", | |
| "1 1/8", | |
| "1 1/4", | |
| "1 3/8", | |
| "1 1/2", | |
| "1 5/8", | |
| "1 3/4", | |
| "2", | |
| "2 1/4", | |
| "2 1/2", | |
| "2 3/4", | |
| "3", | |
| "3 1/4", | |
| "3 1/2", | |
| "3 3/4", | |
| "4", | |
| "4 1/4", | |
| ], | |
| "ISOTyre": [ | |
| "5v1", | |
| "5v2", | |
| "6v1", | |
| "8v1", | |
| "9v1", | |
| "10v2", | |
| "12v1", | |
| "13v1", | |
| "8v2", | |
| "10v1", | |
| "11v1", | |
| "13v2", | |
| "15v1", | |
| "16v1", | |
| "17v1", | |
| "17v2", | |
| "17v3", | |
| "19v1", | |
| "20v1", | |
| ], | |
| } | |
| allowed_types = self.Hole.getEnumerationsOfProperty("ThreadType") | |
| for type_index, thread_type in enumerate(thread_types.keys(), 1): | |
| if thread_type not in allowed_types: | |
| self._helperNotFoundMessage(thread_type, allowed_types) | |
| # Set by number like the saved files | |
| self.Hole.ThreadType = type_index | |
| self._helperNotCorrectMessage(self.Hole.ThreadType, thread_type) | |
| allowed_sizes = self.Hole.getEnumerationsOfProperty("ThreadSize") | |
| for size_index, designation in enumerate(thread_types[thread_type]): | |
| if designation not in allowed_sizes: | |
| self._helperNotFoundMessage(designation, allowed_sizes) | |
| # Set by number like the saved files | |
| self.Hole.ThreadSize = size_index | |
| self._helperNotCorrectMessage(self.Hole.ThreadSize, designation) | |
| def _helperNotCorrectMessage(self, value, comparison): | |
| self.assertEqual( | |
| value, | |
| comparison, | |
| f"{comparison} is not in the correct position\n\n" | |
| "it will break compatibility with older saves", | |
| ) | |
| def _helperNotFoundMessage(self, prop, allowed_props): | |
| raise AssertionError( | |
| "\n" | |
| f"{prop} is not in {allowed_props}\n\n" | |
| "Verify that the tested enums names are updated \n\n" | |
| ) | |
| def tearDown(self): | |
| # closing doc | |
| FreeCAD.closeDocument("PartDesignTestHole") | |
| # print ("omit closing document for debugging") | |