#************************************************************************** # Copyright (c) 2011 Juergen Riegel * # * # This file is part of the FreeCAD CAx development system. * # * # This program is free software; you can redistribute it and/or modify * # it under the terms of the GNU Lesser General Public License (LGPL) * # as published by the Free Software Foundation; either version 2 of * # the License, or (at your option) any later version. * # for detail see the LICENCE text file. * # * # FreeCAD is distributed in the hope that it will be useful, * # but WITHOUT ANY WARRANTY; without even the implied warranty of * # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * # GNU Library General Public License for more details. * # * # You should have received a copy of the GNU Library General Public * # License along with FreeCAD; if not, write to the Free Software * # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * # USA * #************************************************************************** import FreeCAD, unittest, Part import copy import math from FreeCAD import Units from FreeCAD import Base App = FreeCAD from parttests.BRep_tests import BRepTests from parttests.Geom2d_tests import Geom2dTests from parttests.regression_tests import RegressionTests from parttests.TopoShapeListTest import TopoShapeListTest from parttests.TopoShapeTest import TopoShapeTest #--------------------------------------------------------------------------- # define the test cases to test the FreeCAD Part module #--------------------------------------------------------------------------- def getCoincidentVertexes(vtx1, vtx2): pairs = [] tol = Part.Precision.confusion() for i in vtx1: for j in vtx2: if i.Point.distanceToPoint(j.Point) < tol: pairs.append((i, j)) return pairs class PartTestCases(unittest.TestCase): def setUp(self): self.Doc = FreeCAD.newDocument("PartTest") def testBoxCase(self): self.Box = self.Doc.addObject("Part::Box","Box") self.Doc.recompute() self.assertEqual(len(self.Box.Shape.Faces), 6) def testIssue2985(self): v1 = App.Vector(0.0,0.0,0.0) v2 = App.Vector(10.0,0.0,0.0) v3 = App.Vector(10.0,0.0,10.0) v4 = App.Vector(0.0,0.0,10.0) edge1 = Part.makeLine(v1, v2) edge2 = Part.makeLine(v2, v3) edge3 = Part.makeLine(v3, v4) edge4 = Part.makeLine(v4, v1) # Travis build confirms the crash under macOS #result = Part.makeFilledFace([edge1,edge2,edge3,edge4]) #self.Doc.addObject("Part::Feature","Face").Shape = result #self.assertTrue(isinstance(result.Surface, Part.BSplineSurface)) def tearDown(self): #closing doc FreeCAD.closeDocument("PartTest") #print ("omit closing document for debugging") class PartTestBSplineCurve(unittest.TestCase): def setUp(self): self.Doc = FreeCAD.newDocument("PartTest") poles = [[0, 0, 0], [1, 1, 0], [2, 0, 0]] self.spline = Part.BSplineCurve() self.spline.buildFromPoles(poles) poles = [[0, 0, 0], [1, 1, 0], [2, 0, 0], [1, -1, 0]] self.nurbs = Part.BSplineCurve() self.nurbs.buildFromPolesMultsKnots(poles, (3, 1, 3),(0, 0.5, 1), False, 2) def testProperties(self): self.assertEqual(self.spline.Continuity, 'CN') self.assertEqual(self.spline.Degree, 2) self.assertEqual(self.spline.EndPoint, App.Vector(2, 0, 0)) self.assertEqual(self.spline.FirstParameter, 0.0) self.assertEqual(self.spline.FirstUKnotIndex, 1) self.assertEqual(self.spline.KnotSequence, [0.0, 0.0, 0.0, 1.0, 1.0, 1.0]) self.assertEqual(self.spline.LastParameter, 1.0) self.assertEqual(self.spline.LastUKnotIndex, 2) max_degree = self.spline.MaxDegree self.assertEqual(self.spline.NbKnots, 2) self.assertEqual(self.spline.NbPoles, 3) self.assertEqual(self.spline.StartPoint, App.Vector(0.0, 0.0, 0.0)) def testGetters(self): '''only check if the function doesn't crash''' self.spline.getKnot(1) self.spline.getKnots() self.spline.getMultiplicities() self.spline.getMultiplicity(1) self.spline.getPole(1) self.spline.getPoles() self.spline.getPolesAndWeights() self.spline.getResolution(0.5) self.spline.getWeight(1) self.spline.getWeights() def testSetters(self): spline = copy.copy(self.spline) spline.setKnot(1, 0.1) spline.setPeriodic() spline.setNotPeriodic() # spline.setKnots() # spline.setOrigin(2) # not working? self.spline.setPole(1, App.Vector([1, 0, 0])) # first parameter 0 gives occ error def testIssue2671(self): self.Doc = App.newDocument("Issue2671") Box = self.Doc.addObject("Part::Box","Box") Mirroring = self.Doc.addObject("Part::Mirroring", 'Mirroring') Spreadsheet = self.Doc.addObject('Spreadsheet::Sheet', 'Spreadsheet') Mirroring.Source = Box Mirroring.Base = (8, 5, 25) Mirroring.Normal = (0.5, 0.2, 0.9) Spreadsheet.set('A1', '=Mirroring.Base.x') Spreadsheet.set('B1', '=Mirroring.Base.y') Spreadsheet.set('C1', '=Mirroring.Base.z') Spreadsheet.set('A2', '=Mirroring.Normal.x') Spreadsheet.set('B2', '=Mirroring.Normal.y') Spreadsheet.set('C2', '=Mirroring.Normal.z') self.Doc.recompute() self.assertEqual(Spreadsheet.A1, Units.Quantity('8 mm')) self.assertEqual(Spreadsheet.B1, Units.Quantity('5 mm')) self.assertEqual(Spreadsheet.C1, Units.Quantity('25 mm')) self.assertEqual(Spreadsheet.A2, Units.Quantity('0.5 mm')) self.assertEqual(Spreadsheet.B2, Units.Quantity('0.2 mm')) self.assertEqual(Spreadsheet.C2, Units.Quantity('0.9 mm')) App.closeDocument("Issue2671") def testIssue2876(self): self.Doc = App.newDocument("Issue2876") Cylinder = self.Doc.addObject("Part::Cylinder", "Cylinder") Cylinder.Radius = 5 Pipe = self.Doc.addObject("Part::Thickness", "Pipe") Pipe.Faces = (Cylinder, ["Face2", "Face3"]) Pipe.Mode = 1 Pipe.Value = -1 # negative wall thickness Spreadsheet = self.Doc.addObject('Spreadsheet::Sheet', 'Spreadsheet') Spreadsheet.set('A1', 'Pipe OD') Spreadsheet.set('B1', 'Pipe WT') Spreadsheet.set('C1', 'Pipe ID') Spreadsheet.set('A2', '=2*Cylinder.Radius') Spreadsheet.set('B2', '=-Pipe.Value') Spreadsheet.set('C2', '=2*(Cylinder.Radius + Pipe.Value)') self.Doc.recompute() self.assertEqual(Spreadsheet.B2, Units.Quantity('1 mm')) self.assertEqual(Spreadsheet.C2, Units.Quantity('8 mm')) App.closeDocument("Issue2876") def testSubElements(self): box = Part.makeBox(1, 1, 1) with self.assertRaises(ValueError): box.getElement("InvalidName") with self.assertRaises(ValueError): box.getElement("Face6_abc") # getSubTopoShape now catches this before it gets to OCC, so the error changes: # with self.assertRaises(Part.OCCError): with self.assertRaises(IndexError): box.getElement("Face7") def tearDown(self): #closing doc FreeCAD.closeDocument("PartTest") class PartTestCurveToNurbs(unittest.TestCase): def testCircleToNurbs(self): mat = Base.Matrix() mat.rotateX(1) mat.rotateY(1) mat.rotateZ(1) circle = Part.Circle() circle.Radius = 5 circle.transform(mat) nurbs = circle.toNurbs() self.assertEqual(circle.value(0), nurbs.value(0)) arc = circle.trim(0, 2) nurbs = arc.toNurbs() self.assertEqual(circle.value(0), nurbs.value(0)) spline = circle.toBSpline() self.assertAlmostEqual(circle.value(0).distanceToPoint(spline.value(0)), 0) def testEllipseToNurbs(self): mat = Base.Matrix() mat.rotateX(1) mat.rotateY(1) mat.rotateZ(1) ellipse = Part.Ellipse() ellipse.MajorRadius = 5 ellipse.MinorRadius = 3 ellipse.transform(mat) nurbs = ellipse.toNurbs() self.assertEqual(ellipse.value(0), nurbs.value(0)) arc = ellipse.trim(0, 2) nurbs = arc.toNurbs() self.assertEqual(ellipse.value(0), nurbs.value(0)) spline = ellipse.toBSpline() self.assertAlmostEqual(ellipse.value(0).distanceToPoint(spline.value(0)), 0) class PartTestBSplineSurface(unittest.TestCase): def testTorusToSpline(self): to = Part.Toroid() bs = to.toBSpline() bs.setUPeriodic() bs.setVPeriodic() self.assertGreater(len(bs.UKnotSequence), 0) self.assertGreater(len(bs.VKnotSequence), 0) def testBounds(self): to = Part.Toroid() bs = to.toBSpline() self.assertAlmostEqual(bs.bounds()[1], 2 * math.pi) self.assertAlmostEqual(bs.bounds()[3], 2 * math.pi) bs.scaleKnotsToBounds(0.0, 1.0, 0.0, 1.0) self.assertAlmostEqual(bs.bounds()[1], 1.0) self.assertAlmostEqual(bs.bounds()[3], 1.0) class PartTestNormals(unittest.TestCase): def setUp(self): self.face = Part.makePlane(1, 1) def testFaceNormal(self): self.assertEqual(self.face.normalAt(0, 0), Base.Vector(0, 0, 1)) self.assertEqual(self.face.Surface.normal(0, 0), Base.Vector(0, 0, 1)) def testReverseOrientation(self): self.face.reverse() self.assertEqual(self.face.normalAt(0, 0), Base.Vector(0, 0, -1)) self.assertEqual(self.face.Surface.normal(0, 0), Base.Vector(0, 0, 1)) def testPlacement(self): self.face.reverse() self.face.Placement.Rotation.Angle = 1 self.face.Placement.Rotation.Axis = (1,1,1) vec = Base.Vector(-0.63905, 0.33259, -0.69353) self.assertGreater(self.face.normalAt(0, 0).dot(vec), 0.9999) self.assertLess(self.face.Surface.normal(0, 0).dot(vec), -0.9999) def tearDown(self): pass class PartTestShapeRotate(unittest.TestCase): def testPlacement(self): tol = 1e-12 box = Part.makeBox(1, 1, 1) box.Placement.Base = Base.Vector(10, 10, 10) box.rotate((0, 0, 0), (0, 0, 1), 90) p1 = Base.Placement() p1.Base = Base.Vector(10, 10, 10) p2 = Base.Placement() p2.Rotation.Angle = math.radians(90) self.assertTrue(box.Placement.isSame(p2 * p1, tol)) p3 = p1.copy() p3.rotate((0, 0, 0), (0, 0, 1), 90) self.assertTrue(p3.isSame(p1 * p2, tol)) self.assertFalse(box.Placement.isSame(p3, tol)) p4 = p1.copy() p4.rotate((0, 0, 0), (0, 0, 1), 90, True) self.assertTrue(p4.isSame(p2 * p1, tol)) self.assertTrue(box.Placement.isSame(p4, tol)) class PartTestCircle2D(unittest.TestCase): def testValidCircle(self): p1 = App.Base.Vector2d(0.01, 0.01) p2 = App.Base.Vector2d(0.02, 0.02) p3 = App.Base.Vector2d(0.01, -0.01) Part.Geom2d.Circle2d.getCircleCenter(p1, p2, p3) def testCollinearPoints(self): p1 = App.Base.Vector2d(0.01, 0.01) p2 = App.Base.Vector2d(0.02, 0.02) p3 = App.Base.Vector2d(0.04, 0.0399) with self.assertRaises(ValueError): Part.Geom2d.Circle2d.getCircleCenter(p1, p2, p3) class PartTestCone(unittest.TestCase): def testderivatives(self): def get_dn(surface, u, v): pos = surface.value(u, v) v10 = surface.getDN(u, v, 1, 0) v01 = surface.getDN(u, v, 0, 1) v11 = surface.getDN(u, v, 1, 1) return (pos, v10, v01, v11) cone = Part.Cone() cone.SemiAngle = 0.2 cone.Radius = 2.0 u, v = (5.0, 5.0) vp, v1, v2, v3 = get_dn(cone, u, v) shape = cone.toShape(0, 2*math.pi, 0, 10) shape = shape.toNurbs() spline = shape.Face1.Surface u, v = spline.parameter(vp) wp, w1, w2, w3 = get_dn(spline, u, v) self.assertAlmostEqual(vp.distanceToPoint(wp), 0) self.assertAlmostEqual(v1.getAngle(w1), 0) self.assertAlmostEqual(v2.getAngle(w2), 0) self.assertAlmostEqual(v3.getAngle(w3), 0) class PartTestChFi2dAlgos(unittest.TestCase): def testChFi2d_FilletAlgo(self): v = FreeCAD.Vector edge1 = Part.makeLine(v(0,0,0), v(0,10,0)) edge2 = Part.makeLine(v(0,10,0), v(10,10,0)) wire = Part.Wire([edge1, edge2]) pln = Part.Plane() with self.assertRaises(TypeError): alg = Part.ChFi2d.FilletAlgo(pln) alg = Part.ChFi2d.FilletAlgo() with self.assertRaises(TypeError): alg.init() print (alg) # Test without shape with self.assertRaises(Base.CADKernelError): alg.perform(1) with self.assertRaises(TypeError): alg.perform() alg = Part.ChFi2d.FilletAlgo(wire, pln) alg.init(edge1, edge2, pln) alg.init(wire, pln) alg = Part.ChFi2d.FilletAlgo(edge1, edge2, pln) alg.perform(1.0) with self.assertRaises(TypeError): alg.numberOfResults() with self.assertRaises(TypeError): alg.result(1) self.assertEqual(alg.numberOfResults(Base.Vector(0,10,0)), 1) result = alg.result(Base.Vector(0,10,0)) curve = result[0].Curve self.assertEqual(type(curve), Part.Circle) self.assertEqual(curve.Axis, pln.Axis) self.assertEqual(curve.Radius, 1.0) def testChFi2d_AnaFilletAlgo(self): v = FreeCAD.Vector edge1 = Part.makeLine(v(0,0,0), v(0,10,0)) edge2 = Part.makeLine(v(0,10,0), v(10,10,0)) wire = Part.Wire([edge1, edge2]) pln = Part.Plane() with self.assertRaises(TypeError): alg = Part.ChFi2d.AnaFilletAlgo(pln) alg = Part.ChFi2d.AnaFilletAlgo() with self.assertRaises(TypeError): alg.init() print (alg) # Test without shape self.assertFalse(alg.perform(1)) with self.assertRaises(TypeError): alg.perform() alg = Part.ChFi2d.AnaFilletAlgo(wire, pln) alg.init(edge1, edge2, pln) alg.init(wire, pln) alg = Part.ChFi2d.AnaFilletAlgo(edge1, edge2, pln) alg.perform(1.0) with self.assertRaises(TypeError): alg.result(1) result = alg.result() curve = result[0].Curve self.assertEqual(type(curve), Part.Circle) self.assertEqual(curve.Radius, 1.0) def testChFi2d_ChamferAPI(self): v = FreeCAD.Vector edge1 = Part.makeLine(v(0,0,0), v(0,10,0)) edge2 = Part.makeLine(v(0,10,0), v(10,10,0)) wire = Part.Wire([edge1, edge2]) with self.assertRaises(TypeError): alg = Part.ChFi2d.ChamferAPI(edge1) alg = Part.ChFi2d.ChamferAPI(wire) with self.assertRaises(TypeError): alg.init() print (alg) with self.assertRaises(TypeError): alg.perform(1) alg = Part.ChFi2d.ChamferAPI(wire) alg.init(edge1, edge2) alg.init(wire) alg = Part.ChFi2d.ChamferAPI(edge1, edge2) alg.perform() with self.assertRaises(TypeError): alg.result(1) result = alg.result(1.0, 1.0) curve = result[0].Curve self.assertEqual(type(curve), Part.Line) class PartTestRuledSurface(unittest.TestCase): def setUp(self): self.Doc = FreeCAD.newDocument() def testRuledSurfaceFromTwoObjects(self): line1 = Part.makeLine(FreeCAD.Vector(-70,-30,0), FreeCAD.Vector(-50,40,0)) line2 = Part.makeLine(FreeCAD.Vector(-40,-30,0), FreeCAD.Vector(-40,10,0)) plm1 = FreeCAD.Placement() plm1.Rotation = FreeCAD.Rotation(0.7071067811865476, 0.0, 0.0, 0.7071067811865475) line1.Placement = plm1 fea1 = self.Doc.addObject("Part::Feature") fea2 = self.Doc.addObject("Part::Feature") fea1.Shape = line1 fea2.Shape = line2 ruled = self.Doc.addObject("Part::RuledSurface") ruled.Curve1 = fea1 ruled.Curve2 = fea2 self.Doc.recompute() same1 = getCoincidentVertexes(fea1.Shape.Vertexes, ruled.Shape.Vertexes) same2 = getCoincidentVertexes(fea2.Shape.Vertexes, ruled.Shape.Vertexes) self.assertEqual(len(same1), 2) self.assertEqual(len(same2), 2) def testRuledSurfaceFromTwoObjectsWithSharedVertexs(self): """Test reproducing issue #15539""" # Arrange line = Part.makeLine(FreeCAD.Vector(0, 0, 50), FreeCAD.Vector(0, -50, 0)) line1 = Part.makeLine(FreeCAD.Vector(0, 0, 50), FreeCAD.Vector(50, 0, 0)) line2 = Part.makeLine(FreeCAD.Vector(0, 0, 0), FreeCAD.Vector(0, -50, 0)) line3 = Part.makeLine(FreeCAD.Vector(0, 0, 0), FreeCAD.Vector(50, 0, 0)) fea = self.Doc.addObject("Part::Feature") fea1 = self.Doc.addObject("Part::Feature") fea2 = self.Doc.addObject("Part::Feature") fea3 = self.Doc.addObject("Part::Feature") fea.Shape = line fea1.Shape = line1 fea2.Shape = line2 fea3.Shape = line3 # Defining all the surfaces generated by 2 lines with one common vertex ruled = self.Doc.addObject("Part::RuledSurface") ruled.Curve1 = fea ruled.Curve2 = fea1 ruled1 = self.Doc.addObject("Part::RuledSurface") ruled1.Curve1 = fea1 ruled1.Curve2 = fea3 ruled2 = self.Doc.addObject("Part::RuledSurface") ruled2.Curve1 = fea2 ruled2.Curve2 = fea3 ruled3 = self.Doc.addObject("Part::RuledSurface") ruled3.Curve1 = fea ruled3.Curve2 = fea2 # Act self.Doc.recompute() # Assert same00 = getCoincidentVertexes(fea.Shape.Vertexes, ruled.Shape.Vertexes) same03 = getCoincidentVertexes(fea.Shape.Vertexes, ruled3.Shape.Vertexes) same10 = getCoincidentVertexes(fea1.Shape.Vertexes, ruled.Shape.Vertexes) same11 = getCoincidentVertexes(fea1.Shape.Vertexes, ruled1.Shape.Vertexes) same22 = getCoincidentVertexes(fea2.Shape.Vertexes, ruled2.Shape.Vertexes) same23 = getCoincidentVertexes(fea2.Shape.Vertexes, ruled3.Shape.Vertexes) same31 = getCoincidentVertexes(fea3.Shape.Vertexes, ruled1.Shape.Vertexes) same32 = getCoincidentVertexes(fea3.Shape.Vertexes, ruled2.Shape.Vertexes) # BRepFill::Face() seems creating faces with 4 vertexes # Therefore, in this case, every face shares 3 vertexes (1 counted twice as coincident) with the lines that generate that face self.assertEqual(len(same00), 3) self.assertEqual(len(same03), 3) self.assertEqual(len(same10), 3) self.assertEqual(len(same11), 3) self.assertEqual(len(same22), 3) self.assertEqual(len(same23), 3) self.assertEqual(len(same31), 3) self.assertEqual(len(same32), 3) def testRuledSurfaceFromOneObject(self): sketch = self.Doc.addObject('Sketcher::SketchObject', 'Sketch') sketch.Placement = FreeCAD.Placement(FreeCAD.Vector(0.000000, 0.000000, 0.000000), App.Rotation(0.707107, 0.000000, 0.000000, 0.707107)) sketch.MapMode = "Deactivated" sketch.addGeometry(Part.LineSegment(App.Vector(-43.475811,34.364464,0),App.Vector(-65.860519,-20.078733,0)),False) sketch.addGeometry(Part.LineSegment(App.Vector(14.004498,27.390331,0),App.Vector(33.577049,-27.952749,0)),False) ruled = self.Doc.addObject('Part::RuledSurface', 'Ruled Surface') ruled.Curve1 = (sketch,['Edge1']) ruled.Curve2 = (sketch,['Edge2']) self.Doc.recompute() same = getCoincidentVertexes(sketch.Shape.Vertexes, ruled.Shape.Vertexes) self.assertEqual(len(same), 4) def tearDown(self): FreeCAD.closeDocument(self.Doc.Name) class PartTestShapeFix(unittest.TestCase): def testShapeFix_Root(self): with self.assertRaises(TypeError): Part.ShapeFix.Root([]) fix = Part.ShapeFix.Root() print (fix) fix.Precision = 0.0 self.assertEqual(fix.Precision, 0.0) fix.MinTolerance = 0.0 self.assertEqual(fix.MinTolerance, 0.0) fix.MaxTolerance = 0.5 self.assertEqual(fix.MaxTolerance, 0.5) self.assertEqual(fix.limitTolerance(0.25), 0.25) def testShapeFix_Shape(self): surface = Part.Plane() face = surface.toShape(-1, 1, -1, 1) with self.assertRaises(TypeError): Part.ShapeFix.Shape([]) fix = Part.ShapeFix.Shape(face) fix.init(face) print (fix) fix.shape() fix.fixSolidTool() fix.fixShellTool() fix.fixFaceTool() fix.fixWireTool() fix.fixEdgeTool() fix.FixSolidMode = True self.assertEqual(fix.FixSolidMode, True) fix.FixFreeShellMode = True self.assertEqual(fix.FixFreeShellMode, True) fix.FixFreeFaceMode = True self.assertEqual(fix.FixFreeFaceMode, True) fix.FixFreeWireMode = True self.assertEqual(fix.FixFreeWireMode, True) fix.FixSameParameterMode = True self.assertEqual(fix.FixSameParameterMode, True) fix.FixVertexPositionMode = True self.assertEqual(fix.FixVertexPositionMode, True) fix.FixVertexTolMode = True self.assertEqual(fix.FixVertexTolMode, True) fix.perform() def testShapeFix_Edge(self): surface = Part.Plane() face = surface.toShape(-1, 1, -1, 1) with self.assertRaises(TypeError): Part.ShapeFix.Edge([]) wirefix = Part.ShapeFix.Wire(face.OuterWire, face, 1e-7) fix = wirefix.fixEdgeTool() print (fix) fix.fixRemovePCurve(face.Edge1, face) fix.fixRemovePCurve(face.Edge1, face.Surface, face.Placement) with self.assertRaises(TypeError): fix.fixRemovePCurve(face) fix.fixRemoveCurve3d(face.Edge1) fix.fixAddCurve3d(face.Edge1) fix.fixAddPCurve(face.Edge1, face, False) fix.fixAddPCurve(face.Edge1, face.Surface, face.Placement, False) with self.assertRaises(TypeError): fix.fixAddPCurve(face) fix.fixVertexTolerance(face.Edge1) fix.fixVertexTolerance(face.Edge1, face) fix.fixReversed2d(face.Edge1, face) fix.fixReversed2d(face.Edge1, face.Surface, face.Placement) with self.assertRaises(TypeError): fix.fixReversed2d(face) fix.fixSameParameter(face.Edge1) fix.fixSameParameter(face.Edge1, face) with self.assertRaises(TypeError): fix.fixSameParameter(face) def testShapeFix_Face(self): surface = Part.Plane() face = surface.toShape(-1, 1, -1, 1) Part.ShapeFix.Face() Part.ShapeFix.Face(surface, 0.00001, True) with self.assertRaises(TypeError): Part.ShapeFix.Face([]) fix = Part.ShapeFix.Face(face) print (fix) fix.fixOrientation() fix.fixAddNaturalBound() fix.fixMissingSeam() fix.fixSmallAreaWire(True) fix.fixLoopWire() fix.fixIntersectingWires() fix.fixWiresTwoCoincidentEdges() fix.fixPeriodicDegenerated() fix.perform() fix.add(face.OuterWire) current = fix.face() result = fix.result() fix.fixWireTool() fix.FixWireMode = True self.assertEqual(fix.FixWireMode, True) fix.FixOrientationMode = True self.assertEqual(fix.FixOrientationMode, True) fix.FixAddNaturalBoundMode = True self.assertEqual(fix.FixAddNaturalBoundMode, True) fix.FixMissingSeamMode = True self.assertEqual(fix.FixMissingSeamMode, True) fix.FixSmallAreaWireMode = True self.assertEqual(fix.FixSmallAreaWireMode, True) fix.RemoveSmallAreaFaceMode = True self.assertEqual(fix.RemoveSmallAreaFaceMode, True) fix.FixIntersectingWiresMode = True self.assertEqual(fix.FixIntersectingWiresMode, True) fix.FixLoopWiresMode = True self.assertEqual(fix.FixLoopWiresMode, True) fix.FixSplitFaceMode = True self.assertEqual(fix.FixSplitFaceMode, True) fix.AutoCorrectPrecisionMode = True self.assertEqual(fix.AutoCorrectPrecisionMode, True) fix.FixPeriodicDegeneratedMode = True self.assertEqual(fix.FixPeriodicDegeneratedMode, True) fix.clearModes() def testShapeFix_Shell(self): surface = Part.Plane() face = surface.toShape(-1, 1, -1, 1) shell = Part.Shell([face]) Part.ShapeFix.Shell() with self.assertRaises(TypeError): Part.ShapeFix.Face([]) fix = Part.ShapeFix.Shell(shell) fix.init(shell) print (fix) fix.perform() fix.shell() fix.shape() fix.fixFaceTool() fix.setNonManifoldFlag(True) fix.fixFaceOrientation(shell) self.assertEqual(len(fix.errorFaces().Faces), 0) self.assertEqual(fix.numberOfShells(), 1) fix.FixFaceMode = True self.assertEqual(fix.FixFaceMode, True) fix.FixOrientationMode = True self.assertEqual(fix.FixOrientationMode, True) def testShapeFix_Solid(self): box = Part.makeBox(1, 1, 1) with self.assertRaises(TypeError): Part.ShapeFix.Solid([]) fix = Part.ShapeFix.Solid() fix.init(box) print (fix) fix.perform() fix.solid() fix.shape() fix.fixShellTool() fix.solidFromShell(box.Shells[0]) fix.FixShellMode = True self.assertEqual(fix.FixShellMode, True) fix.FixShellOrientationMode = True self.assertEqual(fix.FixShellOrientationMode, True) fix.CreateOpenSolidMode = True self.assertEqual(fix.CreateOpenSolidMode, True) def testShapeFix_Wire(self): with self.assertRaises(TypeError): Part.ShapeFix.Wire([]) surface = Part.Plane() face = surface.toShape(-1, 1, -1, 1) Part.ShapeFix.Wire(face.OuterWire, face, 1e-7) fix = Part.ShapeFix.Wire() fix.init(face.OuterWire, face, 1e-7) fix.load(face.OuterWire) fix.setSurface(surface) fix.setSurface(surface, face.Placement) fix.setFace(face) fix.setMaxTailAngle(math.pi) fix.setMaxTailWidth(10.0) fix.fixEdgeTool() self.assertEqual(fix.isLoaded(), True) self.assertEqual(fix.isReady(), True) self.assertEqual(fix.numberOfEdges(), 4) print (fix) fix.clearModes() fix.clearStatuses() fix.wire() fix.wireAPIMake() fix.face() fix.ModifyTopologyMode = True self.assertEqual(fix.ModifyTopologyMode, True) fix.ModifyGeometryMode = True self.assertEqual(fix.ModifyGeometryMode, True) fix.ModifyRemoveLoopMode = True self.assertEqual(fix.ModifyRemoveLoopMode, True) fix.ClosedWireMode = True self.assertEqual(fix.ClosedWireMode, True) fix.PreferencePCurveMode = True self.assertEqual(fix.PreferencePCurveMode, True) fix.FixGapsByRangesMode = True self.assertEqual(fix.FixGapsByRangesMode, True) fix.FixReorderMode = True self.assertEqual(fix.FixReorderMode, True) fix.FixSmallMode = True self.assertEqual(fix.FixSmallMode, True) fix.FixConnectedMode = True self.assertEqual(fix.FixConnectedMode, True) fix.FixEdgeCurvesMode = True self.assertEqual(fix.FixEdgeCurvesMode, True) fix.FixDegeneratedMode = True self.assertEqual(fix.FixDegeneratedMode, True) fix.FixSelfIntersectionMode = True self.assertEqual(fix.FixSelfIntersectionMode, True) fix.FixLackingMode = True self.assertEqual(fix.FixLackingMode, True) fix.FixGaps3dMode = True self.assertEqual(fix.FixGaps3dMode, True) fix.FixGaps2dMode = True self.assertEqual(fix.FixGaps2dMode, True) fix.FixReversed2dMode = True self.assertEqual(fix.FixReversed2dMode, True) fix.FixRemovePCurveMode = True self.assertEqual(fix.FixRemovePCurveMode, True) fix.FixAddPCurveMode = True self.assertEqual(fix.FixAddPCurveMode, True) fix.FixRemoveCurve3dMode = True self.assertEqual(fix.FixRemoveCurve3dMode, True) fix.FixAddCurve3dMode = True self.assertEqual(fix.FixAddCurve3dMode, True) fix.FixSeamMode = True self.assertEqual(fix.FixSeamMode, True) fix.FixShiftedMode = True self.assertEqual(fix.FixShiftedMode, True) fix.FixSameParameterMode = True self.assertEqual(fix.FixSameParameterMode, True) fix.FixVertexToleranceMode = True self.assertEqual(fix.FixVertexToleranceMode, True) fix.FixNotchedEdgesMode = True self.assertEqual(fix.FixNotchedEdgesMode, True) fix.FixSelfIntersectingEdgeMode = True self.assertEqual(fix.FixSelfIntersectingEdgeMode, True) fix.FixIntersectingEdgesMode = True self.assertEqual(fix.FixIntersectingEdgesMode, True) fix.FixNonAdjacentIntersectingEdgesMode = True self.assertEqual(fix.FixNonAdjacentIntersectingEdgesMode, True) fix.FixTailMode = True self.assertEqual(fix.FixTailMode, True) fix.perform() fix.fixReorder() fix.fixSmall(True) fix.fixSmall(1, True, 1e-7) fix.fixConnected() fix.fixConnected(1, True) fix.fixEdgeCurves() fix.fixDegenerated() fix.fixDegenerated(1) fix.fixSelfIntersection() fix.fixLacking() fix.fixLacking(1, False) fix.fixClosed() fix.fixGaps3d() fix.fixGaps2d() fix.fixSeam(1) fix.fixShifted() fix.fixNotchedEdges() fix.fixGap3d(1, False) fix.fixGap2d(1, False) fix.fixTails() class PartBOPTestContainer(unittest.TestCase): def setUp(self): self.Doc = FreeCAD.newDocument() def testMakeFuse(self): box = self.Doc.addObject("Part::Box", "Box") cyl = self.Doc.addObject("Part::Cylinder", "Cylinder") part = self.Doc.addObject("App::Part", "Part") part.addObject(box) part.addObject(cyl) from BOPTools import BOPFeatures bp = BOPFeatures.BOPFeatures(self.Doc) fuse = bp.make_multi_fuse([cyl.Name, box.Name]) self.assertEqual(part, fuse.getParent()) def testMakeCut(self): box = self.Doc.addObject("Part::Box", "Box") cyl = self.Doc.addObject("Part::Cylinder", "Cylinder") part = self.Doc.addObject("App::Part", "Part") part.addObject(box) part.addObject(cyl) from BOPTools import BOPFeatures bp = BOPFeatures.BOPFeatures(self.Doc) fuse = bp.make_cut([cyl.Name, box.Name]) self.assertEqual(part, fuse.getParent()) def testMakeCommon(self): box = self.Doc.addObject("Part::Box", "Box") cyl = self.Doc.addObject("Part::Cylinder", "Cylinder") part = self.Doc.addObject("App::Part", "Part") part.addObject(box) part.addObject(cyl) from BOPTools import BOPFeatures bp = BOPFeatures.BOPFeatures(self.Doc) fuse = bp.make_multi_common([cyl.Name, box.Name]) self.assertEqual(part, fuse.getParent()) def tearDown(self): FreeCAD.closeDocument(self.Doc.Name) class BSplineCurve2d(unittest.TestCase): def setUp(self): vec2 = FreeCAD.Base.Vector2d self.pts = [vec2(0, 0), vec2(1, 0)] self.bs = Part.Geom2d.BSplineCurve2d() def testInterpolate(self): self.bs.interpolate(Points=self.pts) def testApproximate(self): self.bs.approximate(Points=self.pts) class GeometryCurve(unittest.TestCase): def testProject(self): line = Part.Line() line.projectPoint(FreeCAD.Vector()) class EmptyEdge(unittest.TestCase): def testParameterByLength(self): with self.assertRaises(ValueError): edge = Part.Edge() edge.getParameterByLength(0) def testValueAt(self): with self.assertRaises(ValueError): edge = Part.Edge() edge.valueAt(0) def testParameters(self): with self.assertRaises(ValueError): edge = Part.Edge() face = Part.Face() edge.parameters(face) def testParameterAt(self): with self.assertRaises(ValueError): edge = Part.Edge() vertex = Part.Vertex(0, 0, 0) edge.parameterAt(vertex) def testTangentAt(self): with self.assertRaises(ValueError): edge = Part.Edge() edge.tangentAt(0) def testCurvatureAt(self): with self.assertRaises(ValueError): edge = Part.Edge() edge.curvatureAt(0) def testCenterOfCurvatureAt(self): with self.assertRaises(ValueError): edge = Part.Edge() edge.centerOfCurvatureAt(0) def testDerivative1At(self): with self.assertRaises(ValueError): edge = Part.Edge() edge.derivative1At(0) def testDerivative2At(self): with self.assertRaises(ValueError): edge = Part.Edge() edge.derivative2At(0) def testDerivative3At(self): with self.assertRaises(ValueError): edge = Part.Edge() edge.derivative3At(0) def testNormalAt(self): with self.assertRaises(ValueError): edge = Part.Edge() edge.normalAt(0) def testFirstVertex(self): with self.assertRaises(ValueError): edge = Part.Edge() edge.firstVertex() def testLastVertex(self): with self.assertRaises(ValueError): edge = Part.Edge() edge.lastVertex() def testGetTolerance(self): with self.assertRaises(ValueError): edge = Part.Edge() edge.Tolerance def testSetTolerance(self): with self.assertRaises(ValueError): edge = Part.Edge() edge.Tolerance = 0.01 def testLength(self): with self.assertRaises(ValueError): edge = Part.Edge() edge.Length def testCurve(self): with self.assertRaises(ValueError): edge = Part.Edge() edge.Curve def testParameterRange(self): with self.assertRaises(ValueError): edge = Part.Edge() edge.ParameterRange def testFirstParameter(self): with self.assertRaises(ValueError): edge = Part.Edge() edge.FirstParameter def testLastParameter(self): with self.assertRaises(ValueError): edge = Part.Edge() edge.LastParameter class EmptyFace(unittest.TestCase): def testMakeOffset(self): with self.assertRaises(ValueError): face = Part.Face() face.makeOffset(1) def testValueAt(self): with self.assertRaises(ValueError): face = Part.Face() face.valueAt(0, 0) def testNormalAt(self): with self.assertRaises(ValueError): face = Part.Face() face.normalAt(0, 0) def testTangentAt(self): with self.assertRaises(ValueError): face = Part.Face() face.tangentAt(0, 0) def testCurvatureAt(self): with self.assertRaises(ValueError): face = Part.Face() face.curvatureAt(0, 0) def testDerivative1At(self): with self.assertRaises(ValueError): face = Part.Face() face.derivative1At(0, 0) def testDerivative2At(self): with self.assertRaises(ValueError): face = Part.Face() face.derivative2At(0, 0) def testCutHoles(self): with self.assertRaises(ValueError): face = Part.Face() circle = Part.Circle() wire = Part.Wire(Part.Edge(circle)) face.cutHoles([wire]) def testUVNodes(self): with self.assertRaises(ValueError): face = Part.Face() face.getUVNodes() def testGetTolerance(self): with self.assertRaises(ValueError): face = Part.Face() face.Tolerance def testSetTolerance(self): with self.assertRaises(ValueError): face = Part.Face() face.Tolerance = 0.01 def testParameterRange(self): with self.assertRaises(ValueError): face = Part.Face() face.ParameterRange