Exemple #1
0
 def check_owner_exist(self, entity: DXFEntity) -> None:
     assert self.doc is entity.doc, "Entity from different DXF document."
     if not entity.dxf.hasattr("owner"):  # important for recover mode
         return
     doc = self.doc
     owner_handle = entity.dxf.owner
     handle = entity.dxf.get("handle", "0")
     if owner_handle == "0":
         # Root-Dictionary or Table-Head:
         if handle == self._rootdict_handle or entity.dxftype() == "TABLE":
             return  # '0' handle as owner is valid
     if owner_handle not in doc.entitydb:
         if handle == self._rootdict_handle:
             entity.dxf.owner = "0"
             self.fixed_error(
                 code=AuditError.INVALID_OWNER_HANDLE,
                 message=f"Fixed invalid owner handle in root {str(self)}.",
             )
         elif entity.dxftype() == "TABLE":
             name = entity.dxf.get("name", "UNKNOWN")
             entity.dxf.owner = "0"
             self.fixed_error(
                 code=AuditError.INVALID_OWNER_HANDLE,
                 message=f"Fixed invalid owner handle for {name} table.",
             )
         else:
             self.fixed_error(
                 code=AuditError.INVALID_OWNER_HANDLE,
                 message=f"Deleted {str(entity)} entity with invalid owner "
                 f"handle #{owner_handle}.",
             )
             self.trash(doc.entitydb.get(handle))
Exemple #2
0
def test_default_constructor():
    entity = DXFEntity()
    assert entity.dxftype() == "DXFENTITY"
    assert entity.dxf.handle is None
    assert entity.dxf.owner is None
    assert entity == entity
    assert entity != DXFEntity()
Exemple #3
0
def make_primitive(e: DXFEntity,
                   max_flattening_distance=None) -> AbstractPrimitive:
    """ Factory to create path/mesh primitives. The `max_flattening_distance`
    defines the max distance between the approximation line and the original
    curve. Use `max_flattening_distance` to override the default value.

    Returns an empty primitive for unsupported entities, can be checked by
    property :attr:`is_empty`. The :attr:`path` and the :attr:`mesh` attribute
    is ``None`` and the :meth:`vertices` method yields no vertices.

    Returns an empty primitive for the :class:`~ezdxf.entities.Hatch` entity,
    see docs of the :mod:`~ezdxf.disassemble` module.

    """
    cls = _PRIMITIVE_CLASSES.get(e.dxftype(), GenericPrimitive)
    primitive = cls(e)
    if max_flattening_distance:
        primitive.max_flattening_distance = max_flattening_distance
    return primitive
Exemple #4
0
def make_primitive(entity: DXFEntity,
                   max_flattening_distance=None) -> Primitive:
    """Factory to create path/mesh primitives. The `max_flattening_distance`
    defines the max distance between the approximation line and the original
    curve. Use `max_flattening_distance` to override the default value.

    Returns an **empty primitive** for unsupported entities. The `empty` state
    of a primitive can be checked by the property :attr:`is_empty`.
    The :attr:`path` and the :attr:`mesh` attributes of an empty primitive
    are ``None`` and the :meth:`vertices` method  yields no vertices.

    .. versionchanged:: 0.17
        regular support for the :class:`~ezdxf.entities.Hatch` entity.

    """
    cls = _PRIMITIVE_CLASSES.get(entity.dxftype(), EmptyPrimitive)
    primitive = cls(entity)
    if max_flattening_distance:
        primitive.max_flattening_distance = max_flattening_distance
    return primitive
Exemple #5
0
def make_primitive(entity: DXFEntity,
                   max_flattening_distance=None) -> Primitive:
    """ Factory to create path/mesh primitives. The `max_flattening_distance`
    defines the max distance between the approximation line and the original
    curve. Use `max_flattening_distance` to override the default value.

    Returns an **empty primitive** for unsupported entities. The `empty` state
    of a primitive can be checked by the property :attr:`is_empty`.
    The :attr:`path` and the :attr:`mesh` attributes of an empty primitive
    are ``None`` and the :meth:`vertices` method  yields no vertices.

    Returns an empty primitive for the :class:`~ezdxf.entities.Hatch` entity,
    see docs of the :mod:`~ezdxf.disassemble` module. Use the this to create
    multiple primitives from the HATCH boundary paths::

        primitives = list(to_primitives([hatch_entity]))

    """
    cls = _PRIMITIVE_CLASSES.get(entity.dxftype(), EmptyPrimitive)
    primitive = cls(entity)
    if max_flattening_distance:
        primitive.max_flattening_distance = max_flattening_distance
    return primitive
Exemple #6
0
    def entity_linker_(entity: DXFEntity) -> bool:
        """ Collect and link entities which are linked to a parent entity:

        - VERTEX -> POLYLINE
        - ATTRIB -> INSERT
        - attached MTEXT entity

        Args:
             entity: examined DXF entity

        Returns:
             True if `entity` is linked to a parent entity

        """
        nonlocal main_entity, expected_dxftype, prev
        dxftype: str = entity.dxftype()
        # INSERT & POLYLINE are not linked entities, they are stored in the
        # entity space.
        are_linked_entities = False
        if main_entity is not None:
            # VERTEX, ATTRIB & SEQEND are linked tags, they are NOT stored in
            # the entity space.
            are_linked_entities = True
            if dxftype == 'SEQEND':
                main_entity.link_seqend(entity)
                # Marks also the end of the main entity
                main_entity = None
            # Check for valid DXF structure:
            #   VERTEX follows POLYLINE
            #   ATTRIB follows INSERT
            elif dxftype == expected_dxftype:
                main_entity.link_entity(entity)
            else:
                raise const.DXFStructureError(
                    f"Expected DXF entity {dxftype} or SEQEND")

        elif dxftype in LINKED_ENTITIES:
            # Only INSERT and POLYLINE have a linked entities structure:
            if dxftype == 'INSERT' and not entity.dxf.get('attribs_follow', 0):
                # INSERT must not have following ATTRIBS, ATTRIB can be a stand
                # alone entity:
                #
                #   INSERT with no ATTRIBS, attribs_follow == 0
                #   ATTRIB as stand alone entity
                #   ....
                #   INSERT with ATTRIBS, attribs_follow == 1
                #   ATTRIB as connected entity
                #   SEQEND
                #
                # Therefore a ATTRIB following an INSERT doesn't mean that
                # these entities are linked.
                pass
            else:
                main_entity = entity
                expected_dxftype = LINKED_ENTITIES[dxftype]

        # Attached MTEXT entity:
        elif (dxftype == 'MTEXT') and (entity.dxf.handle is None):
            if prev:
                prev.link_entity(entity)
                are_linked_entities = True
            else:
                raise const.DXFStructureError(
                    "Found attached MTEXT entity without a preceding entity.")
        prev = entity
        return are_linked_entities
Exemple #7
0
    def entity_linker_(entity: DXFEntity) -> bool:
        """Collect and link entities which are linked to a parent entity:

        - VERTEX -> POLYLINE
        - ATTRIB -> INSERT

        Args:
             entity: examined DXF entity

        Returns:
             True if `entity` is linked to a parent entity

        """
        nonlocal main_entity, expected_dxftype
        dxftype: str = entity.dxftype()
        # INSERT & POLYLINE are not linked entities, they are stored in the
        # entity space.
        are_linked_entities = False
        if main_entity is not None:
            # VERTEX, ATTRIB & SEQEND are linked tags, they are NOT stored in
            # the entity space.
            are_linked_entities = True
            if dxftype == "SEQEND":
                main_entity.link_seqend(entity)  # type: ignore
                # Marks also the end of the main entity
                main_entity = None
            # Check for valid DXF structure:
            #   VERTEX follows POLYLINE
            #   ATTRIB follows INSERT
            elif dxftype == expected_dxftype:
                main_entity.link_entity(entity)  # type: ignore
            else:
                raise const.DXFStructureError(
                    f"Expected DXF entity {dxftype} or SEQEND")

        elif dxftype in LINKED_ENTITIES:
            # Only INSERT and POLYLINE have a linked entities structure:
            if dxftype == "INSERT" and not entity.dxf.get("attribs_follow", 0):
                # INSERT must not have following ATTRIBS:
                #
                #   INSERT with no ATTRIBS, attribs_follow == 0
                #   ATTRIB as a stand alone entity, which is a DXF structure
                #   error, but this error should be handled in the audit
                #   process.
                #   ....
                #   INSERT with ATTRIBS, attribs_follow == 1
                #   ATTRIB as connected entity
                #   SEQEND
                #
                # Therefore a ATTRIB following an INSERT doesn't mean that
                # these entities are linked.
                pass
            else:
                main_entity = entity
                expected_dxftype = LINKED_ENTITIES[dxftype]

        # Attached MTEXT entity - this feature most likely does not exist!
        elif (dxftype == "MTEXT") and (entity.dxf.handle is None):
            logger.error(
                "Found attached MTEXT entity. Please open an issue at github: "
                "https://github.com/mozman/ezdxf/issues and provide a DXF "
                "example file.")
        return are_linked_entities