Skip to content

Common Sheet Rule

This guide explains the common sheet rule for branch presentations. When nodes appear on multiple sheets, branches connecting them must reference a sheet where both nodes are visible.

Full Example

View the complete code: 09_common_sheet_rule.py

The Rule

When creating a branch between two nodes:

  1. Identify all sheets where node1 has a presentation
  2. Identify all sheets where node2 has a presentation
  3. The branch presentation must use a sheet in the intersection

Invalid Configuration

A branch referencing a sheet where either endpoint node is not visible will cause them to be "unplaced" in Gaia/Vision.

Example Scenario

Consider three sheets and two nodes:

NodeSheets
Node1Sheet A, Sheet B
Node2Sheet B, Sheet C

Valid branch sheet: Sheet B (the only common sheet)

Invalid branch sheets: Sheet A (Node2 not visible), Sheet C (Node1 not visible)

Implementation

Create Multiple Sheets

python
from pyptp import NetworkMV, configure_logging
from pyptp.elements.color_utils import CL_BLUE, CL_GRAY, CL_GREEN
from pyptp.elements.mv.sheet import SheetMV

configure_logging(level="INFO")

network = NetworkMV()

# Create three sheets
sheet_a = SheetMV(SheetMV.General(name="Sheet A", color=CL_GRAY))
sheet_a.register(network)
sheet_a_guid = sheet_a.general.guid

sheet_b = SheetMV(SheetMV.General(name="Sheet B", color=CL_BLUE))
sheet_b.register(network)
sheet_b_guid = sheet_b.general.guid

sheet_c = SheetMV(SheetMV.General(name="Sheet C", color=CL_GREEN))
sheet_c.register(network)
sheet_c_guid = sheet_c.general.guid

Create Nodes on Multiple Sheets

python
from pyptp.elements.mv.node import NodeMV
from pyptp.elements.mv.presentations import NodePresentation

# Node1 appears on sheets A and B
node1 = NodeMV(
    NodeMV.General(name="Node1", unom=10.0),
    presentations=[
        NodePresentation(sheet=sheet_a_guid, x=400, y=100),
        NodePresentation(sheet=sheet_b_guid, x=100, y=100),
    ],
)
node1.register(network)

# Node2 appears on sheets B and C
node2 = NodeMV(
    NodeMV.General(name="Node2", unom=10.0),
    presentations=[
        NodePresentation(sheet=sheet_b_guid, x=400, y=100),
        NodePresentation(sheet=sheet_c_guid, x=100, y=100),
    ],
)
node2.register(network)

Create Branch on Common Sheet

python
from pyptp.elements.mv.link import LinkMV
from pyptp.elements.mv.presentations import BranchPresentation

# Branch must use Sheet B - the only common sheet
link = LinkMV(
    LinkMV.General(node1=node1.general.guid, node2=node2.general.guid),
    presentations=[
        BranchPresentation(
            sheet=sheet_b_guid,  # Common sheet
            first_corners=[(100, 100), (250, 100)],
            second_corners=[(400, 100)],
        )
    ],
)
link.register(network)

Finding Common Sheets Programmatically

python
def find_common_sheets(node1, node2):
    """Find sheets where both nodes have presentations."""
    sheets1 = {p.sheet for p in node1.presentations}
    sheets2 = {p.sheet for p in node2.presentations}
    return sheets1 & sheets2  # Set intersection


def create_branch_safe(network, node1, node2, corners_func):
    """Create branch on a valid common sheet."""
    common = find_common_sheets(node1, node2)

    if not common:
        raise ValueError(f"No common sheet between {node1.general.name} and {node2.general.name}")

    # Use first common sheet
    sheet_guid = next(iter(common))

    # Get node positions on this sheet
    pos1 = next(p for p in node1.presentations if p.sheet == sheet_guid)
    pos2 = next(p for p in node2.presentations if p.sheet == sheet_guid)

    # Generate corners based on positions
    first_corners, second_corners = corners_func(pos1, pos2)

    return LinkMV(
        LinkMV.General(node1=node1.general.guid, node2=node2.general.guid),
        presentations=[
            BranchPresentation(
                sheet=sheet_guid,
                first_corners=first_corners,
                second_corners=second_corners,
            )
        ],
    )

Complete Example

python
"""Branch presentations must reference a common sheet between both nodes.

When nodes appear on multiple sheets, the branch connecting them must use
a sheet where both nodes are visible.
"""

from pyptp import NetworkMV, configure_logging
from pyptp.elements.color_utils import CL_BLUE, CL_GRAY, CL_GREEN
from pyptp.elements.mv.link import LinkMV
from pyptp.elements.mv.node import NodeMV
from pyptp.elements.mv.presentations import BranchPresentation, NodePresentation
from pyptp.elements.mv.sheet import SheetMV
from pyptp.ptp_log import logger

configure_logging(level="INFO")

network = NetworkMV()

# Create three sheets
sheet_a = SheetMV(SheetMV.General(name="Sheet A", color=CL_GRAY))
sheet_a.register(network)
sheet_a_guid = sheet_a.general.guid

sheet_b = SheetMV(SheetMV.General(name="Sheet B", color=CL_BLUE))
sheet_b.register(network)
sheet_b_guid = sheet_b.general.guid

sheet_c = SheetMV(SheetMV.General(name="Sheet C", color=CL_GREEN))
sheet_c.register(network)
sheet_c_guid = sheet_c.general.guid

# Node1 appears on sheets A and B
node1 = NodeMV(
    NodeMV.General(name="Node1", unom=10.0),
    presentations=[
        NodePresentation(sheet=sheet_a_guid, x=400, y=100),
        NodePresentation(sheet=sheet_b_guid, x=100, y=100),
    ],
)
node1.register(network)

# Node2 appears on sheets B and C
node2 = NodeMV(
    NodeMV.General(name="Node2", unom=10.0),
    presentations=[
        NodePresentation(sheet=sheet_b_guid, x=400, y=100),
        NodePresentation(sheet=sheet_c_guid, x=100, y=100),
    ],
)
node2.register(network)

# Branch must use Sheet B - the only common sheet
link = LinkMV(
    LinkMV.General(node1=node1.general.guid, node2=node2.general.guid),
    presentations=[
        BranchPresentation(
            sheet=sheet_b_guid,
            first_corners=[(100, 100), (250, 100)],
            second_corners=[(400, 100)],
        )
    ],
)
link.register(network)

network.save("common_sheet.vnf")
logger.info("Network with common sheet rule saved")