Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 34 additions & 4 deletions src/papermodels/datatypes/geometry_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import networkx as nx
import hashlib
import json
from warnings import warn

from papermodels.datatypes.element import (
Element,
Expand Down Expand Up @@ -73,6 +74,7 @@ def __init__(
self,
process_gravity_frame: bool = True,
cantilever_abs_tol: Optional[float] = 0.2,
suppress_warnings: bool = False,
):
super().__init__()
self.process_gravity_frame = process_gravity_frame
Expand All @@ -84,6 +86,7 @@ def __init__(
self.pdf_path = None
self.omitted = {}
self.cantilever_abs_tol: Optional[float] = cantilever_abs_tol
self.suppress_warnings = suppress_warnings

@property
def collector_elements(self):
Expand Down Expand Up @@ -129,12 +132,15 @@ def from_elements(
intersection_rules: Optional[list[Rule | callable]] = [
TRANSFER_LINES_CANNOT_INTERSECT_WITH_LINEAR_POLYGONS
],
suppress_warnings: bool = False,
) -> GeometryGraph:
"""
Returns a GeometryGraph (networkx.DiGraph) based upon the intersections and correspondents
of the 'elements'.
"""
g = cls(cantilever_abs_tol=cantilever_abs_tol)
g = cls(
cantilever_abs_tol=cantilever_abs_tol, suppress_warnings=suppress_warnings
)
elements_copy = deepcopy(elements)
if intersection_rules is None:
intersection_rules = []
Expand Down Expand Up @@ -384,11 +390,13 @@ def add_intersection_indexes_below(self):
orphaned_nodes = self.orphaned_elements
self.omitted = {} # Used when generated collectors only have one support
for node in sorted_nodes:
if node in orphaned_nodes:
continue
node_attrs = self.nodes[node]
element: Element = node_attrs["element"]
dependents = list(self.successors(node))
if node in orphaned_nodes and element.geometry.geom_type == "LineString":
if len(dependents) < 2 and not self.suppress_warnings:
warn(f"Orphaned element {element.tag}: only has one support.")
continue
dependent_intersections = get_dependent_intersections(element, dependents)
dependent_correspondents = get_dependent_correspondents(element, dependents)
if not dependent_intersections and not dependent_correspondents:
Expand Down Expand Up @@ -451,13 +459,22 @@ def add_intersection_indexes_below(self):
subextents = subelem.get_collector_extents()
except geom.GeometryError:
self.omitted.update({sub_id: subelem})
if not self.suppress_warnings:
warn(
f"This element generated a GeometryError: {sub_id}"
)
continue

sub_sorted_below_ints = sorted(
sub_local_coords, key=lambda x: x[0]
)
if len(sub_sorted_below_ints) < 2:
self.omitted.update({sub_id: subelem})
if not self.suppress_warnings:
warn(
f"It seems that this subelement only has one support: {sub_id}\n"
"This is likely due to a floating point error at the edge of one of the supports.\n"
)
continue

# raise ValueError(
Expand Down Expand Up @@ -727,6 +744,7 @@ def from_dxf_file(
progress: bool = False,
process_gravity_frame: bool = True,
show_skipped: bool = False,
suppress_warnings: bool = False,
):
"""
Returns a GeometryGraph built from the geometric entities (LINE, LWPOLYLINE, INSERT)
Expand All @@ -743,6 +761,7 @@ def from_dxf_file(
'process_gravity_frame': Processes the geometry for a gravity frame by fully
resolving in-plane connectivity
'show_skipped': Shows the skipped annotations that occured during pdf.load_pdf_annotations
'suppress_warnings': Do not show user warnings during post-processing
"""
if isinstance(legend_table, (str, pathlib.Path)):
legend_table_path = pathlib.Path(legend_table)
Expand Down Expand Up @@ -810,7 +829,11 @@ def from_dxf_file(
elements = Element.from_parsed_annotations(
structural_element_entries, trib_area_entries
)
graph = cls.from_elements(elements, process_gravity_frame=process_gravity_frame)
graph = cls.from_elements(
elements,
process_gravity_frame=process_gravity_frame,
suppress_warnings=suppress_warnings,
)
graph.parsed_annotations = tag_parsed_annotations(parsed_annotations)
graph.raw_annotations = tag_parsed_annotations(raw_annotations)
graph.legend_entries = {}
Expand Down Expand Up @@ -883,6 +906,7 @@ def from_pdf_file(
tag_pdf_file_mode: str = "append",
show_skipped: bool = False,
show_unimplemented: bool = False,
suppress_warnings: bool = False,
):
"""
Returns a GeometryGraph built from that annotations in the provided PDF file
Expand Down Expand Up @@ -917,6 +941,7 @@ def from_pdf_file(
'show_skipped': Shows the skipped annotations that occured during pdf.load_pdf_annotations
'show_unimplemented': Shows the annotations that were read but are not implemented in the
parser yet.
'suppress_warnings': Do not show user warnings during post-processing
"""
annotations = pdf.load_pdf_annotations(
pdf_filepath, show_skipped, show_unimplemented
Expand All @@ -927,6 +952,7 @@ def from_pdf_file(
scale=scale,
process_gravity_frame=process_gravity_frame,
cantilever_abs_tol=cantilever_abs_tol,
suppress_warnings=suppress_warnings,
)
graph.pdf_path = pathlib.Path(pdf_filepath).resolve()
return graph
Expand All @@ -943,6 +969,7 @@ def from_annotations(
debug: bool = False,
progress: bool = False,
process_gravity_frame: bool = False,
suppress_warnings: bool = False,
):
"""
Returns a GeometryGraph built from the provided annotations.
Expand Down Expand Up @@ -973,6 +1000,8 @@ def from_annotations(
'progress': When True, a progress bar will be displayed
'process_gravity_frame': Processes the geometry for a gravity frame by fully
resolving in-plane connectivity
'suppress_warnings': Do not show user warnings when performing gravity frame
post-processing
"""
annots = annotations
page_ids = sorted(set([annot.page for annot in annots]), reverse=True)
Expand Down Expand Up @@ -1052,6 +1081,7 @@ def from_annotations(
elements,
cantilever_abs_tol=cantilever_abs_tol,
process_gravity_frame=process_gravity_frame,
suppress_warnings=suppress_warnings,
)
graph.parsed_annotations = tag_parsed_annotations(parsed_annotations_acc)
graph.raw_annotations = tag_parsed_annotations(raw_annotations_acc)
Expand Down
36 changes: 32 additions & 4 deletions src/papermodels/datatypes/joist_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -667,11 +667,39 @@ def get_extent_edge(self, edge: str = "start"):
'edge': one of {'start', 'end'}
"""
if edge == "start":
node_i = self._extents[0][0]
node_j = self._extents[1][0]
try:
node_i = self._extents[0][0]
except IndexError:
raise geom_ops.GeometryError(
f"The collector element {self.element.tag} seems to have only one support (at the end of the member).\n"
"Please review the geometry and correct it in your source sketch by ensuring the element extends past"
" the centerline of the supporting element."
)
try:
node_j = self._extents[1][0]
except IndexError:
raise geom_ops.GeometryError(
f"The collector element {self.element.tag} seems to have only one support (at the start of the member).\n"
"Please review the geometry and correct it in your source sketch by ensuring the element extends past"
" the centerline of the supporting element."
)
elif edge == "end":
node_i = self._extents[0][1]
node_j = self._extents[1][1]
try:
node_i = self._extents[0][1]
except IndexError:
raise geom_ops.GeometryError(
f"The collector element {self.element.tag} seems to have only one support (at the end of the member).\n"
"Please review the geometry and correct it in your source sketch by ensuring the element extends past"
" the centerline of the supporting element."
)
try:
node_j = self._extents[1][1]
except IndexError:
raise geom_ops.GeometryError(
f"The collector element {self.element.tag} seems to have only one support (at the start of the member).\n"
"Please review the geometry and correct it in your source sketch by ensuring the element extends past"
" the centerline of the supporting element."
)
return LineString([node_i, node_j])

def get_joist_trib_widths(self, index) -> tuple[float, float]:
Expand Down