mirror of
https://github.com/gumyr/build123d.git
synced 2025-12-06 02:30:55 -08:00
Fixed typing problems
This commit is contained in:
parent
c0c3189b81
commit
953019a4a6
12 changed files with 90 additions and 66 deletions
3
mypy.ini
3
mypy.ini
|
|
@ -17,6 +17,9 @@ ignore_missing_imports = True
|
|||
[mypy-OCP.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-ocpsvg.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-scipy.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
|
|
|
|||
|
|
@ -174,6 +174,9 @@ operations_apply_to = {
|
|||
"thicken": ["BuildPart"],
|
||||
}
|
||||
|
||||
B = TypeVar("B", bound="Builder")
|
||||
"""Builder type hint"""
|
||||
|
||||
|
||||
class Builder(ABC):
|
||||
"""Builder
|
||||
|
|
@ -318,10 +321,10 @@ class Builder(ABC):
|
|||
|
||||
@classmethod
|
||||
def _get_context(
|
||||
cls,
|
||||
cls: Type[B],
|
||||
caller: Builder | Shape | Joint | str | None = None,
|
||||
log: bool = True,
|
||||
) -> Builder | None:
|
||||
) -> B | None:
|
||||
"""Return the instance of the current builder"""
|
||||
result = cls._current.get(None)
|
||||
context_name = "None" if result is None else type(result).__name__
|
||||
|
|
@ -335,7 +338,7 @@ class Builder(ABC):
|
|||
caller_name = "None"
|
||||
logger.info("%s context requested by %s", context_name, caller_name)
|
||||
|
||||
return result
|
||||
return cast(B, result)
|
||||
|
||||
def _add_to_context(
|
||||
self,
|
||||
|
|
|
|||
|
|
@ -69,24 +69,28 @@ class BuildLine(Builder):
|
|||
_shape = Edge # Type of shapes being constructed
|
||||
_sub_class = Curve # Class of line/_obj
|
||||
|
||||
@property
|
||||
def _obj(self) -> Curve:
|
||||
return self.line
|
||||
|
||||
@_obj.setter
|
||||
def _obj(self, value: Curve) -> None:
|
||||
self.line = value
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
workplane: Face | Plane | Location = Plane.XY,
|
||||
mode: Mode = Mode.ADD,
|
||||
):
|
||||
self.line: Curve = None
|
||||
self._line: Curve | None = None
|
||||
super().__init__(workplane, mode=mode)
|
||||
if len(self.workplanes) > 1:
|
||||
raise ValueError("BuildLine only accepts one workplane")
|
||||
|
||||
@property
|
||||
def line(self) -> Curve | None:
|
||||
"""Get the current line"""
|
||||
return self._line
|
||||
|
||||
@line.setter
|
||||
def line(self, value: Curve) -> None:
|
||||
"""Set the current line"""
|
||||
self._line = value
|
||||
|
||||
_obj = line # Alias _obj to line
|
||||
|
||||
def __exit__(self, exception_type, exception_value, traceback):
|
||||
"""Upon exiting restore context and send object to parent"""
|
||||
self._current.reset(self._reset_tok)
|
||||
|
|
@ -126,6 +130,6 @@ class BuildLine(Builder):
|
|||
"""solid() not implemented"""
|
||||
raise NotImplementedError("solid() doesn't apply to BuildLine")
|
||||
|
||||
def _add_to_pending(self, *objects: Edge | Face, face_plane: Plane = None):
|
||||
def _add_to_pending(self, *objects: Edge | Face, face_plane: Plane | None = None):
|
||||
"""_add_to_pending not implemented"""
|
||||
raise NotImplementedError("_add_to_pending doesn't apply to BuildLine")
|
||||
|
|
|
|||
|
|
@ -63,14 +63,27 @@ class BuildSketch(Builder):
|
|||
_shape = Face # Type of shapes being constructed
|
||||
_sub_class = Sketch # Class of sketch/_obj
|
||||
|
||||
@property
|
||||
def _obj(self) -> Sketch:
|
||||
"""The builder's object"""
|
||||
return self.sketch_local
|
||||
def __init__(
|
||||
self,
|
||||
*workplanes: Face | Plane | Location,
|
||||
mode: Mode = Mode.ADD,
|
||||
):
|
||||
self.mode = mode
|
||||
self._sketch_local: Sketch | None = None
|
||||
self.pending_edges: ShapeList[Edge] = ShapeList()
|
||||
super().__init__(*workplanes, mode=mode)
|
||||
|
||||
@_obj.setter
|
||||
def _obj(self, value: Sketch) -> None:
|
||||
self.sketch_local = value
|
||||
@property
|
||||
def sketch_local(self) -> Sketch | None:
|
||||
"""Get the builder's object"""
|
||||
return self._sketch_local
|
||||
|
||||
@sketch_local.setter
|
||||
def sketch_local(self, value: Sketch) -> None:
|
||||
"""Set the builder's object"""
|
||||
self._sketch_local = value
|
||||
|
||||
_obj = sketch_local # Alias _obj to sketch_local
|
||||
|
||||
@property
|
||||
def sketch(self):
|
||||
|
|
@ -85,16 +98,6 @@ class BuildSketch(Builder):
|
|||
global_objs.append(plane.from_local_coords(self._obj))
|
||||
return Sketch(Compound(global_objs).wrapped)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*workplanes: Face | Plane | Location,
|
||||
mode: Mode = Mode.ADD,
|
||||
):
|
||||
self.mode = mode
|
||||
self.sketch_local: Sketch = None
|
||||
self.pending_edges: ShapeList[Edge] = ShapeList()
|
||||
super().__init__(*workplanes, mode=mode)
|
||||
|
||||
def solids(self, *args):
|
||||
"""solids() not implemented"""
|
||||
raise NotImplementedError("solids() doesn't apply to BuildSketch")
|
||||
|
|
@ -108,7 +111,7 @@ class BuildSketch(Builder):
|
|||
wires = Wire.combine(self.pending_edges)
|
||||
return wires if len(wires) > 1 else wires[0]
|
||||
|
||||
def _add_to_pending(self, *objects: Edge, face_plane: Plane = None):
|
||||
def _add_to_pending(self, *objects: Edge, face_plane: Plane | None = None):
|
||||
"""Integrate a sequence of objects into existing builder object"""
|
||||
if face_plane:
|
||||
raise NotImplementedError("face_plane arg not supported for this method")
|
||||
|
|
|
|||
|
|
@ -108,10 +108,11 @@ def import_brep(file_name: PathLike | str | bytes) -> Shape:
|
|||
shape = TopoDS_Shape()
|
||||
builder = BRep_Builder()
|
||||
|
||||
BRepTools.Read_s(shape, fsdecode(file_name), builder)
|
||||
file_name_str = fsdecode(file_name)
|
||||
BRepTools.Read_s(shape, file_name_str, builder)
|
||||
|
||||
if shape.IsNull():
|
||||
raise ValueError(f"Could not import {file_name}")
|
||||
raise ValueError(f"Could not import {file_name_str}")
|
||||
|
||||
return Compound.cast(shape)
|
||||
|
||||
|
|
@ -219,7 +220,6 @@ def import_step(filename: PathLike | str | bytes) -> Compound:
|
|||
reader.Transfer(doc)
|
||||
|
||||
root = Compound()
|
||||
root.for_construction = None
|
||||
root.children = build_assembly()
|
||||
# Remove empty Compound wrapper if single free object
|
||||
if len(root.children) == 1:
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ class RigidJoint(Joint):
|
|||
to_part: Solid | Compound | None = None,
|
||||
joint_location: Location | None = None,
|
||||
):
|
||||
context: BuildPart = BuildPart._get_context(self)
|
||||
context: BuildPart | None = BuildPart._get_context(self)
|
||||
validate_inputs(context, self)
|
||||
if to_part is None:
|
||||
if context is not None:
|
||||
|
|
@ -97,6 +97,8 @@ class RigidJoint(Joint):
|
|||
if joint_location is None:
|
||||
joint_location = Location()
|
||||
|
||||
if part_or_builder.location is None:
|
||||
raise ValueError("Part must have a location")
|
||||
self.relative_location = part_or_builder.location.inverse() * joint_location
|
||||
part_or_builder.joints[label] = self
|
||||
super().__init__(label, part_or_builder)
|
||||
|
|
@ -269,7 +271,7 @@ class RevoluteJoint(Joint):
|
|||
angle_reference: VectorLike | None = None,
|
||||
angular_range: tuple[float, float] = (0, 360),
|
||||
):
|
||||
context: BuildPart = BuildPart._get_context(self)
|
||||
context: BuildPart | None = BuildPart._get_context(self)
|
||||
validate_inputs(context, self)
|
||||
if to_part is None:
|
||||
if context is not None:
|
||||
|
|
@ -287,6 +289,8 @@ class RevoluteJoint(Joint):
|
|||
else:
|
||||
self.angle_reference = Plane(origin=(0, 0, 0), z_dir=axis.direction).x_dir
|
||||
self._angle: float | None = None
|
||||
if part_or_builder.location is None:
|
||||
raise ValueError("Part must have a location")
|
||||
self.relative_axis = axis.located(part_or_builder.location.inverse())
|
||||
part_or_builder.joints[label] = self
|
||||
super().__init__(label, part_or_builder)
|
||||
|
|
@ -384,7 +388,7 @@ class LinearJoint(Joint):
|
|||
axis: Axis = Axis.Z,
|
||||
linear_range: tuple[float, float] = (0, inf),
|
||||
):
|
||||
context: BuildPart = BuildPart._get_context(self)
|
||||
context: BuildPart | None = BuildPart._get_context(self)
|
||||
validate_inputs(context, self)
|
||||
if to_part is None:
|
||||
if context is not None:
|
||||
|
|
@ -396,6 +400,8 @@ class LinearJoint(Joint):
|
|||
self.axis = axis
|
||||
self.linear_range = linear_range
|
||||
self.position = None
|
||||
if part_or_builder.location is None:
|
||||
raise ValueError("Part must have a location")
|
||||
self.relative_axis = axis.located(part_or_builder.location.inverse())
|
||||
self.angle = None
|
||||
part_or_builder.joints[label] = self
|
||||
|
|
@ -571,7 +577,7 @@ class CylindricalJoint(Joint):
|
|||
linear_range: tuple[float, float] = (0, inf),
|
||||
angular_range: tuple[float, float] = (0, 360),
|
||||
):
|
||||
context: BuildPart = BuildPart._get_context(self)
|
||||
context: BuildPart | None = BuildPart._get_context(self)
|
||||
validate_inputs(context, self)
|
||||
if to_part is None:
|
||||
if context is not None:
|
||||
|
|
@ -591,6 +597,8 @@ class CylindricalJoint(Joint):
|
|||
self.angle_reference = Plane(origin=(0, 0, 0), z_dir=axis.direction).x_dir
|
||||
self.angular_range = angular_range
|
||||
self.linear_range = linear_range
|
||||
if part_or_builder.location is None:
|
||||
raise ValueError("Part must have a location")
|
||||
self.relative_axis = axis.located(part_or_builder.location.inverse())
|
||||
self.position: float | None = None
|
||||
self.angle: float | None = None
|
||||
|
|
@ -733,7 +741,7 @@ class BallJoint(Joint):
|
|||
] = ((0, 360), (0, 360), (0, 360)),
|
||||
angle_reference: Plane = Plane.XY,
|
||||
):
|
||||
context: BuildPart = BuildPart._get_context(self)
|
||||
context: BuildPart | None = BuildPart._get_context(self)
|
||||
validate_inputs(context, self)
|
||||
if to_part is None:
|
||||
if context is not None:
|
||||
|
|
@ -745,6 +753,8 @@ class BallJoint(Joint):
|
|||
if joint_location is None:
|
||||
joint_location = Location()
|
||||
|
||||
if part_or_builder.location is None:
|
||||
raise ValueError("Part must have a location")
|
||||
self.relative_location = part_or_builder.location.inverse() * joint_location
|
||||
part_or_builder.joints[label] = self
|
||||
self.angular_range = angular_range
|
||||
|
|
|
|||
|
|
@ -86,10 +86,10 @@ import ctypes
|
|||
import math
|
||||
import os
|
||||
import sys
|
||||
import uuid
|
||||
import warnings
|
||||
from os import PathLike, fsdecode
|
||||
from typing import Union
|
||||
from uuid import UUID
|
||||
|
||||
from collections.abc import Iterable
|
||||
|
||||
|
|
@ -295,6 +295,8 @@ class Mesher:
|
|||
ocp_mesh_vertices.append(pnt)
|
||||
|
||||
# Store the triangles from the triangulated faces
|
||||
if facet.wrapped is None:
|
||||
continue
|
||||
facet_reversed = facet.wrapped.Orientation() == ta.TopAbs_REVERSED
|
||||
order = [1, 3, 2] if facet_reversed else [1, 2, 3]
|
||||
for tri in poly_triangulation.Triangles():
|
||||
|
|
@ -305,7 +307,7 @@ class Mesher:
|
|||
@staticmethod
|
||||
def _create_3mf_mesh(
|
||||
ocp_mesh_vertices: list[tuple[float, float, float]],
|
||||
triangles: list[list[int, int, int]],
|
||||
triangles: list[list[int]],
|
||||
):
|
||||
# Round off the vertices to avoid vertices within tolerance being
|
||||
# considered as different vertices
|
||||
|
|
@ -337,7 +339,7 @@ class Mesher:
|
|||
# Remove degenerate triangles
|
||||
if len(set(mapped_indices)) != 3:
|
||||
continue
|
||||
c_array = (ctypes.c_uint * 3)(*mapped_indices)
|
||||
c_array = (ctypes.c_uint * 3)(*mapped_indices) # type: ignore[assignment]
|
||||
triangles_3mf.append(Lib3MF.Triangle(c_array))
|
||||
|
||||
return (vertices_3mf, triangles_3mf)
|
||||
|
|
@ -360,8 +362,8 @@ class Mesher:
|
|||
linear_deflection: float = 0.001,
|
||||
angular_deflection: float = 0.1,
|
||||
mesh_type: MeshType = MeshType.MODEL,
|
||||
part_number: str = None,
|
||||
uuid_value: uuid = None,
|
||||
part_number: str | None = None,
|
||||
uuid_value: UUID | None = None,
|
||||
):
|
||||
"""add_shape
|
||||
|
||||
|
|
@ -507,7 +509,6 @@ class Mesher:
|
|||
|
||||
# Extract 3MF meshes and translate to OCP meshes
|
||||
mesh_iterator: Lib3MF.MeshObjectIterator = self.model.GetMeshObjects()
|
||||
self.meshes: list[Lib3MF.MeshObject]
|
||||
for _i in range(mesh_iterator.Count()):
|
||||
mesh_iterator.MoveNext()
|
||||
self.meshes.append(mesh_iterator.GetCurrentMeshObject())
|
||||
|
|
|
|||
|
|
@ -164,6 +164,8 @@ def extrude(
|
|||
target_object = context.part
|
||||
else:
|
||||
target_object = target
|
||||
if target_object is None:
|
||||
raise ValueError("No target object provided")
|
||||
|
||||
new_solids.append(
|
||||
Solid.extrude_until(
|
||||
|
|
@ -509,7 +511,7 @@ def section(
|
|||
|
||||
if obj is not None:
|
||||
to_section = obj
|
||||
elif context is not None:
|
||||
elif context is not None and context.part is not None:
|
||||
to_section = context.part
|
||||
else:
|
||||
raise ValueError("No object to section")
|
||||
|
|
|
|||
|
|
@ -437,7 +437,7 @@ class Mixin1D(Shape):
|
|||
|
||||
return result
|
||||
|
||||
def edge(self) -> Edge:
|
||||
def edge(self) -> Edge | None:
|
||||
"""Return the Edge"""
|
||||
return Shape.get_single_shape(self, "Edge")
|
||||
|
||||
|
|
@ -1086,7 +1086,7 @@ class Mixin1D(Shape):
|
|||
|
||||
return Vector(gp_Dir(res))
|
||||
|
||||
def vertex(self) -> Vertex:
|
||||
def vertex(self) -> Vertex | None:
|
||||
"""Return the Vertex"""
|
||||
return Shape.get_single_shape(self, "Vertex")
|
||||
|
||||
|
|
@ -1094,7 +1094,7 @@ class Mixin1D(Shape):
|
|||
"""vertices - all the vertices in this Shape"""
|
||||
return Shape.get_shape_list(self, "Vertex")
|
||||
|
||||
def wire(self) -> Wire:
|
||||
def wire(self) -> Wire | None:
|
||||
"""Return the Wire"""
|
||||
return Shape.get_single_shape(self, "Wire")
|
||||
|
||||
|
|
|
|||
|
|
@ -576,7 +576,7 @@ class Mixin3D(Shape):
|
|||
|
||||
return offset_solid
|
||||
|
||||
def solid(self) -> Solid:
|
||||
def solid(self) -> Solid | None:
|
||||
"""Return the Solid"""
|
||||
return Shape.get_single_shape(self, "Solid")
|
||||
|
||||
|
|
@ -1043,9 +1043,7 @@ class Solid(Mixin3D, Shape[TopoDS_Solid]):
|
|||
)
|
||||
|
||||
@classmethod
|
||||
def make_loft(
|
||||
cls, objs: Iterable[Vertex | Wire], ruled: bool = False
|
||||
) -> Solid:
|
||||
def make_loft(cls, objs: Iterable[Vertex | Wire], ruled: bool = False) -> Solid:
|
||||
"""make loft
|
||||
|
||||
Makes a loft from a list of wires and vertices. Vertices can appear only at the
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ class Mixin2D(Shape):
|
|||
|
||||
return new_surface
|
||||
|
||||
def face(self) -> Face:
|
||||
def face(self) -> Face | None:
|
||||
"""Return the Face"""
|
||||
return Shape.get_single_shape(self, "Face")
|
||||
|
||||
|
|
@ -246,7 +246,7 @@ class Mixin2D(Shape):
|
|||
"""Return a copy of self moved along the normal by amount"""
|
||||
return copy.deepcopy(self).moved(Location(self.normal_at() * amount))
|
||||
|
||||
def shell(self) -> Shell:
|
||||
def shell(self) -> Shell | None:
|
||||
"""Return the Shell"""
|
||||
return Shape.get_single_shape(self, "Shell")
|
||||
|
||||
|
|
@ -1191,10 +1191,15 @@ class Face(Mixin2D, Shape[TopoDS_Face]):
|
|||
intersected_shapes.append(Shell(topods_shell))
|
||||
|
||||
intersected_shapes = intersected_shapes.sort_by(Axis(self.center(), direction))
|
||||
intersected_shapes = ShapeList(
|
||||
s.face() if len(s.faces()) == 1 else s for s in intersected_shapes
|
||||
)
|
||||
return intersected_shapes
|
||||
projected_shapes: ShapeList[Face | Shell] = ShapeList()
|
||||
for shape in intersected_shapes:
|
||||
if len(shape.faces()) == 1:
|
||||
shape_face = shape.face()
|
||||
if shape_face is not None:
|
||||
projected_shapes.append(shape_face)
|
||||
else:
|
||||
projected_shapes.append(shape)
|
||||
return projected_shapes
|
||||
|
||||
def to_arcs(self, tolerance: float = 1e-3) -> Face:
|
||||
"""to_arcs
|
||||
|
|
@ -1306,9 +1311,7 @@ class Shell(Mixin2D, Shape[TopoDS_Shell]):
|
|||
return Shell(TopoDS.Shell_s(_extrude_topods_shape(obj.wrapped, direction)))
|
||||
|
||||
@classmethod
|
||||
def make_loft(
|
||||
cls, objs: Iterable[Vertex | Wire], ruled: bool = False
|
||||
) -> Shell:
|
||||
def make_loft(cls, objs: Iterable[Vertex | Wire], ruled: bool = False) -> Shell:
|
||||
"""make loft
|
||||
|
||||
Makes a loft from a list of wires and vertices. Vertices can appear only at the
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ license:
|
|||
from __future__ import annotations
|
||||
|
||||
from math import radians, sin, cos, isclose
|
||||
from typing import Any, Union, TYPE_CHECKING
|
||||
from typing import Any, TYPE_CHECKING
|
||||
|
||||
from collections.abc import Iterable
|
||||
|
||||
|
|
@ -91,9 +91,6 @@ from .shape_core import Shape, ShapeList, downcast, shapetype, unwrap_topods_com
|
|||
if TYPE_CHECKING: # pragma: no cover
|
||||
from .zero_d import Vertex # pylint: disable=R0801
|
||||
from .one_d import Edge, Wire # pylint: disable=R0801
|
||||
from .two_d import Face, Shell # pylint: disable=R0801
|
||||
from .three_d import Solid # pylint: disable=R0801
|
||||
from .composite import Compound, Curve, Sketch, Part # pylint: disable=R0801
|
||||
|
||||
|
||||
def _extrude_topods_shape(obj: TopoDS_Shape, direction: VectorLike) -> TopoDS_Shape:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue