refactor: excel parse
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
# Copyright (c) 2019-2024 Manfred Moitzi
|
||||
# License: MIT License
|
||||
from __future__ import annotations
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
from typing_extensions import Self
|
||||
from ezdxf.lldxf import validator
|
||||
from ezdxf.lldxf.attributes import (
|
||||
DXFAttr,
|
||||
DXFAttributes,
|
||||
DefSubclass,
|
||||
XType,
|
||||
RETURN_DEFAULT,
|
||||
group_code_mapping,
|
||||
merge_group_code_mappings,
|
||||
)
|
||||
from ezdxf.lldxf.const import (
|
||||
SUBCLASS_MARKER,
|
||||
DXF12,
|
||||
DXF2000,
|
||||
MODEL_SPACE_R12,
|
||||
PAPER_SPACE_R12,
|
||||
MODEL_SPACE_R2000,
|
||||
PAPER_SPACE_R2000,
|
||||
)
|
||||
from ezdxf.math import NULLVEC
|
||||
from .dxfentity import base_class, SubclassProcessor, DXFEntity
|
||||
from .factory import register_entity
|
||||
from ezdxf.audit import Auditor, AuditError
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ezdxf.entities import DXFNamespace
|
||||
from ezdxf.lldxf.tagwriter import AbstractTagWriter
|
||||
from ezdxf import xref
|
||||
|
||||
__all__ = ["Block", "EndBlk"]
|
||||
|
||||
acdb_entity = DefSubclass(
|
||||
"AcDbEntity",
|
||||
{
|
||||
# No auto fix for invalid layer names!
|
||||
"layer": DXFAttr(8, default="0", validator=validator.is_valid_layer_name),
|
||||
"paperspace": DXFAttr(
|
||||
67,
|
||||
default=0,
|
||||
optional=True,
|
||||
validator=validator.is_integer_bool,
|
||||
fixer=RETURN_DEFAULT,
|
||||
),
|
||||
},
|
||||
)
|
||||
acdb_entity_group_codes = group_code_mapping(acdb_entity)
|
||||
|
||||
acdb_block_begin = DefSubclass(
|
||||
"AcDbBlockBegin",
|
||||
{
|
||||
"name": DXFAttr(2, validator=validator.is_valid_block_name),
|
||||
# The 2nd name with group code 3 is handled internally, and is not an
|
||||
# explicit DXF attribute.
|
||||
"description": DXFAttr(4, default="", dxfversion=DXF2000, optional=True),
|
||||
# Flags:
|
||||
# 0 = Indicates none of the following flags apply
|
||||
# 1 = This is an anonymous block generated by hatching, associative
|
||||
# dimensioning, other internal operations, or an application
|
||||
# 2 = This block has non-constant attribute definitions (this bit is not set
|
||||
# if the block has any attribute definitions that are constant, or has
|
||||
# no attribute definitions at all)
|
||||
# 4 = This block is an external reference (xref)
|
||||
# 8 = This block is an xref overlay
|
||||
# 16 = This block is externally dependent
|
||||
# 32 = This is a resolved external reference, or dependent of an external
|
||||
# reference (ignored on input)
|
||||
# 64 = This definition is a referenced external reference (ignored on input)
|
||||
"flags": DXFAttr(70, default=0),
|
||||
"base_point": DXFAttr(10, xtype=XType.any_point, default=NULLVEC),
|
||||
"xref_path": DXFAttr(1, default=""),
|
||||
},
|
||||
)
|
||||
acdb_block_begin_group_codes = group_code_mapping(acdb_block_begin)
|
||||
merged_block_begin_group_codes = merge_group_code_mappings(
|
||||
acdb_entity_group_codes, acdb_block_begin_group_codes
|
||||
)
|
||||
|
||||
MODEL_SPACE_R2000_LOWER = MODEL_SPACE_R2000.lower()
|
||||
MODEL_SPACE_R12_LOWER = MODEL_SPACE_R12.lower()
|
||||
PAPER_SPACE_R2000_LOWER = PAPER_SPACE_R2000.lower()
|
||||
PAPER_SPACE_R12_LOWER = PAPER_SPACE_R12.lower()
|
||||
|
||||
|
||||
@register_entity
|
||||
class Block(DXFEntity):
|
||||
"""DXF BLOCK entity"""
|
||||
|
||||
DXFTYPE = "BLOCK"
|
||||
DXFATTRIBS = DXFAttributes(base_class, acdb_entity, acdb_block_begin)
|
||||
|
||||
# Block entity flags:
|
||||
# This is an anonymous block generated by hatching, associative
|
||||
# dimensioning, other internal operations, or an application:
|
||||
ANONYMOUS = 1
|
||||
|
||||
# This block has non-constant attribute definitions (this bit is not set
|
||||
# if the block has any attribute definitions that are constant, or has no
|
||||
# attribute definitions at all):
|
||||
NON_CONSTANT_ATTRIBUTES = 2
|
||||
|
||||
# This block is an external reference:
|
||||
XREF = 4
|
||||
|
||||
# This block is an xref overlay:
|
||||
XREF_OVERLAY = 8
|
||||
|
||||
# This block is externally dependent:
|
||||
EXTERNAL = 16
|
||||
|
||||
# This is a resolved external reference, or dependent of an external reference:
|
||||
RESOLVED = 32
|
||||
|
||||
# This definition is a referenced external reference:
|
||||
REFERENCED = 64
|
||||
|
||||
def load_dxf_attribs(
|
||||
self, processor: Optional[SubclassProcessor] = None
|
||||
) -> DXFNamespace:
|
||||
"""Loading interface. (internal API)"""
|
||||
dxf = super().load_dxf_attribs(processor)
|
||||
if processor is None:
|
||||
return dxf
|
||||
processor.simple_dxfattribs_loader(dxf, merged_block_begin_group_codes)
|
||||
if processor.r12:
|
||||
if dxf.name is None:
|
||||
dxf.name = ""
|
||||
name = dxf.name.lower()
|
||||
if name == MODEL_SPACE_R12_LOWER:
|
||||
dxf.name = MODEL_SPACE_R2000
|
||||
elif name == PAPER_SPACE_R12_LOWER:
|
||||
dxf.name = PAPER_SPACE_R2000
|
||||
return dxf
|
||||
|
||||
def export_entity(self, tagwriter: AbstractTagWriter) -> None:
|
||||
"""Export entity specific data as DXF tags."""
|
||||
super().export_entity(tagwriter)
|
||||
|
||||
if tagwriter.dxfversion > DXF12:
|
||||
tagwriter.write_tag2(SUBCLASS_MARKER, acdb_entity.name)
|
||||
if self.dxf.hasattr("paperspace"):
|
||||
tagwriter.write_tag2(67, 1)
|
||||
self.dxf.export_dxf_attribs(tagwriter, "layer")
|
||||
if tagwriter.dxfversion > DXF12:
|
||||
tagwriter.write_tag2(SUBCLASS_MARKER, acdb_block_begin.name)
|
||||
|
||||
name = self.dxf.name
|
||||
if tagwriter.dxfversion == DXF12:
|
||||
# export modelspace and paperspace with leading '$' instead of '*'
|
||||
if name.lower() == MODEL_SPACE_R2000_LOWER:
|
||||
name = MODEL_SPACE_R12
|
||||
elif name.lower() == PAPER_SPACE_R2000_LOWER:
|
||||
name = PAPER_SPACE_R12
|
||||
|
||||
tagwriter.write_tag2(2, name)
|
||||
self.dxf.export_dxf_attribs(tagwriter, ["flags", "base_point"])
|
||||
tagwriter.write_tag2(3, name)
|
||||
self.dxf.export_dxf_attribs(tagwriter, ["xref_path", "description"])
|
||||
|
||||
@property
|
||||
def is_layout_block(self) -> bool:
|
||||
"""Returns ``True`` if this is a :class:`~ezdxf.layouts.Modelspace` or
|
||||
:class:`~ezdxf.layouts.Paperspace` block definition.
|
||||
"""
|
||||
name = self.dxf.name.lower()
|
||||
return name.startswith("*model_space") or name.startswith("*paper_space")
|
||||
|
||||
@property
|
||||
def is_anonymous(self) -> bool:
|
||||
"""Returns ``True`` if this is an anonymous block generated by
|
||||
hatching, associative dimensioning, other internal operations, or an
|
||||
application.
|
||||
|
||||
"""
|
||||
return self.get_flag_state(Block.ANONYMOUS)
|
||||
|
||||
@property
|
||||
def is_xref(self) -> bool:
|
||||
"""Returns ``True`` if bock is an external referenced file."""
|
||||
return self.get_flag_state(Block.XREF)
|
||||
|
||||
@property
|
||||
def is_xref_overlay(self) -> bool:
|
||||
"""Returns ``True`` if bock is an external referenced overlay file."""
|
||||
return self.get_flag_state(Block.XREF_OVERLAY)
|
||||
|
||||
def audit(self, auditor: Auditor):
|
||||
owner_handle = self.dxf.get("owner")
|
||||
if owner_handle is None: # invalid owner handle - IGNORE
|
||||
return
|
||||
owner = auditor.entitydb.get(owner_handle)
|
||||
if owner is None: # invalid owner entity - IGNORE
|
||||
return
|
||||
owner_name = owner.dxf.get("name", "").upper()
|
||||
block_name = self.dxf.get("name", "").upper()
|
||||
if owner_name != block_name:
|
||||
auditor.add_error(
|
||||
AuditError.BLOCK_NAME_MISMATCH,
|
||||
f"{str(self)} name '{block_name}' and {str(owner)} name '{owner_name}' mismatch",
|
||||
)
|
||||
|
||||
def map_resources(self, clone: Self, mapping: xref.ResourceMapper) -> None:
|
||||
"""Translate resources from self to the copied entity."""
|
||||
assert isinstance(clone, Block)
|
||||
super().map_resources(clone, mapping)
|
||||
clone.dxf.name = mapping.get_block_name(self.dxf.name)
|
||||
|
||||
|
||||
acdb_block_end = DefSubclass("AcDbBlockEnd", {})
|
||||
|
||||
|
||||
@register_entity
|
||||
class EndBlk(DXFEntity):
|
||||
"""DXF ENDBLK entity"""
|
||||
|
||||
DXFTYPE = "ENDBLK"
|
||||
DXFATTRIBS = DXFAttributes(base_class, acdb_entity, acdb_block_end)
|
||||
|
||||
def load_dxf_attribs(
|
||||
self, processor: Optional[SubclassProcessor] = None
|
||||
) -> DXFNamespace:
|
||||
"""Loading interface. (internal API)"""
|
||||
dxf = super().load_dxf_attribs(processor)
|
||||
if processor:
|
||||
processor.simple_dxfattribs_loader(dxf, acdb_entity_group_codes) # type: ignore
|
||||
return dxf
|
||||
|
||||
def export_entity(self, tagwriter: AbstractTagWriter) -> None:
|
||||
"""Export entity specific data as DXF tags."""
|
||||
super().export_entity(tagwriter)
|
||||
|
||||
if tagwriter.dxfversion > DXF12:
|
||||
tagwriter.write_tag2(SUBCLASS_MARKER, acdb_entity.name)
|
||||
if self.dxf.hasattr("paperspace"):
|
||||
tagwriter.write_tag2(67, 1)
|
||||
self.dxf.export_dxf_attribs(tagwriter, "layer")
|
||||
if tagwriter.dxfversion > DXF12:
|
||||
tagwriter.write_tag2(SUBCLASS_MARKER, acdb_block_end.name)
|
||||
Reference in New Issue
Block a user