11# Copyright (c) 2021, Manfred Moitzi
22# License: MIT License
33from typing import TYPE_CHECKING , Iterable , Dict , Optional
4+ import warnings
5+
6+ import ezdxf
47from ezdxf import disassemble
5- from ezdxf .math import BoundingBox , Vec3
8+ from ezdxf .math import BoundingBox
69
710if TYPE_CHECKING :
811 from ezdxf .eztypes import DXFEntity
@@ -82,29 +85,38 @@ def _get_key(self, entity: "DXFEntity") -> Optional[str]:
8285 return key
8386
8487
88+ def _resolve_fast_arg (fast : bool , kwargs ) -> bool :
89+ if "flatten" in kwargs :
90+ warnings .warn (
91+ "Argument 'flatten' replaced by argument 'fast', "
92+ "'flatten' will be removed in v1.0!" ,
93+ DeprecationWarning ,
94+ )
95+ fast = not bool (kwargs ["flatten" ])
96+ return fast
97+
98+
8599def multi_recursive (
86100 entities : Iterable ["DXFEntity" ],
87101 * ,
88- flatten : float = MAX_FLATTENING_DISTANCE ,
102+ fast = False ,
89103 cache : Cache = None ,
104+ ** kwargs ,
90105) -> Iterable [BoundingBox ]:
91106 """Yields all bounding boxes for the given `entities` **or** all bounding
92107 boxes for their sub entities. If an entity (INSERT) has sub entities, only
93108 the bounding boxes of these sub entities will be yielded, **not** the
94109 bounding box of entity (INSERT) itself.
95110
96- Calculate bounding boxes from flattened curves, if argument `flatten`
97- is not 0 (max flattening distance), else from control points .
111+ If argument `fast` is ``True`` the calculation of Bézier curves is based on
112+ their control points, this may return a slightly larger bounding box .
98113
99- """
114+ .. versionchanged:: 0.18
100115
101- def vertices (p : disassemble .Primitive ) -> Iterable [Vec3 ]:
102- if flatten :
103- primitive .max_flattening_distance = abs (flatten )
104- return primitive .vertices ()
105- else :
106- return disassemble .to_control_vertices ([p ])
116+ replaced argument `flatten` by argument `fast`
107117
118+ """
119+ fast = _resolve_fast_arg (fast , kwargs )
108120 flat_entities = disassemble .recursive_decompose (entities )
109121 primitives = disassemble .to_primitives (flat_entities )
110122 for primitive in primitives :
@@ -115,11 +127,11 @@ def vertices(p: disassemble.Primitive) -> Iterable[Vec3]:
115127 if cache is not None :
116128 box = cache .get (entity )
117129 if box is None :
118- box = BoundingBox ( vertices ( primitive ) )
130+ box = primitive . bbox ( fast = fast )
119131 if box .has_data :
120132 cache .store (entity , box )
121133 else :
122- box = BoundingBox ( vertices ( primitive ) )
134+ box = primitive . bbox ( fast = fast )
123135
124136 if box .has_data :
125137 yield box
@@ -128,37 +140,63 @@ def vertices(p: disassemble.Primitive) -> Iterable[Vec3]:
128140def extents (
129141 entities : Iterable ["DXFEntity" ],
130142 * ,
131- flatten : float = MAX_FLATTENING_DISTANCE ,
143+ fast = False ,
132144 cache : Cache = None ,
145+ ** kwargs ,
133146) -> BoundingBox :
134147 """Returns a single bounding box for all given `entities`.
135148
136- Calculate bounding boxes from flattened curves, if argument `flatten`
137- is not 0 (max flattening distance), else from control points.
149+ If argument `fast` is ``True`` the calculation of Bézier curves is based on
150+ their control points, this may return a slightly larger bounding box.
151+ The `fast` mode uses also a simpler and mostly inaccurate text size
152+ calculation instead of the more precise but very slow calculation by
153+ `matplotlib`.
154+
155+ .. hint::
156+
157+ The fast mode is not much faster for non-text based entities, so using
158+ the slower default mode is not a big disadvantage if a more precise text
159+ size calculation is important.
160+
161+ .. versionchanged:: 0.18
162+
163+ added fast mode, replaced argument `flatten` by argument `fast`
138164
139165 """
166+ fast = _resolve_fast_arg (fast , kwargs )
167+ use_matplotlib = ezdxf .options .use_matplotlib # save current state
168+ if fast :
169+ ezdxf .options .use_matplotlib = False
140170 _extends = BoundingBox ()
141- for box in multi_flat (entities , flatten = flatten , cache = cache ):
171+ for box in multi_flat (entities , fast = fast , cache = cache ):
142172 _extends .extend (box )
173+ ezdxf .options .use_matplotlib = use_matplotlib # restore state
143174 return _extends
144175
145176
146177def multi_flat (
147178 entities : Iterable ["DXFEntity" ],
148179 * ,
149- flatten : float = MAX_FLATTENING_DISTANCE ,
180+ fast = False ,
150181 cache : Cache = None ,
182+ ** kwargs ,
151183) -> Iterable [BoundingBox ]:
152184 """Yields a bounding box for each of the given `entities`.
153185
154- Calculate bounding boxes from flattened curves, if argument `flatten`
155- is not 0 (max flattening distance), else from control points.
186+ If argument `fast` is ``True`` the calculation of Bézier curves is based on
187+ their control points, this may return a slightly larger bounding box.
188+
189+ .. versionchanged:: 0.18
190+
191+ replaced argument `flatten` by argument `fast`
156192
157193 """
158194
159195 def extends_ (entities_ : Iterable ["DXFEntity" ]) -> BoundingBox :
160196 _extends = BoundingBox ()
161- for _box in multi_recursive (entities_ , flatten = flatten , cache = cache ):
197+ for _box in multi_recursive (
198+ entities_ , fast = _resolve_fast_arg (fast , kwargs ), cache = cache
199+ ):
162200 _extends .extend (_box )
163201 return _extends
164202
0 commit comments