Skip to content

Commit

Permalink
Merge pull request #51 from cadbuildr/3d-sweep
Browse files Browse the repository at this point in the history
3d sweep
  • Loading branch information
clement91190 authored Nov 7, 2024
2 parents 14dac41 + 78b39f4 commit 79fe8ee
Show file tree
Hide file tree
Showing 18 changed files with 304 additions and 39 deletions.
6 changes: 5 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "foundation"
version = "0.0.0.12"
version = "0.0.0.13"
description = "Python core package for builder"
authors = ["Clement Jambou"]

Expand All @@ -21,3 +21,7 @@ ipykernel = "^6.29.3"
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

[tool.mypy]
# for now until cleaner examples
exclude = ["tests/examples"]
5 changes: 4 additions & 1 deletion src/foundation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,7 @@
from foundation.sketch.sketch import Sketch
from foundation.types.node import Node
from foundation.utils import show, reset_ids
from foundation.types.point_3d import Point3D
from foundation.types.types_3d.point_3d import Point3D
from foundation.types.types_3d.curve import Helix3D
from foundation.operations.sweep import Sweep
from foundation.utils_websocket import set_port
2 changes: 1 addition & 1 deletion src/foundation/finders/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
cast_to_float_parameter,
FloatParameter,
)
from foundation.types.point_3d import Point3D
from foundation.types.types_3d.point_3d import Point3D
from foundation.geometry.plane import Plane


Expand Down
2 changes: 1 addition & 1 deletion src/foundation/geometry/plane.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
cast_to_bool_parameter,
UnCastBool,
)
from foundation.types.point_3d import Point3D
from foundation.types.types_3d.point_3d import Point3D
from foundation.exceptions import (
InvalidParameterTypeException,
InvalidParameterValueException,
Expand Down
5 changes: 3 additions & 2 deletions src/foundation/operations/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
from foundation.operations.fillet import Fillet
from foundation.operations.chamfer import Chamfer
from foundation.operations.loft import Loft
from foundation.operations.sweep import Sweep
from typing import Union

operation_types_tuple = (Extrusion, Hole, Lathe, Fillet, Chamfer, Loft)
operation_types_tuple = (Extrusion, Hole, Lathe, Fillet, Chamfer, Loft, Sweep)

OperationTypes = Union[Extrusion, Hole, Lathe, Fillet, Chamfer, Loft]
OperationTypes = Union[Extrusion, Hole, Lathe, Fillet, Chamfer, Loft, Sweep]
16 changes: 11 additions & 5 deletions src/foundation/operations/extrude.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from foundation.operations.base import Operation
from foundation.types.node import Node

from foundation.sketch.base import SketchElement
from foundation.sketch.point import Point
from foundation.sketch.closed_sketch_shape import Circle, ClosedSketchShape
from foundation.types.node_children import NodeChildren
from foundation.sketch.sketch import Sketch
Expand All @@ -23,7 +23,7 @@ class ExtrusionChildren(NodeChildren):
start: FloatParameter
end: FloatParameter
cut: BoolParameter
sketch: "Sketch"
sketch: Sketch


class Extrusion(Operation, Node):
Expand Down Expand Up @@ -69,8 +69,14 @@ def get_frame(self):
# NOTE this is quite restrictive as a definition ( different type of holes for machining will need to be implemented
# including threads, profiles ... )
class Hole(Extrusion):
def __init__(self, point, radius, depth):
def __init__(
self,
point: Point,
radius: UnCastFloat,
depth: UnCastFloat,
other_depth: UnCastFloat = 0.0,
):
shape = Circle(point, radius)
super().__init__(shape=shape, end=depth, cut=True)
self.diameter = radius
super().__init__(shape=shape, end=depth, start=other_depth, cut=True)
self.diameter = cast_to_float_parameter(radius)
self.point = point
53 changes: 53 additions & 0 deletions src/foundation/operations/sweep.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# TODO
from foundation.operations.base import Operation
from foundation.types.node import Node

from foundation.sketch.base import SketchElement
from foundation.sketch.closed_sketch_shape import Circle, ClosedSketchShape
from foundation.types.node_children import NodeChildren
from foundation.sketch.sketch import Sketch

from foundation.types.parameters import (
UnCastFloat,
UnCastBool,
cast_to_float_parameter,
cast_to_bool_parameter,
FloatParameter,
BoolParameter,
)
from foundation.types.types_3d.curve import Curve3DTypes


class SweepChildren(NodeChildren):
profile: ClosedSketchShape
path: Curve3DTypes
sketch: Sketch

# TODO could add more optional parameters here (frenet, ...)


class Sweep(Operation, Node):
children_class = SweepChildren

def __init__(
self,
profile: ClosedSketchShape,
path: Curve3DTypes,
):

Operation.__init__(self)
Node.__init__(self, parents=[])
self.children.set_profile(profile)
self.children.set_path(path)
self.children.set_sketch(profile.sketch)

# shortcuts
self.profile = self.children.profile
self.path = self.children.path

self.params = {}


SweepChildren.__annotations__["profile"] = ClosedSketchShape
SweepChildren.__annotations__["path"] = Curve3DTypes
SweepChildren.__annotations__["sketch"] = Sketch
2 changes: 2 additions & 0 deletions src/foundation/sketch/sketch.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

from foundation.types.node import Node
from foundation.sketch.point import Point
from foundation.sketch.draw import Draw
Expand Down
3 changes: 2 additions & 1 deletion src/foundation/types/comp_or_assy.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@


class PlaneMethod(Protocol):
def __call__(self: T) -> Plane: ...
def __call__(self: T) -> Plane:
...


# # This is a small trick to facilitate user to create a part without having to call super.
Expand Down
22 changes: 3 additions & 19 deletions src/foundation/types/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ class Node(object):
"""

parent_types: list[str] = (
[]
) # can be reimplemented in child classes to enforce a parent type to the Node
parent_types: list[
str
] = [] # can be reimplemented in child classes to enforce a parent type to the Node
_ids = count(0) # used to generate unique ids for the node
children_class = NodeChildren # Default : overriden in child classes

Expand Down Expand Up @@ -86,22 +86,6 @@ def is_serializable(self):
return True, serializable_nodes[parent.__name__]
return False, None

def to_dict(self, only_keep_serializable_nodes: bool = True) -> dict:
"""Current Node as a dictionary"""
raise DeprecationWarning("to_dict is deprecated replaced with hashing method")
is_serializable, node_type = self.is_serializable()
if only_keep_serializable_nodes and not is_serializable:
raise TypeError(
f"""Node type {type(self).__name__} is not serializable, make sure
to add it to the serializable_nodes dict in the serializable.py file."""
)
node_dict = {
"type": node_type,
"deps": self.children.get_as_dict_of_ids(),
"params": self.params,
}
return node_dict

def get_children(self, type_filter: list[str]):
"""return the children of the component, eventually filtered"""
res = []
Expand Down
2 changes: 1 addition & 1 deletion src/foundation/types/node_children.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from types import MethodType
from typing import get_origin, get_args, Union, Optional, Dict, List
from typing import get_origin, get_args, Union, Dict, List


def is_union_type(tp):
Expand Down
3 changes: 3 additions & 0 deletions src/foundation/types/serializable.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,7 @@
"CustomClosedShape": 30,
"Arc": 31,
"SVGShape": 32,
"Helix3D": 33,
"Sweep": 34,
"Point3D": 35,
}
Empty file.
106 changes: 106 additions & 0 deletions src/foundation/types/types_3d/curve.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
from foundation.types.node_interface import NodeInterface
from foundation.types.node_children import NodeChildren
from foundation.types.types_3d.point_3d import Point3D
from foundation.types.node import Node
from foundation.types.parameters import (
FloatParameter,
BoolParameter,
UnCastFloat,
UnCastBool,
cast_to_float_parameter,
cast_to_bool_parameter,
)


class Curve3D(NodeInterface):
"""Base class for 3D curves."""

def __init__(self):
super().__init__()


class Line3DChildren(NodeChildren):
start: Point3D
end: Point3D


class Line3D(Curve3D, Node):
pass
# TODO: Implement the following classes


# 3 points define a unique arc (note : they need to be on the same plane)
class Arc3DChildren(NodeChildren):
p1: Point3D
p2: Point3D
p3: Point3D


class Arc3D(Curve3D, Node):
# TODO
pass


class HelixChildren(NodeChildren):
pitch: UnCastFloat
height: UnCastFloat
radius: UnCastFloat
center: Point3D
dir: Point3D
lefthand: UnCastBool


class Helix3D(Curve3D, Node):
"""A Helix curve,
starting at (center.x + radius.x, center.y, center.z)"""

children_class = HelixChildren

def __init__(
self,
pitch: float,
height: float,
radius: float,
center: Point3D = Point3D(0, 0, 0),
dir: Point3D = Point3D(0, 0, 1),
lefthand: bool = False,
):
Node.__init__(self)
Curve3D.__init__(self)

self.children.set_pitch(cast_to_float_parameter(pitch))
self.children.set_height(cast_to_float_parameter(height))
self.children.set_radius(cast_to_float_parameter(radius))
self.children.set_center(center)
self.children.set_dir(dir)
self.children.set_lefthand(cast_to_bool_parameter(lefthand))
self.params = {}


class Ellipse3DChildren(NodeChildren):
# TODO
pass


class Ellipse3D(Curve3D, Node):
# TODO
pass


class Spline3DChildren(NodeChildren):
points: list[Point3D]


class Spline3D(Curve3D, Node):
# TODO
pass


Curve3DTypes = Helix3D # U

HelixChildren.__annotations__["pitch"] = FloatParameter
HelixChildren.__annotations__["height"] = FloatParameter
HelixChildren.__annotations__["radius"] = FloatParameter
HelixChildren.__annotations__["center"] = Point3D
HelixChildren.__annotations__["dir"] = Point3D
HelixChildren.__annotations__["lefthand"] = BoolParameter
File renamed without changes.
8 changes: 3 additions & 5 deletions src/foundation/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from typing import Union

try:
import json
import websocket
except ImportError:
# mock the websocket module for environments where it is not available
Expand Down Expand Up @@ -81,10 +80,9 @@ def show(x: DISPLAY_TYPE) -> None:
dag = show_dag(x)

try:
ws = websocket.create_connection("ws://127.0.0.1:3000")
json_str = json.dumps(dag)
ws.send(json_str)
reset_ids()
from foundation.utils_websocket import show_ext

show_ext(dag)
except Exception:
print("WebSocket not available")

Expand Down
Loading

0 comments on commit 79fe8ee

Please sign in to comment.