Total refactoring for CSV into a blenderBim module + use of IfcStore (#1254)

* Add new feature to Load from IFCStore in Cobie

* Initial refactor for CSV to become a CSV Module

* Update __init__.py

* Address Dion's review

Co-authored-by: Ihab El Aghoury <ihab_elaghoury@yahoo.ca>
Co-authored-by: Dion Moult <dion@thinkmoult.com>
This commit is contained in:
ihabelaghoury
2021-01-13 22:53:48 +02:00
committed by GitHub
parent 540f793940
commit 713e70ff63
8 changed files with 191 additions and 133 deletions
@@ -0,0 +1,22 @@
import bpy
from . import ui, prop, operator
classes = (
operator.AddCsvAttribute,
operator.RemoveCsvAttribute,
operator.ExportIfcCsv,
operator.ImportIfcCsv,
operator.EyedropIfcCsv,
prop.CsvProperties,
ui.BIM_PT_ifccsv,
)
def register():
bpy.types.Scene.CsvProperties = bpy.props.PointerProperty(type=prop.CsvProperties)
def unregister():
del bpy.types.Scene.CsvProperties
@@ -0,0 +1,91 @@
import bpy
import ifccsv
import ifcopenshell
import os
import logging
import json
import webbrowser
import tempfile
from blenderbim.bim.ifc import IfcStore
class AddCsvAttribute(bpy.types.Operator):
bl_idname = "bim.add_csv_attribute"
bl_label = "Add CSV Attribute"
def execute(self, context):
attribute = bpy.context.scene.CsvProperties.csv_attributes.add()
return {"FINISHED"}
class RemoveCsvAttribute(bpy.types.Operator):
bl_idname = "bim.remove_csv_attribute"
bl_label = "Remove CSV Attribute"
index: bpy.props.IntProperty()
def execute(self, context):
bpy.context.scene.CsvProperties.csv_attributes.remove(self.index)
return {"FINISHED"}
class ExportIfcCsv(bpy.types.Operator):
bl_idname = "bim.export_ifccsv"
bl_label = "Export IFC to CSV"
filename_ext = ".csv"
filepath: bpy.props.StringProperty(subtype="FILE_PATH")
def invoke(self, context, event):
self.filepath = bpy.path.ensure_ext(bpy.data.filepath, ".csv")
WindowManager = context.window_manager
WindowManager.fileselect_add(self)
return {"RUNNING_MODAL"}
def execute(self, context):
import ifccsv
self.filepath = bpy.path.ensure_ext(self.filepath, ".csv")
ifc_file = ifcopenshell.open(bpy.context.scene.CsvProperties.csv_ifc_file)
selector = ifcopenshell.util.selector.Selector()
results = selector.parse(ifc_file, bpy.context.scene.CsvProperties.ifc_selector)
ifc_csv = ifccsv.IfcCsv()
ifc_csv.output = self.filepath
ifc_csv.attributes = [a.name for a in bpy.context.scene.CsvProperties.csv_attributes]
ifc_csv.selector = selector
if bpy.context.scene.CsvProperties.csv_delimiter == "CUSTOM":
ifc_csv.delimiter = bpy.context.scene.CsvProperties.csv_custom_delimiter
else:
ifc_csv.delimiter = bpy.context.scene.CsvProperties.csv_delimiter
ifc_csv.export(ifc_file, results)
return {"FINISHED"}
class ImportIfcCsv(bpy.types.Operator):
bl_idname = "bim.import_ifccsv"
bl_label = "Import CSV to IFC"
filename_ext = ".csv"
filepath: bpy.props.StringProperty(subtype="FILE_PATH")
def invoke(self, context, event):
self.filepath = bpy.path.ensure_ext(bpy.data.filepath, ".csv")
WindowManager = context.window_manager
WindowManager.fileselect_add(self)
return {"RUNNING_MODAL"}
def execute(self, context):
import ifccsv
ifc_csv = ifccsv.IfcCsv()
ifc_csv.output = self.filepath
ifc_csv.Import(bpy.context.scene.CsvProperties.csv_ifc_file)
return {"FINISHED"}
class EyedropIfcCsv(bpy.types.Operator):
bl_idname = "bim.eyedrop_ifccsv"
bl_label = "Query Selected Items"
def execute(self, context):
global_ids = []
for obj in bpy.context.selected_objects:
if hasattr(obj, "BIMObjectProperties") and obj.BIMObjectProperties.attributes.get("GlobalId"):
global_ids.append("#" + obj.BIMObjectProperties.attributes.get("GlobalId").string_value)
bpy.context.scene.CsvProperties.ifc_selector = "|".join(global_ids)
return {"FINISHED"}
@@ -0,0 +1,27 @@
import bpy
from blenderbim.bim.prop import StrProperty
from bpy.types import PropertyGroup
from bpy.props import (
PointerProperty,
StringProperty,
EnumProperty,
BoolProperty,
IntProperty,
FloatProperty,
FloatVectorProperty,
CollectionProperty,
)
class CsvProperties(PropertyGroup):
csv_ifc_file: StringProperty(default="", name="CSV IFC File")
ifc_selector: StringProperty(default="", name="IFC Selector")
csv_attributes: CollectionProperty(name="CSV Attributes", type=StrProperty)
csv_delimiter: EnumProperty(
items=[(";", ";", ""), (",", ",", ""), (".", ".", ""), ("CUSTOM", "Custom", ""),],
name="IFC CSV Delimiter",
default=",",
)
csv_custom_delimiter: StringProperty(default="", name="Custom Delimiter")
should_load_from_memory: BoolProperty(default=False, name="Load from Memory")
@@ -0,0 +1,50 @@
from bpy.types import Panel
from blenderbim.bim.ifc import IfcStore
class BIM_PT_ifccsv(Panel):
bl_label = "IFC CSV Import/Export"
bl_idname = "BIM_PT_ifccsv"
bl_options = {"DEFAULT_CLOSED"}
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
def draw(self, context):
layout = self.layout
scene = context.scene
props = scene.CsvProperties
if IfcStore.get_file():
row = layout.row()
row.prop(props, "should_load_from_memory")
if not IfcStore.get_file() or not props.should_load_from_memory:
row = layout.row(align=True)
row.prop(props, "csv_ifc_file")
row.operator("bim.import_ifccsv", icon="FILE_FOLDER", text="")
row = layout.row(align=True)
row.prop(props, "ifc_selector")
row.operator("bim.eyedrop_ifccsv", icon="EYEDROPPER", text="")
row = layout.row()
row.label(text="Add IFC attributes to filter", icon="FILE_BLANK")
row.operator("bim.add_csv_attribute")
for index, attribute in enumerate(props.csv_attributes):
row = layout.row(align=True)
row.prop(attribute, "name", text="")
row.operator("bim.remove_csv_attribute", icon="X", text="").index = index
row = layout.row(align=True)
row.prop(props, "csv_delimiter")
if(props.csv_delimiter == 'CUSTOM'):
row = layout.row(align=True)
row.prop(props, "csv_custom_delimiter")
row = layout.row(align=True)
row.operator("bim.export_ifccsv", icon="EXPORT")
row.operator("bim.import_ifccsv", icon="IMPORT")