CellDesigner layout
pd2af.building.celldesigner.layout
Build the AF layout, reusing the input map's glyphs where possible.
make_and_add_layout is the layout pass: it walks the model built by
:mod:pd2af.building.celldesigner.model and populates context.layout and
context.layout_model_mapping, branching on layout_mode. The leaf
primitives below -- synthetic nodes, modulation arcs, mapping helpers, and
background cloning for overlay -- do the per-element construction.
:mod:pd2af.core invokes this pass through a
:class:pd2af.building.context.BuilderContext after
the model pass.
Functions:
| Name | Description |
|---|---|
add_mappings_for_layout_and_descendants |
Map an input glyph and its descendants to their model elements. |
add_modulation_mapping |
Map the arc, together with its two endpoint clusters, to |
clone_layout_pruning_foreground |
Clone an input layout element as a builder, to serve as dimmed background. |
make_and_add_layout |
Build |
make_decoration_stripped_layout |
Return a frozen copy of |
make_logic_arc |
Build a |
make_modulation_arc |
Build the arc layout for |
make_synthetic_gate_layout |
Build a placeholder gate node for |
make_synthetic_layout |
Build a placeholder Node for |
new_layout_and_mapping_builders |
A fresh, empty (layout builder, layout-model mapping builder) pair. |
add_mappings_for_layout_and_descendants
add_mappings_for_layout_and_descendants(context: BuilderContext, input_layout: Any, original_to_stripped: dict[int, Any] | None = None)
Map an input glyph and its descendants to their model elements.
With original_to_stripped, the glyphs actually placed are the stripped
clones of :func:make_decoration_stripped_layout: a clone may be a fresh
dataclasses.replace copy that is not a key of the input layout-model
mapping (keyed by the input frozen objects), so we walk the input originals
and follow each to its stripped counterpart. Dropped decoration glyphs are
absent from that map, so they never get mapped -- and being absent from the
layout, never render.
Source code in src/pd2af/building/celldesigner/layout.py
add_modulation_mapping
add_modulation_mapping(mapping_builder: Any, arc: Any, source_layout: Any, target_layout: Any, modulation: Any)
Map the arc, together with its two endpoint clusters, to modulation.
An endpoint that is already part of a cluster (a species drawn as several glyphs) contributes that whole cluster, so the mapping stays consistent with the one the endpoint's own layout was registered under.
Source code in src/pd2af/building/celldesigner/layout.py
clone_layout_pruning_foreground
clone_layout_pruning_foreground(input_layout_element: Any, foreground_ids: set[int], object_to_builder: dict) -> Any
Clone an input layout element as a builder, to serve as dimmed background.
Any descendant subtree whose input original is in foreground_ids
(already drawn in the foreground) is omitted, and None is returned when
the element itself belongs to the foreground.
Clones share object_to_builder so structure shared across the input
layout stays shared once cloned, and they are builders -- not the input
frozen objects -- so dimming the background never mutates the input
map's layout.
Source code in src/pd2af/building/celldesigner/layout.py
make_and_add_layout
make_and_add_layout(context: BuilderContext)
Build context.layout and context.layout_model_mapping (pass 2).
Source code in src/pd2af/building/celldesigner/layout.py
make_decoration_stripped_layout
make_decoration_stripped_layout(input_layout: Any, original_to_stripped: dict[int, Any] | None) -> Any
Return a frozen copy of input_layout stripped of its decoration glyphs.
Every PTM-decoration and active-border sub-glyph is dropped, at any depth,
and id(original) -> stripped recorded for every kept element.
The merged reading (keep_species off) strips the model's species of their
decorations; this drops the matching layout glyphs
(ModificationLayout / StructuralStateLayout and the *ActiveLayout
active-border sibling -- see _STRIPPABLE_SPECIES_DECORATION_CLASSES) so a
stripped species renders plain. Subunit glyphs of kept complexes are
preserved (and recursively stripped), so the real glyph size and subunit
structure -- which the dot layout deliberately keeps -- survive.
Frozen objects throughout (via :func:dataclasses.replace), never builders,
so the result pickles and round-trips like the reused input glyphs of the
non-stripping path; a subtree that needs no change is returned unchanged
(shared with the input). original_to_stripped lets the caller map the
surviving glyphs back to their model elements
(:func:add_mappings_for_layout_and_descendants).
Source code in src/pd2af/building/celldesigner/layout.py
make_logic_arc
make_logic_arc(context: BuilderContext, gate_layout: Any, input_layout: Any) -> Any
Build a LogicArcLayout from a gate to one of its input species.
The CellDesigner writer locates a gate's inputs by scanning for logic arcs
whose source is the gate layout, so the arc runs gate -> input species
(the CellDesigner convention), not input -> gate.
Source code in src/pd2af/building/celldesigner/layout.py
make_modulation_arc
make_modulation_arc(context: BuilderContext, modulation: Any, source_layout: Any, target_layout: Any) -> Any
Build the arc layout for modulation between two node layouts.
In the dot mode the segments are placeholders that graphviz overwrites;
otherwise they are computed from the two layouts' real geometry.
Source code in src/pd2af/building/celldesigner/layout.py
make_synthetic_gate_layout
Build a placeholder gate node for gate.
Used by the dot mode when the input gate has no curated layout.
index seeds the position so two content-equal synthetic gates stay
content-distinct; make_auto_layout repositions every node before render.
Source code in src/pd2af/building/celldesigner/layout.py
make_synthetic_layout
Build a placeholder Node for species.
index seeds the position so two synthetic layouts for
content-equal species (same class, same name) are themselves
content-distinct. Layout dataclasses have compare=False on
id_, so identical content collapses to one mapping key — and
the layout-model mapping then drops every synthetic but the first.
The position itself is throwaway: make_auto_layout repositions
every node before render.
Source code in src/pd2af/building/celldesigner/layout.py
new_layout_and_mapping_builders
A fresh, empty (layout builder, layout-model mapping builder) pair.