Files
stepanalyser/.venv/lib/python3.12/site-packages/ezdxf/entities/copy.py
Christian Anetzberger a197de9456 initial
2026-01-22 20:23:51 +01:00

103 lines
3.0 KiB
Python

# Copyright (c) 2023, Manfred Moitzi
# License: MIT License
from __future__ import annotations
from typing import TYPE_CHECKING, TypeVar, NamedTuple, Optional
from copy import deepcopy
import logging
from ezdxf.lldxf.const import DXFError
if TYPE_CHECKING:
from ezdxf.entities import DXFEntity
__all__ = ["CopyStrategy", "CopySettings", "CopyNotSupported", "default_copy"]
T = TypeVar("T", bound="DXFEntity")
class CopyNotSupported(DXFError):
pass
class CopySettings(NamedTuple):
reset_handles: bool = True
copy_extension_dict: bool = True
copy_xdata: bool = True
copy_appdata: bool = True
copy_reactors: bool = False
copy_proxy_graphic: bool = True
set_source_of_copy: bool = True
# The processing of copy errors of linked entities has to be done in the
# copy_data() method by the entity itself!
ignore_copy_errors_in_linked_entities: bool = True
class LogMessage(NamedTuple):
message: str
level: int = logging.WARNING
entity: Optional[DXFEntity] = None
class CopyStrategy:
log: list[LogMessage] = []
def __init__(self, settings: CopySettings) -> None:
self.settings = settings
def copy(self, entity: T) -> T:
"""Entity copy for usage in the same document or as virtual entity.
This copy is NOT stored in the entity database and does NOT reside in any
layout, block, table or objects section!
"""
settings = self.settings
clone = entity.__class__()
doc = entity.doc
clone.doc = doc
clone.dxf = entity.dxf.copy(clone)
if settings.reset_handles:
clone.dxf.reset_handles()
if settings.copy_extension_dict:
xdict = entity.extension_dict
if xdict is not None and doc is not None and xdict.is_alive:
# Error handling of unsupported entities in the extension dictionary is
# done by the underlying DICTIONARY entity.
clone.extension_dict = xdict.copy(self)
if settings.copy_reactors and entity.reactors is not None:
clone.reactors = entity.reactors.copy()
if settings.copy_proxy_graphic:
clone.proxy_graphic = entity.proxy_graphic # immutable bytes
# if appdata contains handles, they are treated as shared resources
if settings.copy_appdata:
clone.appdata = deepcopy(entity.appdata)
# if xdata contains handles, they are treated as shared resources
if settings.copy_xdata:
clone.xdata = deepcopy(entity.xdata)
if settings.set_source_of_copy:
clone.set_source_of_copy(entity)
entity.copy_data(clone, copy_strategy=self)
return clone
@classmethod
def add_log_message(
cls, msg: str, level: int = logging.WARNING, entity: Optional[DXFEntity] = None
) -> None:
cls.log.append(LogMessage(msg, level, entity))
@classmethod
def clear_log_message(cls) -> None:
cls.log.clear()
# same strategy as DXFEntity.copy() of v1.1.3
default_copy = CopyStrategy(CopySettings())