Beispiel #1
0
    def set_arrows(self,
                   blk: str = '',
                   blk1: str = '',
                   blk2: str = '',
                   ldrblk: str = '') -> None:
        """
        Set arrows by block names or AutoCAD standard arrow names, set DIMTSZ to ``0`` which disables tick.

        Args:
            blk: block/arrow name for both arrows, if DIMSAH is ``0``
            blk1: block/arrow name for first arrow, if DIMSAH is ``1``
            blk2: block/arrow name for second arrow, if DIMSAH is ``1``
            ldrblk: block/arrow name for leader

        """
        self.set_dxf_attrib('dimblk', blk)
        self.set_dxf_attrib('dimblk1', blk1)
        self.set_dxf_attrib('dimblk2', blk2)
        self.set_dxf_attrib('dimldrblk', ldrblk)
        self.set_dxf_attrib('dimtsz', 0)  # use blocks

        # only existing BLOCK definitions allowed
        if self.doc:
            blocks = self.doc.blocks
            for b in (blk, blk1, blk2, ldrblk):
                if ARROWS.is_acad_arrow(b):  # not real blocks
                    ARROWS.create_block(blocks, b)
                    continue
                if b and b not in blocks:
                    raise DXFValueError(
                        'BLOCK "{}" does not exist.'.format(blk))
Beispiel #2
0
    def add_dimension_line(self, start: 'Vertex', end: 'Vertex') -> None:
        """
        Add dimension line to dimension BLOCK, adds extension DIMDLE if required, and uses DIMSD1 or DIMSD2 to suppress
        first or second part of dimension line. Removes line parts hidden by dimension text.

        Args:
            start: dimension line start
            end: dimension line end

        """
        extension = self.dim_line_vec * self.dim_line_extension
        if self.arrow1_name is None or ARROWS.has_extension_line(self.arrow1_name):
            start = start - extension
        if self.arrow2_name is None or ARROWS.has_extension_line(self.arrow2_name):
            end = end + extension

        attribs = self.dim_line_attributes()

        if self.suppress_dim1_line or self.suppress_dim2_line:
            # TODO: results not as expected, but good enough
            # center should take into account text location
            center = start.lerp(end)
            if not self.suppress_dim1_line:
                self.add_line(start, center, dxfattribs=attribs, remove_hidden_lines=True)
            if not self.suppress_dim2_line:
                self.add_line(center, end, dxfattribs=attribs, remove_hidden_lines=True)
        else:
            self.add_line(start, end, dxfattribs=attribs, remove_hidden_lines=True)
Beispiel #3
0
    def acquire_arrow(self, name: str):
        """ For standard AutoCAD and ezdxf arrows create block definitions if
        required, otherwise check if block `name` exist. (internal API)

        """
        from ezdxf.render.arrows import ARROWS
        if ARROWS.is_acad_arrow(name) or ARROWS.is_ezdxf_arrow(name):
            ARROWS.create_block(self.blocks, name)
        elif name not in self.blocks:
            raise const.DXFValueError(f'Arrow block "{name}" does not exist.')
Beispiel #4
0
    def create_all_arrow_blocks(self):
        """
        For upgrading DXF R12/13/14 files to R2000, it is necessary to create all used arrow blocks before saving the
        DXF file, else $HANDSEED is not the next available handle, which is a problem for AutoCAD.
        To be save create all known AutoCAD arrows, because references to arrow blocks can be in DIMSTYLE,
        DIMENSION override, LEADER override and maybe other places.

        """
        from ezdxf.render.arrows import ARROWS
        for arrow_name in ARROWS.__acad__:
            ARROWS.create_block(self.blocks, arrow_name)
Beispiel #5
0
def is_special_block(name: str) -> bool:
    name = name.upper()
    # Anonymous dimension, groups and table blocks do not have explicit references by INSERT entity
    if name.startswith('*D') or name.startswith('*A') or name.startswith('*T'):
        return True

    # Arrow blocks maybe used in LEADER override without INSERT reference.
    if ARROWS.is_ezdxf_arrow(name):
        return True
    if name.startswith('_'):
        if ARROWS.is_acad_arrow(ARROWS.arrow_name(name)):
            return True

    return False
Beispiel #6
0
    def set_arrows(self,
                   blk: str = '',
                   blk1: str = '',
                   blk2: str = '') -> None:
        """
        Set arrows by block names or AutoCAD standard arrow names, set dimtsz = 0 which disables tick.

        Args:
            blk: block/arrow name for both arrows, if dimsah == 0
            blk1: block/arrow name for first arrow, if dimsah == 1
            blk2: block/arrow name for second arrow, if dimsah == 1

        """
        self.set_dxf_attrib('dimblk', blk)
        self.set_dxf_attrib('dimblk1', blk1)
        self.set_dxf_attrib('dimblk2', blk2)
        self.set_dxf_attrib('dimtsz', 0)  # use blocks

        # only existing BLOCK definitions allowed
        if self.drawing:
            blocks = self.drawing.blocks
            for b in (blk, blk1, blk2):
                if ARROWS.is_acad_arrow(b):  # not real blocks
                    continue
                if b and b not in blocks:
                    raise DXFValueError(
                        'BLOCK "{}" does not exist.'.format(blk))
Beispiel #7
0
def is_special_block(name: str) -> bool:
    name = name.upper()
    # Anonymous dimension, groups and table blocks do not have explicit
    # references by an INSERT entity:
    if is_anonymous_block(name):
        return True

    # Arrow blocks maybe used in DIMENSION or LEADER override without an
    # INSERT reference:
    if ARROWS.is_ezdxf_arrow(name):
        return True
    if name.startswith('_'):
        if ARROWS.is_acad_arrow(ARROWS.arrow_name(name)):
            return True

    return False
Beispiel #8
0
 def _get_arrow_block_name(self, name: str) -> str:
     handle = self.get_dxf_attrib(name, None)
     if handle in (None, '0'):
         # unset handle or handle '0' is default closed filled arrow
         return ARROWS.closed_filled
     else:
         block_name = get_block_name_by_handle(handle, self.drawing)
         return ARROWS.arrow_name(block_name)  # if arrow return standard arrow name else just the block name
Beispiel #9
0
    def _set_blk_handle(self, attr: str, arrow_name: str) -> None:
        if arrow_name == ARROWS.closed_filled:
            # special arrow, no handle needed (is '0' if set)
            # do not create block by default, this will be done if arrow is used
            # and block record handle is not needed here
            self.del_dxf_attrib(attr)
            return

        blocks = self.drawing.blocks
        if ARROWS.is_acad_arrow(arrow_name):
            # create block, because need block record handle is needed here
            block_name = ARROWS.create_block(blocks, arrow_name)
        else:
            block_name = arrow_name

        blk = blocks.get(block_name)
        self.set_dxf_attrib(attr, blk.block_record_handle)
Beispiel #10
0
 def get_arrow_block_name(self, name: str) -> str:
     handle = self.get_dxf_attrib(name, None)
     if handle in (None, '0'):
         # unset handle or handle '0' is default closed filled arrow
         return ARROWS.closed_filled
     else:
         block_name = get_block_name_by_handle(handle, self.doc)
         # Returns standard arrow name or the user defined block name:
         return ARROWS.arrow_name(block_name)
Beispiel #11
0
 def set_arrow_handle(attrib_name, block_name):
     attrib_name += '_handle'
     if block_name in ARROWS:  # create all arrows on demand
         block_name = ARROWS.create_block(blocks, block_name)
     if block_name == '_CLOSEDFILLED':  # special arrow
         handle = '0'  # set special #0 handle for closed filled arrow
     else:
         block = blocks[block_name]
         handle = block.block_record_handle
     data[attrib_name] = handle
Beispiel #12
0
 def get_arrow_block_name(self, name: str) -> str:
     assert self.doc is not None, "valid DXF document required"
     handle = self.get_dxf_attrib(name, None)
     if handle in (None, "0"):
         # unset handle or handle '0' is default closed filled arrow
         return ARROWS.closed_filled
     else:
         block_name = get_block_name_by_handle(handle, self.doc)
         # Returns standard arrow name or the user defined block name:
         return ARROWS.arrow_name(block_name)
Beispiel #13
0
def virtual_arrow(name: str,
                  insert: Vector = Vector(),
                  size: float = 0.625,
                  rotation: float = 0,
                  dxfattribs=None,
                  doc=None):
    from ezdxf.graphicsfactory import VirtualLayout
    from ezdxf.render.arrows import ARROWS
    if name in ARROWS:
        layout = VirtualLayout(doc)
        dxfattribs = dxfattribs or {}
        ARROWS.render_arrow(
            layout,
            name,
            insert=insert,
            size=size,
            rotation=rotation,
            dxfattribs=dxfattribs,
        )
        yield from layout.entities
Beispiel #14
0
    def set_blk_handle(self, attr: str, arrow_name: str) -> None:
        if arrow_name == ARROWS.closed_filled:
            # special arrow, no handle needed (is '0' if set)
            # do not create block by default, this will be done if arrow is used
            # and block record handle is not needed here
            self.dxf.discard(attr)
            return

        blocks = self.doc.blocks
        if ARROWS.is_acad_arrow(arrow_name):
            # create block, because need block record handle is needed here
            block_name = ARROWS.create_block(blocks, arrow_name)
        else:
            block_name = arrow_name

        blk = blocks.get(block_name)
        if blk is not None:
            self.set_dxf_attrib(attr, blk.block_record_handle)
        else:
            raise DXFValueError(f'Block {arrow_name} does not exist.')
Beispiel #15
0
    def _create_missing_arrows(self):
        """
        Create or import required arrows, used by LEADER or DIMSTYLE, which are not imported automatically because they
        are not actually used in an anonymous  DIMENSION blocks.

        """
        self.used_arrows.discard('')  # standard default arrow '' needs no block definition
        for arrow_name in self.used_arrows:
            if ARROWS.is_acad_arrow(arrow_name):
                self.target.acquire_arrow(arrow_name)
            else:
                self.import_block(arrow_name, rename=False)
Beispiel #16
0
    def add_dimension_line(self, start: Vec2, end: Vec2) -> None:
        """Add dimension line to dimension BLOCK, adds extension DIMDLE if
        required, and uses DIMSD1 or DIMSD2 to suppress first or second part of
        dimension line. Removes line parts hidden by dimension text.

        Args:
            start: dimension line start
            end: dimension line end

        """
        dim_line = self.dimension_line
        arrows = self.arrows
        extension = self.dim_line_vec * dim_line.extension
        ticks = arrows.has_ticks
        if ticks or ARROWS.has_extension_line(arrows.arrow1_name):
            start = start - extension
        if ticks or ARROWS.has_extension_line(arrows.arrow2_name):
            end = end + extension

        attribs = dim_line.dxfattribs()

        if dim_line.suppress1 or dim_line.suppress2:
            # TODO: results not as expected, but good enough
            # center should take into account text location
            center = start.lerp(end)
            if not dim_line.suppress1:
                self.add_line(start,
                              center,
                              dxfattribs=attribs,
                              remove_hidden_lines=True)
            if not dim_line.suppress2:
                self.add_line(center,
                              end,
                              dxfattribs=attribs,
                              remove_hidden_lines=True)
        else:
            self.add_line(start,
                          end,
                          dxfattribs=attribs,
                          remove_hidden_lines=True)
Beispiel #17
0
def test_arrow_name():
    assert ARROWS.arrow_name('_CLOSEDFILLED') == ''
    assert ARROWS.arrow_name('') == ''
    assert ARROWS.arrow_name('_DOTSMALL') == 'DOTSMALL'
    assert ARROWS.arrow_name('_boxBlank') == 'BOXBLANK'
    assert ARROWS.arrow_name('EZ_ARROW') == 'EZ_ARROW'
    assert ARROWS.arrow_name('abcdef') == 'abcdef'
Beispiel #18
0
def test_arrow_name():
    assert ARROWS.arrow_name("_CLOSEDFILLED") == ""
    assert ARROWS.arrow_name("") == ""
    assert ARROWS.arrow_name("_DOTSMALL") == "DOTSMALL"
    assert ARROWS.arrow_name("_boxBlank") == "BOXBLANK"
    assert ARROWS.arrow_name("EZ_ARROW") == "EZ_ARROW"
    assert ARROWS.arrow_name("abcdef") == "abcdef"
Beispiel #19
0
 def set_arrow_name(attrib_name: str, handle: str):
     if handle == '0':  # special handle for default arrow CLOSEDFILLED
         data[attrib_name] = ''  # special name for default arrow CLOSEDFILLED
         return
     try:
         block_record = db[handle]
     except KeyError:
         logger.info(
             'Required arrow block #{} does not exist, ignoring {} override.'.format(handle, attrib_name.upper())
         )
         return
     name = block_record.dxf.name
     if name.startswith('_'):  # translate block name into ACAD standard name _OPEN30 -> OPEN30
         acad_arrow_name = name[1:]
         if ARROWS.is_acad_arrow(acad_arrow_name):
             name = acad_arrow_name
     data[attrib_name] = name
Beispiel #20
0
 def set_arrow_name(attrib_name: str, handle: str):
     # Special handle for default arrow CLOSEDFILLED:
     if handle == '0':
         # Special name for default arrow CLOSEDFILLED:
         data[attrib_name] = ''
         return
     try:
         block_record = db[handle]
     except KeyError:
         logger.info(f'Required arrow block #{handle} does not exist, '
                     f'ignoring {attrib_name.upper()} override.')
         return
     name = block_record.dxf.name
     # Translate block name into ACAD standard name _OPEN30 -> OPEN30
     if name.startswith('_'):
         acad_arrow_name = name[1:]
         if ARROWS.is_acad_arrow(acad_arrow_name):
             name = acad_arrow_name
     data[attrib_name] = name
Beispiel #21
0
def test_virtual_entities():
    entities = list(ARROWS.virtual_entities(ARROWS.closed, insert=(0, 0, 0)))
    assert len(entities) > 0
Beispiel #22
0
 def add_arrow_blockref(self, name: str, insert: 'Vertex', size: float = 1., rotation: float = 0,
                        dxfattribs: dict = None) -> Vector:
     return ARROWS.insert_arrow(self, name=name, insert=insert, size=size, rotation=rotation, dxfattribs=dxfattribs)
Beispiel #23
0
def test_closed_arrow_r2000(dxf2000):
    blocks = dxf2000.blocks
    name = ARROWS.create_block(blocks, ARROWS.closed)
    arrow_entities = list(blocks.get(name))
    assert arrow_entities[0].dxftype() == 'LWPOLYLINE'
Beispiel #24
0
def test_render_to_virtual_layout():
    from ezdxf.graphicsfactory import VirtualLayout

    layout = VirtualLayout()
    ARROWS.render_arrow(layout, ARROWS.closed, insert=(0, 0, 0))
    assert len(layout.entities) > 0
Beispiel #25
0
def test_filled_solid_arrow():
    # special name: no name ""
    assert "" in ARROWS
    ARROWS.is_acad_arrow("")
Beispiel #26
0
def test_render_arrow():
    layout = VirtualLayout()
    ARROWS.render_arrow(layout, ARROWS.closed, insert=(0, 0, 0))
    assert len(layout) > 0
Beispiel #27
0
def test_closed_arrow_doc_r2000():
    doc = ezdxf.new(dxfversion="R2000", setup=True)
    blocks = doc.blocks
    name = ARROWS.create_block(blocks, ARROWS.closed)
    arrow_entities = list(blocks.get(name))
    assert arrow_entities[0].dxftype() == "LWPOLYLINE"