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

Adaptive Joint Rule Components #232

Merged
merged 44 commits into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
5cb9a61
first commit
obucklin Feb 15, 2024
ec928cc
Merge branch 'main' into adaptive_GH_Components
obucklin Feb 15, 2024
c06206d
format lint test... undefined name 'ghenv'
obucklin Feb 15, 2024
97e5110
persistnece solved
obucklin Feb 16, 2024
148e187
snake_case
obucklin Feb 16, 2024
619b881
Merge branch 'main' into adaptive_GH_Components
obucklin Feb 16, 2024
d97b243
fixed merge errors
obucklin Feb 16, 2024
a289732
re-de-linted
obucklin Feb 16, 2024
bae285e
Update src/compas_timber/ghpython/components/CT_Joint_Options_FrenchR…
obucklin Feb 16, 2024
dbefd96
refactor_attempt
obucklin Feb 16, 2024
166c601
Merge branch 'adaptive_GH_Components' of https://github.com/gramaziok…
obucklin Feb 16, 2024
dc9c070
moved parameter functions to ghcomponent_helpers
obucklin Feb 16, 2024
477c725
cant make it break
obucklin Feb 19, 2024
d7c03b1
changed beam names to CamelCase
obucklin Feb 20, 2024
c2c1dec
take a break
obucklin Feb 21, 2024
2a8013b
updated helpers
obucklin Mar 7, 2024
824bd55
added adaptive direct and category components
obucklin Mar 7, 2024
b3b9178
made topo components (plural)
obucklin Mar 7, 2024
7990c04
Works but doesnt save
obucklin Mar 7, 2024
fdb9505
beam name chenged
obucklin Mar 7, 2024
0c9cfba
Merge branch 'main' into adaptive_GH_Components
obucklin Mar 7, 2024
f89fac3
Tested Linted Formatted with Videos
obucklin Mar 8, 2024
ff84634
changelog updated
obucklin Mar 8, 2024
055f9c5
typo fix
obucklin Mar 8, 2024
4975957
added example .gh and vids
obucklin Mar 8, 2024
2565367
added TOPO filter to CategoryRule
obucklin Mar 11, 2024
3ac3900
Components cleaned up
obucklin Mar 14, 2024
dd8e454
added demo vids
obucklin Mar 14, 2024
cd8e497
changelog
obucklin Mar 14, 2024
8b3dc96
correct gh file
obucklin Mar 14, 2024
6ba59d1
fixed merge conflict in changelog
obucklin Mar 19, 2024
0ce9af4
fixed_False_arg_input
obucklin Mar 24, 2024
c93db4e
component format changes
obucklin Apr 17, 2024
cedbb7d
vids removed
obucklin Apr 17, 2024
a503b78
Merge branch 'main' into adaptive_GH_Components
obucklin Apr 17, 2024
c612571
reverted changes to joints
chenkasirer Apr 23, 2024
6fe80d8
ignore undefined imports in components
chenkasirer Apr 23, 2024
68d0131
is not None instead of != None
chenkasirer Apr 23, 2024
7d33a25
more specific path to components
chenkasirer Apr 23, 2024
dce66a4
removed DefaulRule
chenkasirer Apr 23, 2024
89403db
mutable default
chenkasirer Apr 23, 2024
185b4aa
removed unused JointOptions
chenkasirer Apr 23, 2024
071929d
snake_cased some functions
chenkasirer Apr 23, 2024
a0ccf31
updated changelog
chenkasirer Apr 23, 2024
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 @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Removed argument `cutoff` from `LMiterJoint` as it was not used anywhere.
* Removed argument `gap` from `TButtJoint` as it was not used anywhere.
* Removed argument `gap` from `FrenchRidgeLap` as it was not used anywhere.
* Removed class `JointOptions` as not used anymore.

## [0.7.0] 2024-02-15

Expand All @@ -32,6 +33,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Added new `NullJoint`.
* Added `mill_depth` argument to butt joints, with geometric representation of milled recess in cross beam.
* Added `ButtJoint` class with methods common to `LButtJoint` and `TButtJoint`
* Added new `L_TopologyJointRule`, `T_TopologyJointRule`, `X_TopologyJointRule` GH components
* Added GH component param support functions in `compas_timber.ghpython.ghcomponent_helpers.py`
* Added `topos` attribute to `CategoryRule` to filter when joints get applied

### Changed

Expand All @@ -43,6 +47,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Changed GH Categories for joint rules.
* Made `beam_side_incident` a `staticmethod` of `Joint` and reworked it.
* Extended `DecomposeBeam` component to optionally show beam frame and faces.
* Changed `CategoryJointRule` and `DirectJointRule` to a dynamic interface where joint type is selected with right click menu
* Changed `Assembly` GH component to apply category joints if the detected topology is in `CategoryRule.topos`
* Changed `TopologyJoints` GH component to `DefaultJoints` Component, which applies default joints based on topology.

### Removed

Expand All @@ -53,6 +60,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* `DrillHole` has default diameter proportional to beam cross-section.
* Removed input `Length` from `DrillHole` component.
* Fixed broken `TrimmingFeature` component.
* Removed all `JointOption` components. these are accessed in context menu of joint rules.

## [0.6.1] 2024-02-02

Expand Down
Binary file removed examples/Grasshopper/CT_NEW_UI_Example.3dm
Binary file not shown.
Binary file removed examples/Grasshopper/CT_NEW_UI_Example.gh
Binary file not shown.
Binary file added examples/Grasshopper/dynamic_gh_demo.gh
Binary file not shown.
3 changes: 3 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ extend-ignore =
E203,
# Only keep black line length check because flake8 forces it on comments as well
E501,
per-file-ignores =
# GH components often have undefined imports (e.g. ghenv)
src/compas_timber/ghpython/components/*/*.py: F821

[doc8]
max-line-length = 120
Expand Down
9 changes: 7 additions & 2 deletions src/compas_timber/ghpython/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,21 @@
from .workflow import TopologyRule
from .workflow import DirectRule
from .workflow import FeatureDefinition
from .workflow import JointOptions
from .workflow import JointDefinition
from .workflow import DebugInfomation
from .ghcomponent_helpers import clear_gh_params
from .ghcomponent_helpers import add_gh_param
from .ghcomponent_helpers import manage_dynamic_params


__all__ = [
"JointDefinition",
"CategoryRule",
"TopologyRule",
"DirectRule",
"FeatureDefinition",
"JointOptions",
"DebugInfomation",
"clear_gh_params",
"add_gh_param",
"manage_dynamic_params",
]
31 changes: 30 additions & 1 deletion src/compas_timber/ghpython/components/CT_Assembly/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,23 @@
from compas_timber.connections import ConnectionSolver
from compas_timber.connections import JointTopology
from compas_timber.connections import BeamJoinningError
from compas_timber.connections import XHalfLapJoint
from compas_timber.connections import TButtJoint
from compas_timber.connections import LMiterJoint
from compas_timber.ghpython import JointDefinition
from compas_timber.ghpython import CategoryRule
from compas_timber.ghpython import TopologyRule
from compas_timber.ghpython import DirectRule
from compas_timber.ghpython import DebugInfomation


JOINT_DEFAULTS = {
JointTopology.TOPO_X: XHalfLapJoint,
JointTopology.TOPO_T: TButtJoint,
JointTopology.TOPO_L: LMiterJoint,
}


class Assembly(component):
def __init__(self):
# maintains relationship of old_beam.id => new_beam_obj for referencing
Expand All @@ -38,9 +48,16 @@ def get_joints_from_rules(self, beams, rules, topologies):
cat_rules = []
direct_rules = []

# TODO: refactor this into some kind of a rule reloving class/function
for r in rules: # separate category and topo and direct joint rules
if isinstance(r, TopologyRule):
topo_rules[r.topology_type] = r
if topo_rules.get(r.topology_type, None): # if rule for this Topo exists
if (r.joint_type != JOINT_DEFAULTS[r.topology_type]) or (
len(r.kwargs) != 0
): # if this rule is NOT default
topo_rules[r.topology_type] = r
else:
topo_rules[r.topology_type] = r
elif isinstance(r, CategoryRule):
cat_rules.append(r)
if isinstance(r, DirectRule):
Expand Down Expand Up @@ -75,6 +92,18 @@ def get_joints_from_rules(self, beams, rules, topologies):
),
)
continue
if rule.topos and detected_topo not in rule.topos:
msg = "Conflict detected! Beams: {}, {} meet with topology: {} but rule allows: {}"
self.AddRuntimeMessage(
Warning,
msg.format(
beam_a.key,
beam_b.key,
JointTopology.get_name(detected_topo),
[JointTopology.get_name(topo) for topo in rule.topos],
),
)
continue
# sort by category to allow beam role by order (main beam first, cross beam second)
beam_a, beam_b = rule.reorder([beam_a, beam_b])
joints.append(JointDefinition(rule.joint_type, [beam_a, beam_b], **rule.kwargs))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@


class Attributes_Check(component):
def RunScript(self, RefObj):
def RunScript(self, ref_obj):
self.data = []

list_input_valid(self, RefObj, "RefObj")
list_input_valid(self, ref_obj, "RefObj")

for obj in RefObj:
d = {"refobj": RefObj, "crv": None, "msg": [], "ok": None, "pln": None, "pt": None}
for obj in ref_obj:
d = {"refobj": ref_obj, "crv": None, "msg": [], "ok": None, "pln": None, "pt": None}

crv = Rhino.RhinoDoc.ActiveDoc.Objects.FindId(obj).Geometry
if not crv:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@


class Attributes_Delete(component):
def RunScript(self, RefObj, AttributeName, update):
if not item_input_valid(self, RefObj, "RefObj"):
def RunScript(self, ref_obj, attribute_name, update):
if not item_input_valid(self, ref_obj, "RefObj"):
return

if update and RefObj:
if not AttributeName:
if update and ref_obj:
if not attribute_name:
# clear all attributes from the refecenced object's name
update_rhobj_attributes_name(RefObj, operation="clear")
update_rhobj_attributes_name(ref_obj, operation="clear")
else:
# remove only the indicated attributes
for attr in AttributeName:
update_rhobj_attributes_name(RefObj, attribute=attr, operation="remove")
for attr in attribute_name:
update_rhobj_attributes_name(ref_obj, attribute=attr, operation="remove")

return
30 changes: 15 additions & 15 deletions src/compas_timber/ghpython/components/CT_Attributes_Get/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,29 @@


class Attributes_Get(component):
def RunScript(self, RefCrv):
if not RefCrv:
def RunScript(self, ref_crv):
if not ref_crv:
self.AddRuntimeMessage(Warning, "Input parameter RefCrv failed to collect data")

ZVector = []
Width = []
Height = []
Category = []
Group = []
z_vector = []
width = []
height = []
category = []
group = []

guid = RefCrv
guid = ref_crv
if guid:
# get attributes from the name string ==========================================
attr = get_obj_attributes(guid)
if attr:
if "width" in attr:
Width = float(attr["width"])
width = float(attr["width"])
if "height" in attr:
Height = float(attr["height"])
height = float(attr["height"])
if "category" in attr:
Category = attr["category"]
category = attr["category"]
if "zvector" in attr:
ZVector = attr["zvector"]
z_vector = attr["zvector"]
# it's a string, but Grasshopper will automatically cast this input as Vector3d

# get the group if objects are grouped =========================================
Expand All @@ -44,9 +44,9 @@ def RunScript(self, RefCrv):
self.AddRuntimeMessage(
Remark, "Some objects belong to more than one group! (I will pick the first group I find.)"
)
Group = gl[0]
group = gl[0]

else:
Group = []
group = []

return (ZVector, Width, Height, Category, Group)
return (z_vector, width, height, category, group)
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@


class Attributes_Get_Custom(component):
def RunScript(self, RefCrv):
if not RefCrv:
def RunScript(self, ref_crv):
if not ref_crv:
self.AddRuntimeMessage(Warning, "Input parameter RefCrv failed to collect data")

AttributeName = []
AttributeValue = []

guid = RefCrv
guid = ref_crv
if guid:
attrdict = get_obj_attributes(guid)
if attrdict:
Expand Down
34 changes: 17 additions & 17 deletions src/compas_timber/ghpython/components/CT_Attributes_Set/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,41 +9,41 @@


class Attributes_Set(component):
def RunScript(self, RefObj, ZVector, Width, Height, Category, update):
_o = list_input_valid(self, RefObj, "RefObj")
def RunScript(self, ref_obj, z_vector, width, height, category, update):
_o = list_input_valid(self, ref_obj, "RefObj")
if not _o:
return

# requires at least one of these inputs to be not None
if ZVector or Width or Height or Category:
if z_vector or width or height or category:
pass
else:
self.AddRuntimeMessage(
Warning, "None of the input parameters 'ZVector', 'Width', 'Height', 'Category' collected any data."
)

n = len(RefObj)
n = len(ref_obj)

if ZVector:
if len(ZVector) not in (0, 1, n):
if z_vector:
if len(z_vector) not in (0, 1, n):
self.AddRuntimeMessage(
Error,
" Input parameter 'ZVector' requires either none, one or the same number of values as in refObj.",
)
if Width:
if len(Width) not in (0, 1, n):
if width:
if len(width) not in (0, 1, n):
self.AddRuntimeMessage(
Error,
" Input parameter 'Width' requires either none, one or the same number of values as in refObj.",
)
if Height:
if len(Height) not in (0, 1, n):
if height:
if len(height) not in (0, 1, n):
self.AddRuntimeMessage(
Error,
" Input parameter 'Height' requires either none, one or the same number of values as in refObj.",
)
if Category:
if len(Category) not in (0, 1, n):
if category:
if len(category) not in (0, 1, n):
self.AddRuntimeMessage(
Error,
" Input parameter 'Category' requires either none, one or the same number of values as in refObj.",
Expand All @@ -58,23 +58,23 @@ def get_item(items, i):
return items[i]

if update:
for i, ro in enumerate(RefObj):
for i, ro in enumerate(ref_obj):
guid = ro

# note: with input type set to Vector, it accepts only a Vector3d, or a string {x,y,z} and casts it to Vector3d
z = get_item(ZVector, i)
z = get_item(z_vector, i)
if z:
update_rhobj_attributes_name(guid, "zvector", "{%s,%s,%s}" % (z.X, z.Y, z.Z))

w = get_item(Width, i)
w = get_item(width, i)
if w:
update_rhobj_attributes_name(guid, "width", str(w))

h = get_item(Height, i)
h = get_item(height, i)
if h:
update_rhobj_attributes_name(guid, "height", str(h))

c = get_item(Category, i)
c = get_item(category, i)
if c:
update_rhobj_attributes_name(guid, "category", str(c))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@


class Attributes_Set_Custom(component):
def RunScript(self, RefObj, Attribute, update):
o = list_input_valid(self, RefObj, "RefObj")
a = list_input_valid(self, Attribute, "Attribute")
def RunScript(self, ref_obj, attribute, update):
o = list_input_valid(self, ref_obj, "RefObj")
a = list_input_valid(self, attribute, "Attribute")

if update and o and a:
for attr in Attribute:
for attr in attribute:
if attr:
for guid in RefObj:
for guid in ref_obj:
if guid:
update_rhobj_attributes_name(guid, attr.name, attr.value)

Expand Down
12 changes: 6 additions & 6 deletions src/compas_timber/ghpython/components/CT_BTLx/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@


class WriteBTLx(component):
def RunScript(self, Assembly, Path, Write):
if not Assembly:
def RunScript(self, assembly, path, write):
if not assembly:
self.AddRuntimeMessage(Warning, "Input parameter Assembly failed to collect data")
return

btlx = BTLx(Assembly)
btlx = BTLx(assembly)
btlx.history["FileName"] = Rhino.RhinoDoc.ActiveDoc.Name

if Write:
if not Path:
if write:
if not path:
self.AddRuntimeMessage(Warning, "Input parameter Path failed to collect data")
return
with open(Path, "w") as f:
with open(path, "w") as f:
f.write(btlx.btlx_string())
return btlx.btlx_string()
Loading
Loading