mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 23:36:20 +00:00
Refactor qto utils and migrate to bmesh volume calculation. See #1222.
This commit is contained in:
@@ -30,6 +30,7 @@ if bpy is not None:
|
|||||||
"owner": None,
|
"owner": None,
|
||||||
"project": None,
|
"project": None,
|
||||||
"pset": None,
|
"pset": None,
|
||||||
|
"qto": None,
|
||||||
"search": None,
|
"search": None,
|
||||||
"spatial": None,
|
"spatial": None,
|
||||||
"style": None,
|
"style": None,
|
||||||
@@ -117,10 +118,6 @@ if bpy is not None:
|
|||||||
operator.SelectIfcPatchInput,
|
operator.SelectIfcPatchInput,
|
||||||
operator.SelectIfcPatchOutput,
|
operator.SelectIfcPatchOutput,
|
||||||
operator.ExecuteIfcPatch,
|
operator.ExecuteIfcPatch,
|
||||||
operator.CalculateEdgeLengths,
|
|
||||||
operator.CalculateFaceAreas,
|
|
||||||
operator.CalculateObjectVolumes,
|
|
||||||
operator.AddOpening,
|
|
||||||
operator.SetOverrideColour,
|
operator.SetOverrideColour,
|
||||||
operator.AddDrawing,
|
operator.AddDrawing,
|
||||||
operator.RemoveDrawing,
|
operator.RemoveDrawing,
|
||||||
@@ -198,7 +195,6 @@ if bpy is not None:
|
|||||||
ui.BIM_PT_text,
|
ui.BIM_PT_text,
|
||||||
ui.BIM_PT_modeling_utilities,
|
ui.BIM_PT_modeling_utilities,
|
||||||
ui.BIM_PT_annotation_utilities,
|
ui.BIM_PT_annotation_utilities,
|
||||||
ui.BIM_PT_qto_utilities,
|
|
||||||
ui.BIM_PT_clash_manager,
|
ui.BIM_PT_clash_manager,
|
||||||
ui.BIM_PT_misc_utilities,
|
ui.BIM_PT_misc_utilities,
|
||||||
ui.BIM_UL_generic,
|
ui.BIM_UL_generic,
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import bpy
|
||||||
|
from . import ui, prop, operator
|
||||||
|
|
||||||
|
classes = (
|
||||||
|
operator.CalculateEdgeLengths,
|
||||||
|
operator.CalculateFaceAreas,
|
||||||
|
operator.CalculateObjectVolumes,
|
||||||
|
prop.BIMQtoProperties,
|
||||||
|
ui.BIM_PT_qto_utilities,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def register():
|
||||||
|
bpy.types.Scene.BIMQtoProperties = bpy.props.PointerProperty(type=prop.BIMQtoProperties)
|
||||||
|
|
||||||
|
|
||||||
|
def unregister():
|
||||||
|
del bpy.types.Scene.BIMQtoProperties
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
import bpy
|
||||||
|
import bmesh
|
||||||
|
|
||||||
|
|
||||||
|
class CalculateEdgeLengths(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.calculate_edge_lengths"
|
||||||
|
bl_label = "Calculate Edge Lengths"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
result = 0
|
||||||
|
for obj in bpy.context.selected_objects:
|
||||||
|
if not obj.data or not obj.data.edges:
|
||||||
|
continue
|
||||||
|
for edge in obj.data.edges:
|
||||||
|
if edge.select:
|
||||||
|
result += (obj.data.vertices[edge.vertices[1]].co - obj.data.vertices[edge.vertices[0]].co).length
|
||||||
|
bpy.context.scene.BIMQtoProperties.qto_result = str(round(result, 3))
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class CalculateFaceAreas(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.calculate_face_areas"
|
||||||
|
bl_label = "Calculate Face Areas"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
result = 0
|
||||||
|
for obj in bpy.context.selected_objects:
|
||||||
|
if not obj.data or not obj.data.polygons:
|
||||||
|
continue
|
||||||
|
for polygon in obj.data.polygons:
|
||||||
|
if polygon.select:
|
||||||
|
result += polygon.area
|
||||||
|
bpy.context.scene.BIMQtoProperties.qto_result = str(round(result, 3))
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class CalculateObjectVolumes(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.calculate_object_volumes"
|
||||||
|
bl_label = "Calculate Object Volumes"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
result = 0
|
||||||
|
for obj in bpy.context.selected_objects:
|
||||||
|
if not obj.data or not isinstance(obj.data, bpy.types.Mesh):
|
||||||
|
continue
|
||||||
|
bm = bmesh.new()
|
||||||
|
bm.from_mesh(obj.data)
|
||||||
|
result += bm.calc_volume()
|
||||||
|
bm.free()
|
||||||
|
bpy.context.scene.BIMQtoProperties.qto_result = str(round(result, 3))
|
||||||
|
return {"FINISHED"}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import bpy
|
||||||
|
from blenderbim.bim.prop import StrProperty, Attribute
|
||||||
|
from blenderbim.bim.module.owner.data import Data
|
||||||
|
from bpy.types import PropertyGroup
|
||||||
|
from bpy.props import (
|
||||||
|
PointerProperty,
|
||||||
|
StringProperty,
|
||||||
|
EnumProperty,
|
||||||
|
BoolProperty,
|
||||||
|
IntProperty,
|
||||||
|
FloatProperty,
|
||||||
|
FloatVectorProperty,
|
||||||
|
CollectionProperty,
|
||||||
|
)
|
||||||
|
|
||||||
|
class BIMQtoProperties(PropertyGroup):
|
||||||
|
qto_result: StringProperty(default="", name="Qto Result")
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
from bpy.types import Panel
|
||||||
|
|
||||||
|
|
||||||
|
class BIM_PT_qto_utilities(Panel):
|
||||||
|
bl_idname = "BIM_PT_qto_utilities"
|
||||||
|
bl_label = "Quantity Take-off"
|
||||||
|
bl_space_type = "VIEW_3D"
|
||||||
|
bl_region_type = "UI"
|
||||||
|
bl_category = "BlenderBIM"
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
props = context.scene.BIMQtoProperties
|
||||||
|
|
||||||
|
row = layout.row()
|
||||||
|
row.prop(props, "qto_result", text="Results")
|
||||||
|
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.operator("bim.calculate_edge_lengths")
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.operator("bim.calculate_face_areas")
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.operator("bim.calculate_object_volumes")
|
||||||
@@ -1838,73 +1838,6 @@ class SelectIfcPatchOutput(bpy.types.Operator):
|
|||||||
return {"RUNNING_MODAL"}
|
return {"RUNNING_MODAL"}
|
||||||
|
|
||||||
|
|
||||||
class CalculateEdgeLengths(bpy.types.Operator):
|
|
||||||
bl_idname = "bim.calculate_edge_lengths"
|
|
||||||
bl_label = "Calculate Edge Lengths"
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
result = 0
|
|
||||||
for obj in bpy.context.selected_objects:
|
|
||||||
if not obj.data or not obj.data.edges:
|
|
||||||
continue
|
|
||||||
for edge in obj.data.edges:
|
|
||||||
if edge.select:
|
|
||||||
result += (obj.data.vertices[edge.vertices[1]].co - obj.data.vertices[edge.vertices[0]].co).length
|
|
||||||
bpy.context.scene.BIMProperties.qto_result = str(round(result, 3))
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class CalculateFaceAreas(bpy.types.Operator):
|
|
||||||
bl_idname = "bim.calculate_face_areas"
|
|
||||||
bl_label = "Calculate Face Areas"
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
result = 0
|
|
||||||
for obj in bpy.context.selected_objects:
|
|
||||||
if not obj.data or not obj.data.polygons:
|
|
||||||
continue
|
|
||||||
for polygon in obj.data.polygons:
|
|
||||||
if polygon.select:
|
|
||||||
result += polygon.area
|
|
||||||
bpy.context.scene.BIMProperties.qto_result = str(round(result, 3))
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class CalculateObjectVolumes(bpy.types.Operator):
|
|
||||||
bl_idname = "bim.calculate_object_volumes"
|
|
||||||
bl_label = "Calculate Object Volumes"
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
# TODO: reimplement
|
|
||||||
qto_calculator = qto.QtoCalculator()
|
|
||||||
result = 0
|
|
||||||
for obj in bpy.context.selected_objects:
|
|
||||||
if not obj.data:
|
|
||||||
continue
|
|
||||||
result += qto_calculator.get_volume(obj)
|
|
||||||
bpy.context.scene.BIMProperties.qto_result = str(round(result, 3))
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class AddOpening(bpy.types.Operator):
|
|
||||||
bl_idname = "bim.add_opening"
|
|
||||||
bl_label = "Add Opening"
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
if context.active_object.children and "IfcOpeningElement/" in context.active_object.children[0].name:
|
|
||||||
opening = context.active_object.children[0]
|
|
||||||
else:
|
|
||||||
opening = context.active_object
|
|
||||||
if context.selected_objects[0] != context.active_object:
|
|
||||||
obj = context.selected_objects[0]
|
|
||||||
else:
|
|
||||||
obj = context.selected_objects[1]
|
|
||||||
modifier = obj.modifiers.new("IfcOpeningElement", "BOOLEAN")
|
|
||||||
modifier.operation = "DIFFERENCE"
|
|
||||||
modifier.object = opening
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class SetOverrideColour(bpy.types.Operator):
|
class SetOverrideColour(bpy.types.Operator):
|
||||||
bl_idname = "bim.set_override_colour"
|
bl_idname = "bim.set_override_colour"
|
||||||
bl_label = "Set Override Colour"
|
bl_label = "Set Override Colour"
|
||||||
|
|||||||
@@ -764,7 +764,6 @@ class BIMProperties(PropertyGroup):
|
|||||||
ifc_patch_input: StringProperty(default="", name="IFC Patch Input IFC")
|
ifc_patch_input: StringProperty(default="", name="IFC Patch Input IFC")
|
||||||
ifc_patch_output: StringProperty(default="", name="IFC Patch Output IFC")
|
ifc_patch_output: StringProperty(default="", name="IFC Patch Output IFC")
|
||||||
ifc_patch_args: StringProperty(default="", name="Arguments")
|
ifc_patch_args: StringProperty(default="", name="Arguments")
|
||||||
qto_result: StringProperty(default="", name="Qto Result")
|
|
||||||
area_unit: EnumProperty(
|
area_unit: EnumProperty(
|
||||||
default="SQUARE_METRE",
|
default="SQUARE_METRE",
|
||||||
items=[
|
items=[
|
||||||
|
|||||||
@@ -832,30 +832,6 @@ class BIM_PT_annotation_utilities(Panel):
|
|||||||
layout.prop(props, "decorations_colour")
|
layout.prop(props, "decorations_colour")
|
||||||
|
|
||||||
|
|
||||||
class BIM_PT_qto_utilities(Panel):
|
|
||||||
bl_idname = "BIM_PT_qto_utilities"
|
|
||||||
bl_label = "Quantity Take-off"
|
|
||||||
bl_space_type = "VIEW_3D"
|
|
||||||
bl_region_type = "UI"
|
|
||||||
bl_category = "BlenderBIM"
|
|
||||||
|
|
||||||
def draw(self, context):
|
|
||||||
layout = self.layout
|
|
||||||
props = context.scene.BIMProperties
|
|
||||||
|
|
||||||
row = layout.row()
|
|
||||||
layout.label(text="Results:")
|
|
||||||
row = layout.row()
|
|
||||||
row.prop(props, "qto_result", text="")
|
|
||||||
|
|
||||||
row = layout.row(align=True)
|
|
||||||
row.operator("bim.calculate_edge_lengths")
|
|
||||||
row = layout.row(align=True)
|
|
||||||
row.operator("bim.calculate_face_areas")
|
|
||||||
row = layout.row(align=True)
|
|
||||||
row.operator("bim.calculate_object_volumes")
|
|
||||||
|
|
||||||
|
|
||||||
class BIM_PT_clash_manager(Panel):
|
class BIM_PT_clash_manager(Panel):
|
||||||
bl_idname = "BIM_PT_clash_manager"
|
bl_idname = "BIM_PT_clash_manager"
|
||||||
bl_label = "Clash Manager"
|
bl_label = "Clash Manager"
|
||||||
|
|||||||
Reference in New Issue
Block a user