def from_hatch(hatch: Hatch) -> Iterable[Path]: """ Yield all HATCH boundary paths as separated :class:`Path` objects. .. versionadded:: 0.16 """ ocs = hatch.ocs() elevation = hatch.dxf.elevation.z for boundary in hatch.paths: yield from_hatch_boundary_path(boundary, ocs, elevation)
def _hatch_as_polygon(hatch: Hatch, distance: float, force_line_string: bool) -> Dict: def boundary_to_vertices(boundary) -> List[Vector]: path = Path.from_hatch_boundary_path(boundary, ocs, elevation) return path_to_vertices(path) def path_to_vertices(path) -> List[Vector]: path.close() return list(path.flattening(distance)) # Path vertex winding order can be ignored here, validation and # correction is done in polygon_mapping(). elevation = hatch.dxf.elevation.z ocs = hatch.ocs() hatch_style = hatch.dxf.hatch_style # Returns boundaries in EXTERNAL, OUTERMOST and DEFAULT order and filters # unused boundaries according the hatch style: boundaries = list(hatch.paths.rendering_paths(hatch_style)) count = len(boundaries) if count == 0: raise ValueError('HATCH without any boundary path.') # Take first path as exterior path, multiple EXTERNAL paths are possible exterior = boundaries[0] if count == 1 or hatch_style == const.HATCH_STYLE_IGNORE: points = boundary_to_vertices(exterior) return _line_string_or_polygon_mapping(points, force_line_string) else: if force_line_string: # Build a MultiString collection: points = boundary_to_vertices(exterior) geometries = [ _line_string_or_polygon_mapping(points, force_line_string) ] # All other boundary paths are treated as holes for hole in boundaries[1:]: points = boundary_to_vertices(hole) geometries.append( _line_string_or_polygon_mapping(points, force_line_string)) return join_multi_single_type_mappings(geometries) else: # Multiple separated polygons are possible in one HATCH entity: polygons = [] for exterior, holes in _boundaries_to_polygons( boundaries, ocs, elevation): points = path_to_vertices(exterior) polygons.append( polygon_mapping(points, [path_to_vertices(hole) for hole in holes])) if len(polygons) > 1: return join_multi_single_type_mappings(polygons) return polygons[0]
def _from_hatch(hatch: Hatch, **kwargs) -> Path: ocs = hatch.ocs() elevation = hatch.dxf.elevation.z offset = NULLVEC if isinstance(hatch, MPolygon): offset = hatch.dxf.get("offset_vector", NULLVEC) paths = [ from_hatch_boundary_path(boundary, ocs, elevation, offset=offset) for boundary in hatch.paths ] # looses the boundary path state: return tools.to_multi_path(paths)
def from_hatch(hatch: Hatch) -> Iterable[Path]: """Yield all HATCH boundary paths as separated :class:`Path` objects. .. versionadded:: 0.16 .. versionchanged:: 17.1 Attaches the boundary state to each path as :class:`ezdxf.lldxf.const.BoundaryPathState`. """ ocs = hatch.ocs() elevation = hatch.dxf.elevation.z for boundary in hatch.paths: p = from_hatch_boundary_path(boundary, ocs, elevation) if p.has_sub_paths: yield from p.sub_paths() else: yield p