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):
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)
if not is_valid:
self.report({"WARNING"}, "The number typed is not valid.")
@@ -2324,7 +2324,7 @@ class MeasureTool(bpy.types.Operator):
def recalculate_inputs(self, context):
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)
if not is_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
from bonsai.bim.module.drawing.helper import format_distance
from dataclasses import dataclass, field
from lark import Lark, Transformer
from math import sin, cos, radians, degrees, atan2, acos
from mathutils import Vector, Matrix
from typing import Optional
@@ -282,3 +283,132 @@ class Polyline(bonsai.core.tool.Polyline):
input_ui.set_value("Z", last_point.z)
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])
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"