Skip to content

Commit

Permalink
Merge pull request #336 from gramaziokohler/beam_populator
Browse files Browse the repository at this point in the history
Beam populator
  • Loading branch information
chenkasirer authored Feb 13, 2025
2 parents 297d90b + 0c28371 commit be15525
Show file tree
Hide file tree
Showing 30 changed files with 2,359 additions and 127 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Added `from_shapes_and_element` class method to `Drilling`, `JackRafterCut`, and `DoubleCut` as a wrapper for their geometry based constructors for use with `BTLxFromGeometryDefinition`.
* Added `YButtJoint` which joins the ends of three joints where the `cross_beams` get a miter cut and the `main_beam` gets a double cut.
* Added `JackRafterCutProxy` to allow for deferred calculation of the `JackRafterCut` geometry thus improving visualization performance.
* Added class "WallPopulator" to `compas_timber.design`.
* Added class "WallPopulatorConfigurationSet" to `compas_timber.design`.
* Added class "WallSelector" to `compas_timber.design`.
* Added class "AnyWallSelector" to `compas_timber.design`.
* Added class "LConnectionDetailA" to `compas_timber.design`.
* Added class "LConnectionDetailB" to `compas_timber.design`.
* Added class "TConnectionDetailA" to `compas_timber.design`.
* Added `from_brep` to `compas_timber.elements.Wall.
* Added `from_polyline` to `compas_timber.elements.Wall.
* Added `WallJoint` to `compas_timber.connections`.

### Changed

Expand All @@ -39,6 +49,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Changed `Show_beam_faces` gh component to `Show_ref_sides`, which now takes an `int` index and shows the corresponding face including origin corner.
* Bug fixes after adding `max_distance` to joint defs.
* Using new `JackRafterCutProxy` in LMiterJoint, LButtJoint and TButtJoint.
* Reworked `Wall` class to be defined with a standard polyline, frame and thickness.

### Removed

Expand Down
2 changes: 1 addition & 1 deletion docs/api/compas_timber.connections.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Functions
:toctree: generated/
:nosignatures:

find_neighboring_beams
find_neighboring_elements

Exceptions
==========
Expand Down
2 changes: 1 addition & 1 deletion docs/api/compas_timber.rhino.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ Plugins
:toctree: generated/
:nosignatures:

find_neighboring_beams
find_neighboring_elements
51 changes: 51 additions & 0 deletions scripts/model_to_ifc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
from compas.data import json_load

from compas_timber.model import TimberModel
from compas_ifc.model import Model

PATH = r"C:\Users\ckasirer\Documents\Projects\COMPAS Timber\sounding_board_2025\demo_v2\multi_wall.json"

model: TimberModel = json_load(PATH)

model.process_joinery()

IFC_PATH = r"C:\Users\ckasirer\Documents\Projects\COMPAS Timber\sounding_board_2025\demo_v2\multi_wall.ifc"


# def join_meshes(meshes):
# joined_mesh = meshes[0]
# for mesh in meshes[1:]:
# joined_mesh.join(mesh)
# return joined_mesh


ifc_model = Model.template()
storey = ifc_model.building_storeys[0]

# for element in model.beams:
# beam = ifc_model.create(
# "IfcBeam",
# parent=storey,
# geometry=element.geometry,
# Name=element.name,
# )

for wall in model.walls:
ifc_wall = ifc_model.create(
"IfcWall",
parent=storey,
geometry=wall.geometry,
Name=wall.name,
)
for beam in model.get_elements_in_group(wall.name):
ifc_model.create(
"IfcBeam",
parent=ifc_wall,
geometry=beam.geometry,
Name=beam.name,
)


ifc_model.unit = "m"
# model.show()
ifc_model.save(IFC_PATH)
10 changes: 8 additions & 2 deletions src/compas_timber/connections/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from .null_joint import NullJoint
from .solver import ConnectionSolver
from .solver import JointTopology
from .solver import find_neighboring_beams
from .solver import find_neighboring_elements
from .t_butt import TButtJoint
from .t_step_joint import TStepJoint
from .t_birdsmouth import TBirdsmouthJoint
Expand All @@ -19,6 +19,9 @@
from .y_butt import YButtJoint
from .utilities import beam_ref_side_incidence
from .utilities import beam_ref_side_incidence_with_vector
from .wall_joint import WallJoint
from .wall_joint import InterfaceLocation
from .wall_joint import InterfaceRole

__all__ = [
"Joint",
Expand All @@ -36,11 +39,14 @@
"LFrenchRidgeLapJoint",
"JointTopology",
"ConnectionSolver",
"find_neighboring_beams",
"find_neighboring_elements",
"TDovetailJoint",
"BallNodeJoint",
"TenonMortiseJoint",
"YButtJoint",
"beam_ref_side_incidence",
"beam_ref_side_incidence_with_vector",
"WallJoint",
"InterfaceLocation",
"InterfaceRole",
]
32 changes: 29 additions & 3 deletions src/compas_timber/connections/solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@


@pluggable(category="solvers")
def find_neighboring_beams(beams, inflate_by=0.0):
def find_neighboring_elements(elements, inflate_by=0.0):
"""Finds neighboring pairs of beams in the given list of beams, using R-tree search.
The inputs to the R-tree algorithm are the axis-aligned bounding boxes of the beams (beam.aabb), enlarged by the `inflate_by` amount.
Expand All @@ -34,7 +34,7 @@ def find_neighboring_beams(beams, inflate_by=0.0):
Notes
-----
This is a `pluggable`. In order to use this function, a compatible `plugin` has to be available.
For example, in Rhino, the function :func:`~compas_timber.rhino.find_neighboring_beams` will be used.
For example, in Rhino, the function :func:`~compas_timber.rhino.find_neighboring_elements` will be used.
"""
raise NotImplementedError
Expand Down Expand Up @@ -107,7 +107,7 @@ def find_intersecting_pairs(cls, beams, rtree=False, max_distance=0.0):
List containing sets or neightboring pairs beams.
"""
return find_neighboring_beams(beams, inflate_by=max_distance) if rtree else itertools.combinations(beams, 2)
return find_neighboring_elements(beams, inflate_by=max_distance) if rtree else itertools.combinations(beams, 2)

def find_topology(self, beam_a, beam_b, tol=TOLERANCE, max_distance=None):
"""If `beam_a` and `beam_b` intersect within the given `max_distance`, return the topology type of the intersection.
Expand All @@ -116,6 +116,8 @@ def find_topology(self, beam_a, beam_b, tol=TOLERANCE, max_distance=None):
(e.g. main beam first, cross beam second), otherwise, the beams are outputted in the same
order as they were inputted.
# TODO: this needs to be reworked ASAP
Parameters
----------
beam_a : :class:`~compas_timber.parts.Beam`
Expand Down Expand Up @@ -216,6 +218,30 @@ def find_topology(self, beam_a, beam_b, tol=TOLERANCE, max_distance=None):
# X-joint (both meeting somewhere along the line)
return JointTopology.TOPO_X, beam_a, beam_b

def find_wall_wall_topology(self, wall_a, wall_b, tol=TOLERANCE, max_distance=None):
"""Calculates the topology of the intersection between two walls.
TODO: Passes-through to the beam topology calculation. This should be reworked.
Parameters
----------
wall_a : :class:`~compas_timber.elements.Wall`
First potential intersecting wall.
wall_b : :class:`~compas_timber.elements.Wall`
Second potential intersecting wall.
tol : float
General tolerance to use for mathematical computations.
max_distance : float, optional
Maximum distance, in desigen units, at which two fs are considered intersecting.
Returns
-------
tuple(:class:`~compas_timber.connections.JointTopology`, :class:`~compas_timber.element.Wall`, :class:`~compas_timber.element.Wall`)
"""
# TODO: make find topology more generic. break down to find_line_line_topo etc.
return self.find_topology(wall_a, wall_b, tol, max_distance)

@staticmethod
def _calc_t(line, plane):
a, b = line
Expand Down
Loading

0 comments on commit be15525

Please sign in to comment.