Bim project manager upgrade (#17909)

* BIM: NativeIFC 2D support - basic import/export + linework annotations

* BIM: NativeIFC 2D support - texts

* BIM: NativeIFC 2D support - dimensions

* BIM: NativeIFC 2D support - optimized export of FreeCAD dimensions

* BIM: NativeIFC 2D support - section planes

* BIM: NativeIFC 2D support - misc fixes cf comment #2383181661

* BIM: NativeIFC 2D support - axes

* BIM: Project manager upgrade

* BIM: Fixed rebase leftover
This commit is contained in:
Yorik van Havre
2025-02-10 10:40:46 +01:00
committed by GitHub
parent d36e41d18b
commit 7829cab969
9 changed files with 596 additions and 362 deletions

View File

@@ -427,10 +427,12 @@ class ViewProviderBuildingPart:
def __init__(self,vobj):
vobj.addExtension("Gui::ViewProviderGroupExtensionPython")
vobj.Proxy = self
self.setProperties(vobj)
vobj.ShapeColor = ArchCommands.getDefaultColor("Helpers")
if vobj:
vobj.addExtension("Gui::ViewProviderGroupExtensionPython")
vobj.Proxy = self
self.setProperties(vobj)
vobj.ShapeColor = ArchCommands.getDefaultColor("Helpers")
self.Object = vobj.Object
def setProperties(self,vobj):
@@ -532,6 +534,9 @@ class ViewProviderBuildingPart:
return ":/icons/Arch_Building_Tree.svg"
elif self.Object.IfcType == "Annotation":
return ":/icons/BIM_ArchView.svg"
elif hasattr(self.Object,"IfcClass"):
from nativeifc import ifc_viewproviders
return ifc_viewproviders.get_icon(self)
return ":/icons/Arch_BuildingPart_Tree.svg"
def attach(self,vobj):
@@ -661,7 +666,10 @@ class ViewProviderBuildingPart:
self.lco.point.setValues([[-fs,0,0],[fs,0,0],[0,-fs,0],[0,fs,0],[0,0,-fs],[0,0,fs]])
elif prop in ["OverrideUnit","ShowUnit","ShowLevel","ShowLabel"]:
if hasattr(vobj,"OverrideUnit") and hasattr(vobj,"ShowUnit") and hasattr(vobj,"ShowLevel") and hasattr(vobj,"ShowLabel") and hasattr(self,"txt"):
z = vobj.Object.Placement.Base.z + vobj.Object.LevelOffset.Value
offset = getattr(vobj.Object, "LevelOffset", 0)
if hasattr(offset, "Value"):
offset = offset.Value
z = vobj.Object.Placement.Base.z + offset
q = FreeCAD.Units.Quantity(z,FreeCAD.Units.Length)
txt = ""
if vobj.ShowLabel:
@@ -729,7 +737,7 @@ class ViewProviderBuildingPart:
self.clip.plane.setValue(plane)
sg.insertChild(self.clip,0)
else:
if self.clip:
if getattr(self,"clip",None):
sg.removeChild(self.clip)
self.clip = None
for o in Draft.get_group_contents(vobj.Object.Group,

View File

@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>402</width>
<height>470</height>
<width>443</width>
<height>840</height>
</rect>
</property>
<property name="windowTitle">
@@ -17,7 +17,7 @@
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>This screen allows you to configure a new BIM project in FreeCAD.</string>
<string>This screen allows you to create and configure a new BIM project in FreeCAD.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@@ -25,43 +25,42 @@
</widget>
</item>
<item>
<widget class="QComboBox" name="presets">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<property name="text">
<string>Use preset...</string>
</property>
</item>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QPushButton" name="buttonSaveTemplate">
<widget class="QComboBox" name="presets">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Saves the current document as a template, including all the current BIM settings</string>
</property>
<property name="text">
<string>Save template...</string>
</property>
<property name="icon">
<iconset theme="gtk-save">
<normaloff/>
</iconset>
<string>Fill this dialog with preset values</string>
</property>
<item>
<property name="text">
<string>Use preset...</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonLoadTemplate">
<widget class="QPushButton" name="buttonSave">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Loads the contents of a FCStd file into the active document, applying all the BIM settings stored in it if any</string>
<string>The settings below can be saved as a preset. Presets are stored as .txt files in your FreeCAD user folder</string>
</property>
<property name="text">
<string>Load template...</string>
<string>Save preset</string>
</property>
<property name="icon">
<iconset theme="gtk-open">
<normaloff/>
</iconset>
<iconset theme="gtk-save">
<normaloff>../../../../../../../.designer/backup</normaloff>../../../../../../../.designer/backup</iconset>
</property>
</widget>
</item>
@@ -76,58 +75,108 @@
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>369</width>
<height>1214</height>
<y>-1041</y>
<width>428</width>
<height>1740</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="groupNewDocument">
<widget class="QGroupBox" name="groupNewProject">
<property name="toolTip">
<string>Create a new BIM project</string>
</property>
<property name="title">
<string>Create new document</string>
<string>Create a new BIM project</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label_18">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="label_8">
<property name="text">
<string>Project name</string>
<string>A new BIM project will be created, either as a new FreeCAD document or as a Native IFC project</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="projectName">
<property name="text">
<string>Unnamed</string>
</property>
</widget>
<item>
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="QRadioButton" name="radioNative1">
<property name="toolTip">
<string>This will create a new FreeCAD docment that allows you to build a BIM model, but with no specific IFC structure yet. This is the most flexible option when you start working ona BIM project. You can convert this project to IFC anytime later.</string>
</property>
<property name="text">
<string>Create a new document witout IFC support yet</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioNative2">
<property name="toolTip">
<string>This will create an IFC project. All the BIM objects you will add to that IFC project will immediately become IFC objects. This is less flexible, but allows you to stick more strictly to the IFC standard.</string>
</property>
<property name="text">
<string>Create a Native IFC project in the current dopcument</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioNative3">
<property name="toolTip">
<string>The new IFC project will be created as a new FreeCAD document. In that mode, the IFC project is the FreeCAD document, anything you create in that document becomes part of the IFC project. This is extremely restrictive as no non-IFC object can be added to the document.</string>
</property>
<property name="text">
<string>Create a locked Native IFC project as a new document</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="label_18">
<property name="text">
<string>Project name</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="projectName">
<property name="toolTip">
<string>A name for this BIM or IFC project</string>
</property>
<property name="text">
<string>Unnamed</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QCheckBox" name="addHumanFigure">
<property name="toolTip">
<string>If this is checked, a human figure will be added, which helps greatly to give a sense of scale when viewing the model</string>
</property>
<property name="text">
<string>Add a human figure</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupSite">
<property name="toolTip">
<string>Create a new site</string>
</property>
<property name="title">
<string>Create Site</string>
<string>Create site</string>
</property>
<property name="flat">
<bool>false</bool>
@@ -150,17 +199,20 @@
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="1">
<widget class="QDoubleSpinBox" name="siteLongitude">
<property name="toolTip">
<string>The East longitude of this site</string>
</property>
<property name="suffix">
<string> E</string>
</property>
<property name="decimals">
<number>4</number>
</property>
<property name="minimum">
<double>-180.000000000000000</double>
</property>
<property name="maximum">
<double>180.0</double>
</property>
<property name="minimum">
<double>-180.0</double>
<double>180.000000000000000</double>
</property>
</widget>
</item>
@@ -180,6 +232,9 @@
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="siteName">
<property name="toolTip">
<string>A name for this site</string>
</property>
<property name="text">
<string>Default Site</string>
</property>
@@ -194,6 +249,9 @@
</item>
<item row="5" column="1">
<widget class="QDoubleSpinBox" name="siteDeviation">
<property name="toolTip">
<string>The difference between the up direction of this site and the true North direction</string>
</property>
<property name="suffix">
<string> °</string>
</property>
@@ -211,13 +269,20 @@
</item>
<item row="6" column="1">
<widget class="Gui::InputField" name="siteElevation">
<property name="toolTip">
<string>The elevation of this site</string>
</property>
<property name="unit" stdset="0">
<string notr="true"/>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="siteAddress"/>
<widget class="QLineEdit" name="siteAddress">
<property name="toolTip">
<string>The physical (postal) address of this site</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
@@ -235,17 +300,20 @@
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="siteLatitude">
<property name="toolTip">
<string>The North latitude of this site</string>
</property>
<property name="suffix">
<string> N</string>
</property>
<property name="decimals">
<number>4</number>
</property>
<property name="maximum">
<double>90.0</double>
</property>
<property name="minimum">
<double>-90.0</double>
<double>-90.000000000000000</double>
</property>
<property name="maximum">
<double>90.000000000000000</double>
</property>
</widget>
</item>
@@ -256,8 +324,11 @@
</item>
<item>
<widget class="QGroupBox" name="groupBuilding">
<property name="toolTip">
<string>Create a new building</string>
</property>
<property name="title">
<string>Create Building</string>
<string>Create building</string>
</property>
<property name="checkable">
<bool>true</bool>
@@ -332,6 +403,9 @@
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>The main use of this building</string>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToMinimumContentsLength</enum>
</property>
@@ -352,6 +426,9 @@
</item>
<item row="7" column="1">
<widget class="QSpinBox" name="countVAxes">
<property name="toolTip">
<string>Number of vertical axes</string>
</property>
<property name="value">
<number>0</number>
</property>
@@ -366,6 +443,9 @@
</item>
<item row="9" column="1">
<widget class="QSpinBox" name="countHAxes">
<property name="toolTip">
<string>Number of horizontal axes</string>
</property>
<property name="value">
<number>0</number>
</property>
@@ -373,8 +453,11 @@
</item>
<item row="5" column="1">
<widget class="Gui::InputField" name="buildingWidth">
<property name="toolTip">
<string>An estimate building width. Keep 0 if you don't want to specify this now</string>
</property>
<property name="text">
<string>0 </string>
<string>0</string>
</property>
<property name="unit" stdset="0">
<string notr="true"/>
@@ -383,6 +466,9 @@
</item>
<item row="13" column="1">
<widget class="QSpinBox" name="lineWidth">
<property name="toolTip">
<string>The line width of axes</string>
</property>
<property name="value">
<number>2</number>
</property>
@@ -390,8 +476,11 @@
</item>
<item row="8" column="1">
<widget class="Gui::InputField" name="distVAxes">
<property name="toolTip">
<string>Distance between vertical axes</string>
</property>
<property name="text">
<string>0 </string>
<string>0</string>
</property>
<property name="unit" stdset="0">
<string notr="true"/>
@@ -400,8 +489,11 @@
</item>
<item row="4" column="1">
<widget class="Gui::InputField" name="buildingLength">
<property name="toolTip">
<string>An estimate building length. Keep 0 if you don't want to specify this now</string>
</property>
<property name="text">
<string>0 </string>
<string>0</string>
</property>
<property name="unit" stdset="0">
<string notr="true"/>
@@ -410,6 +502,9 @@
</item>
<item row="10" column="1">
<widget class="Gui::InputField" name="distHAxes">
<property name="toolTip">
<string>Distance between horizontal axes</string>
</property>
<property name="text">
<string>0 </string>
</property>
@@ -427,6 +522,9 @@
</item>
<item row="14" column="1">
<widget class="Gui::ColorButton" name="lineColor">
<property name="toolTip">
<string>The color of axes</string>
</property>
<property name="color">
<color>
<red>33</red>
@@ -448,16 +546,54 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="addHumanFigure">
<property name="toolTip">
<string>Add a human figure to the document</string>
</property>
<property name="title">
<string>Add a human figure</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QLabel" name="label_10">
<property name="text">
<string>A human figure will be added to the document, which helps giving a sense of scale</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Levels</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QLabel" name="label_9">
<property name="text">
<string>BIM projects are typically organized into levels, that represents the different storeys of a building. Although it is not mandatory to work with levels in FreeCAD, you can set up default levels here</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="1">
<widget class="QSpinBox" name="countLevels">
<property name="toolTip">
<string>The number of levels to create</string>
</property>
<property name="singleStep">
<number>1</number>
</property>
@@ -475,6 +611,9 @@
</item>
<item row="1" column="1">
<widget class="Gui::InputField" name="levelHeight">
<property name="toolTip">
<string>The vertical distance between each level</string>
</property>
<property name="text">
<string>0 </string>
</property>
@@ -492,29 +631,21 @@
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="levelsAxis">
<property name="text">
<string>Bind levels to vertical axes</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="levelsWP">
<property name="text">
<string>Define a working plane for each level</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_34">
<property name="text">
<string>Default groups to be added to each level</string>
<string>Default groups to be added to each level. Defautl groups such as walls, windows,... are useful to organize the different building elements inside a level</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="groupsList">
<property name="toolTip">
<string>A list of grouls to add under each level</string>
</property>
<property name="dragEnabled">
<bool>true</bool>
</property>
@@ -530,25 +661,29 @@
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="buttonAdd">
<property name="toolTip">
<string>Add a new group</string>
</property>
<property name="text">
<string>Add</string>
</property>
<property name="icon">
<iconset theme="add">
<normaloff/>
</iconset>
<normaloff>../../../../../../../.designer/backup</normaloff>../../../../../../../.designer/backup</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonDel">
<property name="toolTip">
<string>Delete a selected group</string>
</property>
<property name="text">
<string>Del</string>
</property>
<property name="icon">
<iconset theme="remove">
<normaloff/>
</iconset>
<normaloff>../../../../../../../.designer/backup</normaloff>../../../../../../../.designer/backup</iconset>
</property>
</widget>
</item>
@@ -561,30 +696,8 @@
</widget>
</widget>
</item>
<item>
<widget class="QLabel" name="label_35">
<property name="text">
<string>The above settings can be saved as a preset. Presets are stored as .txt files in your FreeCAD user folder</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="buttonSave">
<property name="text">
<string>Save preset</string>
</property>
<property name="icon">
<iconset theme="gtk-save">
<normaloff/>
</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
@@ -600,25 +713,29 @@
</item>
<item>
<widget class="QPushButton" name="buttonOK">
<property name="toolTip">
<string>Accept the values fo this form</string>
</property>
<property name="text">
<string>OK</string>
</property>
<property name="icon">
<iconset theme="gtk-ok">
<normaloff/>
</iconset>
<normaloff>../../../../../../../.designer/backup</normaloff>../../../../../../../.designer/backup</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonCancel">
<property name="toolTip">
<string>Cancel</string>
</property>
<property name="text">
<string>Cancel</string>
</property>
<property name="icon">
<iconset theme="gtk-cancel">
<normaloff/>
</iconset>
<normaloff>../../../../../../../.designer/backup</normaloff>../../../../../../../.designer/backup</iconset>
</property>
</widget>
</item>
@@ -638,43 +755,6 @@
<header>Gui/Widgets.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>presets</tabstop>
<tabstop>buttonSaveTemplate</tabstop>
<tabstop>buttonLoadTemplate</tabstop>
<tabstop>scrollArea</tabstop>
<tabstop>groupNewDocument</tabstop>
<tabstop>projectName</tabstop>
<tabstop>addHumanFigure</tabstop>
<tabstop>groupSite</tabstop>
<tabstop>siteName</tabstop>
<tabstop>siteAddress</tabstop>
<tabstop>siteLatitude</tabstop>
<tabstop>siteLongitude</tabstop>
<tabstop>siteDeviation</tabstop>
<tabstop>siteElevation</tabstop>
<tabstop>groupBuilding</tabstop>
<tabstop>buildingName</tabstop>
<tabstop>buildingUse</tabstop>
<tabstop>buildingLength</tabstop>
<tabstop>buildingWidth</tabstop>
<tabstop>countVAxes</tabstop>
<tabstop>distVAxes</tabstop>
<tabstop>countHAxes</tabstop>
<tabstop>distHAxes</tabstop>
<tabstop>lineWidth</tabstop>
<tabstop>lineColor</tabstop>
<tabstop>countLevels</tabstop>
<tabstop>levelHeight</tabstop>
<tabstop>levelsAxis</tabstop>
<tabstop>levelsWP</tabstop>
<tabstop>groupsList</tabstop>
<tabstop>buttonAdd</tabstop>
<tabstop>buttonDel</tabstop>
<tabstop>buttonSave</tabstop>
<tabstop>buttonOK</tabstop>
<tabstop>buttonCancel</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@@ -25,6 +25,7 @@
import os
import sys
import math
import FreeCAD
import FreeCADGui
@@ -33,22 +34,27 @@ translate = FreeCAD.Qt.translate
class BIM_ProjectManager:
def GetResources(self):
return {
"Pixmap": "BIM_ProjectManager",
"MenuText": QT_TRANSLATE_NOOP("BIM_ProjectManager", "Manage project..."),
"MenuText": QT_TRANSLATE_NOOP("BIM_ProjectManager", "Setup project..."),
"ToolTip": QT_TRANSLATE_NOOP(
"BIM_ProjectManager", "Setup your BIM project"
"BIM_ProjectManager", "Create or manage a BIM project"
),
}
def Activated(self):
import FreeCADGui
# load dialog
import FreeCADGui
import ArchBuildingPart
from PySide import QtCore, QtGui
self.form = FreeCADGui.PySideUic.loadUi(":/ui/dialogProjectManager.ui")
self.project = None
self.site = None
self.building = None
# center the dialog over FreeCAD window
mw = FreeCADGui.getMainWindow()
@@ -59,75 +65,130 @@ class BIM_ProjectManager:
)
# set things up
import ArchBuildingPart
self.form.buildingUse.addItems(ArchBuildingPart.BuildingTypes)
self.form.setWindowIcon(QtGui.QIcon(":/icons/BIM_ProjectManager.svg"))
QtCore.QObject.connect(
self.form.buttonAdd, QtCore.SIGNAL("clicked()"), self.addGroup
)
QtCore.QObject.connect(
self.form.buttonDel, QtCore.SIGNAL("clicked()"), self.delGroup
)
QtCore.QObject.connect(
self.form.buttonSave, QtCore.SIGNAL("clicked()"), self.savePreset
)
QtCore.QObject.connect(
self.form.presets,
QtCore.SIGNAL("currentIndexChanged(QString)"),
self.getPreset,
)
QtCore.QObject.connect(
self.form.buttonOK, QtCore.SIGNAL("clicked()"), self.accept
)
QtCore.QObject.connect(
self.form.buttonCancel, QtCore.SIGNAL("clicked()"), self.reject
)
QtCore.QObject.connect(
self.form.buttonSaveTemplate, QtCore.SIGNAL("clicked()"), self.saveTemplate
)
QtCore.QObject.connect(
self.form.buttonLoadTemplate, QtCore.SIGNAL("clicked()"), self.loadTemplate
)
self.form.buttonAdd.clicked.connect(self.addGroup)
self.form.buttonDel.clicked.connect(self.delGroup)
self.form.buttonSave.clicked.connect(self.savePreset)
self.form.presets.currentIndexChanged.connect(self.getPreset)
self.form.buttonOK.clicked.connect(self.accept)
self.form.buttonCancel.clicked.connect(self.reject)
self.fillPresets()
# Detect existing objects
sel = FreeCADGui.Selection.getSelection()
doc = FreeCAD.ActiveDocument
if doc:
if len(sel) == 1:
if hasattr(sel[0], "Proxy") and hasattr(sel[0].Proxy, "ifcfile"):
# case 1: a project is selected
self.project = sel[0]
self.form.groupNewProject.setEnabled(False)
if hasattr(doc, "Proxy"):
# case 2: the actuve document is a project
if hasattr(doc.Proxy, "ifcfile"):
self.project = doc
self.form.groupNewProject.setEnabled(False)
if self.project:
from nativeifc import ifc_tools
sites = ifc_tools.get_children(self.project, ifctype="IfcSite")
sites = list(filter(None, [ifc_tools.get_object(s) for s in sites]))
self.form.projectName.setText(self.project.Label)
else:
sites = [o for o in doc.Objects if getattr(o, "IfcType", "") == "Site"]
if sites:
self.site = sites[0]
self.form.siteName.setText(self.site.Label)
if hasattr(self.site,"Address"):
self.form.siteAddress.setText(self.site.Address)
elif hasattr(self.site,"SiteAddress"):
self.form.siteAddress.setText(self.site.SiteAddress)
if hasattr(self.site,"Longitude"):
self.form.siteLongitude.setValue(self.site.Longitude)
elif hasattr(self.site,"RefLongitude"):
self.form.siteLongitude.setValue(self.site.RefLongitude)
if hasattr(self.site,"Latitude"):
self.form.siteLatitude.setValue(self.site.Latitude)
elif hasattr(self.site,"RefLatitude"):
self.form.siteLatitude.setValue(self.site.RefLatitude)
if hasattr(self.site,"Elevation"):
self.form.siteElevation.setText(self.site.Elevation.UserString)
elif hasattr(self.site,"RefElevation"):
self.form.siteElevation.setText(self.site.RefElevation.UserString)
if hasattr(self.site, "Declination"):
self.form.siteElevation.setText(str(self.site.Declination))
buildings = []
if self.site and self.project:
from nativeifc import ifc_tools
buildings = ifc_tools.get_children(self.site, ifctype="IfcBuilding")
buildings = list(filter(None, [ifc_tools.get_object(b) for b in buildings]))
if not buildings:
buildings = [o for o in doc.Objects if getattr(o, "IfcType", "") == "Building"]
if buildings:
self.building = buildings[0]
self.form.buildingName.setText(self.building.Label)
levels = ifc_tools.get_children(self.building, ifctype="IfcBuildingStorey")
if levels:
self.form.countLevels.setValue(len(levels))
# show dialog
self.form.show()
def reject(self):
self.form.hide()
return True
def accept(self):
import Arch
import Draft
import FreeCADGui
import Part
if self.form.groupNewDocument.isChecked() or (FreeCAD.ActiveDocument is None):
doc = FreeCAD.newDocument()
if self.form.projectName.text():
doc.Label = self.form.projectName.text()
FreeCAD.ActiveDocument = doc
if not FreeCAD.ActiveDocument:
FreeCAD.Console.PrintError(
translate("BIM", "No active document, aborting.") + "\n"
)
site = None
vaxes = []
haxes = []
outline = None
if self.form.groupSite.isChecked():
site = Arch.makeSite()
site.Label = self.form.siteName.text()
site.Address = self.form.siteAddress.text()
site.Longitude = self.form.siteLongitude.value()
site.Latitude = self.form.siteLatitude.value()
if hasattr(site, "NorthDeviation"):
site.NorthDeviation = self.form.siteDeviation.value()
elif hasattr(site, "Declination"):
site.Declination = self.form.siteDeviation.value()
site.Elevation = FreeCAD.Units.Quantity(
self.form.siteElevation.text()
).Value
outtext = None
human = None
grp = None
if self.form.groupNewProject.isChecked():
self.project = None
self.site = None
self.building = None
# reading form values
buildingWidth = FreeCAD.Units.Quantity(self.form.buildingWidth.text()).Value
buildingLength = FreeCAD.Units.Quantity(self.form.buildingLength.text()).Value
distVAxes = FreeCAD.Units.Quantity(self.form.distVAxes.text()).Value
distHAxes = FreeCAD.Units.Quantity(self.form.distHAxes.text()).Value
levelHeight = FreeCAD.Units.Quantity(self.form.levelHeight.text()).Value
color = self.form.lineColor.property("color").getRgbF()[:3]
# Document creation
doc = FreeCAD.ActiveDocument
if self.form.groupNewProject.isChecked():
if self.form.radioNative1.isChecked() or \
self.form.radioNative3.isChecked() or \
(self.form.radioNative2.isChecked() and doc is None):
doc = FreeCAD.newDocument()
if self.form.projectName.text():
doc.Label = self.form.projectName.text()
if doc:
FreeCAD.setActiveDocument(doc.Name)
# Project creation
if self.form.groupNewProject.isChecked():
from nativeifc import ifc_tools
if self.form.radioNative2.isChecked():
self.project = ifc_tools.create_document_object(doc, silent=True)
if self.form.projectName.text():
self.project.Label = self.form.projectName.text()
elif self.form.radioNative3.isChecked():
self.project = ifc_tools.convert_document(doc, silent=True)
# human
human = None
if self.form.addHumanFigure.isChecked():
humanshape = Part.Shape()
@@ -135,47 +196,127 @@ class BIM_ProjectManager:
human = FreeCAD.ActiveDocument.addObject("Part::Feature", "Human")
human.Shape = humanshape
human.Placement.move(FreeCAD.Vector(500, 500, 0))
# Site creation or edition
outline = None
if self.form.groupSite.isChecked():
if not self.site:
self.site = Arch.makeSite()
if self.project:
from nativeifc import ifc_tools
self.site = ifc_tools.aggregate(self.site, self.project)
self.site.Label = self.form.siteName.text()
if hasattr(self.site,"Address"):
self.site.Address = self.form.siteAddress.text()
elif hasattr(self.site,"SiteAddress"):
self.site.SiteAddress = self.form.siteAddress.text()
if hasattr(self.site,"Longitude"):
self.site.Longitude = self.form.siteLongitude.value()
elif hasattr(self.site,"RefLongitude"):
self.site.RefLongitude = self.form.siteLongitude.value()
if hasattr(self.site,"Latitude"):
self.site.Latitude = self.form.siteLatitude.value()
elif hasattr(self.site,"RefLatitude"):
self.site.RefLatitude = self.form.siteLatitude.value()
if hasattr(self.site, "NorthDeviation"):
self.site.NorthDeviation = self.form.siteDeviation.value()
elif hasattr(self.site, "Declination"):
self.site.Declination = self.form.siteDeviation.value()
elev = FreeCAD.Units.Quantity(self.form.siteElevation.text()).Value
if hasattr(self.site, "Elevation"):
self.site.Elevation = elev
elif hasattr(self.site, "RefElevation"):
self.site.RefElevation = elev
# Building creation or edition
if self.form.groupBuilding.isChecked():
building = Arch.makeBuilding()
if site:
site.Group = [building]
building.Label = self.form.buildingName.text()
building.BuildingType = self.form.buildingUse.currentText()
buildingWidth = FreeCAD.Units.Quantity(self.form.buildingWidth.text()).Value
buildingLength = FreeCAD.Units.Quantity(
self.form.buildingLength.text()
).Value
distVAxes = FreeCAD.Units.Quantity(self.form.distVAxes.text()).Value
distHAxes = FreeCAD.Units.Quantity(self.form.distHAxes.text()).Value
levelHeight = FreeCAD.Units.Quantity(self.form.levelHeight.text()).Value
color = self.form.lineColor.property("color").getRgbF()[:3]
grp = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup")
grp.Label = translate("BIM", "Building Layout")
building.addObject(grp)
if not self.building:
self.building = Arch.makeBuilding()
if self.project:
from nativeifc import ifc_tools
if self.site:
self.building = ifc_tools.aggregate(self.building, self.site)
else:
self.building = ifc_tools.aggregate(self.building, self.project)
elif self.site:
self.site.Group = [self.building]
self.building.Label = self.form.buildingName.text()
if hasattr(self.building, "BuildingType"):
self.building.BuildingType = self.form.buildingUse.currentText()
# Detecting existing contents
if self.building:
grp = [o for o in self.building.Group if o.Name.startswith("BuildingLayout")]
if grp:
grp = grp[0]
if grp:
axes = [o for o in grp.Group if o.Name.startswith("Axis")]
if axes:
for ax in axes:
if round(math.degrees(ax.Placement.Rotation.Angle),0) in [0, 180, 360]:
vaxes.append(ax)
elif round(math.degrees(ax.Placement.Rotation.Angle),0) in [90, 270]:
haxes.append(ax)
outline = [o for o in grp.Group if o.Name.startswith("Rectangle")]
if outline:
outline = outline[0]
human = [o for o in grp.Group if o.Name.startswith("Human")]
if human:
human = human[0]
else:
if self.form.addHumanFigure.isChecked() or self.form.countVAxes.value() \
or self.form.countHAxes.value() or (buildingWidth and buildingLength):
grp = doc.addObject("App::DocumentObjectGroup", "BuildingLayout")
grp.Label = translate("BIM", "Building Layout")
if self.building:
if hasattr(self.building, "addObject"):
self.building.addObject(grp)
# Human figure
if self.form.addHumanFigure.isChecked():
if not human:
# TODO embed this
humanpath = os.path.join(
os.path.dirname(__file__), "geometry", "human figure.brep"
)
if os.path.exists(humanpath):
humanshape = Part.Shape()
humanshape.importBrep(humanpath)
human = FreeCAD.ActiveDocument.addObject("Part::Feature", "Human")
human.Shape = humanshape
human.Placement.move(FreeCAD.Vector(500, 500, 0))
if human:
grp.addObject(human)
# TODO: nativeifc
# Outline
if buildingWidth and buildingLength:
outline = Draft.makeRectangle(buildingLength, buildingWidth, face=False)
outline.Label = translate("BIM", "Building Outline")
outline.ViewObject.DrawStyle = "Dashed"
if not outline:
outline = Draft.makeRectangle(buildingLength, buildingWidth, face=False)
outline.Label = translate("BIM", "Building Outline")
outline.ViewObject.DrawStyle = "Dashed"
grp.addObject(outline)
outline.ViewObject.LineColor = color
outline.ViewObject.LineWidth = self.form.lineWidth.value() * 2
grp.addObject(outline)
if self.form.buildingName.text():
buildingname = self.form.buildingName.text()
if sys.version_info.major == 2:
buildingname = unicode(buildingname)
outtext = Draft.makeText(
[buildingname],
point=FreeCAD.Vector(
Draft.getParam("textheight", 0.20) * 0.3,
-Draft.getParam("textheight", 0.20) * 1.43,
0,
),
)
outtext.Label = translate("BIM", "Building Label")
outtext.ViewObject.TextColor = color
grp.addObject(outtext)
if human:
grp.addObject(human)
outline.Length = buildingLength
outline.Height = buildingWidth
# Label
if self.form.buildingName.text():
buildingname = self.form.buildingName.text()
outtext = Draft.make_text(
[buildingname],
FreeCAD.Vector(
Draft.getParam("textheight", 0.20) * 0.3,
-Draft.getParam("textheight", 0.20) * 1.43,
0,
),
)
outtext.Label = translate("BIM", "Building Label")
outtext.ViewObject.TextColor = color
grp.addObject(outtext)
# Axes
axisV = None
if self.form.countVAxes.value() and distVAxes:
axisV = Arch.makeAxis(
@@ -187,18 +328,6 @@ class BIM_ProjectManager:
axisV.ViewObject.FontSize = Draft.getParam("textheight", 0.20)
axisV.ViewObject.BubbleSize = Draft.getParam("textheight", 0.20) * 1.43
axisV.ViewObject.LineColor = color
if outline:
axisV.setExpression("Length", outline.Name + ".Height * 1.1")
axisV.setExpression(
"Placement.Base.y",
outline.Name
+ ".Placement.Base.y - "
+ axisV.Name
+ ".Length * 0.05",
)
axisV.setExpression(
"Placement.Base.x", outline.Name + ".Placement.Base.x"
)
axisH = None
if self.form.countHAxes.value() and distHAxes:
axisH = Arch.makeAxis(
@@ -212,18 +341,6 @@ class BIM_ProjectManager:
axisH.ViewObject.BubbleSize = Draft.getParam("textheight", 0.20) * 1.43
axisH.Placement.Rotation = FreeCAD.Rotation(FreeCAD.Vector(0, 0, 1), 90)
axisH.ViewObject.LineColor = color
if outline:
axisH.setExpression("Length", outline.Name + ".Length * 1.1")
axisH.setExpression(
"Placement.Base.x",
outline.Name
+ ".Placement.Base.x + "
+ axisH.Name
+ ".Length * 0.945",
)
axisH.setExpression(
"Placement.Base.y", outline.Name + ".Placement.Base.y"
)
if axisV and axisH:
axisG = Arch.makeAxisSystem([axisH, axisV])
axisG.Label = translate("BIM", "Axes")
@@ -245,67 +362,41 @@ class BIM_ProjectManager:
alabels.append(lev.Label)
lev.Height = levelHeight
lev.Placement.move(FreeCAD.Vector(0, 0, h))
building.addObject(lev)
if self.form.levelsWP.isChecked():
prx = Draft.makeWorkingPlaneProxy(FreeCAD.Placement())
prx.Placement.move(FreeCAD.Vector(0, 0, h))
lev.addObject(prx)
if self.project and self.building:
from nativeifc import ifc_tools
lev = ifc_tools.aggregate(lev, self.building)
elif self.building:
self.building.addObject(lev)
h += levelHeight
for group in groups:
levGroup = FreeCAD.ActiveDocument.addObject(
"App::DocumentObjectGroup"
)
levGroup.Label = group
lev.addObject(levGroup)
if self.form.levelsAxis.isChecked():
axisL = Arch.makeAxis(
num=self.form.countLevels.value(),
size=levelHeight,
name="laxis",
)
axisL.Label = translate("BIM", "Level Axes")
axisL.ViewObject.BubblePosition = "None"
axisL.ViewObject.LineWidth = self.form.lineWidth.value()
axisL.ViewObject.FontSize = Draft.getParam("textheight", 0.20)
axisL.Placement.Rotation = FreeCAD.Rotation(
FreeCAD.Vector(
0.577350269189626, -0.5773502691896257, 0.5773502691896257
),
120,
)
axisL.ViewObject.LineColor = color
axisL.ViewObject.LabelOffset.Rotation = FreeCAD.Rotation(
FreeCAD.Vector(1, 0, 0), 90
)
axisL.Labels = alabels
axisL.ViewObject.ShowLabel = True
if outline:
axisL.setExpression("Length", outline.Name + ".Length * 1.1")
axisL.setExpression(
"Placement.Base.x",
outline.Name
+ ".Placement.Base.x + "
+ axisL.Name
+ ".Length * 0.945",
)
axisL.setExpression(
"Placement.Base.y", outline.Name + ".Placement.Base.y"
)
grp.addObject(axisL)
axisL.ViewObject.LabelOffset.Base = FreeCAD.Vector(
-axisL.Length.Value + Draft.getParam("textheight", 0.20) * 0.43,
0,
Draft.getParam("textheight", 0.20) * 0.43,
)
self.form.hide()
if self.project:
from nativeifc import ifc_tools
ifc_tools.aggregate(levGroup, lev)
else:
lev.addObject(levGroup)
FreeCAD.ActiveDocument.recompute()
# fit zoom
if outline:
FreeCADGui.Selection.clearSelection()
FreeCADGui.Selection.addSelection(outline)
FreeCADGui.SendMsgToActiveView("ViewSelection")
FreeCADGui.Selection.clearSelection()
# aggregate layout group
if self.building and grp:
if hasattr(self.building, "IfcClass"):
from nativeifc import ifc_tools
ifc_tools.aggregate(grp, self.building)
self.form.hide()
FreeCAD.ActiveDocument.recompute()
if hasattr(FreeCADGui, "Snapper"):
FreeCADGui.Snapper.show()
if self.form.radioNative3.isChecked():
from nativeifc import ifc_status
ifc_status.set_button(True,True)
return True
def addGroup(self):
@@ -403,6 +494,7 @@ class BIM_ProjectManager:
import Arch
from PySide import QtGui
preset = self.form.presets.itemText(preset)
pfile = os.path.join(FreeCAD.getUserAppDataDir(), "BIM", preset + ".txt")
if os.path.exists(pfile):
f = open(pfile, "r")

View File

@@ -2423,7 +2423,8 @@ def getUID(obj,preferences):
obj.IfcData = d
if hasattr(obj, "GlobalId"):
obj.GlobalId = uid
uids.append(uid)
if "uids" in globals():
uids.append(uid)
return uid
@@ -2499,6 +2500,11 @@ def create_annotation(anno, ifcfile, context, history, preferences):
"""Creates an annotation object"""
global curvestyles, ifcbin
reps = []
repid = "Annotation"
reptype = "Annotation2D"
description = getattr(anno, "Description", None)
# uses global ifcbin, curvestyles
objectType = None
ovc = None
zvc = None
@@ -2506,7 +2512,6 @@ def create_annotation(anno, ifcfile, context, history, preferences):
reps = []
repid = "Annotation"
reptype = "Annotation2D"
description = getattr(anno, "Description", None)
if anno.isDerivedFrom("Part::Feature"):
if Draft.getType(anno) == "Hatch":
objectType = "HATCH"
@@ -2525,15 +2530,8 @@ def create_annotation(anno, ifcfile, context, history, preferences):
axes.append(axis)
if axes:
if len(axes) > 1:
xvc = ifcbin.createIfcDirection((1.0,0.0,0.0))
zvc = ifcbin.createIfcDirection((0.0,0.0,1.0))
ovc = ifcbin.createIfcCartesianPoint((0.0,0.0,0.0))
gpl = ifcbin.createIfcAxis2Placement3D(ovc,zvc,xvc)
plac = ifcbin.createIfcLocalPlacement(gpl)
grid = ifcfile.createIfcGrid(uid,history,name,description,None,plac,None,axes,None,None)
return grid
else:
return axes[0]
print("DEBUG: exportIFC.create_annotation: Cannot create more thna one axis",anno.Label)
return axes[0]
else:
print("Unable to handle object",anno.Label)
return None

View File

@@ -13,10 +13,10 @@
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU Library General Public License for more details. *
# * *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
# * *
# ***************************************************************************
@@ -196,6 +196,8 @@ def get_object_type(ifcentity, objecttype=None):
objecttype = "axis"
elif ifcentity.is_a("IfcControl"):
objecttype = "schedule"
elif ifcentity.is_a() in ["IfcBuilding", "IfcBuildingStorey"]:
objecttype = "buildingpart"
return objecttype

View File

@@ -28,7 +28,7 @@ translate = FreeCAD.Qt.translate
# the property groups below should not be treated as psets
NON_PSETS = ["Base", "IFC", "", "Geometry", "Dimension", "Linear/radial dimension",
"SectionPlane", "Axis", "PhysicalProperties"]
"SectionPlane", "Axis", "PhysicalProperties", "BuildingPart", "IFC Attributes"]
class ifc_object:
"""Base class for all IFC-based objects"""
@@ -325,8 +325,6 @@ class ifc_object:
ifc_types.edit_type(obj)
def edit_quantity(self, obj, prop):
"""Edits the given quantity"""
pass # TODO implement

View File

@@ -81,10 +81,14 @@ class ifc_observer:
def slotChangedDocument(self, doc, prop):
"""Watch document IFC properties"""
# only look at locked IFC documents
if not "IfcFilePath" in doc.PropertiesList:
return
from nativeifc import ifc_tools # lazy import
from nativeifc import ifc_status
if prop == "Schema" and "IfcFilePath" in doc.PropertiesList:
if prop == "Schema":
schema = doc.Schema
ifcfile = ifc_tools.get_ifcfile(doc)
if ifcfile:
@@ -101,6 +105,10 @@ class ifc_observer:
]
if len(child) == 1:
child[0].StepId = new_id
elif prop == "Label":
ifcfile = ifc_tools.get_ifcfile(doc)
project = ifc_tools.get_ifc_element(doc)
ifc_tools.set_attribute(ifcfile, project, "Name", doc.Label)
def slotCreatedObject(self, obj):
"""If this is an IFC document, turn the object into IFC"""

View File

@@ -61,6 +61,7 @@ from nativeifc import ifc_export
from nativeifc import ifc_psets
from draftviewproviders import view_layer
import ArchBuildingPart
from PySide import QtCore
SCALE = 1000.0 # IfcOpenShell works in meters, FreeCAD works in mm
@@ -396,7 +397,7 @@ def assign_groups(children, ifcfile=None):
def get_children(
obj, ifcfile=None, only_structure=False, assemblies=True, expand=False, iftype=None
obj, ifcfile=None, only_structure=False, assemblies=True, expand=False, ifctype=None
):
"""Returns the direct descendants of an object"""
@@ -417,7 +418,7 @@ def get_children(
result = filter_elements(
children, ifcfile, expand=expand, spaces=True, assemblies=assemblies
)
if iftype:
if ifctype:
result = [r for r in result if r.is_a(ifctype)]
return result
@@ -524,6 +525,7 @@ def add_object(document, otype=None, oname="IfcObject"):
'sectionplane',
'axis',
'schedule'
'buildingpart'
or anything else for a standard IFC object"""
if not document:
@@ -572,6 +574,16 @@ def add_object(document, otype=None, oname="IfcObject"):
proxy = ifc_objects.ifc_object(otype)
vproxy = ifc_viewproviders.ifc_vp_document()
obj = document.addObject("Part::FeaturePython", oname, proxy, vproxy, False)
elif otype == "buildingpart":
obj = Arch.makeBuildingPart()
if obj.ViewObject:
obj.ViewObject.ShowLevel = False
obj.ViewObject.ShowLabel = False
obj.ViewObject.Proxy = ifc_viewproviders.ifc_vp_buildingpart(obj.ViewObject)
for p in obj.PropertiesList:
if obj.getGroupOfProperty(p) in ["BuildingPart","IFC Attributes","Children"]:
obj.removeProperty(p)
obj.Proxy = ifc_objects.ifc_object(otype)
else: # default case, standard IFC object
proxy = ifc_objects.ifc_object(otype)
vproxy = ifc_viewproviders.ifc_vp_object()
@@ -701,6 +713,12 @@ def add_properties(
setattr(obj, attr, [value])
setattr(obj, attr, value)
setattr(obj, attr, items)
elif attr in ["RefLongitude", "RefLatitude"]:
obj.addProperty("App::PropertyFloat", attr, "IFC")
if value is not None:
# convert from list of 4 ints
value = value[0] + value[1]/60. + value[2]/3600. + value[3]/3600.e6
setattr(obj, attr, value)
else:
if attr not in obj.PropertiesList:
obj.addProperty("App::PropertyString", attr, "IFC")
@@ -717,6 +735,10 @@ def add_properties(
obj.setExpression("CustomText", "AxisTag")
if "Length" not in obj.PropertiesList:
obj.addProperty("App::PropertyLength","Length","Axis")
if "Text" not in obj.PropertiesList:
obj.addProperty("App::PropertyStringList", "Text", "Base")
obj.Text = [text.Literal]
obj.Placement = ifc_export.get_placement(ifcentity.ObjectPlacement, ifcfile)
obj.Length = axisdata[1]
elif ifcentity.is_a("IfcAnnotation"):
sectionplane = ifc_export.get_sectionplane(ifcentity)
@@ -929,6 +951,12 @@ def set_attribute(ifcfile, element, attribute, value):
product = api_run(cmd, ifcfile, product=element, ifc_class=value)
# TODO fix attributes
return product
if attribute in ["RefLongitude", "RefLatitude"]:
c = [int(value)]
c.append(int((value - c[0]) * 60))
c.append(int(((value - c[0]) * 60 - c[1]) * 60))
c.append(int((((value - c[0]) * 60 - c[1]) * 60 - c[2]) * 1.e6))
value = c
cmd = "attribute.edit_attributes"
attribs = {attribute: value}
if hasattr(element, attribute):
@@ -1226,6 +1254,9 @@ def aggregate(obj, parent, mode=None):
elif hasattr(child,"Hosts") and obj in child.Hosts:
#op = create_product(child, newobj, ifcfile, ifcclass="IfcOpeningElement")
aggregate(child, newobj)
for child in getattr(obj, "Group", []):
if newobj.IfcClass == "IfcGroup" and child in obj.Group:
aggregate(child, newobj)
delete = not (PARAMS.GetBool("KeepAggregated", False))
if new and delete and base:
obj.Document.removeObject(base.Name)
@@ -1352,10 +1383,10 @@ def create_relationship(old_obj, obj, parent, element, ifcfile, mode=None):
if hasattr(old_par, "Group") and old_obj in old_par.Group:
old_par.Group = [o for o in old_par.Group if o != old_obj]
try:
api_run("spatial.unassign_container", ifcfile, products=[element])
uprel = api_run("spatial.unassign_container", ifcfile, products=[element])
except:
# older version of IfcOpenShell
api_run("spatial.unassign_container", ifcfile, product=element)
uprel = api_run("spatial.unassign_container", ifcfile, product=element)
if element.is_a("IfcOpeningElement"):
uprel = api_run(
"void.add_opening",

View File

@@ -22,6 +22,7 @@
import FreeCADGui
import ArchBuildingPart
class ifc_vp_object:
@@ -70,22 +71,7 @@ class ifc_vp_object:
obj.ViewObject.DiffuseColor = colors
def getIcon(self):
from PySide import QtCore, QtGui # lazy import
rclass = self.Object.IfcClass.replace("StandardCase","")
rclass = self.Object.IfcClass.replace("Type","")
ifcicon = ":/icons/IFC/" + rclass + ".svg"
if QtCore.QFile.exists(ifcicon):
if getattr(self, "ifcclass", "") != rclass:
self.ifcclass = rclass
self.ifcicon = overlay(ifcicon, ":/icons/IFC.svg")
return getattr(self, "ifcicon", overlay(ifcicon, ":/icons/IFC.svg"))
elif self.Object.IfcClass == "IfcGroup":
return QtGui.QIcon.fromTheme("folder", QtGui.QIcon(":/icons/folder.svg"))
elif self.Object.ShapeMode == "Shape":
return ":/icons/IFC_object.svg"
else:
return ":/icons/IFC_mesh.svg"
return get_icon(self)
def claimChildren(self):
if hasattr(self.Object, "Group"):
@@ -632,6 +618,13 @@ class ifc_vp_material:
self.Object.Document.recompute()
class ifc_vp_buildingpart(ifc_vp_object, ArchBuildingPart.ViewProviderBuildingPart):
"""A vp that inherits the Arch BuildingPart vp, but keeps aggregating properties of ifc vp"""
def __init__(self, vobj):
ArchBuildingPart.ViewProviderBuildingPart.__init__(self,vobj)
def overlay(icon1, icon2):
"""Overlays icon2 onto icon1"""
@@ -678,3 +671,27 @@ def get_filepath(project):
project.IfcFilePath = sf
return sf
return None
def get_icon(vp):
"""Returns an icon for a view provider"""
from PySide import QtCore, QtGui # lazy import
if hasattr(vp, "Object"):
if hasattr(vp.Object, "IfcClass"):
rclass = vp.Object.IfcClass.replace("StandardCase","")
rclass = vp.Object.IfcClass.replace("Type","")
ifcicon = ":/icons/IFC/" + rclass + ".svg"
if QtCore.QFile.exists(ifcicon):
if getattr(self, "ifcclass", "") != rclass:
vp.ifcclass = rclass
vp.ifcicon = overlay(ifcicon, ":/icons/IFC.svg")
return getattr(vp, "ifcicon", overlay(ifcicon, ":/icons/IFC.svg"))
elif vp.Object.IfcClass == "IfcGroup":
return QtGui.QIcon.fromTheme("folder", QtGui.QIcon(":/icons/folder.svg"))
elif vp.Object.ShapeMode == "Shape":
return ":/icons/IFC_object.svg"
else:
return ":/icons/IFC_mesh.svg"
return ":/icons/IFC_object.svg"