This commit is contained in:
Andrej730
2025-11-05 19:18:11 +05:00
parent b46136e9f8
commit 6f04eb12d0
2 changed files with 42 additions and 39 deletions
+26 -23
View File
@@ -345,22 +345,24 @@ class BIMArrayProperties(PropertyGroup):
method: Literal["OFFSET", "DISTRIBUTE"] method: Literal["OFFSET", "DISTRIBUTE"]
sync_children: bool sync_children: bool
relating_array_object: Union[bpy.types.Object, None] relating_array_object: Union[bpy.types.Object, None]
def update_total_length_target(self: "BIMStairProperties", context: bpy.types.Context) -> None: def update_total_length_target(self: "BIMStairProperties", context: bpy.types.Context) -> None:
"""Update tread_run when total_length_target changes""" """Update tread_run when total_length_target changes"""
# Calculate available length for default treads # Calculate available length for default treads
available_length = self.total_length_target available_length = self.total_length_target
n_default_treads = self.number_of_treads + 1 # number of risers n_default_treads = self.number_of_treads + 1 # number of risers
# Subtract custom first tread if not locked and not zero # Subtract custom first tread if not locked and not zero
if not self.custom_tread_lock and self.custom_first_last_tread_run[0] != 0: if not self.custom_tread_lock and self.custom_first_last_tread_run[0] != 0:
available_length -= self.custom_first_last_tread_run[0] available_length -= self.custom_first_last_tread_run[0]
n_default_treads -= 1 n_default_treads -= 1
# Subtract custom last tread if not locked and not zero # Subtract custom last tread if not locked and not zero
if not self.custom_tread_lock and self.custom_first_last_tread_run[1] != 0: if not self.custom_tread_lock and self.custom_first_last_tread_run[1] != 0:
available_length -= self.custom_first_last_tread_run[1] available_length -= self.custom_first_last_tread_run[1]
n_default_treads -= 1 n_default_treads -= 1
# Calculate tread_run for remaining treads # Calculate tread_run for remaining treads
if n_default_treads > 0: if n_default_treads > 0:
self["tread_run"] = available_length / n_default_treads self["tread_run"] = available_length / n_default_treads
@@ -375,7 +377,7 @@ def update_tread_run(self: "BIMStairProperties", context: bpy.types.Context) ->
# Calculate how much length custom treads take up # Calculate how much length custom treads take up
custom_length = 0 custom_length = 0
n_custom_treads = 0 n_custom_treads = 0
if not self.custom_tread_lock: if not self.custom_tread_lock:
if self.custom_first_last_tread_run[0] != 0: if self.custom_first_last_tread_run[0] != 0:
custom_length += self.custom_first_last_tread_run[0] custom_length += self.custom_first_last_tread_run[0]
@@ -383,7 +385,7 @@ def update_tread_run(self: "BIMStairProperties", context: bpy.types.Context) ->
if self.custom_first_last_tread_run[1] != 0: if self.custom_first_last_tread_run[1] != 0:
custom_length += self.custom_first_last_tread_run[1] custom_length += self.custom_first_last_tread_run[1]
n_custom_treads += 1 n_custom_treads += 1
# Calculate how many default treads fit in remaining space # Calculate how many default treads fit in remaining space
available_length = self.total_length_target - custom_length available_length = self.total_length_target - custom_length
if self.tread_run > 0: if self.tread_run > 0:
@@ -395,7 +397,7 @@ def update_tread_run(self: "BIMStairProperties", context: bpy.types.Context) ->
# Calculate total length from current settings # Calculate total length from current settings
n_default_treads = self.number_of_treads + 1 n_default_treads = self.number_of_treads + 1
total_length = 0 total_length = 0
if not self.custom_tread_lock: if not self.custom_tread_lock:
if self.custom_first_last_tread_run[0] != 0: if self.custom_first_last_tread_run[0] != 0:
total_length += self.custom_first_last_tread_run[0] total_length += self.custom_first_last_tread_run[0]
@@ -403,7 +405,7 @@ def update_tread_run(self: "BIMStairProperties", context: bpy.types.Context) ->
if self.custom_first_last_tread_run[1] != 0: if self.custom_first_last_tread_run[1] != 0:
total_length += self.custom_first_last_tread_run[1] total_length += self.custom_first_last_tread_run[1]
n_default_treads -= 1 n_default_treads -= 1
total_length += n_default_treads * self.tread_run total_length += n_default_treads * self.tread_run
self["total_length_target"] = total_length self["total_length_target"] = total_length
@@ -414,7 +416,7 @@ def update_number_of_treads(self: "BIMStairProperties", context: bpy.types.Conte
# Calculate available length for default treads # Calculate available length for default treads
available_length = self.total_length_target available_length = self.total_length_target
n_default_treads = self.number_of_treads + 1 n_default_treads = self.number_of_treads + 1
if not self.custom_tread_lock: if not self.custom_tread_lock:
if self.custom_first_last_tread_run[0] != 0: if self.custom_first_last_tread_run[0] != 0:
available_length -= self.custom_first_last_tread_run[0] available_length -= self.custom_first_last_tread_run[0]
@@ -422,7 +424,7 @@ def update_number_of_treads(self: "BIMStairProperties", context: bpy.types.Conte
if self.custom_first_last_tread_run[1] != 0: if self.custom_first_last_tread_run[1] != 0:
available_length -= self.custom_first_last_tread_run[1] available_length -= self.custom_first_last_tread_run[1]
n_default_treads -= 1 n_default_treads -= 1
if n_default_treads > 0: if n_default_treads > 0:
self["tread_run"] = available_length / n_default_treads self["tread_run"] = available_length / n_default_treads
else: else:
@@ -431,7 +433,7 @@ def update_number_of_treads(self: "BIMStairProperties", context: bpy.types.Conte
# Calculate total length from current settings # Calculate total length from current settings
n_default_treads = self.number_of_treads + 1 n_default_treads = self.number_of_treads + 1
total_length = 0 total_length = 0
if not self.custom_tread_lock: if not self.custom_tread_lock:
if self.custom_first_last_tread_run[0] != 0: if self.custom_first_last_tread_run[0] != 0:
total_length += self.custom_first_last_tread_run[0] total_length += self.custom_first_last_tread_run[0]
@@ -439,7 +441,7 @@ def update_number_of_treads(self: "BIMStairProperties", context: bpy.types.Conte
if self.custom_first_last_tread_run[1] != 0: if self.custom_first_last_tread_run[1] != 0:
total_length += self.custom_first_last_tread_run[1] total_length += self.custom_first_last_tread_run[1]
n_default_treads -= 1 n_default_treads -= 1
total_length += n_default_treads * self.tread_run total_length += n_default_treads * self.tread_run
self["total_length_target"] = total_length self["total_length_target"] = total_length
@@ -450,7 +452,7 @@ def update_custom_first_last_tread_run(self: "BIMStairProperties", context: bpy.
# Recalculate tread_run to maintain total length # Recalculate tread_run to maintain total length
available_length = self.total_length_target available_length = self.total_length_target
n_default_treads = self.number_of_treads + 1 n_default_treads = self.number_of_treads + 1
if not self.custom_tread_lock: if not self.custom_tread_lock:
if self.custom_first_last_tread_run[0] != 0: if self.custom_first_last_tread_run[0] != 0:
available_length -= self.custom_first_last_tread_run[0] available_length -= self.custom_first_last_tread_run[0]
@@ -458,14 +460,14 @@ def update_custom_first_last_tread_run(self: "BIMStairProperties", context: bpy.
if self.custom_first_last_tread_run[1] != 0: if self.custom_first_last_tread_run[1] != 0:
available_length -= self.custom_first_last_tread_run[1] available_length -= self.custom_first_last_tread_run[1]
n_default_treads -= 1 n_default_treads -= 1
if n_default_treads > 0: if n_default_treads > 0:
self["tread_run"] = available_length / n_default_treads self["tread_run"] = available_length / n_default_treads
else: else:
# Recalculate total length # Recalculate total length
n_default_treads = self.number_of_treads + 1 n_default_treads = self.number_of_treads + 1
total_length = 0 total_length = 0
if not self.custom_tread_lock: if not self.custom_tread_lock:
if self.custom_first_last_tread_run[0] != 0: if self.custom_first_last_tread_run[0] != 0:
total_length += self.custom_first_last_tread_run[0] total_length += self.custom_first_last_tread_run[0]
@@ -473,10 +475,11 @@ def update_custom_first_last_tread_run(self: "BIMStairProperties", context: bpy.
if self.custom_first_last_tread_run[1] != 0: if self.custom_first_last_tread_run[1] != 0:
total_length += self.custom_first_last_tread_run[1] total_length += self.custom_first_last_tread_run[1]
n_default_treads -= 1 n_default_treads -= 1
total_length += n_default_treads * self.tread_run total_length += n_default_treads * self.tread_run
self["total_length_target"] = total_length self["total_length_target"] = total_length
StairType = Literal["CONCRETE", "WOOD/STEEL", "GENERIC"] StairType = Literal["CONCRETE", "WOOD/STEEL", "GENERIC"]
@@ -531,14 +534,14 @@ class BIMStairProperties(PropertyGroup):
update=update_custom_tread_lock, update=update_custom_tread_lock,
) )
custom_first_last_tread_run: bpy.props.FloatVectorProperty( custom_first_last_tread_run: bpy.props.FloatVectorProperty(
name="Custom First / Last Treads Widths", name="Custom First / Last Treads Widths",
description='Specify custom first / last treads widths, different from the general "Tread Run". Leave 0 to disable.', description='Specify custom first / last treads widths, different from the general "Tread Run". Leave 0 to disable.',
default=(0, 0), default=(0, 0),
min=0, min=0,
unit="LENGTH", unit="LENGTH",
size=2, size=2,
update=update_custom_first_last_tread_run, # Added update callback update=update_custom_first_last_tread_run, # Added update callback
) )
nosing_length: bpy.props.FloatProperty( nosing_length: bpy.props.FloatProperty(
name="Nosing Length", name="Nosing Length",
description=( description=(
+16 -16
View File
@@ -1324,7 +1324,7 @@ class Model(bonsai.core.tool.Model):
@classmethod @classmethod
def is_parametric_door_active(cls) -> bool: def is_parametric_door_active(cls) -> bool:
return bool((DoorData.is_loaded or not DoorData.load()) and DoorData.data["pset_data"]) return bool((DoorData.is_loaded or not DoorData.load()) and DoorData.data["pset_data"])
@classmethod @classmethod
def get_active_stair_calculated_params(cls, pset_data: Optional[dict[str, Any]] = None) -> dict[str, Any]: def get_active_stair_calculated_params(cls, pset_data: Optional[dict[str, Any]] = None) -> dict[str, Any]:
props = bpy.context.active_object.BIMStairProperties props = bpy.context.active_object.BIMStairProperties
@@ -1355,20 +1355,20 @@ class Model(bonsai.core.tool.Model):
# Start with all treads using default tread_run # Start with all treads using default tread_run
n_default_tread_runs = number_of_rises n_default_tread_runs = number_of_rises
length = 0 length = 0
# If first tread has custom width (non-zero), use it instead of default # If first tread has custom width (non-zero), use it instead of default
if first_tread_run != 0: if first_tread_run != 0:
n_default_tread_runs -= 1 n_default_tread_runs -= 1
length += first_tread_run length += first_tread_run
# If last tread has custom width (non-zero), use it instead of default # If last tread has custom width (non-zero), use it instead of default
if last_tread_run != 0: if last_tread_run != 0:
n_default_tread_runs -= 1 n_default_tread_runs -= 1
length += last_tread_run length += last_tread_run
# Add remaining default tread runs # Add remaining default tread runs
length += tread_run * n_default_tread_runs length += tread_run * n_default_tread_runs
# Handle nosing length effects on total length # Handle nosing length effects on total length
# Nosing overlaps don't affect tread run spacing, # Nosing overlaps don't affect tread run spacing,
# but the first tread's nosing extends the total length # but the first tread's nosing extends the total length
@@ -1376,7 +1376,7 @@ class Model(bonsai.core.tool.Model):
length += nosing_length length += nosing_length
if nosing_length < 0: # tread gaps between treads if nosing_length < 0: # tread gaps between treads
length += abs(nosing_length) * number_of_treads length += abs(nosing_length) * number_of_treads
calculated_params["Length"] = round(length, 5) calculated_params["Length"] = round(length, 5)
pitch = height / length pitch = height / length
pitch_formatted = str(round(pitch * 100, 1)) + " % / " + str(round(degrees(atan(pitch)), 1)) + " deg" pitch_formatted = str(round(pitch * 100, 1)) + " % / " + str(round(degrees(atan(pitch)), 1)) + " deg"
@@ -1415,9 +1415,9 @@ class Model(bonsai.core.tool.Model):
nosing_overlap_offset = -V_(nosing_overlap, 0) nosing_overlap_offset = -V_(nosing_overlap, 0)
# ============ DEBUG LOGGING START ============ # ============ DEBUG LOGGING START ============
print("\n" + "="*80) print("\n" + "=" * 80)
print("STAIR GENERATION DEBUG - WOOD/STEEL TYPE") print("STAIR GENERATION DEBUG - WOOD/STEEL TYPE")
print("="*80) print("=" * 80)
print(f"Input Parameters:") print(f"Input Parameters:")
print(f" stair_type: {stair_type}") print(f" stair_type: {stair_type}")
print(f" number_of_treads: {number_of_treads}") print(f" number_of_treads: {number_of_treads}")
@@ -1433,7 +1433,7 @@ class Model(bonsai.core.tool.Model):
print(f" nosing_overlap: {nosing_overlap}") print(f" nosing_overlap: {nosing_overlap}")
print(f" nosing_tread_gap: {nosing_tread_gap}") print(f" nosing_tread_gap: {nosing_tread_gap}")
print(f" nosing_overlap_offset: {nosing_overlap_offset}") print(f" nosing_overlap_offset: {nosing_overlap_offset}")
print("="*80 + "\n") print("=" * 80 + "\n")
# ============ DEBUG LOGGING END ============ # ============ DEBUG LOGGING END ============
def define_generic_stair_treads(): def define_generic_stair_treads():
@@ -1499,10 +1499,10 @@ class Model(bonsai.core.tool.Model):
current_offset += tread_offset current_offset += tread_offset
if stair_type == "WOOD/STEEL": if stair_type == "WOOD/STEEL":
print("\n" + "-"*80) print("\n" + "-" * 80)
print("WOOD/STEEL STAIR GENERATION PROCESS") print("WOOD/STEEL STAIR GENERATION PROCESS")
print("-"*80) print("-" * 80)
builder = ShapeBuilder(None) builder = ShapeBuilder(None)
# full tread rectangle # full tread rectangle
@@ -1555,10 +1555,10 @@ class Model(bonsai.core.tool.Model):
# each tread is a separate shape # each tread is a separate shape
cur_offset = V_(0, 0) cur_offset = V_(0, 0)
tread_index = 0 tread_index = 0
print(f"\nGenerating Treads:") print(f"\nGenerating Treads:")
print(f" Number of risers to process: {number_of_risers}") print(f" Number of risers to process: {number_of_risers}")
for i in range(number_of_risers): for i in range(number_of_risers):
tread_offset, tread_verts = get_tread_data(i) tread_offset, tread_verts = get_tread_data(i)
@@ -1567,7 +1567,7 @@ class Model(bonsai.core.tool.Model):
cur_trade_shape = [v + cur_offset + nosing_overlap_offset for v in tread_verts] cur_trade_shape = [v + cur_offset + nosing_overlap_offset for v in tread_verts]
print(f" Adding geometry at cur_offset: {cur_offset}") print(f" Adding geometry at cur_offset: {cur_offset}")
print(f" Final vertices (after offset): {cur_trade_shape}") print(f" Final vertices (after offset): {cur_trade_shape}")
vertices.extend(cur_trade_shape) vertices.extend(cur_trade_shape)
cur_vertex = tread_index * 4 cur_vertex = tread_index * 4
@@ -1590,7 +1590,7 @@ class Model(bonsai.core.tool.Model):
print(f" Total vertices: {len(vertices)}") print(f" Total vertices: {len(vertices)}")
print(f" Total edges: {len(edges)}") print(f" Total edges: {len(edges)}")
print(f" Total treads generated: {tread_index}") print(f" Total treads generated: {tread_index}")
print("-"*80 + "\n") print("-" * 80 + "\n")
elif stair_type == "GENERIC": elif stair_type == "GENERIC":
define_generic_stair_treads() define_generic_stair_treads()