1# Copyright (c) 2020, Manfred Moitzi 2# License: MIT License 3 4import pytest 5from ezdxf.render.forms import square, translate 6from ezdxf.path import Path, nesting, from_vertices 7 8EXTERIOR = list(translate(square(10), (-5, -5))) 9EXT1_PATH = from_vertices(EXTERIOR) 10EXT2_PATH = from_vertices(translate(EXTERIOR, (11, 0))) 11 12CENTER_HOLE1 = list(translate(square(8), (-4, -4))) 13CH1_PATH = from_vertices(CENTER_HOLE1) 14 15CENTER_HOLE2 = list(translate(square(6), (-3, -3))) 16CH2_PATH = from_vertices(CENTER_HOLE2) 17 18LEFT_HOLE = list(translate(square(2.1), (-3, -1))) 19LH_PATH = from_vertices(LEFT_HOLE) 20 21RIGHT_HOLE = list(translate(square(2.0), (3, -1))) 22RH_PATH = from_vertices(RIGHT_HOLE) 23 24DETECTION_DATA = [ 25 pytest.param( 26 # Each polygon is a list of paths 27 [EXT1_PATH], [[EXT1_PATH]], 28 id='1 path'), 29 pytest.param( 30 # returns the path sorted by area, and reversed if equal sized 31 [EXT1_PATH, EXT2_PATH], [[EXT2_PATH], [EXT1_PATH]], 32 id='2 separated paths'), 33 pytest.param( 34 [CH1_PATH, EXT1_PATH], [[EXT1_PATH, [CH1_PATH]]], 35 id='1 nested sub-path'), 36 pytest.param( 37 [CH1_PATH, EXT1_PATH, CH2_PATH], [[EXT1_PATH, [CH1_PATH, [CH2_PATH]]]], 38 id='2 nested sub-path'), 39 pytest.param( 40 [RH_PATH, LH_PATH, EXT1_PATH], [[EXT1_PATH, [LH_PATH], [RH_PATH]]], 41 id='2 separated sub-paths'), 42] 43 44 45@pytest.mark.parametrize('paths,polygons', DETECTION_DATA) 46def test_fast_bbox_detection(paths, polygons): 47 assert nesting.fast_bbox_detection(paths) == polygons 48 49 50@pytest.mark.parametrize('polygons,exp_ccw,exp_cw', [ 51 pytest.param( 52 [[EXT1_PATH]], 53 [EXT1_PATH], # ccw paths 54 [], # cw paths 55 id='1 polygon'), 56 pytest.param( 57 [[EXT1_PATH], [EXT1_PATH]], 58 [EXT1_PATH, EXT1_PATH], # ccw paths 59 [], # cw paths 60 id='2 polygons'), 61 pytest.param( 62 [[EXT1_PATH, [CH1_PATH]]], 63 [EXT1_PATH], # ccw paths 64 [CH1_PATH], # cw paths 65 id='1 polygon 1 nested sub-polygon'), 66 pytest.param( 67 [[EXT1_PATH, [CH1_PATH, [CH1_PATH]]]], 68 [EXT1_PATH, CH1_PATH], # ccw paths 69 [CH1_PATH], # cw paths 70 id='1 polygon 2 nested sub-polygons' 71 ), 72 pytest.param( 73 [[EXT1_PATH, [CH1_PATH], [CH1_PATH]]], 74 [EXT1_PATH], # ccw paths 75 [CH1_PATH, CH1_PATH], # cw paths 76 id='1 polygon 2 separated sub-polygons' 77 ), 78]) 79def test_winding_deconstruction(polygons, exp_ccw, exp_cw): 80 ccw, cw = nesting.winding_deconstruction(polygons) 81 assert ccw == exp_ccw 82 assert cw == exp_cw 83 84 85@pytest.mark.parametrize('polygons,n', [ 86 pytest.param( 87 [[EXT1_PATH]], 1, 88 id='1 polygon'), 89 pytest.param( 90 [[EXT1_PATH], [EXT1_PATH]], 2, 91 id='2 polygons'), 92 pytest.param( 93 [[EXT1_PATH, [CH1_PATH]]], 2, 94 id='1 polygon 1 nested sub-polygon'), 95 pytest.param( 96 [[EXT1_PATH, [CH1_PATH, [CH1_PATH]]]], 3, 97 id='1 polygon 2 nested sub-polygons' 98 ), 99 pytest.param( 100 [[EXT1_PATH, [CH1_PATH], [CH1_PATH]]], 3, 101 id='1 polygon 2 separated sub-polygons' 102 ), 103 pytest.param( 104 [[EXT1_PATH, [CH1_PATH, [CH2_PATH]], [CH1_PATH, [CH2_PATH]]]], 5, 105 id='1 polygon 2 separated nested sub-polygons' 106 ), 107]) 108def test_flatten_polygons(polygons, n): 109 nlists = 0 110 npaths = 0 111 for path in list(nesting.flatten_polygons(polygons)): 112 if isinstance(path, Path): 113 npaths += 1 114 elif isinstance(path, list): 115 nlists += 1 116 else: 117 raise TypeError('?') 118 119 assert nlists == 0 120 assert npaths == n 121 122 123if __name__ == '__main__': 124 pytest.main([__file__]) 125