See #5938. This commit starts fixing this issue by:

- Fix wall decorator with obtuse angles.
- Preventing slabs from using obtuse angles, for now.
This commit is contained in:
Bruno Perdigão
2025-01-28 16:10:17 -03:00
parent ab0549daa6
commit d9903e93f2
3 changed files with 16 additions and 14 deletions
@@ -35,7 +35,7 @@ import bonsai.core.geometry
import bonsai.core.model as core import bonsai.core.model as core
import bonsai.tool as tool import bonsai.tool as tool
from bonsai.bim.ifc import IfcStore from bonsai.bim.ifc import IfcStore
from math import pi, sin, cos, degrees, tan from math import pi, sin, cos, degrees, tan, radians
from mathutils import Vector, Matrix, Quaternion from mathutils import Vector, Matrix, Quaternion
from bonsai.bim.module.model.opening import FilledOpeningGenerator from bonsai.bim.module.model.opening import FilledOpeningGenerator
from bonsai.bim.module.model.decorator import PolylineDecorator from bonsai.bim.module.model.decorator import PolylineDecorator
@@ -82,7 +82,9 @@ def get_wall_preview_data(context, relating_type):
height = float(model_props.extrusion_depth) height = float(model_props.extrusion_depth)
rl = float(model_props.rl1) rl = float(model_props.rl1)
x_angle = float(model_props.x_angle) x_angle = float(model_props.x_angle)
angle_distortion = height * tan(x_angle) if x_angle > radians(90) or x_angle < radians(-90):
height *= -1
angle_distance = height * tan(x_angle)
data = {} data = {}
data["verts"] = [] data["verts"] = []
@@ -109,8 +111,8 @@ def get_wall_preview_data(context, relating_type):
bm_base = create_bmesh_from_vertices(polyline_vertices, is_closed) bm_base = create_bmesh_from_vertices(polyline_vertices, is_closed)
base_vertices = tool.Cad.offset_edges(bm_base, offset) base_vertices = tool.Cad.offset_edges(bm_base, offset)
offset_base_verts = tool.Cad.offset_edges(bm_base, thickness + offset) offset_base_verts = tool.Cad.offset_edges(bm_base, thickness + offset)
top_vertices = tool.Cad.offset_edges(bm_base, angle_distortion + offset) top_vertices = tool.Cad.offset_edges(bm_base, angle_distance + offset)
offset_top_verts = tool.Cad.offset_edges(bm_base, angle_distortion + thickness + offset) offset_top_verts = tool.Cad.offset_edges(bm_base, angle_distance + thickness + offset)
if is_closed: if is_closed:
base_vertices.append(base_vertices[0]) base_vertices.append(base_vertices[0])
offset_base_verts.append(offset_base_verts[0]) offset_base_verts.append(offset_base_verts[0])
+8 -4
View File
@@ -21,7 +21,6 @@
import bpy import bpy
import copy import copy
import math import math
import bmesh
import ifcopenshell import ifcopenshell
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.util.unit import ifcopenshell.util.unit
@@ -42,7 +41,6 @@ from bonsai.bim.module.model.opening import FilledOpeningGenerator
from bonsai.bim.module.model.decorator import PolylineDecorator, ProductDecorator from bonsai.bim.module.model.decorator import PolylineDecorator, ProductDecorator
from bonsai.bim.module.model.polyline import PolylineOperator from bonsai.bim.module.model.polyline import PolylineOperator
from typing import Optional, assert_never, TYPE_CHECKING, get_args, Literal, Union, Any from typing import Optional, assert_never, TYPE_CHECKING, get_args, Literal, Union, Any
from lark import Lark, Transformer
class UnjoinWalls(bpy.types.Operator, tool.Ifc.Operator): class UnjoinWalls(bpy.types.Operator, tool.Ifc.Operator):
@@ -237,7 +235,13 @@ class ChangeExtrusionXAngle(bpy.types.Operator, tool.Ifc.Operator):
x, y, z = extrusion.ExtrudedDirection.DirectionRatios x, y, z = extrusion.ExtrudedDirection.DirectionRatios
existing_x_angle = tool.Model.get_existing_x_angle(extrusion) existing_x_angle = tool.Model.get_existing_x_angle(extrusion)
perpendicular_depth = extrusion.Depth / (1 / cos(existing_x_angle)) perpendicular_depth = extrusion.Depth / (1 / cos(existing_x_angle))
extrusion.Depth = perpendicular_depth * (1 / cos(x_angle)) if tool.Model.get_usage_type(element) == "LAYER2":
extrusion.Depth = abs(perpendicular_depth * (1 / cos(x_angle)))
if tool.Model.get_usage_type(element) == "LAYER3":
# TODO support angles between 91 and 179
if x_angle > radians(90) or x_angle < -radians(90):
return
extrusion.Depth = perpendicular_depth * (1 / cos(x_angle))
extrusion.ExtrudedDirection.DirectionRatios = (0.0, sin(x_angle), cos(x_angle)) extrusion.ExtrudedDirection.DirectionRatios = (0.0, sin(x_angle), cos(x_angle))
if tool.Model.get_usage_type(element) == "LAYER2": if tool.Model.get_usage_type(element) == "LAYER2":
layer2_objs.append(obj) layer2_objs.append(obj)
@@ -254,7 +258,7 @@ class ChangeExtrusionXAngle(bpy.types.Operator, tool.Ifc.Operator):
] ]
# The extrusion direction calculated previously default to the positive direction # The extrusion direction calculated previously default to the positive direction
# Here we set the extrusion direction to negative it that's the case # Here we set the extrusion direction to negative if that's the case
x, y, z = extrusion.ExtrudedDirection.DirectionRatios x, y, z = extrusion.ExtrudedDirection.DirectionRatios
layer_params = tool.Model.get_material_layer_parameters(element) layer_params = tool.Model.get_material_layer_parameters(element)
offset = layer_params["offset"] offset = layer_params["offset"]
+2 -6
View File
@@ -2075,10 +2075,6 @@ class Model(bonsai.core.tool.Model):
@classmethod @classmethod
def get_existing_x_angle(cls, extrusion): def get_existing_x_angle(cls, extrusion):
x, y, z = extrusion.ExtrudedDirection.DirectionRatios x, y, z = extrusion.ExtrudedDirection.DirectionRatios
# The existing angle result can change when the direction sense in Negative because the DirectionRatios may have negative y and z. x_angle = Vector((0, 1)).angle_signed(Vector((y, z)))
# For instance, a 30 degree angled slab, with negative direction will show as -150 degrees. To prevent that we do the following transformations
existing_x_angle = Vector((0, 1)).angle_signed(Vector((y, z)))
existing_x_angle = existing_x_angle + radians(180) if existing_x_angle < -radians(90) else existing_x_angle
existing_x_angle = existing_x_angle - radians(180) if existing_x_angle > radians(90) else existing_x_angle
return existing_x_angle return x_angle