Use SVG to get component positions and handle inverted schematics
This commit is contained in:
parent
ff2d6595fb
commit
280736732c
@ -129,6 +129,39 @@ def find_page_viewbox(
|
||||
return view_box
|
||||
|
||||
|
||||
def find_component_by_id(
|
||||
page: ET.Element,
|
||||
component_id: str,
|
||||
) -> Optional[ET.Element]:
|
||||
"""
|
||||
Find a component element by the given ID.
|
||||
"""
|
||||
|
||||
for child in page:
|
||||
if (
|
||||
child.tag == "{http://www.w3.org/2000/svg}g"
|
||||
and child.get("data-path") == "components"
|
||||
and child.get("data-id") == component_id
|
||||
):
|
||||
return child
|
||||
return None
|
||||
|
||||
|
||||
def x_y_from_transform(
|
||||
transform: Optional[str],
|
||||
) -> Optional[Position]:
|
||||
"""
|
||||
Get the x and y coordinates from the transform string.
|
||||
"""
|
||||
|
||||
if not transform:
|
||||
return None
|
||||
x, y = transform.lstrip("translate(").rstrip(")").split(",")
|
||||
x = float(x)
|
||||
y = float(y)
|
||||
return {"x": x, "y": y}
|
||||
|
||||
|
||||
def find_component_position(
|
||||
page: ET.Element,
|
||||
component_id: str,
|
||||
@ -144,18 +177,14 @@ def find_component_position(
|
||||
and child.get("data-id") == component_id
|
||||
):
|
||||
transform = child.get("transform")
|
||||
if not transform:
|
||||
return None
|
||||
x, y = transform.lstrip("translate(").rstrip(")").split(",")
|
||||
x = float(x)
|
||||
y = float(y)
|
||||
return {"x": x, "y": y}
|
||||
return x_y_from_transform(transform)
|
||||
return None
|
||||
|
||||
|
||||
def position_of_element(
|
||||
element_designator: str,
|
||||
ir_page: dict,
|
||||
svg_page: ET.Element,
|
||||
) -> Optional[Position]:
|
||||
split_designator = element_designator.split(".")
|
||||
component_designator = split_designator[0]
|
||||
@ -174,9 +203,14 @@ def position_of_element(
|
||||
if not component:
|
||||
return None
|
||||
|
||||
component_position = component.get("position")
|
||||
component_id = component["id"]
|
||||
svg_component = find_component_by_id(svg_page, component_id)
|
||||
|
||||
if svg_component is None:
|
||||
return component.get("position")
|
||||
component_position = x_y_from_transform(svg_component.get("transform"))
|
||||
if not component_position:
|
||||
return None
|
||||
return component.get("position")
|
||||
|
||||
if pin_designator:
|
||||
pin = None
|
||||
@ -198,6 +232,37 @@ def position_of_element(
|
||||
return component_position
|
||||
|
||||
|
||||
def percentage_view_box(
|
||||
view_box: list[float], view_bounds: list[float], shifted: bool
|
||||
) -> list[float]:
|
||||
margin = 2.5
|
||||
sig_figs = 6
|
||||
width = view_bounds[2]
|
||||
height = view_bounds[3]
|
||||
percentage_view_box = [
|
||||
(view_box[0] - view_bounds[0]) / width * 100,
|
||||
(view_box[1] - view_bounds[1]) / height * 100,
|
||||
(view_box[2] - view_bounds[0]) / width * 100,
|
||||
(view_box[3] - view_bounds[1]) / height * 100,
|
||||
]
|
||||
if shifted:
|
||||
view_coords = [
|
||||
max(0, round(percentage_view_box[0] - margin, sig_figs)),
|
||||
max(0, round((100 - percentage_view_box[3]) - margin, sig_figs)),
|
||||
min(100, round(percentage_view_box[2] + margin, sig_figs)),
|
||||
min(100, round((100 - percentage_view_box[1]) + margin, sig_figs)),
|
||||
]
|
||||
else:
|
||||
view_coords = [
|
||||
max(0, round(percentage_view_box[0] - margin, sig_figs)),
|
||||
max(0, round(percentage_view_box[1] - margin, sig_figs)),
|
||||
min(100, round(percentage_view_box[2] + margin, sig_figs)),
|
||||
min(100, round(percentage_view_box[3] + margin, sig_figs)),
|
||||
]
|
||||
|
||||
return view_coords
|
||||
|
||||
|
||||
def format_snippet(
|
||||
view_box: list[float],
|
||||
id: str,
|
||||
@ -208,31 +273,13 @@ def format_snippet(
|
||||
dr_number: str,
|
||||
view_bounds: list[float],
|
||||
) -> str:
|
||||
margin = 2.5
|
||||
sig_figs = 6
|
||||
width = view_bounds[2] - view_bounds[0]
|
||||
height = view_bounds[3] - view_bounds[1]
|
||||
percentage_view_box = [
|
||||
(view_box[0] - view_bounds[0]) / width * 100,
|
||||
(view_box[1] - view_bounds[1]) / height * 100,
|
||||
(view_box[2] - view_bounds[0]) / width * 100,
|
||||
(view_box[3] - view_bounds[1]) / height * 100,
|
||||
]
|
||||
view_coords = [
|
||||
max(0, round(percentage_view_box[0] - margin, sig_figs)),
|
||||
max(0, round((100 - percentage_view_box[3]) - margin, sig_figs)),
|
||||
min(100, round(percentage_view_box[2] + margin, sig_figs)),
|
||||
min(100, round((100 - percentage_view_box[1]) + margin, sig_figs)),
|
||||
]
|
||||
aspect_ratio = round(
|
||||
(view_bounds[2] - view_bounds[0]) / (view_bounds[3] - view_bounds[1]), sig_figs
|
||||
)
|
||||
aspect_ratio = view_bounds[2] / view_bounds[3]
|
||||
|
||||
snippet = (
|
||||
f'!thumbnail[]({file_path}){"{"} diff="{repo}:{base_commit}...{head_commit}" '
|
||||
f'pr="{dr_number}" is-added=true doc-id="{id}" diff-visibility="full" variant="default" '
|
||||
f'view-coords="{view_coords[0]:.2f},{view_coords[1]:.2f},{view_coords[2]:.2f},{view_coords[3]:.2f}" '
|
||||
f'aspect-ratio="{aspect_ratio}" '
|
||||
f'view-coords="{view_box[0]:.2f},{view_box[1]:.2f},{view_box[2]:.2f},{view_box[3]:.2f}" '
|
||||
f'aspect-ratio="{aspect_ratio:.2f}" '
|
||||
'}'
|
||||
)
|
||||
|
||||
@ -276,12 +323,15 @@ def into_review_comment(
|
||||
if elements:
|
||||
elements = elements.split(", ")
|
||||
|
||||
if ir_page and svg_page:
|
||||
if ir_page and (svg_page is not None):
|
||||
page_view_bounds = find_page_viewbox(svg_page, y_shift)
|
||||
positions: list[Position] = []
|
||||
|
||||
for element in elements:
|
||||
if pos := position_of_element(element, ir_page):
|
||||
if pos := position_of_element(element, ir_page, svg_page):
|
||||
# 🤷♂️
|
||||
if y_shift != 0:
|
||||
pos["y"] = -pos["y"]
|
||||
positions.append(pos)
|
||||
|
||||
if positions:
|
||||
@ -290,6 +340,11 @@ def into_review_comment(
|
||||
min_y = min([pos["y"] for pos in positions])
|
||||
max_y = max([pos["y"] for pos in positions])
|
||||
view_box = [min_x, min_y, max_x, max_y]
|
||||
view_box = percentage_view_box(
|
||||
view_box,
|
||||
page_view_bounds,
|
||||
y_shift != 0,
|
||||
)
|
||||
snippet = format_snippet(
|
||||
view_box,
|
||||
ir_page["id"],
|
||||
|
Loading…
Reference in New Issue
Block a user