mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-26 10:11:46 +00:00
Merge branch 'v0.8.0' into ifcmax/initial-refresh
This commit is contained in:
@@ -466,13 +466,14 @@ class PolylineDecorator:
|
|||||||
|
|
||||||
self.addon_prefs = tool.Blender.get_addon_preferences()
|
self.addon_prefs = tool.Blender.get_addon_preferences()
|
||||||
self.font_id = 0
|
self.font_id = 0
|
||||||
font_size = tool.Blender.scale_font_size(12)
|
font_size = tool.Blender.scale_font_size()
|
||||||
|
offset = tool.Blender.scale_font_size() * 1.5
|
||||||
|
line_height = tool.Blender.scale_font_size() * 1.25
|
||||||
blf.size(self.font_id, font_size)
|
blf.size(self.font_id, font_size)
|
||||||
blf.enable(self.font_id, blf.SHADOW)
|
blf.enable(self.font_id, blf.SHADOW)
|
||||||
blf.shadow(self.font_id, 6, 0, 0, 0, 1)
|
blf.shadow(self.font_id, 6, 0, 0, 0, 1)
|
||||||
color = self.addon_prefs.decorations_colour
|
color = self.addon_prefs.decorations_colour
|
||||||
color_highlight = self.addon_prefs.decorator_color_special
|
color_highlight = self.addon_prefs.decorator_color_special
|
||||||
offset = 20
|
|
||||||
new_line = 0
|
new_line = 0
|
||||||
for i, (key, field_name) in enumerate(texts.items()):
|
for i, (key, field_name) in enumerate(texts.items()):
|
||||||
formatted_value = None
|
formatted_value = None
|
||||||
@@ -480,7 +481,7 @@ class PolylineDecorator:
|
|||||||
# Controls which options are displayed in the UI
|
# Controls which options are displayed in the UI
|
||||||
if key not in self.input_ui.input_options:
|
if key not in self.input_ui.input_options:
|
||||||
continue
|
continue
|
||||||
new_line += 20
|
new_line += line_height
|
||||||
if self.tool_state and key != self.tool_state.input_type:
|
if self.tool_state and key != self.tool_state.input_type:
|
||||||
formatted_value = self.input_ui.get_formatted_value(key)
|
formatted_value = self.input_ui.get_formatted_value(key)
|
||||||
else:
|
else:
|
||||||
@@ -515,7 +516,7 @@ class PolylineDecorator:
|
|||||||
self.addon_prefs = tool.Blender.get_addon_preferences()
|
self.addon_prefs = tool.Blender.get_addon_preferences()
|
||||||
self.font_id = 1
|
self.font_id = 1
|
||||||
self.shader = gpu.shader.from_builtin("UNIFORM_COLOR")
|
self.shader = gpu.shader.from_builtin("UNIFORM_COLOR")
|
||||||
font_size = tool.Blender.scale_font_size(12)
|
font_size = tool.Blender.scale_font_size()
|
||||||
blf.size(self.font_id, font_size)
|
blf.size(self.font_id, font_size)
|
||||||
blf.enable(self.font_id, blf.SHADOW)
|
blf.enable(self.font_id, blf.SHADOW)
|
||||||
blf.shadow(self.font_id, 6, 0, 0, 0, 1)
|
blf.shadow(self.font_id, 6, 0, 0, 0, 1)
|
||||||
@@ -1936,7 +1937,7 @@ class BoundingBoxDecorator:
|
|||||||
|
|
||||||
addon_prefs = tool.Blender.get_addon_preferences()
|
addon_prefs = tool.Blender.get_addon_preferences()
|
||||||
font_id = 0
|
font_id = 0
|
||||||
font_size = tool.Blender.scale_font_size(12)
|
font_size = tool.Blender.scale_font_size()
|
||||||
blf.size(font_id, font_size)
|
blf.size(font_id, font_size)
|
||||||
blf.enable(font_id, blf.SHADOW)
|
blf.enable(font_id, blf.SHADOW)
|
||||||
blf.shadow(font_id, 6, 0, 0, 0, 1)
|
blf.shadow(font_id, 6, 0, 0, 0, 1)
|
||||||
|
|||||||
@@ -747,6 +747,12 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences):
|
|||||||
default=".ifc.metadata.blend",
|
default=".ifc.metadata.blend",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
decorator_font_scale: bpy.props.FloatProperty(
|
||||||
|
name="Decorator Font Scale",
|
||||||
|
description="Scale factor for decorator font size.",
|
||||||
|
default=1.0,
|
||||||
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
svg2pdf_command: str
|
svg2pdf_command: str
|
||||||
svg2dxf_command: str
|
svg2dxf_command: str
|
||||||
@@ -786,6 +792,7 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences):
|
|||||||
mass_time_units_in_wizard: bool
|
mass_time_units_in_wizard: bool
|
||||||
chain_filter_with_set_operations: bool
|
chain_filter_with_set_operations: bool
|
||||||
save_metadata_blend_file: bool
|
save_metadata_blend_file: bool
|
||||||
|
decorator_font_scale: float
|
||||||
|
|
||||||
def draw(self, context: bpy.types.Context) -> None:
|
def draw(self, context: bpy.types.Context) -> None:
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
@@ -1009,6 +1016,7 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences):
|
|||||||
else:
|
else:
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.operator("bim.manage_tab_visibility", icon="PREFERENCES")
|
row.operator("bim.manage_tab_visibility", icon="PREFERENCES")
|
||||||
|
layout.prop(self, "decorator_font_scale")
|
||||||
|
|
||||||
|
|
||||||
# Scene panel groups
|
# Scene panel groups
|
||||||
|
|||||||
@@ -1571,13 +1571,18 @@ class Blender(bonsai.core.tool.Blender):
|
|||||||
return getattr(scene, "sun_pos_properties", None)
|
return getattr(scene, "sun_pos_properties", None)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def scale_font_size(cls, size):
|
def scale_font_size(cls, size=None):
|
||||||
default_dpi = 72
|
default_dpi = 72
|
||||||
default_pixel_size = 1.0
|
default_pixel_size = 1.0
|
||||||
|
ui_style = bpy.context.preferences.ui_styles[0]
|
||||||
|
base_size = ui_style.widget.points if size is None else size
|
||||||
|
platform_scale = 0.5 if sys.platform == "darwin" else 1
|
||||||
|
|
||||||
default_scale = default_dpi * default_pixel_size
|
default_scale = default_dpi * default_pixel_size
|
||||||
system = bpy.context.preferences.system
|
system = bpy.context.preferences.system
|
||||||
system_scale = system.dpi * system.pixel_size
|
system_scale = system.dpi * system.pixel_size
|
||||||
return (system_scale / default_scale) * size
|
return (system_scale / default_scale) * base_size *platform_scale * tool.Blender.get_addon_preferences().decorator_font_scale
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def apply_transform_as_local(cls, obj: bpy.types.Object) -> bool:
|
def apply_transform_as_local(cls, obj: bpy.types.Object) -> bool:
|
||||||
|
|||||||
@@ -1244,18 +1244,7 @@ class Model(bonsai.core.tool.Model):
|
|||||||
|
|
||||||
height = 100
|
height = 100
|
||||||
|
|
||||||
is_horizontal = False
|
is_horizontal = cls.get_usage_type(element) == "LAYER3"
|
||||||
if element.is_a("IfcSlabType"):
|
|
||||||
is_horizontal = True
|
|
||||||
|
|
||||||
parametric = ifcopenshell.util.element.get_psets(element).get("EPset_Parametric")
|
|
||||||
if parametric:
|
|
||||||
layer_set_direction = parametric.get("LayerSetDirection", None)
|
|
||||||
if layer_set_direction == "AXIS2":
|
|
||||||
is_horizontal = False
|
|
||||||
elif layer_set_direction == "AXIS3":
|
|
||||||
is_horizontal = True
|
|
||||||
|
|
||||||
if is_horizontal:
|
if is_horizontal:
|
||||||
width, height = height, width
|
width, height = height, width
|
||||||
|
|
||||||
@@ -1266,7 +1255,7 @@ class Model(bonsai.core.tool.Model):
|
|||||||
del thicknesses[-1]
|
del thicknesses[-1]
|
||||||
for thickness in thicknesses:
|
for thickness in thicknesses:
|
||||||
current_thickness += thickness
|
current_thickness += thickness
|
||||||
if element.is_a("IfcSlabType"):
|
if is_horizontal:
|
||||||
y = (current_thickness / total_thickness) * height
|
y = (current_thickness / total_thickness) * height
|
||||||
line = [x_offset, y_offset + y, x_offset + width, y_offset + y]
|
line = [x_offset, y_offset + y, x_offset + width, y_offset + y]
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -165,13 +165,6 @@ bool OpenCascadeKernel::convert(const taxonomy::loft::ptr loft, TopoDS_Shape& re
|
|||||||
std::vector<TopoDS_Shape> shps(loft->children.size());
|
std::vector<TopoDS_Shape> shps(loft->children.size());
|
||||||
std::vector<std::vector<std::set<std::string>>> all_tags;
|
std::vector<std::vector<std::set<std::string>>> all_tags;
|
||||||
|
|
||||||
|
|
||||||
std::ostringstream oss;
|
|
||||||
loft->children[0]->print(oss);
|
|
||||||
loft->children[1]->print(oss);
|
|
||||||
auto s = oss.str();
|
|
||||||
std::wcout << s.c_str() << std::endl;
|
|
||||||
|
|
||||||
// First convert all taxonomy items to TopoDS_Wire/Face
|
// First convert all taxonomy items to TopoDS_Wire/Face
|
||||||
for (auto it = loft->children.begin(); it < loft->children.end(); ++it) {
|
for (auto it = loft->children.begin(); it < loft->children.end(); ++it) {
|
||||||
auto i = std::distance(loft->children.begin(), it);
|
auto i = std::distance(loft->children.begin(), it);
|
||||||
@@ -267,6 +260,18 @@ bool OpenCascadeKernel::convert(const taxonomy::loft::ptr loft, TopoDS_Shape& re
|
|||||||
return true;
|
return true;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (shps.size() < 2) {
|
||||||
|
Logger::Error("Not enough sections to loft");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shps[0].ShapeType() == TopAbs_FACE) {
|
||||||
|
// When processing a sectioned *surface* there are no
|
||||||
|
// begin and end caps that need to be added.
|
||||||
|
BB.Add(comp, shps.front().Reversed());
|
||||||
|
BB.Add(comp, shps.back());
|
||||||
|
}
|
||||||
|
|
||||||
// @todo this approach is
|
// @todo this approach is
|
||||||
// potentially incorrect as there is no guarantee that the wires for
|
// potentially incorrect as there is no guarantee that the wires for
|
||||||
// subsequently placed profiles are traversed from an equivalent start vertex.
|
// subsequently placed profiles are traversed from an equivalent start vertex.
|
||||||
@@ -292,18 +297,6 @@ bool OpenCascadeKernel::convert(const taxonomy::loft::ptr loft, TopoDS_Shape& re
|
|||||||
ws[0][i] = TopoDS::Wire(*fa[i]);
|
ws[0][i] = TopoDS::Wire(*fa[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (it->ShapeType() == TopAbs_FACE) {
|
|
||||||
// When processing a sectioned *surface* there are no
|
|
||||||
// begin and end caps that need to be added.
|
|
||||||
if (it == shps.begin()) {
|
|
||||||
// faces.Append(shps[0]);
|
|
||||||
BB.Add(comp, shps[0]);
|
|
||||||
}
|
|
||||||
if (jt == shps.end() - 1) {
|
|
||||||
// faces.Append(shps[1]);
|
|
||||||
BB.Add(comp, shps[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!all_tags.empty()) {
|
if (!all_tags.empty()) {
|
||||||
// only open profiles have tags for now, so there is only one wire, no inner wires
|
// only open profiles have tags for now, so there is only one wire, no inner wires
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ nest formulas, for example ``concat(title("foo"), lower("Bar"))`` will produce
|
|||||||
"``imperial_length({{value}}, {{precision}}, {{input_unit}}, {{output_unit}}, {{suppress_zero_inches}})``", "``imperial_length(3.0, 4, ""foot"", ""foot"", true)`` OR ``imperial_length(3.0, 4, ""foot"", ""foot"", false)``", "``3'`` OR ``3' - 0""``", "The ``{{value}}`` may be specified either as ``foot`` or ``inch`` depending on ``{{input_unit}}``. The ``{{value}}`` is then rounded to the nearest ``1/{{precision}}`` inch, then formatted using fractional feet and inches if ``{{output_unit}}`` is set to ``foot``, or just inches if ``{{output_unit}}`` is set to ``inch``. When ``{{suppress_zero_inches}}`` is ``true`` (default), measurements with zero inches will omit the inch portion (e.g., ``3'`` instead of ``3' - 0""``)."
|
"``imperial_length({{value}}, {{precision}}, {{input_unit}}, {{output_unit}}, {{suppress_zero_inches}})``", "``imperial_length(3.0, 4, ""foot"", ""foot"", true)`` OR ``imperial_length(3.0, 4, ""foot"", ""foot"", false)``", "``3'`` OR ``3' - 0""``", "The ``{{value}}`` may be specified either as ``foot`` or ``inch`` depending on ``{{input_unit}}``. The ``{{value}}`` is then rounded to the nearest ``1/{{precision}}`` inch, then formatted using fractional feet and inches if ``{{output_unit}}`` is set to ``foot``, or just inches if ``{{output_unit}}`` is set to ``inch``. When ``{{suppress_zero_inches}}`` is ``true`` (default), measurements with zero inches will omit the inch portion (e.g., ``3'`` instead of ``3' - 0""``)."
|
||||||
"``sort({{values}})``", "``sort({{mats.Name}})``", "``Name1, Name2``", "Sorts a list of items."
|
"``sort({{values}})``", "``sort({{mats.Name}})``", "``Name1, Name2``", "Sorts a list of items."
|
||||||
"``reverse({{values}})``", "``reverse({{mats.Name}})``", "``Name2, Name1``", "Reverses a list of items."
|
"``reverse({{values}})``", "``reverse({{mats.Name}})``", "``Name2, Name1``", "Reverses a list of items."
|
||||||
"``join({{separator}}, {{values}})``", "``join("-", {{mats.Name}})``", "``Name1-Name2``", "Joins a list of items with a custom separator. By default, all lists a rendered as comma separated."
|
"``join({{separator}}, {{values}})``", "``join(""-"", {{mats.Name}})``", "``Name1-Name2``", "Joins a list of items with a custom separator. By default, all lists a rendered as comma separated."
|
||||||
"``{{value1}}[+-*/]{{value2}}``", "``{{z}}+3``", "``5``", "Does arithmetic. Typical operators such as +, -, \*, and / are allowed and can be mixed with other variables and formatting functions."
|
"``{{value1}}[+-*/]{{value2}}``", "``{{z}}+3``", "``5``", "Does arithmetic. Typical operators such as +, -, \*, and / are allowed and can be mixed with other variables and formatting functions."
|
||||||
|
|
||||||
When using queries in an IfcAnnotation tag surround with backticks.
|
When using queries in an IfcAnnotation tag surround with backticks.
|
||||||
|
|||||||
@@ -63,14 +63,15 @@ def reference_structure(
|
|||||||
storey1 = ifcopenshell.api.root.create_entity(model, ifc_class="IfcBuildingStorey")
|
storey1 = ifcopenshell.api.root.create_entity(model, ifc_class="IfcBuildingStorey")
|
||||||
storey2 = ifcopenshell.api.root.create_entity(model, ifc_class="IfcBuildingStorey")
|
storey2 = ifcopenshell.api.root.create_entity(model, ifc_class="IfcBuildingStorey")
|
||||||
storey3 = ifcopenshell.api.root.create_entity(model, ifc_class="IfcBuildingStorey")
|
storey3 = ifcopenshell.api.root.create_entity(model, ifc_class="IfcBuildingStorey")
|
||||||
|
space = ifcopenshell.api.root.create_entity(model, ifc_class="IfcSpace")
|
||||||
|
|
||||||
# The project contains a site (note that project aggregation is a special case in IFC)
|
# The project contains a site (note that project aggregation is a special case in IFC)
|
||||||
ifcopenshell.api.aggregate.assign_object(model, products=[site], relating_object=project)
|
ifcopenshell.api.aggregate.assign_object(model, products=[site], relating_object=project)
|
||||||
|
|
||||||
# The site has a building, the building has a storey, and the storey has a space
|
# The site has a building, the building has a storey, and the storey has a space
|
||||||
ifcopenshell.api.aggregate.assign_object(model, products=[building], relating_object=site)
|
ifcopenshell.api.aggregate.assign_object(model, products=[building], relating_object=site)
|
||||||
ifcopenshell.api.aggregate.assign_object(model, products=[storey], relating_object=building)
|
ifcopenshell.api.aggregate.assign_object(model, products=[storey1,storey2,storey3], relating_object=building)
|
||||||
ifcopenshell.api.aggregate.assign_object(model, products=[space], relating_object=storey)
|
ifcopenshell.api.aggregate.assign_object(model, products=[space], relating_object=storey1)
|
||||||
|
|
||||||
# Create a column, this column spans 3 storeys
|
# Create a column, this column spans 3 storeys
|
||||||
column = ifcopenshell.api.root.create_entity(model, ifc_class="IfcWall")
|
column = ifcopenshell.api.root.create_entity(model, ifc_class="IfcWall")
|
||||||
@@ -80,7 +81,11 @@ def reference_structure(
|
|||||||
|
|
||||||
# And referenced in the others
|
# And referenced in the others
|
||||||
ifcopenshell.api.spatial.reference_structure(
|
ifcopenshell.api.spatial.reference_structure(
|
||||||
model, products=[column], relating_structure=[storey2, storey3]
|
model, products=[column], relating_structure=storey2
|
||||||
|
)
|
||||||
|
|
||||||
|
ifcopenshell.api.spatial.reference_structure(
|
||||||
|
model, products=[column], relating_structure=storey3
|
||||||
)
|
)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user