Make pin_objects and wire_objects dictionaries

This commit is contained in:
Daniel Rojas 2021-10-24 17:01:28 +02:00 committed by KV
parent 8b9d997054
commit 7902ba6aa6
3 changed files with 63 additions and 83 deletions

View File

@ -4,7 +4,7 @@ from collections import namedtuple
from dataclasses import dataclass, field from dataclasses import dataclass, field
from enum import Enum from enum import Enum
from itertools import zip_longest from itertools import zip_longest
from typing import Dict, List, Optional, Tuple, Union from typing import Any, Dict, List, Optional, Tuple, Union
from wireviz.wv_bom import ( from wireviz.wv_bom import (
BomHash, BomHash,
@ -273,7 +273,9 @@ class AdditionalComponent(Component):
self.qty = self.parse_number_and_unit(self.qty, None) self.qty = self.parse_number_and_unit(self.qty, None)
self.amount = self.parse_number_and_unit(self.amount, None) self.amount = self.parse_number_and_unit(self.amount, None)
if isinstance(self.qty_multiplier, float) or isinstance(self.qty_multiplier, int): if isinstance(self.qty_multiplier, float) or isinstance(
self.qty_multiplier, int
):
pass pass
else: else:
self.qty_multiplier = self.qty_multiplier.upper() self.qty_multiplier = self.qty_multiplier.upper()
@ -325,9 +327,7 @@ class Connector(TopLevelGraphicalComponent):
pins: List[Pin] = field(default_factory=list) # legacy pins: List[Pin] = field(default_factory=list) # legacy
pinlabels: List[Pin] = field(default_factory=list) # legacy pinlabels: List[Pin] = field(default_factory=list) # legacy
pincolors: List[str] = field(default_factory=list) # legacy pincolors: List[str] = field(default_factory=list) # legacy
pin_objects: List[PinClass] = field( pin_objects: Dict[Any, PinClass] = field(default_factory=dict) # new
default_factory=list
) # new, to replace the lists above
# rendering option # rendering option
show_pincount: Optional[bool] = None show_pincount: Optional[bool] = None
hide_disconnected_pins: bool = False hide_disconnected_pins: bool = False
@ -347,8 +347,11 @@ class Connector(TopLevelGraphicalComponent):
] ]
return ", ".join([str(s) for s in substrs if s is not None and s != ""]) return ", ".join([str(s) for s in substrs if s is not None and s != ""])
def should_show_pin(self, pin_name): def should_show_pin(self, pin_id):
return not self.hide_disconnected_pins or self.visible_pins.get(pin_name, False) return (
not self.hide_disconnected_pins
or self.pin_objects[pin_id]._num_connections > 0
)
@property @property
def unit(self): # for compatibility with BOM hashing def unit(self): # for compatibility with BOM hashing
@ -404,16 +407,14 @@ class Connector(TopLevelGraphicalComponent):
self.pincolors, self.pincolors,
) )
for pin_index, (pin_id, pin_label, pin_color) in enumerate(pin_tuples): for pin_index, (pin_id, pin_label, pin_color) in enumerate(pin_tuples):
self.pin_objects.append( self.pin_objects[pin_id] = PinClass(
PinClass( index=pin_index,
index=pin_index, id=pin_id,
id=pin_id, label=pin_label,
label=pin_label, color=MultiColor(pin_color),
color=MultiColor(pin_color), parent=self.designator,
parent=self.designator, _anonymous=self.is_autogenerated,
_anonymous=self.is_autogenerated, _simple=self.style == "simple",
_simple=self.style == "simple",
)
) )
if self.show_name is None: if self.show_name is None:
@ -433,27 +434,16 @@ class Connector(TopLevelGraphicalComponent):
if pin not in self.pins: if pin not in self.pins:
raise Exception(f'Unknown loop pin "{pin}" for connector "{self.name}"!') raise Exception(f'Unknown loop pin "{pin}" for connector "{self.name}"!')
# Make sure loop connected pins are not hidden. # Make sure loop connected pins are not hidden.
self.activate_pin(pin) # side=None, determine side to show loops during rendering
self.activate_pin(pin, side=None, is_connection=True)
for i, item in enumerate(self.additional_components): for i, item in enumerate(self.additional_components):
if isinstance(item, dict): if isinstance(item, dict):
self.additional_components[i] = AdditionalComponent(**item) self.additional_components[i] = AdditionalComponent(**item)
def _check_if_unique_id(self, id): def activate_pin(self, pin_id, side: Side = None, is_connection=True) -> None:
results = [pin for pin in self.pin_objects if pin.id == id] if is_connection:
if len(results) == 0: self.pin_objects[pin_id]._num_connections += 1
raise Exception(f"Pin ID {id} not found in {self.designator}")
if len(results) > 1:
raise Exception(f"Pin ID {id} found more than once in {self.designator}")
return True
def get_pin_by_id(self, id):
if self._check_if_unique_id(id):
pin = [pin for pin in self.pin_objects if pin.id == id]
return pin[0]
def activate_pin(self, pin: Pin, side: Side) -> None:
self.visible_pins[pin] = True
if side == Side.LEFT: if side == Side.LEFT:
self.ports_left = True self.ports_left = True
elif side == Side.RIGHT: elif side == Side.RIGHT:
@ -473,6 +463,7 @@ class Connector(TopLevelGraphicalComponent):
# QtyMultiplierCable = Enum( # QtyMultiplierCable = Enum(
# "QtyMultiplierCable", "ONE WIRECOUNT TERMINATION LENGTH TOTAL_LENGTH" # "QtyMultiplierCable", "ONE WIRECOUNT TERMINATION LENGTH TOTAL_LENGTH"
# ) # )
# def get_qty_multiplier(self, qty_multiplier: Optional[ConnectorMultiplier]) -> int: # def get_qty_multiplier(self, qty_multiplier: Optional[ConnectorMultiplier]) -> int:
# # TODO!!! how and when to compute final qty for additional components??? # # TODO!!! how and when to compute final qty for additional components???
# if not qty_multiplier: # if not qty_multiplier:
@ -565,9 +556,7 @@ class Cable(TopLevelGraphicalComponent):
shield: Union[bool, MultiColor] = False shield: Union[bool, MultiColor] = False
colors: List[str] = field(default_factory=list) # legacy colors: List[str] = field(default_factory=list) # legacy
wirelabels: List[Wire] = field(default_factory=list) # legacy wirelabels: List[Wire] = field(default_factory=list) # legacy
wire_objects: List[WireClass] = field( wire_objects: Dict[Any, WireClass] = field(default_factory=dict) # new
default_factory=list
) # to replace the lists above
# internal # internal
_connections: List[Connection] = field(default_factory=list) _connections: List[Connection] = field(default_factory=list)
# rendering options # rendering options
@ -704,37 +693,35 @@ class Cable(TopLevelGraphicalComponent):
self.wirelabels, self.wirelabels,
) )
for wire_index, (wire_color, wire_label) in enumerate(wire_tuples): for wire_index, (wire_color, wire_label) in enumerate(wire_tuples):
self.wire_objects.append( id = wire_index + 1
WireClass( self.wire_objects[id] = WireClass(
parent=self.designator, parent=self.designator,
# wire-specific properties # wire-specific properties
index=wire_index, # TODO: wire_id index=wire_index, # TODO: wire_id
id=wire_index + 1, # TODO: wire_id id=id, # TODO: wire_id
label=wire_label, label=wire_label,
color=MultiColor(wire_color), color=MultiColor(wire_color),
# inheritable from parent cable # inheritable from parent cable
type=self.type, type=self.type,
subtype=self.subtype, subtype=self.subtype,
gauge=self.gauge, gauge=self.gauge,
length=self.length, length=self.length,
sum_amounts_in_bom=self.sum_amounts_in_bom, sum_amounts_in_bom=self.sum_amounts_in_bom,
# TODO partnumbers # TODO partnumbers
)
) )
if self.shield: if self.shield:
index_offset = len(self.wire_objects) index_offset = len(self.wire_objects)
# TODO: add support for multiple shields # TODO: add support for multiple shields
self.wire_objects.append( id = "s"
ShieldClass( self.wire_objects[id] = ShieldClass(
index=index_offset, index=index_offset,
id="s", id=id,
label="Shield", label="Shield",
color=MultiColor(self.shield) color=MultiColor(self.shield)
if isinstance(self.shield, str) if isinstance(self.shield, str)
else MultiColor(None), else MultiColor(None),
parent=self.designator, parent=self.designator,
)
) )
if self.show_name is None: if self.show_name is None:
@ -748,24 +735,15 @@ class Cable(TopLevelGraphicalComponent):
if isinstance(item, dict): if isinstance(item, dict):
self.additional_components[i] = AdditionalComponent(**item) self.additional_components[i] = AdditionalComponent(**item)
def get_wire_by_id(self, id):
wire = [wire for wire in self.wire_objects if wire.id == id]
if len(wire) == 0:
raise Exception(f"Wire ID {id} not found in {self.designator}")
if len(wire) > 1:
raise Exception(f"Wire ID {id} found more than once in {self.designator}")
return wire[0]
def _connect( def _connect(
self, self,
from_pin_obj: [PinClass], from_pin_obj: [PinClass],
via_wire_id: str, via_wire_id: str,
to_pin_obj: [PinClass], to_pin_obj: [PinClass],
) -> None: ) -> None:
via_wire_obj = self.get_wire_by_id(via_wire_id) via_wire_obj = self.wire_objects[via_wire_id]
self._connections.append(Connection(from_pin_obj, via_wire_obj, to_pin_obj)) self._connections.append(Connection(from_pin_obj, via_wire_obj, to_pin_obj))
# def get_qty_multiplier(self, qty_multiplier: Optional[CableMultiplier]) -> float: # def get_qty_multiplier(self, qty_multiplier: Optional[CableMultiplier]) -> float:
# if not qty_multiplier: # if not qty_multiplier:
# return 1 # return 1

View File

@ -166,8 +166,8 @@ def nested_table(lines: List[Td]) -> Table:
def gv_pin_table(component) -> Table: def gv_pin_table(component) -> Table:
pin_rows = [] pin_rows = []
for pin in component.pin_objects: for pin in component.pin_objects.values():
if component.should_show_pin(pin.id): # TODO remove True if component.should_show_pin(pin.id):
pin_rows.append(gv_pin_row(pin, component)) pin_rows.append(gv_pin_row(pin, component))
tbl = Table(pin_rows, border=0, cellborder=1, cellpadding=3, cellspacing=0) tbl = Table(pin_rows, border=0, cellborder=1, cellpadding=3, cellspacing=0)
return tbl return tbl
@ -211,7 +211,7 @@ def gv_conductor_table(cable) -> Table:
rows.append(Tr(Td(" "))) # spacer row on top rows.append(Tr(Td(" "))) # spacer row on top
inserted_break_inbetween = False inserted_break_inbetween = False
for wire in cable.wire_objects: for wire in cable.wire_objects.values():
# insert blank space between wires and shields # insert blank space between wires and shields
if isinstance(wire, ShieldClass) and not inserted_break_inbetween: if isinstance(wire, ShieldClass) and not inserted_break_inbetween:

View File

@ -67,14 +67,16 @@ class Harness:
def add_mate_pin(self, from_name, from_pin, to_name, to_pin, arrow_str) -> None: def add_mate_pin(self, from_name, from_pin, to_name, to_pin, arrow_str) -> None:
from_con = self.connectors[from_name] from_con = self.connectors[from_name]
from_pin_obj = from_con.get_pin_by_id(from_pin) from_pin_obj = from_con.pin_objects[from_pin]
to_con = self.connectors[to_name] to_con = self.connectors[to_name]
to_pin_obj = to_con.get_pin_by_id(to_pin) to_pin_obj = to_con.pin_objects[to_pin]
arrow = Arrow(direction=parse_arrow_str(arrow_str), weight=ArrowWeight.SINGLE) arrow = Arrow(direction=parse_arrow_str(arrow_str), weight=ArrowWeight.SINGLE)
self.mates.append(MatePin(from_pin_obj, to_pin_obj, arrow)) self.mates.append(MatePin(from_pin_obj, to_pin_obj, arrow))
self.connectors[from_name].activate_pin(from_pin, Side.RIGHT) self.connectors[from_name].activate_pin(
self.connectors[to_name].activate_pin(to_pin, Side.LEFT) from_pin, Side.RIGHT, is_connection=False
)
self.connectors[to_name].activate_pin(to_pin, Side.LEFT, is_connection=False)
def add_mate_component(self, from_name, to_name, arrow_str) -> None: def add_mate_component(self, from_name, to_name, arrow_str) -> None:
arrow = Arrow(direction=parse_arrow_str(arrow_str), weight=ArrowWeight.SINGLE) arrow = Arrow(direction=parse_arrow_str(arrow_str), weight=ArrowWeight.SINGLE)
@ -126,7 +128,7 @@ class Harness:
cat = "" cat = ""
if item.category == "bundle": if item.category == "bundle":
for subitem in item.wire_objects: for subitem in item.wire_objects.values():
_add( _add(
hash=subitem.bom_hash, hash=subitem.bom_hash,
qty=item.bom_qty, # should be 1 qty=item.bom_qty, # should be 1
@ -225,12 +227,12 @@ class Harness:
# perform the actual connection # perform the actual connection
if from_name is not None: if from_name is not None:
from_con = self.connectors[from_name] from_con = self.connectors[from_name]
from_pin_obj = from_con.get_pin_by_id(from_pin) from_pin_obj = from_con.pin_objects[from_pin]
else: else:
from_pin_obj = None from_pin_obj = None
if to_name is not None: if to_name is not None:
to_con = self.connectors[to_name] to_con = self.connectors[to_name]
to_pin_obj = to_con.get_pin_by_id(to_pin) to_pin_obj = to_con.pin_objects[to_pin]
else: else:
to_pin_obj = None to_pin_obj = None
@ -267,7 +269,7 @@ class Harness:
wire_is_multicolor = [ wire_is_multicolor = [
len(wire.color) > 1 len(wire.color) > 1
for cable in self.cables.values() for cable in self.cables.values()
for wire in cable.wire_objects for wire in cable.wire_objects.values()
] ]
if any(wire_is_multicolor): if any(wire_is_multicolor):
wireviz.wv_colors.padding_amount = 3 wireviz.wv_colors.padding_amount = 3