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))
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()
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
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
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
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
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