Merge branch 'v0.8.0' into ifcmax/initial-refresh

This commit is contained in:
Josef Wienerroither
2026-02-13 10:24:14 +01:00
6 changed files with 26 additions and 13 deletions
@@ -211,22 +211,21 @@ class PolylineOperator:
context.workspace.status_text_set(draw_instructions) context.workspace.status_text_set(draw_instructions)
def handle_lock_axis(self, context: bpy.types.Context, event: bpy.types.Event) -> None: def handle_lock_axis(self, context: bpy.types.Context, event: bpy.types.Event) -> None:
angle_snap = tool.Snap.get_angle_snap_value(context)
if event.value == "PRESS" and event.type == "A": if event.value == "PRESS" and event.type == "A":
self.tool_state.lock_axis = False if self.tool_state.lock_axis else True self.tool_state.lock_axis = False if self.tool_state.lock_axis else True
if self.tool_state.lock_axis: if self.tool_state.lock_axis:
self.tool_state.snap_angle = self.input_ui.get_number_value("WORLD_ANGLE") self.tool_state.snap_angle = self.input_ui.get_number_value("WORLD_ANGLE")
# Round to the closest 5 self.tool_state.snap_angle = round(self.tool_state.snap_angle / angle_snap) * angle_snap
self.tool_state.snap_angle = round(self.tool_state.snap_angle / 5) * 5
if event.shift and event.type in {"WHEELUPMOUSE", "WHEELDOWNMOUSE"}: if event.shift and event.type in {"WHEELUPMOUSE", "WHEELDOWNMOUSE"}:
self.tool_state.lock_axis = True self.tool_state.lock_axis = True
self.tool_state.snap_angle = self.input_ui.get_number_value("WORLD_ANGLE") self.tool_state.snap_angle = self.input_ui.get_number_value("WORLD_ANGLE")
# Round to the closest 5 self.tool_state.snap_angle = round(self.tool_state.snap_angle / angle_snap) * angle_snap
self.tool_state.snap_angle = round(self.tool_state.snap_angle / 5) * 5
if event.type in {"WHEELUPMOUSE"}: if event.type in {"WHEELUPMOUSE"}:
self.tool_state.snap_angle += 5 self.tool_state.snap_angle += angle_snap
else: else:
self.tool_state.snap_angle -= 5 self.tool_state.snap_angle -= angle_snap
self.handle_mouse_move(context, event) self.handle_mouse_move(context, event)
detected_snaps = tool.Snap.detect_snapping_points(context, event, self.objs_2d_bbox, self.tool_state) detected_snaps = tool.Snap.detect_snapping_points(context, event, self.objs_2d_bbox, self.tool_state)
self.snapping_points = tool.Snap.select_snapping_points(context, event, self.tool_state, detected_snaps) self.snapping_points = tool.Snap.select_snapping_points(context, event, self.tool_state, detected_snaps)
@@ -17,7 +17,7 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>. # along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import copy import copy
from math import atan2, degrees, pi from math import atan2, degrees, pi, radians
from typing import Any, Literal, Optional, Union from typing import Any, Literal, Optional, Union
import bmesh import bmesh
@@ -195,8 +195,8 @@ class DumbProfileGenerator:
if should_round: if should_round:
# Round to nearest 50mm (yes, metric for now) # Round to nearest 50mm (yes, metric for now)
self.length = 0.05 * round(length / 0.05) self.length = 0.05 * round(length / 0.05)
# Round to nearest 5 degrees angle_snap = tool.Snap.get_angle_snap_value(bpy.context)
nearest_degree = (pi / 180) * 5 nearest_degree = radians(angle_snap)
self.rotation = nearest_degree * round(self.rotation / nearest_degree) self.rotation = nearest_degree * round(self.rotation / nearest_degree)
self.location = coords[0] self.location = coords[0]
data["obj"] = self.create_profile() data["obj"] = self.create_profile()
+2 -2
View File
@@ -916,8 +916,8 @@ class DumbWallGenerator:
if should_round: if should_round:
# Round to nearest 50mm (yes, metric for now) # Round to nearest 50mm (yes, metric for now)
self.length = 0.05 * round(length / 0.05) self.length = 0.05 * round(length / 0.05)
# Round to nearest 5 degrees angle_snap = tool.Snap.get_angle_snap_value(bpy.context)
nearest_degree = (math.pi / 180) * 5 nearest_degree = math.radians(angle_snap)
self.rotation = nearest_degree * round(self.rotation / nearest_degree) self.rotation = nearest_degree * round(self.rotation / nearest_degree)
self.location = coords[0] self.location = coords[0]
data["obj"] = self.create_wall() data["obj"] = self.create_wall()
+2 -1
View File
@@ -191,7 +191,8 @@ class Polyline(bonsai.core.tool.Polyline):
orientation_angle = 0 orientation_angle = 0
if input_ui: if input_ui:
if should_round: if should_round:
angle = 5 * round(angle / 5) if distance < angle_round_threshold else angle angle_snap = tool.Snap.get_angle_snap_value(context)
angle = angle_snap * round(angle / angle_snap) if distance < angle_round_threshold else angle
factor = tool.Snap.get_increment_snap_value(context) factor = tool.Snap.get_increment_snap_value(context)
distance = factor * round(distance / factor) distance = factor * round(distance / factor)
input_ui.set_value("X", mouse_vector.x) input_ui.set_value("X", mouse_vector.x)
+13
View File
@@ -114,6 +114,19 @@ class Snap(bonsai.core.tool.Snap):
return increment return increment
@classmethod
def get_angle_snap_value(cls, context: bpy.types.Context) -> float:
"""Get the angle snap increment from Blender's tool settings.
Uses snap_angle_increment_3d (Blender 5.0+) or snap_angle_increment (Blender 4.x).
:param context: Blender context
:return: Angle snap increment in degrees
"""
if bpy.app.version >= (5, 0, 0):
return math.degrees(context.scene.tool_settings.snap_angle_increment_3d)
return math.degrees(context.scene.tool_settings.snap_angle_increment)
@classmethod @classmethod
def get_snap_points_on_raycasted_face(cls, context, event, obj, face_index): def get_snap_points_on_raycasted_face(cls, context, event, obj, face_index):
matrix = obj.matrix_world.copy() matrix = obj.matrix_world.copy()
+1 -1
View File
@@ -746,7 +746,7 @@ namespace {
static std::string format_double(const double& d) { static std::string format_double(const double& d) {
std::ostringstream oss; std::ostringstream oss;
oss.imbue(std::locale::classic()); oss.imbue(std::locale::classic());
oss << std::setprecision(std::numeric_limits<double>::digits10) << d; oss << std::setprecision(std::numeric_limits<double>::max_digits10) << d;
const std::string str = oss.str(); const std::string str = oss.str();
oss.str(""); oss.str("");
std::string::size_type e = str.find('e'); std::string::size_type e = str.find('e');