Refactor qto utils and migrate to bmesh volume calculation. See #1222.

This commit is contained in:
Dion Moult
2021-01-23 18:01:29 +11:00
parent f19b962ab1
commit aa3a855b4c
8 changed files with 110 additions and 97 deletions
@@ -30,6 +30,7 @@ if bpy is not None:
"owner": None,
"project": None,
"pset": None,
"qto": None,
"search": None,
"spatial": None,
"style": None,
@@ -117,10 +118,6 @@ if bpy is not None:
operator.SelectIfcPatchInput,
operator.SelectIfcPatchOutput,
operator.ExecuteIfcPatch,
operator.CalculateEdgeLengths,
operator.CalculateFaceAreas,
operator.CalculateObjectVolumes,
operator.AddOpening,
operator.SetOverrideColour,
operator.AddDrawing,
operator.RemoveDrawing,
@@ -198,7 +195,6 @@ if bpy is not None:
ui.BIM_PT_text,
ui.BIM_PT_modeling_utilities,
ui.BIM_PT_annotation_utilities,
ui.BIM_PT_qto_utilities,
ui.BIM_PT_clash_manager,
ui.BIM_PT_misc_utilities,
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"}
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):
bl_idname = "bim.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_output: StringProperty(default="", name="IFC Patch Output IFC")
ifc_patch_args: StringProperty(default="", name="Arguments")
qto_result: StringProperty(default="", name="Qto Result")
area_unit: EnumProperty(
default="SQUARE_METRE",
items=[
-24
View File
@@ -832,30 +832,6 @@ class BIM_PT_annotation_utilities(Panel):
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):
bl_idname = "BIM_PT_clash_manager"
bl_label = "Clash Manager"