Ejemplo n.º 1
0
def multi_recursive(entities: Iterable['DXFEntity'],
                    cache: Cache = None) -> Iterable[BoundingBox]:
    """ Yields all bounding boxes for the given `entities` **or** all bounding
    boxes for their sub entities. If an entity (INSERT) has sub entities, only
    the bounding boxes of these sub entities will be yielded, **not** the
    bounding box of entity (INSERT) itself.

    """
    flat_entities = disassemble.recursive_decompose(entities)
    primitives = disassemble.to_primitives(flat_entities)
    for primitive in primitives:
        if primitive.is_empty:
            continue

        entity = primitive.entity
        if cache is not None:
            box = cache.get(entity)
            if box is None:
                box = BoundingBox(primitive.vertices())
                if box.has_data:
                    cache.store(entity, box)
        else:
            box = BoundingBox(primitive.vertices())

        if box.has_data:
            yield box
Ejemplo n.º 2
0
def test_hatch_returns_multiple_primitives():
    hatch = factory.new('HATCH')
    paths = hatch.paths

    # Conversion of boundary paths is tested in 708.
    paths.add_polyline_path([(0, 0), (1, 0), (1, 1)])
    paths.add_polyline_path([(0, 2), (1, 2), (1, 3), (0, 3)])
    res = list(disassemble.to_primitives([hatch]))
    assert len(res) == 2
    assert len(list(res[0].vertices())) == 4, "expected closed triangle"
    assert len(list(res[1].vertices())) == 5, "expected closed box"
Ejemplo n.º 3
0
def test_hatch_returns_multiple_primitives():
    hatch = factory.new("HATCH")
    paths = hatch.paths

    # Conversion of boundary paths is tested in 708.
    paths.add_polyline_path([(0, 0), (1, 0), (1, 1)])
    paths.add_polyline_path([(0, 2), (1, 2), (1, 3), (0, 3)])
    res = list(disassemble.to_primitives([hatch]))
    assert len(res) == 1
    p = res[0]
    assert p.path is not None
    assert p.path.has_sub_paths is True
    p0, p1 = p.path.sub_paths()
    v0 = list(p0.approximate())
    v1 = list(p1.approximate())
    assert len(v0) == 4, "expected closed triangle"
    assert len(v1) == 5, "expected closed box"
Ejemplo n.º 4
0
    def save(self, filename: str) -> None:
        # Convert entities to primitives
        primitives = disassemble.to_primitives(self.msp)

        # Collect paths from primitives:
        paths = [p.path for p in primitives if p.path]

        # Render this paths as HATCH entities
        path.render_hatches(self.msp,
                            paths,
                            dxfattribs={
                                "layer": "HATCHES",
                                "color": 2
                            })

        self.doc.set_modelspace_vport(15, (4, 4))
        self.doc.saveas(DIR / f"{filename}.dxf")
Ejemplo n.º 5
0
def multi_recursive(
    entities: Iterable["DXFEntity"],
    *,
    flatten: float = MAX_FLATTENING_DISTANCE,
    cache: Cache = None,
) -> Iterable[BoundingBox]:
    """Yields all bounding boxes for the given `entities` **or** all bounding
    boxes for their sub entities. If an entity (INSERT) has sub entities, only
    the bounding boxes of these sub entities will be yielded, **not** the
    bounding box of entity (INSERT) itself.

    Calculate bounding boxes from flattened curves, if argument `flatten`
    is not 0 (max flattening distance), else from control points.

    """

    def vertices(p: disassemble.Primitive) -> Iterable[Vec3]:
        if flatten:
            primitive.max_flattening_distance = abs(flatten)
            return primitive.vertices()
        else:
            return disassemble.to_control_vertices([p])

    flat_entities = disassemble.recursive_decompose(entities)
    primitives = disassemble.to_primitives(flat_entities)
    for primitive in primitives:
        if primitive.is_empty:
            continue

        entity = primitive.entity
        if cache is not None:
            box = cache.get(entity)
            if box is None:
                box = BoundingBox(vertices(primitive))
                if box.has_data:
                    cache.store(entity, box)
        else:
            box = BoundingBox(vertices(primitive))

        if box.has_data:
            yield box
Ejemplo n.º 6
0
def multi_recursive(entities: Iterable['DXFEntity'],
                    *,
                    flatten: bool = True,
                    cache: Cache = None) -> Iterable[BoundingBox]:
    """ Yields all bounding boxes for the given `entities` **or** all bounding
    boxes for their sub entities. If an entity (INSERT) has sub entities, only
    the bounding boxes of these sub entities will be yielded, **not** the
    bounding box of entity (INSERT) itself.

    Calculate bounding boxes from flattened curves, if argument `flatten` is
    ``True``, else from control points.

    """
    def vertices(p: disassemble.Primitive) -> Iterable[Vec3]:
        if not flatten:
            return disassemble.to_control_vertices([p])
        return primitive.vertices()

    flat_entities = disassemble.recursive_decompose(entities)
    primitives = disassemble.to_primitives(flat_entities)
    for primitive in primitives:
        if primitive.is_empty:
            continue

        entity = primitive.entity
        if cache is not None:
            box = cache.get(entity)
            if box is None:
                box = BoundingBox(vertices(primitive))
                if box.has_data:
                    cache.store(entity, box)
        else:
            box = BoundingBox(vertices(primitive))

        if box.has_data:
            yield box
Ejemplo n.º 7
0
doc.layers.new("FORMS", dxfattribs={"color": 1})
doc.layers.new("HATCHES")

msp = doc.modelspace()
attribs = {"layer": "FORMS"}

# Create DXF primitives:
msp.add_circle((2, 3), radius=2, dxfattribs=attribs)

# Ellipse with hole:
msp.add_ellipse((5, 0), major_axis=(3, 1), ratio=0.5, dxfattribs=attribs)
msp.add_circle((5, 0), radius=1.5, dxfattribs=attribs)

# Rectangle with a hole
rect = translate(box(3, 2), (3, 6))
msp.add_lwpolyline(rect, close=True, dxfattribs=attribs)
hole = translate(box(2, 1), (3.4, 6.4))
msp.add_lwpolyline(hole, close=True, dxfattribs=attribs)

# Convert entities to primitives
primitives = disassemble.to_primitives(msp)

# Collect paths from primitives:
paths = [p.path for p in primitives if p.path]

# Render this paths as HATCH entities
path.render_hatches(msp, paths, dxfattribs={"layer": "HATCHES", "color": 2})

doc.set_modelspace_vport(15, (4, 4))
doc.saveas(DIR / "hatches_from_entities.dxf")
Ejemplo n.º 8
0
def test_do_nothing():
    assert list(disassemble.recursive_decompose([])) == []
    assert list(disassemble.to_primitives([])) == []
    assert list(disassemble.to_vertices([])) == []
Ejemplo n.º 9
0
def test_multiple_unsupported_entities_to_vertices():
    w = factory.new("3DSOLID")
    primitives = list(disassemble.to_primitives([w, w, w]))
    assert len(primitives) == 3, "3 empty primitives expected"
    vertices = list(disassemble.to_vertices(primitives))
    assert len(vertices) == 0, "no vertices expected"
Ejemplo n.º 10
0
# License: MIT License

import pathlib
import ezdxf
from ezdxf import disassemble, zoom
from ezdxf.tools import fonts

DIR = pathlib.Path('~/Desktop/Outbox').expanduser()
fonts.load()

FILES = [
    'text_fonts.dxf',
    'text_oblique_rotate.dxf',
    'text_mirror_true_type_font.dxf',
    'text_stacked_shx_font.dxf',
]
for filename in FILES:
    print(f"Processing: {filename}")
    doc = ezdxf.readfile(
        pathlib.Path(__file__).parent.parent / 'examples_dxf' / filename)
    msp = doc.modelspace()

    # required to switch layer on/off
    doc.layers.new('TEXT_FRAME', dxfattribs={'color': 6})
    for frame in disassemble.to_primitives(msp.query('TEXT')):
        msp.add_lwpolyline(frame.vertices(), close=True,
                           dxfattribs={'layer': 'TEXT_FRAME'})

    zoom.extents(msp, factor=1.1)
    doc.saveas(DIR / filename)
Ejemplo n.º 11
0
FILE1 = "text_mirror_true_type_font.dxf"
FILE2 = "text_oblique_rotate.dxf"

FILE = FILE2
doc = ezdxf.readfile(EXAMPLES / FILE)
doc.layers.new('OUTLINE', dxfattribs={'color': 1})
doc.layers.new('BBOX', dxfattribs={'color': 5})
msp = doc.modelspace()
text_entities = msp.query('TEXT')

# Convert TEXT entities into SPLINE and POLYLINE entities:
kind = text2path.Kind.SPLINES
for text in text_entities:
    for e in text2path.virtual_entities(text, kind=kind):
        e.dxf.layer = 'OUTLINE'
        e.dxf.color = const.BYLAYER
        msp.add_entity(e)

# Add bounding boxes
attrib = {'layer': 'BBOX'}
boxes = []

# The "primitive" representation for TEXT entities is the bounding box:
for prim in disassemble.to_primitives(text_entities):
    p = msp.add_lwpolyline(prim.vertices(), dxfattribs=attrib)
    boxes.append(p)

# Zoom on bounding boxes (fast):
zoom.objects(msp, boxes,factor=1.1)
doc.saveas(OUTBOX / FILE)
Ejemplo n.º 12
0
import pathlib
import ezdxf
from ezdxf import disassemble, zoom
from ezdxf.tools import fonts

DIR = pathlib.Path("~/Desktop/Outbox").expanduser()
fonts.load()

FILES = [
    "text_fonts.dxf",
    "text_oblique_rotate.dxf",
    "text_mirror_true_type_font.dxf",
    "text_stacked_shx_font.dxf",
]
for filename in FILES:
    print(f"Processing: {filename}")
    doc = ezdxf.readfile(
        pathlib.Path(__file__).parent.parent / "examples_dxf" / filename
    )
    msp = doc.modelspace()

    # required to switch layer on/off
    doc.layers.add("TEXT_FRAME", color=6)
    for frame in disassemble.to_primitives(msp.query("TEXT")):
        msp.add_lwpolyline(
            frame.vertices(), close=True, dxfattribs={"layer": "TEXT_FRAME"}
        )

    zoom.extents(msp, factor=1.1)
    doc.saveas(DIR / filename)