1

Filtre les pièces techniques et documente l’étape 28

This commit is contained in:
2025-12-02 15:28:22 +01:00
parent 301e2e25c5
commit a93813a9f7
12 changed files with 109 additions and 13 deletions

View File

@@ -9,7 +9,7 @@ from matplotlib.lines import Line2D
from lib.filesystem import ensure_parent_dir
from lib.color_sort import lab_sort_key, sort_hex_colors_lab
from lib.rebrickable.color_ignores import is_ignored_color_rgb
from lib.rebrickable.color_ignores import is_ignored_color_rgb, is_ignored_part_category
from lib.rebrickable.parts_inventory import normalize_boolean
from lib.rebrickable.stats import read_rows
@@ -21,18 +21,38 @@ def sort_colors_perceptually(colors: Iterable[dict]) -> List[dict]:
return sorted(colors, key=lambda color: index_map[color["color_rgb"]])
def load_used_colors(parts_path: Path, colors_path: Path, minifig_only: bool = False) -> List[dict]:
def load_part_categories(parts_catalog_path: Path) -> Dict[str, str]:
"""Indexe les catégories par part_num."""
categories: Dict[str, str] = {}
with parts_catalog_path.open() as catalog_file:
import csv
reader = csv.DictReader(catalog_file)
for row in reader:
categories[row["part_num"]] = row["part_cat_id"]
return categories
def load_used_colors(
parts_path: Path,
colors_path: Path,
parts_catalog_path: Path,
minifig_only: bool = False,
) -> List[dict]:
"""Charge les couleurs utilisées (hors rechanges) et leurs quantités totales.
Si minifig_only est vrai, ne conserve que les pièces marquées is_minifig_part=true.
Sinon, exclut les pièces de minifig.
"""
rows = read_rows(parts_path)
categories = load_part_categories(parts_catalog_path)
colors_lookup = {(row["rgb"], normalize_boolean(row["is_trans"])): row["name"] for row in read_rows(colors_path)}
totals: Dict[Tuple[str, str], int] = {}
for row in rows:
if is_ignored_color_rgb(row["color_rgb"]):
continue
if is_ignored_part_category(categories[row["part_num"]]):
continue
if minifig_only and row.get("is_minifig_part") != "true":
continue
if not minifig_only and row.get("is_minifig_part") == "true":
@@ -85,11 +105,12 @@ def build_background(width: float, height: float, resolution: int = 600) -> np.n
def plot_colors_grid(
parts_path: Path,
colors_path: Path,
parts_catalog_path: Path,
destination_path: Path,
minifig_only: bool = False,
) -> None:
"""Dessine une grille artistique des couleurs utilisées."""
colors = load_used_colors(parts_path, colors_path, minifig_only=minifig_only)
colors = load_used_colors(parts_path, colors_path, parts_catalog_path, minifig_only=minifig_only)
positions = build_hex_positions(len(colors))
x_values = [x for x, _ in positions]
y_values = [y for _, y in positions]