mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 23:20:56 +00:00
Initial implementation of unit handling for wall polyline tool.
The input panel now works with meters, millimeters and imperial units.
This commit is contained in:
@@ -28,6 +28,7 @@ from bpy_extras import view3d_utils
|
|||||||
from mathutils import Vector, Matrix
|
from mathutils import Vector, Matrix
|
||||||
from gpu_extras.batch import batch_for_shader
|
from gpu_extras.batch import batch_for_shader
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
from bonsai.bim.module.drawing.helper import format_distance
|
||||||
|
|
||||||
|
|
||||||
def transparent_color(color, alpha=0.1):
|
def transparent_color(color, alpha=0.1):
|
||||||
@@ -511,6 +512,15 @@ class PolylineDecorator:
|
|||||||
|
|
||||||
def draw_input_panel(self, context):
|
def draw_input_panel(self, context):
|
||||||
texts = {"D": "Distance:", "A": "Angle:", "X": "X coord:", "Y": "Y coord:", "Z": "Z coord:", "AREA": "Area:"}
|
texts = {"D": "Distance:", "A": "Angle:", "X": "X coord:", "Y": "Y coord:", "Z": "Z coord:", "AREA": "Area:"}
|
||||||
|
|
||||||
|
unit_system = tool.Drawing.get_unit_system()
|
||||||
|
if unit_system == "IMPERIAL":
|
||||||
|
precision = context.scene.DocProperties.imperial_precision
|
||||||
|
factor = 3.28084
|
||||||
|
else:
|
||||||
|
precision = None
|
||||||
|
factor = 1
|
||||||
|
|
||||||
self.addon_prefs = tool.Blender.get_addon_preferences()
|
self.addon_prefs = tool.Blender.get_addon_preferences()
|
||||||
self.font_id = 0
|
self.font_id = 0
|
||||||
blf.size(self.font_id, 12)
|
blf.size(self.font_id, 12)
|
||||||
@@ -521,6 +531,15 @@ class PolylineDecorator:
|
|||||||
offset = 20
|
offset = 20
|
||||||
new_line = 20
|
new_line = 20
|
||||||
for i, (key, value) in enumerate(self.input_panel.items()):
|
for i, (key, value) in enumerate(self.input_panel.items()):
|
||||||
|
|
||||||
|
if key != "A" and key != self.input_type:
|
||||||
|
value = float(value)
|
||||||
|
if context.scene.unit_settings.length_unit == 'MILLIMETERS':
|
||||||
|
value = value * 1000
|
||||||
|
formatted_value = format_distance(value*factor, precision=precision, suppress_zero_inches=True, in_unit_length=True)
|
||||||
|
else:
|
||||||
|
formatted_value = value
|
||||||
|
|
||||||
if key not in list(texts.keys()):
|
if key not in list(texts.keys()):
|
||||||
continue
|
continue
|
||||||
if key == self.input_type:
|
if key == self.input_type:
|
||||||
@@ -528,7 +547,7 @@ class PolylineDecorator:
|
|||||||
else:
|
else:
|
||||||
blf.color(self.font_id, *color)
|
blf.color(self.font_id, *color)
|
||||||
blf.position(self.font_id, self.mouse_pos[0] + offset, self.mouse_pos[1] - (new_line * i), 0)
|
blf.position(self.font_id, self.mouse_pos[0] + offset, self.mouse_pos[1] - (new_line * i), 0)
|
||||||
blf.draw(self.font_id, texts[key] + value)
|
blf.draw(self.font_id, texts[key] + formatted_value)
|
||||||
|
|
||||||
def draw_measurements(self, context):
|
def draw_measurements(self, context):
|
||||||
region = context.region
|
region = context.region
|
||||||
@@ -550,8 +569,23 @@ class PolylineDecorator:
|
|||||||
continue
|
continue
|
||||||
pos_dim = (Vector(measurement_prop[i].position) + Vector(measurement_prop[i-1].position)) / 2
|
pos_dim = (Vector(measurement_prop[i].position) + Vector(measurement_prop[i-1].position)) / 2
|
||||||
coords_dim = view3d_utils.location_3d_to_region_2d(region, rv3d, pos_dim)
|
coords_dim = view3d_utils.location_3d_to_region_2d(region, rv3d, pos_dim)
|
||||||
|
|
||||||
|
unit_system = tool.Drawing.get_unit_system()
|
||||||
|
if unit_system == "IMPERIAL":
|
||||||
|
precision = context.scene.DocProperties.imperial_precision
|
||||||
|
factor = 3.28084
|
||||||
|
else:
|
||||||
|
precision = None
|
||||||
|
factor = 1
|
||||||
|
|
||||||
|
value = measurement_prop[i].dim
|
||||||
|
value = float(value)
|
||||||
|
if context.scene.unit_settings.length_unit == 'MILLIMETERS':
|
||||||
|
value = value * 1000
|
||||||
|
formatted_value = format_distance(value*factor, precision=precision, suppress_zero_inches=True, in_unit_length=True)
|
||||||
|
|
||||||
blf.position(self.font_id, coords_dim[0], coords_dim[1], 0)
|
blf.position(self.font_id, coords_dim[0], coords_dim[1], 0)
|
||||||
blf.draw(self.font_id, "d: " + measurement_prop[i].dim)
|
blf.draw(self.font_id, "d: " + formatted_value)
|
||||||
|
|
||||||
pos_angle = measurement_prop[i-1].position
|
pos_angle = measurement_prop[i-1].position
|
||||||
coords_angle = view3d_utils.location_3d_to_region_2d(region, rv3d, pos_angle)
|
coords_angle = view3d_utils.location_3d_to_region_2d(region, rv3d, pos_angle)
|
||||||
|
|||||||
@@ -294,7 +294,7 @@ class DrawPolylineWall(bpy.types.Operator):
|
|||||||
self.action_count = 0
|
self.action_count = 0
|
||||||
self.visible_objs = []
|
self.visible_objs = []
|
||||||
self.objs_2d_bbox = []
|
self.objs_2d_bbox = []
|
||||||
self.number_options = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ".", "+", "-", "*", "/"}
|
self.number_options = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", " ", ".", "+", "-", "*", "/", "'", "\"", "="}
|
||||||
self.number_input = []
|
self.number_input = []
|
||||||
self.number_output = ""
|
self.number_output = ""
|
||||||
self.number_is_negative = False
|
self.number_is_negative = False
|
||||||
@@ -416,6 +416,7 @@ class DrawPolylineWall(bpy.types.Operator):
|
|||||||
self.is_input_on = True
|
self.is_input_on = True
|
||||||
self.input_type = event.type
|
self.input_type = event.type
|
||||||
self.number_input = []
|
self.number_input = []
|
||||||
|
self.input_panel[self.input_type] = ""
|
||||||
PolylineDecorator.set_input_panel(self.input_panel, self.input_type)
|
PolylineDecorator.set_input_panel(self.input_panel, self.input_type)
|
||||||
tool.Blender.update_viewport()
|
tool.Blender.update_viewport()
|
||||||
|
|
||||||
|
|||||||
@@ -455,10 +455,21 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def validate_input(cls, input_number):
|
def validate_input(cls, input_number):
|
||||||
|
|
||||||
grammar = """
|
grammar = """
|
||||||
start: dim expr?
|
start: FORMULA? dim expr?
|
||||||
dim: NUMBER
|
dim: metric | imperial
|
||||||
expr: (ADD | SUB | MUL | DIV) NUMBER
|
|
||||||
|
FORMULA: "="
|
||||||
|
|
||||||
|
metric: NUMBER
|
||||||
|
|
||||||
|
imperial: feet? "-"? inches?
|
||||||
|
feet: NUMBER? " "? fraction? "'"
|
||||||
|
inches: NUMBER? " "? fraction? "\\""
|
||||||
|
fraction: NUMBER "/" NUMBER
|
||||||
|
|
||||||
|
expr: (ADD | SUB | MUL | DIV) dim
|
||||||
|
|
||||||
NUMBER: /-?\\d+(?:\\.\\d+)?/
|
NUMBER: /-?\\d+(?:\\.\\d+)?/
|
||||||
ADD: "+"
|
ADD: "+"
|
||||||
@@ -470,8 +481,34 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
class InputTransform(Transformer):
|
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:
|
||||||
|
result = (args[0] + args[1])
|
||||||
|
else:
|
||||||
|
result = args[0]
|
||||||
|
return result * 0.3048
|
||||||
|
|
||||||
|
def metric(self, args):
|
||||||
|
return args[0]
|
||||||
|
|
||||||
def dim(self, args):
|
def dim(self, args):
|
||||||
return float(args[0])
|
return args[0]
|
||||||
|
|
||||||
def expr(self, args):
|
def expr(self, args):
|
||||||
op = args[0]
|
op = args[0]
|
||||||
@@ -485,17 +522,32 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
elif op == "/":
|
elif op == "/":
|
||||||
return lambda x: x / value
|
return lambda x: x / value
|
||||||
|
|
||||||
|
def FORMULA(cls, args):
|
||||||
|
return args[0]
|
||||||
|
|
||||||
def start(self, args):
|
def start(self, args):
|
||||||
dimension = args[0]
|
i = 0
|
||||||
if len(args) > 1:
|
if args[0] == "=":
|
||||||
expression = args[1]
|
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)
|
return expression(dimension)
|
||||||
else:
|
else:
|
||||||
return dimension
|
return dimension
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
parser = Lark(grammar, parser="lalr", transformer=InputTransform())
|
parser = Lark(grammar)
|
||||||
result = parser.parse(input_number)
|
parse_tree = parser.parse(input_number)
|
||||||
|
|
||||||
|
transformer = InputTransform()
|
||||||
|
result = transformer.transform(parse_tree)
|
||||||
|
if bpy.context.scene.unit_settings.length_unit == 'MILLIMETERS':
|
||||||
|
result /= 1000
|
||||||
return True, str(result)
|
return True, str(result)
|
||||||
except:
|
except:
|
||||||
return False, "0"
|
return False, "0"
|
||||||
|
|||||||
Reference in New Issue
Block a user