3013 lines
124 KiB
Python
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)
|