Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lap BTLx Feature // T-Butt & L-Butt #322

Merged
merged 25 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
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
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Added `Element.reset()` method.

* Added new `fasteners.py` module with new `Fastener` element type.
* Added new `compas_timber._fabrication.Lap`.

### Changed

Expand All @@ -52,11 +53,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Changed `model.element_by_guid()` instead of direct `elementsdict[]` access for beam retrieval in joint modules: `LMiterJoint`, `TStepJoint`, `TDovetailJoint`, `TBirdsmouthJoint`.
* Reworked the model generation pipeline.
* Reworked `comply` methods for `JointRule`s.
* Fixed error with angle and inclination calculation in `compas_timber._fabrication.JackRafterCut`
* Changed `compas_timber.connections.TButtJoint` and `compas_timber.connections.LButtJoint` by using the new implemented BTLx Processes to define the Joints

### Removed

* Removed module `compas_timber.utils.compas_extra`.
* Removed a bunch of spaghetti from `CT_model` GH component.
* Removed module `compas_timber.fabrication.joint_factories.t_butt_factory`
* Removed module `compas_timber.fabrication.joint_factories.l_butt_factory`
* Removed module `compas_timber.connections.butt_joint`



## [0.11.0] 2024-09-17

Expand Down
7,812 changes: 7,812 additions & 0 deletions examples/Grasshopper/tests/test_lap.ghx

Large diffs are not rendered by default.

513 changes: 298 additions & 215 deletions examples/Grasshopper/tests/test_step_joint.ghx

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions src/compas_timber/_fabrication/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
from .dovetail_tenon import DovetailTenonParams
from .dovetail_mortise import DovetailMortise
from .dovetail_mortise import DovetailMortiseParams
from .lap import Lap
from .lap import LapParams


__all__ = [
Expand All @@ -35,4 +37,6 @@
"DovetailTenonParams",
"DovetailMortise",
"DovetailMortiseParams",
"Lap",
"LapParams",
]
41 changes: 41 additions & 0 deletions src/compas_timber/_fabrication/btlx_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,44 @@ class LimitationTopType(object):
LIMITED = "limited"
UNLIMITED = "unlimited"
POCKET = "pocket"


class MachiningLimits(object):
"""Configuration class for the machining limits of the cut.

Attributes
----------
EXPECTED_KEYS : set
The expected keys for the limits dictionary.
face_limited_start : bool
Limit the start face.
face_limited_end : bool
Limit the end face.
face_limited_front : bool
Limit the front face.
face_limited_back : bool
Limit the back face.

Properties
----------
limits : dict
The limits dictionary with values as a boolean.
"""

EXPECTED_KEYS = ["FaceLimitedStart", "FaceLimitedEnd", "FaceLimitedFront", "FaceLimitedBack"]
papachap marked this conversation as resolved.
Show resolved Hide resolved

def __init__(self):
self.face_limited_start = True
self.face_limited_end = True
self.face_limited_front = True
self.face_limited_back = True

@property
def limits(self):
"""Dynamically generate the limits dictionary with boolean values from instance attributes."""
return {
"FaceLimitedStart": self.face_limited_start,
"FaceLimitedEnd": self.face_limited_end,
"FaceLimitedFront": self.face_limited_front,
"FaceLimitedBack": self.face_limited_back,
}
26 changes: 11 additions & 15 deletions src/compas_timber/_fabrication/jack_cut.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,6 @@ def from_plane_and_beam(cls, plane, beam, ref_side_index=0):
ref_side = beam.ref_sides[ref_side_index] # TODO: is this arbitrary?
ref_edge = Line.from_point_and_vector(ref_side.point, ref_side.xaxis)
orientation = cls._calculate_orientation(ref_side, plane)

point_start_x = intersection_line_plane(ref_edge, plane)
if point_start_x is None:
raise ValueError("Plane does not intersect with beam.")
Expand All @@ -190,20 +189,14 @@ def _calculate_angle(ref_side, plane, orientation):
# vector rotation direction of the plane's normal in the vertical direction
angle_vector = Vector.cross(ref_side.zaxis, plane.normal)
angle = angle_vectors_signed(ref_side.xaxis, angle_vector, ref_side.zaxis, deg=True)
if orientation == OrientationType.START:
return 180 - abs(angle) # get the other side of the angle
else:
return abs(angle)
return 180 - abs(angle)

@staticmethod
def _calculate_inclination(ref_side, plane, orientation):
# vector rotation direction of the plane's normal in the horizontal direction
inclination_vector = Vector.cross(ref_side.yaxis, plane.normal)
inclination = angle_vectors_signed(ref_side.xaxis, inclination_vector, ref_side.yaxis, deg=True)
if orientation == OrientationType.START:
return 180 - abs(inclination) # get the other side of the angle
else:
return abs(inclination)
inclination_vector = Vector.cross(ref_side.zaxis, plane.normal)
inclination = angle_vectors_signed(ref_side.zaxis, plane.normal, inclination_vector, deg=True)
return 180 - abs(inclination)

########################################################################
# Methods
Expand Down Expand Up @@ -265,11 +258,14 @@ def plane_from_params_and_beam(self, beam):
cutting_plane = Frame(p_origin, ref_side.frame.xaxis, ref_side.frame.yaxis)

# normal pointing towards xaxis so just need the delta
horizontal_angle = math.radians(self.angle - 90)
rot_a = Rotation.from_axis_and_angle(cutting_plane.zaxis, horizontal_angle, point=p_origin)
if self.orientation == OrientationType.END:
horizontal_angle = math.radians(90 - self.angle)
vertical_angle = math.radians(90 - self.inclination)
else:
horizontal_angle = math.radians(self.angle - 90)
vertical_angle = math.radians(self.inclination - 90)

# normal pointing towards xaxis so just need the delta
vertical_angle = math.radians(self.inclination - 90)
rot_a = Rotation.from_axis_and_angle(cutting_plane.zaxis, horizontal_angle, point=p_origin)
rot_b = Rotation.from_axis_and_angle(cutting_plane.yaxis, vertical_angle, point=p_origin)

cutting_plane.transform(rot_a * rot_b)
Expand Down
Loading
Loading