BIM: Support for property sets in Native IFC (#18067)
* BIM: UI to add properties and psets to IFC objects * BIM: Support native IFC objects in BimProperties * BIM: Support removing IFC properties * BIM: Fixed lint issues
This commit is contained in:
@@ -116,6 +116,8 @@ def setStatusIcons(show=True):
|
||||
if show:
|
||||
if statuswidget:
|
||||
statuswidget.show()
|
||||
if hasattr(statuswidget, "propertybuttons"):
|
||||
statuswidget.propertybuttons.show()
|
||||
else:
|
||||
statuswidget = FreeCADGui.UiLoader().createWidget("Gui::ToolBar")
|
||||
statuswidget.setObjectName("BIMStatusWidget")
|
||||
@@ -221,3 +223,5 @@ def setStatusIcons(show=True):
|
||||
if statuswidget:
|
||||
statuswidget.hide()
|
||||
statuswidget.toggleViewAction().setVisible(False)
|
||||
if hasattr(statuswidget, "propertybuttons"):
|
||||
statuswidget.propertybuttons.hide()
|
||||
|
||||
@@ -82,6 +82,7 @@ SET(Arch_presets
|
||||
Presets/ifc_types_IFC4.json
|
||||
Presets/ifc_contexts_IFC2X3.json
|
||||
Presets/ifc_contexts_IFC4.json
|
||||
Presets/properties_conversion.csv
|
||||
)
|
||||
|
||||
SET(bimcommands_SRCS
|
||||
|
||||
230
src/Mod/BIM/Presets/properties_conversion.csv
Normal file
230
src/Mod/BIM/Presets/properties_conversion.csv
Normal file
@@ -0,0 +1,230 @@
|
||||
FreeCAD,IFC
|
||||
App::PropertyBool,IfcBoolean:IfcLogical
|
||||
App::PropertyBoolList,
|
||||
App::PropertyFloat,IfcReal
|
||||
App::PropertyFloatList,
|
||||
App::PropertyFloatConstraint,
|
||||
App::PropertyPrecision,
|
||||
App::PropertyQuantity,
|
||||
App::PropertyQuantityConstraint,
|
||||
App::PropertyInteger,IfcInteger
|
||||
App::PropertyIntegerConstraint,
|
||||
App::PropertyPercent,
|
||||
App::PropertyEnumeration,
|
||||
App::PropertyIntegerList,
|
||||
App::PropertyIntegerSet,
|
||||
App::PropertyMap,
|
||||
App::PropertyString,IfcLabel:IfcIdentifier:IfcText
|
||||
App::PropertyPersistentObject,
|
||||
App::PropertyUUID,IfcGloballyUniqueId
|
||||
App::PropertyFont,IfcTextFontName
|
||||
App::PropertyStringList,
|
||||
App::PropertyLink,
|
||||
App::PropertyLinkChild,
|
||||
App::PropertyLinkGlobal,
|
||||
App::PropertyLinkHidden,
|
||||
App::PropertyLinkSub,
|
||||
App::PropertyLinkSubChild,
|
||||
App::PropertyLinkSubGlobal,
|
||||
App::PropertyLinkSubHidden,
|
||||
App::PropertyLinkList,
|
||||
App::PropertyLinkListChild,
|
||||
App::PropertyLinkListGlobal,
|
||||
App::PropertyLinkListHidden,
|
||||
App::PropertyLinkSubList,
|
||||
App::PropertyLinkSubListChild,
|
||||
App::PropertyLinkSubListGlobal,
|
||||
App::PropertyLinkSubListHidden,
|
||||
App::PropertyXLink,
|
||||
App::PropertyXLinkSub,
|
||||
App::PropertyXLinkSubHidden,
|
||||
App::PropertyXLinkSubList,
|
||||
App::PropertyXLinkList,
|
||||
App::PropertyMatrix,
|
||||
App::PropertyVector,
|
||||
App::PropertyVectorDistance,
|
||||
App::PropertyPosition,
|
||||
App::PropertyDirection,
|
||||
App::PropertyVectorList,
|
||||
App::PropertyPlacement,
|
||||
App::PropertyPlacementList,
|
||||
App::PropertyPlacementLink,
|
||||
App::PropertyRotation,
|
||||
App::PropertyColor,
|
||||
App::PropertyColorList,
|
||||
App::PropertyMaterial,
|
||||
App::PropertyMaterialList,
|
||||
App::PropertyPath,
|
||||
App::PropertyFile,
|
||||
App::PropertyFileIncluded,
|
||||
App::PropertyPythonObject,
|
||||
App::PropertyExpressionEngine,
|
||||
App::PropertyAcceleration,
|
||||
App::PropertyAmountOfSubstance,
|
||||
App::PropertyAngle,IfcPlaneAngleMeasure
|
||||
App::PropertyArea,IfcAreaMeasure
|
||||
App::PropertyCompressiveStrength,
|
||||
App::PropertyCurrentDensity,
|
||||
App::PropertyDensity,
|
||||
App::PropertyDissipationRate,
|
||||
App::PropertyDistance,IfcLengthMeasure
|
||||
App::PropertyDynamicViscosity,
|
||||
App::PropertyElectricalCapacitance,
|
||||
App::PropertyElectricalConductance,
|
||||
App::PropertyElectricalConductivity,
|
||||
App::PropertyElectricalInductance,
|
||||
App::PropertyElectricalResistance,
|
||||
App::PropertyElectricCharge,
|
||||
App::PropertyElectricCurrent,
|
||||
App::PropertyElectricPotential,
|
||||
App::PropertyFrequency,IfcFrequencyMeasure
|
||||
App::PropertyForce,IfcForceMeasure
|
||||
App::PropertyHeatFlux,IfcHeatFluxDensityMeasure
|
||||
App::PropertyInverseArea,
|
||||
App::PropertyInverseLength,
|
||||
App::PropertyInverseVolume,
|
||||
App::PropertyKinematicViscosity,
|
||||
App::PropertyLength,IfcPositiveLengthMeasure
|
||||
App::PropertyLuminousIntensity,
|
||||
App::PropertyMagneticFieldStrength,
|
||||
App::PropertyMagneticFlux,
|
||||
App::PropertyMagneticFluxDensity,
|
||||
App::PropertyMagnetization,
|
||||
App::PropertyMass,IfcMassMeasure
|
||||
App::PropertyMoment,IfcMomentOfInertiaMeasure
|
||||
App::PropertyPressure,IfcPressureMeasure
|
||||
App::PropertyPower,IfcPowerMeasure
|
||||
App::PropertyShearModulus,IfcShearModulusMeasure
|
||||
App::PropertySpecificEnergy,
|
||||
App::PropertySpecificHeat,
|
||||
App::PropertySpeed,
|
||||
App::PropertyStiffness,
|
||||
App::PropertyStiffnessDensity,
|
||||
App::PropertyStress,
|
||||
App::PropertyTemperature,IfcThermodynamicTemperatureMeasure
|
||||
App::PropertyThermalConductivity,IfcThermalConductivityMeasure
|
||||
App::PropertyThermalExpansionCoefficient,IfcThermalExpansionCoefficientMeasure
|
||||
App::PropertyThermalTransferCoefficient,IfcThermalTransmittanceMeasure
|
||||
App::PropertyTime,IfcDateTime:IfcDate:IfcTime:IfcTimeMeasure:IfcTimeStamp
|
||||
App::PropertyUltimateTensileStrength,
|
||||
App::PropertyVacuumPermittivity,
|
||||
App::PropertyVelocity,
|
||||
App::PropertyVolume,IfcVolumeMeasure
|
||||
App::PropertyVolumeFlowRate,
|
||||
App::PropertyVolumetricThermalExpansionCoefficient,
|
||||
App::PropertyWork,
|
||||
App::PropertyYieldStrength,
|
||||
App::PropertyYoungsModulus,
|
||||
Materials::PropertyMaterial,
|
||||
Part::PropertyPartShape,
|
||||
Part::PropertyGeometryList,
|
||||
Part::PropertyShapeHistory,
|
||||
Part::PropertyFilletEdges,
|
||||
Part::PropertyShapeCache,
|
||||
Part::PropertyTopoShapeList,
|
||||
Sketcher::PropertyConstraintList,
|
||||
,IfcBSplineCurveForm
|
||||
,IfcBSplineSurfaceForm
|
||||
,IfcBooleanOperator
|
||||
,IfcKnotType
|
||||
,IfcNullStyle
|
||||
,IfcPreferredSurfaceCurveRepresentation
|
||||
,IfcSIPrefix
|
||||
,IfcSIUnitName
|
||||
,IfcSurfaceSide
|
||||
,IfcTextPath
|
||||
,IfcTransitionCode
|
||||
,IfcTrimmingPreference
|
||||
,IfcAbsorbedDoseMeasure
|
||||
,IfcAccelerationMeasure
|
||||
,IfcAmountOfSubstanceMeasure
|
||||
,IfcAngularVelocityMeasure
|
||||
,IfcAreaDensityMeasure
|
||||
,IfcBoxAlignment
|
||||
,IfcCardinalPointReference
|
||||
,IfcContextDependentMeasure
|
||||
,IfcCountMeasure
|
||||
,IfcCurvatureMeasure
|
||||
,IfcDayInMonthNumber
|
||||
,IfcDayInWeekNumber
|
||||
,IfcDescriptiveMeasure
|
||||
,IfcDimensionCount
|
||||
,IfcDoseEquivalentMeasure
|
||||
,IfcDuration
|
||||
,IfcDynamicViscosityMeasure
|
||||
,IfcElectricCapacitanceMeasure
|
||||
,IfcElectricChargeMeasure
|
||||
,IfcElectricConductanceMeasure
|
||||
,IfcElectricCurrentMeasure
|
||||
,IfcElectricResistanceMeasure
|
||||
,IfcElectricVoltageMeasure
|
||||
,IfcEnergyMeasure
|
||||
,IfcFontStyle
|
||||
,IfcFontVariant
|
||||
,IfcFontWeight
|
||||
,IfcHeatingValueMeasure
|
||||
,IfcIlluminanceMeasure
|
||||
,IfcInductanceMeasure
|
||||
,IfcIntegerCountRateMeasure
|
||||
,IfcIonConcentrationMeasure
|
||||
,IfcIsothermalMoistureCapacityMeasure
|
||||
,IfcKinematicViscosityMeasure
|
||||
,IfcLanguageId
|
||||
,IfcLinearForceMeasure
|
||||
,IfcLinearMomentMeasure
|
||||
,IfcLinearStiffnessMeasure
|
||||
,IfcLinearVelocityMeasure
|
||||
,IfcLuminousFluxMeasure
|
||||
,IfcLuminousIntensityDistributionMeasure
|
||||
,IfcLuminousIntensityMeasure
|
||||
,IfcMagneticFluxDensityMeasure
|
||||
,IfcMagneticFluxMeasure
|
||||
,IfcMassDensityMeasure
|
||||
,IfcMassFlowRateMeasure
|
||||
,IfcMassPerLengthMeasure
|
||||
,IfcModulusOfElasticityMeasure
|
||||
,IfcModulusOfLinearSubgradeReactionMeasure
|
||||
,IfcModulusOfRotationalSubgradeReactionMeasure
|
||||
,IfcModulusOfSubgradeReactionMeasure
|
||||
,IfcMoistureDiffusivityMeasure
|
||||
,IfcMolecularWeightMeasure
|
||||
,IfcMonetaryMeasure
|
||||
,IfcMonthInYearNumber
|
||||
,IfcNonNegativeLengthMeasure
|
||||
,IfcNormalisedRatioMeasure
|
||||
,IfcNumericMeasure
|
||||
,IfcPHMeasure
|
||||
,IfcParameterValue
|
||||
,IfcPlanarForceMeasure
|
||||
,IfcPositiveInteger
|
||||
,IfcPositivePlaneAngleMeasure
|
||||
,IfcPositiveRatioMeasure
|
||||
,IfcPresentableText
|
||||
,IfcRadioActivityMeasure
|
||||
,IfcRatioMeasure
|
||||
,IfcRotationalFrequencyMeasure
|
||||
,IfcRotationalMassMeasure
|
||||
,IfcRotationalStiffnessMeasure
|
||||
,IfcSectionModulusMeasure
|
||||
,IfcSectionalAreaIntegralMeasure
|
||||
,IfcSolidAngleMeasure
|
||||
,IfcSoundPowerLevelMeasure
|
||||
,IfcSoundPowerMeasure
|
||||
,IfcSoundPressureLevelMeasure
|
||||
,IfcSoundPressureMeasure
|
||||
,IfcSpecificHeatCapacityMeasure
|
||||
,IfcSpecularExponent
|
||||
,IfcSpecularRoughness
|
||||
,IfcTemperatureGradientMeasure
|
||||
,IfcTemperatureRateOfChangeMeasure
|
||||
,IfcTextAlignment
|
||||
,IfcTextDecoration
|
||||
,IfcTextTransformation
|
||||
,IfcThermalAdmittanceMeasure
|
||||
,IfcThermalResistanceMeasure
|
||||
,IfcTorqueMeasure
|
||||
,IfcURIReference
|
||||
,IfcVaporPermeabilityMeasure
|
||||
,IfcVolumetricFlowRateMeasure
|
||||
,IfcWarpingConstantMeasure
|
||||
,IfcWarpingMomentMeasure
|
||||
|
@@ -185,6 +185,8 @@
|
||||
<file>ui/ParametersWindowFixed.svg</file>
|
||||
<file>ui/ParametersWindowSimple.svg</file>
|
||||
<file>ui/ParametersWindowStash.svg</file>
|
||||
<file>ui/dialogAddPSet.ui</file>
|
||||
<file>ui/dialogAddProperty.ui</file>
|
||||
<file>ui/dialogClasses.ui</file>
|
||||
<file>ui/dialogClassification.ui</file>
|
||||
<file>ui/dialogConvertDocument.ui</file>
|
||||
|
||||
94
src/Mod/BIM/Resources/ui/dialogAddPSet.ui
Normal file
94
src/Mod/BIM/Resources/ui/dialogAddPSet.ui
Normal file
@@ -0,0 +1,94 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Dialog</class>
|
||||
<widget class="QDialog" name="Dialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>310</width>
|
||||
<height>122</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Add standard IFC PSet</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="3" column="1">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="field_pset">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>Dialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>Dialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
142
src/Mod/BIM/Resources/ui/dialogAddProperty.ui
Normal file
142
src/Mod/BIM/Resources/ui/dialogAddProperty.ui
Normal file
@@ -0,0 +1,142 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Dialog</class>
|
||||
<widget class="QDialog" name="Dialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>338</width>
|
||||
<height>217</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Add IFC property</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="5" column="1">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="field_type">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>IfcLabel</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>IfcBoolean</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>IfcInteger</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>IfcReal</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>IfcLengthMeasure</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>IfcAreaMeasure</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="field_name"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Type</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>PSet</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="field_pset">
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>Dialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>Dialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -175,6 +175,8 @@ class BIM_IfcProperties:
|
||||
obj.IfcProperties, dict
|
||||
):
|
||||
props = obj.IfcProperties
|
||||
elif hasattr(obj, "IfcClass"):
|
||||
props = self.getNativeIfcProperties(obj)
|
||||
else:
|
||||
props = {}
|
||||
objectslist[obj.Name] = [role, props]
|
||||
@@ -182,6 +184,7 @@ class BIM_IfcProperties:
|
||||
val = val.split(";;")
|
||||
if ";;" in key:
|
||||
# 0.19 format
|
||||
# pset;;pname = ptype;;pvalue
|
||||
key = key.split(";;")
|
||||
val = [key[1]] + val
|
||||
key = key[0]
|
||||
@@ -222,6 +225,8 @@ class BIM_IfcProperties:
|
||||
return obj.IfcType
|
||||
elif hasattr(obj, "IfcRole"):
|
||||
return obj.IfcRole
|
||||
elif hasattr(obj, "IfcClass"):
|
||||
return obj.IfcClass
|
||||
else:
|
||||
return None
|
||||
|
||||
@@ -259,14 +264,7 @@ class BIM_IfcProperties:
|
||||
obj = FreeCAD.ActiveDocument.getObject(name)
|
||||
if obj:
|
||||
it1 = QtGui.QStandardItem(obj.Label)
|
||||
if QtCore.QFileInfo(
|
||||
":/icons/Arch_" + obj.Proxy.Type + "_Tree.svg"
|
||||
).exists():
|
||||
icon = QtGui.QIcon(
|
||||
":/icons/Arch_" + obj.Proxy.Type + "_Tree.svg"
|
||||
)
|
||||
else:
|
||||
icon = QtGui.QIcon(":/icons/Arch_Component.svg")
|
||||
icon = obj.ViewObject.Icon
|
||||
it1.setIcon(icon)
|
||||
it1.setToolTip(obj.Name)
|
||||
it2 = QtGui.QStandardItem(group)
|
||||
@@ -315,12 +313,7 @@ class BIM_IfcProperties:
|
||||
role = self.objectslist[obj.Name][0]
|
||||
if (not self.form.onlyVisible.isChecked()) or obj.ViewObject.isVisible():
|
||||
it1 = QtGui.QStandardItem(obj.Label)
|
||||
if QtCore.QFileInfo(
|
||||
":/icons/Arch_" + obj.Proxy.Type + "_Tree.svg"
|
||||
).exists():
|
||||
icon = QtGui.QIcon(":/icons/Arch_" + obj.Proxy.Type + "_Tree.svg")
|
||||
else:
|
||||
icon = QtGui.QIcon(":/icons/Arch_Component.svg")
|
||||
icon = obj.ViewObject.Icon
|
||||
it1.setIcon(icon)
|
||||
it1.setToolTip(obj.Name)
|
||||
it2 = QtGui.QStandardItem(role)
|
||||
@@ -353,14 +346,7 @@ class BIM_IfcProperties:
|
||||
not self.form.onlyVisible.isChecked()
|
||||
) or obj.ViewObject.isVisible():
|
||||
it1 = QtGui.QStandardItem(obj.Label)
|
||||
if QtCore.QFileInfo(
|
||||
":/icons/Arch_" + obj.Proxy.Type + "_Tree.svg"
|
||||
).exists():
|
||||
icon = QtGui.QIcon(
|
||||
":/icons/Arch_" + obj.Proxy.Type + "_Tree.svg"
|
||||
)
|
||||
else:
|
||||
icon = QtGui.QIcon(":/icons/Arch_Component.svg")
|
||||
icon = obj.ViewObject.Icon
|
||||
it1.setIcon(icon)
|
||||
it1.setToolTip(obj.Name)
|
||||
it2 = QtGui.QStandardItem(role)
|
||||
@@ -398,13 +384,28 @@ class BIM_IfcProperties:
|
||||
)
|
||||
continue
|
||||
props = obj.IfcProperties
|
||||
elif hasattr(obj, "IfcClass"):
|
||||
props = self.getNativeIfcProperties(obj)
|
||||
else:
|
||||
props = {}
|
||||
if values[1] != props:
|
||||
if not changed:
|
||||
FreeCAD.ActiveDocument.openTransaction("Change properties")
|
||||
changed = True
|
||||
if not hasattr(obj, "IfcProperties"):
|
||||
if hasattr(obj,"IfcClass"):
|
||||
print("props:",props)
|
||||
for key,value in values[1].items():
|
||||
if ";;" in key and ";;" in value:
|
||||
pname, pset = key.split(";;")
|
||||
ptype, pvalue = value.split(";;")
|
||||
from nativeifc import ifc_psets # lazy loading
|
||||
fctype = ifc_psets.get_freecad_type(ptype)
|
||||
if not pname in obj.PropertiesList:
|
||||
obj.addProperty(fctype, pname, pset, ptype+":"+pname)
|
||||
ifc_psets.edit_pset(obj, pname, force=True)
|
||||
if pvalue:
|
||||
setattr(obj, pname, pvalue)
|
||||
elif not hasattr(obj, "IfcProperties"):
|
||||
obj.addProperty(
|
||||
"App::PropertyMap",
|
||||
"IfcPRoperties",
|
||||
@@ -413,11 +414,23 @@ class BIM_IfcProperties:
|
||||
"App::Property", "IFC properties of this object"
|
||||
),
|
||||
)
|
||||
obj.IfcProperties = values[1]
|
||||
if hasattr(obj, "IfcProperties"):
|
||||
obj.IfcProperties = values[1]
|
||||
if changed:
|
||||
FreeCAD.ActiveDocument.commitTransaction()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
def getNativeIfcProperties(self, obj):
|
||||
props = {}
|
||||
for p in obj.PropertiesList:
|
||||
pset = obj.getGroupOfProperty(p)
|
||||
ttip = obj.getDocumentationOfProperty(p)
|
||||
if ":" in ttip:
|
||||
ptype, pname = ttip.split(":")
|
||||
if pset not in ["Base", "IFC", "Geometry"]:
|
||||
props[pname+";;"+pset] = ptype+";;"+str(getattr(obj,p))
|
||||
return props
|
||||
|
||||
def getSearchResults(self, obj):
|
||||
from PySide import QtCore, QtGui
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ params = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/NativeIFC")
|
||||
|
||||
|
||||
def add_observer():
|
||||
"""Adds an observer to the running FreeCAD instance"""
|
||||
"""Adds this observer to the running FreeCAD instance"""
|
||||
|
||||
FreeCAD.BIMobserver = ifc_observer()
|
||||
FreeCAD.addDocumentObserver(FreeCAD.BIMobserver)
|
||||
@@ -123,6 +123,11 @@ class ifc_observer:
|
||||
|
||||
ifc_status.on_activate()
|
||||
|
||||
def slotRemoveDynamicProperty(self, obj, prop):
|
||||
|
||||
from nativeifc import ifc_psets
|
||||
ifc_psets.remove_property(obj, prop)
|
||||
|
||||
# implementation methods
|
||||
|
||||
def fit_all(self):
|
||||
|
||||
@@ -23,10 +23,13 @@
|
||||
"""This NativeIFC module deals with properties and property sets"""
|
||||
|
||||
|
||||
import os
|
||||
import re
|
||||
import FreeCAD
|
||||
from nativeifc import ifc_tools
|
||||
|
||||
translate = FreeCAD.Qt.translate
|
||||
|
||||
|
||||
def has_psets(obj):
|
||||
"""Returns True if an object has attached psets"""
|
||||
@@ -148,75 +151,117 @@ def show_psets(obj):
|
||||
setattr(obj, pname, value)
|
||||
|
||||
|
||||
def edit_pset(obj, prop, value=None):
|
||||
"""Edits the corresponding property"""
|
||||
def edit_pset(obj, prop, value=None, force=False):
|
||||
"""Edits the corresponding property. If force is True,
|
||||
the property is created even if it has no value"""
|
||||
|
||||
pset = obj.getGroupOfProperty(prop)
|
||||
ttip = obj.getDocumentationOfProperty(prop)
|
||||
ptype = obj.getDocumentationOfProperty(prop)
|
||||
if value is None:
|
||||
value = getattr(obj, prop)
|
||||
ifcfile = ifc_tools.get_ifcfile(obj)
|
||||
element = ifc_tools.get_ifc_element(obj)
|
||||
pset_exist = get_psets(element)
|
||||
if ttip.startswith("Ifc") and ":" in ttip:
|
||||
target_prop = ttip.split(":", 1)[-1]
|
||||
target_prop = None
|
||||
value_exist = None
|
||||
|
||||
# build prop name and type
|
||||
if ptype.startswith("Ifc"):
|
||||
if ":" in ptype:
|
||||
target_prop = ptype.split(":", 1)[-1]
|
||||
ptype = ptype.split(":", 1)[0]
|
||||
else:
|
||||
# no tooltip set - try to build a name
|
||||
ptype = obj.getTypeIdOfProperty(prop)
|
||||
if ifcprop == "App::PropertyDistance":
|
||||
ptype = "IfcLengthMeasure"
|
||||
elif ifcprop == "App::PropertyLength":
|
||||
ptype = "IfcPositiveLengthMeasure"
|
||||
elif ifcprop == "App::PropertyBool":
|
||||
ptype = "IfcBoolean"
|
||||
elif ifcprop == "App::PropertyInteger":
|
||||
ptype = "IfcInteger"
|
||||
elif ifcprop == "App::PropertyFloat":
|
||||
ptype = "IfcReal"
|
||||
elif ifcprop == "App::PropertyArea":
|
||||
ptype = "IfcAreaMeasure"
|
||||
else:
|
||||
# default
|
||||
ptype = "IfcLabel"
|
||||
if not target_prop:
|
||||
# test if the prop exists under different forms (uncameled, unslashed...)
|
||||
prop = prop.rstrip("_")
|
||||
prop_uncamel = re.sub(r"(\w)([A-Z])", r"\1 \2", prop)
|
||||
prop_unslash = re.sub(r"(\w)([A-Z])", r"\1\/\2", prop)
|
||||
target_prop = None
|
||||
if pset in pset_exist:
|
||||
if not target_prop:
|
||||
if pset in pset_exist:
|
||||
if prop in pset_exist[pset]:
|
||||
target_prop = prop
|
||||
elif prop_uncamel in pset_exist[pset]:
|
||||
target_prop = prop_uncamel
|
||||
elif prop_unslash in pset_exist[pset]:
|
||||
target_prop = prop_unslash
|
||||
if target_prop:
|
||||
value_exist = pset_exist[pset][target_prop].split("(", 1)[1][:-1].strip("'")
|
||||
if value_exist in [".F.", ".U."]:
|
||||
value_exist = False
|
||||
elif value_exist in [".T."]:
|
||||
value_exist = True
|
||||
elif isinstance(value, int):
|
||||
value_exist = int(value_exist.strip("."))
|
||||
elif isinstance(value, float):
|
||||
value_exist = float(value_exist)
|
||||
elif isinstance(value, FreeCAD.Units.Quantity):
|
||||
if value.Unit.Type == "Angle":
|
||||
value_exist = float(value_exist)
|
||||
while value_exist > 360:
|
||||
value_exist = value_exist - 360
|
||||
value_exist = FreeCAD.Units.Quantity(float(value_exist), value.Unit)
|
||||
if value == value_exist:
|
||||
return False
|
||||
else:
|
||||
FreeCAD.Console.PrintLog(
|
||||
"IFC: property changed for "
|
||||
+ obj.Label
|
||||
+ " ("
|
||||
+ str(obj.StepId)
|
||||
+ ") : "
|
||||
+ str(target_prop)
|
||||
+ " : "
|
||||
+ str(value)
|
||||
+ " ("
|
||||
+ str(type(value))
|
||||
+ ") -> "
|
||||
+ str(value_exist)
|
||||
+ " ("
|
||||
+ str(type(value_exist))
|
||||
+ ")\n"
|
||||
)
|
||||
pset = get_pset(pset, element)
|
||||
else:
|
||||
pset = ifc_tools.api_run("pset.add_pset", ifcfile, product=element, name=pset)
|
||||
if not target_prop:
|
||||
target_prop = prop
|
||||
|
||||
# create pset if needed
|
||||
if pset in pset_exist:
|
||||
ifcpset = get_pset(pset, element)
|
||||
if target_prop in pset_exist[pset]:
|
||||
value_exist = pset_exist[pset][target_prop].split("(", 1)[1][:-1].strip("'")
|
||||
else:
|
||||
ifcpset = ifc_tools.api_run("pset.add_pset", ifcfile, product=element, name=pset)
|
||||
|
||||
# value conversions
|
||||
if value_exist in [".F.", ".U."]:
|
||||
value_exist = False
|
||||
elif value_exist in [".T."]:
|
||||
value_exist = True
|
||||
elif isinstance(value, int):
|
||||
if value_exist:
|
||||
value_exist = int(value_exist.strip("."))
|
||||
elif isinstance(value, float):
|
||||
if value_exist:
|
||||
value_exist = float(value_exist)
|
||||
elif isinstance(value, FreeCAD.Units.Quantity):
|
||||
if value_exist:
|
||||
value_exist = float(value_exist)
|
||||
if value.Unit.Type == "Angle":
|
||||
if value_exist:
|
||||
while value_exist > 360:
|
||||
value_exist = value_exist - 360
|
||||
value = value.getValueAs("deg")
|
||||
elif value.Unit.Type == "Length":
|
||||
value = value.getValueAs("mm").Value * ifc_tools.get_scale(ifcfile)
|
||||
else:
|
||||
print("DEBUG: unhandled quantity type:",value, value.Unit.Type)
|
||||
return False
|
||||
if value == value_exist:
|
||||
return False
|
||||
if not force and not value and not value_exist:
|
||||
return False
|
||||
FreeCAD.Console.PrintLog(
|
||||
"IFC: property changed for "
|
||||
+ obj.Label
|
||||
+ " ("
|
||||
+ str(obj.StepId)
|
||||
+ "): "
|
||||
+ str(target_prop)
|
||||
+ ": "
|
||||
+ str(value_exist)
|
||||
+ " ("
|
||||
+ type(value_exist).__name__
|
||||
+ ") -> "
|
||||
+ str(value)
|
||||
+ " ("
|
||||
+ type(value).__name__
|
||||
+ ")\n"
|
||||
)
|
||||
|
||||
# run the change
|
||||
# TODO the property type is automatically determined by ifcopenhell
|
||||
# https://docs.ifcopenshell.org/autoapi/ifcopenshell/api/pset/edit_pset/index.html
|
||||
# and is therefore wrong for Quantity types. Research a way to overcome that
|
||||
ifc_tools.api_run(
|
||||
"pset.edit_pset", ifcfile, pset=pset, properties={target_prop: value}
|
||||
"pset.edit_pset", ifcfile, pset=ifcpset, properties={target_prop: value}
|
||||
)
|
||||
# TODO manage quantities
|
||||
return True
|
||||
@@ -252,3 +297,62 @@ def add_property(ifcfile, pset, name, value=""):
|
||||
To force a certain type, value can also be an IFC element such as IfcLabel"""
|
||||
|
||||
ifc_tools.api_run("pset.edit_pset", ifcfile, pset=pset, properties={name: value})
|
||||
|
||||
|
||||
def get_freecad_type(ptype):
|
||||
"""Returns a FreeCAD property type correspinding to an IFC property type"""
|
||||
|
||||
conv = read_properties_conversion()
|
||||
for key, values in conv.items():
|
||||
if ptype.lower() in [v.lower() for v in values.split(":")]:
|
||||
return key
|
||||
return "App::PropertyString"
|
||||
|
||||
|
||||
def get_ifc_type(fctype):
|
||||
"""Returns an IFC property type correspinding to a FreeCAD property type"""
|
||||
|
||||
conv = read_properties_conversion()
|
||||
for key, values in conv.items():
|
||||
if fctype.lower() == key.lower():
|
||||
return values.split(":")[0]
|
||||
return "IfcLabel"
|
||||
|
||||
|
||||
def read_properties_conversion():
|
||||
"""Reads the properties conversion table"""
|
||||
|
||||
import csv
|
||||
csvfile = os.path.join(
|
||||
FreeCAD.getResourceDir(), "Mod", "BIM", "Presets", "properties_conversion.csv"
|
||||
)
|
||||
result = {}
|
||||
if os.path.exists(csvfile):
|
||||
with open(csvfile, "r") as f:
|
||||
reader = csv.reader(f, delimiter=",")
|
||||
for row in reader:
|
||||
result[row[0]] = row[1]
|
||||
return result
|
||||
|
||||
|
||||
def remove_property(obj, prop):
|
||||
"""Removes a custom property"""
|
||||
|
||||
from nativeifc import ifc_tools
|
||||
ifcfile = ifc_tools.get_ifcfile(obj)
|
||||
if not ifcfile:
|
||||
return
|
||||
element = ifc_tools.get_ifc_element(obj, ifcfile)
|
||||
if not element:
|
||||
return
|
||||
psets = get_psets(element)
|
||||
for psetname, props in psets.items():
|
||||
if prop in props:
|
||||
pset = get_pset(psetname, element)
|
||||
if pset:
|
||||
FreeCAD.Console.PrintMessage(translate("BIM","Removing property")+": "+prop)
|
||||
ifc_tools.api_run("pset.edit_pset", ifcfile, pset=pset, properties={prop: None})
|
||||
if len(props) == 1:
|
||||
# delete the pset too
|
||||
FreeCAD.Console.PrintMessage(translate("BIM","Removing property set")+": "+psetname)
|
||||
ifc_tools.api_run("pset.remove_pset", ifcfile, product=element, pset=pset)
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
"""This contains nativeifc status widgets and functionality"""
|
||||
|
||||
|
||||
import os
|
||||
import csv
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
|
||||
@@ -56,6 +58,169 @@ def set_status_widget(statuswidget):
|
||||
lock_button.setChecked(checked)
|
||||
on_toggle_lock(checked, noconvert=True)
|
||||
lock_button.triggered.connect(on_toggle_lock)
|
||||
set_properties_editor(statuswidget)
|
||||
|
||||
|
||||
def set_properties_editor(statuswidget):
|
||||
"""Adds additional buttons to the properties editor"""
|
||||
|
||||
if hasattr(statuswidget, "propertybuttons"):
|
||||
statuswidget.propertybuttons.show()
|
||||
else:
|
||||
from PySide import QtCore, QtGui # lazy loading
|
||||
|
||||
mw = FreeCADGui.getMainWindow()
|
||||
editor = mw.findChild(QtGui.QTabWidget,"propertyTab")
|
||||
if editor:
|
||||
pTabCornerWidget = QtGui.QWidget()
|
||||
pButton1 = QtGui.QToolButton(pTabCornerWidget)
|
||||
pButton1.setText("")
|
||||
pButton1.setToolTip(translate("BIM","Add IFC property..."))
|
||||
pButton1.setIcon(QtGui.QIcon(":/icons/IFC.svg"))
|
||||
pButton1.clicked.connect(on_add_property)
|
||||
pButton2 = QtGui.QToolButton(pTabCornerWidget)
|
||||
pButton2.setText("")
|
||||
pButton2.setToolTip(translate("BIM","Add standard IFC Property Set..."))
|
||||
pButton2.setIcon(QtGui.QIcon(":/icons/BIM_IfcProperties.svg"))
|
||||
pButton2.clicked.connect(on_add_pset)
|
||||
pHLayout = QtGui.QHBoxLayout(pTabCornerWidget)
|
||||
pHLayout.addWidget(pButton1)
|
||||
pHLayout.addWidget(pButton2)
|
||||
pHLayout.setSpacing(2)
|
||||
pHLayout.setContentsMargins(2, 2, 0, 0)
|
||||
pHLayout.insertStretch(0)
|
||||
editor.setCornerWidget(pTabCornerWidget, QtCore.Qt.BottomRightCorner)
|
||||
statuswidget.propertybuttons = pTabCornerWidget
|
||||
QtCore.QTimer.singleShot(0,pTabCornerWidget.show)
|
||||
|
||||
|
||||
def on_add_property():
|
||||
"""When the 'add property' button is clicked"""
|
||||
|
||||
sel = FreeCADGui.Selection.getSelection()
|
||||
if not sel:
|
||||
return
|
||||
from PySide import QtCore, QtGui # lazy loading
|
||||
from nativeifc import ifc_psets
|
||||
obj = sel[0]
|
||||
psets = list(set([obj.getGroupOfProperty(p) for p in obj.PropertiesList]))
|
||||
psets = [p for p in psets if p]
|
||||
psets = [p for p in psets if p not in ["Base", "IFC", "Geometry"]]
|
||||
mw = FreeCADGui.getMainWindow()
|
||||
editor = mw.findChild(QtGui.QTabWidget,"propertyTab")
|
||||
pset = None
|
||||
if editor:
|
||||
wid = editor.currentWidget()
|
||||
if wid and wid.objectName() == "propertyEditorData":
|
||||
if wid.currentIndex().parent():
|
||||
pset = wid.currentIndex().parent().data()
|
||||
else:
|
||||
pset = wid.currentIndex().data()
|
||||
form = FreeCADGui.PySideUic.loadUi(":/ui/dialogAddProperty.ui")
|
||||
# center the dialog over FreeCAD window
|
||||
form.move(mw.frameGeometry().topLeft() + mw.rect().center() - form.rect().center())
|
||||
form.field_pset.clear()
|
||||
form.field_pset.addItems(psets)
|
||||
if pset and (pset in psets):
|
||||
form.field_pset.setCurrentIndex(psets.index(pset))
|
||||
# TODO check for name duplicates while typing
|
||||
# execute
|
||||
result = form.exec_()
|
||||
if not result:
|
||||
return
|
||||
pname = form.field_name.text()
|
||||
if pname in obj.PropertiesList:
|
||||
print("DEBUG: property already exists",pname)
|
||||
return
|
||||
pset = form.field_pset.currentText()
|
||||
if not pset:
|
||||
# TODO disable the OK button if empty
|
||||
t = translate("BIM","No Property set provided")
|
||||
FreeCAD.Console.PrintError(t+"\n")
|
||||
ptype = form.field_type.currentIndex()
|
||||
ptype = ["IfcLabel", "IfcBoolean",
|
||||
"IfcInteger", "IfcReal",
|
||||
"IfcLengthMeasure", "IfcAreaMeasure"][ptype]
|
||||
fctype = ifc_psets.get_freecad_type(ptype)
|
||||
FreeCAD.ActiveDocument.openTransaction(translate("BIM","add property"))
|
||||
for obj in sel:
|
||||
obj.addProperty(fctype, pname, pset, ptype+":"+pname)
|
||||
ifc_psets.edit_pset(obj, pname, force=True)
|
||||
FreeCAD.ActiveDocument.commitTransaction()
|
||||
|
||||
|
||||
def on_add_pset():
|
||||
"""When the 'add pset' button is pressed"""
|
||||
|
||||
def read_csv(csvfile):
|
||||
result = {}
|
||||
if os.path.exists(csvfile):
|
||||
with open(csvfile, "r") as f:
|
||||
reader = csv.reader(f, delimiter=";")
|
||||
for row in reader:
|
||||
result[row[0]] = row[1:]
|
||||
return result
|
||||
|
||||
def get_fcprop(ifcprop):
|
||||
if ifcprop == "IfcLengthMeasure":
|
||||
return "App::PropertyDistance"
|
||||
elif ifcprop == "IfcPositiveLengthMeasure":
|
||||
return "App::PropertyLength"
|
||||
elif ifcprop in ["IfcBoolean", "IfcLogical"]:
|
||||
return "App::PropertyBool"
|
||||
elif ifcprop == "IfcInteger":
|
||||
return "App::PropertyInteger"
|
||||
elif ifcprop == "IfcReal":
|
||||
return "App::PropertyFloat"
|
||||
elif ifcprop == "IfcAreaMeasure":
|
||||
return "App::PropertyArea"
|
||||
return "App::PropertyString"
|
||||
|
||||
sel = FreeCADGui.Selection.getSelection()
|
||||
if not sel:
|
||||
return
|
||||
from PySide import QtCore, QtGui # lazy loading
|
||||
from nativeifc import ifc_psets
|
||||
obj = sel[0]
|
||||
mw = FreeCADGui.getMainWindow()
|
||||
# read standard psets
|
||||
psetpath = os.path.join(
|
||||
FreeCAD.getResourceDir(), "Mod", "BIM", "Presets", "pset_definitions.csv"
|
||||
)
|
||||
custompath = os.path.join(FreeCAD.getUserAppDataDir(), "BIM", "CustomPsets.csv")
|
||||
psetdefs = read_csv(psetpath)
|
||||
psetdefs.update(read_csv(custompath))
|
||||
psetkeys = list(psetdefs.keys())
|
||||
psetkeys.sort()
|
||||
form = FreeCADGui.PySideUic.loadUi(":/ui/dialogAddPSet.ui")
|
||||
# center the dialog over FreeCAD window
|
||||
form.move(mw.frameGeometry().topLeft() + mw.rect().center() - form.rect().center())
|
||||
form.field_pset.clear()
|
||||
form.field_pset.addItems(psetkeys)
|
||||
# execute
|
||||
result = form.exec_()
|
||||
if not result:
|
||||
return
|
||||
pset = form.field_pset.currentText()
|
||||
existing_psets = list(set([obj.getGroupOfProperty(p) for p in obj.PropertiesList]))
|
||||
if pset in existing_psets:
|
||||
t = translate("BIM","Property set already exists")
|
||||
FreeCAD.Console.PrintError(t+": "+pset+"\n")
|
||||
return
|
||||
props = [psetdefs[pset][i:i+2] for i in range(0, len(psetdefs[pset]), 2)]
|
||||
props = [[p[0], p[1]] for p in props]
|
||||
FreeCAD.ActiveDocument.openTransaction(translate("BIM","add property set"))
|
||||
for obj in sel:
|
||||
existing_psets = list(set([obj.getGroupOfProperty(p) for p in obj.PropertiesList]))
|
||||
if pset not in existing_psets:
|
||||
ifc_psets.add_pset(obj, pset)
|
||||
for prop in props:
|
||||
if prop[0] in obj.PropertiesList:
|
||||
t = translate("BIM","Property already exists")
|
||||
FreeCAD.Console.PrintWarning(t+": "+obj.Label+","+prop[0]+"\n")
|
||||
else:
|
||||
obj.addProperty(get_fcprop(prop[1]),prop[0],pset,prop[1]+":"+prop[0])
|
||||
FreeCAD.ActiveDocument.commitTransaction()
|
||||
|
||||
|
||||
def on_toggle_lock(checked=None, noconvert=False, setchecked=False):
|
||||
|
||||
@@ -745,6 +745,21 @@ def set_attribute(ifcfile, element, attribute, value):
|
||||
|
||||
# This function can become pure IFC
|
||||
|
||||
def differs(val1, val2):
|
||||
if val1 == val2:
|
||||
return False
|
||||
if not val1 and not val2:
|
||||
return False
|
||||
if val1 is None and "NOTDEFINED" in str(val2).upper():
|
||||
return False
|
||||
if val1 is None and "UNDEFINED" in str(val2).upper():
|
||||
return False
|
||||
if val2 is None and "NOTDEFINED" in str(val1).upper():
|
||||
return False
|
||||
if val2 is None and "UNDEFINED" in str(val1).upper():
|
||||
return False
|
||||
return True
|
||||
|
||||
if not ifcfile or not element:
|
||||
return False
|
||||
if isinstance(value, FreeCAD.Units.Quantity):
|
||||
@@ -774,7 +789,7 @@ def set_attribute(ifcfile, element, attribute, value):
|
||||
):
|
||||
# do not consider default FreeCAD names given to unnamed alements
|
||||
return False
|
||||
if getattr(element, attribute) != value:
|
||||
if differs(getattr(element, attribute, None),value):
|
||||
FreeCAD.Console.PrintLog(
|
||||
"Changing IFC attribute value of "
|
||||
+ str(attribute)
|
||||
@@ -802,22 +817,25 @@ def set_colors(obj, colors):
|
||||
else:
|
||||
colors = [abs(c) for c in colors]
|
||||
if hasattr(vobj, "ShapeColor"):
|
||||
if isinstance(colors[0], (tuple, list)):
|
||||
vobj.ShapeColor = colors[0][:3]
|
||||
# do not set transparency when the object has more than one color
|
||||
#if len(colors[0]) > 3:
|
||||
# vobj.Transparency = int(colors[0][3] * 100)
|
||||
else:
|
||||
vobj.ShapeColor = colors[:3]
|
||||
if len(colors) > 3:
|
||||
vobj.Transparency = int(colors[3] * 100)
|
||||
if hasattr(vobj, "DiffuseColor"):
|
||||
# strip out transparency value because it currently gives ugly
|
||||
# results in FreeCAD when combining transparent and non-transparent objects
|
||||
if all([len(c) > 3 and c[3] != 0 for c in colors]):
|
||||
vobj.DiffuseColor = colors
|
||||
else:
|
||||
vobj.DiffuseColor = [c[:3] for c in colors]
|
||||
# 1.0 materials
|
||||
if not isinstance(colors[0], (tuple, list)):
|
||||
colors = [colors]
|
||||
# set the first color to opaque otherwise it spoils object transparency
|
||||
if len(colors) > 1:
|
||||
#colors[0] = colors[0][:3] + (0.0,)
|
||||
# TEMP HACK: if multiple colors, set everything to opaque because it looks wrong
|
||||
colors = [color[:3] + (0.0,) for color in colors]
|
||||
sapp = []
|
||||
for color in colors:
|
||||
sapp_mat = FreeCAD.Material()
|
||||
if len(color) < 4:
|
||||
sapp_mat.DiffuseColor = color + (1.0,)
|
||||
else:
|
||||
sapp_mat.DiffuseColor = color[:3] + (1.0 - color[3],)
|
||||
sapp_mat.Transparency = color[3] if len(color) > 3 else 0.0
|
||||
sapp.append(sapp_mat)
|
||||
#print(vobj.Object.Label,[[m.DiffuseColor,m.Transparency] for m in sapp])
|
||||
vobj.ShapeAppearance = sapp
|
||||
|
||||
|
||||
def get_body_context_ids(ifcfile):
|
||||
|
||||
Reference in New Issue
Block a user