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

176 lines
5.3 KiB
Python

# Copyright (c) 2023, Manfred Moitzi
# License: MIT License
from __future__ import annotations
import dataclasses
import enum
import copy
from ezdxf.colors import RGB
class FillType(enum.IntEnum):
"""Fill type enumeration."""
NONE = 0
SOLID = 1
HATCHING = 2
CROSS_HATCHING = 3
SHADING = 4
class FillMethod(enum.IntEnum):
"""Fill method enumeration."""
EVEN_ODD = 0
NON_ZERO_WINDING = 1
RGB_NONE = RGB(-1, -1, -1)
RGB_BLACK = RGB(0, 0, 0)
RGB_WHITE = RGB(255, 255, 255)
LIGHT_GREY = RGB(200, 200, 200)
@dataclasses.dataclass
class Pen:
"""Represents a pen table entry."""
index: int
width: float # in mm
color: RGB
class Properties:
"""Consolidated display properties."""
DEFAULT_PEN = Pen(1, 0.35, RGB_NONE)
def __init__(self) -> None:
# hashed content
self.pen_index: int = 1
self.pen_color = RGB_NONE
self.pen_width: float = 0.35 # in mm
self.fill_type = FillType.SOLID
self.fill_method = FillMethod.EVEN_ODD
self.fill_hatch_line_angle: float = 0.0 # in degrees
self.fill_hatch_line_spacing: float = 40.0 # in plotter units
self.fill_shading_density: float = 100.0
# not hashed content
self.max_pen_count: int = 2
self.pen_table: dict[int, Pen] = {}
self.reset()
def hash(self) -> int:
return hash(
(
self.pen_index,
self.pen_color,
self.pen_width,
self.fill_type,
self.fill_method,
self.fill_hatch_line_angle,
self.fill_hatch_line_spacing,
self.fill_shading_density,
)
)
def copy(self) -> Properties:
# the pen table is shared across all copies of Properties
return copy.copy(self)
def setup_default_pen_table(self):
if len(self.pen_table):
return
pens = self.pen_table
width = self.DEFAULT_PEN.width
pens[0] = Pen(0, width, RGB(255, 255, 255)) # white
pens[1] = Pen(1, width, RGB(0, 0, 0)) # black
pens[2] = Pen(2, width, RGB(255, 0, 0)) # red
pens[3] = Pen(3, width, RGB(0, 255, 0)) # green
pens[4] = Pen(4, width, RGB(255, 255, 0)) # yellow
pens[5] = Pen(5, width, RGB(0, 0, 255)) # blue
pens[6] = Pen(6, width, RGB(255, 0, 255)) # magenta
pens[7] = Pen(6, width, RGB(0, 255, 255)) # cyan
def reset(self) -> None:
self.max_pen_count = 2
self.pen_index = self.DEFAULT_PEN.index
self.pen_color = self.DEFAULT_PEN.color
self.pen_width = self.DEFAULT_PEN.width
self.pen_table = {}
self.fill_type = FillType.SOLID
self.fill_method = FillMethod.EVEN_ODD
self.fill_hatch_line_angle = 0.0
self.fill_hatch_line_spacing = 40.0
self.fill_shading_density = 1.0
self.setup_default_pen_table()
def get_pen(self, index: int) -> Pen:
return self.pen_table.get(index, self.DEFAULT_PEN)
def set_max_pen_count(self, count: int) -> None:
self.max_pen_count = count
def set_current_pen(self, index: int) -> None:
self.pen_index = index
pen = self.get_pen(index)
self.pen_width = pen.width
self.pen_color = pen.color
def set_pen_width(self, index: int, width: float) -> None:
if index == -1:
self.pen_width = width
else:
pen = self.pen_table.setdefault(
index, Pen(index, width, self.DEFAULT_PEN.color)
)
pen.width = width
def set_pen_color(self, index: int, rgb: RGB) -> None:
if index == -1:
self.pen_color = rgb
else:
pen = self.pen_table.setdefault(
index, Pen(index, self.DEFAULT_PEN.width, rgb)
)
pen.color = rgb
def set_fill_type(self, fill_type: int, spacing: float, angle: float):
if fill_type == 3:
self.fill_type = FillType.HATCHING
self.fill_hatch_line_spacing = spacing
self.fill_hatch_line_angle = angle
elif fill_type == 4:
self.fill_type = FillType.CROSS_HATCHING
self.fill_hatch_line_spacing = spacing
self.fill_hatch_line_angle = angle
elif fill_type == 10:
self.fill_type = FillType.SHADING
self.fill_shading_density = spacing
else:
self.fill_type = FillType.SOLID
def set_fill_method(self, fill_method: int) -> None:
self.fill_method = FillMethod(fill_method)
def resolve_pen_color(self) -> RGB:
"""Returns the final RGB pen color."""
rgb = self.pen_color
if rgb is RGB_NONE:
pen = self.pen_table.get(self.pen_index, self.DEFAULT_PEN)
rgb = pen.color
if rgb is RGB_NONE:
return RGB_BLACK
return rgb
def resolve_fill_color(self) -> RGB:
"""Returns the final RGB fill color."""
ft = self.fill_type
if ft == FillType.SOLID:
return self.resolve_pen_color()
elif ft == FillType.SHADING:
grey = min(int(2.55 * (100.0 - self.fill_shading_density)), 255)
return RGB(grey, grey, grey)
elif ft == FillType.HATCHING or ft == FillType.CROSS_HATCHING:
return LIGHT_GREY
return RGB_WHITE