Changed input validation to tool/polyline.py

This commit is contained in:
Bruno Perdigão
2024-09-06 14:26:31 -03:00
committed by Bruno Perdigão
parent 8dc77735a5
commit e546971ada
4 changed files with 132 additions and 129 deletions
+1 -1
View File
@@ -339,7 +339,7 @@ class DrawPolylineWall(bpy.types.Operator):
def recalculate_inputs(self, context): def recalculate_inputs(self, context):
if self.number_input: if self.number_input:
is_valid, self.number_output = tool.Snap.validate_input(self.number_output, self.input_type) is_valid, self.number_output = tool.Polyline.validate_input(self.number_output, self.input_type)
self.input_ui.set_value(self.input_type, self.number_output) self.input_ui.set_value(self.input_type, self.number_output)
if not is_valid: if not is_valid:
self.report({"WARNING"}, "The number typed is not valid.") self.report({"WARNING"}, "The number typed is not valid.")
@@ -2324,7 +2324,7 @@ class MeasureTool(bpy.types.Operator):
def recalculate_inputs(self, context): def recalculate_inputs(self, context):
if self.number_input: if self.number_input:
is_valid, self.number_output = tool.Snap.validate_input(self.number_output, self.input_type) is_valid, self.number_output = tool.Polyline.validate_input(self.number_output, self.input_type)
self.input_ui.set_value(self.input_type, self.number_output) self.input_ui.set_value(self.input_type, self.number_output)
if not is_valid: if not is_valid:
self.report({"WARNING"}, "The number typed is not valid.") self.report({"WARNING"}, "The number typed is not valid.")
+130
View File
@@ -21,6 +21,7 @@ import bonsai.core.tool
import bonsai.tool as tool import bonsai.tool as tool
from bonsai.bim.module.drawing.helper import format_distance from bonsai.bim.module.drawing.helper import format_distance
from dataclasses import dataclass, field from dataclasses import dataclass, field
from lark import Lark, Transformer
from math import sin, cos, radians, degrees, atan2, acos from math import sin, cos, radians, degrees, atan2, acos
from mathutils import Vector, Matrix from mathutils import Vector, Matrix
from typing import Optional from typing import Optional
@@ -282,3 +283,132 @@ class Polyline(bonsai.core.tool.Polyline):
input_ui.set_value("Z", last_point.z) input_ui.set_value("Z", last_point.z)
return return
@classmethod
def validate_input(cls, input_number, input_type):
grammar_imperial = """
start: (FORMULA dim expr) | dim
dim: imperial
FORMULA: "="
imperial: feet? "-"? inches?
feet: NUMBER? "-"? fraction? "'"
inches: NUMBER? "-"? fraction? "\\""
fraction: NUMBER "/" NUMBER
expr: (ADD | SUB) dim | (MUL | DIV) NUMBER
NUMBER: /-?\\d+(?:\\.\\d+)?/
ADD: "+"
SUB: "-"
MUL: "*"
DIV: "/"
%ignore " "
"""
grammar_metric = """
start: FORMULA? dim expr?
dim: metric
FORMULA: "="
metric: NUMBER
expr: (ADD | SUB | MUL | DIV) dim
NUMBER: /-?\\d+(?:\\.\\d+)?/
ADD: "+"
SUB: "-"
MUL: "*"
DIV: "/"
%ignore " "
"""
class InputTransform(Transformer):
def NUMBER(self, n):
return float(n)
def fraction(self, numbers):
return numbers[0] / numbers[1]
def inches(self, args):
if len(args) > 1:
result = args[0] + args[1]
else:
result = args[0]
return result / 12
def feet(self, args):
return args[0]
def imperial(self, args):
if len(args) > 1:
if args[0] <= 0:
result = args[0] - args[1]
else:
result = args[0] + args[1]
else:
result = args[0]
return result
def metric(self, args):
return args[0]
def dim(self, args):
return 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 FORMULA(cls, args):
return args[0]
def start(self, args):
i = 0
if args[0] == "=":
i += 1
else:
if len(args) > 1:
raise ValueError("Invalid input.")
dimension = args[i]
if len(args) > i + 1:
expression = args[i + 1]
return expression(dimension) * factor
else:
return dimension * factor
try:
if bpy.context.scene.unit_settings.system == "IMPERIAL":
parser = Lark(grammar_imperial)
factor = 0.3048
else:
parser = Lark(grammar_metric)
factor = 1
if bpy.context.scene.unit_settings.length_unit == "MILLIMETERS":
factor = 0.001
if input_type == "A":
parser = Lark(grammar_metric)
factor = 1
parse_tree = parser.parse(input_number)
transformer = InputTransform()
result = transformer.transform(parse_tree)
return True, str(result)
except:
return False, "0"
-127
View File
@@ -509,130 +509,3 @@ class Snap(bonsai.core.tool.Snap):
cls.update_snapping_point(shifted_list[0][0], shifted_list[0][1]) cls.update_snapping_point(shifted_list[0][0], shifted_list[0][1])
return shifted_list return shifted_list
@classmethod
def validate_input(cls, input_number, input_type):
grammar_imperial = """
start: (FORMULA dim expr) | dim
dim: imperial
FORMULA: "="
imperial: feet? "-"? inches?
feet: NUMBER? "-"? fraction? "'"
inches: NUMBER? "-"? fraction? "\\""
fraction: NUMBER "/" NUMBER
expr: (ADD | SUB) dim | (MUL | DIV) NUMBER
NUMBER: /-?\\d+(?:\\.\\d+)?/
ADD: "+"
SUB: "-"
MUL: "*"
DIV: "/"
%ignore " "
"""
grammar_metric = """
start: FORMULA? dim expr?
dim: metric
FORMULA: "="
metric: NUMBER
expr: (ADD | SUB | MUL | DIV) dim
NUMBER: /-?\\d+(?:\\.\\d+)?/
ADD: "+"
SUB: "-"
MUL: "*"
DIV: "/"
%ignore " "
"""
class InputTransform(Transformer):
def NUMBER(self, n):
return float(n)
def fraction(self, numbers):
return numbers[0] / numbers[1]
def inches(self, args):
if len(args) > 1:
result = args[0] + args[1]
else:
result = args[0]
return result / 12
def feet(self, args):
return args[0]
def imperial(self, args):
if len(args) > 1:
if args[0] <= 0:
result = args[0] - args[1]
else:
result = args[0] + args[1]
else:
result = args[0]
return result
def metric(self, args):
return args[0]
def dim(self, args):
return 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 FORMULA(cls, args):
return args[0]
def start(self, args):
i = 0
if args[0] == "=":
i += 1
else:
if len(args) > 1:
raise ValueError("Invalid input.")
dimension = args[i]
if len(args) > i + 1:
expression = args[i + 1]
return expression(dimension) * factor
else:
return dimension * factor
try:
if bpy.context.scene.unit_settings.system == "IMPERIAL":
parser = Lark(grammar_imperial)
factor = 0.3048
else:
parser = Lark(grammar_metric)
factor = 1
if bpy.context.scene.unit_settings.length_unit == "MILLIMETERS":
factor = 0.001
if input_type == "A":
parser = Lark(grammar_metric)
factor = 1
parse_tree = parser.parse(input_number)
transformer = InputTransform()
result = transformer.transform(parse_tree)
return True, str(result)
except:
return False, "0"