mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-06 07:51:47 +00:00
Closes #8063: ordinate dimensioning
Generated with the assistance of an AI coding tool.
This commit is contained in:
@@ -28,7 +28,7 @@ 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,IfcAnnotation/RADIUS,IfcAnnotation/DIAMETER,IfcTypeProduct',(#25,#26,#35,#27,#28,#30,#34));
|
#24=IFCPROPERTYSETTEMPLATE('0I9merLinF5Ap$aZwaclgm',$,'BBIM_Dimension','',.PSET_TYPEDRIVENOVERRIDE.,'IfcAnnotation/DIMENSION,IfcAnnotation/RADIUS,IfcAnnotation/DIAMETER,IfcTypeProduct',(#25,#26,#35,#36,#27,#28,#30,#34));
|
||||||
#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.);
|
||||||
@@ -39,6 +39,7 @@ DATA;
|
|||||||
#32=IFCSIMPLEPROPERTYTEMPLATE('0gjJzDYBX8P85qn1xcAOOo',$,'Reverse_List','',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
#32=IFCSIMPLEPROPERTYTEMPLATE('0gjJzDYBX8P85qn1xcAOOo',$,'Reverse_List','',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||||
#34=IFCSIMPLEPROPERTYTEMPLATE('1Kx4Pm9nR8vBwZqTs2uYeL',$,'Separator','Characters placed between multiple dimension values when CustomUnit has more than one unit selected (default: '' / '')',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
#34=IFCSIMPLEPROPERTYTEMPLATE('1Kx4Pm9nR8vBwZqTs2uYeL',$,'Separator','Characters placed between multiple dimension values when CustomUnit has more than one unit selected (default: '' / '')',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||||
#35=IFCSIMPLEPROPERTYTEMPLATE('3Nf6Qs1mT0pWxBuCvDyEzA',$,'SuppressZeroFeet','Suppress 0 feet in dimension annotation text (for example: 0'' - 3 1/2" -> 3 1/2")',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
#35=IFCSIMPLEPROPERTYTEMPLATE('3Nf6Qs1mT0pWxBuCvDyEzA',$,'SuppressZeroFeet','Suppress 0 feet in dimension annotation text (for example: 0'' - 3 1/2" -> 3 1/2")',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||||
|
#36=IFCSIMPLEPROPERTYTEMPLATE('2Rg7Hn5jK4mLpNqOsVwXtY',$,'IsOrdinate','Show accumulated distance from the first vertex instead of individual segment lengths',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||||
#33=IFCSIMPLEPROPERTYTEMPLATE('22TrcxF8jFNB4buSmzjGEF',$,'List_Separator','',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.);
|
#33=IFCSIMPLEPROPERTYTEMPLATE('22TrcxF8jFNB4buSmzjGEF',$,'List_Separator','',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.);
|
||||||
ENDSEC;
|
ENDSEC;
|
||||||
END-ISO-10303-21;
|
END-ISO-10303-21;
|
||||||
|
|||||||
@@ -800,6 +800,7 @@ class DecoratorData:
|
|||||||
show_description_only = pset_data.get("ShowDescriptionOnly", False)
|
show_description_only = pset_data.get("ShowDescriptionOnly", False)
|
||||||
suppress_zero_inches = pset_data.get("SuppressZeroInches", False)
|
suppress_zero_inches = pset_data.get("SuppressZeroInches", False)
|
||||||
suppress_zero_feet = pset_data.get("SuppressZeroFeet", False)
|
suppress_zero_feet = pset_data.get("SuppressZeroFeet", False)
|
||||||
|
is_ordinate = pset_data.get("IsOrdinate", 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_units = list(pset_data.get("CustomUnit", None) or [])
|
custom_units = list(pset_data.get("CustomUnit", None) or [])
|
||||||
@@ -810,6 +811,7 @@ class DecoratorData:
|
|||||||
"show_description_only": show_description_only,
|
"show_description_only": show_description_only,
|
||||||
"suppress_zero_inches": suppress_zero_inches,
|
"suppress_zero_inches": suppress_zero_inches,
|
||||||
"suppress_zero_feet": suppress_zero_feet,
|
"suppress_zero_feet": suppress_zero_feet,
|
||||||
|
"is_ordinate": is_ordinate,
|
||||||
"text_prefix": text_prefix,
|
"text_prefix": text_prefix,
|
||||||
"text_suffix": text_suffix,
|
"text_suffix": text_suffix,
|
||||||
"fill_bg": fill_bg,
|
"fill_bg": fill_bg,
|
||||||
|
|||||||
@@ -719,11 +719,13 @@ class DimensionDecorator(BaseDecorator):
|
|||||||
if not dimension_data:
|
if not dimension_data:
|
||||||
return
|
return
|
||||||
show_description_only = dimension_data["show_description_only"]
|
show_description_only = dimension_data["show_description_only"]
|
||||||
|
is_ordinate = dimension_data["is_ordinate"]
|
||||||
text_prefix = dimension_data["text_prefix"]
|
text_prefix = dimension_data["text_prefix"]
|
||||||
text_suffix = dimension_data["text_suffix"]
|
text_suffix = dimension_data["text_suffix"]
|
||||||
viewportDrawingScale = self.get_viewport_drawing_scale(context)
|
viewportDrawingScale = self.get_viewport_drawing_scale(context)
|
||||||
text_offset_value = viewportDrawingScale * 3
|
text_offset_value = viewportDrawingScale * 3
|
||||||
|
|
||||||
|
ordinate_total = 0.0
|
||||||
for i0, i1 in indices:
|
for i0, i1 in indices:
|
||||||
v0 = Vector(vertices[i0])
|
v0 = Vector(vertices[i0])
|
||||||
v1 = Vector(vertices[i1])
|
v1 = Vector(vertices[i1])
|
||||||
@@ -742,10 +744,13 @@ class DimensionDecorator(BaseDecorator):
|
|||||||
"multiline": True,
|
"multiline": True,
|
||||||
"text_dir": text_dir,
|
"text_dir": text_dir,
|
||||||
}
|
}
|
||||||
base_pos = p0 + text_dir * 0.5
|
base_pos = p1 if is_ordinate else p0 + text_dir * 0.5
|
||||||
|
|
||||||
if not show_description_only:
|
if not show_description_only:
|
||||||
length = (v1 - v0).length
|
segment_length = (v1 - v0).length
|
||||||
|
if is_ordinate:
|
||||||
|
ordinate_total += segment_length
|
||||||
|
length = ordinate_total if is_ordinate else segment_length
|
||||||
units_to_format = dimension_data["custom_units"] if dimension_data["custom_units"] else [None]
|
units_to_format = dimension_data["custom_units"] if dimension_data["custom_units"] else [None]
|
||||||
parts = [
|
parts = [
|
||||||
self.format_value(
|
self.format_value(
|
||||||
@@ -768,15 +773,18 @@ class DimensionDecorator(BaseDecorator):
|
|||||||
|
|
||||||
self.draw_label(
|
self.draw_label(
|
||||||
text=text,
|
text=text,
|
||||||
pos=base_pos + text_offset,
|
pos=base_pos + text_offset + (Vector((0, text_offset_value)) if is_ordinate else Vector((0, 0))),
|
||||||
box_alignment="bottom-middle",
|
box_alignment="bottom-right" if is_ordinate else "bottom-middle",
|
||||||
multiline_to_bottom=False,
|
multiline_to_bottom=False,
|
||||||
**common_label_attrs,
|
**common_label_attrs,
|
||||||
)
|
)
|
||||||
|
|
||||||
if not show_description_only and description:
|
if not show_description_only and description:
|
||||||
self.draw_label(
|
self.draw_label(
|
||||||
text=description, pos=base_pos - text_offset, box_alignment="top-middle", **common_label_attrs
|
text=description,
|
||||||
|
pos=base_pos - text_offset + (Vector((0, text_offset_value)) if is_ordinate else Vector((0, 0))),
|
||||||
|
box_alignment="top-right" if is_ordinate else "top-middle",
|
||||||
|
**common_label_attrs,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1523,11 +1523,15 @@ class SvgWriter:
|
|||||||
dimension_data = DecoratorData.get_dimension_data(obj)
|
dimension_data = DecoratorData.get_dimension_data(obj)
|
||||||
|
|
||||||
assert isinstance(obj.data, bpy.types.Curve)
|
assert isinstance(obj.data, bpy.types.Curve)
|
||||||
|
is_ordinate = dimension_data["is_ordinate"]
|
||||||
for spline in obj.data.splines:
|
for spline in obj.data.splines:
|
||||||
points = self.get_spline_points(spline)
|
points = self.get_spline_points(spline)
|
||||||
|
ordinate_total = 0.0
|
||||||
for i in range(len(points) - 1):
|
for i in range(len(points) - 1):
|
||||||
v0_global = matrix_world @ points[i].co.xyz
|
v0_global = matrix_world @ points[i].co.xyz
|
||||||
v1_global = matrix_world @ points[i + 1].co.xyz
|
v1_global = matrix_world @ points[i + 1].co.xyz
|
||||||
|
if is_ordinate:
|
||||||
|
ordinate_total += (v1_global - v0_global).length
|
||||||
self.draw_dimension_annotation(
|
self.draw_dimension_annotation(
|
||||||
v0_global,
|
v0_global,
|
||||||
v1_global,
|
v1_global,
|
||||||
@@ -1541,6 +1545,7 @@ class SvgWriter:
|
|||||||
fill_bg=dimension_data["fill_bg"],
|
fill_bg=dimension_data["fill_bg"],
|
||||||
custom_units=dimension_data["custom_units"],
|
custom_units=dimension_data["custom_units"],
|
||||||
separator=dimension_data["separator"],
|
separator=dimension_data["separator"],
|
||||||
|
distance_override=ordinate_total if is_ordinate else None,
|
||||||
)
|
)
|
||||||
|
|
||||||
def draw_measureit_arch_dimension_annotations(self) -> None:
|
def draw_measureit_arch_dimension_annotations(self) -> None:
|
||||||
@@ -1570,6 +1575,7 @@ class SvgWriter:
|
|||||||
fill_bg=False,
|
fill_bg=False,
|
||||||
custom_units=None,
|
custom_units=None,
|
||||||
separator=" / ",
|
separator=" / ",
|
||||||
|
distance_override=None,
|
||||||
) -> None:
|
) -> 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)
|
||||||
@@ -1582,7 +1588,10 @@ class SvgWriter:
|
|||||||
sheet_dimension = (end - start).length
|
sheet_dimension = (end - start).length
|
||||||
|
|
||||||
# if annotation can't fit offset text to the right of marker
|
# if annotation can't fit offset text to the right of marker
|
||||||
text_position = mid if sheet_dimension > 5 else (end + (3 * vector.normalized()))
|
if distance_override is not None:
|
||||||
|
text_position = end
|
||||||
|
else:
|
||||||
|
text_position = mid if sheet_dimension > 5 else (end + (3 * vector.normalized()))
|
||||||
angle = math.degrees(vector.angle_signed(Vector((1, 0))))
|
angle = math.degrees(vector.angle_signed(Vector((1, 0))))
|
||||||
|
|
||||||
line = self.svg.line(start=start, end=end, class_=" ".join(classes))
|
line = self.svg.line(start=start, end=end, class_=" ".join(classes))
|
||||||
@@ -1597,7 +1606,7 @@ class SvgWriter:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if not show_description_only:
|
if not show_description_only:
|
||||||
dimension = (v1_global - v0_global).length
|
dimension = distance_override if distance_override is not None else (v1_global - v0_global).length
|
||||||
units_to_format = custom_units if custom_units else [None]
|
units_to_format = custom_units if custom_units else [None]
|
||||||
parts = [
|
parts = [
|
||||||
helper.format_distance(
|
helper.format_distance(
|
||||||
@@ -1618,8 +1627,8 @@ class SvgWriter:
|
|||||||
|
|
||||||
text_tags += self.create_text_tag(
|
text_tags += self.create_text_tag(
|
||||||
text,
|
text,
|
||||||
text_position + perpendicular,
|
text_position + perpendicular + (Vector((0, 1.5)) if distance_override is not None else Vector((0, 0))),
|
||||||
box_alignment="bottom-middle",
|
box_alignment="bottom-right" if distance_override is not None else "bottom-middle",
|
||||||
multiline_to_bottom=False,
|
multiline_to_bottom=False,
|
||||||
**text_tag_kwargs,
|
**text_tag_kwargs,
|
||||||
)
|
)
|
||||||
@@ -1627,8 +1636,8 @@ class SvgWriter:
|
|||||||
if not show_description_only and dimension_text:
|
if not show_description_only and dimension_text:
|
||||||
text_tags += self.create_text_tag(
|
text_tags += self.create_text_tag(
|
||||||
dimension_text,
|
dimension_text,
|
||||||
text_position - perpendicular,
|
text_position - perpendicular + (Vector((0, 1.5)) if distance_override is not None else Vector((0, 0))),
|
||||||
box_alignment="top-middle",
|
box_alignment="top-right" if distance_override is not None else "top-middle",
|
||||||
multiline_to_bottom=True,
|
multiline_to_bottom=True,
|
||||||
**text_tag_kwargs,
|
**text_tag_kwargs,
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user