Merge pull request #783 from erooke/housekeeping

Housekeeping
This commit is contained in:
Roger Maitland 2024-11-14 10:39:33 -05:00 committed by GitHub
commit 4c43b22bb0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 137 additions and 69 deletions

View file

@ -386,7 +386,7 @@ class Builder(ABC):
x_dir=(1, 0, 0),
z_dir=new_face.normal_at(),
)
except:
except Exception:
plane = Plane(origin=(0, 0, 0), z_dir=new_face.normal_at())
new_face = plane.to_local_coords(new_face)
@ -521,7 +521,10 @@ class Builder(ABC):
all_vertices = self.vertices(select)
vertex_count = len(all_vertices)
if vertex_count != 1:
warnings.warn(f"Found {vertex_count} vertices, returning first")
warnings.warn(
f"Found {vertex_count} vertices, returning first",
stacklevel=2,
)
return all_vertices[0]
def edges(self, select: Select = Select.ALL) -> ShapeList[Edge]:
@ -561,7 +564,10 @@ class Builder(ABC):
all_edges = self.edges(select)
edge_count = len(all_edges)
if edge_count != 1:
warnings.warn(f"Found {edge_count} edges, returning first")
warnings.warn(
f"Found {edge_count} edges, returning first",
stacklevel=2,
)
return all_edges[0]
def wires(self, select: Select = Select.ALL) -> ShapeList[Wire]:
@ -601,7 +607,10 @@ class Builder(ABC):
all_wires = self.wires(select)
wire_count = len(all_wires)
if wire_count != 1:
warnings.warn(f"Found {wire_count} wires, returning first")
warnings.warn(
f"Found {wire_count} wires, returning first",
stacklevel=2,
)
return all_wires[0]
def faces(self, select: Select = Select.ALL) -> ShapeList[Face]:
@ -641,7 +650,10 @@ class Builder(ABC):
all_faces = self.faces(select)
face_count = len(all_faces)
if face_count != 1:
warnings.warn(f"Found {face_count} faces, returning first")
warnings.warn(
f"Found {face_count} faces, returning first",
stacklevel=2,
)
return all_faces[0]
def solids(self, select: Select = Select.ALL) -> ShapeList[Solid]:
@ -681,7 +693,10 @@ class Builder(ABC):
all_solids = self.solids(select)
solid_count = len(all_solids)
if solid_count != 1:
warnings.warn(f"Found {solid_count} solids, returning first")
warnings.warn(
f"Found {solid_count} solids, returning first",
stacklevel=2,
)
return all_solids[0]
def _shapes(self, obj_type: Union[Vertex, Edge, Face, Solid] = None) -> ShapeList:
@ -1291,7 +1306,7 @@ T2 = TypeVar("T2")
def __gen_context_component_getter(
func: Callable[Concatenate[Builder, P], T2]
func: Callable[Concatenate[Builder, P], T2],
) -> Callable[P, T2]:
@functools.wraps(func)
def getter(select: Select = Select.ALL):

View file

@ -30,10 +30,10 @@ from __future__ import annotations
from typing import Union
from build123d.build_common import Builder, WorkplaneList, logger
from build123d.build_common import Builder, WorkplaneList
from build123d.build_enums import Mode
from build123d.geometry import Location, Plane
from build123d.topology import Compound, Edge, Face, ShapeList, Sketch, Wire, Vertex
from build123d.topology import Compound, Edge, Face, ShapeList, Sketch, Wire
class BuildSketch(Builder):

View file

@ -620,7 +620,7 @@ class TechnicalDrawing(BaseSketchObject):
def __init__(
self,
designed_by: str = "build123d",
design_date: date = date.today(),
design_date: Optional[date] = None,
page_size: PageSize = PageSize.A4,
title: str = "Title",
sub_title: str = "Sub Title",
@ -633,6 +633,9 @@ class TechnicalDrawing(BaseSketchObject):
):
# pylint: disable=too-many-locals
if design_date is None:
design_date = date.today()
page_dim = TechnicalDrawing.page_sizes[page_size]
# Frame
frame_width = page_dim[0] - 2 * TechnicalDrawing.margin - 2 * nominal_text_size

View file

@ -124,7 +124,7 @@ def _create_xde(to_export: Shape, unit: Unit = Unit.MM) -> TDocStd_Document:
elif isinstance(node, Curve):
explorer = TopExp_Explorer(node.wrapped, ta.TopAbs_EDGE)
else:
warnings.warn("Unknown Compound type, color not set")
warnings.warn("Unknown Compound type, color not set", stacklevel=2)
explorer = TopExp_Explorer() # don't know what to look for
while explorer.More():

View file

@ -51,14 +51,12 @@ from typing import (
overload,
TypeVar,
)
from typing_extensions import deprecated
from OCP.Bnd import Bnd_Box, Bnd_OBB
from OCP.BRep import BRep_Tool
from OCP.BRepBndLib import BRepBndLib
from OCP.BRepBuilderAPI import BRepBuilderAPI_MakeFace
from OCP.BRepGProp import BRepGProp, BRepGProp_Face # used for mass calculation
from OCP.BRepMesh import BRepMesh_IncrementalMesh
from OCP.BRepTools import BRepTools
from OCP.Geom import Geom_BoundedSurface, Geom_Line, Geom_Plane
from OCP.GeomAPI import GeomAPI_ProjectPointOnSurf, GeomAPI_IntCS, GeomAPI_IntSS

View file

@ -34,7 +34,6 @@ from math import degrees
from pathlib import Path
from typing import TextIO, Union, Optional
import OCP.IFSelect
from OCP.BRep import BRep_Builder
from OCP.BRepGProp import BRepGProp
from OCP.BRepTools import BRepTools
@ -42,7 +41,6 @@ from OCP.GProp import GProp_GProps
from OCP.Quantity import Quantity_ColorRGBA
from OCP.RWStl import RWStl
from OCP.STEPCAFControl import STEPCAFControl_Reader
from OCP.STEPControl import STEPControl_Reader
from OCP.TCollection import TCollection_AsciiString, TCollection_ExtendedString
from OCP.TDataStd import TDataStd_Name
from OCP.TDF import TDF_Label, TDF_LabelSequence

View file

@ -29,7 +29,7 @@ license:
from __future__ import annotations
from math import inf
from typing import Union, overload
from typing import Optional, Union, overload
from build123d.build_common import validate_inputs
from build123d.build_enums import Align
@ -75,8 +75,8 @@ class RigidJoint(Joint):
def __init__(
self,
label: str,
to_part: Union[Solid, Compound] = None,
joint_location: Location = Location(),
to_part: Optional[Union[Solid, Compound]] = None,
joint_location: Union[Location, None] = None,
):
context: BuildPart = BuildPart._get_context(self)
validate_inputs(context, self)
@ -86,6 +86,9 @@ class RigidJoint(Joint):
else:
raise ValueError("Either specify to_part or place in BuildPart scope")
if joint_location is None:
joint_location = Location()
self.relative_location = to_part.location.inverse() * joint_location
to_part.joints[label] = self
super().__init__(label, to_part)
@ -677,8 +680,8 @@ class BallJoint(Joint):
def __init__(
self,
label: str,
to_part: Union[Solid, Compound] = None,
joint_location: Location = Location(),
to_part: Optional[Union[Solid, Compound]] = None,
joint_location: Optional[Location] = None,
angular_range: tuple[
tuple[float, float], tuple[float, float], tuple[float, float]
] = ((0, 360), (0, 360), (0, 360)),
@ -692,6 +695,9 @@ class BallJoint(Joint):
else:
raise ValueError("Either specify to_part or place in BuildPart scope")
if joint_location is None:
joint_location = Location()
self.relative_location = to_part.location.inverse() * joint_location
to_part.joints[label] = self
self.angular_range = angular_range

View file

@ -83,7 +83,6 @@ license:
# pylint: disable=no-name-in-module, import-error
import copy
import ctypes
import itertools
import math
import os
import sys
@ -103,7 +102,6 @@ from OCP.BRepMesh import BRepMesh_IncrementalMesh
from OCP.gp import gp_Pnt
import OCP.TopAbs as ta
from OCP.GProp import GProp_GProps
from OCP.ShapeFix import ShapeFix_Shape
from OCP.TopAbs import TopAbs_ShapeEnum
from OCP.TopExp import TopExp_Explorer
from OCP.TopoDS import TopoDS_Compound
@ -111,8 +109,8 @@ from OCP.TopLoc import TopLoc_Location
from py_lib3mf import Lib3MF
from build123d.build_enums import MeshType, Unit
from build123d.geometry import Color, TOLERANCE, Vector
from build123d.topology import Compound, Face, Shape, Shell, Solid, downcast
from build123d.geometry import Color, TOLERANCE
from build123d.topology import Compound, Shape, Shell, Solid, downcast
class Mesher:
@ -400,7 +398,10 @@ class Mesher:
# Skip invalid meshes
if len(ocp_mesh_vertices) < 3 or not triangles:
warnings.warn(f"Degenerate shape {b3d_shape} - skipped")
warnings.warn(
f"Degenerate shape {b3d_shape} - skipped",
stacklevel=2,
)
continue
# Create 3mf mesh inputs
@ -429,7 +430,7 @@ class Mesher:
if not mesh_3mf.IsValid():
raise RuntimeError("3mf mesh is invalid")
if not mesh_3mf.IsManifoldAndOriented():
warnings.warn("3mf mesh is not manifold")
warnings.warn("3mf mesh is not manifold", stacklevel=2)
# Add mesh to model
self.meshes.append(mesh_3mf)

View file

@ -29,7 +29,6 @@ license:
from __future__ import annotations
import copy
import warnings
from math import copysign, cos, radians, sin, sqrt
from scipy.optimize import minimize
from typing import Iterable, Union

View file

@ -618,7 +618,7 @@ def offset(
)
else:
inner_wires.append(offset_wire)
except:
except Exception:
pass
# inner wires may go beyond the outer wire so subtract faces
new_face = Face(outer_wire)

View file

@ -301,7 +301,7 @@ def make_brake_formed(
line = line.wires()[0]
elif not isinstance(line, (Edge, Wire)):
raise ValueError("line must be either a Curve, Edge or Wire")
elif context is not None and not context.pending_edges_as_wire is None:
elif context is not None and context.pending_edges_as_wire is not None:
line = context.pending_edges_as_wire
else:
raise ValueError("A line must be provided")

View file

@ -45,7 +45,6 @@ from build123d.topology import (
from build123d.geometry import Vector
from build123d.build_common import flatten_sequence, validate_inputs
from build123d.build_sketch import BuildSketch
from build123d.objects_curve import ThreePointArc
from scipy.spatial import Voronoi

View file

@ -170,7 +170,6 @@ from OCP.Geom2dAPI import Geom2dAPI_InterCurveCurve
from OCP.GeomAbs import GeomAbs_C0, GeomAbs_Intersection, GeomAbs_JoinType
from OCP.GeomAPI import (
GeomAPI_Interpolate,
GeomAPI_IntCS,
GeomAPI_PointsToBSpline,
GeomAPI_PointsToBSplineSurface,
GeomAPI_ProjectPointOnSurf,
@ -453,7 +452,7 @@ class Mixin1D:
else:
try:
pnt = Vector(position)
except:
except Exception:
raise ValueError("position must be a float or a point")
# GeomAPI_ProjectPointOnCurve only works with Edges so find
# the closest Edge if the shape has multiple Edges.
@ -1848,8 +1847,11 @@ class Shape(NodeMixin):
try:
upgrader.Build()
self.wrapped = downcast(upgrader.Shape())
except: # pylint: disable=bare-except
warnings.warn(f"Unable to clean {self}")
except Exception:
warnings.warn(
f"Unable to clean {self}",
stacklevel=2,
)
return self
def fix(self) -> Self:
@ -2207,7 +2209,10 @@ class Shape(NodeMixin):
vertices = self.vertices()
vertex_count = len(vertices)
if vertex_count != 1:
warnings.warn(f"Found {vertex_count} vertices, returning first")
warnings.warn(
f"Found {vertex_count} vertices, returning first",
stacklevel=2,
)
return vertices[0]
def edges(self) -> ShapeList[Edge]:
@ -2228,7 +2233,10 @@ class Shape(NodeMixin):
edges = self.edges()
edge_count = len(edges)
if edge_count != 1:
warnings.warn(f"Found {edge_count} edges, returning first")
warnings.warn(
f"Found {edge_count} edges, returning first",
stacklevel=2,
)
return edges[0]
def compounds(self) -> ShapeList[Compound]:
@ -2246,7 +2254,10 @@ class Shape(NodeMixin):
compounds = self.compounds()
compound_count = len(compounds)
if compound_count != 1:
warnings.warn(f"Found {compound_count} compounds, returning first")
warnings.warn(
f"Found {compound_count} compounds, returning first",
stacklevel=2,
)
return compounds[0]
def wires(self) -> ShapeList[Wire]:
@ -2258,7 +2269,10 @@ class Shape(NodeMixin):
wires = self.wires()
wire_count = len(wires)
if wire_count != 1:
warnings.warn(f"Found {wire_count} wires, returning first")
warnings.warn(
f"Found {wire_count} wires, returning first",
stacklevel=2,
)
return wires[0]
def faces(self) -> ShapeList[Face]:
@ -2274,7 +2288,7 @@ class Shape(NodeMixin):
face_count = len(faces)
if face_count != 1:
msg = f"Found {face_count} faces, returning first"
warnings.warn(msg)
warnings.warn(msg, stacklevel=2)
return faces[0]
def shells(self) -> ShapeList[Shell]:
@ -2286,7 +2300,10 @@ class Shape(NodeMixin):
shells = self.shells()
shell_count = len(shells)
if shell_count != 1:
warnings.warn(f"Found {shell_count} shells, returning first")
warnings.warn(
f"Found {shell_count} shells, returning first",
stacklevel=2,
)
return shells[0]
def solids(self) -> ShapeList[Solid]:
@ -2298,7 +2315,10 @@ class Shape(NodeMixin):
solids = self.solids()
solid_count = len(solids)
if solid_count != 1:
warnings.warn(f"Found {solid_count} solids, returning first")
warnings.warn(
f"Found {solid_count} solids, returning first",
stacklevel=2,
)
return solids[0]
@property
@ -2907,10 +2927,10 @@ class Shape(NodeMixin):
# Is left or right the inside?
perimeter_length = perimeter.length
left_perimeter_length = (
sum(e.length for e in left.edges()) if not left is None else 0
sum(e.length for e in left.edges()) if left is not None else 0
)
right_perimeter_length = (
sum(e.length for e in right.edges()) if not right is None else 0
sum(e.length for e in right.edges()) if right is not None else 0
)
left_inside = abs(perimeter_length - left_perimeter_length) < abs(
perimeter_length - right_perimeter_length
@ -3773,7 +3793,10 @@ class ShapeList(list[T]):
vertices = self.vertices()
vertex_count = len(vertices)
if vertex_count != 1:
warnings.warn(f"Found {vertex_count} vertices, returning first")
warnings.warn(
f"Found {vertex_count} vertices, returning first",
stacklevel=2,
)
return vertices[0]
def edges(self) -> ShapeList[Edge]:
@ -3785,7 +3808,10 @@ class ShapeList(list[T]):
edges = self.edges()
edge_count = len(edges)
if edge_count != 1:
warnings.warn(f"Found {edge_count} edges, returning first")
warnings.warn(
f"Found {edge_count} edges, returning first",
stacklevel=2,
)
return edges[0]
def wires(self) -> ShapeList[Wire]:
@ -3797,7 +3823,10 @@ class ShapeList(list[T]):
wires = self.wires()
wire_count = len(wires)
if wire_count != 1:
warnings.warn(f"Found {wire_count} wires, returning first")
warnings.warn(
f"Found {wire_count} wires, returning first",
stacklevel=2,
)
return wires[0]
def faces(self) -> ShapeList[Face]:
@ -3810,7 +3839,7 @@ class ShapeList(list[T]):
face_count = len(faces)
if face_count != 1:
msg = f"Found {face_count} faces, returning first"
warnings.warn(msg)
warnings.warn(msg, stacklevel=2)
return faces[0]
def shells(self) -> ShapeList[Shell]:
@ -3822,7 +3851,10 @@ class ShapeList(list[T]):
shells = self.shells()
shell_count = len(shells)
if shell_count != 1:
warnings.warn(f"Found {shell_count} shells, returning first")
warnings.warn(
f"Found {shell_count} shells, returning first",
stacklevel=2,
)
return shells[0]
def solids(self) -> ShapeList[Solid]:
@ -3834,7 +3866,10 @@ class ShapeList(list[T]):
solids = self.solids()
solid_count = len(solids)
if solid_count != 1:
warnings.warn(f"Found {solid_count} solids, returning first")
warnings.warn(
f"Found {solid_count} solids, returning first",
stacklevel=2,
)
return solids[0]
def compounds(self) -> ShapeList[Compound]:
@ -3846,7 +3881,10 @@ class ShapeList(list[T]):
compounds = self.compounds()
compound_count = len(compounds)
if compound_count != 1:
warnings.warn(f"Found {compound_count} compounds, returning first")
warnings.warn(
f"Found {compound_count} compounds, returning first",
stacklevel=2,
)
return compounds[0]
def __gt__(self, sort_by: Union[Axis, SortBy] = Axis.Z):
@ -5947,7 +5985,10 @@ class Face(Shape):
def wire(self) -> Wire:
"""Return the outerwire, generate a warning if inner_wires present"""
if self.inner_wires():
warnings.warn("Found holes, returning outer_wire")
warnings.warn(
"Found holes, returning outer_wire",
stacklevel=2,
)
return self.outer_wire()
@classmethod
@ -6718,7 +6759,6 @@ class Face(Shape):
projection = projection_faces.pop(0).fuse(*projection_faces).clean()
return projection
return target_projected_edges
def make_holes(self, interior_wires: list[Wire]) -> Face:
"""Make Holes in Face
@ -7589,8 +7629,11 @@ class Solid(Mixin3D, Shape):
.solids()
.sort_by(direction_axis)[0]
)
except: # pylint: disable=bare-except
warnings.warn("clipping error - extrusion may be incorrect")
except Exception:
warnings.warn(
"clipping error - extrusion may be incorrect",
stacklevel=2,
)
else:
extrusion_parts = [extrusion.intersect(target_object)]
for clipping_object in clipping_objects:
@ -7600,8 +7643,11 @@ class Solid(Mixin3D, Shape):
.solids()
.sort_by(direction_axis)[0]
)
except: # pylint: disable=bare-except
warnings.warn("clipping error - extrusion may be incorrect")
except Exception:
warnings.warn(
"clipping error - extrusion may be incorrect",
stacklevel=2,
)
extrusion = Shape.fuse(*extrusion_parts)
return extrusion
@ -8420,7 +8466,7 @@ class Wire(Mixin1D, Shape):
wire_builder.Build()
if not wire_builder.IsDone():
if wire_builder.Error() == BRepBuilderAPI_NonManifoldWire:
warnings.warn("Wire is non manifold")
warnings.warn("Wire is non manifold", stacklevel=2)
elif wire_builder.Error() == BRepBuilderAPI_EmptyWire:
raise RuntimeError("Wire is empty")
elif wire_builder.Error() == BRepBuilderAPI_DisconnectedWire:
@ -8653,11 +8699,11 @@ class Wire(Mixin1D, Shape):
edge1 = points_lookup[simplice[1]][0]
# Look for connecting edges between edges
if edge0 != edge1:
if not edge0 in trim_points:
if edge0 not in trim_points:
trim_points[edge0] = [simplice[0]]
else:
trim_points[edge0].append(simplice[0])
if not edge1 in trim_points:
if edge1 not in trim_points:
trim_points[edge1] = [simplice[1]]
else:
trim_points[edge1].append(simplice[1])
@ -8671,7 +8717,7 @@ class Wire(Mixin1D, Shape):
elif abs(simplice[0] - simplice[1]) != 1:
start_pnt = min(simplice.tolist())
end_pnt = max(simplice.tolist())
if not edge0 in trim_points:
if edge0 not in trim_points:
trim_points[edge0] = [start_pnt, end_pnt]
else:
trim_points[edge0].extend([start_pnt, end_pnt])
@ -8749,7 +8795,7 @@ class Wire(Mixin1D, Shape):
center_point = Vector(center)
# Project the wire on the target object
if not direction_vector is None:
if direction_vector is not None:
projection_object = BRepProj_Projection(
self.wrapped,
Shape.cast(target_object.wrapped).wrapped,

View file

@ -12,7 +12,8 @@ except Exception: # pylint: disable=broad-exception-caught
warnings.warn(
f'could not determine {__name__.split(".", maxsplit=1)[0]} package version; '
"this indicates a broken installation"
"this indicates a broken installation",
stacklevel=2,
)
del warnings

View file

@ -30,6 +30,8 @@ import math
import unittest
from datetime import date
import pytest
from build123d import (
IN,
Axis,
@ -295,13 +297,13 @@ class ExtensionLineTestCase(unittest.TestCase):
)
class TestTechnicalDrawing(unittest.TestCase):
def test_basic_drawing(self):
drawing = TechnicalDrawing(design_date=date(2023, 9, 17), sheet_number=1)
bbox = drawing.bounding_box()
self.assertGreater(bbox.size.X, 280)
self.assertGreater(bbox.size.Y, 195)
self.assertGreater(len(drawing.faces()), 110)
@pytest.mark.parametrize("design_date", [date(2023, 9, 17), None])
def test_basic_drawing(design_date):
drawing = TechnicalDrawing(design_date=design_date, sheet_number=1)
bbox = drawing.bounding_box()
assert bbox.size.X > 280
assert bbox.size.Y > 195
assert len(drawing.faces()) > 110
if __name__ == "__main__":