mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-12 14:33:28 +00:00
Merge branch 'v0.6.0' of https://github.com/IfcOpenShell/IfcOpenShell into v0.6.0
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import math
|
import math
|
||||||
|
import bpy
|
||||||
|
|
||||||
# TODO: Deprecate this in favour of ifcopenshell.util.unit
|
# TODO: Deprecate this in favour of ifcopenshell.util.unit
|
||||||
|
|
||||||
@@ -101,3 +102,144 @@ class SIUnitHelper:
|
|||||||
value *= (1 / SIUnitHelper.get_prefix_multiplier(to_prefix))
|
value *= (1 / SIUnitHelper.get_prefix_multiplier(to_prefix))
|
||||||
value *= (1 / SIUnitHelper.get_prefix_multiplier(to_prefix))
|
value *= (1 / SIUnitHelper.get_prefix_multiplier(to_prefix))
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
# This function stolen from https://github.com/kevancress/MeasureIt_ARCH/blob/dcf607ce0896aa2284463c6b4ae9cd023fc54cbe/measureit_arch_baseclass.py
|
||||||
|
# MeasureIt-ARCH is GPL-v3
|
||||||
|
# In the future I will need to rewrite this to allow the user to have custom
|
||||||
|
# settings for each annotation object, not read from Blender.
|
||||||
|
def format_distance(value, isArea=False, hide_units=True):
|
||||||
|
s_code = "\u00b2" # Superscript two THIS IS LEGACY (but being kept for when Area Measurements are re-implimented)
|
||||||
|
|
||||||
|
# Get Scene Unit Settings
|
||||||
|
scaleFactor = bpy.context.scene.unit_settings.scale_length
|
||||||
|
unit_system = bpy.context.scene.unit_settings.system
|
||||||
|
unit_length = bpy.context.scene.unit_settings.length_unit
|
||||||
|
imperial_precision = 32
|
||||||
|
# (('1', "1\"", "1 Inch"),
|
||||||
|
# ('2', "1/2\"", "1/2 Inch"),
|
||||||
|
# ('4', "1/4\"", "1/4 Inch"),
|
||||||
|
# ('8', "1/8\"", "1/8th Inch"),
|
||||||
|
# ('16', "1/16\"", "1/16th Inch"),
|
||||||
|
# ('32', "1/32\"", "1/32th Inch"),
|
||||||
|
# ('64', "1/64\"", "1/64th Inch")),
|
||||||
|
|
||||||
|
toInches = 39.3700787401574887
|
||||||
|
inPerFoot = 11.999
|
||||||
|
|
||||||
|
if isArea:
|
||||||
|
toInches = 1550
|
||||||
|
inPerFoot = 143.999
|
||||||
|
|
||||||
|
value *= scaleFactor
|
||||||
|
|
||||||
|
# Imperial Formating
|
||||||
|
if unit_system == "IMPERIAL":
|
||||||
|
base = int(imperial_precision)
|
||||||
|
decInches = value * toInches
|
||||||
|
|
||||||
|
# Seperate ft and inches
|
||||||
|
# Unless Inches are the specified Length Unit
|
||||||
|
if unit_length != 'INCHES':
|
||||||
|
feet = math.floor(decInches/inPerFoot)
|
||||||
|
decInches -= feet*inPerFoot
|
||||||
|
else:
|
||||||
|
feet = 0
|
||||||
|
|
||||||
|
|
||||||
|
#Seperate Fractional Inches
|
||||||
|
inches = math.floor(decInches)
|
||||||
|
if inches != 0:
|
||||||
|
frac = round(base*(decInches-inches))
|
||||||
|
else:
|
||||||
|
frac = round(base*(decInches))
|
||||||
|
|
||||||
|
#Set proper numerator and denominator
|
||||||
|
if frac != base:
|
||||||
|
numcycles = int(math.log2(base))
|
||||||
|
for i in range(numcycles):
|
||||||
|
if frac%2 == 0:
|
||||||
|
frac = int(frac/2)
|
||||||
|
base = int(base/2)
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
frac = 0
|
||||||
|
inches += 1
|
||||||
|
|
||||||
|
# Check values and compose string
|
||||||
|
if inches == 12:
|
||||||
|
feet += 1
|
||||||
|
inches = 0
|
||||||
|
|
||||||
|
if inches !=0:
|
||||||
|
inchesString = str(inches)
|
||||||
|
if frac != 0: inchesString += "-"
|
||||||
|
else: inchesString += "\""
|
||||||
|
else: inchesString = ""
|
||||||
|
|
||||||
|
if feet != 0:
|
||||||
|
feetString = str(feet) + "' "
|
||||||
|
else: feetString = ""
|
||||||
|
|
||||||
|
if frac != 0:
|
||||||
|
fracString = str(frac) + "/" + str(base) +"\""
|
||||||
|
else: fracString = ""
|
||||||
|
|
||||||
|
if not isArea:
|
||||||
|
tx_dist = feetString + inchesString + fracString
|
||||||
|
else:
|
||||||
|
tx_dist = str('%1.3f' % (value*toInches/inPerFoot)) + " sq. ft."
|
||||||
|
|
||||||
|
|
||||||
|
# METRIC FORMATING
|
||||||
|
elif unit_system == "METRIC":
|
||||||
|
|
||||||
|
# Meters
|
||||||
|
if unit_length == 'METERS':
|
||||||
|
fmt = '%1.3f'
|
||||||
|
if hide_units is False:
|
||||||
|
fmt += " m"
|
||||||
|
tx_dist = fmt % value
|
||||||
|
# Centimeters
|
||||||
|
elif unit_length == 'CENTIMETERS':
|
||||||
|
fmt = '%1.1f'
|
||||||
|
if hide_units is False:
|
||||||
|
fmt += " cm"
|
||||||
|
d_cm = value * (100)
|
||||||
|
tx_dist = fmt % d_cm
|
||||||
|
#Millimeters
|
||||||
|
elif unit_length == 'MILLIMETERS':
|
||||||
|
fmt = '%1.0f'
|
||||||
|
if hide_units is False:
|
||||||
|
fmt += " mm"
|
||||||
|
d_mm = value * (1000)
|
||||||
|
tx_dist = fmt % d_mm
|
||||||
|
|
||||||
|
# Otherwise Use Adaptive Units
|
||||||
|
else:
|
||||||
|
if round(value, 2) >= 1.0:
|
||||||
|
fmt = '%1.3f'
|
||||||
|
if hide_units is False:
|
||||||
|
fmt += " m"
|
||||||
|
tx_dist = fmt % value
|
||||||
|
else:
|
||||||
|
if round(value, 2) >= 0.01:
|
||||||
|
fmt = '%1.1f'
|
||||||
|
if hide_units is False:
|
||||||
|
fmt += " cm"
|
||||||
|
d_cm = value * (100)
|
||||||
|
tx_dist = fmt % d_cm
|
||||||
|
else:
|
||||||
|
fmt = '%1.0f'
|
||||||
|
if hide_units is False:
|
||||||
|
fmt += " mm"
|
||||||
|
d_mm = value * (1000)
|
||||||
|
tx_dist = fmt % d_mm
|
||||||
|
if isArea:
|
||||||
|
tx_dist += s_code
|
||||||
|
else:
|
||||||
|
tx_dist = fmt % value
|
||||||
|
|
||||||
|
|
||||||
|
return tx_dist
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import xml.etree.ElementTree as ET
|
|||||||
import svgwrite
|
import svgwrite
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
from . import annotation
|
from . import annotation
|
||||||
|
from . import helper
|
||||||
from mathutils import Vector
|
from mathutils import Vector
|
||||||
from mathutils import geometry
|
from mathutils import geometry
|
||||||
|
|
||||||
@@ -189,14 +190,18 @@ class SvgWriter():
|
|||||||
(x_offset + projected_points[0].x) * self.scale,
|
(x_offset + projected_points[0].x) * self.scale,
|
||||||
((y_offset - projected_points[0].y) * self.scale) - 2.5
|
((y_offset - projected_points[0].y) * self.scale) - 2.5
|
||||||
))
|
))
|
||||||
# TODO: unhardcode m unit
|
# TODO: allow metric to be configurable
|
||||||
rl = ((matrix_world @
|
rl = ((matrix_world @
|
||||||
points[0].co).xyz + self.ifc_cutter.plan_level_obj.location).z
|
points[0].co).xyz + self.ifc_cutter.plan_level_obj.location).z
|
||||||
|
if bpy.context.scene.unit_settings.system == 'IMPERIAL':
|
||||||
|
rl = helper.format_distance(rl)
|
||||||
|
else:
|
||||||
|
rl = '{:.3f}m'.format(rl)
|
||||||
if projected_points[0].x > projected_points[-1].x:
|
if projected_points[0].x > projected_points[-1].x:
|
||||||
text_anchor = 'end'
|
text_anchor = 'end'
|
||||||
else:
|
else:
|
||||||
text_anchor = 'start'
|
text_anchor = 'start'
|
||||||
self.svg.add(self.svg.text('RL +{:.3f}m'.format(rl), insert=tuple(text_position), **{
|
self.svg.add(self.svg.text('RL +{}'.format(rl), insert=tuple(text_position), **{
|
||||||
'font-size': annotation.Annotator.get_svg_text_size(2.5),
|
'font-size': annotation.Annotator.get_svg_text_size(2.5),
|
||||||
'font-family': 'OpenGost Type B TT',
|
'font-family': 'OpenGost Type B TT',
|
||||||
'text-anchor': text_anchor,
|
'text-anchor': text_anchor,
|
||||||
@@ -221,9 +226,13 @@ class SvgWriter():
|
|||||||
(x_offset + projected_points[0].x) * self.scale,
|
(x_offset + projected_points[0].x) * self.scale,
|
||||||
((y_offset - projected_points[0].y) * self.scale) - 3.5
|
((y_offset - projected_points[0].y) * self.scale) - 3.5
|
||||||
))
|
))
|
||||||
# TODO: unhardcode m unit
|
# TODO: allow metric to be configurable
|
||||||
rl = (matrix_world @ points[0].co.xyz).z
|
rl = (matrix_world @ points[0].co.xyz).z
|
||||||
self.svg.add(self.svg.text('RL +{:.3f}m'.format(rl), insert=tuple(text_position), **{
|
if bpy.context.scene.unit_settings.system == 'IMPERIAL':
|
||||||
|
rl = helper.format_distance(rl)
|
||||||
|
else:
|
||||||
|
rl = '{:.3f}m'.format(rl)
|
||||||
|
self.svg.add(self.svg.text('RL +{}'.format(rl), insert=tuple(text_position), **{
|
||||||
'font-size': annotation.Annotator.get_svg_text_size(2.5),
|
'font-size': annotation.Annotator.get_svg_text_size(2.5),
|
||||||
'font-family': 'OpenGost Type B TT',
|
'font-family': 'OpenGost Type B TT',
|
||||||
'text-anchor': 'start',
|
'text-anchor': 'start',
|
||||||
@@ -485,10 +494,10 @@ class SvgWriter():
|
|||||||
start = Vector(((x_offset + v0.x), (y_offset - v0.y)))
|
start = Vector(((x_offset + v0.x), (y_offset - v0.y)))
|
||||||
end = Vector(((x_offset + v1.x), (y_offset - v1.y)))
|
end = Vector(((x_offset + v1.x), (y_offset - v1.y)))
|
||||||
mid = ((end - start) / 2) + start
|
mid = ((end - start) / 2) + start
|
||||||
# TODO: hardcoded meters to mm conversion, until I properly do units
|
|
||||||
vector = end - start
|
vector = end - start
|
||||||
perpendicular = Vector((vector.y, -vector.x)).normalized()
|
perpendicular = Vector((vector.y, -vector.x)).normalized()
|
||||||
dimension = (v1_global - v0_global).length * 1000
|
dimension = (v1_global - v0_global).length
|
||||||
|
dimension = helper.format_distance(dimension)
|
||||||
sheet_dimension = ((end*self.scale) - (start*self.scale)).length
|
sheet_dimension = ((end*self.scale) - (start*self.scale)).length
|
||||||
if sheet_dimension < 5: # annotation can't fit
|
if sheet_dimension < 5: # annotation can't fit
|
||||||
# offset text to right of marker
|
# offset text to right of marker
|
||||||
@@ -503,7 +512,7 @@ class SvgWriter():
|
|||||||
if text_override is not None:
|
if text_override is not None:
|
||||||
text = text_override
|
text = text_override
|
||||||
else:
|
else:
|
||||||
text = str(round(dimension))
|
text = str(dimension)
|
||||||
self.svg.add(self.svg.text(text, insert=tuple(text_position), **{
|
self.svg.add(self.svg.text(text, insert=tuple(text_position), **{
|
||||||
'transform': 'rotate({} {} {})'.format(
|
'transform': 'rotate({} {} {})'.format(
|
||||||
rotation,
|
rotation,
|
||||||
|
|||||||
Reference in New Issue
Block a user