FreeCAD

Форк
0
/
TestPartApp.py 
1119 строк · 37.8 Кб
1
#**************************************************************************
2
#   Copyright (c) 2011 Juergen Riegel <FreeCAD@juergen-riegel.net>        *
3
#                                                                         *
4
#   This file is part of the FreeCAD CAx development system.              *
5
#                                                                         *
6
#   This program is free software; you can redistribute it and/or modify  *
7
#   it under the terms of the GNU Lesser General Public License (LGPL)    *
8
#   as published by the Free Software Foundation; either version 2 of     *
9
#   the License, or (at your option) any later version.                   *
10
#   for detail see the LICENCE text file.                                 *
11
#                                                                         *
12
#   FreeCAD is distributed in the hope that it will be useful,            *
13
#   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
14
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
15
#   GNU Library General Public License for more details.                  *
16
#                                                                         *
17
#   You should have received a copy of the GNU Library General Public     *
18
#   License along with FreeCAD; if not, write to the Free Software        *
19
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
20
#   USA                                                                   *
21
#**************************************************************************
22

23
import FreeCAD, unittest, Part
24
import copy
25
import math
26
from FreeCAD import Units
27
from FreeCAD import Base
28
App = FreeCAD
29

30
from parttests.BRep_tests import BRepTests
31
from parttests.Geom2d_tests import Geom2dTests
32
from parttests.regression_tests import RegressionTests
33
from parttests.TopoShapeListTest import TopoShapeListTest
34
from parttests.TopoShapeTest import TopoShapeTest
35

36
#---------------------------------------------------------------------------
37
# define the test cases to test the FreeCAD Part module
38
#---------------------------------------------------------------------------
39
def getCoincidentVertexes(vtx1, vtx2):
40
    pairs = []
41
    tol = Part.Precision.confusion()
42
    for i in vtx1:
43
        for j in vtx2:
44
            if i.Point.distanceToPoint(j.Point) < tol:
45
                pairs.append((i, j))
46

47
    return pairs
48

49

50
class PartTestCases(unittest.TestCase):
51
    def setUp(self):
52
        self.Doc = FreeCAD.newDocument("PartTest")
53

54
    def testBoxCase(self):
55
        self.Box = self.Doc.addObject("Part::Box","Box")
56
        self.Doc.recompute()
57
        self.assertEqual(len(self.Box.Shape.Faces), 6)
58

59
    def testIssue2985(self):
60
        v1 = App.Vector(0.0,0.0,0.0)
61
        v2 = App.Vector(10.0,0.0,0.0)
62
        v3 = App.Vector(10.0,0.0,10.0)
63
        v4 = App.Vector(0.0,0.0,10.0)
64
        edge1 = Part.makeLine(v1, v2)
65
        edge2 = Part.makeLine(v2, v3)
66
        edge3 = Part.makeLine(v3, v4)
67
        edge4 = Part.makeLine(v4, v1)
68
        # Travis build confirms the crash under macOS
69
        #result = Part.makeFilledFace([edge1,edge2,edge3,edge4])
70
        #self.Doc.addObject("Part::Feature","Face").Shape = result
71
        #self.assertTrue(isinstance(result.Surface, Part.BSplineSurface))
72

73
    def tearDown(self):
74
        #closing doc
75
        FreeCAD.closeDocument("PartTest")
76
        #print ("omit closing document for debugging")
77

78
class PartTestBSplineCurve(unittest.TestCase):
79
    def setUp(self):
80
        self.Doc = FreeCAD.newDocument("PartTest")
81

82
        poles = [[0, 0, 0], [1, 1, 0], [2, 0, 0]]
83
        self.spline = Part.BSplineCurve()
84
        self.spline.buildFromPoles(poles)
85

86
        poles = [[0, 0, 0], [1, 1, 0], [2, 0, 0], [1, -1, 0]]
87
        self.nurbs = Part.BSplineCurve()
88
        self.nurbs.buildFromPolesMultsKnots(poles, (3, 1, 3),(0, 0.5, 1), False, 2)
89

90
    def testProperties(self):
91
        self.assertEqual(self.spline.Continuity, 'CN')
92
        self.assertEqual(self.spline.Degree, 2)
93
        self.assertEqual(self.spline.EndPoint, App.Vector(2, 0, 0))
94
        self.assertEqual(self.spline.FirstParameter, 0.0)
95
        self.assertEqual(self.spline.FirstUKnotIndex, 1)
96
        self.assertEqual(self.spline.KnotSequence, [0.0, 0.0, 0.0, 1.0, 1.0, 1.0])
97
        self.assertEqual(self.spline.LastParameter, 1.0)
98
        self.assertEqual(self.spline.LastUKnotIndex, 2)
99
        max_degree = self.spline.MaxDegree
100
        self.assertEqual(self.spline.NbKnots, 2)
101
        self.assertEqual(self.spline.NbPoles, 3)
102
        self.assertEqual(self.spline.StartPoint, App.Vector(0.0, 0.0, 0.0))
103

104
    def testGetters(self):
105
        '''only check if the function doesn't crash'''
106
        self.spline.getKnot(1)
107
        self.spline.getKnots()
108
        self.spline.getMultiplicities()
109
        self.spline.getMultiplicity(1)
110
        self.spline.getPole(1)
111
        self.spline.getPoles()
112
        self.spline.getPolesAndWeights()
113
        self.spline.getResolution(0.5)
114
        self.spline.getWeight(1)
115
        self.spline.getWeights()
116

117
    def testSetters(self):
118
        spline = copy.copy(self.spline)
119
        spline.setKnot(1, 0.1)
120
        spline.setPeriodic()
121
        spline.setNotPeriodic()
122
        # spline.setKnots()
123
        # spline.setOrigin(2)   # not working?
124
        self.spline.setPole(1, App.Vector([1, 0, 0])) # first parameter 0 gives occ error
125

126
    def testIssue2671(self):
127
        self.Doc = App.newDocument("Issue2671")
128
        Box = self.Doc.addObject("Part::Box","Box")
129
        Mirroring = self.Doc.addObject("Part::Mirroring", 'Mirroring')
130
        Spreadsheet = self.Doc.addObject('Spreadsheet::Sheet', 'Spreadsheet')
131
        Mirroring.Source = Box
132
        Mirroring.Base = (8, 5, 25)
133
        Mirroring.Normal = (0.5, 0.2, 0.9)
134
        Spreadsheet.set('A1', '=Mirroring.Base.x')
135
        Spreadsheet.set('B1', '=Mirroring.Base.y')
136
        Spreadsheet.set('C1', '=Mirroring.Base.z')
137
        Spreadsheet.set('A2', '=Mirroring.Normal.x')
138
        Spreadsheet.set('B2', '=Mirroring.Normal.y')
139
        Spreadsheet.set('C2', '=Mirroring.Normal.z')
140
        self.Doc.recompute()
141
        self.assertEqual(Spreadsheet.A1, Units.Quantity('8 mm'))
142
        self.assertEqual(Spreadsheet.B1, Units.Quantity('5 mm'))
143
        self.assertEqual(Spreadsheet.C1, Units.Quantity('25 mm'))
144
        self.assertEqual(Spreadsheet.A2, Units.Quantity('0.5 mm'))
145
        self.assertEqual(Spreadsheet.B2, Units.Quantity('0.2 mm'))
146
        self.assertEqual(Spreadsheet.C2, Units.Quantity('0.9 mm'))
147
        App.closeDocument("Issue2671")
148

149
    def testIssue2876(self):
150
        self.Doc = App.newDocument("Issue2876")
151
        Cylinder = self.Doc.addObject("Part::Cylinder", "Cylinder")
152
        Cylinder.Radius = 5
153
        Pipe = self.Doc.addObject("Part::Thickness", "Pipe")
154
        Pipe.Faces = (Cylinder, ["Face2", "Face3"])
155
        Pipe.Mode = 1
156
        Pipe.Value = -1 # negative wall thickness
157
        Spreadsheet = self.Doc.addObject('Spreadsheet::Sheet', 'Spreadsheet')
158
        Spreadsheet.set('A1', 'Pipe OD')
159
        Spreadsheet.set('B1', 'Pipe WT')
160
        Spreadsheet.set('C1', 'Pipe ID')
161
        Spreadsheet.set('A2', '=2*Cylinder.Radius')
162
        Spreadsheet.set('B2', '=-Pipe.Value')
163
        Spreadsheet.set('C2', '=2*(Cylinder.Radius + Pipe.Value)')
164
        self.Doc.recompute()
165
        self.assertEqual(Spreadsheet.B2, Units.Quantity('1 mm'))
166
        self.assertEqual(Spreadsheet.C2, Units.Quantity('8 mm'))
167
        App.closeDocument("Issue2876")
168

169
    def testSubElements(self):
170
        box = Part.makeBox(1, 1, 1)
171
        with self.assertRaises(ValueError):
172
            box.getElement("InvalidName")
173
        with self.assertRaises(ValueError):
174
            box.getElement("Face6_abc")
175
        # getSubTopoShape now catches this before it gets to OCC, so the error changes:
176
        # with self.assertRaises(Part.OCCError):
177
        with self.assertRaises(IndexError):
178
            box.getElement("Face7")
179

180
    def tearDown(self):
181
        #closing doc
182
        FreeCAD.closeDocument("PartTest")
183

184
class PartTestCurveToNurbs(unittest.TestCase):
185
    def testCircleToNurbs(self):
186
        mat = Base.Matrix()
187
        mat.rotateX(1)
188
        mat.rotateY(1)
189
        mat.rotateZ(1)
190

191
        circle = Part.Circle()
192
        circle.Radius = 5
193

194
        circle.transform(mat)
195
        nurbs = circle.toNurbs()
196
        self.assertEqual(circle.value(0), nurbs.value(0))
197

198
        arc = circle.trim(0, 2)
199
        nurbs = arc.toNurbs()
200
        self.assertEqual(circle.value(0), nurbs.value(0))
201

202
        spline = circle.toBSpline()
203
        self.assertAlmostEqual(circle.value(0).distanceToPoint(spline.value(0)), 0)
204

205
    def testEllipseToNurbs(self):
206
        mat = Base.Matrix()
207
        mat.rotateX(1)
208
        mat.rotateY(1)
209
        mat.rotateZ(1)
210

211
        ellipse = Part.Ellipse()
212
        ellipse.MajorRadius = 5
213
        ellipse.MinorRadius = 3
214

215
        ellipse.transform(mat)
216
        nurbs = ellipse.toNurbs()
217
        self.assertEqual(ellipse.value(0), nurbs.value(0))
218

219
        arc = ellipse.trim(0, 2)
220
        nurbs = arc.toNurbs()
221
        self.assertEqual(ellipse.value(0), nurbs.value(0))
222

223
        spline = ellipse.toBSpline()
224
        self.assertAlmostEqual(ellipse.value(0).distanceToPoint(spline.value(0)), 0)
225

226
class PartTestBSplineSurface(unittest.TestCase):
227
    def testTorusToSpline(self):
228
        to = Part.Toroid()
229
        bs = to.toBSpline()
230
        bs.setUPeriodic()
231
        bs.setVPeriodic()
232
        self.assertGreater(len(bs.UKnotSequence), 0)
233
        self.assertGreater(len(bs.VKnotSequence), 0)
234

235
    def testBounds(self):
236
        to = Part.Toroid()
237
        bs = to.toBSpline()
238
        self.assertAlmostEqual(bs.bounds()[1], 2 * math.pi)
239
        self.assertAlmostEqual(bs.bounds()[3], 2 * math.pi)
240
        bs.scaleKnotsToBounds(0.0, 1.0, 0.0, 1.0)
241
        self.assertAlmostEqual(bs.bounds()[1], 1.0)
242
        self.assertAlmostEqual(bs.bounds()[3], 1.0)
243

244
class PartTestNormals(unittest.TestCase):
245
    def setUp(self):
246
        self.face = Part.makePlane(1, 1)
247

248
    def testFaceNormal(self):
249
        self.assertEqual(self.face.normalAt(0, 0), Base.Vector(0, 0, 1))
250
        self.assertEqual(self.face.Surface.normal(0, 0), Base.Vector(0, 0, 1))
251

252
    def testReverseOrientation(self):
253
        self.face.reverse()
254
        self.assertEqual(self.face.normalAt(0, 0), Base.Vector(0, 0, -1))
255
        self.assertEqual(self.face.Surface.normal(0, 0), Base.Vector(0, 0, 1))
256

257
    def testPlacement(self):
258
        self.face.reverse()
259
        self.face.Placement.Rotation.Angle = 1
260
        self.face.Placement.Rotation.Axis = (1,1,1)
261
        vec = Base.Vector(-0.63905, 0.33259, -0.69353)
262
        self.assertGreater(self.face.normalAt(0, 0).dot(vec), 0.9999)
263
        self.assertLess(self.face.Surface.normal(0, 0).dot(vec), -0.9999)
264

265
    def tearDown(self):
266
        pass
267

268
class PartTestShapeRotate(unittest.TestCase):
269
    def testPlacement(self):
270
        tol = 1e-12
271

272
        box = Part.makeBox(1, 1, 1)
273
        box.Placement.Base = Base.Vector(10, 10, 10)
274
        box.rotate((0, 0, 0), (0, 0, 1), 90)
275

276
        p1 = Base.Placement()
277
        p1.Base = Base.Vector(10, 10, 10)
278

279
        p2 = Base.Placement()
280
        p2.Rotation.Angle = math.radians(90)
281
        self.assertTrue(box.Placement.isSame(p2 * p1, tol))
282

283
        p3 = p1.copy()
284
        p3.rotate((0, 0, 0), (0, 0, 1), 90)
285
        self.assertTrue(p3.isSame(p1 * p2, tol))
286
        self.assertFalse(box.Placement.isSame(p3, tol))
287

288
        p4 = p1.copy()
289
        p4.rotate((0, 0, 0), (0, 0, 1), 90, True)
290
        self.assertTrue(p4.isSame(p2 * p1, tol))
291
        self.assertTrue(box.Placement.isSame(p4, tol))
292

293
class PartTestCircle2D(unittest.TestCase):
294
    def testValidCircle(self):
295
        p1 = App.Base.Vector2d(0.01, 0.01)
296
        p2 = App.Base.Vector2d(0.02, 0.02)
297
        p3 = App.Base.Vector2d(0.01, -0.01)
298
        Part.Geom2d.Circle2d.getCircleCenter(p1, p2, p3)
299

300
    def testCollinearPoints(self):
301
        p1 = App.Base.Vector2d(0.01, 0.01)
302
        p2 = App.Base.Vector2d(0.02, 0.02)
303
        p3 = App.Base.Vector2d(0.04, 0.0399)
304
        with self.assertRaises(ValueError):
305
            Part.Geom2d.Circle2d.getCircleCenter(p1, p2, p3)
306

307
class PartTestCone(unittest.TestCase):
308
    def testderivatives(self):
309
        def get_dn(surface, u, v):
310
            pos = surface.value(u, v)
311
            v10 = surface.getDN(u, v, 1, 0)
312
            v01 = surface.getDN(u, v, 0, 1)
313
            v11 = surface.getDN(u, v, 1, 1)
314
            return (pos, v10, v01, v11)
315

316
        cone = Part.Cone()
317
        cone.SemiAngle = 0.2
318
        cone.Radius = 2.0
319

320
        u, v = (5.0, 5.0)
321
        vp, v1, v2, v3 = get_dn(cone, u, v)
322

323
        shape = cone.toShape(0, 2*math.pi, 0, 10)
324
        shape = shape.toNurbs()
325
        spline = shape.Face1.Surface
326

327
        u, v = spline.parameter(vp)
328
        wp, w1, w2, w3 = get_dn(spline, u, v)
329

330
        self.assertAlmostEqual(vp.distanceToPoint(wp), 0)
331
        self.assertAlmostEqual(v1.getAngle(w1), 0)
332
        self.assertAlmostEqual(v2.getAngle(w2), 0)
333
        self.assertAlmostEqual(v3.getAngle(w3), 0)
334

335
class PartTestChFi2dAlgos(unittest.TestCase):
336
    def testChFi2d_FilletAlgo(self):
337
        v = FreeCAD.Vector
338
        edge1 = Part.makeLine(v(0,0,0), v(0,10,0))
339
        edge2 = Part.makeLine(v(0,10,0), v(10,10,0))
340
        wire = Part.Wire([edge1, edge2])
341
        pln = Part.Plane()
342

343
        with self.assertRaises(TypeError):
344
            alg = Part.ChFi2d.FilletAlgo(pln)
345

346
        alg = Part.ChFi2d.FilletAlgo()
347
        with self.assertRaises(TypeError):
348
            alg.init()
349

350
        print (alg)
351
        # Test without shape
352
        with self.assertRaises(Base.CADKernelError):
353
            alg.perform(1)
354

355
        with self.assertRaises(TypeError):
356
            alg.perform()
357

358
        alg = Part.ChFi2d.FilletAlgo(wire, pln)
359
        alg.init(edge1, edge2, pln)
360
        alg.init(wire, pln)
361

362
        alg = Part.ChFi2d.FilletAlgo(edge1, edge2, pln)
363
        alg.perform(1.0)
364

365
        with self.assertRaises(TypeError):
366
            alg.numberOfResults()
367

368
        with self.assertRaises(TypeError):
369
            alg.result(1)
370

371
        self.assertEqual(alg.numberOfResults(Base.Vector(0,10,0)), 1)
372
        result = alg.result(Base.Vector(0,10,0))
373
        curve = result[0].Curve
374
        self.assertEqual(type(curve), Part.Circle)
375
        self.assertEqual(curve.Axis, pln.Axis)
376
        self.assertEqual(curve.Radius, 1.0)
377

378
    def testChFi2d_AnaFilletAlgo(self):
379
        v = FreeCAD.Vector
380
        edge1 = Part.makeLine(v(0,0,0), v(0,10,0))
381
        edge2 = Part.makeLine(v(0,10,0), v(10,10,0))
382
        wire = Part.Wire([edge1, edge2])
383
        pln = Part.Plane()
384

385
        with self.assertRaises(TypeError):
386
            alg = Part.ChFi2d.AnaFilletAlgo(pln)
387

388
        alg = Part.ChFi2d.AnaFilletAlgo()
389
        with self.assertRaises(TypeError):
390
            alg.init()
391

392
        print (alg)
393
        # Test without shape
394
        self.assertFalse(alg.perform(1))
395

396
        with self.assertRaises(TypeError):
397
            alg.perform()
398

399
        alg = Part.ChFi2d.AnaFilletAlgo(wire, pln)
400
        alg.init(edge1, edge2, pln)
401
        alg.init(wire, pln)
402

403
        alg = Part.ChFi2d.AnaFilletAlgo(edge1, edge2, pln)
404
        alg.perform(1.0)
405

406
        with self.assertRaises(TypeError):
407
            alg.result(1)
408

409
        result = alg.result()
410
        curve = result[0].Curve
411
        self.assertEqual(type(curve), Part.Circle)
412
        self.assertEqual(curve.Radius, 1.0)
413

414
    def testChFi2d_ChamferAPI(self):
415
        v = FreeCAD.Vector
416
        edge1 = Part.makeLine(v(0,0,0), v(0,10,0))
417
        edge2 = Part.makeLine(v(0,10,0), v(10,10,0))
418
        wire = Part.Wire([edge1, edge2])
419

420
        with self.assertRaises(TypeError):
421
            alg = Part.ChFi2d.ChamferAPI(edge1)
422

423
        alg = Part.ChFi2d.ChamferAPI(wire)
424
        with self.assertRaises(TypeError):
425
            alg.init()
426

427
        print (alg)
428

429
        with self.assertRaises(TypeError):
430
            alg.perform(1)
431

432
        alg = Part.ChFi2d.ChamferAPI(wire)
433
        alg.init(edge1, edge2)
434
        alg.init(wire)
435

436
        alg = Part.ChFi2d.ChamferAPI(edge1, edge2)
437
        alg.perform()
438

439
        with self.assertRaises(TypeError):
440
            alg.result(1)
441

442
        result = alg.result(1.0, 1.0)
443
        curve = result[0].Curve
444
        self.assertEqual(type(curve), Part.Line)
445

446
class PartTestRuledSurface(unittest.TestCase):
447
    def setUp(self):
448
        self.Doc = FreeCAD.newDocument()
449

450
    def testRuledSurfaceFromTwoObjects(self):
451
        line1 = Part.makeLine(FreeCAD.Vector(-70,-30,0), FreeCAD.Vector(-50,40,0))
452
        line2 = Part.makeLine(FreeCAD.Vector(-40,-30,0), FreeCAD.Vector(-40,10,0))
453
        plm1 = FreeCAD.Placement()
454
        plm1.Rotation = FreeCAD.Rotation(0.7071067811865476, 0.0, 0.0, 0.7071067811865475)
455
        line1.Placement = plm1
456
        fea1 = self.Doc.addObject("Part::Feature")
457
        fea2 = self.Doc.addObject("Part::Feature")
458
        fea1.Shape = line1
459
        fea2.Shape = line2
460
        ruled = self.Doc.addObject("Part::RuledSurface")
461
        ruled.Curve1 = fea1
462
        ruled.Curve2 = fea2
463

464
        self.Doc.recompute()
465

466
        same1 = getCoincidentVertexes(fea1.Shape.Vertexes, ruled.Shape.Vertexes)
467
        same2 = getCoincidentVertexes(fea2.Shape.Vertexes, ruled.Shape.Vertexes)
468
        self.assertEqual(len(same1), 2)
469
        self.assertEqual(len(same2), 2)
470

471
    def testRuledSurfaceFromTwoObjectsWithSharedVertexs(self):
472
        """Test reproducing issue #15539"""
473

474
        # Arrange
475
        line = Part.makeLine(FreeCAD.Vector(0, 0, 50), FreeCAD.Vector(0, -50, 0))
476
        line1 = Part.makeLine(FreeCAD.Vector(0, 0, 50), FreeCAD.Vector(50, 0, 0))
477
        line2 = Part.makeLine(FreeCAD.Vector(0, 0, 0), FreeCAD.Vector(0, -50, 0))
478
        line3 = Part.makeLine(FreeCAD.Vector(0, 0, 0), FreeCAD.Vector(50, 0, 0))
479
        fea = self.Doc.addObject("Part::Feature")
480
        fea1 = self.Doc.addObject("Part::Feature")
481
        fea2 = self.Doc.addObject("Part::Feature")
482
        fea3 = self.Doc.addObject("Part::Feature")
483
        fea.Shape = line
484
        fea1.Shape = line1
485
        fea2.Shape = line2
486
        fea3.Shape = line3
487

488
        # Defining all the surfaces generated by 2 lines with one common vertex
489
        ruled = self.Doc.addObject("Part::RuledSurface")
490
        ruled.Curve1 = fea
491
        ruled.Curve2 = fea1
492

493
        ruled1 = self.Doc.addObject("Part::RuledSurface")
494
        ruled1.Curve1 = fea1
495
        ruled1.Curve2 = fea3
496

497
        ruled2 = self.Doc.addObject("Part::RuledSurface")
498
        ruled2.Curve1 = fea2
499
        ruled2.Curve2 = fea3
500

501
        ruled3 = self.Doc.addObject("Part::RuledSurface")
502
        ruled3.Curve1 = fea
503
        ruled3.Curve2 = fea2
504

505
        # Act
506
        self.Doc.recompute()
507

508
        # Assert
509
        same00 = getCoincidentVertexes(fea.Shape.Vertexes, ruled.Shape.Vertexes)
510
        same03 = getCoincidentVertexes(fea.Shape.Vertexes, ruled3.Shape.Vertexes)
511
        same10 = getCoincidentVertexes(fea1.Shape.Vertexes, ruled.Shape.Vertexes)
512
        same11 = getCoincidentVertexes(fea1.Shape.Vertexes, ruled1.Shape.Vertexes)
513
        same22 = getCoincidentVertexes(fea2.Shape.Vertexes, ruled2.Shape.Vertexes)
514
        same23 = getCoincidentVertexes(fea2.Shape.Vertexes, ruled3.Shape.Vertexes)
515
        same31 = getCoincidentVertexes(fea3.Shape.Vertexes, ruled1.Shape.Vertexes)
516
        same32 = getCoincidentVertexes(fea3.Shape.Vertexes, ruled2.Shape.Vertexes)
517

518
        # BRepFill::Face() seems creating faces with 4 vertexes
519
        # Therefore, in this case, every face shares 3 vertexes (1 counted twice as coincident) with the lines that generate that face
520
        self.assertEqual(len(same00), 3)
521
        self.assertEqual(len(same03), 3)
522
        self.assertEqual(len(same10), 3)
523
        self.assertEqual(len(same11), 3)
524
        self.assertEqual(len(same22), 3)
525
        self.assertEqual(len(same23), 3)
526
        self.assertEqual(len(same31), 3)
527
        self.assertEqual(len(same32), 3)
528

529
    def testRuledSurfaceFromOneObject(self):
530
        sketch = self.Doc.addObject('Sketcher::SketchObject', 'Sketch')
531
        sketch.Placement = FreeCAD.Placement(FreeCAD.Vector(0.000000, 0.000000, 0.000000), App.Rotation(0.707107, 0.000000, 0.000000, 0.707107))
532
        sketch.MapMode = "Deactivated"
533

534
        sketch.addGeometry(Part.LineSegment(App.Vector(-43.475811,34.364464,0),App.Vector(-65.860519,-20.078733,0)),False)
535
        sketch.addGeometry(Part.LineSegment(App.Vector(14.004498,27.390331,0),App.Vector(33.577049,-27.952749,0)),False)
536

537
        ruled = self.Doc.addObject('Part::RuledSurface', 'Ruled Surface')
538
        ruled.Curve1 = (sketch,['Edge1'])
539
        ruled.Curve2 = (sketch,['Edge2'])
540
        self.Doc.recompute()
541

542
        same = getCoincidentVertexes(sketch.Shape.Vertexes, ruled.Shape.Vertexes)
543
        self.assertEqual(len(same), 4)
544

545
    def tearDown(self):
546
        FreeCAD.closeDocument(self.Doc.Name)
547

548
class PartTestShapeFix(unittest.TestCase):
549
    def testShapeFix_Root(self):
550
        with self.assertRaises(TypeError):
551
            Part.ShapeFix.Root([])
552

553
        fix = Part.ShapeFix.Root()
554
        print (fix)
555

556
        fix.Precision = 0.0
557
        self.assertEqual(fix.Precision, 0.0)
558

559
        fix.MinTolerance = 0.0
560
        self.assertEqual(fix.MinTolerance, 0.0)
561

562
        fix.MaxTolerance = 0.5
563
        self.assertEqual(fix.MaxTolerance, 0.5)
564

565
        self.assertEqual(fix.limitTolerance(0.25), 0.25)
566

567
    def testShapeFix_Shape(self):
568
        surface = Part.Plane()
569
        face = surface.toShape(-1, 1, -1, 1)
570

571
        with self.assertRaises(TypeError):
572
            Part.ShapeFix.Shape([])
573

574
        fix = Part.ShapeFix.Shape(face)
575
        fix.init(face)
576
        print (fix)
577
        fix.shape()
578
        fix.fixSolidTool()
579
        fix.fixShellTool()
580
        fix.fixFaceTool()
581
        fix.fixWireTool()
582
        fix.fixEdgeTool()
583

584
        fix.FixSolidMode = True
585
        self.assertEqual(fix.FixSolidMode, True)
586

587
        fix.FixFreeShellMode = True
588
        self.assertEqual(fix.FixFreeShellMode, True)
589

590
        fix.FixFreeFaceMode = True
591
        self.assertEqual(fix.FixFreeFaceMode, True)
592

593
        fix.FixFreeWireMode = True
594
        self.assertEqual(fix.FixFreeWireMode, True)
595

596
        fix.FixSameParameterMode = True
597
        self.assertEqual(fix.FixSameParameterMode, True)
598

599
        fix.FixVertexPositionMode = True
600
        self.assertEqual(fix.FixVertexPositionMode, True)
601

602
        fix.FixVertexTolMode = True
603
        self.assertEqual(fix.FixVertexTolMode, True)
604

605
        fix.perform()
606

607
    def testShapeFix_Edge(self):
608
        surface = Part.Plane()
609
        face = surface.toShape(-1, 1, -1, 1)
610

611
        with self.assertRaises(TypeError):
612
            Part.ShapeFix.Edge([])
613

614
        wirefix = Part.ShapeFix.Wire(face.OuterWire, face, 1e-7)
615
        fix = wirefix.fixEdgeTool()
616
        print (fix)
617

618
        fix.fixRemovePCurve(face.Edge1, face)
619
        fix.fixRemovePCurve(face.Edge1, face.Surface, face.Placement)
620
        with self.assertRaises(TypeError):
621
            fix.fixRemovePCurve(face)
622

623
        fix.fixRemoveCurve3d(face.Edge1)
624
        fix.fixAddCurve3d(face.Edge1)
625

626
        fix.fixAddPCurve(face.Edge1, face, False)
627
        fix.fixAddPCurve(face.Edge1, face.Surface, face.Placement, False)
628
        with self.assertRaises(TypeError):
629
            fix.fixAddPCurve(face)
630

631
        fix.fixVertexTolerance(face.Edge1)
632
        fix.fixVertexTolerance(face.Edge1, face)
633

634
        fix.fixReversed2d(face.Edge1, face)
635
        fix.fixReversed2d(face.Edge1, face.Surface, face.Placement)
636
        with self.assertRaises(TypeError):
637
            fix.fixReversed2d(face)
638

639
        fix.fixSameParameter(face.Edge1)
640
        fix.fixSameParameter(face.Edge1, face)
641
        with self.assertRaises(TypeError):
642
            fix.fixSameParameter(face)
643

644
    def testShapeFix_Face(self):
645
        surface = Part.Plane()
646
        face = surface.toShape(-1, 1, -1, 1)
647

648
        Part.ShapeFix.Face()
649
        Part.ShapeFix.Face(surface, 0.00001, True)
650
        with self.assertRaises(TypeError):
651
            Part.ShapeFix.Face([])
652

653
        fix = Part.ShapeFix.Face(face)
654
        print (fix)
655

656
        fix.fixOrientation()
657
        fix.fixAddNaturalBound()
658
        fix.fixMissingSeam()
659
        fix.fixSmallAreaWire(True)
660
        fix.fixLoopWire()
661
        fix.fixIntersectingWires()
662
        fix.fixWiresTwoCoincidentEdges()
663
        fix.fixPeriodicDegenerated()
664
        fix.perform()
665

666
        fix.add(face.OuterWire)
667
        current = fix.face()
668
        result = fix.result()
669
        fix.fixWireTool()
670

671
        fix.FixWireMode = True
672
        self.assertEqual(fix.FixWireMode, True)
673

674
        fix.FixOrientationMode = True
675
        self.assertEqual(fix.FixOrientationMode, True)
676

677
        fix.FixAddNaturalBoundMode = True
678
        self.assertEqual(fix.FixAddNaturalBoundMode, True)
679

680
        fix.FixMissingSeamMode = True
681
        self.assertEqual(fix.FixMissingSeamMode, True)
682

683
        fix.FixSmallAreaWireMode = True
684
        self.assertEqual(fix.FixSmallAreaWireMode, True)
685

686
        fix.RemoveSmallAreaFaceMode = True
687
        self.assertEqual(fix.RemoveSmallAreaFaceMode, True)
688

689
        fix.FixIntersectingWiresMode = True
690
        self.assertEqual(fix.FixIntersectingWiresMode, True)
691

692
        fix.FixLoopWiresMode = True
693
        self.assertEqual(fix.FixLoopWiresMode, True)
694

695
        fix.FixSplitFaceMode = True
696
        self.assertEqual(fix.FixSplitFaceMode, True)
697

698
        fix.AutoCorrectPrecisionMode = True
699
        self.assertEqual(fix.AutoCorrectPrecisionMode, True)
700

701
        fix.FixPeriodicDegeneratedMode = True
702
        self.assertEqual(fix.FixPeriodicDegeneratedMode, True)
703

704
        fix.clearModes()
705

706
    def testShapeFix_Shell(self):
707
        surface = Part.Plane()
708
        face = surface.toShape(-1, 1, -1, 1)
709
        shell = Part.Shell([face])
710

711
        Part.ShapeFix.Shell()
712
        with self.assertRaises(TypeError):
713
            Part.ShapeFix.Face([])
714

715
        fix = Part.ShapeFix.Shell(shell)
716
        fix.init(shell)
717
        print (fix)
718
        fix.perform()
719
        fix.shell()
720
        fix.shape()
721
        fix.fixFaceTool()
722

723
        fix.setNonManifoldFlag(True)
724
        fix.fixFaceOrientation(shell)
725

726
        self.assertEqual(len(fix.errorFaces().Faces), 0)
727

728
        self.assertEqual(fix.numberOfShells(), 1)
729

730
        fix.FixFaceMode = True
731
        self.assertEqual(fix.FixFaceMode, True)
732

733
        fix.FixOrientationMode = True
734
        self.assertEqual(fix.FixOrientationMode, True)
735

736
    def testShapeFix_Solid(self):
737
        box = Part.makeBox(1, 1, 1)
738
        with self.assertRaises(TypeError):
739
            Part.ShapeFix.Solid([])
740

741
        fix = Part.ShapeFix.Solid()
742
        fix.init(box)
743
        print (fix)
744

745
        fix.perform()
746
        fix.solid()
747
        fix.shape()
748
        fix.fixShellTool()
749
        fix.solidFromShell(box.Shells[0])
750

751
        fix.FixShellMode = True
752
        self.assertEqual(fix.FixShellMode, True)
753

754
        fix.FixShellOrientationMode = True
755
        self.assertEqual(fix.FixShellOrientationMode, True)
756

757
        fix.CreateOpenSolidMode = True
758
        self.assertEqual(fix.CreateOpenSolidMode, True)
759

760
    def testShapeFix_Wire(self):
761
        with self.assertRaises(TypeError):
762
            Part.ShapeFix.Wire([])
763

764
        surface = Part.Plane()
765
        face = surface.toShape(-1, 1, -1, 1)
766
        Part.ShapeFix.Wire(face.OuterWire, face, 1e-7)
767
        fix = Part.ShapeFix.Wire()
768
        fix.init(face.OuterWire, face, 1e-7)
769
        fix.load(face.OuterWire)
770
        fix.setSurface(surface)
771
        fix.setSurface(surface, face.Placement)
772
        fix.setFace(face)
773
        fix.setMaxTailAngle(math.pi)
774
        fix.setMaxTailWidth(10.0)
775
        fix.fixEdgeTool()
776

777
        self.assertEqual(fix.isLoaded(), True)
778
        self.assertEqual(fix.isReady(), True)
779
        self.assertEqual(fix.numberOfEdges(), 4)
780

781
        print (fix)
782
        fix.clearModes()
783
        fix.clearStatuses()
784

785
        fix.wire()
786
        fix.wireAPIMake()
787
        fix.face()
788

789
        fix.ModifyTopologyMode = True
790
        self.assertEqual(fix.ModifyTopologyMode, True)
791

792
        fix.ModifyGeometryMode = True
793
        self.assertEqual(fix.ModifyGeometryMode, True)
794

795
        fix.ModifyRemoveLoopMode = True
796
        self.assertEqual(fix.ModifyRemoveLoopMode, True)
797

798
        fix.ClosedWireMode = True
799
        self.assertEqual(fix.ClosedWireMode, True)
800

801
        fix.PreferencePCurveMode = True
802
        self.assertEqual(fix.PreferencePCurveMode, True)
803

804
        fix.FixGapsByRangesMode = True
805
        self.assertEqual(fix.FixGapsByRangesMode, True)
806

807
        fix.FixReorderMode = True
808
        self.assertEqual(fix.FixReorderMode, True)
809

810
        fix.FixSmallMode = True
811
        self.assertEqual(fix.FixSmallMode, True)
812

813
        fix.FixConnectedMode = True
814
        self.assertEqual(fix.FixConnectedMode, True)
815

816
        fix.FixEdgeCurvesMode = True
817
        self.assertEqual(fix.FixEdgeCurvesMode, True)
818

819
        fix.FixDegeneratedMode = True
820
        self.assertEqual(fix.FixDegeneratedMode, True)
821

822
        fix.FixSelfIntersectionMode = True
823
        self.assertEqual(fix.FixSelfIntersectionMode, True)
824

825
        fix.FixLackingMode = True
826
        self.assertEqual(fix.FixLackingMode, True)
827

828
        fix.FixGaps3dMode = True
829
        self.assertEqual(fix.FixGaps3dMode, True)
830

831
        fix.FixGaps2dMode = True
832
        self.assertEqual(fix.FixGaps2dMode, True)
833

834
        fix.FixReversed2dMode = True
835
        self.assertEqual(fix.FixReversed2dMode, True)
836

837
        fix.FixRemovePCurveMode = True
838
        self.assertEqual(fix.FixRemovePCurveMode, True)
839

840
        fix.FixAddPCurveMode = True
841
        self.assertEqual(fix.FixAddPCurveMode, True)
842

843
        fix.FixRemoveCurve3dMode = True
844
        self.assertEqual(fix.FixRemoveCurve3dMode, True)
845

846
        fix.FixAddCurve3dMode = True
847
        self.assertEqual(fix.FixAddCurve3dMode, True)
848

849
        fix.FixSeamMode = True
850
        self.assertEqual(fix.FixSeamMode, True)
851

852
        fix.FixShiftedMode = True
853
        self.assertEqual(fix.FixShiftedMode, True)
854

855
        fix.FixSameParameterMode = True
856
        self.assertEqual(fix.FixSameParameterMode, True)
857

858
        fix.FixVertexToleranceMode = True
859
        self.assertEqual(fix.FixVertexToleranceMode, True)
860

861
        fix.FixNotchedEdgesMode = True
862
        self.assertEqual(fix.FixNotchedEdgesMode, True)
863

864
        fix.FixSelfIntersectingEdgeMode = True
865
        self.assertEqual(fix.FixSelfIntersectingEdgeMode, True)
866

867
        fix.FixIntersectingEdgesMode = True
868
        self.assertEqual(fix.FixIntersectingEdgesMode, True)
869

870
        fix.FixNonAdjacentIntersectingEdgesMode = True
871
        self.assertEqual(fix.FixNonAdjacentIntersectingEdgesMode, True)
872

873
        fix.FixTailMode = True
874
        self.assertEqual(fix.FixTailMode, True)
875

876
        fix.perform()
877
        fix.fixReorder()
878
        fix.fixSmall(True)
879
        fix.fixSmall(1, True, 1e-7)
880
        fix.fixConnected()
881
        fix.fixConnected(1, True)
882
        fix.fixEdgeCurves()
883
        fix.fixDegenerated()
884
        fix.fixDegenerated(1)
885
        fix.fixSelfIntersection()
886
        fix.fixLacking()
887
        fix.fixLacking(1, False)
888
        fix.fixClosed()
889
        fix.fixGaps3d()
890
        fix.fixGaps2d()
891
        fix.fixSeam(1)
892
        fix.fixShifted()
893
        fix.fixNotchedEdges()
894
        fix.fixGap3d(1, False)
895
        fix.fixGap2d(1, False)
896
        fix.fixTails()
897

898
class PartBOPTestContainer(unittest.TestCase):
899
    def setUp(self):
900
        self.Doc = FreeCAD.newDocument()
901

902
    def testMakeFuse(self):
903
        box = self.Doc.addObject("Part::Box", "Box")
904
        cyl = self.Doc.addObject("Part::Cylinder", "Cylinder")
905
        part = self.Doc.addObject("App::Part", "Part")
906
        part.addObject(box)
907
        part.addObject(cyl)
908
        from BOPTools import BOPFeatures
909
        bp = BOPFeatures.BOPFeatures(self.Doc)
910
        fuse = bp.make_multi_fuse([cyl.Name, box.Name])
911
        self.assertEqual(part, fuse.getParent())
912

913
    def testMakeCut(self):
914
        box = self.Doc.addObject("Part::Box", "Box")
915
        cyl = self.Doc.addObject("Part::Cylinder", "Cylinder")
916
        part = self.Doc.addObject("App::Part", "Part")
917
        part.addObject(box)
918
        part.addObject(cyl)
919
        from BOPTools import BOPFeatures
920
        bp = BOPFeatures.BOPFeatures(self.Doc)
921
        fuse = bp.make_cut([cyl.Name, box.Name])
922
        self.assertEqual(part, fuse.getParent())
923

924
    def testMakeCommon(self):
925
        box = self.Doc.addObject("Part::Box", "Box")
926
        cyl = self.Doc.addObject("Part::Cylinder", "Cylinder")
927
        part = self.Doc.addObject("App::Part", "Part")
928
        part.addObject(box)
929
        part.addObject(cyl)
930
        from BOPTools import BOPFeatures
931
        bp = BOPFeatures.BOPFeatures(self.Doc)
932
        fuse = bp.make_multi_common([cyl.Name, box.Name])
933
        self.assertEqual(part, fuse.getParent())
934

935
    def tearDown(self):
936
        FreeCAD.closeDocument(self.Doc.Name)
937

938
class BSplineCurve2d(unittest.TestCase):
939
    def setUp(self):
940
        vec2 = FreeCAD.Base.Vector2d
941
        self.pts = [vec2(0, 0), vec2(1, 0)]
942
        self.bs = Part.Geom2d.BSplineCurve2d()
943

944
    def testInterpolate(self):
945
        self.bs.interpolate(Points=self.pts)
946

947
    def testApproximate(self):
948
        self.bs.approximate(Points=self.pts)
949

950
class GeometryCurve(unittest.TestCase):
951
    def testProject(self):
952
        line = Part.Line()
953
        line.projectPoint(FreeCAD.Vector())
954

955
class EmptyEdge(unittest.TestCase):
956
    def testParameterByLength(self):
957
        with self.assertRaises(ValueError):
958
            edge = Part.Edge()
959
            edge.getParameterByLength(0)
960

961
    def testValueAt(self):
962
        with self.assertRaises(ValueError):
963
            edge = Part.Edge()
964
            edge.valueAt(0)
965

966
    def testParameters(self):
967
        with self.assertRaises(ValueError):
968
            edge = Part.Edge()
969
            face = Part.Face()
970
            edge.parameters(face)
971

972
    def testParameterAt(self):
973
        with self.assertRaises(ValueError):
974
            edge = Part.Edge()
975
            vertex = Part.Vertex(0, 0, 0)
976
            edge.parameterAt(vertex)
977

978
    def testTangentAt(self):
979
        with self.assertRaises(ValueError):
980
            edge = Part.Edge()
981
            edge.tangentAt(0)
982

983
    def testCurvatureAt(self):
984
        with self.assertRaises(ValueError):
985
            edge = Part.Edge()
986
            edge.curvatureAt(0)
987

988
    def testCenterOfCurvatureAt(self):
989
        with self.assertRaises(ValueError):
990
            edge = Part.Edge()
991
            edge.centerOfCurvatureAt(0)
992

993
    def testDerivative1At(self):
994
        with self.assertRaises(ValueError):
995
            edge = Part.Edge()
996
            edge.derivative1At(0)
997

998
    def testDerivative2At(self):
999
        with self.assertRaises(ValueError):
1000
            edge = Part.Edge()
1001
            edge.derivative2At(0)
1002

1003
    def testDerivative3At(self):
1004
        with self.assertRaises(ValueError):
1005
            edge = Part.Edge()
1006
            edge.derivative3At(0)
1007

1008
    def testNormalAt(self):
1009
        with self.assertRaises(ValueError):
1010
            edge = Part.Edge()
1011
            edge.normalAt(0)
1012

1013
    def testFirstVertex(self):
1014
        with self.assertRaises(ValueError):
1015
            edge = Part.Edge()
1016
            edge.firstVertex()
1017

1018
    def testLastVertex(self):
1019
        with self.assertRaises(ValueError):
1020
            edge = Part.Edge()
1021
            edge.lastVertex()
1022

1023
    def testGetTolerance(self):
1024
        with self.assertRaises(ValueError):
1025
            edge = Part.Edge()
1026
            edge.Tolerance
1027

1028
    def testSetTolerance(self):
1029
        with self.assertRaises(ValueError):
1030
            edge = Part.Edge()
1031
            edge.Tolerance = 0.01
1032

1033
    def testLength(self):
1034
        with self.assertRaises(ValueError):
1035
            edge = Part.Edge()
1036
            edge.Length
1037

1038
    def testCurve(self):
1039
        with self.assertRaises(ValueError):
1040
            edge = Part.Edge()
1041
            edge.Curve
1042

1043
    def testParameterRange(self):
1044
        with self.assertRaises(ValueError):
1045
            edge = Part.Edge()
1046
            edge.ParameterRange
1047

1048
    def testFirstParameter(self):
1049
        with self.assertRaises(ValueError):
1050
            edge = Part.Edge()
1051
            edge.FirstParameter
1052

1053
    def testLastParameter(self):
1054
        with self.assertRaises(ValueError):
1055
            edge = Part.Edge()
1056
            edge.LastParameter
1057

1058
class EmptyFace(unittest.TestCase):
1059
    def testMakeOffset(self):
1060
        with self.assertRaises(ValueError):
1061
            face = Part.Face()
1062
            face.makeOffset(1)
1063

1064
    def testValueAt(self):
1065
        with self.assertRaises(ValueError):
1066
            face = Part.Face()
1067
            face.valueAt(0, 0)
1068

1069
    def testNormalAt(self):
1070
        with self.assertRaises(ValueError):
1071
            face = Part.Face()
1072
            face.normalAt(0, 0)
1073

1074
    def testTangentAt(self):
1075
        with self.assertRaises(ValueError):
1076
            face = Part.Face()
1077
            face.tangentAt(0, 0)
1078

1079
    def testCurvatureAt(self):
1080
        with self.assertRaises(ValueError):
1081
            face = Part.Face()
1082
            face.curvatureAt(0, 0)
1083

1084
    def testDerivative1At(self):
1085
        with self.assertRaises(ValueError):
1086
            face = Part.Face()
1087
            face.derivative1At(0, 0)
1088

1089
    def testDerivative2At(self):
1090
        with self.assertRaises(ValueError):
1091
            face = Part.Face()
1092
            face.derivative2At(0, 0)
1093

1094
    def testCutHoles(self):
1095
        with self.assertRaises(ValueError):
1096
            face = Part.Face()
1097
            circle = Part.Circle()
1098
            wire = Part.Wire(Part.Edge(circle))
1099
            face.cutHoles([wire])
1100

1101
    def testUVNodes(self):
1102
        with self.assertRaises(ValueError):
1103
            face = Part.Face()
1104
            face.getUVNodes()
1105

1106
    def testGetTolerance(self):
1107
        with self.assertRaises(ValueError):
1108
            face = Part.Face()
1109
            face.Tolerance
1110

1111
    def testSetTolerance(self):
1112
        with self.assertRaises(ValueError):
1113
            face = Part.Face()
1114
            face.Tolerance = 0.01
1115

1116
    def testParameterRange(self):
1117
        with self.assertRaises(ValueError):
1118
            face = Part.Face()
1119
            face.ParameterRange
1120

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.