Download src/Mod/PartDesign/PartDesignTests/TestTopologicalNamingProblem.py from AbdulElahGwaith/FreeCAD: direct link, hf CLI and curl.
- Browser
- Download file 133 kB
-
https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/PartDesign/PartDesignTests/TestTopologicalNamingProblem.py
- Command line
-
hf download hf://AbdulElahGwaith/FreeCAD/src/Mod/PartDesign/PartDesignTests/TestTopologicalNamingProblem.py
-
curl -L -o TestTopologicalNamingProblem.py https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/PartDesign/PartDesignTests/TestTopologicalNamingProblem.py
133 kB
| # SPDX-License-Identifier: LGPL-2.1-or-later | |
| # *************************************************************************** | |
| # * * | |
| # * Copyright (c) 2024 bgbsww@gmail.com * | |
| # * * | |
| # * This file is part of FreeCAD. * | |
| # * * | |
| # * FreeCAD is free software: you can redistribute it and/or modify it * | |
| # * under the terms of the GNU Lesser General Public License as * | |
| # * published by the Free Software Foundation, either version 2.1 of the * | |
| # * License, or (at your option) any later version. * | |
| # * * | |
| # * 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 * | |
| # * Lesser General Public License for more details. * | |
| # * * | |
| # * You should have received a copy of the GNU Lesser General Public * | |
| # * License along with FreeCAD. If not, see * | |
| # * <https://www.gnu.org/licenses/>. * | |
| # * * | |
| # *************************************************************************** | |
| """Tests related to the Topological Naming Problem""" | |
| import os | |
| import math | |
| import unittest | |
| import tempfile | |
| import FreeCAD as App | |
| import Part | |
| import Sketcher | |
| import TestSketcherApp | |
| class TestTopologicalNamingProblem(unittest.TestCase): | |
| """Tests related to the Topological Naming Problem""" | |
| # pylint: disable=attribute-defined-outside-init | |
| def setUp(self): | |
| """Create a document for each test in the test suite""" | |
| self.Doc = App.newDocument("PartDesignTestTNP." + self._testMethodName) | |
| def countFacesEdgesVertexes(self, map): | |
| """Helper to return a tuple of the counts of Faces, Edges, and Vertexes in a map for | |
| easier test writing""" | |
| faces = [name for name in map.keys() if name.startswith("Face")] | |
| edges = [name for name in map.keys() if name.startswith("Edge")] | |
| vertexes = [name for name in map.keys() if name.startswith("Vertex")] | |
| return (len(faces), len(edges), len(vertexes)) | |
| def testPadsOnBaseObject(self): | |
| """Simple TNP test case | |
| By creating three Pads dependent on each other in succession, and then moving the | |
| middle one we can determine if the last one breaks because of a broken reference | |
| to the middle one. This is the essence of a TNP. Pretty much a duplicate of the | |
| steps at https://wiki.freecad.org/Topological_naming_problem""" | |
| # Arrange | |
| self.Body = self.Doc.addObject("PartDesign::Body", "Body") | |
| # Make first offset cube Pad | |
| self.PadSketch = self.Doc.addObject("Sketcher::SketchObject", "SketchPad") | |
| self.Body.addObject(self.PadSketch) | |
| TestSketcherApp.CreateRectangleSketch(self.PadSketch, (0, 0), (1, 1)) | |
| self.Doc.recompute() | |
| self.Pad = self.Doc.addObject("PartDesign::Pad", "Pad") | |
| self.Body.addObject(self.Pad) | |
| self.Pad.Profile = self.PadSketch | |
| self.Pad.Length = 1 | |
| self.Doc.recompute() | |
| # Attach a second pad to the top of the first. | |
| self.PadSketch1 = self.Doc.addObject("Sketcher::SketchObject", "SketchPad1") | |
| self.Body.addObject(self.PadSketch1) | |
| self.PadSketch1.MapMode = "FlatFace" | |
| self.PadSketch1.AttachmentSupport = [(self.Doc.getObject("Pad"), "Face6")] | |
| TestSketcherApp.CreateRectangleSketch(self.PadSketch1, (0, 0), (1, 1)) | |
| self.Doc.recompute() | |
| self.Pad1 = self.Doc.addObject("PartDesign::Pad", "Pad1") | |
| self.Body.addObject(self.Pad1) | |
| self.Pad1.Profile = self.PadSketch1 | |
| self.Pad1.Length = 1 | |
| self.Doc.recompute() | |
| # Attach a third pad to the top of the second. | |
| self.PadSketch2 = self.Doc.addObject("Sketcher::SketchObject", "SketchPad2") | |
| self.Body.addObject(self.PadSketch2) | |
| self.PadSketch2.MapMode = "FlatFace" | |
| self.PadSketch2.AttachmentSupport = [(self.Doc.getObject("Pad1"), "Face6")] | |
| TestSketcherApp.CreateRectangleSketch(self.PadSketch2, (0, 0), (1, 1)) | |
| self.Doc.recompute() | |
| self.Pad2 = self.Doc.addObject("PartDesign::Pad", "Pad2") | |
| self.Body.addObject(self.Pad2) | |
| self.Pad2.Profile = self.PadSketch2 | |
| self.Pad2.Length = 1 | |
| self.Doc.recompute() | |
| # Assert everything is valid | |
| self.assertTrue(self.Pad.isValid()) | |
| self.assertTrue(self.Pad1.isValid()) | |
| self.assertTrue(self.Pad2.isValid()) | |
| # Act | |
| # Move the second pad ( the sketch attachment point ) | |
| self.PadSketch1.AttachmentOffset = App.Placement( | |
| App.Vector(0.5000000000, 0.0000000000, 0.0000000000), | |
| App.Rotation(0.0000000000, 0.0000000000, 0.0000000000), | |
| ) | |
| self.Doc.recompute() | |
| # Assert everything is still valid. | |
| self.assertTrue(self.Pad.isValid()) | |
| self.assertTrue(self.Pad1.isValid()) | |
| if self.Body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| self.assertFalse(self.Pad2.isValid()) # TNP problem is present without ElementMaps | |
| else: | |
| self.assertTrue(self.Pad2.isValid()) # TNP problem is not present with ElementMaps | |
| def testPartDesignElementMapSketch(self): | |
| """Test that creating a sketch results in a correct element map.""" | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| sketch = self.Doc.addObject("Sketcher::SketchObject", "SketchPad") | |
| body.addObject(sketch) | |
| TestSketcherApp.CreateRectangleSketch(sketch, (0, 0), (1, 1)) | |
| # Act | |
| self.Doc.recompute() | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| reverseMap = sketch.Shape.ElementReverseMap | |
| reverseFaces = [name for name in reverseMap.keys() if name.startswith("Face")] | |
| edges = [name for name in reverseMap.keys() if name.startswith("Edge")] | |
| vertexes = [name for name in reverseMap.keys() if name.startswith("Vertex")] | |
| # Assert | |
| self.assertEqual(sketch.Shape.ElementMapSize, 12) | |
| self.assertEqual(len(reverseMap), 8) | |
| self.assertEqual(len(reverseFaces), 0) | |
| self.assertEqual(len(edges), 4) | |
| self.assertEqual(len(vertexes), 4) | |
| def testPartDesignBasicFusion(self): | |
| """Test that a basic fusion creates an element map, and refine retains it""" | |
| # Arrange | |
| doc = self.Doc | |
| box1 = doc.addObject("Part::Box", "Box") | |
| if App.GuiUp: | |
| mat = App.Material() | |
| mat.AmbientColor = (128, 0, 0) | |
| box1.ViewObject.ShapeAppearance = mat # Change color ( material ) for at least one | |
| box2 = doc.addObject("Part::Box", "Box001") | |
| box3 = doc.addObject("Part::Box", "Box002") | |
| cyl1 = doc.addObject("Part::Cylinder", "Cylinder") | |
| fuse1 = doc.addObject("Part::MultiFuse", "Fusion") | |
| doc.Fusion.Shapes = [box1, box2] | |
| fuse2 = doc.addObject("Part::MultiFuse", "Fusion001") | |
| doc.Fusion001.Shapes = [box3, cyl1] | |
| doc.recompute() | |
| # Assert | |
| self.assertEqual(fuse1.Shape.ElementMapSize, 26) | |
| self.assertEqual(fuse2.Shape.ElementMapSize, 44) | |
| # Act | |
| doc.Fusion.Refine = True # activate refinement | |
| doc.Fusion001.Refine = True # activate refinement | |
| doc.recompute() | |
| self.assertEqual(fuse1.Shape.ElementMapSize, 26) | |
| self.assertEqual(fuse2.Shape.ElementMapSize, 44) | |
| def testPartDesignElementMapPad(self): | |
| """Test that padding a sketch results in a correct element map. Note that comprehensive | |
| testing of the geometric functionality of the Pad is in TestPad.py""" | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| padSketch = self.Doc.addObject("Sketcher::SketchObject", "SketchPad") | |
| pad = self.Doc.addObject("PartDesign::Pad", "Pad") | |
| body.addObject(padSketch) | |
| body.addObject(pad) | |
| TestSketcherApp.CreateRectangleSketch(padSketch, (0, 0), (1, 1)) | |
| pad.Profile = padSketch | |
| pad.Length = 1 | |
| # Act | |
| self.Doc.recompute() | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| reverseMap = pad.Shape.ElementReverseMap | |
| faces = [name for name in reverseMap.keys() if name.startswith("Face")] | |
| edges = [name for name in reverseMap.keys() if name.startswith("Edge")] | |
| vertexes = [name for name in reverseMap.keys() if name.startswith("Vertex")] | |
| # Assert | |
| self.assertEqual(pad.Shape.ElementMapSize, 30) # 4 duplicated Vertexes in here | |
| self.assertEqual(len(reverseMap), 26) | |
| self.assertEqual(len(faces), 6) | |
| self.assertEqual(len(edges), 12) | |
| self.assertEqual(len(vertexes), 8) | |
| def testPartDesignElementMapBox(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| box = self.Doc.addObject("PartDesign::AdditiveBox", "Box") | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Act / Assert | |
| self.assertEqual(len(box.Shape.childShapes()), 0) | |
| self.Doc.recompute() | |
| self.assertEqual(len(box.Shape.childShapes()), 1) | |
| self.assertEqual(box.Shape.childShapes()[0].ElementMapSize, 26) | |
| body.addObject(box) | |
| self.assertEqual(len(body.Shape.childShapes()), 0) | |
| self.Doc.recompute() | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 26) | |
| def testPartDesignElementMapCylinder(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| cylinder = self.Doc.addObject("PartDesign::AdditiveCylinder", "Cylinder") | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Act / Assert | |
| self.assertEqual(len(cylinder.Shape.childShapes()), 0) | |
| self.Doc.recompute() | |
| self.assertEqual(len(cylinder.Shape.childShapes()), 1) | |
| self.assertEqual(cylinder.Shape.childShapes()[0].ElementMapSize, 8) | |
| body.addObject(cylinder) | |
| self.assertEqual(len(body.Shape.childShapes()), 0) | |
| self.Doc.recompute() | |
| reverseMap = body.Shape.childShapes()[0].ElementReverseMap | |
| faces = [name for name in reverseMap.keys() if name.startswith("Face")] | |
| edges = [name for name in reverseMap.keys() if name.startswith("Edge")] | |
| vertexes = [name for name in reverseMap.keys() if name.startswith("Vertex")] | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 8) | |
| self.assertEqual(len(reverseMap), 8) | |
| self.assertEqual(len(faces), 3) | |
| self.assertEqual(len(edges), 3) | |
| self.assertEqual(len(vertexes), 2) | |
| def testPartDesignElementMapSphere(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| sphere = self.Doc.addObject("PartDesign::AdditiveSphere", "Sphere") | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Act / Assert | |
| self.assertEqual(len(sphere.Shape.childShapes()), 0) | |
| self.Doc.recompute() | |
| self.assertEqual(len(sphere.Shape.childShapes()), 1) | |
| self.assertEqual(sphere.Shape.childShapes()[0].ElementMapSize, 6) | |
| body.addObject(sphere) | |
| self.assertEqual(len(body.Shape.childShapes()), 0) | |
| self.Doc.recompute() | |
| reverseMap = body.Shape.childShapes()[0].ElementReverseMap | |
| faces = [name for name in reverseMap.keys() if name.startswith("Face")] | |
| edges = [name for name in reverseMap.keys() if name.startswith("Edge")] | |
| vertexes = [name for name in reverseMap.keys() if name.startswith("Vertex")] | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 6) | |
| self.assertEqual(len(reverseMap), 6) | |
| self.assertEqual(len(faces), 1) | |
| self.assertEqual(len(edges), 3) | |
| self.assertEqual(len(vertexes), 2) | |
| def testPartDesignElementMapCone(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| cone = self.Doc.addObject("PartDesign::AdditiveCone", "Cone") | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Act / Assert | |
| self.assertEqual(len(cone.Shape.childShapes()), 0) | |
| self.Doc.recompute() | |
| self.assertEqual(len(cone.Shape.childShapes()), 1) | |
| self.assertEqual(cone.Shape.childShapes()[0].ElementMapSize, 8) | |
| body.addObject(cone) | |
| self.assertEqual(len(body.Shape.childShapes()), 0) | |
| self.Doc.recompute() | |
| reverseMap = body.Shape.childShapes()[0].ElementReverseMap | |
| faces = [name for name in reverseMap.keys() if name.startswith("Face")] | |
| edges = [name for name in reverseMap.keys() if name.startswith("Edge")] | |
| vertexes = [name for name in reverseMap.keys() if name.startswith("Vertex")] | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 8) | |
| self.assertEqual(len(reverseMap), 8) | |
| self.assertEqual(len(faces), 3) | |
| self.assertEqual(len(edges), 3) | |
| self.assertEqual(len(vertexes), 2) | |
| def testPartDesignElementMapEllipsoid(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| ellipsoid = self.Doc.addObject("PartDesign::AdditiveEllipsoid", "Ellipsoid") | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Act / Assert | |
| self.assertEqual(len(ellipsoid.Shape.childShapes()), 0) | |
| self.Doc.recompute() | |
| self.assertEqual(len(ellipsoid.Shape.childShapes()), 1) | |
| self.assertEqual(ellipsoid.Shape.childShapes()[0].ElementMapSize, 6) | |
| body.addObject(ellipsoid) | |
| self.assertEqual(len(body.Shape.childShapes()), 0) | |
| self.Doc.recompute() | |
| reverseMap = body.Shape.childShapes()[0].ElementReverseMap | |
| faces = [name for name in reverseMap.keys() if name.startswith("Face")] | |
| edges = [name for name in reverseMap.keys() if name.startswith("Edge")] | |
| vertexes = [name for name in reverseMap.keys() if name.startswith("Vertex")] | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 6) | |
| self.assertEqual(len(reverseMap), 6) | |
| self.assertEqual(len(faces), 1) | |
| self.assertEqual(len(edges), 3) | |
| self.assertEqual(len(vertexes), 2) | |
| def testPartDesignElementMapTorus(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| torus = self.Doc.addObject("PartDesign::AdditiveTorus", "Torus") | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Act / Assert | |
| self.assertEqual(len(torus.Shape.childShapes()), 0) | |
| self.Doc.recompute() | |
| self.assertEqual(len(torus.Shape.childShapes()), 1) | |
| self.assertEqual(torus.Shape.childShapes()[0].ElementMapSize, 4) | |
| body.addObject(torus) | |
| self.assertEqual(len(body.Shape.childShapes()), 0) | |
| self.Doc.recompute() | |
| reverseMap = body.Shape.childShapes()[0].ElementReverseMap | |
| faces = [name for name in reverseMap.keys() if name.startswith("Face")] | |
| edges = [name for name in reverseMap.keys() if name.startswith("Edge")] | |
| vertexes = [name for name in reverseMap.keys() if name.startswith("Vertex")] | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 4) | |
| self.assertEqual(len(reverseMap), 4) | |
| self.assertEqual(len(faces), 1) | |
| self.assertEqual(len(edges), 2) | |
| self.assertEqual(len(vertexes), 1) | |
| def testPartDesignElementMapPrism(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| prism = self.Doc.addObject("PartDesign::AdditivePrism", "Prism") | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Act / Assert | |
| self.assertEqual(len(prism.Shape.childShapes()), 0) | |
| self.Doc.recompute() | |
| self.assertEqual(len(prism.Shape.childShapes()), 1) | |
| self.assertEqual(prism.Shape.childShapes()[0].ElementMapSize, 38) | |
| body.addObject(prism) | |
| self.assertEqual(len(body.Shape.childShapes()), 0) | |
| self.Doc.recompute() | |
| reverseMap = body.Shape.childShapes()[0].ElementReverseMap | |
| faces = [name for name in reverseMap.keys() if name.startswith("Face")] | |
| edges = [name for name in reverseMap.keys() if name.startswith("Edge")] | |
| vertexes = [name for name in reverseMap.keys() if name.startswith("Vertex")] | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 38) | |
| self.assertEqual(len(reverseMap), 38) | |
| self.assertEqual(len(faces), 8) | |
| self.assertEqual(len(edges), 18) | |
| self.assertEqual(len(vertexes), 12) | |
| def testPartDesignElementMapWedge(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| wedge = self.Doc.addObject("PartDesign::AdditiveWedge", "Wedge") | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Act / Assert | |
| self.assertEqual(len(wedge.Shape.childShapes()), 0) | |
| self.Doc.recompute() | |
| self.assertEqual(len(wedge.Shape.childShapes()), 1) | |
| self.assertEqual(wedge.Shape.childShapes()[0].ElementMapSize, 26) | |
| body.addObject(wedge) | |
| self.assertEqual(len(body.Shape.childShapes()), 0) | |
| self.Doc.recompute() | |
| reverseMap = body.Shape.childShapes()[0].ElementReverseMap | |
| faces = [name for name in reverseMap.keys() if name.startswith("Face")] | |
| edges = [name for name in reverseMap.keys() if name.startswith("Edge")] | |
| vertexes = [name for name in reverseMap.keys() if name.startswith("Vertex")] | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 26) | |
| self.assertEqual(len(reverseMap), 26) | |
| self.assertEqual(len(faces), 6) | |
| self.assertEqual(len(edges), 12) | |
| self.assertEqual(len(vertexes), 8) | |
| # body.BaseFeature = box | |
| def testPartDesignElementMapSubBox(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| box = self.Doc.addObject("PartDesign::AdditiveBox", "Box") | |
| box.Length = 20 | |
| box.Width = 20 | |
| box.Height = 20 | |
| body.addObject(box) | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Act | |
| subbox = self.Doc.addObject("PartDesign::SubtractiveBox", "Box") | |
| subbox.BaseFeature = box | |
| body.addObject(subbox) | |
| self.Doc.recompute() | |
| # Assert | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 44) | |
| def testPartDesignElementMapSubCylinder(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| box = self.Doc.addObject("PartDesign::AdditiveBox", "Box") | |
| box.Length = 20 | |
| box.Width = 20 | |
| box.Height = 20 | |
| body.addObject(box) | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Act | |
| subcylinder = self.Doc.addObject("PartDesign::SubtractiveCylinder", "Cylinder") | |
| subcylinder.BaseFeature = box | |
| body.addObject(subcylinder) | |
| # Assert | |
| self.Doc.recompute() | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 38) | |
| def testPartDesignElementMapSubSphere(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| box = self.Doc.addObject("PartDesign::AdditiveBox", "Box") | |
| box.Length = 20 | |
| box.Width = 20 | |
| box.Height = 20 | |
| body.addObject(box) | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Act | |
| subsphere = self.Doc.addObject("PartDesign::SubtractiveSphere", "Sphere") | |
| subsphere.BaseFeature = box | |
| body.addObject(subsphere) | |
| self.Doc.recompute() | |
| # Assert | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 33) | |
| def testPartDesignElementMapSubCone(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| box = self.Doc.addObject("PartDesign::AdditiveBox", "Box") | |
| box.Length = 20 | |
| box.Width = 20 | |
| box.Height = 20 | |
| body.addObject(box) | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Act | |
| subcone = self.Doc.addObject("PartDesign::SubtractiveCone", "Cone") | |
| subcone.BaseFeature = box | |
| body.addObject(subcone) | |
| # Assert | |
| self.Doc.recompute() | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 38) | |
| def testPartDesignElementMapSubEllipsoid(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| box = self.Doc.addObject("PartDesign::AdditiveBox", "Box") | |
| box.Length = 20 | |
| box.Width = 20 | |
| box.Height = 20 | |
| body.addObject(box) | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Act | |
| subellipsoid = self.Doc.addObject("PartDesign::SubtractiveEllipsoid", "Ellipsoid") | |
| subellipsoid.BaseFeature = box | |
| body.addObject(subellipsoid) | |
| self.Doc.recompute() | |
| # Assert | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 33) | |
| def testPartDesignElementMapSubTorus(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| box = self.Doc.addObject("PartDesign::AdditiveBox", "Box") | |
| box.Length = 20 | |
| box.Width = 20 | |
| box.Height = 20 | |
| body.addObject(box) | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Act | |
| subtorus = self.Doc.addObject("PartDesign::SubtractiveTorus", "Torus") | |
| subtorus.BaseFeature = box | |
| body.addObject(subtorus) | |
| self.Doc.recompute() | |
| # Assert | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 38) | |
| def testPartDesignElementMapSubPrism(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| box = self.Doc.addObject("PartDesign::AdditiveBox", "Box") | |
| box.Length = 20 | |
| box.Width = 20 | |
| box.Height = 20 | |
| body.addObject(box) | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Act | |
| subprism = self.Doc.addObject("PartDesign::SubtractivePrism", "Prism") | |
| subprism.BaseFeature = box | |
| body.addObject(subprism) | |
| self.Doc.recompute() | |
| # Assert | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 44) | |
| def testPartDesignElementMapSubWedge(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| box = self.Doc.addObject("PartDesign::AdditiveBox", "Box") | |
| box.Length = 20 | |
| box.Width = 20 | |
| box.Height = 20 | |
| body.addObject(box) | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Act | |
| subwedge = self.Doc.addObject("PartDesign::SubtractiveWedge", "Wedge") | |
| subwedge.BaseFeature = box | |
| body.addObject(subwedge) | |
| self.Doc.recompute() | |
| # Assert | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 50) | |
| def testPartDesignElementPadSketch(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| sketch = self.Doc.addObject("Sketcher::SketchObject", "Sketch") | |
| TestSketcherApp.CreateRectangleSketch(sketch, (0, 0), (1, 1)) | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Act | |
| pad = self.Doc.addObject("PartDesign::Pad", "Pad") | |
| pad.Profile = sketch | |
| body.addObject(sketch) | |
| body.addObject(pad) | |
| self.Doc.recompute() | |
| # Assert | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 30) # The pad | |
| self.assertEqual(body.Shape.ElementMapSize, 26) | |
| self.assertEqual(sketch.Shape.ElementMapSize, 12) | |
| self.assertEqual(pad.Shape.ElementMapSize, 30) # pad has the 26 plus the 4 original | |
| self.assertNotEqual( | |
| pad.Shape.ElementReverseMap["Vertex1"], "Vertex1" | |
| ) # NewName, not OldName | |
| self.assertEqual(self.countFacesEdgesVertexes(pad.Shape.ElementReverseMap), (6, 12, 8)) | |
| # Todo: Offer a way to turn on hashing and check that with a # starting | |
| # Pad -> Extrusion -> makes compounds and does booleans, thus the resulting newName element maps | |
| # See if we can turn those off, or try them on the other types? | |
| def _testPartDesignElementMapRevolution(self, order, vertex, face): | |
| # App.KeepTestDoc = True # Uncomment this if you want to keep the test document to examine | |
| self.Doc.UseHasher = False | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| sketch = self.Doc.addObject("Sketcher::SketchObject", "Sketch") | |
| TestSketcherApp.CreateRectangleSketch(sketch, (0, 1), (3, 2)) # (pt), (w,l) | |
| body.addObject(sketch) | |
| self.Doc.recompute() | |
| pad = self.Doc.addObject("PartDesign::Pad", "Pad") | |
| pad.Profile = sketch | |
| pad.Length = 3 | |
| body.addObject(pad) | |
| self.Doc.recompute() | |
| sketch2 = self.Doc.addObject("Sketcher::SketchObject", "Sketch001") | |
| TestSketcherApp.CreateRectangleSketch(sketch2, (2, -3), (1, 2)) # (pt), (w,l) | |
| sketch2.AttachmentSupport = (pad, ["Face5"]) | |
| sketch2.MapMode = "FlatFace" | |
| body.addObject(sketch2) | |
| self.Doc.recompute() | |
| revolution = self.Doc.addObject("PartDesign::Revolution", "Revolution") | |
| revolution.ReferenceAxis = (sketch2, ["V_Axis"]) | |
| revolution.Reversed = 1 | |
| revolution.Profile = sketch2 | |
| revolution.Angle = 180 | |
| revolution.Refine = True | |
| revolution.FuseOrder = order | |
| body.addObject(revolution) | |
| volume = (math.pi * 3 * 3 - math.pi * 2 * 2) * 2 / 2 | |
| padVolume = 3 * 3 * 2 # 50.26548245743668 | |
| # Act | |
| self.Doc.recompute() | |
| # Assert the Shape is correct | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertAlmostEqual(pad.Shape.Volume, padVolume) | |
| self.assertAlmostEqual(revolution.Shape.Volume, volume + padVolume) | |
| # Assert the element map is correct | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 46) | |
| self.assertEqual(revolution.Shape.ElementMapSize, 46) | |
| self.assertEqual( | |
| self.countFacesEdgesVertexes(revolution.Shape.ElementReverseMap), (9, 21, 14) | |
| ) | |
| self.assertEqual(revolution.Shape.ElementReverseMap[vertex][1].count(";"), 3) | |
| self.assertEqual(revolution.Shape.ElementReverseMap[face].count(";"), 19) | |
| ### This test has been removed because FeatureRevolution generates improper element maps when the user select the | |
| # UpToFace mode. That behavior seems to be the fault of OpenCASCADE itself, and we need to rewrite that section | |
| # before re-enabling this test. | |
| # Arrange for an UpToFace mode test | |
| # revolution.Type = 3 | |
| # revolution.UpToFace = (pad, ("Face4")) | |
| # revolution.Reversed = 1 | |
| # revolution.Midplane = 0 | |
| # volume = (math.pi * 3 * 3 - math.pi * 2 * 2) * 2 / 4 * 3 | |
| # # Act | |
| # self.Doc.recompute() | |
| # # Assert UpToFace shape is correct | |
| # self.assertAlmostEqual(revolution.Shape.Volume, volume + padVolume) | |
| # # Assert UpToFace element map is correct | |
| # self.assertEqual(self.countFacesEdgesVertexes(revolution.Shape.ElementReverseMap), | |
| # (8, 18, 12)) | |
| # # Assertions modified/added while reviewing PR#17119 by CalligaroV | |
| # # Previously the condition counted the number of ";" (element map operations prefix) | |
| # # If the number of operations changes then the number of ";" will change accordingly | |
| # # | |
| # # However, it is more useful to count the number of times an element name is | |
| # # present in the MappedName of an element (a MappedName is defined also using the | |
| # # element names - "Vertex*", "Edge*", "Face*" - used by an OCCT operation to generate | |
| # # output elements) | |
| # self.assertEqual( revolution.Shape.ElementReverseMap["Face8"].count("Face8"), 3) | |
| # self.assertEqual( revolution.Shape.ElementReverseMap["Face8"].count("Face10"), 3) | |
| def testPartDesignElementMapRevolutionFuseFeatureFirst(self): | |
| self._testPartDesignElementMapRevolution("FeatureFirst", "Vertex9", "Face9") | |
| def testPartDesignElementMapRevolutionWithDefaultFuseOrder(self): | |
| self._testPartDesignElementMapRevolution("BaseFirst", "Vertex8", "Face8") | |
| def testPartDesignBinderRevolution(self): | |
| doc = self.Doc | |
| body = doc.addObject("PartDesign::Body", "Body") | |
| sketch = body.newObject("Sketcher::SketchObject", "Sketch") | |
| sketch.AttachmentSupport = (doc.getObject("XY_Plane"), [""]) | |
| sketch.MapMode = "FlatFace" | |
| doc.recompute() | |
| geoList = [] | |
| geoList.append( | |
| Part.LineSegment( | |
| App.Vector(-44.107212, 34.404858, 0.000000), | |
| App.Vector(-44.107212, 9.881049, 0.000000), | |
| ) | |
| ) | |
| geoList.append( | |
| Part.LineSegment( | |
| App.Vector(-44.107212, 9.881049, 0.0000000), | |
| App.Vector(-10.297691, 9.881049, 0.000000), | |
| ) | |
| ) | |
| geoList.append( | |
| Part.LineSegment( | |
| App.Vector(-10.297691, 9.881049, 0.0000000), | |
| App.Vector(-10.297691, 34.404858, 0.00000), | |
| ) | |
| ) | |
| geoList.append( | |
| Part.LineSegment( | |
| App.Vector(-10.297691, 34.404858, 0.000000), | |
| App.Vector(-44.107212, 34.404858, 0.00000), | |
| ) | |
| ) | |
| sketch.addGeometry(geoList, False) | |
| del geoList | |
| constraintList = [] | |
| constraintList.append(Sketcher.Constraint("Coincident", 0, 2, 1, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 1, 2, 2, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 2, 2, 3, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 3, 2, 0, 1)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 0)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 2)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 1)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 3)) | |
| sketch.addConstraint(constraintList) | |
| del constraintList | |
| doc.recompute() | |
| binder = body.newObject("PartDesign::ShapeBinder", "ShapeBinder") | |
| binder.Support = [ | |
| sketch, | |
| (""), | |
| ] | |
| binder.Visibility = False | |
| doc.recompute() | |
| revolve = body.newObject("PartDesign::Revolution", "Revolution") | |
| revolve.Profile = ( | |
| doc.getObject("ShapeBinder"), | |
| [ | |
| "", | |
| ], | |
| ) | |
| revolve.ReferenceAxis = (doc.getObject("Y_Axis"), [""]) | |
| revolve.Angle = 360.0 | |
| doc.recompute() | |
| self.assertTrue(revolve.isValid()) | |
| def testPartDesignElementMapLoft(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| sketch = self.Doc.addObject("Sketcher::SketchObject", "Sketch") | |
| TestSketcherApp.CreateRectangleSketch(sketch, (0, 0), (1, 1)) | |
| sketch2 = self.Doc.addObject("Sketcher::SketchObject", "Sketch") | |
| TestSketcherApp.CreateRectangleSketch(sketch2, (0, 0), (2, 2)) | |
| sketch2.Placement.move(App.Vector(0, 0, 3)) | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Act | |
| loft = self.Doc.addObject("PartDesign::AdditiveLoft", "Loft") | |
| loft.Profile = sketch | |
| loft.Sections = [sketch2] | |
| body.addObject(sketch) | |
| body.addObject(sketch2) | |
| body.addObject(loft) | |
| self.Doc.recompute() | |
| # Assert | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| # 6 face 12 edge 8 vertexes = 26 | |
| # 4 edges are duplicated (the originals from the sketch loft profile, and then those in the loft) | |
| # 4 vertexes are quad dups for 12 more. 26 + 4 + 12 = 42 | |
| # self.assertEqual(body.Shape.ElementMapSize, 42) | |
| revMap = body.Shape.ElementReverseMap | |
| self.assertNotEqual(loft.Shape.ElementReverseMap["Vertex1"], "Vertex1") | |
| self.assertNotEqual(revMap["Vertex1"], "Vertex1") | |
| self.assertEqual(self.countFacesEdgesVertexes(loft.Shape.ElementReverseMap), (6, 12, 8)) | |
| volume = 7.0 | |
| self.assertAlmostEqual(loft.Shape.Volume, volume) | |
| def testPartDesignElementMapPipe(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| sketch = self.Doc.addObject("Sketcher::SketchObject", "Sketch") | |
| TestSketcherApp.CreateRectangleSketch(sketch, (0, 0), (1, 1)) | |
| sketch2 = self.Doc.addObject("Sketcher::SketchObject", "Sketch001") | |
| sketch2.AttachmentSupport = (self.Doc.getObject("XZ_Plane"), [""]) | |
| sketch2.addGeometry(Part.LineSegment(App.Vector(0, 0, 0), App.Vector(0, 1, 0))) | |
| sketch2.Placement = App.Placement( | |
| App.Vector(0, 0, 0), App.Rotation(App.Vector(1.00, 0.00, 0.00), 90.00) | |
| ) | |
| # Need to set sketch2 placement? | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Act | |
| pipe = self.Doc.addObject("PartDesign::AdditivePipe", "Pipe") | |
| pipe.Profile = sketch | |
| pipe.Spine = sketch2 | |
| body.addObject(sketch) | |
| body.addObject(sketch2) | |
| body.addObject(pipe) | |
| self.Doc.recompute() | |
| # Assert | |
| self.assertAlmostEqual(body.Shape.Volume, 1) | |
| self.assertAlmostEqual(body.Shape.BoundBox.XMin, 0) | |
| self.assertAlmostEqual(body.Shape.BoundBox.YMin, 0) | |
| self.assertAlmostEqual(body.Shape.BoundBox.ZMin, 0) | |
| self.assertAlmostEqual(body.Shape.BoundBox.XMax, 1) | |
| self.assertAlmostEqual(body.Shape.BoundBox.YMax, 1) | |
| self.assertAlmostEqual(body.Shape.BoundBox.ZMax, 1) | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 26) | |
| revMap = body.Shape.childShapes()[0].ElementReverseMap | |
| # revMap = pipe.Shape.ElementReverseMap | |
| # TODO: This is a child of the body and not the actual Pipe. | |
| # 1: is that okay and normal, or should the pipe have an element map | |
| self.assertEqual(self.countFacesEdgesVertexes(revMap), (6, 12, 8)) | |
| def testPartDesignElementMapHelix(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| sketch = self.Doc.addObject("Sketcher::SketchObject", "Sketch") | |
| TestSketcherApp.CreateRectangleSketch(sketch, (0, 0), (1, 1)) | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Act | |
| helix = self.Doc.addObject("PartDesign::AdditiveHelix", "Helix") | |
| helix.Profile = sketch | |
| helix.ReferenceAxis = (self.Doc.getObject("Sketch"), ["N_Axis"]) | |
| # helix.Mode = 0 | |
| body.addObject(sketch) | |
| body.addObject(helix) | |
| self.Doc.recompute() | |
| # Assert | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertGreaterEqual(body.Shape.childShapes()[0].ElementMapSize, 26) | |
| revMap = body.Shape.childShapes()[0].ElementReverseMap | |
| self.assertEqual(self.countFacesEdgesVertexes(revMap), (14, 28, 16)) | |
| Radius = 0 # Rectangle is on the axis, but wouldn't matter regardless here | |
| Area = Part.Face(sketch.Shape).Area | |
| # General helix formula; not actually used here since devolves to just the | |
| # height in this orientation. | |
| helixLength = ( | |
| helix.Height.Value | |
| / helix.Pitch.Value | |
| * math.sqrt((math.pi * Radius) ** 2 + helix.Pitch.Value**2) | |
| ) | |
| Volume = Area * helixLength | |
| self.assertAlmostEqual(Area, 1) | |
| self.assertAlmostEqual(helixLength, helix.Height.Value) | |
| self.assertAlmostEqual(helix.Shape.Volume, Volume, 2) | |
| self.assertEqual(body.Shape.ElementMapSize, 58) | |
| def testPartDesignElementMapPocket(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| box = self.Doc.addObject("PartDesign::AdditiveBox", "Box") | |
| body.addObject(box) | |
| sketch = self.Doc.addObject("Sketcher::SketchObject", "Sketch") | |
| sketch.AttachmentSupport = (box, "Face6") | |
| sketch.MapMode = "FlatFace" | |
| TestSketcherApp.CreateRectangleSketch(sketch, (1, 1), (1, 1)) | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Act | |
| pocket = self.Doc.addObject("PartDesign::Pocket", "Pocket") | |
| pocket.Profile = sketch | |
| pocket.Length = 5 | |
| pocket.Direction = (0, 0, -1) | |
| pocket.ReferenceAxis = (sketch, ["N_Axis"]) | |
| pocket.Refine = True | |
| body.addObject(sketch) | |
| body.addObject(pocket) | |
| self.Doc.recompute() | |
| # Assert | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 51) | |
| self.assertEqual(body.Shape.ElementMapSize, 51) | |
| self.assertEqual(sketch.Shape.ElementMapSize, 12) | |
| self.assertEqual(pocket.Shape.ElementMapSize, 51) | |
| self.assertNotEqual( | |
| pocket.Shape.ElementReverseMap["Vertex1"], "Vertex1" | |
| ) # NewName, not OldName | |
| self.assertEqual(self.countFacesEdgesVertexes(pocket.Shape.ElementReverseMap), (11, 24, 16)) | |
| volume = 1000 - 5 * 1 * 1 | |
| self.assertAlmostEqual(pocket.Shape.Volume, volume) | |
| def testPartDesignElementMapHole(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| box = self.Doc.addObject("PartDesign::AdditiveBox", "Box") | |
| body.addObject(box) | |
| self.Doc.recompute() | |
| sketch = self.Doc.addObject("Sketcher::SketchObject", "Sketch") | |
| sketch.AttachmentSupport = (box, "Face6") | |
| sketch.MapMode = "FlatFace" | |
| TestSketcherApp.CreateCircleSketch(sketch, (5, 5), 1) | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Act | |
| hole = self.Doc.addObject("PartDesign::Hole", "Hole") | |
| hole.Profile = sketch | |
| body.addObject(sketch) | |
| body.addObject(hole) | |
| self.Doc.recompute() | |
| # Assert | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 32) | |
| self.assertEqual(body.Shape.ElementMapSize, 32) | |
| self.assertEqual(sketch.Shape.ElementMapSize, 2) | |
| self.assertNotEqual( | |
| body.Shape.ElementReverseMap["Vertex1"], "Vertex1" | |
| ) # NewName, not OldName | |
| self.assertEqual(self.countFacesEdgesVertexes(body.Shape.ElementReverseMap), (7, 15, 10)) | |
| volume = 1000 - 10 * math.pi * 3 * 3 | |
| self.assertAlmostEqual(hole.Shape.Volume, volume) | |
| def testPartDesignElementMapGroove(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| box = self.Doc.addObject("PartDesign::AdditiveBox", "Box") | |
| body.addObject(box) | |
| groove = self.Doc.addObject("PartDesign::Groove", "Groove") | |
| body.addObject(groove) | |
| groove.ReferenceAxis = (self.Doc.getObject("Y_Axis"), [""]) | |
| groove.Angle = 360.0 | |
| groove.Profile = (box, ["Face6"]) | |
| groove.ReferenceAxis = (box, ["Edge9"]) | |
| groove.Midplane = 0 | |
| groove.Reversed = 0 | |
| groove.Base = App.Vector(0, 0, 0) | |
| self.Doc.recompute() | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Assert | |
| revMap = groove.Shape.ElementReverseMap # body.Shape.childShapes()[0].ElementReverseMap | |
| self.assertEqual(self.countFacesEdgesVertexes(revMap), (5, 9, 6)) | |
| volume = 785.3981633974482 # TODO: math formula to calc this. Maybe make a sketch as the Profile. | |
| self.assertAlmostEqual(groove.Shape.Volume, volume) | |
| def testPartDesignElementMapSubLoft(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| box = self.Doc.addObject("PartDesign::AdditiveBox", "Box") | |
| body.addObject(box) | |
| sketch = self.Doc.addObject("Sketcher::SketchObject", "Sketch") | |
| TestSketcherApp.CreateRectangleSketch(sketch, (1, 1), (1, 1)) | |
| sketch2 = self.Doc.addObject("Sketcher::SketchObject", "Sketch") | |
| TestSketcherApp.CreateRectangleSketch(sketch2, (1, 1), (2, 2)) | |
| sketch2.Placement.move(App.Vector(0, 0, 3)) | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Act | |
| loft = self.Doc.addObject("PartDesign::SubtractiveLoft", "SubLoft") | |
| loft.Profile = sketch | |
| loft.Sections = [sketch2] | |
| body.addObject(loft) | |
| self.Doc.recompute() | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Assert | |
| revMap = loft.Shape.ElementReverseMap # body.Shape.childShapes()[0].ElementReverseMap | |
| self.assertEqual(self.countFacesEdgesVertexes(revMap), (11, 24, 16)) | |
| volume = 993 # TODO: math formula to calc this. | |
| self.assertAlmostEqual(loft.Shape.Volume, volume) | |
| def testPartDesignElementMapSubPipe(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| box = self.Doc.addObject("PartDesign::AdditiveBox", "Box") | |
| body.addObject(box) | |
| sketch = self.Doc.addObject("Sketcher::SketchObject", "Sketch") | |
| TestSketcherApp.CreateRectangleSketch(sketch, (0, 0), (1, 1)) | |
| sketch2 = self.Doc.addObject("Sketcher::SketchObject", "Sketch001") | |
| sketch2.AttachmentSupport = (self.Doc.getObject("XZ_Plane"), [""]) | |
| sketch2.addGeometry(Part.LineSegment(App.Vector(0, 0, 0), App.Vector(0, 1, 0))) | |
| sketch2.Placement = App.Placement( | |
| App.Vector(0, 0, 0), App.Rotation(App.Vector(1.00, 0.00, 0.00), 90.00) | |
| ) | |
| # Need to set sketch2 placement? | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Act | |
| pipe = self.Doc.addObject("PartDesign::SubtractivePipe", "SubPipe") | |
| pipe.Profile = sketch | |
| pipe.Spine = sketch2 | |
| body.addObject(sketch) | |
| body.addObject(sketch2) | |
| body.addObject(pipe) | |
| self.Doc.recompute() | |
| # Assert | |
| self.assertAlmostEqual(body.Shape.Volume, 999) | |
| self.assertAlmostEqual(body.Shape.BoundBox.XMin, 0) | |
| self.assertAlmostEqual(body.Shape.BoundBox.YMin, 0) | |
| self.assertAlmostEqual(body.Shape.BoundBox.ZMin, 0) | |
| self.assertAlmostEqual(body.Shape.BoundBox.XMax, 10) | |
| self.assertAlmostEqual(body.Shape.BoundBox.YMax, 10) | |
| self.assertAlmostEqual(body.Shape.BoundBox.ZMax, 10) | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 44) | |
| revMap = body.Shape.ElementReverseMap # | |
| self.assertEqual(self.countFacesEdgesVertexes(revMap), (9, 21, 14)) | |
| def testPartDesignElementMapSubHelix(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| box = self.Doc.addObject("PartDesign::AdditiveBox", "Box") | |
| body.addObject(box) | |
| sketch = self.Doc.addObject("Sketcher::SketchObject", "Sketch") | |
| TestSketcherApp.CreateRectangleSketch(sketch, (5, 5), (1, 1)) | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Act | |
| helix = self.Doc.addObject("PartDesign::SubtractiveHelix", "SubHelix") | |
| helix.Profile = sketch | |
| helix.ReferenceAxis = (self.Doc.getObject("Sketch"), ["V_Axis"]) | |
| helix.Reversed = True | |
| body.addObject(sketch) | |
| body.addObject(helix) | |
| self.Doc.recompute() | |
| # Assert | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 50) | |
| revMap = body.Shape.childShapes()[0].ElementReverseMap | |
| self.assertEqual(self.countFacesEdgesVertexes(revMap), (10, 24, 16)) | |
| volume = 991.3606 # TODO: math formula to calc this. | |
| self.assertAlmostEqual(helix.Shape.Volume, volume, 4) | |
| def testPartDesignElementMapChamfer(self): | |
| """Test Chamfer ( and FeatureDressup )""" | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| box = self.Doc.addObject("PartDesign::AdditiveBox", "Box") | |
| if body.Shape.ElementMapVersion == "": # Skip without element maps. | |
| return | |
| chamfer = self.Doc.addObject("PartDesign::Chamfer", "Chamfer") | |
| chamfer.Base = ( | |
| box, | |
| [ | |
| "Edge1", | |
| "Edge2", | |
| "Edge3", | |
| "Edge4", | |
| "Edge5", | |
| "Edge6", | |
| "Edge7", | |
| "Edge8", | |
| "Edge9", | |
| "Edge10", | |
| "Edge11", | |
| "Edge12", | |
| ], | |
| ) | |
| chamfer.Size = 1 | |
| chamfer.UseAllEdges = True | |
| # Act / Assert | |
| body.addObject(box) | |
| body.addObject(chamfer) | |
| self.Doc.recompute() | |
| reverseMap = body.Shape.childShapes()[0].ElementReverseMap | |
| faces = [name for name in reverseMap.keys() if name.startswith("Face")] | |
| edges = [name for name in reverseMap.keys() if name.startswith("Edge")] | |
| vertexes = [name for name in reverseMap.keys() if name.startswith("Vertex")] | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 98) | |
| self.assertEqual(len(reverseMap), 98) | |
| self.assertEqual(len(faces), 26) # 6 Faces become 26 ( +8 + 2*6 ) | |
| self.assertEqual(len(edges), 48) # 12 Edges become 48 | |
| self.assertEqual(len(vertexes), 24) # 8 Vertices become 24 | |
| def testPartDesignElementMapFillet(self): | |
| """Test Fillet ( and FeatureDressup )""" | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| box = self.Doc.addObject("PartDesign::AdditiveBox", "Box") | |
| if body.Shape.ElementMapVersion == "": # Skip without element maps. | |
| return | |
| fillet = self.Doc.addObject("PartDesign::Fillet", "Fillet") | |
| fillet.Base = ( | |
| box, | |
| [ | |
| "Edge1", | |
| "Edge2", | |
| "Edge3", | |
| "Edge4", | |
| "Edge5", | |
| "Edge6", | |
| "Edge7", | |
| "Edge8", | |
| "Edge9", | |
| "Edge10", | |
| "Edge11", | |
| "Edge12", | |
| ], | |
| ) | |
| # Act / Assert | |
| body.addObject(box) | |
| body.addObject(fillet) | |
| self.Doc.recompute() | |
| reverseMap = body.Shape.childShapes()[0].ElementReverseMap | |
| faces = [name for name in reverseMap.keys() if name.startswith("Face")] | |
| edges = [name for name in reverseMap.keys() if name.startswith("Edge")] | |
| vertexes = [name for name in reverseMap.keys() if name.startswith("Vertex")] | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 106) | |
| self.assertEqual(len(reverseMap), 106) | |
| self.assertEqual(len(faces), 26) # 6 Faces become 26 ( +8 + 2*6 ) | |
| self.assertEqual(len(edges), 56) # 12 Edges become 56 Why? | |
| self.assertEqual(len(vertexes), 24) # 8 Vertices become 24 | |
| def testPartDesignElementMapTransform(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| box = self.Doc.addObject("PartDesign::AdditiveBox", "Box") | |
| if body.Shape.ElementMapVersion == "": # Skip without element maps. | |
| return | |
| multitransform = self.Doc.addObject("PartDesign::MultiTransform", "MultiTransform") | |
| scaled = self.Doc.addObject("PartDesign::Scaled", "Scaled") | |
| scaled.Factor = 2 | |
| scaled.Occurrences = 2 | |
| multitransform.Transformations = scaled | |
| multitransform.Shape = box.Shape | |
| # Act / Assert | |
| self.Doc.recompute() | |
| body.addObject(box) | |
| body.addObject(multitransform) | |
| self.assertEqual(len(body.Shape.childShapes()), 0) | |
| self.Doc.recompute() | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 26) | |
| def testPartDesignElementMapShapeBinder(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| box = self.Doc.addObject("PartDesign::AdditiveBox", "Box") | |
| shapebinder = self.Doc.addObject("PartDesign::ShapeBinder", "ShapeBinder") | |
| if body.Shape.ElementMapVersion == "": # Skip without element maps. | |
| return | |
| # Act / Assert | |
| body.addObject(box) | |
| body.addObject(shapebinder) | |
| shapebinder.Support = [box] | |
| self.Doc.recompute() | |
| self.assertEqual(len(shapebinder.Shape.childShapes()), 1) | |
| self.assertEqual(shapebinder.Shape.childShapes()[0].ElementMapSize, 26) | |
| def testPartDesignElementMapSubShapeBinder(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| box = self.Doc.addObject("PartDesign::AdditiveBox", "Box") | |
| subshapebinder = self.Doc.addObject("PartDesign::SubShapeBinder", "SubShapeBinder") | |
| if body.Shape.ElementMapVersion == "": # Skip without element maps. | |
| return | |
| # Act / Assert | |
| body.addObject(box) | |
| body.addObject(subshapebinder) | |
| subshapebinder.Support = [(box, ["Face1"])] | |
| self.assertEqual(len(body.Shape.childShapes()), 0) | |
| self.Doc.recompute() | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(subshapebinder.Shape.childShapes()[0].ElementMapSize, 9) | |
| def testSketchElementMap(self): | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| sketch = self.Doc.addObject("Sketcher::SketchObject", "Sketch") | |
| TestSketcherApp.CreateRectangleSketch(sketch, (0, 0), (1, 1)) | |
| body.addObject(sketch) | |
| self.Doc.recompute() | |
| self.assertEqual(sketch.Shape.ElementMapSize, 12) | |
| pad = self.Doc.addObject("PartDesign::Pad", "Pad") | |
| pad.Profile = sketch | |
| body.addObject(pad) | |
| self.Doc.recompute() | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Assert | |
| self.assertEqual(sketch.Shape.ElementMapSize, 12) | |
| self.assertEqual(pad.Shape.ElementMapSize, 30) # The sketch plus the pad in the map | |
| # TODO: differing results between main and LS3 on these values. Does it matter? | |
| # self.assertEqual(body.Shape.ElementMapSize,0) # 8? | |
| # self.assertEqual(body.Shape.ElementMapSize,30) # 26 | |
| def testPlaneElementMap(self): | |
| plane = self.Doc.addObject("Part::Plane", "Plane") | |
| plane.Length = 10 | |
| plane.Width = 10 | |
| self.Doc.recompute() | |
| self.assertEqual(plane.Shape.ElementMapSize, 0) | |
| pad = self.Doc.addObject("PartDesign::Pad", "Pad") | |
| pad.Profile = plane | |
| self.Doc.recompute() | |
| if pad.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| # Assert | |
| self.assertEqual(plane.Shape.ElementMapSize, 0) | |
| self.assertEqual(pad.Shape.ElementMapSize, 26) | |
| def testChangeSketch(self): | |
| # Arrange | |
| doc = self.Doc | |
| body = doc.addObject("PartDesign::Body", "Body") | |
| # Make first offset cube Pad | |
| padSketch = doc.addObject("Sketcher::SketchObject", "Sketch") | |
| body.addObject(padSketch) | |
| TestSketcherApp.CreateRectangleSketch(padSketch, (0, 0), (31.37, 25.2)) | |
| doc.recompute() | |
| pad = doc.addObject("PartDesign::Pad", "Pad") | |
| body.addObject(pad) | |
| pad.Profile = padSketch | |
| pad.Length = 10 | |
| doc.recompute() | |
| sketch001 = body.newObject("Sketcher::SketchObject", "Sketch001") | |
| sketch001 = doc.Sketch001 | |
| sketch001.AttachmentSupport = ( | |
| doc.getObject("Pad"), | |
| [ | |
| "Face6", | |
| ], | |
| ) | |
| sketch001.MapMode = "FlatFace" | |
| App.ActiveDocument.recompute() | |
| geoList = [] | |
| geoList.append( | |
| Part.Circle( | |
| App.Vector(15.093666, 13.036922, 0.000000), | |
| App.Vector(0.000000, 0.000000, 1.000000), | |
| 5.000000, | |
| ) | |
| ) | |
| sketch001.addGeometry(geoList, False) | |
| del geoList | |
| sketch001.addConstraint(Sketcher.Constraint("Radius", 0, 5.000000)) | |
| doc.recompute() | |
| pad001 = body.newObject("PartDesign::Pad", "Pad001") | |
| pad001.Profile = doc.getObject("Sketch001") | |
| pad001.Length = 10 | |
| App.ActiveDocument.recompute() | |
| pad001.ReferenceAxis = (doc.getObject("Sketch001"), ["N_Axis"]) | |
| sketch001.Visibility = False | |
| App.ActiveDocument.recompute() | |
| pad001.Length = 10.000000 | |
| pad001.TaperAngle = 0.000000 | |
| pad001.UseCustomVector = 0 | |
| pad001.Direction = (0, 0, 1) | |
| pad001.ReferenceAxis = (doc.getObject("Sketch001"), ["N_Axis"]) | |
| pad001.AlongSketchNormal = 1 | |
| pad001.Type = 0 | |
| pad001.UpToFace = None | |
| pad001.Reversed = 0 | |
| pad001.SideType = "One side" | |
| pad001.Offset = 0 | |
| doc.recompute() | |
| doc.getObject("Pad").Visibility = False | |
| doc.getObject("Sketch001").Visibility = False | |
| # Modify the original sketch to generate TNP issue | |
| geoList = [] | |
| geoList.append( | |
| Part.LineSegment( | |
| App.Vector(2.510468, 22.837425, 0.000000), | |
| App.Vector(2.510468, 19.933617, 0.000000), | |
| ) | |
| ) | |
| geoList.append( | |
| Part.LineSegment( | |
| App.Vector(2.510468, 19.933617, 0.000000), | |
| App.Vector(4.869811, 19.933617, 0.000000), | |
| ) | |
| ) | |
| geoList.append( | |
| Part.LineSegment( | |
| App.Vector(4.869811, 19.933617, 0.000000), | |
| App.Vector(4.869811, 22.837425, 0.000000), | |
| ) | |
| ) | |
| geoList.append( | |
| Part.LineSegment( | |
| App.Vector(4.869811, 22.837425, 0.000000), | |
| App.Vector(2.510468, 22.837425, 0.000000), | |
| ) | |
| ) | |
| padSketch.addGeometry(geoList, False) | |
| del geoList | |
| constraintList = [] | |
| constraintList.append(Sketcher.Constraint("Coincident", 4, 2, 5, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 5, 2, 6, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 6, 2, 7, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 7, 2, 4, 1)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 4)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 6)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 5)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 7)) | |
| padSketch.addConstraint(constraintList) | |
| del constraintList | |
| doc.recompute() | |
| # Assert | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| self.assertEqual(body.Shape.BoundBox.XMin, 0) | |
| self.assertEqual(body.Shape.BoundBox.YMin, 0) | |
| self.assertEqual(body.Shape.BoundBox.ZMin, 0) | |
| self.assertEqual(body.Shape.BoundBox.XMax, 31.37) | |
| self.assertEqual(body.Shape.BoundBox.YMax, 25.2) | |
| self.assertEqual(body.Shape.BoundBox.ZMax, 20) | |
| def testApplyFillet(self): | |
| # Arrange | |
| doc = self.Doc | |
| body = doc.addObject("PartDesign::Body", "Body") | |
| # Make first offset cube Pad | |
| padSketch = doc.addObject("Sketcher::SketchObject", "Sketch") | |
| body.addObject(padSketch) | |
| TestSketcherApp.CreateRectangleSketch(padSketch, (0, 0), (31.37, 25.2)) | |
| doc.recompute() | |
| pad = doc.addObject("PartDesign::Pad", "Pad") | |
| body.addObject(pad) | |
| pad.Profile = padSketch | |
| pad.Length = 10 | |
| doc.recompute() | |
| sketch001 = body.newObject("Sketcher::SketchObject", "Sketch001") | |
| sketch001.AttachmentSupport = ( | |
| doc.getObject("Pad"), | |
| [ | |
| "Face6", | |
| ], | |
| ) | |
| sketch001.MapMode = "FlatFace" | |
| geoList = [] | |
| geoList.append( | |
| Part.Circle( | |
| App.Vector(15.093666, 13.036922, 0.000000), | |
| App.Vector(0.000000, 0.000000, 1.000000), | |
| 5.000000, | |
| ) | |
| ) | |
| sketch001.addGeometry(geoList, False) | |
| del geoList | |
| sketch001.addConstraint(Sketcher.Constraint("Radius", 0, 5.000000)) | |
| doc.recompute() | |
| pad001 = body.newObject("PartDesign::Pad", "Pad001") | |
| pad001.Profile = doc.getObject("Sketch001") | |
| pad001.Length = 10 | |
| App.ActiveDocument.recompute() | |
| pad001.ReferenceAxis = (doc.getObject("Sketch001"), ["N_Axis"]) | |
| sketch001.Visibility = False | |
| App.ActiveDocument.recompute() | |
| pad001.Length = 10.000000 | |
| pad001.TaperAngle = 0.000000 | |
| pad001.UseCustomVector = 0 | |
| pad001.Direction = (0, 0, 1) | |
| pad001.ReferenceAxis = (doc.getObject("Sketch001"), ["N_Axis"]) | |
| pad001.AlongSketchNormal = 1 | |
| pad001.Type = 0 | |
| pad001.UpToFace = None | |
| pad001.Reversed = 0 | |
| pad001.SideType = "One side" | |
| pad001.Offset = 0 | |
| doc.recompute() | |
| doc.getObject("Pad").Visibility = False | |
| doc.getObject("Sketch001").Visibility = False | |
| area1 = pad.Shape.Area | |
| # Act | |
| doc.getObject("Sketch").fillet( | |
| 2, | |
| 3, | |
| App.Vector(6.673934, 25.000000, 0), | |
| App.Vector(0.000000, 21.980343, 0), | |
| 4.740471, | |
| True, | |
| True, | |
| False, | |
| ) | |
| doc.recompute() | |
| area2 = pad.Shape.Area | |
| # Assert | |
| if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| self.assertEqual(body.Shape.BoundBox.XMin, 0) | |
| self.assertEqual(body.Shape.BoundBox.YMin, 0) | |
| self.assertEqual(body.Shape.BoundBox.ZMin, 0) | |
| self.assertEqual(body.Shape.BoundBox.XMax, 31.37) | |
| self.assertAlmostEqual(body.Shape.BoundBox.YMax, 25.2) | |
| self.assertEqual(body.Shape.BoundBox.ZMax, 20) | |
| self.assertNotEqual(area1, area2) | |
| def testShapeBinder(self): | |
| doc = self.Doc | |
| self.Body = doc.addObject("PartDesign::Body", "TNP_Test_Body_SubShape") | |
| doc.getObject("TNP_Test_Body_SubShape").Label = "TNP_Test_Body_SubShape" | |
| doc.recompute() | |
| doc.getObject("TNP_Test_Body_SubShape").newObject("Sketcher::SketchObject", "Sketch") | |
| doc.Sketch.AttachmentSupport = (doc.getObject("XY_Plane"), [""]) | |
| doc.Sketch.MapMode = "FlatFace" | |
| doc.recompute() | |
| geoList = [] | |
| geoList.append( | |
| Part.LineSegment( | |
| App.Vector(0.000000, 0.000000, 0.000000), | |
| App.Vector(35.000000, 0.000000, 0.000000), | |
| ) | |
| ) | |
| geoList.append( | |
| Part.LineSegment( | |
| App.Vector(35.000000, 0.000000, 0.000000), | |
| App.Vector(35.000000, 25.000000, 0.000000), | |
| ) | |
| ) | |
| geoList.append( | |
| Part.LineSegment( | |
| App.Vector(35.000000, 25.000000, 0.000000), | |
| App.Vector(0.000000, 25.000000, 0.000000), | |
| ) | |
| ) | |
| geoList.append( | |
| Part.LineSegment( | |
| App.Vector(0.000000, 25.000000, 0.000000), | |
| App.Vector(0.000000, 0.000000, 0.000000), | |
| ) | |
| ) | |
| doc.Sketch.addGeometry(geoList, False) | |
| del geoList | |
| constraintList = [] | |
| constraintList.append(Sketcher.Constraint("Coincident", 0, 2, 1, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 1, 2, 2, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 2, 2, 3, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 3, 2, 0, 1)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 0)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 2)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 1)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 3)) | |
| doc.Sketch.addConstraint(constraintList) | |
| del constraintList | |
| doc.Sketch.addConstraint(Sketcher.Constraint("Distance", 1, 1, 3, 2, 35.000000)) | |
| doc.Sketch.addConstraint(Sketcher.Constraint("Distance", 0, 1, 2, 2, 25.000000)) | |
| doc.Sketch.addConstraint(Sketcher.Constraint("Coincident", 0, 1, -1, 1)) | |
| doc.recompute() | |
| doc.getObject("TNP_Test_Body_SubShape").newObject("PartDesign::Pad", "Pad") | |
| doc.Pad.Profile = doc.Sketch | |
| doc.Pad.Length = 10 | |
| doc.recompute() | |
| doc.Pad.ReferenceAxis = (doc.Sketch, ["N_Axis"]) | |
| doc.Sketch.Visibility = False | |
| doc.recompute() | |
| doc.Pad.Length = 10.000000 | |
| doc.Pad.TaperAngle = 0.000000 | |
| doc.Pad.UseCustomVector = 0 | |
| doc.Pad.Direction = (0, 0, 1) | |
| doc.Pad.ReferenceAxis = (doc.Sketch, ["N_Axis"]) | |
| doc.Pad.AlongSketchNormal = 1 | |
| doc.Pad.Type = 0 | |
| doc.Pad.UpToFace = None | |
| doc.Pad.Reversed = 0 | |
| doc.Pad.SideType = "One side" | |
| doc.Pad.Offset = 0 | |
| doc.recompute() | |
| doc.Sketch.Visibility = False | |
| doc.addObject("PartDesign::Body", "TNP_Test_Body_Second") | |
| doc.getObject("TNP_Test_Body_Second").Label = "TNP_Test_Body_Second" | |
| doc.recompute() | |
| obj = doc.getObject("TNP_Test_Body_Second").newObject( | |
| "PartDesign::ShapeBinder", "ShapeBinder" | |
| ) | |
| obj.Support = (doc.getObject("TNP_Test_Body_SubShape"), ["Face6"]) | |
| doc.recompute() | |
| doc.getObject("TNP_Test_Body_Second").newObject("Sketcher::SketchObject", "Sketch001") | |
| doc.getObject("Sketch001").AttachmentSupport = ( | |
| doc.getObject("ShapeBinder"), | |
| [""], | |
| ) | |
| doc.getObject("Sketch001").MapMode = "FlatFace" | |
| doc.recompute() | |
| geoList = [] | |
| geoList.append( | |
| Part.Circle( | |
| App.Vector(14.725412, 16.666899, 0.000000), | |
| App.Vector(0.000000, 0.000000, 1.000000), | |
| 2.162720, | |
| ) | |
| ) | |
| doc.getObject("Sketch001").addGeometry(geoList, False) | |
| del geoList | |
| doc.recompute() | |
| doc.getObject("TNP_Test_Body_Second").newObject("PartDesign::Pad", "Pad001") | |
| doc.getObject("Pad001").Profile = doc.getObject("Sketch001") | |
| doc.getObject("Pad001").Length = 10 | |
| doc.recompute() | |
| doc.getObject("Pad001").ReferenceAxis = (doc.getObject("Sketch001"), ["N_Axis"]) | |
| doc.getObject("Sketch001").Visibility = False | |
| doc.recompute() | |
| doc.getObject("Pad001").Length = 10.000000 | |
| doc.getObject("Pad001").TaperAngle = 0.000000 | |
| doc.getObject("Pad001").UseCustomVector = 0 | |
| doc.getObject("Pad001").Direction = (0, 0, 1) | |
| doc.getObject("Pad001").ReferenceAxis = (doc.getObject("Sketch001"), ["N_Axis"]) | |
| doc.getObject("Pad001").AlongSketchNormal = 1 | |
| doc.getObject("Pad001").Type = 0 | |
| doc.getObject("Pad001").UpToFace = None | |
| doc.getObject("Pad001").Reversed = 0 | |
| doc.getObject("Pad001").SideType = "One side" | |
| doc.getObject("Pad001").Offset = 0 | |
| doc.recompute() | |
| doc.getObject("ShapeBinder").Visibility = False | |
| doc.getObject("Sketch001").Visibility = False | |
| geoList = [] | |
| geoList.append( | |
| Part.LineSegment( | |
| App.Vector(28.380075, 21.486303, 0.000000), | |
| App.Vector(28.380075, 15.462212, 0.000000), | |
| ) | |
| ) | |
| geoList.append( | |
| Part.LineSegment( | |
| App.Vector(28.380075, 15.462212, 0.000000), | |
| App.Vector(32.797741, 15.462212, 0.000000), | |
| ) | |
| ) | |
| geoList.append( | |
| Part.LineSegment( | |
| App.Vector(32.797741, 15.462212, 0.000000), | |
| App.Vector(32.797741, 21.486303, 0.000000), | |
| ) | |
| ) | |
| geoList.append( | |
| Part.LineSegment( | |
| App.Vector(32.797741, 21.486303, 0.000000), | |
| App.Vector(28.380075, 21.486303, 0.000000), | |
| ) | |
| ) | |
| doc.Sketch.addGeometry(geoList, False) | |
| del geoList | |
| constraintList = [] | |
| constraintList.append(Sketcher.Constraint("Coincident", 4, 2, 5, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 5, 2, 6, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 6, 2, 7, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 7, 2, 4, 1)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 4)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 6)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 5)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 7)) | |
| doc.Sketch.addConstraint(constraintList) | |
| del constraintList | |
| doc.recompute() | |
| # Assert | |
| if self.Body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| self.assertEqual(self.Body.Shape.BoundBox.XMin, 0) | |
| self.assertEqual(self.Body.Shape.BoundBox.YMin, 0) | |
| self.assertEqual(self.Body.Shape.BoundBox.ZMin, 0) | |
| self.assertEqual(self.Body.Shape.BoundBox.XMax, 35) | |
| self.assertEqual(self.Body.Shape.BoundBox.YMax, 25) | |
| self.assertEqual(self.Body.Shape.BoundBox.ZMax, 10) | |
| def testSubShapeBinder(self): | |
| doc = self.Doc | |
| self.Body = doc.addObject("PartDesign::Body", "Body") | |
| doc.Body.Label = "Body" | |
| doc.recompute() | |
| doc.Body.newObject("Sketcher::SketchObject", "Sketch") | |
| doc.Sketch.AttachmentSupport = (doc.getObject("XY_Plane"), [""]) | |
| doc.Sketch.MapMode = "FlatFace" | |
| doc.recompute() | |
| geoList = [] | |
| geoList.append( | |
| Part.LineSegment( | |
| App.Vector(0.000000, 0.000000, 0.000000), | |
| App.Vector(35.000000, 0.000000, 0.000000), | |
| ) | |
| ) | |
| geoList.append( | |
| Part.LineSegment( | |
| App.Vector(35.000000, 0.000000, 0.000000), | |
| App.Vector(35.000000, 25.000000, 0.000000), | |
| ) | |
| ) | |
| geoList.append( | |
| Part.LineSegment( | |
| App.Vector(35.000000, 25.000000, 0.000000), | |
| App.Vector(0.000000, 25.000000, 0.000000), | |
| ) | |
| ) | |
| geoList.append( | |
| Part.LineSegment( | |
| App.Vector(0.000000, 25.000000, 0.000000), | |
| App.Vector(0.000000, 0.000000, 0.000000), | |
| ) | |
| ) | |
| doc.Sketch.addGeometry(geoList, False) | |
| del geoList | |
| constraintList = [] | |
| constraintList.append(Sketcher.Constraint("Coincident", 0, 2, 1, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 1, 2, 2, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 2, 2, 3, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 3, 2, 0, 1)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 0)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 2)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 1)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 3)) | |
| doc.Sketch.addConstraint(constraintList) | |
| del constraintList | |
| doc.Sketch.addConstraint(Sketcher.Constraint("Distance", 1, 1, 3, 2, 35.000000)) | |
| doc.Sketch.addConstraint(Sketcher.Constraint("Distance", 0, 1, 2, 2, 25.000000)) | |
| doc.Sketch.addConstraint(Sketcher.Constraint("Coincident", 0, 1, -1, 1)) | |
| doc.recompute() | |
| doc.Body.newObject("PartDesign::Pad", "Pad") | |
| doc.Pad.Profile = doc.Sketch | |
| doc.Pad.Length = 10 | |
| doc.recompute() | |
| doc.Pad.ReferenceAxis = (doc.Sketch, ["N_Axis"]) | |
| doc.Sketch.Visibility = False | |
| doc.Pad.Length = 10.000000 | |
| doc.Pad.TaperAngle = 0.000000 | |
| doc.Pad.UseCustomVector = 0 | |
| doc.Pad.Direction = (0, 0, 1) | |
| doc.Pad.ReferenceAxis = (doc.Sketch, ["N_Axis"]) | |
| doc.Pad.AlongSketchNormal = 1 | |
| doc.Pad.Type = 0 | |
| doc.Pad.UpToFace = None | |
| doc.Pad.Reversed = 0 | |
| doc.Pad.SideType = "One side" | |
| doc.Pad.Offset = 0 | |
| doc.recompute() | |
| doc.Sketch.Visibility = False | |
| doc.addObject("PartDesign::Body", "Body001") | |
| doc.getObject("Body001").Label = "Body" | |
| doc.recompute() | |
| binder = doc.getObject("Body001").newObject("PartDesign::SubShapeBinder", "Binder") | |
| binder.Support = self.Body | |
| doc.getObject("Body001").newObject("Sketcher::SketchObject", "Sketch001") | |
| doc.getObject("Sketch001").AttachmentSupport = ( | |
| doc.getObject("Binder"), | |
| [ | |
| "Face6", | |
| ], | |
| ) | |
| doc.getObject("Sketch001").MapMode = "FlatFace" | |
| doc.recompute() | |
| geoList = [] | |
| geoList.append( | |
| Part.Circle( | |
| App.Vector(16.566162, 13.537925, 0.000000), | |
| App.Vector(0.000000, 0.000000, 1.000000), | |
| 2.197371, | |
| ) | |
| ) | |
| doc.getObject("Sketch001").addGeometry(geoList, False) | |
| del geoList | |
| doc.recompute() | |
| ### Begin command PartDesign_Pad | |
| doc.getObject("Body001").newObject("PartDesign::Pad", "Pad001") | |
| doc.Pad001.Profile = doc.getObject("Sketch001") | |
| doc.Pad001.Length = 10 | |
| doc.recompute() | |
| doc.Pad001.ReferenceAxis = (doc.getObject("Sketch001"), ["N_Axis"]) | |
| doc.getObject("Sketch001").Visibility = False | |
| doc.recompute() | |
| doc.Pad001.Length = 10.000000 | |
| doc.Pad001.TaperAngle = 0.000000 | |
| doc.Pad001.UseCustomVector = 0 | |
| doc.Pad001.Direction = (0, 0, 1) | |
| doc.Pad001.ReferenceAxis = (doc.getObject("Sketch001"), ["N_Axis"]) | |
| doc.Pad001.AlongSketchNormal = 1 | |
| doc.Pad001.Type = 0 | |
| doc.Pad001.UpToFace = None | |
| doc.Pad001.Reversed = 0 | |
| doc.Pad001.SideType = "One side" | |
| doc.Pad001.Offset = 0 | |
| doc.recompute() | |
| doc.getObject("Binder").Visibility = False | |
| doc.getObject("Sketch001").Visibility = False | |
| geoList = [] | |
| geoList.append( | |
| Part.LineSegment( | |
| App.Vector(30.009926, 21.026653, 0.000000), | |
| App.Vector(30.009926, 16.425089, 0.000000), | |
| ) | |
| ) | |
| geoList.append( | |
| Part.LineSegment( | |
| App.Vector(30.009926, 16.425089, 0.000000), | |
| App.Vector(31.994911, 16.425089, 0.000000), | |
| ) | |
| ) | |
| geoList.append( | |
| Part.LineSegment( | |
| App.Vector(31.994911, 16.425089, 0.000000), | |
| App.Vector(31.994911, 21.026653, 0.000000), | |
| ) | |
| ) | |
| geoList.append( | |
| Part.LineSegment( | |
| App.Vector(31.994911, 21.026653, 0.000000), | |
| App.Vector(30.009926, 21.026653, 0.000000), | |
| ) | |
| ) | |
| doc.Sketch.addGeometry(geoList, False) | |
| del geoList | |
| constraintList = [] | |
| constraintList.append(Sketcher.Constraint("Coincident", 4, 2, 5, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 5, 2, 6, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 6, 2, 7, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 7, 2, 4, 1)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 4)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 6)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 5)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 7)) | |
| doc.Sketch.addConstraint(constraintList) | |
| del constraintList | |
| doc.recompute() | |
| # Assert | |
| if self.Body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| self.assertEqual(self.Body.Shape.BoundBox.XMin, 0) | |
| self.assertEqual(self.Body.Shape.BoundBox.YMin, 0) | |
| self.assertEqual(self.Body.Shape.BoundBox.ZMin, 0) | |
| self.assertEqual(self.Body.Shape.BoundBox.XMax, 35) | |
| self.assertEqual(self.Body.Shape.BoundBox.YMax, 25) | |
| self.assertEqual(self.Body.Shape.BoundBox.ZMax, 10) | |
| def testPartDesignTNPChamfer(self): | |
| """Test Chamfer""" | |
| # Arrange | |
| doc = self.Doc | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| box = self.Doc.addObject("PartDesign::AdditiveBox", "Box") | |
| body.addObject(box) | |
| self.Doc.recompute() | |
| volume1 = body.Shape.Volume | |
| chamfer = self.Doc.addObject("PartDesign::Chamfer", "Chamfer") | |
| chamfer.Base = ( | |
| box, | |
| [ | |
| "Edge1", | |
| "Edge5", | |
| "Edge7", | |
| ], | |
| ) | |
| chamfer.Size = 1 | |
| body.addObject(chamfer) | |
| self.Doc.recompute() | |
| volume2 = body.Shape.Volume | |
| doc.Body.newObject("Sketcher::SketchObject", "Sketch") | |
| doc.Sketch.AttachmentSupport = (chamfer, "Face8") | |
| doc.Sketch.MapMode = "FlatFace" | |
| doc.recompute() | |
| x1, x2, y1, y2 = ( | |
| 10 / math.sqrt(2) - math.sqrt(2), | |
| 10 / math.sqrt(2) + math.sqrt(2), | |
| 6, | |
| 11, | |
| ) | |
| geoList = [] | |
| geoList.append(Part.LineSegment(App.Vector(x1, y1, 0.0), App.Vector(x1, y2, 0.0))) | |
| geoList.append(Part.LineSegment(App.Vector(x1, y2, 0.0), App.Vector(x2, y2, 0.0))) | |
| geoList.append(Part.LineSegment(App.Vector(x2, y2, 0.0), App.Vector(x2, y1, 0.0))) | |
| geoList.append(Part.LineSegment(App.Vector(x2, y1, 0.0), App.Vector(x1, y1, 0.0))) | |
| doc.Sketch.addGeometry(geoList, False) | |
| del geoList | |
| constraintList = [] | |
| constraintList.append(Sketcher.Constraint("Coincident", 0, 2, 1, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 1, 2, 2, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 2, 2, 3, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 3, 2, 0, 1)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 0)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 2)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 1)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 3)) | |
| doc.Sketch.addConstraint(constraintList) | |
| del constraintList | |
| body.addObject(doc.Sketch) | |
| pocket = self.Doc.addObject("PartDesign::Pocket", "Pocket") | |
| pocket.Type = "Length" | |
| pocket.Length = 3 | |
| pocket.Direction = App.Vector(-0.710000000, 0.7100000000, 0.0000000000) | |
| pocket.Profile = doc.Sketch | |
| body.addObject(pocket) | |
| self.Doc.recompute() | |
| volume3 = body.Shape.Volume | |
| # Change the chamfered edges, potentially triggering TNP | |
| chamfer.Base = ( | |
| box, | |
| [ | |
| "Edge5", | |
| "Edge7", | |
| ], | |
| ) | |
| self.Doc.recompute() | |
| volume4 = body.Shape.Volume | |
| # Assert | |
| if body.Shape.ElementMapVersion == "": # Skip without element maps. | |
| return | |
| reverseMap = body.Shape.childShapes()[0].ElementReverseMap | |
| faces = [name for name in reverseMap.keys() if name.startswith("Face")] | |
| edges = [name for name in reverseMap.keys() if name.startswith("Edge")] | |
| vertexes = [name for name in reverseMap.keys() if name.startswith("Vertex")] | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 62) | |
| self.assertEqual(len(reverseMap), 62) | |
| self.assertEqual(len(faces), 12) | |
| self.assertEqual(len(edges), 30) | |
| self.assertEqual(len(vertexes), 20) | |
| boxVolume = 10 * 10 * 10 | |
| chamferVolume = 1 * 1 * 0.5 * 10 | |
| # cut area is rectangle with sqrt(2) as one side minus 2 isosceles right triangles | |
| cutArea = (2 * math.sqrt(2)) * 3 - ((math.sqrt(2) / 2 * math.sqrt(2) / 2) / 2) * 2 | |
| cutVolume = cutArea * 4 # height is 4 ( 11-6 with a limit of 10 from the box ) | |
| self.assertAlmostEqual(volume1, boxVolume) | |
| self.assertAlmostEqual(volume2, boxVolume - 3 * chamferVolume) | |
| self.assertAlmostEqual(volume3, boxVolume - 3 * chamferVolume - cutVolume, 4) | |
| self.assertAlmostEqual(volume4, boxVolume - 2 * chamferVolume - cutVolume, 4) | |
| def testPartDesignTNPFillet(self): | |
| """Test Fillet""" | |
| # Arrange | |
| doc = self.Doc | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| box = self.Doc.addObject("PartDesign::AdditiveBox", "Box") | |
| body.addObject(box) | |
| self.Doc.recompute() | |
| volume1 = body.Shape.Volume | |
| fillet = self.Doc.addObject("PartDesign::Fillet", "Fillet") | |
| fillet.Refine = True | |
| fillet.Base = ( | |
| box, | |
| [ | |
| "Edge1", | |
| "Edge5", | |
| "Edge7", | |
| ], | |
| ) | |
| # fillet.Size = 1 | |
| body.addObject(fillet) | |
| self.Doc.recompute() | |
| volume2 = body.Shape.Volume | |
| doc.Body.newObject("Sketcher::SketchObject", "Sketch") | |
| doc.Sketch.AttachmentSupport = (fillet, "Face2") | |
| doc.Sketch.MapMode = "FlatFace" | |
| doc.recompute() | |
| x1, x2, y1, y2 = 4, 6, 6, 11 | |
| geoList = [] | |
| geoList.append(Part.LineSegment(App.Vector(x1, y1, 0.0), App.Vector(x1, y2, 0.0))) | |
| geoList.append(Part.LineSegment(App.Vector(x1, y2, 0.0), App.Vector(x2, y2, 0.0))) | |
| geoList.append(Part.LineSegment(App.Vector(x2, y2, 0.0), App.Vector(x2, y1, 0.0))) | |
| geoList.append(Part.LineSegment(App.Vector(x2, y1, 0.0), App.Vector(x1, y1, 0.0))) | |
| doc.Sketch.addGeometry(geoList, False) | |
| del geoList | |
| constraintList = [] | |
| constraintList.append(Sketcher.Constraint("Coincident", 0, 2, 1, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 1, 2, 2, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 2, 2, 3, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 3, 2, 0, 1)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 0)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 2)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 1)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 3)) | |
| doc.Sketch.addConstraint(constraintList) | |
| del constraintList | |
| body.addObject(doc.Sketch) | |
| pocket = self.Doc.addObject("PartDesign::Pocket", "Pocket") | |
| pocket.Refine = True | |
| pocket.Type = "Length" | |
| pocket.Length = 3 | |
| pocket.Direction = App.Vector(-0.710000000, 0.7100000000, 0.0000000000) | |
| pocket.Profile = doc.Sketch | |
| # pocket.Reversed = False | |
| body.addObject(pocket) | |
| self.Doc.recompute() | |
| volume3 = body.Shape.Volume | |
| # Change the filleted edges, potentially triggering TNP | |
| fillet.Base = ( | |
| box, | |
| [ | |
| "Edge5", | |
| "Edge7", | |
| ], | |
| ) | |
| self.Doc.recompute() | |
| volume4 = body.Shape.Volume | |
| # Assert | |
| if body.Shape.ElementMapVersion == "": # Skip without element maps. | |
| return | |
| reverseMap = body.Shape.childShapes()[0].ElementReverseMap | |
| faces = [name for name in reverseMap.keys() if name.startswith("Face")] | |
| edges = [name for name in reverseMap.keys() if name.startswith("Edge")] | |
| vertexes = [name for name in reverseMap.keys() if name.startswith("Vertex")] | |
| self.assertEqual(len(body.Shape.childShapes()), 1) | |
| self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 62) | |
| self.assertEqual(len(reverseMap), 62) | |
| self.assertEqual(len(faces), 12) | |
| self.assertEqual(len(edges), 30) | |
| self.assertEqual(len(vertexes), 20) | |
| boxVolume = 10 * 10 * 10 | |
| # Full prism minus the rounded triangle prism. | |
| filletVolume = 1 * 1 * 10 - 1 * 1 * math.pi / 4 * 10 # 0.5 * 10 | |
| cutVolume = 24 | |
| self.assertAlmostEqual(volume1, boxVolume) | |
| self.assertAlmostEqual(volume2, boxVolume - 3 * filletVolume) | |
| self.assertAlmostEqual(volume3, boxVolume - 3 * filletVolume - cutVolume, 4) | |
| self.assertAlmostEqual(volume4, boxVolume - 2 * filletVolume - cutVolume, 4) | |
| # TODO: ENABLE THIS TEST WHEN MULTISOLIDS AND TNP PLAY NICELY | |
| # def testPD_TNPSketchPadMultipleSolids(self): | |
| # """ Prove that a sketch with multiple wires works correctly""" | |
| # doc = App.ActiveDocument | |
| # App.activeDocument().addObject('PartDesign::Body','Body') | |
| # doc.Body.newObject('Sketcher::SketchObject','Sketch') | |
| # doc.Sketch.AttachmentSupport = (doc.XY_Plane,['']) | |
| # doc.Sketch.MapMode = 'FlatFace' | |
| # radius = 15 | |
| # geoList = [] | |
| # geoList.append(Part.Circle(App.Vector(-20, 20, 0.000000), App.Vector(0.000000, 0.000000, 1.000000), radius)) | |
| # doc.Sketch.addGeometry(geoList,False) | |
| # geoList = [] | |
| # geoList.append(Part.Circle(App.Vector(20, 20, 0.000000), App.Vector(0.000000, 0.000000, 1.000000), radius)) | |
| # doc.Sketch.addGeometry(geoList,False) | |
| # geoList = [] | |
| # geoList.append(Part.Circle(App.Vector(20, -20, 0.000000), App.Vector(0.000000, 0.000000, 1.000000), radius)) | |
| # doc.Sketch.addGeometry(geoList,False) | |
| # geoList = [] | |
| # geoList.append(Part.Circle(App.Vector(-20,-20, 0.000000), App.Vector(0.000000, 0.000000, 1.000000), radius)) | |
| # doc.Sketch.addGeometry(geoList,False) | |
| # del geoList | |
| # doc.recompute() | |
| # doc.Body.newObject('PartDesign::Pad','Pad') | |
| # doc.Pad.Profile = (doc.Sketch, ['',]) | |
| # doc.Pad.Length = 10 | |
| # doc.Pad.ReferenceAxis = (doc.Sketch,['N_Axis']) | |
| # doc.Sketch.Visibility = False | |
| # doc.recompute() | |
| # expected_volume = math.pi * radius * radius * 10 * 4 # Volume of 4 padded circles | |
| # self.assertAlmostEqual(doc.Body.Shape.Volume, expected_volume ) | |
| # # Add additional code to attach another sketch, then change the original sketch and check TNP | |
| def testPD_TNPSketchPadTouching(self): | |
| """Prove that a sketch with touching wires works correctly""" | |
| doc = App.ActiveDocument | |
| App.activeDocument().addObject("PartDesign::Body", "Body") | |
| doc.Body.newObject("Sketcher::SketchObject", "Sketch") | |
| doc.Sketch.AttachmentSupport = (doc.XY_Plane, [""]) | |
| doc.Sketch.MapMode = "FlatFace" | |
| radius = 20 | |
| geoList = [] | |
| geoList.append( | |
| Part.Circle( | |
| App.Vector(-20, 20, 0.000000), | |
| App.Vector(0.000000, 0.000000, 1.000000), | |
| radius, | |
| ) | |
| ) | |
| doc.Sketch.addGeometry(geoList, False) | |
| geoList = [] | |
| geoList.append( | |
| Part.Circle( | |
| App.Vector(20, 20, 0.000000), | |
| App.Vector(0.000000, 0.000000, 1.000000), | |
| radius, | |
| ) | |
| ) | |
| doc.Sketch.addGeometry(geoList, False) | |
| geoList = [] | |
| geoList.append( | |
| Part.Circle( | |
| App.Vector(20, -20, 0.000000), | |
| App.Vector(0.000000, 0.000000, 1.000000), | |
| radius, | |
| ) | |
| ) | |
| doc.Sketch.addGeometry(geoList, False) | |
| geoList = [] | |
| geoList.append( | |
| Part.Circle( | |
| App.Vector(-20, -20, 0.000000), | |
| App.Vector(0.000000, 0.000000, 1.000000), | |
| radius, | |
| ) | |
| ) | |
| doc.Sketch.addGeometry(geoList, False) | |
| del geoList | |
| doc.recompute() | |
| doc.Body.newObject("PartDesign::Pad", "Pad") | |
| doc.Pad.Profile = ( | |
| doc.Sketch, | |
| [ | |
| "", | |
| ], | |
| ) | |
| doc.Pad.Length = 10 | |
| doc.Pad.ReferenceAxis = (doc.Sketch, ["N_Axis"]) | |
| doc.Sketch.Visibility = False | |
| doc.recompute() | |
| expected_volume = math.pi * radius * radius * 10 * 4 # Volume of 4 padded circles | |
| # self.assertAlmostEqual(doc.Body.Shape.Volume, expected_volume ) # TODO ENABLE THIS ASSERTION WHEN IT PASSES | |
| # # Add additional code to attach another sketch, then change the original sketch and check TNP | |
| # TODO ENABLE THIS TEST IF CODE IS WRITTEN TO SUPPORT SKETCHES WITH OVERLAPS. | |
| # def testPD_TNPSketchPadOverlapping(self): | |
| # """ Prove that a sketch with overlapping wires works correctly""" | |
| # doc = App.ActiveDocument | |
| # App.activeDocument().addObject('PartDesign::Body','Body') | |
| # doc.Body.newObject('Sketcher::SketchObject','Sketch') | |
| # doc.Sketch.AttachmentSupport = (doc.XY_Plane,['']) | |
| # doc.Sketch.MapMode = 'FlatFace' | |
| # radius = 25 | |
| # geoList = [] | |
| # geoList.append(Part.Circle(App.Vector(-20, 20, 0.000000), App.Vector(0.000000, 0.000000, 1.000000), radius)) | |
| # doc.Sketch.addGeometry(geoList,False) | |
| # geoList = [] | |
| # geoList.append(Part.Circle(App.Vector(20, 20, 0.000000), App.Vector(0.000000, 0.000000, 1.000000), radius)) | |
| # doc.Sketch.addGeometry(geoList,False) | |
| # geoList = [] | |
| # geoList.append(Part.Circle(App.Vector(20, -20, 0.000000), App.Vector(0.000000, 0.000000, 1.000000), radius)) | |
| # doc.Sketch.addGeometry(geoList,False) | |
| # geoList = [] | |
| # geoList.append(Part.Circle(App.Vector(-20,-20, 0.000000), App.Vector(0.000000, 0.000000, 1.000000), radius)) | |
| # doc.Sketch.addGeometry(geoList,False) | |
| # del geoList | |
| # doc.recompute() | |
| # doc.Body.newObject('PartDesign::Pad','Pad') | |
| # doc.Pad.Profile = (doc.Sketch, ['',]) | |
| # doc.Pad.Length = 10 | |
| # doc.Pad.ReferenceAxis = (doc.Sketch,['N_Axis']) | |
| # doc.Sketch.Visibility = False | |
| # doc.recompute() | |
| # expected_volume = math.pi * radius * radius * 10 * 4 # Volume of 4 padded circles | |
| # length = 12 # FIXME arbitrary guess, figure out the right value for either this or the angle. | |
| # angle = 2 * math.asin(length/2*radius) | |
| # expected_volume = expected_volume - 1/2 * radius * radius * (angle-math.sin(angle)) # Volume of the overlap areas | |
| # self.assertAlmostEqual(doc.Body.Shape.Volume, expected_volume ) | |
| # # Add additional code to attach another sketch, then change the original sketch and check TNP | |
| def testPD_TNPSketchPadSketchMove(self): | |
| """Prove that a sketch attached to a padded sketch shape does not have a problem when the initial sketch has geometry move""" | |
| doc = App.ActiveDocument | |
| App.activeDocument().addObject("PartDesign::Body", "Body") | |
| doc.Body.newObject("Sketcher::SketchObject", "Sketch") | |
| doc.Sketch.AttachmentSupport = (doc.XY_Plane, [""]) | |
| doc.Sketch.MapMode = "FlatFace" | |
| geoList = [] | |
| geoList.append(Part.LineSegment(App.Vector(0, 0, 0), App.Vector(40, 0, 0))) | |
| geoList.append(Part.LineSegment(App.Vector(40, 0, 0), App.Vector(40, 20, 0))) | |
| geoList.append(Part.LineSegment(App.Vector(40, 20, 0), App.Vector(0, 20, 0))) | |
| geoList.append(Part.LineSegment(App.Vector(0, 20, 0), App.Vector(0, 0, 0))) | |
| doc.Sketch.addGeometry(geoList, False) | |
| constraintList = [] | |
| constraintList.append(Sketcher.Constraint("Coincident", 0, 2, 1, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 1, 2, 2, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 2, 2, 3, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 3, 2, 0, 1)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 0)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 2)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 1)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 3)) | |
| doc.Sketch.addConstraint(constraintList) | |
| doc.recompute() | |
| doc.Body.newObject("PartDesign::Pad", "Pad") | |
| doc.Pad.Profile = ( | |
| doc.Sketch, | |
| [ | |
| "", | |
| ], | |
| ) | |
| doc.Pad.Length = 10 | |
| doc.Pad.ReferenceAxis = (doc.Sketch, ["N_Axis"]) | |
| doc.Sketch.Visibility = False | |
| doc.Pad.Length = 10.000000 | |
| doc.Pad.TaperAngle = 0.000000 | |
| doc.Pad.UseCustomVector = 0 | |
| doc.Pad.Direction = (0, 0, 1) | |
| doc.Pad.ReferenceAxis = (doc.Sketch, ["N_Axis"]) | |
| doc.Pad.AlongSketchNormal = 1 | |
| doc.Pad.Type = 0 | |
| doc.Pad.UpToFace = None | |
| doc.Pad.Reversed = 0 | |
| doc.Pad.SideType = "One side" | |
| doc.Pad.Offset = 0 | |
| doc.recompute() | |
| doc.Sketch.Visibility = False | |
| doc.Body.newObject("Sketcher::SketchObject", "Sketch001") | |
| doc.Sketch001.AttachmentSupport = ( | |
| doc.Pad, | |
| [ | |
| "Face6", | |
| ], | |
| ) | |
| doc.Sketch001.MapMode = "FlatFace" | |
| geoList = [] | |
| geoList.append(Part.LineSegment(App.Vector(5, 5, 0), App.Vector(5, 10, 0))) | |
| geoList.append(Part.LineSegment(App.Vector(5, 10, 0), App.Vector(25, 10, 0))) | |
| geoList.append(Part.LineSegment(App.Vector(25, 10, 0), App.Vector(25, 5, 0))) | |
| geoList.append(Part.LineSegment(App.Vector(25, 5, 0), App.Vector(5, 5, 0))) | |
| doc.Sketch001.addGeometry(geoList, False) | |
| del geoList | |
| constraintList = [] | |
| constraintList.append(Sketcher.Constraint("Coincident", 0, 2, 1, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 1, 2, 2, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 2, 2, 3, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 3, 2, 0, 1)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 0)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 2)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 1)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 3)) | |
| doc.Sketch001.addConstraint(constraintList) | |
| doc.recompute() | |
| doc.Body.newObject("PartDesign::Pad", "Pad001") | |
| doc.Pad001.Profile = ( | |
| doc.Sketch001, | |
| [ | |
| "", | |
| ], | |
| ) | |
| doc.Pad001.Length = 10 | |
| doc.Pad001.ReferenceAxis = (doc.Sketch001, ["N_Axis"]) | |
| doc.Sketch001.Visibility = False | |
| doc.Pad001.Length = 10.000000 | |
| doc.Pad001.TaperAngle = 0.000000 | |
| doc.Pad001.UseCustomVector = 0 | |
| doc.Pad001.Direction = (0, 0, 1) | |
| doc.Pad001.ReferenceAxis = (doc.Sketch001, ["N_Axis"]) | |
| doc.Pad001.AlongSketchNormal = 1 | |
| doc.Pad001.Type = 0 | |
| doc.Pad001.UpToFace = None | |
| doc.Pad001.Reversed = 0 | |
| doc.Pad001.SideType = "One side" | |
| doc.Pad001.Offset = 0 | |
| doc.recompute() | |
| doc.Pad.Visibility = False | |
| doc.Sketch001.Visibility = False | |
| doc.Sketch.moveGeometry(3, 0, App.Vector(-5, 0, 0), 1) | |
| doc.Sketch.moveGeometry(0, 0, App.Vector(0.000000, -5, 0), 1) | |
| doc.Sketch.moveGeometry(1, 0, App.Vector(-5, 0.000000, 0), 1) | |
| doc.Sketch.moveGeometry(2, 0, App.Vector(-0, -5, 0), 1) | |
| doc.recompute() | |
| # If Sketch001 is still at the right start point, we are good. | |
| self.assertTrue(doc.Sketch001.AttachmentOffset.Matrix == App.Matrix()) | |
| matrix1 = App.Matrix() | |
| matrix1.A34 = 10 # Z offset by 10. | |
| self.assertTrue(doc.Sketch001.Placement.Matrix == matrix1) | |
| def testPD_TNPSketchPadSketchDelete(self): | |
| """Prove that a sketch attached to a padded sketch shape does not have a problem when the initial sketch has geometry deleted""" | |
| doc = App.ActiveDocument | |
| App.activeDocument().addObject("PartDesign::Body", "Body") | |
| doc.Body.newObject("Sketcher::SketchObject", "Sketch") | |
| doc.Sketch.AttachmentSupport = (doc.XY_Plane, [""]) | |
| doc.Sketch.MapMode = "FlatFace" | |
| import ProfileLib.RegularPolygon | |
| ProfileLib.RegularPolygon.makeRegularPolygon( | |
| doc.Sketch, | |
| 6, | |
| App.Vector(0.000000, 0.000000, 0), | |
| App.Vector(24, 12, 0), | |
| False, | |
| ) | |
| doc.Sketch.addConstraint(Sketcher.Constraint("Coincident", 6, 3, -1, 1)) | |
| doc.Sketch.addConstraint(Sketcher.Constraint("PointOnObject", 0, 2, -2)) | |
| doc.recompute() | |
| doc.Body.newObject("PartDesign::Pad", "Pad") | |
| doc.Pad.Profile = ( | |
| doc.Sketch, | |
| [ | |
| "", | |
| ], | |
| ) | |
| doc.Pad.Length = 10 | |
| doc.Pad.ReferenceAxis = (doc.Sketch, ["N_Axis"]) | |
| doc.Sketch.Visibility = False | |
| doc.Pad.Length = 10.000000 | |
| doc.Pad.TaperAngle = 0.000000 | |
| doc.Pad.UseCustomVector = 0 | |
| doc.Pad.Direction = (0, 0, 1) | |
| doc.Pad.ReferenceAxis = (doc.Sketch, ["N_Axis"]) | |
| doc.Pad.AlongSketchNormal = 1 | |
| doc.Pad.Type = 0 | |
| doc.Pad.UpToFace = None | |
| doc.Pad.Reversed = 0 | |
| doc.Pad.SideType = "One side" | |
| doc.Pad.Offset = 0 | |
| doc.recompute() | |
| doc.Sketch.Visibility = False | |
| doc.Body.newObject("Sketcher::SketchObject", "Sketch001") | |
| doc.Sketch001.AttachmentSupport = ( | |
| doc.Pad, | |
| [ | |
| "Face8", | |
| ], | |
| ) | |
| doc.Sketch001.MapMode = "FlatFace" | |
| geoList = [] | |
| geoList.append(Part.LineSegment(App.Vector(-5, 5, 0.000000), App.Vector(-5, -5, 0.000000))) | |
| geoList.append(Part.LineSegment(App.Vector(-5, -5, 0.000000), App.Vector(5, -5, 0.000000))) | |
| geoList.append(Part.LineSegment(App.Vector(5, -5, 0.000000), App.Vector(5, 5, 0.000000))) | |
| geoList.append(Part.LineSegment(App.Vector(5, 5, 0.000000), App.Vector(-5, 5, 0.000000))) | |
| doc.Sketch001.addGeometry(geoList, False) | |
| del geoList | |
| constraintList = [] | |
| constraintList.append(Sketcher.Constraint("Coincident", 0, 2, 1, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 1, 2, 2, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 2, 2, 3, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 3, 2, 0, 1)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 0)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 2)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 1)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 3)) | |
| doc.Sketch001.addConstraint(constraintList) | |
| constraintList = [] | |
| doc.recompute() | |
| doc.Body.newObject("PartDesign::Pad", "Pad001") | |
| doc.Pad001.Profile = ( | |
| doc.Sketch001, | |
| [ | |
| "", | |
| ], | |
| ) | |
| doc.Pad001.Length = 10 | |
| doc.Pad001.ReferenceAxis = (doc.Sketch001, ["N_Axis"]) | |
| doc.Sketch001.Visibility = False | |
| doc.Pad001.Length = 10.000000 | |
| doc.Pad001.TaperAngle = 0.000000 | |
| doc.Pad001.UseCustomVector = 0 | |
| doc.Pad001.Direction = (0, 0, 1) | |
| doc.Pad001.ReferenceAxis = (doc.Sketch001, ["N_Axis"]) | |
| doc.Pad001.AlongSketchNormal = 1 | |
| doc.Pad001.Type = 0 | |
| doc.Pad001.UpToFace = None | |
| doc.Pad001.Reversed = 0 | |
| doc.Pad001.SideType = "One side" | |
| doc.Pad001.Offset = 0 | |
| doc.recompute() | |
| doc.Pad.Visibility = False | |
| doc.Sketch001.Visibility = False | |
| doc.Sketch.delGeometries([4]) | |
| doc.Sketch.addConstraint(Sketcher.Constraint("Coincident", 3, 2, 4, 1)) | |
| doc.Sketch.delConstraint(12) | |
| doc.recompute() | |
| # If Sketch001 is still at the right start point, we are good. | |
| self.assertTrue(doc.Sketch001.AttachmentOffset.Matrix == App.Matrix()) | |
| matrix1 = App.Matrix() | |
| matrix1.A34 = 10 # Z offset by 10 | |
| self.assertTrue(doc.Sketch001.Placement.Matrix == matrix1) | |
| def testPD_TNPSketchPadSketchSplit(self): | |
| """Prove that a sketch attached to a padded sketch shape does not have a problem when the initial sketch has geometry split""" | |
| doc = App.ActiveDocument | |
| App.activeDocument().addObject("PartDesign::Body", "Body") | |
| doc.Body.newObject("Sketcher::SketchObject", "Sketch") | |
| doc.Sketch.AttachmentSupport = (doc.XY_Plane, [""]) | |
| doc.Sketch.MapMode = "FlatFace" | |
| geoList = [] | |
| geoList.append(Part.LineSegment(App.Vector(0, 0, 0), App.Vector(40, 0, 0))) | |
| geoList.append(Part.LineSegment(App.Vector(40, 0, 0), App.Vector(40, 20, 0))) | |
| geoList.append(Part.LineSegment(App.Vector(40, 20, 0), App.Vector(0, 20, 0))) | |
| geoList.append(Part.LineSegment(App.Vector(0, 20, 0), App.Vector(0, 0, 0))) | |
| doc.Sketch.addGeometry(geoList, False) | |
| constraintList = [] | |
| constraintList.append(Sketcher.Constraint("Coincident", 0, 2, 1, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 1, 2, 2, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 2, 2, 3, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 3, 2, 0, 1)) | |
| # constraintList.append(Sketcher.Constraint("Horizontal", 0)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 2)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 1)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 3)) | |
| constraintList.append(Sketcher.Constraint("DistanceX", 0, 40)) | |
| constraintList.append(Sketcher.Constraint("DistanceY", 1, 20)) | |
| constraintList.append(Sketcher.Constraint("DistanceX", 0, 1, 0)) | |
| constraintList.append(Sketcher.Constraint("DistanceY", 0, 1, 0)) | |
| doc.Sketch.addConstraint(constraintList) | |
| doc.recompute() | |
| doc.Body.newObject("PartDesign::Pad", "Pad") | |
| doc.Pad.Profile = ( | |
| doc.Sketch, | |
| [ | |
| "", | |
| ], | |
| ) | |
| doc.Pad.Length = 10 | |
| doc.Pad.ReferenceAxis = (doc.Sketch, ["N_Axis"]) | |
| doc.Sketch.Visibility = False | |
| doc.Pad.Length = 10.000000 | |
| doc.Pad.TaperAngle = 0.000000 | |
| doc.Pad.UseCustomVector = 0 | |
| doc.Pad.Direction = (0, 0, 1) | |
| doc.Pad.ReferenceAxis = (doc.Sketch, ["N_Axis"]) | |
| doc.Pad.AlongSketchNormal = 1 | |
| doc.Pad.Type = 0 | |
| doc.Pad.UpToFace = None | |
| doc.Pad.Reversed = 0 | |
| doc.Pad.SideType = "One side" | |
| doc.Pad.Offset = 0 | |
| doc.Pad.Refine = True | |
| doc.recompute() | |
| doc.Sketch.Visibility = False | |
| doc.Body.newObject("Sketcher::SketchObject", "Sketch001") | |
| doc.Sketch001.AttachmentSupport = ( | |
| doc.Pad, | |
| [ | |
| "Face6", | |
| ], | |
| ) | |
| doc.Sketch001.MapMode = "FlatFace" | |
| geoList = [] | |
| geoList.append(Part.LineSegment(App.Vector(5, 5, 0), App.Vector(5, 10, 0))) | |
| geoList.append(Part.LineSegment(App.Vector(5, 10, 0), App.Vector(25, 10, 0))) | |
| geoList.append(Part.LineSegment(App.Vector(25, 10, 0), App.Vector(25, 5, 0))) | |
| geoList.append(Part.LineSegment(App.Vector(25, 5, 0), App.Vector(5, 5, 0))) | |
| doc.Sketch001.addGeometry(geoList, False) | |
| del geoList | |
| constraintList = [] | |
| constraintList.append(Sketcher.Constraint("Coincident", 0, 2, 1, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 1, 2, 2, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 2, 2, 3, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 3, 2, 0, 1)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 0)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 2)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 1)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 3)) | |
| doc.Sketch001.addConstraint(constraintList) | |
| doc.recompute() | |
| doc.Body.newObject("PartDesign::Pad", "Pad001") | |
| doc.Pad001.Profile = ( | |
| doc.Sketch001, | |
| [ | |
| "", | |
| ], | |
| ) | |
| doc.Pad001.Length = 10 | |
| doc.Pad001.ReferenceAxis = (doc.Sketch001, ["N_Axis"]) | |
| doc.Sketch001.Visibility = False | |
| doc.Pad001.Length = 10.000000 | |
| doc.Pad001.TaperAngle = 0.000000 | |
| doc.Pad001.UseCustomVector = 0 | |
| doc.Pad001.Direction = (0, 0, 1) | |
| doc.Pad001.ReferenceAxis = (doc.Sketch001, ["N_Axis"]) | |
| doc.Pad001.AlongSketchNormal = 1 | |
| doc.Pad001.Type = 0 | |
| doc.Pad001.UpToFace = None | |
| doc.Pad001.Reversed = 0 | |
| doc.Pad001.SideType = "One side" | |
| doc.Pad001.Offset = 0 | |
| doc.recompute() | |
| doc.Pad.Visibility = False | |
| doc.Sketch001.Visibility = False | |
| self.assertAlmostEqual(doc.Pad.Shape.Volume, 8000) | |
| doc.Sketch.split(0, App.Vector(10, 0, 0)) # Geo 0 moves to Geo 3, create Geo4 | |
| doc.Sketch.split(4, App.Vector(30, 0, 0)) # Create Geo5 | |
| doc.Sketch.moveGeometry(4, 1, App.Vector(10, 2, 0), False) | |
| doc.Sketch.moveGeometry(4, 2, App.Vector(30, 2, 0), False) | |
| doc.recompute() | |
| self.assertAlmostEqual(doc.Pad.Shape.Volume, 7400) # Prove the points moved | |
| self.assertTrue(doc.Sketch001.isValid()) # Check for a TNP fail. | |
| # If Sketch001 is still at the right start point, we are good. | |
| self.assertTrue(doc.Sketch001.AttachmentOffset.Matrix == App.Matrix()) | |
| matrix1 = App.Matrix() | |
| matrix1.A34 = 10 # Z offset by 10. | |
| self.assertTrue(doc.Sketch001.Placement.Matrix == matrix1) | |
| def testPD_TNPSketchPadSketchConstructionChange(self): | |
| """Prove that a sketch attached to a padded sketch shape does not have a problem when the initial sketch has geometry changed from Construction""" | |
| pass # TODO | |
| def testPD_TNPSketchPadSketchTrim(self): | |
| """Prove that a sketch attached to a padded sketch shape does not have a problem when the initial sketch has geometry trimmed""" | |
| pass # TODO | |
| def testPD_TNPSketchPadSketchExternal(self): | |
| """Prove that a sketch attached to a padded sketch shape does not have a problem when the initial sketch has external geometry changed""" | |
| pass # TODO | |
| def testPD_TNPSketchPadSketchTransform(self): | |
| """Prove that a sketch attached to a padded sketch shape does not have a problem when the initial sketch has a transformation applied""" | |
| pass # TODO | |
| def testPD_TNPSketchPadSketchSymmetry(self): | |
| """Prove that a sketch attached to a padded sketch shape does not have a problem when the initial sketch has Symmetry applied""" | |
| pass # TODO | |
| def testPD_TNPSketchPadSketchBSpline(self): | |
| """Prove that a sketch attached to a padded sketch shape does not have a problem when the initial sketch has BSpline changed""" | |
| pass # TODO | |
| def testPD_TNPSketchRotSketchMove(self): | |
| """Prove that a sketch attached to a rotated sketch shape does not have a problem when the initial sketch has geometry moved""" | |
| pass # TODO | |
| def testPD_TNPSketchPocketSketchMove(self): | |
| """Prove that a sketch attached to a pocketed sketch shape does not have a problem when the initial sketch has geometry moved""" | |
| pass # TODO | |
| def testPD_TNPSketchLoftSketchMove(self): | |
| """Prove that a sketch attached to a lofted sketch shape does not have a problem when the initial sketch has geometry moved""" | |
| pass # TODO | |
| def testPD_TNPSketchPipeSketchMove(self): | |
| """Prove that a sketch attached to a piped sketch shape does not have a problem when the initial sketch has geometry moved""" | |
| pass # TODO | |
| def testSubelementNames(self): | |
| # Arrange | |
| doc = App.ActiveDocument | |
| plane = doc.addObject("Part::Plane", "Plane") | |
| plane.Length = 10 | |
| plane.Width = 10 | |
| extrude = doc.addObject("Part::Extrusion", "Extrude") | |
| extrude.Base = plane | |
| extrude.LengthFwd = 10 | |
| doc.recompute() | |
| if not App.GuiUp: | |
| return | |
| # Act | |
| App.Gui.Selection.addSelection("", extrude.Name, "Face2") | |
| # Assert | |
| self.assertEqual(len(App.Gui.Selection.getSelectionEx("", 0)[0].SubElementNames), 1) | |
| if extrude.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| self.assertEqual(App.Gui.Selection.getSelectionEx("", 0)[0].SubElementNames[0], "Face2") | |
| else: | |
| self.assertEqual( | |
| App.Gui.Selection.getSelectionEx("", 0)[0].SubElementNames[0][-8:], | |
| ",F.Face2", | |
| ) | |
| def testGetElementFunctionality(self): | |
| # Arrange | |
| body = self.Doc.addObject("PartDesign::Body", "Body") | |
| padSketch = self.Doc.addObject("Sketcher::SketchObject", "SketchPad") | |
| pad = self.Doc.addObject("PartDesign::Pad", "Pad") | |
| body.addObject(padSketch) | |
| body.addObject(pad) | |
| TestSketcherApp.CreateRectangleSketch(padSketch, (0, 0), (1, 1)) | |
| pad.Profile = padSketch | |
| pad.Length = 1 | |
| # Act | |
| self.Doc.recompute() | |
| if pad.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023. | |
| return | |
| map = pad.Shape.ElementMap | |
| # Assert | |
| self.assertGreater(pad.Shape.ElementMapSize, 0) | |
| for tnpName in map.keys(): | |
| element1 = pad.Shape.getElement(tnpName) | |
| element2 = pad.Shape.getElement(map[tnpName]) | |
| self.assertTrue(element1.isSame(element2)) | |
| def testFileSaveRestore(self): | |
| # Arrange | |
| self.Body = self.Doc.addObject("PartDesign::Body", "Body") | |
| self.create_t_sketch() | |
| self.assertEqual(self.Doc.Sketch.Shape.ElementMapSize, 18) | |
| filename = tempfile.gettempdir() + os.sep + self.Doc.Name | |
| # Act | |
| self.Doc.saveAs(filename) | |
| App.closeDocument(self.Doc.Name) | |
| self.Doc = App.openDocument(filename + ".FCStd") | |
| self.Doc.recompute() | |
| # Assert | |
| self.assertEqual(self.Doc.Sketch.Shape.ElementMapSize, 18) | |
| def testBodySubShapeBinderElementMap(self): | |
| # Arrange | |
| doc = App.ActiveDocument | |
| doc.addObject("Part::Box", "Box") | |
| doc.ActiveObject.Label = "Cube" | |
| doc.addObject("Part::Box", "Box") | |
| doc.ActiveObject.Label = "Cube" | |
| doc.addObject("Part::MultiFuse", "Fusion") | |
| doc.Fusion.Refine = False | |
| doc.Fusion.Shapes = [ | |
| doc.Box, | |
| doc.Box001, | |
| ] | |
| doc.recompute() | |
| self.assertEqual(doc.Fusion.Shape.ElementMapSize, 26) | |
| doc.addObject("PartDesign::Body", "Body") | |
| doc.Body.Label = "Body" | |
| doc.addObject("PartDesign::Body", "Body001") | |
| doc.Body001.Label = "Body001" | |
| # act | |
| # Set up the subshapebinder version | |
| binder = doc.Body.newObject("PartDesign::SubShapeBinder", "Binder") | |
| binder.Support = [(doc.Fusion, (""))] | |
| doc.recompute() | |
| # Set up the base feature version | |
| doc.Body001.BaseFeature = App.activeDocument().Fusion | |
| doc.recompute() | |
| # assert | |
| self.assertEqual( | |
| doc.Body.OutList[1].Shape.ElementMapSize, 26 | |
| ) # subobjects ( subshapebinder here ) should have elementmap | |
| self.assertEqual( | |
| doc.Body.Shape.ElementMapSize, 0 | |
| ) # TODO: This is Sus, although LS3 passes. Might be because | |
| # SubShapeBinder is different in LS3. | |
| self.assertEqual( | |
| doc.Body001.BaseFeature.Shape.ElementMapSize, 26 | |
| ) # base feature lookup should have element map | |
| self.assertEqual(doc.Body001.Shape.ElementMapSize, 26) # Body Shape should have element map | |
| def testBaseFeatureAttachmentSupport(self): | |
| # Arrange | |
| doc = App.ActiveDocument | |
| doc.addObject("Part::Box", "Box") | |
| doc.ActiveObject.Label = "Cube" | |
| doc.recompute() | |
| doc.addObject("Part::Box", "Box") | |
| doc.ActiveObject.Label = "Cube" | |
| doc.Box001.Placement = App.Placement( | |
| App.Vector(5.00, 5.00, 5.00), | |
| App.Rotation(App.Vector(0.00, 0.00, 1.00), 0.00), | |
| ) | |
| doc.recompute() | |
| doc.addObject("Part::MultiFuse", "Fusion") | |
| doc.Fusion.Refine = False | |
| doc.Fusion.Shapes = [ | |
| doc.Box, | |
| doc.Box001, | |
| ] | |
| doc.recompute() | |
| # doc.Box.Visibility = False | |
| # doc.Box001.Visibility = False | |
| # doc.recompute() | |
| doc.addObject("PartDesign::Body", "Body") | |
| doc.Body.Label = "Body" | |
| doc.Body.BaseFeature = App.activeDocument().Fusion | |
| doc.recompute() | |
| doc.Body.newObject("Sketcher::SketchObject", "Sketch") | |
| doc.Sketch.AttachmentSupport = (doc.getObject("BaseFeature"), ("Face8")) | |
| doc.Sketch.MapMode = "FlatFace" | |
| doc.recompute() | |
| geoList = [] | |
| geoList.append( | |
| Part.LineSegment(App.Vector(12.0, 13.0, 0.000000), App.Vector(12.0, 11.0, 0.000000)) | |
| ) | |
| geoList.append( | |
| Part.LineSegment(App.Vector(12.0, 11, 0.000000), App.Vector(14.0, 11.0, 0.000000)) | |
| ) | |
| geoList.append( | |
| Part.LineSegment(App.Vector(14.0, 11, 0.000000), App.Vector(14.0, 13.0, 0.000000)) | |
| ) | |
| geoList.append( | |
| Part.LineSegment(App.Vector(14.0, 13.0, 0.000000), App.Vector(12, 13.0, 0.000000)) | |
| ) | |
| doc.Sketch.addGeometry(geoList, False) | |
| del geoList | |
| constraintList = [] | |
| constraintList.append(Sketcher.Constraint("Coincident", 0, 2, 1, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 1, 2, 2, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 2, 2, 3, 1)) | |
| constraintList.append(Sketcher.Constraint("Coincident", 3, 2, 0, 1)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 0)) | |
| constraintList.append(Sketcher.Constraint("Vertical", 2)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 1)) | |
| constraintList.append(Sketcher.Constraint("Horizontal", 3)) | |
| doc.Sketch.addConstraint(constraintList) | |
| del constraintList | |
| constraintList = [] | |
| doc.recompute() | |
| # Assert that we have a sketch element map before proceeding | |
| self.assertEqual(doc.Sketch.Shape.ElementMapSize, 12) | |
| # Arrange | |
| doc.Body.newObject("PartDesign::Pad", "Pad") | |
| doc.Pad.Profile = ( | |
| doc.Sketch, | |
| [ | |
| "", | |
| ], | |
| ) | |
| doc.Pad.Length = 10 | |
| doc.recompute() | |
| doc.Pad.ReferenceAxis = (doc.Sketch, ["N_Axis"]) | |
| doc.Sketch.Visibility = False | |
| doc.Pad.Length = 10.000000 | |
| doc.Pad.TaperAngle = 0.000000 | |
| doc.Pad.UseCustomVector = 0 | |
| doc.Pad.Direction = (0, -1, 0) | |
| doc.Pad.ReferenceAxis = (doc.Sketch, ["N_Axis"]) | |
| doc.Pad.AlongSketchNormal = 1 | |
| doc.Pad.Type = 0 | |
| doc.Pad.UpToFace = None | |
| doc.Pad.Reversed = 0 | |
| doc.Pad.SideType = "One side" | |
| doc.Pad.Offset = 0 | |
| doc.BaseFeature.Visibility = False | |
| doc.Sketch.Visibility = False | |
| doc.recompute() | |
| # Act | |
| doc.Box001.Width = "3.00 mm" | |
| doc.Box001.Placement = App.Placement( | |
| App.Vector(5.00, 5.00, 5.00), | |
| App.Rotation(App.Vector(0.00, 0.00, 1.00), 0.00), | |
| ) | |
| doc.recompute() | |
| # Assert | |
| self.assertEqual(len(doc.Body.Shape.Faces), 17) # Check that the object seems right. | |
| self.assertEqual(len(doc.Body.Shape.Edges), 42) | |
| self.assertEqual(len(doc.Body.Shape.Vertexes), 28) | |
| self.assertEqual(len(doc.Body.Shape.Shells), 1) | |
| self.assertEqual(len(doc.Body.Shape.Solids), 1) | |
| self.assertEqual( | |
| doc.Sketch.AttachmentSupport[0][1][0], "Face9" | |
| ) # Attachment autochanged from Face8. | |
| # potentially check the .BoundBox ( calc seems off on this, Not applying sketch position to Pad object ) | |
| def create_t_sketch(self): | |
| self.Doc.getObject("Body").newObject("Sketcher::SketchObject", "Sketch") | |
| geo_list = [ | |
| Part.LineSegment(App.Vector(0, 0, 0), App.Vector(20, 0, 0)), | |
| Part.LineSegment(App.Vector(20, 0, 0), App.Vector(20, 10, 0)), | |
| Part.LineSegment(App.Vector(20, 10, 0), App.Vector(10, 10, 0)), | |
| Part.LineSegment(App.Vector(10, 10, 0), App.Vector(10, 20, 0)), | |
| Part.LineSegment(App.Vector(10, 20, 0), App.Vector(0, 20, 0)), | |
| Part.LineSegment(App.Vector(0, 20, 0), App.Vector(0, 0, 0)), | |
| ] | |
| self.Doc.getObject("Sketch").addGeometry(geo_list, False) | |
| con_list = [ | |
| Sketcher.Constraint("Coincident", 0, 2, 1, 1), | |
| Sketcher.Constraint("Coincident", 1, 2, 2, 1), | |
| Sketcher.Constraint("Coincident", 2, 2, 3, 1), | |
| Sketcher.Constraint("Coincident", 3, 2, 4, 1), | |
| Sketcher.Constraint("Coincident", 4, 2, 5, 1), | |
| Sketcher.Constraint("Coincident", 5, 2, 0, 1), | |
| Sketcher.Constraint("Horizontal", 0), | |
| Sketcher.Constraint("Horizontal", 2), | |
| Sketcher.Constraint("Horizontal", 4), | |
| Sketcher.Constraint("Vertical", 1), | |
| Sketcher.Constraint("Vertical", 3), | |
| Sketcher.Constraint("Vertical", 5), | |
| ] | |
| self.Doc.getObject("Sketch").addConstraint(con_list) | |
| del geo_list, con_list | |
| self.Doc.recompute() | |
| def testRectanglewithArcChangeinGlobalCenter(self): | |
| # Arrange | |
| self.Body = self.Doc.addObject("PartDesign::Body", "Body") | |
| # Make first offset cube Pad | |
| self.PadSketch = self.Doc.addObject("Sketcher::SketchObject", "Sketch") | |
| self.Body.addObject(self.PadSketch) | |
| TestSketcherApp.CreateRectangleSketch(self.PadSketch, (-50, -25), (100, 50)) | |
| self.Doc.recompute() | |
| self.Pad = self.Doc.addObject("PartDesign::Pad", "Pad") | |
| self.Body.addObject(self.Pad) | |
| self.Pad.Profile = self.PadSketch | |
| self.Pad.Length = 10 | |
| self.Doc.recompute() | |
| self.Sketch001 = self.Body.newObject("Sketcher::SketchObject", "Sketch001") | |
| self.Sketch001.AttachmentSupport = ( | |
| self.Doc.getObject("Pad"), | |
| [ | |
| "Face6", | |
| ], | |
| ) | |
| self.Sketch001.MapMode = "FlatFace" | |
| TestSketcherApp.CreateRectangleSketch(self.Sketch001, (-40, -20), (80, 40)) | |
| self.Doc.recompute() | |
| self.Pad1 = self.Doc.addObject("PartDesign::Pad", "Pad1") | |
| self.Body.addObject(self.Pad1) | |
| self.Pad1.Profile = self.Sketch001 | |
| self.Pad1.Length = 10 | |
| self.Doc.recompute() | |
| self.geoList = [] | |
| self.geoList.append( | |
| Part.ArcOfCircle( | |
| Part.Circle( | |
| App.Vector(0.000000, -109.419670, 0.000000), | |
| App.Vector(0.000000, 0.000000, 1.000000), | |
| 88.713871, | |
| ), | |
| 1.258384, | |
| 1.886112, | |
| ) | |
| ) | |
| self.PadSketch.addGeometry(self.geoList, False) | |
| del self.geoList | |
| self.constraintList = [] | |
| self.constraintList.append(Sketcher.Constraint("PointOnObject", 4, 3, -2)) | |
| self.constraintList.append(Sketcher.Constraint("PointOnObject", 4, 1, 2)) | |
| self.constraintList.append(Sketcher.Constraint("PointOnObject", 4, 2, 2)) | |
| self.PadSketch.addConstraint(self.constraintList) | |
| del self.constraintList | |
| self.PadSketch.trim(2, App.Vector(7.337847, -25.000000, 0)) | |
| self.PadSketch.addConstraint(Sketcher.Constraint("Equal", 3, 1)) | |
| radConstr = self.PadSketch.addConstraint(Sketcher.Constraint("Radius", 4, 73.031111)) | |
| self.PadSketch.setDatum(radConstr, App.Units.Quantity("70.000000 mm")) | |
| distYConstr = self.PadSketch.addConstraint( | |
| Sketcher.Constraint("DistanceY", 4, 3, -1, 1, 88.867210) | |
| ) | |
| self.PadSketch.setDatum(distYConstr, App.Units.Quantity("80.000000 mm")) | |
| self.Doc.recompute() | |
| self.assertTrue(self.Sketch001.isValid()) | |
| def testRectanglewithArcChangeinGlobalUpperRight(self): | |
| # Arrange | |
| self.Body = self.Doc.addObject("PartDesign::Body", "Body") | |
| # Make first offset cube Pad | |
| self.PadSketch = self.Body.newObject("Sketcher::SketchObject", "Sketch") | |
| self.PadSketch.AttachmentSupport = (self.Doc.getObject("XY_Plane"), [""]) | |
| self.PadSketch.MapMode = "FlatFace" | |
| self.Doc.recompute() | |
| lastGeoId = len(self.PadSketch.Geometry) | |
| self.geoList = [] | |
| self.geoList.append( | |
| Part.LineSegment( | |
| App.Vector(6.565019, 5.821458, 0.000000), | |
| App.Vector(131.750198, 5.821458, 0.000000), | |
| ) | |
| ) | |
| self.geoList.append( | |
| Part.LineSegment( | |
| App.Vector(131.750198, 5.821458, 0.000000), | |
| App.Vector(131.750198, 75.265900, 0.000000), | |
| ) | |
| ) | |
| self.geoList.append( | |
| Part.LineSegment( | |
| App.Vector(131.750198, 75.265900, 0.000000), | |
| App.Vector(6.565019, 75.265900, 0.000000), | |
| ) | |
| ) | |
| self.geoList.append( | |
| Part.LineSegment( | |
| App.Vector(6.565019, 75.265900, 0.000000), | |
| App.Vector(6.565019, 5.821458, 0.000000), | |
| ) | |
| ) | |
| self.PadSketch.addGeometry(self.geoList, False) | |
| del self.geoList | |
| self.constraintList = [] | |
| self.constraintList.append(Sketcher.Constraint("Coincident", 0, 2, 1, 1)) | |
| self.constraintList.append(Sketcher.Constraint("Coincident", 1, 2, 2, 1)) | |
| self.constraintList.append(Sketcher.Constraint("Coincident", 2, 2, 3, 1)) | |
| self.constraintList.append(Sketcher.Constraint("Coincident", 3, 2, 0, 1)) | |
| self.constraintList.append(Sketcher.Constraint("Horizontal", 0)) | |
| self.constraintList.append(Sketcher.Constraint("Horizontal", 2)) | |
| self.constraintList.append(Sketcher.Constraint("Vertical", 1)) | |
| self.constraintList.append(Sketcher.Constraint("Vertical", 3)) | |
| self.PadSketch.addConstraint(self.constraintList) | |
| del self.constraintList | |
| self.Doc.recompute() | |
| self.Pad = self.Body.newObject("PartDesign::Pad", "Pad") | |
| self.Pad.Profile = ( | |
| self.Doc.getObject("Sketch"), | |
| [ | |
| "", | |
| ], | |
| ) | |
| self.Pad.Length = 10 | |
| self.Doc.recompute() | |
| self.Pad.ReferenceAxis = (self.Doc.getObject("Sketch"), ["N_Axis"]) | |
| self.Doc.recompute() | |
| self.Pad.Length = 10.000000 | |
| self.Pad.TaperAngle = 0.000000 | |
| self.Pad.UseCustomVector = 0 | |
| self.Pad.Direction = (0, 0, 1) | |
| self.Pad.ReferenceAxis = (self.Doc.getObject("Sketch"), ["N_Axis"]) | |
| self.Pad.AlongSketchNormal = 1 | |
| self.Pad.Type = 0 | |
| self.Pad.UpToFace = None | |
| self.Pad.Reversed = 0 | |
| self.Pad.SideType = "One side" | |
| self.Pad.Offset = 0 | |
| self.Doc.recompute() | |
| self.Sketch001 = self.Body.newObject("Sketcher::SketchObject", "Sketch001") | |
| self.Sketch001.AttachmentSupport = ( | |
| self.Doc.getObject("Pad"), | |
| [ | |
| "Face6", | |
| ], | |
| ) | |
| self.Sketch001.MapMode = "FlatFace" | |
| self.Doc.recompute() | |
| lastGeoId = len(self.Sketch001.Geometry) | |
| self.geoList = [] | |
| self.geoList.append( | |
| Part.LineSegment( | |
| App.Vector(33.048996, 24.872660, 0.000000), | |
| App.Vector(125.086029, 24.872660, 0.000000), | |
| ) | |
| ) | |
| self.geoList.append( | |
| Part.LineSegment( | |
| App.Vector(125.086029, 24.872660, 0.000000), | |
| App.Vector(125.086029, 72.835625, 0.000000), | |
| ) | |
| ) | |
| self.geoList.append( | |
| Part.LineSegment( | |
| App.Vector(125.086029, 72.835625, 0.000000), | |
| App.Vector(33.048996, 72.835625, 0.000000), | |
| ) | |
| ) | |
| self.geoList.append( | |
| Part.LineSegment( | |
| App.Vector(33.048996, 72.835625, 0.000000), | |
| App.Vector(33.048996, 24.872660, 0.000000), | |
| ) | |
| ) | |
| self.Sketch001.addGeometry(self.geoList, False) | |
| del self.geoList | |
| self.constraintList = [] | |
| self.constraintList.append(Sketcher.Constraint("Coincident", 0, 2, 1, 1)) | |
| self.constraintList.append(Sketcher.Constraint("Coincident", 1, 2, 2, 1)) | |
| self.constraintList.append(Sketcher.Constraint("Coincident", 2, 2, 3, 1)) | |
| self.constraintList.append(Sketcher.Constraint("Coincident", 3, 2, 0, 1)) | |
| self.constraintList.append(Sketcher.Constraint("Horizontal", 0)) | |
| self.constraintList.append(Sketcher.Constraint("Horizontal", 2)) | |
| self.constraintList.append(Sketcher.Constraint("Vertical", 1)) | |
| self.constraintList.append(Sketcher.Constraint("Vertical", 3)) | |
| self.Sketch001.addConstraint(self.constraintList) | |
| del self.constraintList | |
| self.Doc.recompute() | |
| self.Pad1 = self.Body.newObject("PartDesign::Pad", "Pad001") | |
| self.Pad1.Profile = ( | |
| self.Doc.getObject("Sketch001"), | |
| [ | |
| "", | |
| ], | |
| ) | |
| self.Pad1.Length = 10 | |
| self.Doc.recompute() | |
| self.Pad1.ReferenceAxis = (self.Doc.getObject("Sketch001"), ["N_Axis"]) | |
| self.Doc.recompute() | |
| self.Pad1.Length = 10.000000 | |
| self.Pad1.TaperAngle = 0.000000 | |
| self.Pad1.UseCustomVector = 0 | |
| self.Pad1.Direction = (0, 0, 1) | |
| self.Pad1.ReferenceAxis = (self.Doc.getObject("Sketch001"), ["N_Axis"]) | |
| self.Pad1.AlongSketchNormal = 1 | |
| self.Pad1.Type = 0 | |
| self.Pad1.UpToFace = None | |
| self.Pad1.Reversed = 0 | |
| self.Pad1.SideType = "One side" | |
| self.Pad1.Offset = 0 | |
| self.Doc.recompute() | |
| lastGeoId = len(self.Sketch001.Geometry) | |
| self.geoList = [] | |
| self.geoList.append( | |
| Part.ArcOfCircle( | |
| Part.Circle( | |
| App.Vector(73.611900, -60.502949, 0.000000), | |
| App.Vector(0.000000, 0.000000, 1.000000), | |
| 80.806032, | |
| ), | |
| 0.997061, | |
| 2.178808, | |
| ) | |
| ) | |
| self.PadSketch.addGeometry(self.geoList, False) | |
| del self.geoList | |
| self.constraintList = [] | |
| self.constraintList.append(Sketcher.Constraint("PointOnObject", 4, 2, 0)) | |
| self.constraintList.append(Sketcher.Constraint("PointOnObject", 4, 1, 0)) | |
| self.PadSketch.addConstraint(self.constraintList) | |
| del self.constraintList | |
| self.Doc.recompute() | |
| self.PadSketch.trim(0, App.Vector(69.157609, 5.865876, 0)) | |
| self.Doc.recompute() | |
| self.assertTrue(self.Sketch001.isValid()) | |
| def testPadChange_UpToFirst_to_Dimension(self): | |
| # Arrange | |
| self.Body = self.Doc.addObject("PartDesign::Body", "Body") | |
| # Make first offset cube Pad | |
| self.PadSketch = self.Doc.addObject("Sketcher::SketchObject", "Sketch") | |
| self.Body.addObject(self.PadSketch) | |
| TestSketcherApp.CreateRectangleSketch(self.PadSketch, (-42.5, -42.5), (85, 85)) | |
| self.Doc.recompute() | |
| TestSketcherApp.CreateRectangleSketch(self.PadSketch, (-37.5, -37.5), (75, 75)) | |
| self.Doc.recompute() | |
| self.Pad = self.Doc.addObject("PartDesign::Pad", "Pad") | |
| self.Body.addObject(self.Pad) | |
| self.Pad.Profile = self.PadSketch | |
| self.Pad.Length = 10 | |
| self.Doc.recompute() | |
| self.Sketch001 = self.Body.newObject("Sketcher::SketchObject", "Sketch001") | |
| self.Sketch001.AttachmentSupport = ( | |
| self.Doc.getObject("Pad"), | |
| [ | |
| "Face5", | |
| ], | |
| ) | |
| self.Sketch001.MapMode = "FlatFace" | |
| self.Doc.recompute() | |
| lastGeoId = len(self.Sketch001.Geometry) | |
| self.geoList = [] | |
| self.geoList.append( | |
| Part.LineSegment( | |
| App.Vector(-33.953453, 7.680901, 0.000000), | |
| App.Vector(-33.953453, 2.543239, 0.000000), | |
| ) | |
| ) | |
| self.geoList.append( | |
| Part.LineSegment( | |
| App.Vector(-33.953453, 2.543239, 0.000000), | |
| App.Vector(33.282925, 2.543239, 0.000000), | |
| ) | |
| ) | |
| self.geoList.append( | |
| Part.LineSegment( | |
| App.Vector(33.282925, 2.543239, 0.000000), | |
| App.Vector(33.282925, 7.680901, 0.000000), | |
| ) | |
| ) | |
| self.geoList.append( | |
| Part.LineSegment( | |
| App.Vector(33.282925, 7.680901, 0.000000), | |
| App.Vector(-33.953453, 7.680901, 0.000000), | |
| ) | |
| ) | |
| self.Sketch001.addGeometry(self.geoList, False) | |
| del self.geoList | |
| self.constraintList = [] | |
| self.constraintList.append(Sketcher.Constraint("Coincident", 0, 2, 1, 1)) | |
| self.constraintList.append(Sketcher.Constraint("Coincident", 1, 2, 2, 1)) | |
| self.constraintList.append(Sketcher.Constraint("Coincident", 2, 2, 3, 1)) | |
| self.constraintList.append(Sketcher.Constraint("Coincident", 3, 2, 0, 1)) | |
| self.constraintList.append(Sketcher.Constraint("Vertical", 0)) | |
| self.constraintList.append(Sketcher.Constraint("Vertical", 2)) | |
| self.constraintList.append(Sketcher.Constraint("Horizontal", 1)) | |
| self.constraintList.append(Sketcher.Constraint("Horizontal", 3)) | |
| self.Sketch001.addConstraint(self.constraintList) | |
| del self.constraintList | |
| self.Doc.recompute() | |
| self.Pad001 = self.Body.newObject("PartDesign::Pad", "Pad001") | |
| self.Pad001.Profile = ( | |
| self.Doc.getObject("Sketch001"), | |
| [ | |
| "", | |
| ], | |
| ) | |
| self.Pad001.Length = 10 | |
| self.Doc.recompute() | |
| self.Pad001.ReferenceAxis = (self.Doc.getObject("Sketch001"), ["N_Axis"]) | |
| self.Doc.recompute() | |
| self.Pad001.UseCustomVector = 0 | |
| self.Pad001.Direction = (0, -1, 0) | |
| self.Pad001.ReferenceAxis = (self.Doc.getObject("Sketch001"), ["N_Axis"]) | |
| self.Pad001.AlongSketchNormal = 1 | |
| self.Pad001.Type = 2 | |
| self.Pad001.UpToFace = None | |
| self.Pad001.Reversed = 0 | |
| self.Pad001.SideType = "One side" | |
| self.Pad001.Offset = 0 | |
| self.Doc.recompute() | |
| self.Sketch002 = self.Body.newObject("Sketcher::SketchObject", "Sketch002") | |
| self.Sketch002.AttachmentSupport = ( | |
| self.Doc.getObject("Pad001"), | |
| [ | |
| "Face11", | |
| ], | |
| ) | |
| self.Sketch002.MapMode = "FlatFace" | |
| self.Doc.recompute() | |
| lastGeoId = len(self.Sketch002.Geometry) | |
| self.geoList = [] | |
| self.geoList.append( | |
| Part.LineSegment( | |
| App.Vector(-30.826233, 35.070259, 0.000000), | |
| App.Vector(-30.826233, 30.602728, 0.000000), | |
| ) | |
| ) | |
| self.geoList.append( | |
| Part.LineSegment( | |
| App.Vector(-30.826233, 30.602728, 0.000000), | |
| App.Vector(30.602348, 30.602728, 0.000000), | |
| ) | |
| ) | |
| self.geoList.append( | |
| Part.LineSegment( | |
| App.Vector(30.602348, 30.602728, 0.000000), | |
| App.Vector(30.602348, 35.070259, 0.000000), | |
| ) | |
| ) | |
| self.geoList.append( | |
| Part.LineSegment( | |
| App.Vector(30.602348, 35.070259, 0.000000), | |
| App.Vector(-30.826233, 35.070259, 0.000000), | |
| ) | |
| ) | |
| self.Sketch002.addGeometry(self.geoList, False) | |
| del self.geoList | |
| self.constraintList = [] | |
| self.constraintList.append(Sketcher.Constraint("Coincident", 0, 2, 1, 1)) | |
| self.constraintList.append(Sketcher.Constraint("Coincident", 1, 2, 2, 1)) | |
| self.constraintList.append(Sketcher.Constraint("Coincident", 2, 2, 3, 1)) | |
| self.constraintList.append(Sketcher.Constraint("Coincident", 3, 2, 0, 1)) | |
| self.constraintList.append(Sketcher.Constraint("Vertical", 0)) | |
| self.constraintList.append(Sketcher.Constraint("Vertical", 2)) | |
| self.constraintList.append(Sketcher.Constraint("Horizontal", 1)) | |
| self.constraintList.append(Sketcher.Constraint("Horizontal", 3)) | |
| self.Sketch002.addConstraint(self.constraintList) | |
| del self.constraintList | |
| self.Doc.recompute() | |
| self.Pad002 = self.Body.newObject("PartDesign::Pad", "Pad002") | |
| self.Pad002.Profile = ( | |
| self.Doc.getObject("Sketch002"), | |
| [ | |
| "", | |
| ], | |
| ) | |
| self.Pad002.Length = 10 | |
| self.Doc.recompute() | |
| self.Pad002.ReferenceAxis = (self.Doc.getObject("Sketch002"), ["N_Axis"]) | |
| self.Doc.recompute() | |
| self.Pad002.Length = 10.000000 | |
| self.Pad002.TaperAngle = 0.000000 | |
| self.Pad002.UseCustomVector = 0 | |
| self.Pad002.Direction = (0, 0, 1) | |
| self.Pad002.ReferenceAxis = (self.Doc.getObject("Sketch002"), ["N_Axis"]) | |
| self.Pad002.AlongSketchNormal = 1 | |
| self.Pad002.Type = 0 | |
| self.Pad002.UpToFace = None | |
| self.Pad002.Reversed = 0 | |
| self.Pad002.SideType = "One side" | |
| self.Pad002.Offset = 0 | |
| self.Doc.recompute() | |
| self.Pad001.Type = "Length" | |
| self.Pad001.Length = "4 mm" | |
| self.Doc.recompute() | |
| """Assumption: the warning <PropertyLinks> PropertyLinks.cpp(453): | |
| PartDesignTestTNP1#Sketch002.AttachmentSupport missing element | |
| reference PartDesignTestTNP1#Pad001 ;g815v1;SKT;:H976,V;:L#2;PSM; | |
| :H976:9,E;:L#8;PSM;:H976:9,F;:H-977,F.Face11 is only temporary and can be ignored.""" | |
| self.assertTrue(self.Sketch002.AttachmentSupport[0][1][0] == "Face11") | |
| self.assertGreaterEqual(self.Body.Shape.Volume, 20126) | |
| def tearDown(self): | |
| """Clean up our test, optionally preserving the test document""" | |
| # This flag allows doing something like this: | |
| # App.KeepTestDoc = True | |
| # import TestApp | |
| # TestApp.Test("TestPartDesignApp.TestTopologicalNamingProblem.testPadChange_UpToFirst_to_Dimension") | |
| # to leave the test document(s) around for further examination in an interactive setting. | |
| if hasattr(App, "KeepTestDoc") and App.KeepTestDoc: | |
| return | |
| App.closeDocument(self.Doc.Name) | |