AbdulElahGwaith's picture
Upload folder using huggingface_hub
985c397 verified
# **************************************************************************
# 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")