Skip to content

Commit

Permalink
Merge pull request #265 from gramaziokohler/reference_frame
Browse files Browse the repository at this point in the history
Reference frame
  • Loading branch information
chenkasirer authored Jul 9, 2024
2 parents 86e8c82 + 9da597b commit 6b66a71
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

* Added `ref_frame` attribute to `Beam`.
* Added `ref_sides` attribute to `Beam`.
* Added `ref_edges` attribute to `Beam`.

### Changed

* Fixed error in BakeWithBoxMap component.
Expand Down
45 changes: 45 additions & 0 deletions src/compas_timber/elements/beam.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ class Beam(Element):
A feature-less box representing the parametric geometry of this beam.
blank : :class:`~compas.geometry.Box`
A feature-less box representing the material stock geometry to produce this beam.
ref_frame : :class:`~compas.geometry.Frame`
Reference frame for machining processes according to BTLx standard.
ref_sides : tuple(:class:`~compas.geometry.Frame`)
A tuple containing the 6 frames representing the sides of the beam according to BTLx standard.
ref_edges : tuple(:class:`~compas.geometry.Line`)
A tuple containing the 4 lines representing the long edges of the beam according to BTLx standard.
faces : list(:class:`~compas.geometry.Frame`)
A list of frames representing the 6 faces of this beam.
0: +y (side's frame normal is equal to the beam's Y positive direction)
Expand Down Expand Up @@ -120,12 +126,20 @@ def blank_length(self):

@property
def blank_frame(self):
# TODO: could be replaced by `ref_frame`?
assert self.frame
start, _ = self._resolve_blank_extensions()
frame = self.frame.copy()
frame.point += -frame.xaxis * start # "extension" to the start edge
return frame

@property
def ref_frame(self):
ref_point = self.blank_frame.point.copy()
ref_point += self.blank_frame.yaxis * self.width * 0.5
ref_point -= self.blank_frame.zaxis * self.height * 0.5
return Frame(ref_point, self.blank_frame.xaxis, self.blank_frame.zaxis)

@property
def faces(self):
assert self.frame
Expand Down Expand Up @@ -158,6 +172,37 @@ def faces(self):
), # small face at end point
]

@property
def ref_sides(self):
# type: () -> tuple[Frame, Frame, Frame, Frame, Frame, Frame]
# See: https://design2machine.com/btlx/BTLx_2_2_0.pdf
# TODO: cache these
rs1_point = self.ref_frame.point
rs2_point = rs1_point + self.ref_frame.yaxis * self.height
rs3_point = rs1_point + self.ref_frame.yaxis * self.height + self.ref_frame.zaxis * self.width
rs4_point = rs1_point + self.ref_frame.zaxis * self.width
rs5_point = rs1_point
rs6_point = rs1_point + self.ref_frame.xaxis * self.blank_length + self.ref_frame.yaxis * self.height
return (
Frame(rs1_point, self.ref_frame.xaxis, self.ref_frame.zaxis, name="RS_1"),
Frame(rs2_point, self.ref_frame.xaxis, -self.ref_frame.yaxis, name="RS_2"),
Frame(rs3_point, self.ref_frame.xaxis, -self.ref_frame.zaxis, name="RS_3"),
Frame(rs4_point, self.ref_frame.xaxis, self.ref_frame.yaxis, name="RS_4"),
Frame(rs5_point, self.ref_frame.zaxis, self.ref_frame.yaxis, name="RS_5"),
Frame(rs6_point, self.ref_frame.zaxis, -self.ref_frame.yaxis, name="RS_6"),
)

@property
def ref_edges(self):
# so tuple is not created every time
ref_sides = self.ref_sides
return (
Line(ref_sides[0].point, ref_sides[0].point + ref_sides[0].xaxis * self.blank_length, name="RE_1"),
Line(ref_sides[1].point, ref_sides[1].point + ref_sides[1].xaxis * self.blank_length, name="RE_2"),
Line(ref_sides[2].point, ref_sides[2].point + ref_sides[2].xaxis * self.blank_length, name="RE_3"),
Line(ref_sides[3].point, ref_sides[3].point + ref_sides[3].xaxis * self.blank_length, name="RE_4"),
)

@property
def centerline(self):
return Line(self.centerline_start, self.centerline_end)
Expand Down
70 changes: 70 additions & 0 deletions tests/compas_timber/test_btlx.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

from compas.geometry import Line
from compas.geometry import Point
from compas.geometry import Frame
from compas.geometry import Vector

from compas_timber.elements import Beam
from compas_timber.fabrication import BTLxPart
Expand All @@ -23,3 +25,71 @@ def test_beam_ref_faces(mock_beam):
assert btlx_part.ref_side_from_face(mock_beam.faces[3]) == 4
assert btlx_part.ref_side_from_face(mock_beam.faces[4]) == 5
assert btlx_part.ref_side_from_face(mock_beam.faces[5]) == 6


def test_beam_ref_faces_attribute(mock_beam):
ref_side_frames_expected = (
Frame(
point=Point(x=-48.67193560518159, y=20.35704602012424, z=0.0005429194857271558),
xaxis=Vector(x=0.9374000278319115, y=0.3451241645032913, z=0.04658861337963174),
yaxis=Vector(x=0.3454993211307862, y=-0.9384189997533969, z=-1.734723475976807e-18),
),
Frame(
point=Point(x=-48.7156552451492, y=20.340949685829152, z=0.9994570805142728),
xaxis=Vector(x=0.9374000278319115, y=0.3451241645032913, z=0.04658861337963174),
yaxis=Vector(x=0.04371963996761174, y=0.016096334295087427, z=-0.9989141610285457),
),
Frame(
point=Point(x=-48.37015592401841, y=19.402530686075757, z=0.9994570805142728),
xaxis=Vector(x=0.9374000278319115, y=0.3451241645032913, z=0.04658861337963174),
yaxis=Vector(x=-0.3454993211307862, y=0.9384189997533969, z=1.734723475976807e-18),
),
Frame(
point=Point(x=-48.3264362840508, y=19.41862702037084, z=0.000542919485727154),
xaxis=Vector(x=0.9374000278319115, y=0.3451241645032913, z=0.04658861337963174),
yaxis=Vector(x=-0.04371963996761174, y=-0.016096334295087427, z=0.9989141610285457),
),
Frame(
point=Point(x=-48.67193560518159, y=20.35704602012424, z=0.0005429194857271558),
xaxis=Vector(x=0.3454993211307862, y=-0.9384189997533969, z=-1.734723475976807e-18),
yaxis=Vector(x=-0.04371963996761173, y=-0.016096334295087424, z=0.9989141610285456),
),
Frame(
point=Point(x=-38.6552567933492, y=24.04490371522915, z=1.499457080514273),
xaxis=Vector(x=0.3454993211307862, y=-0.9384189997533969, z=-1.734723475976807e-18),
yaxis=Vector(x=0.04371963996761173, y=0.016096334295087424, z=-0.9989141610285456),
),
)

for index in range(6):
ref_side = mock_beam.ref_sides[index]
assert ref_side_frames_expected[index] == ref_side
assert ref_side.name == "RS_{}".format(index + 1)


def test_beam_ref_edges(mock_beam):

ref_edges_expected = (
Line(
Point(x=-48.67193560518159, y=20.35704602012424, z=0.0005429194857271558),
Point(x=-38.61153715338159, y=24.06100004952424, z=0.5005429194857273),
),
Line(
Point(x=-48.7156552451492, y=20.340949685829152, z=0.9994570805142728),
Point(x=-38.6552567933492, y=24.04490371522915, z=1.499457080514273),
),
Line(
Point(x=-48.37015592401841, y=19.402530686075757, z=0.9994570805142728),
Point(x=-38.309757472218415, y=23.106484715475755, z=1.499457080514273),
),
Line(
Point(x=-48.3264362840508, y=19.41862702037084, z=0.000542919485727154),
Point(x=-38.2660378322508, y=23.12258104977084, z=0.5005429194857273),
),
)
assert len(mock_beam.ref_edges) == 4

for index in range(4):
ref_edge = mock_beam.ref_edges[index]
assert ref_edges_expected[index] == ref_edge
assert ref_edge.name == "RE_{}".format(index + 1)

0 comments on commit 6b66a71

Please sign in to comment.