def test_decompose_block_reference_level_1(doc, sx, sy, sz):
    msp = doc.modelspace()
    msp.delete_all_entities()
    msp.add_blockref("L1", (0, 0), dxfattribs=scale(sx, sy, sz))
    types = [e.dxftype() for e in recursive_decompose(msp)]
    assert len(types) == count(doc, ["L0", "L1"])
    assert set(types) == {"LINE"}, "expected only LINES"
Exemple #2
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
def explode(layout: 'BaseLayout'):
    if EXPLODE_CONTENT:
        entities = list(disassemble.recursive_decompose(layout))
        for e in entities:
            if e.dxftype() in ('ATTRIB', 'ATTDEF'):
                if not EXPLODE_ATTRIBS:
                    continue
                e = copy_attrib_as_text(cast('BaseAttrib', e))
            e = cast('DXFGraphic', e)
            e.dxf.layer = EXPLODE
            e.dxf.color = 6
            layout.add_entity(e)
Exemple #4
0
def test_cache_usage_with_uuids_for_reused_virtual_entities(msp_solids, func):
    cache = bbox.Cache(uuid=True)
    # Create flat entity structure by yourself, so that virtual entities are
    # only created once:
    entities = list(disassemble.recursive_decompose(msp_solids))
    for _ in range(10):
        list(func(entities, cache=cache))

    # This works, because virtual entities are cached by UUID
    # multi_flat and extents, have a second access stage: 2x2 misses, but
    # triggers only 2 bounding box calculations.
    # multi_recursive is the lowest level and has only 2 cache misses.
    assert cache.misses in (2, 4)
    assert cache.hits == 18
Exemple #5
0
def test_cache_usage_for_reused_virtual_entities(msp_solids, func):
    cache = bbox.Cache()
    # Create flat entity structure by yourself, so that virtual entities are
    # only created once:
    entities = list(disassemble.recursive_decompose(msp_solids))
    for _ in range(10):
        list(func(entities, cache=cache))

    # This does not work well by "handle only" usage, because 'entities' contains
    # virtual entities which have no handle and therefore are not cached:
    # multi_flat and extents, have a second access stage and triggers 2x20 cache
    # misses but this is just a cache access issue, this does not trigger 40
    # bounding box calculations!
    # multi_recursive is the lowest level and has only 20 cache misses.
    assert cache.misses in (20, 40)  # virtual entities do not have handles
    assert cache.hits == 0  # parent INSERT bbox is not calculated and cached
Exemple #6
0
def test_decompose_minsert_level_1(doc):
    nrows = 2
    ncols = 2
    expected_count = count(doc, ['L0', 'L1']) * nrows * ncols

    msp = doc.modelspace()
    msp.delete_all_entities()
    msp.add_blockref('L1', (0, 0), dxfattribs={
        'row_count': nrows,
        'row_spacing': 5,
        'column_count': ncols,
        'column_spacing': 5,
    })
    types = [e.dxftype() for e in recursive_decompose(msp)]
    assert len(types) == expected_count
    assert set(types) == {'LINE'}, "expected only LINES"
def test_decompose_minsert_level_1(doc):
    nrows = 2
    ncols = 2
    expected_count = count(doc, ["L0", "L1"]) * nrows * ncols

    msp = doc.modelspace()
    msp.delete_all_entities()
    msp.add_blockref(
        "L1",
        (0, 0),
        dxfattribs={
            "row_count": nrows,
            "row_spacing": 5,
            "column_count": ncols,
            "column_spacing": 5,
        },
    )
    types = [e.dxftype() for e in recursive_decompose(msp)]
    assert len(types) == expected_count
    assert set(types) == {"LINE"}, "expected only LINES"
Exemple #8
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
Exemple #9
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
def test_do_nothing():
    assert list(disassemble.recursive_decompose([])) == []
    assert list(disassemble.to_primitives([])) == []
    assert list(disassemble.to_vertices([])) == []
def test_decompose_block_level_1(doc):
    l1 = doc.blocks.get("L1")
    types = [e.dxftype() for e in recursive_decompose(l1)]
    assert len(types) == count(doc, ["L0", "L1"])
    assert set(types) == {"LINE"}, "expected only LINES"
def test_decompose_block_reference_level_0(doc, sx, sy, sz):
    msp = doc.modelspace()
    msp.delete_all_entities()
    msp.add_blockref("L0", (0, 0), dxfattribs=scale(sx, sy, sz))
    result = list(recursive_decompose(msp))
    assert len(result) == count(doc, ["L0"])
def test_decompose_block_level_0(doc):
    l0 = doc.blocks.get("L0")
    result = list(recursive_decompose(l0))
    assert len(result) == count(doc, ["L0"])
 def entities(self, doc):
     return list(recursive_decompose(doc.modelspace()))
Exemple #15
0
def test_decompose_block_level_1(doc):
    l1 = doc.blocks.get('L1')
    types = [e.dxftype() for e in recursive_decompose(l1)]
    assert len(types) == count(doc, ['L0', 'L1'])
    assert set(types) == {'LINE'}, "expected only LINES"