@@ -53,6 +53,7 @@ def test_sphere(self):
5353 self .assertAlmostEqual (mesh .volume , 4 / 3 * math .pi , places = int (math .log10 (segments )))
5454 self .assertEqual (Model .sphere (0 ).name , '!sphere-4' )
5555 self .assertEqual (Model .sphere (5 ).name , '!sphere-8' )
56+ self .assertIs (Model .sphere (), Model .sphere (DefaultSegments ))
5657
5758 def test_cylinder (self ):
5859 for segments in (4 , DefaultSegments , 1024 ):
@@ -70,6 +71,8 @@ def test_cylinder(self):
7071 else :
7172 self .assertAlmostEqual (mesh .area , 4 * math .pi , places = int (math .log10 (segments )))
7273 self .assertAlmostEqual (mesh .volume , math .pi , places = int (math .log10 (segments )))
74+ self .assertEqual (Model .cylinder (0 ).name , '!cylinder-2' )
75+ self .assertIs (Model .cylinder (), Model .cylinder (DefaultSegments ))
7376
7477 def test_cone (self ):
7578 for segments in (4 , DefaultSegments , 1024 ):
@@ -87,6 +90,8 @@ def test_cone(self):
8790 else :
8891 self .assertAlmostEqual (mesh .area , (1 + math .sqrt (2 ))* math .pi , places = int (math .log10 (segments )))
8992 self .assertAlmostEqual (mesh .volume , math .pi / 3 , places = int (math .log10 (segments )))
93+ self .assertEqual (Model .cone (0 ).name , '!cone-2' )
94+ self .assertIs (Model .cone (), Model .cone (DefaultSegments ))
9095
9196
9297class TestBasicFunctionality (utils .TestCase ):
@@ -470,7 +475,7 @@ def test_difference(self):
470475 self .assertEqual (Model .difference (Model .box (), Model .sphere ()).trim (self .P , self .N ).name , f'difference(trim(!box, { self .PN_hash } ), !sphere)' )
471476
472477
473- class TestUVRemapping (utils .TestCase ):
478+ class TestUnaryOperations (utils .TestCase ):
474479 def tearDown (self ):
475480 Model .flush_caches (0 , 0 )
476481
@@ -483,6 +488,22 @@ def test_uv_remap_sphere(self):
483488 v = (math .atan2 (z , r ) / math .pi + 0.5 ) % 1
484489 self .assertAllAlmostEqual (uv , [u , v ])
485490
491+ def test_flatten (self ):
492+ model = Model .sphere ()
493+ nrows = DefaultSegments // 4
494+ mesh = model .get_trimesh ()
495+ self .assertEqual (len (mesh .vertices ), 4 * (nrows + 1 )* (nrows + 2 ))
496+ self .assertEqual (len (mesh .faces ), 8 * nrows * nrows )
497+ self .assertAlmostEqual (mesh .area , 4 * math .pi , places = 1 )
498+ self .assertAlmostEqual (mesh .volume , 4 / 3 * math .pi , places = 1 )
499+ flat_model = model .flatten ()
500+ self .assertIsNot (flat_model , model )
501+ mesh = flat_model .get_trimesh ()
502+ self .assertEqual (len (mesh .vertices ), 3 * 8 * nrows * nrows )
503+ self .assertEqual (len (mesh .faces ), 8 * nrows * nrows )
504+ self .assertAlmostEqual (mesh .area , 4 * math .pi , places = 1 )
505+ self .assertAlmostEqual (mesh .volume , 4 / 3 * math .pi , places = 1 )
506+
486507
487508class TestTrim (utils .TestCase ):
488509 def tearDown (self ):
@@ -621,6 +642,35 @@ def wrap_name(self, name):
621642 return f'sdf({ name } , -3;-3;-3, 3;3;3, 0.1)'
622643
623644
645+ class TestSdfTrim (utils .TestCase ):
646+ def tearDown (self ):
647+ Model .flush_caches (0 , 0 )
648+
649+ def test_trim_sphere_to_box (self ):
650+ model = Model .sphere ()
651+ for x in (- 1 , 1 ):
652+ model = model .trim ((x / 2 , 0 , 0 ), (x , 0 , 0 ))
653+ for y in (- 1 , 1 ):
654+ model = model .trim ((0 , y / 2 , 0 ), (0 , y , 0 ))
655+ for z in (- 1 , 1 ):
656+ model = model .trim ((0 , 0 , z / 2 ), (0 , 0 , z ))
657+ model = Model .sdf (None , model , (- 1 , - 1 , - 1 ), (1 , 1 , 1 ), 0.05 )
658+ mesh = model .get_trimesh ()
659+ self .assertEqual (mesh .bounds .tolist (), [[- 0.5 , - 0.5 , - 0.5 ], [0.5 , 0.5 , 0.5 ]])
660+ self .assertAlmostEqual (mesh .area , 6 )
661+ self .assertAlmostEqual (mesh .volume , 1 )
662+
663+ def test_trim_to_nothing (self ):
664+ model = Model .box ()
665+ model = model .trim ((0 , 0 , - 1 ), (0 , 0 , 1 ))
666+ model = Model .sdf (None , model , (- 1 , - 1 , - 1 ), (1 , 1 , 1 ), 0.05 )
667+ with unittest .mock .patch ('flitter.render.window.models.logger' ) as mock_logger :
668+ manifold = model .get_manifold ()
669+ mock_logger .warning .assert_called_with ("Result of operation was empty mesh: {}" , model .name )
670+ self .assertIsNone (manifold )
671+ self .assertIsNone (model .get_trimesh ())
672+
673+
624674class TestBuffers (utils .TestCase ):
625675 def tearDown (self ):
626676 Model .flush_caches (0 , 0 )
0 commit comments