freecad-cam/Mod/PartDesign/PartDesignTests/TestTopologicalNamingProblem.py
2026-02-01 01:59:24 +01:00

3013 lines
124 KiB
Python

# 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 math
import unittest
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):
# 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
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["Vertex9"][1].count(";"), 3)
self.assertEqual( revolution.Shape.ElementReverseMap["Face9"].count(";"), 16)
# 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 elemement name is
# present in the MappedName of an element (a MappedName is definined 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 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)
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.assertEqual(hole.Shape.ElementMapSize, 32)
# self.assertNotEqual(hole.Shape.ElementReverseMap['Vertex1'],"Vertex1") # NewName, not OldName
self.assertEqual(
self.countFacesEdgesVertexes(hole.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.Midplane = 0
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.Midplane = 0
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.Midplane = 0
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").Midplane = 0
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.Midplane = 0
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.Midplane = 0
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.Midplane = 0
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.Midplane = 0
doc.Pad001.Offset = 0
doc.recompute()
doc.Pad.Visibility = False
doc.Sketch001.Visibility = False
doc.Sketch.movePoint(3, 0, App.Vector(-5, 0, 0), 1)
doc.Sketch.movePoint(0, 0, App.Vector(0.000000, -5, 0), 1)
doc.Sketch.movePoint(1, 0, App.Vector(-5, 0.000000, 0), 1)
doc.Sketch.movePoint(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.Midplane = 0
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.Midplane = 0
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_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 = self.Doc.Name
# Act
self.Doc.saveAs(filename)
App.closeDocument(filename)
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.Midplane = 0
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))
self.PadSketch.addConstraint(Sketcher.Constraint("Horizontal", 5))
self.PadSketch.addConstraint(Sketcher.Constraint("Radius", 4, 73.031111))
self.PadSketch.setDatum(18, App.Units.Quantity("70.000000 mm"))
self.PadSketch.addConstraint(
Sketcher.Constraint("DistanceY", 4, 3, -1, 1, 88.867210)
)
self.PadSketch.setDatum(19, 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.Midplane = 0
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.Midplane = 0
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.Midplane = 0
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.Midplane = 0
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)