mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +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 bpy
|
||||
|
||||
# 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))
|
||||
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 ifcopenshell
|
||||
from . import annotation
|
||||
from . import helper
|
||||
from mathutils import Vector
|
||||
from mathutils import geometry
|
||||
|
||||
@@ -189,14 +190,18 @@ class SvgWriter():
|
||||
(x_offset + projected_points[0].x) * self.scale,
|
||||
((y_offset - projected_points[0].y) * self.scale) - 2.5
|
||||
))
|
||||
# TODO: unhardcode m unit
|
||||
# TODO: allow metric to be configurable
|
||||
rl = ((matrix_world @
|
||||
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:
|
||||
text_anchor = 'end'
|
||||
else:
|
||||
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-family': 'OpenGost Type B TT',
|
||||
'text-anchor': text_anchor,
|
||||
@@ -221,9 +226,13 @@ class SvgWriter():
|
||||
(x_offset + projected_points[0].x) * self.scale,
|
||||
((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
|
||||
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-family': 'OpenGost Type B TT',
|
||||
'text-anchor': 'start',
|
||||
@@ -485,10 +494,10 @@ class SvgWriter():
|
||||
start = Vector(((x_offset + v0.x), (y_offset - v0.y)))
|
||||
end = Vector(((x_offset + v1.x), (y_offset - v1.y)))
|
||||
mid = ((end - start) / 2) + start
|
||||
# TODO: hardcoded meters to mm conversion, until I properly do units
|
||||
vector = end - start
|
||||
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
|
||||
if sheet_dimension < 5: # annotation can't fit
|
||||
# offset text to right of marker
|
||||
@@ -503,7 +512,7 @@ class SvgWriter():
|
||||
if text_override is not None:
|
||||
text = text_override
|
||||
else:
|
||||
text = str(round(dimension))
|
||||
text = str(dimension)
|
||||
self.svg.add(self.svg.text(text, insert=tuple(text_position), **{
|
||||
'transform': 'rotate({} {} {})'.format(
|
||||
rotation,
|
||||
|
||||
Reference in New Issue
Block a user