mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-18 22:33:33 +00:00
Allow dimensions to use custom units from BBIM_Dimension Pset.
- Implementation of @theoryshaw PR #5922. - Note: `IfcPropertyEnumeration` allows multiple choices, but this is not applicable for this use case. Users must manually deselect other options; otherwise, it defaults to the first selected option.
This commit is contained in:
@@ -28,11 +28,13 @@ DATA;
|
|||||||
#21=IFCSIMPLEPROPERTYTEMPLATE('1UDakJ5_f7kBhggNSW4$h5',$,'SymbolsPath','Default symbols SVG',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
#21=IFCSIMPLEPROPERTYTEMPLATE('1UDakJ5_f7kBhggNSW4$h5',$,'SymbolsPath','Default symbols SVG',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||||
#22=IFCSIMPLEPROPERTYTEMPLATE('0d53LEtgLDQxnv__NfgH7i',$,'PatternsPath','Default patterns SVG',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
#22=IFCSIMPLEPROPERTYTEMPLATE('0d53LEtgLDQxnv__NfgH7i',$,'PatternsPath','Default patterns SVG',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||||
#23=IFCSIMPLEPROPERTYTEMPLATE('26qFNMv7nCHgU6Jd7Anga5',$,'ShadingStylesPath','Default shading styles',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
#23=IFCSIMPLEPROPERTYTEMPLATE('26qFNMv7nCHgU6Jd7Anga5',$,'ShadingStylesPath','Default shading styles',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||||
#24=IFCPROPERTYSETTEMPLATE('0I9merLinF5Ap$aZwaclgm',$,'BBIM_Dimension','',.PSET_TYPEDRIVENOVERRIDE.,'IfcAnnotation/DIMENSION,IfcTypeProduct',(#25,#26,#27,#28));
|
#24=IFCPROPERTYSETTEMPLATE('0I9merLinF5Ap$aZwaclgm',$,'BBIM_Dimension','',.PSET_TYPEDRIVENOVERRIDE.,'IfcAnnotation/DIMENSION,IfcAnnotation/RADIUS,IfcAnnotation/DIAMETER,IfcTypeProduct',(#25,#26,#27,#28,#30));
|
||||||
#25=IFCSIMPLEPROPERTYTEMPLATE('1rL2AbQsXD8RbpoWH5pYOV',$,'ShowDescriptionOnly','Hide the measurement values and show only annotation description',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
#25=IFCSIMPLEPROPERTYTEMPLATE('1rL2AbQsXD8RbpoWH5pYOV',$,'ShowDescriptionOnly','Hide the measurement values and show only annotation description',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||||
#26=IFCSIMPLEPROPERTYTEMPLATE('0SVyOfB0rC2xNfdRYf3XvY',$,'SuppressZeroInches','Suppress 0 inch values in dimension annotation text (for example: 12'' - 0" -> 12'')',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
#26=IFCSIMPLEPROPERTYTEMPLATE('0SVyOfB0rC2xNfdRYf3XvY',$,'SuppressZeroInches','Suppress 0 inch values in dimension annotation text (for example: 12'' - 0" -> 12'')',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||||
#27=IFCSIMPLEPROPERTYTEMPLATE('2bUmj458PBqPAtUoI3MXsb',$,'TextPrefix','Text to add before annotation measurement value',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
#27=IFCSIMPLEPROPERTYTEMPLATE('2bUmj458PBqPAtUoI3MXsb',$,'TextPrefix','Text to add before annotation measurement value',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||||
#28=IFCSIMPLEPROPERTYTEMPLATE('0bnzttUb9BPuN597uNTXOE',$,'TextSuffix','Text to add after annotation measurement value',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
#28=IFCSIMPLEPROPERTYTEMPLATE('0bnzttUb9BPuN597uNTXOE',$,'TextSuffix','Text to add after annotation measurement value',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||||
#29=IFCSIMPLEPROPERTYTEMPLATE('2pJmUDpB50VBdCOib1zcJJ',$,'Newline_At','',.P_SINGLEVALUE.,'IfcInteger',$,$,$,$,$,.READWRITE.);
|
#29=IFCSIMPLEPROPERTYTEMPLATE('2pJmUDpB50VBdCOib1zcJJ',$,'Newline_At','',.P_SINGLEVALUE.,'IfcInteger',$,$,$,$,$,.READWRITE.);
|
||||||
|
#30=IFCSIMPLEPROPERTYTEMPLATE('2TJn72t_v2cvBUG916Dpev',$,'CustomUnit','Dimension''s custom unit',.P_ENUMERATEDVALUE.,'IfcText',$,#31,$,$,$,.READWRITE.);
|
||||||
|
#31=IFCPROPERTYENUMERATION('CustomUnit',(IFCTEXT('Feet and Inches - Fractional'),IFCTEXT('Feet - Decimal'),IFCTEXT('Inches - Fractional'),IFCTEXT('Inches - Decimal'),IFCTEXT('Meters'),IFCTEXT('Decimeters'),IFCTEXT('Centimeters'),IFCTEXT('Millimeters')),$);
|
||||||
ENDSEC;
|
ENDSEC;
|
||||||
END-ISO-10303-21;
|
END-ISO-10303-21;
|
||||||
|
|||||||
@@ -386,6 +386,8 @@ class DecoratorData:
|
|||||||
suppress_zero_inches = pset_data.get("SuppressZeroInches", False)
|
suppress_zero_inches = pset_data.get("SuppressZeroInches", False)
|
||||||
text_prefix = pset_data.get("TextPrefix", None) or ""
|
text_prefix = pset_data.get("TextPrefix", None) or ""
|
||||||
text_suffix = pset_data.get("TextSuffix", None) or ""
|
text_suffix = pset_data.get("TextSuffix", None) or ""
|
||||||
|
custom_unit_list = pset_data.get("CustomUnit", None) or ""
|
||||||
|
custom_unit = custom_unit_list[0] if custom_unit_list else ""
|
||||||
|
|
||||||
dimension_data = {
|
dimension_data = {
|
||||||
"dimension_style": dimension_style,
|
"dimension_style": dimension_style,
|
||||||
@@ -394,6 +396,7 @@ class DecoratorData:
|
|||||||
"text_prefix": text_prefix,
|
"text_prefix": text_prefix,
|
||||||
"text_suffix": text_suffix,
|
"text_suffix": text_suffix,
|
||||||
"fill_bg": fill_bg,
|
"fill_bg": fill_bg,
|
||||||
|
"custom_unit": custom_unit,
|
||||||
}
|
}
|
||||||
cls.data[obj.name] = dimension_data
|
cls.data[obj.name] = dimension_data
|
||||||
return dimension_data
|
return dimension_data
|
||||||
|
|||||||
@@ -495,14 +495,14 @@ class BaseDecorator:
|
|||||||
self.draw_label(context, text=text, line_no=line_number_start, multiline=True, **draw_label_kwargs)
|
self.draw_label(context, text=text, line_no=line_number_start, multiline=True, **draw_label_kwargs)
|
||||||
|
|
||||||
@lru_cache(maxsize=None)
|
@lru_cache(maxsize=None)
|
||||||
def format_value(self, context, value):
|
def format_value(self, context, value, custom_unit=None):
|
||||||
drawing_pset_data = DrawingsData.data["active_drawing_pset_data"]
|
drawing_pset_data = DrawingsData.data["active_drawing_pset_data"]
|
||||||
precision = drawing_pset_data.get("MetricPrecision", None)
|
precision = drawing_pset_data.get("MetricPrecision", None)
|
||||||
if not precision:
|
if not precision:
|
||||||
precision = drawing_pset_data.get("ImperialPrecision", None)
|
precision = drawing_pset_data.get("ImperialPrecision", None)
|
||||||
|
|
||||||
decimal_places = drawing_pset_data.get("DecimalPlaces", None)
|
decimal_places = drawing_pset_data.get("DecimalPlaces", None)
|
||||||
return format_distance(value, precision=precision, decimal_places=decimal_places)
|
return format_distance(value, precision=precision, decimal_places=decimal_places, suppress_zero_inches=True, custom_unit=custom_unit)
|
||||||
|
|
||||||
def draw_asterisk(self, context: bpy.types.Context, pos: Vector, rotation: float = 0.0, scale: float = 1.0) -> None:
|
def draw_asterisk(self, context: bpy.types.Context, pos: Vector, rotation: float = 0.0, scale: float = 1.0) -> None:
|
||||||
"""`pos` is a world space position\n
|
"""`pos` is a world space position\n
|
||||||
@@ -737,7 +737,7 @@ class DimensionDecorator(BaseDecorator):
|
|||||||
|
|
||||||
if not show_description_only:
|
if not show_description_only:
|
||||||
length = (v1 - v0).length
|
length = (v1 - v0).length
|
||||||
text = self.format_value(context, length)
|
text = self.format_value(context, length, custom_unit=dimension_data["custom_unit"])
|
||||||
if isinstance(self, DiameterDecorator):
|
if isinstance(self, DiameterDecorator):
|
||||||
text = "D" + text
|
text = "D" + text
|
||||||
text = text_prefix + text + text_suffix
|
text = text_prefix + text + text_suffix
|
||||||
@@ -946,7 +946,7 @@ class RadiusDecorator(BaseDecorator):
|
|||||||
|
|
||||||
def get_text():
|
def get_text():
|
||||||
length = (spline_points[-1] - spline_points[-2]).length
|
length = (spline_points[-1] - spline_points[-2]).length
|
||||||
return "R" + self.format_value(context, length)
|
return "R" + self.format_value(context, length, custom_unit=dimension_data["custom_unit"])
|
||||||
|
|
||||||
self.draw_dimension_text(
|
self.draw_dimension_text(
|
||||||
context, get_text, description, dimension_data, pos=pos, text_dir=Vector((1, 0)), box_alignment="center"
|
context, get_text, description, dimension_data, pos=pos, text_dir=Vector((1, 0)), box_alignment="center"
|
||||||
|
|||||||
@@ -130,30 +130,52 @@ def format_distance(
|
|||||||
decimal_places=None,
|
decimal_places=None,
|
||||||
suppress_zero_inches=False,
|
suppress_zero_inches=False,
|
||||||
in_unit_length=False,
|
in_unit_length=False,
|
||||||
|
custom_unit=None,
|
||||||
):
|
):
|
||||||
# Get Blender Scene Unit Settings
|
# Get Blender Scene Unit Settings
|
||||||
unit_scale = bpy.context.scene.unit_settings.scale_length
|
unit_scale = bpy.context.scene.unit_settings.scale_length
|
||||||
unit_system = bpy.context.scene.unit_settings.system
|
unit_system = bpy.context.scene.unit_settings.system
|
||||||
unit_length = bpy.context.scene.unit_settings.length_unit
|
unit_length = bpy.context.scene.unit_settings.length_unit
|
||||||
area_unit_symbol = " m2" if unit_system == "METRIC" else " ft2"
|
area_unit_symbol = " m2" if unit_system == "METRIC" else " ft2"
|
||||||
|
|
||||||
# Get IFC Unit Settings
|
# Get IFC Unit Settings
|
||||||
if tool.Ifc.get():
|
if tool.Ifc.get():
|
||||||
|
unit_scale = 1
|
||||||
if length_unit := ifcopenshell.util.unit.get_project_unit(tool.Ifc.get(), "LENGTHUNIT"):
|
if length_unit := ifcopenshell.util.unit.get_project_unit(tool.Ifc.get(), "LENGTHUNIT"):
|
||||||
unit_system = "METRIC" if length_unit.Name == "METRE" else "IMPERIAL"
|
unit_system = "METRIC" if length_unit.Name == "METRE" else "IMPERIAL"
|
||||||
unit_length = length_unit.Name
|
unit_length = length_unit.Name
|
||||||
if hasattr(length_unit, "Prefix") and length_unit.Prefix:
|
if hasattr(length_unit, "Prefix") and length_unit.Prefix:
|
||||||
unit_length = length_unit.Prefix + length_unit.Name
|
unit_length = length_unit.Prefix + length_unit.Name
|
||||||
string_conversion = {
|
unit_length_mapping = {
|
||||||
"foot": "FEET",
|
"foot": "FEET",
|
||||||
"inch": "INCHES",
|
"inch": "INCHES",
|
||||||
"METRE": "METERS",
|
"METRE": "METERS",
|
||||||
|
"DECIMETRE": "DECIMETERS",
|
||||||
"CENTIMETRE": "CENTIMETERS",
|
"CENTIMETRE": "CENTIMETERS",
|
||||||
"MILLIMETRE": "MILLIMETERS",
|
"MILLIMETRE": "MILLIMETERS",
|
||||||
}
|
}
|
||||||
unit_length = string_conversion[unit_length]
|
unit_length = unit_length_mapping[unit_length]
|
||||||
|
# For now we only format area in IFC Units
|
||||||
if area_unit := ifcopenshell.util.unit.get_project_unit(tool.Ifc.get(), "AREAUNIT"):
|
if area_unit := ifcopenshell.util.unit.get_project_unit(tool.Ifc.get(), "AREAUNIT"):
|
||||||
area_unit_symbol = " " + ifcopenshell.util.unit.get_unit_symbol(area_unit)
|
area_unit_symbol = " " + ifcopenshell.util.unit.get_unit_symbol(area_unit)
|
||||||
|
|
||||||
|
unit_fraction = True if unit_system == "IMPERIAL" else False
|
||||||
|
|
||||||
|
# Custom Unit Settings
|
||||||
|
if custom_unit:
|
||||||
|
unit_mapping = {
|
||||||
|
"Feet and Inches - Fractional": ("IMPERIAL", "FEET", True),
|
||||||
|
"Feet - Decimal": ("IMPERIAL", "FEET", False),
|
||||||
|
"Inches - Fractional": ("IMPERIAL", "INCHES", True),
|
||||||
|
"Inches - Decimal": ("IMPERIAL", "INCHES", False),
|
||||||
|
"Meters": ("METRIC", "METERS", False),
|
||||||
|
"Decimeters": ("METRIC", "DECIMETERS", False),
|
||||||
|
"Centimeters": ("METRIC", "CENTIMETERS", False),
|
||||||
|
"Millimeters": ("METRIC", "MILLIMETERS", False),
|
||||||
|
}
|
||||||
|
if custom_unit in unit_mapping:
|
||||||
|
unit_system, unit_length, unit_fraction = unit_mapping[custom_unit]
|
||||||
|
|
||||||
value *= unit_scale
|
value *= unit_scale
|
||||||
|
|
||||||
# Imperial Formatting
|
# Imperial Formatting
|
||||||
@@ -181,8 +203,11 @@ def format_distance(
|
|||||||
decInches = value * toInches
|
decInches = value * toInches
|
||||||
|
|
||||||
# Separate ft and inches
|
# Separate ft and inches
|
||||||
# Unless Inches are the specified Length Unit
|
# Unless Inches are the specified Length Unit or unit_fraction is False
|
||||||
if unit_length != "INCHES":
|
if (unit_length == "FEET" and not unit_fraction):
|
||||||
|
feet = round(decInches / inPerFoot, 3) # keep decimal
|
||||||
|
decInches = 0
|
||||||
|
elif unit_length != "INCHES":
|
||||||
feet = int(decInches / inPerFoot) # remove decimal
|
feet = int(decInches / inPerFoot) # remove decimal
|
||||||
decInches -= feet * inPerFoot
|
decInches -= feet * inPerFoot
|
||||||
else:
|
else:
|
||||||
@@ -217,6 +242,10 @@ def format_distance(
|
|||||||
feet += 1
|
feet += 1
|
||||||
inches = 0
|
inches = 0
|
||||||
|
|
||||||
|
# Check whether decimal or fractional
|
||||||
|
if not unit_fraction:
|
||||||
|
inches = round(decInches, 3)
|
||||||
|
frac = None
|
||||||
if not isArea:
|
if not isArea:
|
||||||
add_inches = bool(inches) or not suppress_zero_inches or (inches == 0 and frac)
|
add_inches = bool(inches) or not suppress_zero_inches or (inches == 0 and frac)
|
||||||
tx_dist = ""
|
tx_dist = ""
|
||||||
@@ -265,6 +294,8 @@ def format_distance(
|
|||||||
# METRIC FORMATTING
|
# METRIC FORMATTING
|
||||||
elif unit_system == "METRIC":
|
elif unit_system == "METRIC":
|
||||||
if in_unit_length:
|
if in_unit_length:
|
||||||
|
if unit_length == "DECIMETERS":
|
||||||
|
value = value / 10
|
||||||
if unit_length == "CENTIMETERS":
|
if unit_length == "CENTIMETERS":
|
||||||
value = value / 100
|
value = value / 100
|
||||||
if unit_length == "MILLIMETERS":
|
if unit_length == "MILLIMETERS":
|
||||||
@@ -283,6 +314,14 @@ def format_distance(
|
|||||||
if hide_units is False:
|
if hide_units is False:
|
||||||
fmt += " m"
|
fmt += " m"
|
||||||
tx_dist = fmt % value
|
tx_dist = fmt % value
|
||||||
|
# Decimeters
|
||||||
|
elif unit_length == "DECIMETERS":
|
||||||
|
if decimal_places is None:
|
||||||
|
fmt = "%1.1f"
|
||||||
|
if hide_units is False:
|
||||||
|
fmt += " dm"
|
||||||
|
d_dm = value * (10)
|
||||||
|
tx_dist = fmt % d_dm
|
||||||
# Centimeters
|
# Centimeters
|
||||||
elif unit_length == "CENTIMETERS":
|
elif unit_length == "CENTIMETERS":
|
||||||
if decimal_places is None:
|
if decimal_places is None:
|
||||||
|
|||||||
@@ -1128,7 +1128,7 @@ class SvgWriter:
|
|||||||
|
|
||||||
def get_text():
|
def get_text():
|
||||||
radius = (points[-1].co - points[-2].co).length
|
radius = (points[-1].co - points[-2].co).length
|
||||||
radius = helper.format_distance(radius, precision=self.precision, decimal_places=self.decimal_places)
|
radius = helper.format_distance(radius, precision=self.precision, decimal_places=self.decimal_places, custom_unit=dimension_data["custom_unit"])
|
||||||
text = f"R{radius}"
|
text = f"R{radius}"
|
||||||
return text
|
return text
|
||||||
|
|
||||||
@@ -1256,6 +1256,7 @@ class SvgWriter:
|
|||||||
text_prefix=dimension_data["text_prefix"],
|
text_prefix=dimension_data["text_prefix"],
|
||||||
text_suffix=dimension_data["text_suffix"],
|
text_suffix=dimension_data["text_suffix"],
|
||||||
fill_bg=dimension_data["fill_bg"],
|
fill_bg=dimension_data["fill_bg"],
|
||||||
|
custom_unit=dimension_data["custom_unit"]
|
||||||
)
|
)
|
||||||
|
|
||||||
def draw_dimension_annotations(self, obj):
|
def draw_dimension_annotations(self, obj):
|
||||||
@@ -1280,6 +1281,7 @@ class SvgWriter:
|
|||||||
text_prefix=dimension_data["text_prefix"],
|
text_prefix=dimension_data["text_prefix"],
|
||||||
text_suffix=dimension_data["text_suffix"],
|
text_suffix=dimension_data["text_suffix"],
|
||||||
fill_bg=dimension_data["fill_bg"],
|
fill_bg=dimension_data["fill_bg"],
|
||||||
|
custom_unit=dimension_data["custom_unit"],
|
||||||
)
|
)
|
||||||
|
|
||||||
def draw_measureit_arch_dimension_annotations(self):
|
def draw_measureit_arch_dimension_annotations(self):
|
||||||
@@ -1306,6 +1308,7 @@ class SvgWriter:
|
|||||||
text_prefix="",
|
text_prefix="",
|
||||||
text_suffix="",
|
text_suffix="",
|
||||||
fill_bg=False,
|
fill_bg=False,
|
||||||
|
custom_unit=None,
|
||||||
):
|
):
|
||||||
offset = Vector([self.raw_width, self.raw_height]) / 2
|
offset = Vector([self.raw_width, self.raw_height]) / 2
|
||||||
v0 = self.project_point_onto_camera(v0_global)
|
v0 = self.project_point_onto_camera(v0_global)
|
||||||
@@ -1339,6 +1342,7 @@ class SvgWriter:
|
|||||||
precision=self.precision,
|
precision=self.precision,
|
||||||
decimal_places=self.decimal_places,
|
decimal_places=self.decimal_places,
|
||||||
suppress_zero_inches=suppress_zero_inches,
|
suppress_zero_inches=suppress_zero_inches,
|
||||||
|
custom_unit=custom_unit,
|
||||||
)
|
)
|
||||||
text = text_prefix + str(dimension) + text_suffix
|
text = text_prefix + str(dimension) + text_suffix
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user