refactor: excel parse
This commit is contained in:
@@ -0,0 +1,664 @@
|
||||
# Purpose: Import data from another DXF document
|
||||
# Copyright (c) 2013-2022, Manfred Moitzi
|
||||
# License: MIT License
|
||||
from __future__ import annotations
|
||||
from typing import TYPE_CHECKING, Iterable, cast, Union, Optional
|
||||
import logging
|
||||
from ezdxf.lldxf import const
|
||||
from ezdxf.render.arrows import ARROWS
|
||||
from ezdxf.entities import (
|
||||
DXFEntity,
|
||||
DXFGraphic,
|
||||
Hatch,
|
||||
Polyline,
|
||||
DimStyle,
|
||||
Dimension,
|
||||
Viewport,
|
||||
Linetype,
|
||||
Insert,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ezdxf.document import Drawing
|
||||
from ezdxf.layouts import BaseLayout, Layout
|
||||
|
||||
logger = logging.getLogger("ezdxf")
|
||||
|
||||
IMPORT_TABLES = ["linetypes", "layers", "styles", "dimstyles"]
|
||||
IMPORT_ENTITIES = {
|
||||
"LINE",
|
||||
"POINT",
|
||||
"CIRCLE",
|
||||
"ARC",
|
||||
"TEXT",
|
||||
"SOLID",
|
||||
"TRACE",
|
||||
"3DFACE",
|
||||
"SHAPE",
|
||||
"POLYLINE",
|
||||
"ATTRIB",
|
||||
"INSERT",
|
||||
"ELLIPSE",
|
||||
"MTEXT",
|
||||
"LWPOLYLINE",
|
||||
"SPLINE",
|
||||
"HATCH",
|
||||
"MESH",
|
||||
"XLINE",
|
||||
"RAY",
|
||||
"ATTDEF",
|
||||
"DIMENSION",
|
||||
"LEADER", # dimension style override not supported!
|
||||
"VIEWPORT",
|
||||
}
|
||||
|
||||
|
||||
class Importer:
|
||||
"""
|
||||
The :class:`Importer` class is central element for importing data from
|
||||
other DXF documents.
|
||||
|
||||
Args:
|
||||
source: source :class:`~ezdxf.drawing.Drawing`
|
||||
target: target :class:`~ezdxf.drawing.Drawing`
|
||||
|
||||
Attributes:
|
||||
source: source DXF document
|
||||
target: target DXF document
|
||||
used_layers: Set of used layer names as string, AutoCAD accepts layer
|
||||
names without a LAYER table entry.
|
||||
used_linetypes: Set of used linetype names as string, these linetypes
|
||||
require a TABLE entry or AutoCAD will crash.
|
||||
used_styles: Set of used text style names, these text styles require
|
||||
a TABLE entry or AutoCAD will crash.
|
||||
used_dimstyles: Set of used dimension style names, these dimension
|
||||
styles require a TABLE entry or AutoCAD will crash.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, source: Drawing, target: Drawing):
|
||||
self.source: Drawing = source
|
||||
self.target: Drawing = target
|
||||
|
||||
self.used_layers: set[str] = set()
|
||||
self.used_linetypes: set[str] = set()
|
||||
self.used_styles: set[str] = set()
|
||||
self.used_shape_files: set[str] = set() # style entry without a name!
|
||||
self.used_dimstyles: set[str] = set()
|
||||
self.used_arrows: set[str] = set()
|
||||
self.handle_mapping: dict[str, str] = dict() # old_handle: new_handle
|
||||
|
||||
# collects all imported INSERT entities, for later name resolving.
|
||||
self.imported_inserts: list[DXFEntity] = list() # imported inserts
|
||||
|
||||
# collects all imported block names and their assigned new name
|
||||
# imported_block[original_name] = new_name
|
||||
self.imported_blocks: dict[str, str] = dict()
|
||||
self._default_plotstyle_handle = target.plotstyles["Normal"].dxf.handle
|
||||
self._default_material_handle = target.materials["Global"].dxf.handle
|
||||
|
||||
def _add_used_resources(self, entity: DXFEntity) -> None:
|
||||
"""Register used resources."""
|
||||
self.used_layers.add(entity.get_dxf_attrib("layer", "0"))
|
||||
self.used_linetypes.add(entity.get_dxf_attrib("linetype", "BYLAYER"))
|
||||
if entity.is_supported_dxf_attrib("style"):
|
||||
self.used_styles.add(entity.get_dxf_attrib("style", "Standard"))
|
||||
if entity.is_supported_dxf_attrib("dimstyle"):
|
||||
self.used_dimstyles.add(entity.get_dxf_attrib("dimstyle", "Standard"))
|
||||
|
||||
def _add_dimstyle_resources(self, dimstyle: DimStyle) -> None:
|
||||
self.used_styles.add(dimstyle.get_dxf_attrib("dimtxsty", "Standard"))
|
||||
self.used_linetypes.add(dimstyle.get_dxf_attrib("dimltype", "BYLAYER"))
|
||||
self.used_linetypes.add(dimstyle.get_dxf_attrib("dimltex1", "BYLAYER"))
|
||||
self.used_linetypes.add(dimstyle.get_dxf_attrib("dimltex2", "BYLAYER"))
|
||||
self.used_arrows.add(dimstyle.get_dxf_attrib("dimblk", ""))
|
||||
self.used_arrows.add(dimstyle.get_dxf_attrib("dimblk1", ""))
|
||||
self.used_arrows.add(dimstyle.get_dxf_attrib("dimblk2", ""))
|
||||
self.used_arrows.add(dimstyle.get_dxf_attrib("dimldrblk", ""))
|
||||
|
||||
def _add_linetype_resources(self, linetype: Linetype) -> None:
|
||||
if not linetype.pattern_tags.is_complex_type():
|
||||
return
|
||||
style_handle = linetype.pattern_tags.get_style_handle()
|
||||
style = self.source.entitydb.get(style_handle)
|
||||
if style is None:
|
||||
return
|
||||
if style.dxf.name == "":
|
||||
# Shape file entries have no name!
|
||||
self.used_shape_files.add(style.dxf.font)
|
||||
else:
|
||||
self.used_styles.add(style.dxf.name)
|
||||
|
||||
def import_tables(
|
||||
self, table_names: Union[str, Iterable[str]] = "*", replace=False
|
||||
) -> None:
|
||||
"""Import DXF tables from the source document into the target document.
|
||||
|
||||
Args:
|
||||
table_names: iterable of tables names as strings, or a single table
|
||||
name as string or "*" for all supported tables
|
||||
replace: ``True`` to replace already existing table entries else
|
||||
ignore existing entries
|
||||
|
||||
Raises:
|
||||
TypeError: unsupported table type
|
||||
|
||||
"""
|
||||
if isinstance(table_names, str):
|
||||
if table_names == "*": # import all supported tables
|
||||
table_names = IMPORT_TABLES
|
||||
else: # import one specific table
|
||||
table_names = (table_names,)
|
||||
for table_name in table_names:
|
||||
self.import_table(table_name, entries="*", replace=replace)
|
||||
|
||||
def import_table(
|
||||
self, name: str, entries: Union[str, Iterable[str]] = "*", replace=False
|
||||
) -> None:
|
||||
"""
|
||||
Import specific table entries from the source document into the
|
||||
target document.
|
||||
|
||||
Args:
|
||||
name: valid table names are "layers", "linetypes" and "styles"
|
||||
entries: Iterable of table names as strings, or a single table name
|
||||
or "*" for all table entries
|
||||
replace: ``True`` to replace the already existing table entry else
|
||||
ignore existing entries
|
||||
|
||||
Raises:
|
||||
TypeError: unsupported table type
|
||||
|
||||
"""
|
||||
if name not in IMPORT_TABLES:
|
||||
raise TypeError(f'Table "{name}" import not supported.')
|
||||
source_table = getattr(self.source.tables, name)
|
||||
target_table = getattr(self.target.tables, name)
|
||||
|
||||
if isinstance(entries, str):
|
||||
if entries == "*": # import all table entries
|
||||
entries = (entry.dxf.name for entry in source_table)
|
||||
else: # import just one table entry
|
||||
entries = (entries,)
|
||||
for entry_name in entries:
|
||||
try:
|
||||
table_entry = source_table.get(entry_name)
|
||||
except const.DXFTableEntryError:
|
||||
logger.warning(
|
||||
f'Required table entry "{entry_name}" in table f{name} '
|
||||
f"not found."
|
||||
)
|
||||
continue
|
||||
entry_name = table_entry.dxf.name
|
||||
if entry_name in target_table:
|
||||
if replace:
|
||||
logger.debug(
|
||||
f'Replacing already existing entry "{entry_name}" '
|
||||
f"of {name} table."
|
||||
)
|
||||
target_table.remove(table_entry.dxf.name)
|
||||
else:
|
||||
logger.debug(
|
||||
f'Discarding already existing entry "{entry_name}" '
|
||||
f"of {name} table."
|
||||
)
|
||||
continue
|
||||
|
||||
if name == "layers":
|
||||
self.used_linetypes.add(
|
||||
table_entry.get_dxf_attrib("linetype", "Continuous")
|
||||
)
|
||||
elif name == "dimstyles":
|
||||
self._add_dimstyle_resources(table_entry)
|
||||
elif name == "linetypes":
|
||||
self._add_linetype_resources(table_entry)
|
||||
|
||||
# Duplicate table entry:
|
||||
new_table_entry = self._duplicate_table_entry(table_entry)
|
||||
target_table.add_entry(new_table_entry)
|
||||
|
||||
# Register resource handles for mapping:
|
||||
self.handle_mapping[table_entry.dxf.handle] = new_table_entry.dxf.handle
|
||||
|
||||
def import_shape_files(self, fonts: set[str]) -> None:
|
||||
"""Import shape file table entries from the source document into the
|
||||
target document.
|
||||
Shape file entries are stored in the styles table but without a name.
|
||||
|
||||
"""
|
||||
for font in fonts:
|
||||
table_entry = self.source.styles.find_shx(font)
|
||||
# copy is not necessary, just create a new entry:
|
||||
new_table_entry = self.target.styles.get_shx(font)
|
||||
if table_entry:
|
||||
# Register resource handles for mapping:
|
||||
self.handle_mapping[table_entry.dxf.handle] = new_table_entry.dxf.handle
|
||||
else:
|
||||
logger.warning(f'Required shape file entry "{font}" not found.')
|
||||
|
||||
def _set_table_entry_dxf_attribs(self, entity: DXFEntity) -> None:
|
||||
entity.doc = self.target
|
||||
if entity.dxf.hasattr("plotstyle_handle"):
|
||||
entity.dxf.plotstyle_handle = self._default_plotstyle_handle
|
||||
if entity.dxf.hasattr("material_handle"):
|
||||
entity.dxf.material_handle = self._default_material_handle
|
||||
|
||||
def _duplicate_table_entry(self, entry: DXFEntity) -> DXFEntity:
|
||||
# duplicate table entry
|
||||
new_entry = new_clean_entity(entry)
|
||||
self._set_table_entry_dxf_attribs(entry)
|
||||
|
||||
# create a new handle and add entity to target entity database
|
||||
self.target.entitydb.add(new_entry)
|
||||
return new_entry
|
||||
|
||||
def import_entity(
|
||||
self, entity: DXFEntity, target_layout: Optional[BaseLayout] = None
|
||||
) -> None:
|
||||
"""
|
||||
Imports a single DXF `entity` into `target_layout` or the modelspace
|
||||
of the target document, if `target_layout` is ``None``.
|
||||
|
||||
Args:
|
||||
entity: DXF entity to import
|
||||
target_layout: any layout (modelspace, paperspace or block) from
|
||||
the target document
|
||||
|
||||
Raises:
|
||||
DXFStructureError: `target_layout` is not a layout of target document
|
||||
|
||||
"""
|
||||
|
||||
def set_dxf_attribs(e):
|
||||
e.doc = self.target
|
||||
# remove invalid resources
|
||||
e.dxf.discard("plotstyle_handle")
|
||||
e.dxf.discard("material_handle")
|
||||
e.dxf.discard("visualstyle_handle")
|
||||
|
||||
if target_layout is None:
|
||||
target_layout = self.target.modelspace()
|
||||
elif target_layout.doc != self.target:
|
||||
raise const.DXFStructureError(
|
||||
"Target layout has to be a layout or block from the target " "document."
|
||||
)
|
||||
|
||||
dxftype = entity.dxftype()
|
||||
if dxftype not in IMPORT_ENTITIES:
|
||||
logger.debug(f"Import of {str(entity)} not supported")
|
||||
return
|
||||
self._add_used_resources(entity)
|
||||
|
||||
try:
|
||||
new_entity = cast(DXFGraphic, new_clean_entity(entity))
|
||||
except const.DXFTypeError:
|
||||
logger.debug(f"Copying for DXF type {dxftype} not supported.")
|
||||
return
|
||||
|
||||
set_dxf_attribs(new_entity)
|
||||
self.target.entitydb.add(new_entity)
|
||||
target_layout.add_entity(new_entity)
|
||||
|
||||
try: # additional processing
|
||||
getattr(self, "_import_" + dxftype.lower())(new_entity)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def _import_insert(self, insert: Insert):
|
||||
self.imported_inserts.append(insert)
|
||||
# remove all possible source document dependencies from sub entities
|
||||
for attrib in insert.attribs:
|
||||
remove_dependencies(attrib)
|
||||
|
||||
def _import_polyline(self, polyline: Polyline):
|
||||
# remove all possible source document dependencies from sub entities
|
||||
for vertex in polyline.vertices:
|
||||
remove_dependencies(vertex)
|
||||
|
||||
def _import_hatch(self, hatch: Hatch):
|
||||
hatch.dxf.discard("associative")
|
||||
|
||||
def _import_viewport(self, viewport: Viewport):
|
||||
viewport.dxf.discard("sun_handle")
|
||||
viewport.dxf.discard("clipping_boundary_handle")
|
||||
viewport.dxf.discard("ucs_handle")
|
||||
viewport.dxf.discard("ucs_base_handle")
|
||||
viewport.dxf.discard("background_handle")
|
||||
viewport.dxf.discard("shade_plot_handle")
|
||||
viewport.dxf.discard("visual_style_handle")
|
||||
viewport.dxf.discard("ref_vp_object_1")
|
||||
viewport.dxf.discard("ref_vp_object_2")
|
||||
viewport.dxf.discard("ref_vp_object_3")
|
||||
viewport.dxf.discard("ref_vp_object_4")
|
||||
|
||||
def _import_dimension(self, dimension: Dimension):
|
||||
if dimension.virtual_block_content:
|
||||
for entity in dimension.virtual_block_content:
|
||||
if isinstance(entity, Insert): # import arrow blocks
|
||||
self.import_block(entity.dxf.name, rename=False)
|
||||
self._add_used_resources(entity)
|
||||
else:
|
||||
logger.error("The required geometry block for DIMENSION is not defined.")
|
||||
|
||||
def import_entities(
|
||||
self,
|
||||
entities: Iterable[DXFEntity],
|
||||
target_layout: Optional[BaseLayout] = None,
|
||||
) -> None:
|
||||
"""Import all `entities` into `target_layout` or the modelspace of the
|
||||
target document, if `target_layout` is ``None``.
|
||||
|
||||
Args:
|
||||
entities: Iterable of DXF entities
|
||||
target_layout: any layout (modelspace, paperspace or block) from
|
||||
the target document
|
||||
|
||||
Raises:
|
||||
DXFStructureError: `target_layout` is not a layout of target document
|
||||
|
||||
"""
|
||||
for entity in entities:
|
||||
self.import_entity(entity, target_layout)
|
||||
|
||||
def import_modelspace(self, target_layout: Optional[BaseLayout] = None) -> None:
|
||||
"""Import all entities from source modelspace into `target_layout` or
|
||||
the modelspace of the target document, if `target_layout` is ``None``.
|
||||
|
||||
Args:
|
||||
target_layout: any layout (modelspace, paperspace or block) from
|
||||
the target document
|
||||
|
||||
Raises:
|
||||
DXFStructureError: `target_layout` is not a layout of target document
|
||||
|
||||
"""
|
||||
self.import_entities(self.source.modelspace(), target_layout=target_layout)
|
||||
|
||||
def recreate_source_layout(self, name: str) -> Layout:
|
||||
"""Recreate source paperspace layout `name` in the target document.
|
||||
The layout will be renamed if `name` already exist in the target
|
||||
document. Returns target modelspace for layout name "Model".
|
||||
|
||||
Args:
|
||||
name: layout name as string
|
||||
|
||||
Raises:
|
||||
KeyError: if source layout `name` not exist
|
||||
|
||||
"""
|
||||
|
||||
def get_target_name():
|
||||
tname = name
|
||||
base_name = name
|
||||
count = 1
|
||||
while tname in self.target.layouts:
|
||||
tname = base_name + str(count)
|
||||
count += 1
|
||||
|
||||
return tname
|
||||
|
||||
def clear(dxfattribs: dict) -> dict:
|
||||
def discard(name: str):
|
||||
try:
|
||||
del dxfattribs[name]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
discard("handle")
|
||||
discard("owner")
|
||||
discard("taborder")
|
||||
discard("shade_plot_handle")
|
||||
discard("block_record_handle")
|
||||
discard("viewport_handle")
|
||||
discard("ucs_handle")
|
||||
discard("base_ucs_handle")
|
||||
return dxfattribs
|
||||
|
||||
if name.lower() == "model":
|
||||
return self.target.modelspace()
|
||||
|
||||
source_layout = self.source.layouts.get(name) # raises KeyError
|
||||
target_name = get_target_name()
|
||||
dxfattribs = clear(source_layout.dxf_layout.dxfattribs())
|
||||
target_layout = self.target.layouts.new(target_name, dxfattribs=dxfattribs)
|
||||
return target_layout
|
||||
|
||||
def import_paperspace_layout(self, name: str) -> Layout:
|
||||
"""Import paperspace layout `name` into the target document.
|
||||
|
||||
Recreates the source paperspace layout in the target document, renames
|
||||
the target paperspace if a paperspace with same `name` already exist
|
||||
and imports all entities from the source paperspace into the target
|
||||
paperspace.
|
||||
|
||||
Args:
|
||||
name: source paper space name as string
|
||||
|
||||
Returns: new created target paperspace :class:`Layout`
|
||||
|
||||
Raises:
|
||||
KeyError: source paperspace does not exist
|
||||
DXFTypeError: invalid modelspace import
|
||||
|
||||
"""
|
||||
if name.lower() == "model":
|
||||
raise const.DXFTypeError(
|
||||
"Can not import modelspace, use method import_modelspace()."
|
||||
)
|
||||
source_layout = self.source.layouts.get(name)
|
||||
target_layout = self.recreate_source_layout(name)
|
||||
self.import_entities(source_layout, target_layout)
|
||||
return target_layout
|
||||
|
||||
def import_paperspace_layouts(self) -> None:
|
||||
"""Import all paperspace layouts and their content into the target
|
||||
document.
|
||||
Target layouts will be renamed if a layout with the same name already
|
||||
exist. Layouts will be imported in original tab order.
|
||||
|
||||
"""
|
||||
for name in self.source.layouts.names_in_taborder():
|
||||
if name.lower() != "model": # do not import modelspace
|
||||
self.import_paperspace_layout(name)
|
||||
|
||||
def import_blocks(self, block_names: Iterable[str], rename=False) -> None:
|
||||
"""Import all BLOCK definitions from source document.
|
||||
|
||||
If a BLOCK already exist the BLOCK will be renamed if argument
|
||||
`rename` is ``True``, otherwise the existing BLOCK in the target
|
||||
document will be used instead of the BLOCK from the source document.
|
||||
Required name resolving for imported BLOCK references (INSERT), will be
|
||||
done in the :meth:`Importer.finalize` method.
|
||||
|
||||
Args:
|
||||
block_names: names of BLOCK definitions to import
|
||||
rename: rename BLOCK if a BLOCK with the same name already exist in
|
||||
target document
|
||||
|
||||
Raises:
|
||||
ValueError: BLOCK in source document not found (defined)
|
||||
|
||||
"""
|
||||
for block_name in block_names:
|
||||
self.import_block(block_name, rename=rename)
|
||||
|
||||
def import_block(self, block_name: str, rename=True) -> str:
|
||||
"""Import one BLOCK definition from source document.
|
||||
|
||||
If the BLOCK already exist the BLOCK will be renamed if argument
|
||||
`rename` is ``True``, otherwise the existing BLOCK in the target
|
||||
document will be used instead of the BLOCK in the source document.
|
||||
Required name resolving for imported block references (INSERT), will be
|
||||
done in the :meth:`Importer.finalize` method.
|
||||
|
||||
To replace an existing BLOCK in the target document, just delete it
|
||||
before importing data:
|
||||
:code:`target.blocks.delete_block(block_name, safe=False)`
|
||||
|
||||
Args:
|
||||
block_name: name of BLOCK to import
|
||||
rename: rename BLOCK if a BLOCK with the same name already exist in
|
||||
target document
|
||||
|
||||
Returns: (renamed) BLOCK name
|
||||
|
||||
Raises:
|
||||
ValueError: BLOCK in source document not found (defined)
|
||||
|
||||
"""
|
||||
|
||||
def get_new_block_name() -> str:
|
||||
num = 0
|
||||
name = block_name
|
||||
while name in target_blocks:
|
||||
name = block_name + str(num)
|
||||
num += 1
|
||||
return name
|
||||
|
||||
try: # already imported block?
|
||||
return self.imported_blocks[block_name]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
try:
|
||||
source_block = self.source.blocks[block_name]
|
||||
except const.DXFKeyError:
|
||||
raise ValueError(f'Source block "{block_name}" not found.')
|
||||
|
||||
target_blocks = self.target.blocks
|
||||
if (block_name in target_blocks) and (rename is False):
|
||||
self.imported_blocks[block_name] = block_name
|
||||
return block_name
|
||||
|
||||
new_block_name = get_new_block_name()
|
||||
block = source_block.block
|
||||
assert block is not None
|
||||
target_block = target_blocks.new(
|
||||
new_block_name,
|
||||
base_point=block.dxf.base_point,
|
||||
dxfattribs={
|
||||
"description": block.dxf.description,
|
||||
"flags": block.dxf.flags,
|
||||
"xref_path": block.dxf.xref_path,
|
||||
},
|
||||
)
|
||||
self.import_entities(source_block, target_layout=target_block)
|
||||
self.imported_blocks[block_name] = new_block_name
|
||||
return new_block_name
|
||||
|
||||
def _create_missing_arrows(self):
|
||||
"""Create or import required arrow blocks, used by the LEADER or the
|
||||
DIMSTYLE entity, which are not imported automatically because they are
|
||||
not used in an anonymous DIMENSION geometry BLOCK.
|
||||
|
||||
"""
|
||||
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)
|
||||
|
||||
def _resolve_inserts(self) -> None:
|
||||
"""Resolve BLOCK names of imported BLOCK reference entities (INSERT).
|
||||
|
||||
This is required for the case the name of the imported BLOCK collides
|
||||
with an already existing BLOCK in the target document and the conflict
|
||||
resolving method is "rename".
|
||||
|
||||
"""
|
||||
while len(self.imported_inserts):
|
||||
inserts = list(self.imported_inserts)
|
||||
# clear imported inserts, block import may append additional inserts
|
||||
self.imported_inserts = []
|
||||
for insert in inserts:
|
||||
block_name = self.import_block(insert.dxf.name)
|
||||
insert.dxf.name = block_name
|
||||
|
||||
def _import_required_table_entries(self) -> None:
|
||||
"""Import required table entries collected while importing entities
|
||||
into the target document.
|
||||
|
||||
"""
|
||||
# 1. dimstyles import adds additional required linetype and style
|
||||
# resources and required arrows
|
||||
if len(self.used_dimstyles):
|
||||
self.import_table("dimstyles", self.used_dimstyles)
|
||||
|
||||
# 2. layers import adds additional required linetype resources
|
||||
if len(self.used_layers):
|
||||
self.import_table("layers", self.used_layers)
|
||||
|
||||
# 3. complex linetypes adds additional required style resources
|
||||
if len(self.used_linetypes):
|
||||
self.import_table("linetypes", self.used_linetypes)
|
||||
|
||||
# 4. Text styles do not add additional required resources
|
||||
if len(self.used_styles):
|
||||
self.import_table("styles", self.used_styles)
|
||||
|
||||
# 5. Shape files are text style entries without a name
|
||||
if len(self.used_shape_files):
|
||||
self.import_shape_files(self.used_shape_files)
|
||||
|
||||
# 6. Update text style handles of imported complex linetypes:
|
||||
self.update_complex_linetypes()
|
||||
|
||||
def _add_required_complex_linetype_resources(self):
|
||||
for ltype_name in self.used_linetypes:
|
||||
try:
|
||||
ltype = self.source.linetypes.get(ltype_name)
|
||||
except const.DXFTableEntryError:
|
||||
continue
|
||||
self._add_linetype_resources(ltype)
|
||||
|
||||
def update_complex_linetypes(self):
|
||||
std_handle = self.target.styles.get("STANDARD").dxf.handle
|
||||
for linetype in self.target.linetypes:
|
||||
if linetype.pattern_tags.is_complex_type():
|
||||
old_handle = linetype.pattern_tags.get_style_handle()
|
||||
new_handle = self.handle_mapping.get(old_handle, std_handle)
|
||||
linetype.pattern_tags.set_style_handle(new_handle)
|
||||
|
||||
def finalize(self) -> None:
|
||||
"""Finalize the import by importing required table entries and BLOCK
|
||||
definitions, without finalization the target document is maybe invalid
|
||||
for AutoCAD. Call the :meth:`~Importer.finalize()` method as last step
|
||||
of the import process.
|
||||
|
||||
"""
|
||||
self._resolve_inserts()
|
||||
self._add_required_complex_linetype_resources()
|
||||
self._import_required_table_entries()
|
||||
self._create_missing_arrows()
|
||||
|
||||
|
||||
def new_clean_entity(entity: DXFEntity, keep_xdata: bool = False) -> DXFEntity:
|
||||
"""Copy entity and remove all external dependencies.
|
||||
|
||||
Args:
|
||||
entity: DXF entity
|
||||
keep_xdata: keep xdata flag
|
||||
|
||||
"""
|
||||
new_entity = entity.copy()
|
||||
new_entity.doc = None
|
||||
return remove_dependencies(new_entity, keep_xdata=keep_xdata)
|
||||
|
||||
|
||||
def remove_dependencies(entity: DXFEntity, keep_xdata: bool = False) -> DXFEntity:
|
||||
"""Remove all external dependencies.
|
||||
|
||||
Args:
|
||||
entity: DXF entity
|
||||
keep_xdata: keep xdata flag
|
||||
|
||||
"""
|
||||
entity.appdata = None
|
||||
entity.reactors = None
|
||||
entity.extension_dict = None
|
||||
if not keep_xdata:
|
||||
entity.xdata = None
|
||||
return entity
|
||||
Reference in New Issue
Block a user