Changed input validantion to Snap tool

This commit is contained in:
Bruno Perdigão
2024-08-13 17:32:57 -03:00
committed by Bruno Perdigão
parent d1d9db3ed8
commit b137197586
3 changed files with 94 additions and 12 deletions
@@ -21,7 +21,7 @@ import gpu
import gpu_extras
import bmesh
import bonsai.tool as tool
from math import sin, cos, radians
from math import sin, cos, radians, degrees, atan2, acos
from bpy.types import SpaceView3D
from mathutils import Vector, Matrix
from gpu_extras.batch import batch_for_shader
@@ -343,12 +343,22 @@ class WallPolylineDecorator:
@classmethod
def calculate_distance_and_angle(cls, context, is_input_on):
def calculate_angle(snap_vector, last_point, second_to_last_point):
v1 = snap_vector - last_point
v2 = last_point - second_to_last_point
cos_angle = (v1.dot(v2)) / (v1.length * v2.length)
if cos_angle > 1:
cos_angle = 1
angle = acos(cos_angle)
return degrees(angle)
try:
polyline_data = context.scene.BIMModelProperties.polyline_point
default_container_elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z
last_point_data = polyline_data[len(polyline_data) - 1]
except:
last_point_data = None
second_to_last_point_data = None
default_container_elevation = 0
snap_prop = context.scene.BIMModelProperties.snap_mouse_point[0]
@@ -358,6 +368,11 @@ class WallPolylineDecorator:
else:
last_point = Vector((0, 0, 0))
second_to_last_point = None
if len(polyline_data) > 1:
second_to_last_point_data = polyline_data[len(polyline_data) - 2]
second_to_last_point = Vector((second_to_last_point_data.x, second_to_last_point_data.y, second_to_last_point_data.z))
if is_input_on:
snap_vector = Vector(
(float(cls.input_panel["X"]), float(cls.input_panel["Y"]), default_container_elevation)
@@ -373,12 +388,22 @@ class WallPolylineDecorator:
Vector((0, 0)),
Vector((1, 0)),
)
if second_to_last_point:
previous_axis = (
Vector((second_to_last_point.x, second_to_last_point.y)),
Vector((last_point.x, last_point.y)),
)
else:
second_to_last_point = Vector((last_point.x + 10, last_point.y, last_point.z))
previous_axis = x_axis_edge
current_axis = (
Vector((last_point.x, last_point.y)),
Vector((snap_vector.x, snap_vector.y)),
)
if distance > 0:
angle = tool.Cad.angle_edges(x_axis_edge, current_axis, degrees=True, signed=True)
angle = tool.Cad.angle_3_vectors(snap_vector, last_point, second_to_last_point, degrees=True)
angle = 180 - angle
if cls.input_panel:
cls.input_panel["X"] = str(round(snap_vector.x, 4))
cls.input_panel["Y"] = str(round(snap_vector.y, 4))
@@ -400,11 +425,20 @@ class WallPolylineDecorator:
return
last_point = Vector((last_point_data.x, last_point_data.y, last_point_data.z))
second_to_last_point = None
if len(polyline_data) > 2:
second_to_last_point_data = polyline_data[len(polyline_data) - 2]
second_to_last_point = Vector((second_to_last_point_data.x, second_to_last_point_data.y, second_to_last_point_data.z))
else:
second_to_last_point = Vector((0, 0, 0))
distance = float(cls.input_panel["D"])
if distance < 0 or distance > 0:
angle_degrees = float(cls.input_panel["A"])
angle_radians = radians(360 - angle_degrees) # Substracting from 360 to make it clockwise
reference_vector = second_to_last_point - last_point
reference_angle = degrees(atan2(reference_vector[1], reference_vector[0]))
angle_radians = radians(360 - (angle_degrees - reference_angle)) # Substracting from 360 to make it clockwise
x = last_point[0] + distance * cos(angle_radians)
y = last_point[1] + distance * sin(angle_radians)
if cls.input_panel:
@@ -503,11 +537,9 @@ class WallPolylineDecorator:
# Line between last polyline point and mouse
edges = [[0, 1]]
if polyline_points:
print("PP", polyline_points)
if snap_prop.snap_type != "Plane" and projection_point:
self.draw_batch("LINES", [polyline_points[-1]] + projection_point, decorator_color_unselected, edges)
else:
print("FOI")
self.draw_batch("LINES", [polyline_points[-1]] + mouse_point, decorator_color_unselected, edges)
# Line for angle axis snap
+7 -7
View File
@@ -285,7 +285,6 @@ class DrawPolylineWall(bpy.types.Operator):
bl_label = "Draw Polyline Wall"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
return context.space_data.type == "VIEW_3D"
@@ -482,14 +481,18 @@ class DrawPolylineWall(bpy.types.Operator):
def recalculate_inputs(self, context):
if self.number_input:
is_valid, self.number_output = self.validate_input(self.number_output)
is_valid, self.number_output = tool.Snap.validate_input(self.number_output)
self.input_panel[self.input_type] = self.number_output
if is_valid:
if not is_valid:
self.report({"WARNING"}, "The number typed is not valid.")
else:
if self.input_type in {"X", "Y"}:
self.input_panel = WallPolylineDecorator.calculate_distance_and_angle(context, self.is_input_on)
elif self.input_type in {"D", "A"}:
self.input_panel = WallPolylineDecorator.calculate_x_and_y(context)
self.input_panel[self.input_type] = self.number_output
WallPolylineDecorator.set_input_panel(self.input_panel, self.input_type)
tool.Blender.update_viewport()
@@ -509,15 +512,12 @@ class DrawPolylineWall(bpy.types.Operator):
relating_type = tool.Ifc.get().by_id(int(relating_type_id))
walls, is_polyline_closed = DumbWallGenerator(relating_type).generate(True)
print(is_polyline_closed)
if walls:
if is_polyline_closed:
for wall1, wall2 in zip(walls, walls[1:] + [walls[0]]):
print(wall1["obj"], wall2["obj"])
DumbWallJoiner().join_V(wall1["obj"], wall2["obj"])
else:
for wall1, wall2 in zip(walls[:-1], walls[1:]):
print(wall1["obj"], wall2["obj"])
DumbWallJoiner().join_V(wall1["obj"], wall2["obj"])
def modal(self, context, event):
@@ -660,7 +660,7 @@ class DrawPolylineWall(bpy.types.Operator):
WallPolylineDecorator.install(context)
tool.Snap.set_use_default_container(True)
WallPolylineDecorator.set_use_default_container(True)
tool.Snap.set_snap_plane_method('XY')
tool.Snap.set_snap_plane_method("XY")
WallPolylineDecorator.set_input_panel(self.input_panel, self.input_type)
self.visible_objs = tool.Raycast.get_visible_objects(context)
for obj in self.visible_objs:
+50
View File
@@ -23,6 +23,7 @@ from bonsai.bim.module.model.decorator import WallPolylineDecorator
import math
import mathutils
from mathutils import Matrix, Vector
from lark import Lark, Transformer
class Snap(bonsai.core.tool.Snap):
@@ -327,3 +328,52 @@ class Snap(bonsai.core.tool.Snap):
cls.update_snaping_point(rot_intersection, "Axis")
else:
cls.update_snaping_point(intersection, "Plane")
@classmethod
def validate_input(cls, input_number):
grammar = """
start: dim expr?
dim: NUMBER
expr: (ADD | SUB | MUL | DIV) NUMBER
NUMBER: /-?\\d+(?:\\.\\d+)?/
ADD: "+"
SUB: "-"
MUL: "*"
DIV: "/"
%ignore " "
"""
class InputTransform(Transformer):
def dim(self, args):
return float(args[0])
def expr(self, args):
op = args[0]
value = float(args[1])
if op == "+":
return lambda x: x + value
elif op == "-":
return lambda x: x - value
elif op == "*":
return lambda x: x * value
elif op == "/":
return lambda x: x / value
def start(self, args):
dimension = args[0]
if len(args) > 1:
expression = args[1]
return expression(dimension)
else:
return dimension
try:
parser = Lark(grammar, parser="lalr", transformer=InputTransform())
result = parser.parse(input_number)
return True, str(result)
except:
return False, "0"