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

Gh bake rework #290

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

* Merged both Grasshopper Bake Components into one.

### Removed


Expand Down
87 changes: 55 additions & 32 deletions src/compas_timber/ghpython/components/CT_Bake_BoxMap/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import math
import random

import scriptcontext as sc
import Rhino
import rhinoscriptsyntax as rs
from compas_rhino.conversions import frame_to_rhino
from ghpythonlib.componentbase import executingcomponent as component
Expand All @@ -14,44 +16,46 @@


class BakeBoxMap(component):
def RunScript(self, model, map_size, bake):
if map_size and len(map_size) != 3:
self.AddRuntimeMessage(
Error, "Input parameter MapSize requires exactly three float values (scale factors in x,y,z directions)"
)
return

if map_size:
dimx, dimy, dimz = map_size
else:
# for the pine 251 material bitmap, rotated
dimx = 0.2
dimy = 0.2
dimz = 1.0
def RunScript(self, model, beam_map_size, plate_map_size, beam_layer_name, plate_layer_name, swap_uv, bake):
def get_dimensions(map_size, default):
return map_size if map_size else default

# Check if model exists and baking is enabled
if not model:
self.AddRuntimeMessage(Warning, "Input parameters Model failed to collect any Beam objects.")
return

if not bake:
if not bake: # Exit early if bake is False
return

try:
frames = [frame_to_rhino(b.frame) for b in model.beams]
breps = [beam.geometry.native_brep for beam in model.beams]
# Switch document context to Rhino's active document for baking
sc.doc = Rhino.RhinoDoc.ActiveDoc

# Define dimensions
b_dimx, b_dimy, b_dimz = get_dimensions(beam_map_size, [0.2, 0.2, 1.0])
p_dimx, p_dimy, p_dimz = get_dimensions(plate_map_size, [1.0, 1.0, 1.0])

# Bake beams
beam_frames = [frame_to_rhino(b.frame) for b in model.beams]
beam_breps = [beam.geometry.native_brep for beam in model.beams]
self.add_brep_to_document(beam_breps, beam_frames, beam_layer_name, b_dimx, b_dimy, b_dimz, False)

if frames and breps:
rs.EnableRedraw(False)
# Bake plates
plate_frames = [frame_to_rhino(p.frame) for p in model.plates]
plate_breps = [plate.geometry.native_brep for plate in model.plates]
self.add_brep_to_document(plate_breps, plate_frames, plate_layer_name, p_dimx, p_dimy, p_dimz, swap_uv)

for brep, frame in zip(breps, frames):
guid = ActiveDoc.Objects.Add(brep)
boxmap = self.create_box_map(frame, dimx, dimy, dimz)
ActiveDoc.Objects.ModifyTextureMapping(guid, 1, boxmap)
finally:
# Restore document context back to Grasshopper
sc.doc = ghdoc
jonashaldemann marked this conversation as resolved.
Show resolved Hide resolved

# Enabling redraw after baking
rs.EnableRedraw(True)


@staticmethod
def create_box_map(pln, sx, sy, sz):
def create_box_map(pln, sx, sy, sz, swap_uv):
"""
pln: frame of beam box, where x=main axis, y=width, z=height
sx,sy,sz: box map size in x,y,z direction
Expand All @@ -61,14 +65,9 @@ def create_box_map(pln, sx, sy, sz):
w = pln.ZAxis
pt = pln.Origin

# random deviation
a = math.pi * 0.5
randangle = (random.random() - 0.5) * a
v.Rotate(randangle, pln.XAxis)

b = math.pi * 0.01
randangle = (random.random() - 0.5) * b
w.Rotate(randangle, pln.XAxis)
# Apply random deviation
v.Rotate(BakeBoxMap.random_rotation_angle(math.pi * 0.5), pln.XAxis)
w.Rotate(BakeBoxMap.random_rotation_angle(math.pi * 0.01), pln.XAxis)

randpos = sx * random.random()
pt += pln.XAxis * randpos
Expand All @@ -78,7 +77,31 @@ def create_box_map(pln, sx, sy, sz):
dx = Interval(-sx * 0.5, sx * 0.5)
dy = Interval(-sy * 0.5, sy * 0.5)
dz = Interval(-sz * 0.5, sz * 0.5)
if swap_uv:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so is it ok that there's only one swap_uv? this will flip the coordinates for both beams and plates right? can it be user might want to flip for just one of them?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've set swap_uv of the Beams to False, because we usually don't need it (yet):
self.add_brep_to_document(beam_breps, beam_frames, beam_layer_name, b_dimx, b_dimy, b_dimz, False)

But is there a clever way to avoid this unnecessary setting in this case without duplicating too many lines to solve Beams & Plates?

mappingPln.Rotate(math.radians(90), mappingPln.XAxis)

BoxMap = Render.TextureMapping.CreateBoxMapping(mappingPln, dx, dy, dz, False)

return BoxMap

@staticmethod
def add_brep_to_document(breps, frames, layer_name, b_dimx, b_dimy, b_dimz, swap_uv):
if frames and breps:
rs.EnableRedraw(False)

for brep, frame in zip(breps, frames):
guid = sc.doc.Objects.Add(brep)
if layer_name:
BakeBoxMap.ensure_layer_exists(layer_name)
rs.ObjectLayer(guid, layer_name)
boxmap = BakeBoxMap.create_box_map(frame, b_dimx, b_dimy, b_dimz, swap_uv)
sc.doc.Objects.ModifyTextureMapping(guid, 1, boxmap)

@staticmethod
def ensure_layer_exists(layer_name):
if not rs.IsLayer(layer_name):
rs.AddLayer(layer_name)

@staticmethod
def random_rotation_angle(max_angle):
return (random.random() - 0.5) * max_angle
30 changes: 27 additions & 3 deletions src/compas_timber/ghpython/components/CT_Bake_BoxMap/metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"nickname": "BakeWithBoxMap",
"category": "COMPAS Timber",
"subcategory": "Utils",
"description": "Bakes Beam objects with a BoxMapping (by default the material is applied 'by layer' and has to be defined in the layer the objects are baked to).",
"description": "Bakes the Model with a Box Mapping on Beams and Plates.",
"exposure": 4,
"ghpython": {
"isAdvancedMode": true,
Expand All @@ -16,11 +16,35 @@
"scriptParamAccess": 0
},
{
"name": "MapSize",
"description": "Scaling of the BoxMap in x,y,z directions (list of three positive values) (optional).",
"name": "BeamMapSize",
"description": "Scaling of the BoxMap for Beams in x,y,z directions (list of three positive values) (optional).",
"typeHintID": "float",
"scriptParamAccess": 1
},
{
"name": "PlateMapSize",
"description": "Scaling of the BoxMap for Plates in x,y,z directions (list of three positive values) (optional).",
"typeHintID": "float",
"scriptParamAccess": 1
},
{
"name": "BeamLayerName",
"description": "Layer onto which the Beams are to be baked (optional).",
"typeHintID": "str",
"scriptParamAccess": 0
},
{
"name": "PlateLayerName",
"description": "Layer onto which the Plates are to be baked (optional).",
"typeHintID": "str",
"scriptParamAccess": 0
},
{
"name": "SwapUV",
"description": "Rotates the BoxMap 90 degrees (optional).",
"typeHintID": "bool",
"scriptParamAccess": 0
},
{
"name": "Bake",
"description": "Set to True to Bake. Nothing happens if None or False.",
Expand Down
85 changes: 0 additions & 85 deletions src/compas_timber/ghpython/components/CT_Bake_PlateBoxMap/code.py

This file was deleted.

Binary file not shown.

This file was deleted.

Loading