diff --git a/Install/Program Files to Install/Autodesk.SteelConnections.ASIFC.dll b/Install/Program Files to Install/Autodesk.SteelConnections.ASIFC.dll
index a868c86f..9caa3719 100644
Binary files a/Install/Program Files to Install/Autodesk.SteelConnections.ASIFC.dll and b/Install/Program Files to Install/Autodesk.SteelConnections.ASIFC.dll differ
diff --git a/Install/Program Files to Install/bundle/Contents/Resources/ADSKIFCExporterHelp.htm b/Install/Program Files to Install/bundle/Contents/Resources/ADSKIFCExporterHelp.htm
index f66ee86a..3599a269 100644
--- a/Install/Program Files to Install/bundle/Contents/Resources/ADSKIFCExporterHelp.htm
+++ b/Install/Program Files to Install/bundle/Contents/Resources/ADSKIFCExporterHelp.htm
@@ -236,6 +236,33 @@
Support Information
or if you have an inquiry specific to this add-in, send us an e-mail to: Revit.apps@autodesk.com
Version History
+
25.4.0.27
+
+ General:
+
+
This is the major release of IFC Exporter 25.4 for Revit 2025.
+
It contains a various improvements and bug fixes for the previous 25.2 version.
+
+
+
+
+ Improvements:
+
+
Added option that allows to export ceiling grids.
+
Implemented the ability to add type properties to instance properties for user-defined property sets.
+
+
+
+
+ Bug Fixes:
+
+
Restored the functionality of the IFC Export As parameter when using the IFC Exporter version lower than Revit.
+
+
+
+
+
+
25.2.0.5
General:
diff --git a/Install/Program Files to Install/bundle/PackageContents.xml b/Install/Program Files to Install/bundle/PackageContents.xml
index 64878809..2fe4d31c 100644
--- a/Install/Program Files to Install/bundle/PackageContents.xml
+++ b/Install/Program Files to Install/bundle/PackageContents.xml
@@ -1,10 +1,10 @@
-
+
-
-
+
+
\ No newline at end of file
diff --git a/Install/RevitIFCSetupWix/Product.wxs b/Install/RevitIFCSetupWix/Product.wxs
index ead8a261..dfa292c6 100644
--- a/Install/RevitIFCSetupWix/Product.wxs
+++ b/Install/RevitIFCSetupWix/Product.wxs
@@ -2,7 +2,7 @@
-
+
diff --git a/Install/RevitIFCSetupWix/RevitIFCSetupWix.wixproj b/Install/RevitIFCSetupWix/RevitIFCSetupWix.wixproj
index f7a1c7ce..56460b22 100644
--- a/Install/RevitIFCSetupWix/RevitIFCSetupWix.wixproj
+++ b/Install/RevitIFCSetupWix/RevitIFCSetupWix.wixproj
@@ -6,7 +6,7 @@
3.87dfbd495-c588-4c7b-b8f6-5b793adb06f22.0
- IFC for Revit 2025.2.0.5
+ IFC for Revit 2025.4.0.27Package$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets
diff --git a/Install/RevitIFCSetupWix/buildInstaller.bat b/Install/RevitIFCSetupWix/buildInstaller.bat
index ac68ba99..d7d55679 100644
--- a/Install/RevitIFCSetupWix/buildInstaller.bat
+++ b/Install/RevitIFCSetupWix/buildInstaller.bat
@@ -11,9 +11,9 @@ rem It is necessary to add the Wix bin directory to the system path temporarily
SET PATH=%PATH%;%WixRoot%
candle.exe -dProjectDir=%2 -ext WixUtilExtension %2Product.wxs
-light.exe -ext WixUtilExtension -out RevitIFC2025.2.0.msi product.wixobj -ext WixUIExtension
+light.exe -ext WixUtilExtension -out RevitIFC2025.4.0.msi product.wixobj -ext WixUIExtension
-copy RevitIFC2025.2.0.msi %1..\Releasex64
-del RevitIFC2025.2.0.msi
+copy RevitIFC2025.4.0.msi %1..\Releasex64
+del RevitIFC2025.4.0.msi
-echo %1..\Releasex64\RevitIFC2025.2.0.msi
+echo %1..\Releasex64\RevitIFC2025.4.0.msi
diff --git a/Source/IFCExporterUIOverride/IFCExportConfiguration.cs b/Source/IFCExporterUIOverride/IFCExportConfiguration.cs
index e5effa31..a04ec00f 100644
--- a/Source/IFCExporterUIOverride/IFCExportConfiguration.cs
+++ b/Source/IFCExporterUIOverride/IFCExportConfiguration.cs
@@ -209,6 +209,11 @@ public Enum FacilityPredefinedType
///
public bool ExportBaseQuantities { get; set; } = false;
+ ///
+ /// Whether or not to include ceilings grids for ceilings in the export data.
+ ///
+ public bool ExportCeilingGrids { get; set; } = false;
+
///
/// True to include the material property sets.
/// False to exclude them.
@@ -237,6 +242,11 @@ public Enum FacilityPredefinedType
///
public string ExportUserDefinedPsetsFileName { get; set; } = "";
+ ///
+ /// Whether or not to include type property to the user defined property sets.
+ ///
+ public bool UseTypePropertiesInInstacePSets { get; set; } = false;
+
///
/// True if the User decides to use the Parameter Mapping Table
/// False if the user decides to ignore it
@@ -338,6 +348,12 @@ public Enum FacilityPredefinedType
/// Use Author field in Project Information to set IfcOwnerHistory LastModified attribute
///
public bool OwnerHistoryLastModified { get; set; } = false;
+
+ ///
+ /// Use this field in Project Information to set how will be bars in uniform sets exported in IFC.
+ ///
+ public bool ExportBarsInUniformSetsAsSeparateIFCEntities { get; set; } = false;
+
///
/// Value indicating whether the IFC Entity Name will use visible Revit Name
///
@@ -478,6 +494,7 @@ public static IFCExportConfiguration CreateBuiltInConfiguration(IFCVersion ifcVe
bool materialPsets,
bool schedulesAsPSets,
bool userDefinedPSets,
+ bool useTypePropertiesInInstacePSets,
bool userDefinedParameterMapping,
bool PlanElems2D,
bool exportBoundingBox,
@@ -487,7 +504,8 @@ public static IFCExportConfiguration CreateBuiltInConfiguration(IFCVersion ifcVe
KnownERNames exchangeRequirement = KnownERNames.NotDefined,
string customName = null,
KnownFacilityTypes facilityType = KnownFacilityTypes.NotDefined,
- Enum facilityPredefinedType = null)
+ Enum facilityPredefinedType = null,
+ bool exportCeilingGrids = false)
{
IFCExportConfiguration configuration = new IFCExportConfiguration();
@@ -512,6 +530,7 @@ public static IFCExportConfiguration CreateBuiltInConfiguration(IFCVersion ifcVe
// Items from Additional Content Tab
configuration.Export2DElements = PlanElems2D;
configuration.ExportLinkedFiles = exportLinkedFiles;
+ configuration.ExportCeilingGrids = exportCeilingGrids;
// Items from Property Sets Tab
configuration.ExportInternalRevitPropertySets = internalSets;
@@ -519,6 +538,7 @@ public static IFCExportConfiguration CreateBuiltInConfiguration(IFCVersion ifcVe
configuration.ExportMaterialPsets = materialPsets;
configuration.ExportSchedulesAsPsets = schedulesAsPSets;
configuration.ExportUserDefinedPsets = userDefinedPSets;
+ configuration.UseTypePropertiesInInstacePSets = useTypePropertiesInInstacePSets;
configuration.ExportUserDefinedPsetsFileName = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\" + configuration.Name + @".txt";
configuration.ExportUserDefinedParameterMapping = userDefinedParameterMapping;
diff --git a/Source/IFCExporterUIOverride/IFCExportConfigurationsMap.cs b/Source/IFCExporterUIOverride/IFCExportConfigurationsMap.cs
index e7bde736..3b9086d7 100644
--- a/Source/IFCExporterUIOverride/IFCExportConfigurationsMap.cs
+++ b/Source/IFCExporterUIOverride/IFCExportConfigurationsMap.cs
@@ -76,21 +76,21 @@ public void AddBuiltInConfigurations()
// These are the built-in configurations. Provide a more extensible means of storage.
// Order of construction: name, version, space boundaries, QTO, split walls, internal sets, 2d elems, boundingBox
- AddOrReplace(IFCExportConfiguration.CreateBuiltInConfiguration(IFCVersion.IFC2x3CV2, 0, false, false, false, false, false, false, false, false, false, linkedFileExportAs, includeSteelElements: true));
- AddOrReplace(IFCExportConfiguration.CreateBuiltInConfiguration(IFCVersion.IFC2x3, 1, false, false, true, false, false, false, false, true, false, linkedFileExportAs, includeSteelElements: true));
- AddOrReplace(IFCExportConfiguration.CreateBuiltInConfiguration(IFCVersion.IFCCOBIE, 2, true, true, true, false, false, false, false, true, true, linkedFileExportAs, includeSteelElements: true));
- AddOrReplace(IFCExportConfiguration.CreateBuiltInConfiguration(IFCVersion.IFC2x3BFM, 1, true, true, false, false, false, false, false, true, false, linkedFileExportAs, includeSteelElements: true));
- AddOrReplace(IFCExportConfiguration.CreateBuiltInConfiguration(IFCVersion.IFC2x2, 1, false, false, true, false, false, false, false, false, false, linkedFileExportAs));
- AddOrReplace(IFCExportConfiguration.CreateBuiltInConfiguration(IFCVersion.IFC2x3FM, 1, true, false, false, false, true, true, false, true, true, linkedFileExportAs, includeSteelElements: true));
- AddOrReplace(IFCExportConfiguration.CreateBuiltInConfiguration(IFCVersion.IFC4RV, 0, true, false, false, false, false, false, false, false, false, linkedFileExportAs, includeSteelElements: true,
+ AddOrReplace(IFCExportConfiguration.CreateBuiltInConfiguration(IFCVersion.IFC2x3CV2, 0, false, false, false, false, false, false, false, false, false, false, linkedFileExportAs, includeSteelElements: true));
+ AddOrReplace(IFCExportConfiguration.CreateBuiltInConfiguration(IFCVersion.IFC2x3, 1, false, false, true, false, false, false, false, false, true, false, linkedFileExportAs, includeSteelElements: true));
+ AddOrReplace(IFCExportConfiguration.CreateBuiltInConfiguration(IFCVersion.IFCCOBIE, 2, true, true, true, false, false, false, false, false, true, true, linkedFileExportAs, includeSteelElements: true));
+ AddOrReplace(IFCExportConfiguration.CreateBuiltInConfiguration(IFCVersion.IFC2x3BFM, 1, true, true, false, false, false, false, false, false, true, false, linkedFileExportAs, includeSteelElements: true));
+ AddOrReplace(IFCExportConfiguration.CreateBuiltInConfiguration(IFCVersion.IFC2x2, 1, false, false, true, false, false, false, false, false, false, false, linkedFileExportAs));
+ AddOrReplace(IFCExportConfiguration.CreateBuiltInConfiguration(IFCVersion.IFC2x3FM, 1, true, false, false, false, true, true, false, false, true, true, linkedFileExportAs, includeSteelElements: true));
+ AddOrReplace(IFCExportConfiguration.CreateBuiltInConfiguration(IFCVersion.IFC4RV, 0, true, false, false, false, false, false, false, false, false, false, linkedFileExportAs, includeSteelElements: true,
exchangeRequirement:KnownERNames.Architecture));
- AddOrReplace(IFCExportConfiguration.CreateBuiltInConfiguration(IFCVersion.IFC4RV, 0, true, false, false, false, false, false, false, false, false, linkedFileExportAs, includeSteelElements: true,
+ AddOrReplace(IFCExportConfiguration.CreateBuiltInConfiguration(IFCVersion.IFC4RV, 0, true, false, false, false, false, false, false, false, false, false, linkedFileExportAs, includeSteelElements: true,
exchangeRequirement:KnownERNames.Structural));
- AddOrReplace(IFCExportConfiguration.CreateBuiltInConfiguration(IFCVersion.IFC4RV, 0, true, false, false, false, false, false, false, false, false, linkedFileExportAs, includeSteelElements: true,
+ AddOrReplace(IFCExportConfiguration.CreateBuiltInConfiguration(IFCVersion.IFC4RV, 0, true, false, false, false, false, false, false, false, false, false, linkedFileExportAs, includeSteelElements: true,
exchangeRequirement:KnownERNames.BuildingService));
- AddOrReplace(IFCExportConfiguration.CreateBuiltInConfiguration(IFCVersion.IFC4DTV, 0, true, false, false, false, false, false, false, false, false, linkedFileExportAs, includeSteelElements: true));
- AddOrReplace(IFCExportConfiguration.CreateBuiltInConfiguration(IFCVersion.IFC4x3, 0, true, false, false, false, false, false, false, false, false, linkedFileExportAs, includeSteelElements: true));
- AddOrReplace(IFCExportConfiguration.CreateBuiltInConfiguration(IFCVersion.IFCSG, 1, true, true, false, false, false, true, false, true, false, linkedFileExportAs, includeSteelElements: true));
+ AddOrReplace(IFCExportConfiguration.CreateBuiltInConfiguration(IFCVersion.IFC4DTV, 0, true, false, false, false, false, false, false, false, false, false, linkedFileExportAs, includeSteelElements: true));
+ AddOrReplace(IFCExportConfiguration.CreateBuiltInConfiguration(IFCVersion.IFC4x3, 0, true, false, false, false, false, false, false, false, false, false, linkedFileExportAs, includeSteelElements: true));
+ AddOrReplace(IFCExportConfiguration.CreateBuiltInConfiguration(IFCVersion.IFCSG, 1, true, true, false, false, false, true, false, false, true, false, linkedFileExportAs, includeSteelElements: true));
}
private LinkedFileExportAs ParseLinkedFilesAs(string val,
@@ -140,6 +140,7 @@ public void AddSavedConfigurations()
configuration.ExportBaseQuantities = configEntity.Get(s_setupQTO);
configuration.SplitWallsAndColumns = configEntity.Get(s_splitWallsAndColumns);
configuration.Export2DElements = configEntity.Get(s_setupExport2D);
+ configuration.ExportCeilingGrids = configEntity.Get(s_setupExportCeilingGrids);
configuration.ExportInternalRevitPropertySets = configEntity.Get(s_setupExportRevitProps);
configuration.CategoryMapping = configEntity.Get(s_categoryMapping);
Field fieldIFCCommonPropertySets = m_OldSchema.GetField(s_setupExportIFCCommonProperty);
@@ -168,6 +169,9 @@ public void AddSavedConfigurations()
Field fieldExportUserDefinedPsetsFileName = m_OldSchema.GetField(s_setupExportUserDefinedPsetsFileName);
if (fieldExportUserDefinedPsetsFileName != null)
configuration.ExportUserDefinedPsetsFileName = configEntity.Get(s_setupExportUserDefinedPsetsFileName);
+ Field fieldUseTypePropertiesInInstacePSets = m_OldSchema.GetField(s_setupUseTypePropertiesInInstacePSets);
+ if (fieldExportUserDefinedPsets != null)
+ configuration.UseTypePropertiesInInstacePSets = configEntity.Get(s_setupUseTypePropertiesInInstacePSets);
Field fieldExportUserDefinedParameterMapingTable = m_OldSchema.GetField(s_setupExportUserDefinedParameterMapping);
if (fieldExportUserDefinedParameterMapingTable != null)
@@ -214,7 +218,9 @@ public void AddSavedConfigurations()
Field fieldOwnerHistoryLastModified = m_OldSchema.GetField(s_ownerHistoryLastModified);
if (fieldOwnerHistoryLastModified != null)
configuration.OwnerHistoryLastModified = configEntity.Get(s_ownerHistoryLastModified);
-
+ Field fieldExportBarsInUniformRebarSetsAsSeparateIFCEntitiesd = m_OldSchema.GetField(s_exportBarsInUniformRebarSetsAsSeparateIFCEntities);
+ if (fieldExportBarsInUniformRebarSetsAsSeparateIFCEntitiesd != null)
+ configuration.ExportBarsInUniformSetsAsSeparateIFCEntities = configEntity.Get(s_exportBarsInUniformRebarSetsAsSeparateIFCEntities);
AddOrReplace(configuration);
}
}
@@ -256,6 +262,8 @@ public void AddSavedConfigurations()
configuration.SplitWallsAndColumns = bool.Parse(configMap[s_splitWallsAndColumns]);
if (configMap.ContainsKey(s_setupExport2D))
configuration.Export2DElements = bool.Parse(configMap[s_setupExport2D]);
+ if (configMap.ContainsKey(s_setupExportCeilingGrids))
+ configuration.ExportCeilingGrids = bool.Parse(configMap[s_setupExportCeilingGrids]);
if (configMap.ContainsKey(s_setupExportRevitProps))
configuration.ExportInternalRevitPropertySets = bool.Parse(configMap[s_setupExportRevitProps]);
if (configMap.ContainsKey(s_setupExportIFCCommonProperty))
@@ -306,6 +314,8 @@ public void AddSavedConfigurations()
configuration.ExportHostAsSingleEntity = bool.Parse(configMap[s_exportHostAsSingleEntity]);
if (configMap.ContainsKey(s_ownerHistoryLastModified))
configuration.OwnerHistoryLastModified = bool.Parse(configMap[s_ownerHistoryLastModified]);
+ if (configMap.ContainsKey(s_exportBarsInUniformRebarSetsAsSeparateIFCEntities))
+ configuration.ExportBarsInUniformSetsAsSeparateIFCEntities = bool.Parse(configMap[s_exportBarsInUniformRebarSetsAsSeparateIFCEntities]);
if (configMap.ContainsKey(s_setupTessellationLevelOfDetail))
configuration.TessellationLevelOfDetail = double.Parse(configMap[s_setupTessellationLevelOfDetail]);
if (configMap.ContainsKey(s_categoryMapping))
@@ -390,6 +400,7 @@ public void AddSavedConfigurations()
private const string s_splitWallsAndColumns = "SplitWallsAndColumns";
private const string s_setupCurrentView = "VisibleElementsInCurrentView";
private const string s_setupExport2D = "Export2DElements";
+ private const string s_setupExportCeilingGrids = "ExportCeilingGrids";
private const string s_setupExportRevitProps = "ExportInternalRevitPropertySets";
private const string s_setupExportIFCCommonProperty = "ExportIFCCommonPropertySets";
private const string s_setupUse2DForRoomVolume = "Use2DBoundariesForRoomVolume";
@@ -405,6 +416,7 @@ public void AddSavedConfigurations()
private const string s_setupExportUserDefinedPsetsFileName = "ExportUserDefinedPsetsFileName";
private const string s_setupExportUserDefinedParameterMapping = "ExportUserDefinedParameterMapping";
private const string s_setupExportUserDefinedParameterMappingFileName = "ExportUserDefinedParameterMappingFileName";
+ private const string s_setupUseTypePropertiesInInstacePSets = "UseTypePropertiesInInstacePSets";
private const string s_setupExportLinkedFiles = "ExportLinkedFiles";
private const string s_setupIncludeSiteElevation = "IncludeSiteElevation";
private const string s_setupTessellationLevelOfDetail = "TessellationLevelOfDetail";
@@ -412,16 +424,14 @@ public void AddSavedConfigurations()
private const string s_setupStoreIFCGUID = "StoreIFCGUID";
private const string s_setupActivePhase = "ActivePhase";
private const string s_setupExportRoomsInView = "ExportRoomsInView";
- private const string s_excludeFilter = "ExcludeFilter";
private const string s_setupSitePlacement = "SitePlacement";
private const string s_useTypeNameOnlyForIfcType = "UseTypeNameOnlyForIfcType";
private const string s_useVisibleRevitNameAsEntityName = "UseVisibleRevitNameAsEntityName";
private const string s_exportHostAsSingleEntity = "ExportHostAsSingleEntity";
private const string s_ownerHistoryLastModified = "OwnerHistoryLastModified";
+ private const string s_exportBarsInUniformRebarSetsAsSeparateIFCEntities = "ExportBarsInUniformRebarSetsAsSeparateIFCEntities";
private const string s_categoryMapping = "CategoryMapping";
// Used for COBie 2.4
- private const string s_cobieCompanyInfo = "COBieCompanyInfo";
- private const string s_cobieProjectInfo = "COBieProjectInfo";
private const string s_includeSteelElements = "IncludeSteelElements";
// Geo Reference info
private const string s_selectedSite = "SelectedSite";
diff --git a/Source/IFCExporterUIOverride/IFCExporterUI.csproj b/Source/IFCExporterUIOverride/IFCExporterUI.csproj
index 72a4e8e5..111d8bba 100644
--- a/Source/IFCExporterUIOverride/IFCExporterUI.csproj
+++ b/Source/IFCExporterUIOverride/IFCExporterUI.csproj
@@ -9,15 +9,6 @@
truetrue
-
- 7.3
-
-
- 7.3
-
-
- 7.3
-
diff --git a/Source/IFCExporterUIOverride/IFCExporterUIOverride.csproj b/Source/IFCExporterUIOverride/IFCExporterUIOverride.csproj
index a442af7f..d81c4238 100644
--- a/Source/IFCExporterUIOverride/IFCExporterUIOverride.csproj
+++ b/Source/IFCExporterUIOverride/IFCExporterUIOverride.csproj
@@ -14,15 +14,12 @@
IFC_OPENSOURCE
- 7.3IFC_OPENSOURCE
- 7.3IFC_OPENSOURCE
- 7.3
diff --git a/Source/IFCExporterUIOverride/IFCExporterUIWindow.xaml b/Source/IFCExporterUIOverride/IFCExporterUIWindow.xaml
index 00abdcd4..867d4d78 100644
--- a/Source/IFCExporterUIOverride/IFCExporterUIWindow.xaml
+++ b/Source/IFCExporterUIOverride/IFCExporterUIWindow.xaml
@@ -43,10 +43,11 @@
-
-
+
+
+
@@ -64,11 +65,12 @@
-
-
-
-
-
+
+
+
+
+
+
@@ -93,6 +95,7 @@
+
diff --git a/Source/IFCExporterUIOverride/IFCExporterUIWindow.xaml.cs b/Source/IFCExporterUIOverride/IFCExporterUIWindow.xaml.cs
index a50240fe..4f584dc1 100644
--- a/Source/IFCExporterUIOverride/IFCExporterUIWindow.xaml.cs
+++ b/Source/IFCExporterUIOverride/IFCExporterUIWindow.xaml.cs
@@ -407,6 +407,7 @@ private void UpdateActiveConfigurationOptions(IFCExportConfiguration configurati
checkboxExportBaseQuantities.IsChecked = configuration.ExportBaseQuantities;
checkboxSplitWalls.IsChecked = configuration.SplitWallsAndColumns;
checkbox2dElements.IsChecked = configuration.Export2DElements;
+ checkboxExportCeilingGrids.IsChecked = configuration.ExportCeilingGrids;
checkboxInternalPropertySets.IsChecked = configuration.ExportInternalRevitPropertySets;
checkboxIFCCommonPropertySets.IsChecked = configuration.ExportIFCCommonPropertySets;
checkboxVisibleElementsCurrView.IsChecked = configuration.VisibleElementsOfCurrentView;
@@ -421,6 +422,7 @@ private void UpdateActiveConfigurationOptions(IFCExportConfiguration configurati
checkBoxExportSpecificSchedules.IsChecked = configuration.ExportSpecificSchedules;
checkboxExportUserDefinedPset.IsChecked = configuration.ExportUserDefinedPsets;
userDefinedPropertySetFileName.Text = configuration.ExportUserDefinedPsetsFileName;
+ checkboxUseTypePropertiesInInstacePSets.IsChecked = configuration.UseTypePropertiesInInstacePSets;
checkboxIncludeIfcSiteElevation.IsChecked = configuration.IncludeSiteElevation;
checkboxStoreIFCGUID.IsChecked = configuration.StoreIFCGUID;
checkBoxExportRoomsInView.IsChecked = configuration.ExportRoomsInView;
@@ -444,6 +446,8 @@ private void UpdateActiveConfigurationOptions(IFCExportConfiguration configurati
checkbox_OwnerHistoryLastModified.IsChecked = configuration.OwnerHistoryLastModified;
+ checkbox_ExportBarsInUniformSetsAsSeparateIFCEntities.IsChecked = configuration.ExportBarsInUniformSetsAsSeparateIFCEntities;
+
// Keep old behavior where by default we looked for ParameterMappingTable.txt in the current directory if ExportUserDefinedParameterMappingFileName
// isn't set.
if (string.IsNullOrWhiteSpace(configuration.ExportUserDefinedParameterMappingFileName))
@@ -480,6 +484,7 @@ private void UpdateActiveConfigurationOptions(IFCExportConfiguration configurati
comboboxActivePhase,
checkboxExportUserDefinedPset,
userDefinedPropertySetFileName,
+ checkboxUseTypePropertiesInInstacePSets,
checkBoxExportUserDefinedParameterMapping,
userDefinedParameterMappingTable,
buttonBrowse,
@@ -492,6 +497,7 @@ private void UpdateActiveConfigurationOptions(IFCExportConfiguration configurati
checkbox_UseVisibleRevitNameAsEntityName,
checkbox_ExportHostAsSingleEntity,
checkbox_OwnerHistoryLastModified,
+ checkbox_ExportBarsInUniformSetsAsSeparateIFCEntities,
comboBoxCategoryMapping,
buttonCategoryMapping
};
@@ -501,6 +507,7 @@ private void UpdateActiveConfigurationOptions(IFCExportConfiguration configurati
element.IsEnabled = !configuration.IsBuiltIn;
}
comboboxActivePhase.IsEnabled = comboboxActivePhase.IsEnabled && !configuration.VisibleElementsOfCurrentView;
+ checkboxUseTypePropertiesInInstacePSets.IsEnabled = checkboxUseTypePropertiesInInstacePSets.IsEnabled && configuration.ExportUserDefinedPsets;
userDefinedPropertySetFileName.IsEnabled = userDefinedPropertySetFileName.IsEnabled && configuration.ExportUserDefinedPsets;
userDefinedParameterMappingTable.IsEnabled = userDefinedParameterMappingTable.IsEnabled && configuration.ExportUserDefinedParameterMapping;
buttonBrowse.IsEnabled = buttonBrowse.IsEnabled && configuration.ExportUserDefinedPsets;
@@ -542,6 +549,9 @@ private void UpdateActiveConfigurationOptions(IFCExportConfiguration configurati
checkbox_OwnerHistoryLastModified.IsChecked = configuration.OwnerHistoryLastModified;
checkbox_OwnerHistoryLastModified.IsEnabled = true;
+ checkbox_ExportBarsInUniformSetsAsSeparateIFCEntities.IsChecked = configuration.ExportBarsInUniformSetsAsSeparateIFCEntities;
+ checkbox_ExportBarsInUniformSetsAsSeparateIFCEntities.IsEnabled = true;
+
if (configuration.IFCVersion.Equals(IFCVersion.IFC2x3FM))
{
DoCOBieSpecificSetup(configuration);
@@ -1018,6 +1028,21 @@ private void checkboxExportBaseQuantities_Checked(object sender, RoutedEventArgs
}
}
+ ///
+ /// Updates the result after the ExportCeilingGrids is picked.
+ ///
+ /// The source of the event.
+ /// Event arguments that contains the event data.
+ private void checkboxExportCeilingGrids_Checked(object sender, RoutedEventArgs e)
+ {
+ CheckBox checkBox = (CheckBox)sender;
+ IFCExportConfiguration configuration = GetSelectedConfiguration();
+ if (configuration != null)
+ {
+ configuration.ExportCeilingGrids = GetCheckbuttonChecked(checkBox);
+ }
+ }
+
///
/// Updates the result after the SplitWalls is picked.
///
@@ -1423,6 +1448,23 @@ private void checkboxExportUserDefinedPset_Checked(object sender, RoutedEventArg
configuration.ExportUserDefinedPsets = GetCheckbuttonChecked(checkBox);
userDefinedPropertySetFileName.IsEnabled = configuration.ExportUserDefinedPsets;
buttonBrowse.IsEnabled = configuration.ExportUserDefinedPsets;
+ checkboxUseTypePropertiesInInstacePSets.IsEnabled = configuration.ExportUserDefinedPsets;
+ checkboxUseTypePropertiesInInstacePSets.IsChecked = false;
+ }
+ }
+
+ ///
+ /// Update checkbox for exporting type properties for the instances
+ ///
+ /// The source of the event.
+ /// Event arguments that contains the event data.
+ private void checkboxUseTypePropertiesInInstacePSets_Checked(object sender, RoutedEventArgs e)
+ {
+ CheckBox checkBox = (CheckBox)sender;
+ IFCExportConfiguration configuration = GetSelectedConfiguration();
+ if (configuration != null)
+ {
+ configuration.UseTypePropertiesInInstacePSets = GetCheckbuttonChecked(checkBox);
}
}
@@ -1647,6 +1689,18 @@ private void Checkbox_OwnerHistoryLastModified_Unchecked(object sender, RoutedEv
configuration.OwnerHistoryLastModified = false;
}
+ private void checkbox_ExportBarsInUniformSetsAsSeparateIFCEntities_Checked(object sender, RoutedEventArgs e)
+ {
+ IFCExportConfiguration configuration = GetSelectedConfiguration();
+ configuration.ExportBarsInUniformSetsAsSeparateIFCEntities = true;
+ }
+
+ private void checkbox_ExportBarsInUniformSetsAsSeparateIFCEntities_Unchecked(object sender, RoutedEventArgs e)
+ {
+ IFCExportConfiguration configuration = GetSelectedConfiguration();
+ configuration.ExportBarsInUniformSetsAsSeparateIFCEntities = false;
+ }
+
private void Checkbox_UseVisibleRevitName_Checked(object sender, RoutedEventArgs e)
{
IFCExportConfiguration configuration = GetSelectedConfiguration();
diff --git a/Source/IFCExporterUIOverride/Properties/AssemblyInfo.cs b/Source/IFCExporterUIOverride/Properties/AssemblyInfo.cs
index c8881784..f43c74d8 100644
--- a/Source/IFCExporterUIOverride/Properties/AssemblyInfo.cs
+++ b/Source/IFCExporterUIOverride/Properties/AssemblyInfo.cs
@@ -67,6 +67,6 @@
// The following information is used in the Open Source version as the release version number.
// The number will show up in the Title bar of the export dialog as well as at the IFC header file
// This number must be manually updated prior to releasing the new version
-[assembly: AssemblyVersion("25.2.0.5")]
-[assembly: AssemblyFileVersion("25.2.0.5")]
+[assembly: AssemblyVersion("25.4.0.27")]
+[assembly: AssemblyFileVersion("25.4.0.27")]
#endif
\ No newline at end of file
diff --git a/Source/IFCExporterUIOverride/Properties/Resources.Designer.cs b/Source/IFCExporterUIOverride/Properties/Resources.Designer.cs
index d46a4b2e..85c0691f 100644
--- a/Source/IFCExporterUIOverride/Properties/Resources.Designer.cs
+++ b/Source/IFCExporterUIOverride/Properties/Resources.Designer.cs
@@ -861,6 +861,24 @@ public static string Export {
}
}
+ ///
+ /// Looks up a localized string similar to Export bars in uniform rebar sets as separate IFC entities.
+ ///
+ public static string ExportBarsInUniformRebarSetsAsSeparateIFCEntities {
+ get {
+ return ResourceManager.GetString("ExportBarsInUniformRebarSetsAsSeparateIFCEntities", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Use this option to export bars in uniform rebar sets as separate IFC entities..
+ ///
+ public static string ExportBarsInUniformRebarSetsAsSeparateIFCEntitiesToopTip {
+ get {
+ return ResourceManager.GetString("ExportBarsInUniformRebarSetsAsSeparateIFCEntitiesToopTip", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Export base quantities.
///
@@ -897,6 +915,15 @@ public static string ExportCategoryMappingFilter {
}
}
+ ///
+ /// Looks up a localized string similar to Export Ceiling Grids.
+ ///
+ public static string ExportCeilingGrids {
+ get {
+ return ResourceManager.GetString("ExportCeilingGrids", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Export only elements visible in current view.
///
@@ -3264,6 +3291,15 @@ public static string UseTypeNameOnlyTooltip {
}
}
+ ///
+ /// Looks up a localized string similar to Allow use of type properties in instance property sets.
+ ///
+ public static string UseTypePropertiesInInstacePSets {
+ get {
+ return ResourceManager.GetString("UseTypePropertiesInInstacePSets", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Use visible Revit name as the IFCEntity name.
///
diff --git a/Source/IFCExporterUIOverride/Properties/Resources.resx b/Source/IFCExporterUIOverride/Properties/Resources.resx
index 7f823772..5d37d93e 100644
--- a/Source/IFCExporterUIOverride/Properties/Resources.resx
+++ b/Source/IFCExporterUIOverride/Properties/Resources.resx
@@ -1208,4 +1208,16 @@
This is not a valid category mapping file.
+
+ Export Ceiling Grids
+
+
+ Export bars in uniform rebar sets as separate IFC entities
+
+
+ Use this option to export bars in uniform rebar sets as separate IFC entities.
+
+
+ Allow use of type properties in instance property sets
+
\ No newline at end of file
diff --git a/Source/Revit.IFC.Common/Properties/AssemblyInfo.cs b/Source/Revit.IFC.Common/Properties/AssemblyInfo.cs
index 843c920e..b94a2b27 100644
--- a/Source/Revit.IFC.Common/Properties/AssemblyInfo.cs
+++ b/Source/Revit.IFC.Common/Properties/AssemblyInfo.cs
@@ -12,8 +12,8 @@
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-[assembly: AssemblyVersion("25.2.0.5")]
-[assembly: AssemblyFileVersion("25.2.0.5")]
+[assembly: AssemblyVersion("25.4.0.27")]
+[assembly: AssemblyFileVersion("25.4.0.27")]
// Version information can now be found in Source\Foundation\RevitENU\Version.cs
diff --git a/Source/Revit.IFC.Common/Utility/IfcSchemaEntityTree.cs b/Source/Revit.IFC.Common/Utility/IfcSchemaEntityTree.cs
index 2789a664..3edf0109 100644
--- a/Source/Revit.IFC.Common/Utility/IfcSchemaEntityTree.cs
+++ b/Source/Revit.IFC.Common/Utility/IfcSchemaEntityTree.cs
@@ -407,13 +407,18 @@ static public IfcSchemaEntityNode FindNonAbsInstanceSuperType(IFCVersion context
/// This is done in a heuristic fashion, so we will need to
/// make sure exceptions are dealt with.
///
- public static string GetTypeNameFromInstanceName(string instanceName)
+ public static string GetTypeNameFromInstanceName(string instanceName, bool exportAsOlderThanIFC4)
{
// Deal with exceptions.
if (string.Compare(instanceName, "IfcProduct", true) == 0)
return "IfcTypeProduct";
else if (string.Compare(instanceName, "IfcObject", true) == 0)
return "IfcTypeObject";
+ // IFCDoorType and IFCWindowType are available since IFC4.
+ else if (string.Compare(instanceName, "IfcWindow", true) == 0 && exportAsOlderThanIFC4)
+ return "IfcWindowStyle";
+ else if (string.Compare(instanceName, "IFCDoor", true) == 0 && exportAsOlderThanIFC4)
+ return "IFCDoorStyle";
return instanceName + "Type";
}
@@ -438,8 +443,12 @@ static public IfcSchemaEntityNode FindNonAbsInstanceSuperType(string context, st
return res;
}
+
+ bool schemaOlderThanIFC4 = context.Equals(Ifc2x3Schema, StringComparison.InvariantCultureIgnoreCase)
+ || context.Equals(Ifc2x2Schema, StringComparison.InvariantCultureIgnoreCase);
+
string theTypeName = typeName.EndsWith("Type", StringComparison.CurrentCultureIgnoreCase) ?
- typeName : GetTypeNameFromInstanceName(typeName);
+ typeName : GetTypeNameFromInstanceName(typeName, schemaOlderThanIFC4);
IfcSchemaEntityNode entNode = ifcEntitySchemaTree.Find(theTypeName);
if (entNode != null)
diff --git a/Source/Revit.IFC.Export/Exporter/CeilingExporter.cs b/Source/Revit.IFC.Export/Exporter/CeilingExporter.cs
index 320d4408..84980d21 100644
--- a/Source/Revit.IFC.Export/Exporter/CeilingExporter.cs
+++ b/Source/Revit.IFC.Export/Exporter/CeilingExporter.cs
@@ -25,6 +25,7 @@
using Revit.IFC.Export.Utility;
using Revit.IFC.Export.Toolkit;
using Revit.IFC.Common.Enums;
+using System.Reflection;
namespace Revit.IFC.Export.Exporter
{
@@ -74,9 +75,9 @@ public static void ExportCovering(ExporterIFC exporterIFC, Element element, ref
return;
IFCFile file = exporterIFC.GetFile();
- MaterialLayerSetInfo layersetInfo = new MaterialLayerSetInfo(exporterIFC, element, productWrapper);
+ MaterialLayerSetInfo layersetInfo = new(exporterIFC, element, productWrapper);
- using (IFCTransaction transaction = new IFCTransaction(file))
+ using (IFCTransaction transaction = new(file))
{
// For IFC4RV export, Element will be split into its parts(temporarily) in order to export the wall by its parts
// If Parts are created by code and not by user then their name should be equal to Material name.
@@ -91,11 +92,11 @@ public static void ExportCovering(ExporterIFC exporterIFC, Element element, ref
// Check for containment override
IFCAnyHandle overrideContainerHnd = null;
ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, element, out overrideContainerHnd);
- IList representations = new List();
+ List representations = new();
using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, null, overrideContainerId, overrideContainerHnd))
{
- using (IFCExportBodyParams ecData = new IFCExportBodyParams())
+ using (IFCExportBodyParams ecData = new())
{
ElementId categoryId = CategoryUtil.GetSafeCategoryId(element);
@@ -105,7 +106,7 @@ public static void ExportCovering(ExporterIFC exporterIFC, Element element, ref
ecData.SetLocalPlacement(setter.LocalPlacement);
ecData.PossibleExtrusionAxes = (element is FamilyInstance) ? IFCExtrusionAxes.TryXYZ : IFCExtrusionAxes.TryZ;
- BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
+ BodyExporterOptions bodyExporterOptions = new(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
if (!exportByComponents)
{
prodRep = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, element,
@@ -138,6 +139,62 @@ public static void ExportCovering(ExporterIFC exporterIFC, Element element, ref
productWrapper, setter, setter.LocalPlacement, ElementId.InvalidElementId, layersetInfo, ecData);
}
+ if (ExporterCacheManager.ExportCeilingGrids())
+ {
+ IList ceilingGridLines = null;
+
+ var ceiling = element as Ceiling;
+ if (ceiling != null)
+ {
+ try
+ {
+ var methodInfo = typeof(Ceiling).GetMethod("GetCeilingGridLines", BindingFlags.Instance | BindingFlags.Public);
+ if (methodInfo != null)
+ {
+ // Invoke the method dynamically and cast the result to the expected type
+ ceilingGridLines = (IList)methodInfo.Invoke(ceiling, new object[] { true });
+ }
+ }
+ catch (Exception)
+ {
+ // Ceiling.GetCeilingGridLines method is availiable since 2025.3
+ // ignore ceiling grid export for older Revit versions.
+ }
+ }
+
+ HashSet repItems = new();
+ if (ceilingGridLines != null)
+ {
+ Transform localPlacementOffset = ExporterUtil.GetTransformFromLocalPlacementHnd(setter.LocalPlacement, true);
+ if (localPlacementOffset.IsIdentity)
+ {
+ localPlacementOffset = null;
+ }
+ else
+ {
+ localPlacementOffset = localPlacementOffset.Inverse;
+ }
+
+ foreach (Curve ceilingGrid in ceilingGridLines)
+ {
+ Curve transformedCeilingGrid =
+ localPlacementOffset != null ? ceilingGrid.CreateTransformed(localPlacementOffset) : ceilingGrid;
+ repItems.AddIfNotNull(GeometryUtil.CreateIFCCurveFromRevitCurve(file, exporterIFC,
+ transformedCeilingGrid, false, null, GeometryUtil.TrimCurvePreference.UsePolyLineOrTrim, null));
+ }
+ }
+
+ if (repItems.Count > 0)
+ {
+ IFCAnyHandle contextOfItemsFootprint = exporterIFC.Get3DContextHandle("FootPrint");
+ IFCAnyHandle footprintShapeRep = RepresentationUtil.CreateBaseShapeRepresentation(exporterIFC, contextOfItemsFootprint,
+ "FootPrint", "Curve2D", repItems);
+ List newRep = new() { footprintShapeRep };
+ IFCAnyHandleUtil.AddRepresentations(prodRep, newRep);
+ }
+ }
+
+
IFCAnyHandle covering = IFCInstanceExporter.CreateCovering(exporterIFC, element, instanceGUID, ExporterCacheManager.OwnerHistoryHandle,
setter.LocalPlacement, prodRep, coveringType);
@@ -149,7 +206,7 @@ public static void ExportCovering(ExporterIFC exporterIFC, Element element, ref
ExporterUtil.AddIntoComplexPropertyCache(covering, layersetInfo);
- IFCExportInfoPair exportInfo = new IFCExportInfoPair(IFCEntityType.IfcCovering, IFCEntityType.IfcCoveringType, coveringType);
+ IFCExportInfoPair exportInfo = new(IFCEntityType.IfcCovering, IFCEntityType.IfcCoveringType, coveringType);
IFCAnyHandle typeHnd = ExporterUtil.CreateGenericTypeFromElement(element, exportInfo, file, productWrapper);
ExporterCacheManager.TypeRelationsCache.Add(typeHnd, covering);
diff --git a/Source/Revit.IFC.Export/Exporter/Exporter.cs b/Source/Revit.IFC.Export/Exporter/Exporter.cs
index 615e7659..d61a2d82 100644
--- a/Source/Revit.IFC.Export/Exporter/Exporter.cs
+++ b/Source/Revit.IFC.Export/Exporter/Exporter.cs
@@ -485,19 +485,21 @@ protected void ExportSpatialElements(ExporterIFC exporterIFC, Document document)
protected void ExportNonSpatialElements(ExporterIFC exporterIFC, Document document)
{
- FilteredElementCollector otherElementCollector = GetExportElementCollector(document, true);
+ // Cache non-spatial Elements for later usage.
+ ICollection nonSpatialElements = ElementFilteringUtil.GetNonSpatialElements(document, exporterIFC);
- ElementFilter nonSpatialElementFilter = ElementFilteringUtil.GetNonSpatialElementFilter(document, exporterIFC);
- otherElementCollector.WherePasses(nonSpatialElementFilter);
-
- int numOfOtherElement = otherElementCollector.Count();
- IList otherElementCollListCopy = new List(otherElementCollector);
+ int numNonSpatialElements = nonSpatialElements.Count;
int otherElementCollectorCount = 1;
- foreach (Element element in otherElementCollListCopy)
+ foreach (ElementId elementId in nonSpatialElements)
{
- statusBar.Set(string.Format(Resources.IFCProcessingNonSpatialElements, otherElementCollectorCount, numOfOtherElement, element.Id));
+ statusBar.Set(string.Format(Resources.IFCProcessingNonSpatialElements, otherElementCollectorCount, numNonSpatialElements, elementId));
+
otherElementCollectorCount++;
- ExportElement(exporterIFC, element);
+ Element element = document.GetElement(elementId);
+ if (element != null)
+ {
+ ExportElement(exporterIFC, element);
+ }
}
}
@@ -809,13 +811,19 @@ public virtual void ExportElementImpl(ExporterIFC exporterIFC, Element element,
{
exporterIFC.PushExportState(element, geomElem);
- Autodesk.Revit.DB.Document doc = element.Document;
+ Document doc = element.Document;
using (SubTransaction st = new SubTransaction(doc))
{
st.Start();
+ // A very quick check if we happen to be exporting only geometry.
+ if (ExporterCacheManager.ExportOptionsCache.ExportGeometryOnly)
+ {
+ ProxyElementExporter.Export(exporterIFC, element, geomElem, productWrapper);
+ }
+
// A long list of supported elements. Please keep in alphabetical order by the first item in the list..
- if (element is AreaScheme)
+ else if (element is AreaScheme)
{
AreaSchemeExporter.ExportAreaScheme(exporterIFC, element as AreaScheme, productWrapper);
}
@@ -900,7 +908,7 @@ public virtual void ExportElementImpl(ExporterIFC exporterIFC, Element element,
else if (element is FilledRegion)
{
FilledRegion filledRegion = element as FilledRegion;
- FilledRegionExporter.Export(exporterIFC, filledRegion, geomElem, productWrapper);
+ FilledRegionExporter.Export(exporterIFC, filledRegion, productWrapper);
}
else if (element is Grid)
{
@@ -1258,10 +1266,10 @@ private void BeginDocumentExportCommon(ExporterIFC exporterIFC, Document documen
IFCAnyHandle buildingPlacement = CreateBuildingPlacement(file);
IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle;
-
+
// create levels
// Check if there is any level assigned as a building storey, if no at all, model will be exported without Building and BuildingStorey, all containment will be to Site
- IList allLevels = LevelUtil.FindAllLevels(document);
+ List allLevels = !ExporterCacheManager.ExportOptionsCache.ExportGeometryOnly ? LevelUtil.FindAllLevels(document) : [];
bool exportBuilding = ExportBuilding(allLevels);
@@ -1425,7 +1433,7 @@ private static void UpdateLocalPlacementForElement(IFCAnyHandle elemHnd, IFCFile
IFCAnyHandle oldRelativePlacement = IFCAnyHandleUtil.GetInstanceAttribute(elemObjectPlacementHnd, "PlacementRelTo");
if (IFCAnyHandleUtil.IsNullOrHasNoValue(oldRelativePlacement))
{
- newTrf = ExporterUtil.GetTransformFromLocalPlacementHnd(elemObjectPlacementHnd);
+ newTrf = ExporterUtil.GetTransformFromLocalPlacementHnd(elemObjectPlacementHnd, false);
}
else
{
@@ -1446,7 +1454,7 @@ private static void UpdateLocalPlacementForElement(IFCAnyHandle elemHnd, IFCFile
private void CreatePresentationLayerAssignments(ExporterIFC exporterIFC, IFCFile file)
{
- if (ExporterCacheManager.ExportOptionsCache.ExportAs2x2)
+ if (ExporterCacheManager.ExportOptionsCache.ExportAs2x2 || ExporterCacheManager.ExportOptionsCache.ExportGeometryOnly)
return;
ISet assignedRepresentations = new HashSet();
@@ -2463,23 +2471,26 @@ private void WriteIFCFile(IFCFile file, IFCFileDocumentInfo ifcFileDocumentInfo)
}
- string versionLine = string.Format("RevitIdentifiers [ContentGUID: {0}, VersionGUID: {1}, NumberOfSaves: {2}]",
- ifcFileDocumentInfo.ContentGUIDString, ifcFileDocumentInfo.VersionGUIDString, ifcFileDocumentInfo.NumberOfSaves);
-
- descriptions.Add(versionLine);
-
- if (!string.IsNullOrEmpty(ExporterCacheManager.ExportOptionsCache.ExcludeFilter))
+ if (!ExporterCacheManager.ExportOptionsCache.ExportGeometryOnly)
{
- descriptions.Add("Options [Excluded Entities: " + ExporterCacheManager.ExportOptionsCache.ExcludeFilter + "]");
- }
+ string versionLine = string.Format("RevitIdentifiers [ContentGUID: {0}, VersionGUID: {1}, NumberOfSaves: {2}]",
+ ifcFileDocumentInfo.ContentGUIDString, ifcFileDocumentInfo.VersionGUIDString, ifcFileDocumentInfo.NumberOfSaves);
+
+ descriptions.Add(versionLine);
+
+ if (!string.IsNullOrEmpty(ExporterCacheManager.ExportOptionsCache.ExcludeFilter))
+ {
+ descriptions.Add("Options [Excluded Entities: " + ExporterCacheManager.ExportOptionsCache.ExcludeFilter + "]");
+ }
- string projectNumber = ifcFileDocumentInfo?.ProjectNumber ?? string.Empty;
- string projectName = ifcFileDocumentInfo?.ProjectName ?? string.Empty;
- string projectStatus = ifcFileDocumentInfo?.ProjectStatus ?? string.Empty;
+ string projectNumber = ifcFileDocumentInfo?.ProjectNumber ?? string.Empty;
+ string projectName = ifcFileDocumentInfo?.ProjectName ?? string.Empty;
+ string projectStatus = ifcFileDocumentInfo?.ProjectStatus ?? string.Empty;
- IFCAnyHandle project = ExporterCacheManager.ProjectHandle;
- if (!IFCAnyHandleUtil.IsNullOrHasNoValue(project))
- IFCAnyHandleUtil.UpdateProject(project, projectNumber, projectName, projectStatus);
+ IFCAnyHandle project = ExporterCacheManager.ProjectHandle;
+ if (!IFCAnyHandleUtil.IsNullOrHasNoValue(project))
+ IFCAnyHandleUtil.UpdateProject(project, projectNumber, projectName, projectStatus);
+ }
IFCInstanceExporter.CreateFileSchema(file);
@@ -2731,25 +2742,24 @@ private HashSet CreateContextInformation(ExporterIFC exporterIFC,
int dimCount = 3;
IFCAnyHandle context3D = IFCInstanceExporter.CreateGeometricRepresentationContext(file, null,
"Model", dimCount, precision, wcs, trueNorth);
- // CoordinationView2.0 requires sub-contexts of "Axis", "Body", and "Box".
- // We will use these for regular export also.
+
+ ExporterCacheManager.Set3DContextHandle(exporterIFC, IFCRepresentationIdentifier.None, context3D);
+
+ if (!ExporterCacheManager.ExportOptionsCache.ExportGeometryOnly)
{
- IFCAnyHandle context3DAxis = IFCInstanceExporter.CreateGeometricRepresentationSubContext(file,
- "Axis", "Model", context3D, null, IFCGeometricProjection.Graph_View, null);
- IFCAnyHandle context3DBody = IFCInstanceExporter.CreateGeometricRepresentationSubContext(file,
- "Body", "Model", context3D, null, IFCGeometricProjection.Model_View, null);
- IFCAnyHandle context3DBox = IFCInstanceExporter.CreateGeometricRepresentationSubContext(file,
- "Box", "Model", context3D, null, IFCGeometricProjection.Model_View, null);
- IFCAnyHandle context3DFootPrint = IFCInstanceExporter.CreateGeometricRepresentationSubContext(file,
- "FootPrint", "Model", context3D, null, IFCGeometricProjection.Model_View, null);
-
- ExporterCacheManager.Set3DContextHandle(exporterIFC, IFCRepresentationIdentifier.Axis, context3DAxis);
- ExporterCacheManager.Set3DContextHandle(exporterIFC, IFCRepresentationIdentifier.Body, context3DBody);
- ExporterCacheManager.Set3DContextHandle(exporterIFC, IFCRepresentationIdentifier.Box, context3DBox);
- ExporterCacheManager.Set3DContextHandle(exporterIFC, IFCRepresentationIdentifier.FootPrint, context3DFootPrint);
+ ExporterCacheManager.Get3DContextHandle(IFCRepresentationIdentifier.Axis);
+ }
+
+ // We will force creation of the Body subcontext because internal code expects it.
+ // For the rest, we will create sub-contexts as we need them.
+ ExporterCacheManager.Get3DContextHandle(IFCRepresentationIdentifier.Body);
+
+ if (!ExporterCacheManager.ExportOptionsCache.ExportGeometryOnly)
+ {
+ ExporterCacheManager.Get3DContextHandle(IFCRepresentationIdentifier.Box);
+ ExporterCacheManager.Get3DContextHandle(IFCRepresentationIdentifier.FootPrint);
}
- ExporterCacheManager.Set3DContextHandle(exporterIFC, IFCRepresentationIdentifier.None, context3D);
repContexts.Add(context3D); // Only Contexts in list, not sub-contexts.
// Create IFCMapConversion information for the context
@@ -2916,7 +2926,7 @@ private void CreateProject(ExporterIFC exporterIFC, Document doc, IFCAnyHandle a
string author = string.Empty;
bool hasPotentialLastUser = false;
- ProjectInfo projectInfo = doc.ProjectInformation;
+ ProjectInfo projectInfo = !ExporterCacheManager.ExportOptionsCache.ExportGeometryOnly ? doc.ProjectInformation : null;
if (projectInfo != null)
{
try
@@ -2942,6 +2952,7 @@ private void CreateProject(ExporterIFC exporterIFC, Document doc, IFCAnyHandle a
IFCAnyHandle ownerHistory = null;
IFCAnyHandle person = null;
IFCAnyHandle organization = null;
+ IFCAnyHandle owningUser = null;
COBieCompanyInfo cobieCompInfo = ExporterCacheManager.ExportOptionsCache.COBieCompanyInfo;
@@ -2956,13 +2967,13 @@ private void CreateProject(ExporterIFC exporterIFC, Document doc, IFCAnyHandle a
null, new List() { postalAddress, telecomAddress });
person = IFCInstanceExporter.CreatePerson(file, null, null, null, null, null, null, null, null);
}
- else
+ else if (!ExporterCacheManager.ExportOptionsCache.ExportGeometryOnly)
{
- IList telecomAddresses = null;
+ List telecomAddresses = null;
IFCAnyHandle telecomAddress = GetTelecomAddressFromExtStorage(file);
if (telecomAddress != null)
{
- telecomAddresses = new List() { telecomAddress };
+ telecomAddresses = [ telecomAddress ];
}
person = IFCInstanceExporter.CreatePerson(file, null, familyName, givenName, middleNames,
@@ -2985,15 +2996,24 @@ private void CreateProject(ExporterIFC exporterIFC, Document doc, IFCAnyHandle a
organization = IFCInstanceExporter.CreateOrganization(file, null, organizationName, organizationDescription, null, null);
}
- IFCAnyHandle owningUser = IFCInstanceExporter.CreatePersonAndOrganization(file, person, organization, null);
- IFCAnyHandle lastModifyingUser = hasPotentialLastUser && ExporterCacheManager.ExportOptionsCache.OwnerHistoryLastModified
- ? owningUser : null;
+ if (person != null || organization != null)
+ {
+ owningUser = IFCInstanceExporter.CreatePersonAndOrganization(file, person, organization, null);
+ }
+
+ // TODO: Fix regression tests whose line numbers change as a result of missing handles.
+ // Change to if (ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4)
+ if (ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4 || !ExporterCacheManager.ExportOptionsCache.ExportGeometryOnly)
+ {
+ IFCAnyHandle lastModifyingUser = hasPotentialLastUser && ExporterCacheManager.ExportOptionsCache.OwnerHistoryLastModified
+ ? owningUser : null;
- ownerHistory = IFCInstanceExporter.CreateOwnerHistory(file, owningUser, application, null,
+ ownerHistory = IFCInstanceExporter.CreateOwnerHistory(file, owningUser, application, null,
IFCChangeAction.NoChange, null, lastModifyingUser, null, creationDate);
- exporterIFC.SetOwnerHistoryHandle(ownerHistory); // For use by native code only.
- ExporterCacheManager.OwnerHistoryHandle = ownerHistory;
+ exporterIFC.SetOwnerHistoryHandle(ownerHistory); // For use by native code only.
+ ExporterCacheManager.OwnerHistoryHandle = ownerHistory;
+ }
// Getting contact information from Revit extensible storage that COBie extension tool creates
GetCOBieContactInfo(file, doc);
@@ -3008,25 +3028,28 @@ private void CreateProject(ExporterIFC exporterIFC, Document doc, IFCAnyHandle a
string projectDescription = null;
string projectPhase = null;
- COBieProjectInfo cobieProjInfo = ExporterCacheManager.ExportOptionsCache.COBieProjectInfo;
- if (ExporterCacheManager.ExportOptionsCache.ExportAs2x3COBIE24DesignDeliverable && cobieProjInfo != null)
- {
- projectName = cobieProjInfo.ProjectName;
- projectDescription = cobieProjInfo.ProjectDescription;
- projectPhase = cobieProjInfo.ProjectPhase;
- }
- else
+ if (!ExporterCacheManager.ExportOptionsCache.ExportGeometryOnly)
{
- // As per IFC implementer's agreement, we get IfcProject.Name from ProjectInfo.Number and IfcProject.Longname from ProjectInfo.Name
- projectName = projectInfo?.Number;
- projectLongName = projectInfo?.Name;
+ COBieProjectInfo cobieProjInfo = ExporterCacheManager.ExportOptionsCache.COBieProjectInfo;
+ if (ExporterCacheManager.ExportOptionsCache.ExportAs2x3COBIE24DesignDeliverable && cobieProjInfo != null)
+ {
+ projectName = cobieProjInfo.ProjectName;
+ projectDescription = cobieProjInfo.ProjectDescription;
+ projectPhase = cobieProjInfo.ProjectPhase;
+ }
+ else
+ {
+ // As per IFC implementer's agreement, we get IfcProject.Name from ProjectInfo.Number and IfcProject.Longname from ProjectInfo.Name
+ projectName = projectInfo?.Number;
+ projectLongName = projectInfo?.Name;
- // Get project description if it is set in the Project info
- projectDescription = (projectInfo != null) ? NamingUtil.GetDescriptionOverride(projectInfo, null) : null;
+ // Get project description if it is set in the Project info
+ projectDescription = (projectInfo != null) ? NamingUtil.GetDescriptionOverride(projectInfo, null) : null;
- if (projectInfo != null)
- if (ParameterUtil.GetStringValueFromElement(projectInfo, "IfcProject.Phase", out projectPhase) == null)
- ParameterUtil.GetStringValueFromElement(projectInfo, "Project Phase", out projectPhase);
+ if (projectInfo != null)
+ if (ParameterUtil.GetStringValueFromElement(projectInfo, "IfcProject.Phase", out projectPhase) == null)
+ ParameterUtil.GetStringValueFromElement(projectInfo, "Project Phase", out projectPhase);
+ }
}
string projectGUID = GUIDUtil.CreateProjectLevelGUID(doc, GUIDUtil.ProjectLevelGUIDType.Project);
@@ -3034,7 +3057,6 @@ private void CreateProject(ExporterIFC exporterIFC, Document doc, IFCAnyHandle a
projectName, projectDescription, projectLongName, projectPhase, repContexts, null);
ExporterCacheManager.ProjectHandle = projectHandle;
-
if (projectInfo != null)
{
using (ProductWrapper productWrapper = ProductWrapper.Create(exporterIFC, true))
@@ -3065,30 +3087,26 @@ private void CreateContact(IFCFile file, string category, string company, string
IFCAnyHandle contactTelecomAddress = IFCInstanceExporter.CreateTelecomAddress(file, null, null, null, telNoList, null, null, eMailAddressList, null);
IFCAnyHandle contactPostalAddress = IFCInstanceExporter.CreatePostalAddress(file, null, null, null, department, addressLines, postalBox, town, stateRegion,
postalCode, country);
- IList contactAddresses = new List();
- contactAddresses.Add(contactTelecomAddress);
- contactAddresses.Add(contactPostalAddress);
+ List contactAddresses = [ contactTelecomAddress, contactPostalAddress ];
IFCAnyHandle contactPerson = IFCInstanceExporter.CreatePerson(file, null, contactFamilyName, contactFirstName, null,
null, null, null, contactAddresses);
IFCAnyHandle contactOrganization = IFCInstanceExporter.CreateOrganization(file, organizationCode, company, null,
null, null);
IFCAnyHandle actorRole = IFCInstanceExporter.CreateActorRole(file, "UserDefined", category, null);
- IList actorRoles = new List();
- actorRoles.Add(actorRole);
+ List actorRoles = [actorRole ];
IFCAnyHandle contactEntry = IFCInstanceExporter.CreatePersonAndOrganization(file, contactPerson, contactOrganization, actorRoles);
}
private IFCAnyHandle GetTelecomAddressFromExtStorage(IFCFile file)
{
IFCFileHeaderItem fHItem = ExporterCacheManager.ExportOptionsCache.FileHeaderItem;
- if (!string.IsNullOrEmpty(fHItem.AuthorEmail))
+ if (string.IsNullOrEmpty(fHItem.AuthorEmail))
{
- IList electronicMailAddress = new List();
- electronicMailAddress.Add(fHItem.AuthorEmail);
- return IFCInstanceExporter.CreateTelecomAddress(file, null, null, null, null, null, null, electronicMailAddress, null);
+ return null;
}
- return null;
+ List electronicMailAddress = [fHItem.AuthorEmail];
+ return IFCInstanceExporter.CreateTelecomAddress(file, null, null, null, null, null, null, electronicMailAddress, null);
}
///
@@ -3099,7 +3117,7 @@ private IFCAnyHandle GetTelecomAddressFromExtStorage(IFCFile file)
/// The handle of IFC file.
static public IFCAnyHandle CreateIFCAddressFromExtStorage(IFCFile file, Document document)
{
- IFCAddress savedAddress = new IFCAddress();
+ IFCAddress savedAddress = new();
IFCAddressItem savedAddressItem;
if (savedAddress.GetSavedAddress(document, out savedAddressItem) == true)
@@ -3916,6 +3934,7 @@ private bool ExportIFCMapConversion(ExporterIFC exporterIFC, Document doc, IFCAn
eastings = UnitUtils.ConvertFromInternalUnits(eastings, utId);
northings = UnitUtils.ConvertFromInternalUnits(northings, utId);
orthogonalHeight = UnitUtils.ConvertFromInternalUnits(orthogonalHeight, utId);
+
IFCAnyHandle mapConversionHnd = IFCInstanceExporter.CreateMapConversion(file, geomRepContext, projectedCRS, eastings, northings,
orthogonalHeight, xAxisAbscissa, xAxisOrdinate, scale);
diff --git a/Source/Revit.IFC.Export/Exporter/ExporterInitializer.cs b/Source/Revit.IFC.Export/Exporter/ExporterInitializer.cs
index 7a0be1c2..c150222a 100644
--- a/Source/Revit.IFC.Export/Exporter/ExporterInitializer.cs
+++ b/Source/Revit.IFC.Export/Exporter/ExporterInitializer.cs
@@ -234,6 +234,7 @@ private static void InitUserDefinedPropertySets(IList
/// The ExporterIFC object.
/// The filled region element.
- /// The geometry element.
/// The ProductWrapper.
- public static void Export(ExporterIFC exporterIFC, FilledRegion filledRegion,
- GeometryElement geometryElement, ProductWrapper productWrapper)
+ public static void Export(ExporterIFC exporterIFC, FilledRegion filledRegion, ProductWrapper productWrapper)
{
- if (filledRegion == null || geometryElement == null)
+ if (filledRegion == null)
return;
// Check the intended IFC entity or type name is in the exclude list specified in the UI
diff --git a/Source/Revit.IFC.Export/Exporter/GenericElementExporter.cs b/Source/Revit.IFC.Export/Exporter/GenericElementExporter.cs
index 08e3fb55..996b6fc4 100644
--- a/Source/Revit.IFC.Export/Exporter/GenericElementExporter.cs
+++ b/Source/Revit.IFC.Export/Exporter/GenericElementExporter.cs
@@ -52,7 +52,10 @@ public static IFCAnyHandle ExportSimpleGenericElement(ExporterIFC exporterIFC, E
ElementId categoryId = CategoryUtil.GetSafeCategoryId(element);
- BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
+ bool tryToExportAsTessellation = !ExporterCacheManager.ExportOptionsCache.ExportGeometryOnly;
+
+ BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(tryToExportAsTessellation,
+ ExportOptionsCache.ExportTessellationLevel.ExtraLow);
IFCAnyHandle representation = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, element,
categoryId, geometryElement, bodyExporterOptions, null, ecData, true);
diff --git a/Source/Revit.IFC.Export/Exporter/PartExporter.cs b/Source/Revit.IFC.Export/Exporter/PartExporter.cs
index 18ade433..81f1ae74 100644
--- a/Source/Revit.IFC.Export/Exporter/PartExporter.cs
+++ b/Source/Revit.IFC.Export/Exporter/PartExporter.cs
@@ -368,8 +368,8 @@ public static IFCAnyHandle ExportPart(ExporterIFC exporterIFC, Element partEleme
{
originalPlacement = IFCAnyHandleUtil.GetObjectPlacement(hostHandle);
}
- hostTrf = ExporterUtil.GetTransformFromLocalPlacementHnd(originalPlacement);
- hostTrf = ExporterUtil.UnscaleTransformOrigin(hostTrf);
+ hostTrf = ExporterUtil.GetTransformFromLocalPlacementHnd(originalPlacement, true);
+
geometryElement = SolidMeshGeometryInfo.GetTransformedGeometry(geometryElement, hostTrf.Inverse,
ExporterCacheManager.AllocatedGeometryObjectCache);
}
diff --git a/Source/Revit.IFC.Export/Exporter/PropertySet/ClassificationUtil.cs b/Source/Revit.IFC.Export/Exporter/PropertySet/ClassificationUtil.cs
index bf04fb57..6cc04f42 100644
--- a/Source/Revit.IFC.Export/Exporter/PropertySet/ClassificationUtil.cs
+++ b/Source/Revit.IFC.Export/Exporter/PropertySet/ClassificationUtil.cs
@@ -51,6 +51,9 @@ private static string GetUniformatURL()
/// the element handle
public static void CreateUniformatClassification(ExporterIFC exporterIFC, IFCFile file, Element element, IFCAnyHandle elemHnd)
{
+ if (ExporterCacheManager.ExportOptionsCache.ExportGeometryOnly)
+ return;
+
IFCEntityType entType = IFCEntityType.IfcObjectDefinition;
if (!Enum.TryParse(elemHnd.TypeName, out IFCEntityType hndEntType))
entType = hndEntType;
@@ -119,6 +122,9 @@ public static void CreateUniformatClassification(ExporterIFC exporterIFC, IFCFil
public static bool CreateClassification(ExporterIFC exporterIFC, IFCFile file,
Element element, IFCAnyHandle elemHnd)
{
+ if (ExporterCacheManager.ExportOptionsCache.ExportGeometryOnly)
+ return false;
+
bool createdClassification = false;
string paramClassificationCode = "";
diff --git a/Source/Revit.IFC.Export/Exporter/PropertySet/PropertySetDescription.cs b/Source/Revit.IFC.Export/Exporter/PropertySet/PropertySetDescription.cs
index 4c277068..a3fc6f73 100644
--- a/Source/Revit.IFC.Export/Exporter/PropertySet/PropertySetDescription.cs
+++ b/Source/Revit.IFC.Export/Exporter/PropertySet/PropertySetDescription.cs
@@ -112,6 +112,11 @@ public class PropertySetDescription : Description
IList m_Entries = new List();
+ ///
+ /// Determines whether properties from the element's type should be added to the instance.
+ ///
+ public bool AddTypePropertiesToInstance { get; set; }
+
///
/// The entries stored in this property set description.
///
@@ -186,7 +191,7 @@ public ISet ProcessEntries(IFCFile file, ExporterIFC exporterIFC,
{
try
{
- IFCAnyHandle propHnd = entry.ProcessEntry(file, exporterIFC, Name, ifcParams, elementOrConnectorToUse, elemTypeToUse, handle, lookInType);
+ IFCAnyHandle propHnd = entry.ProcessEntry(file, exporterIFC, Name, ifcParams, elementOrConnectorToUse, elemTypeToUse, handle, lookInType, AddTypePropertiesToInstance);
if (IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd) && ExporterCacheManager.ExportOptionsCache.PropertySetOptions.ExportMaterialPsets)
propHnd = MaterialBuildInParameterUtil.CreateMaterialPropertyIfBuildIn(Name, entry.PropertyName, entry.PropertyType, elementOrConnectorToUse?.Element, file);
diff --git a/Source/Revit.IFC.Export/Exporter/PropertySet/PropertySetEntry.cs b/Source/Revit.IFC.Export/Exporter/PropertySet/PropertySetEntry.cs
index fc3121ef..d1543b29 100644
--- a/Source/Revit.IFC.Export/Exporter/PropertySet/PropertySetEntry.cs
+++ b/Source/Revit.IFC.Export/Exporter/PropertySet/PropertySetEntry.cs
@@ -416,10 +416,11 @@ private IFCAnyHandle CreateTextPropertyFromCombinedParameterData(IFCFile file, E
/// The element type of which this property is created for.
/// The handle for which this property is created for.
/// True if it's appropriate to look for value in element type.
+ /// Indicates whether properties from the element's type should be added to the instance.
/// The created property handle.
public IFCAnyHandle ProcessEntry(IFCFile file, ExporterIFC exporterIFC, string owningPsetName,
IFCExportBodyParams extrusionCreationData, ElementOrConnector elementOrConnector,
- ElementType elementType, IFCAnyHandle handle, bool lookInType = false)
+ ElementType elementType, IFCAnyHandle handle, bool lookInType = false, bool addTypePropertiesToInstance = false)
{
// if CombinedParameterData, then we have to recreate the parameter value, since there is no
// API for this.
@@ -434,7 +435,7 @@ public IFCAnyHandle ProcessEntry(IFCFile file, ExporterIFC exporterIFC, string o
IFCAnyHandle propHnd = map.ProcessEntry(file, exporterIFC, owningPsetName,
extrusionCreationData, elementOrConnector, elementType, handle, PropertyType,
PropertyArgumentType, PropertyValueType, PropertyEnumerationType, PropertyName,
- lookInType);
+ lookInType, addTypePropertiesToInstance);
if (propHnd != null)
return propHnd;
}
diff --git a/Source/Revit.IFC.Export/Exporter/PropertySet/PropertySetEntryMap.cs b/Source/Revit.IFC.Export/Exporter/PropertySet/PropertySetEntryMap.cs
index 4fbb477f..36c8a79b 100644
--- a/Source/Revit.IFC.Export/Exporter/PropertySet/PropertySetEntryMap.cs
+++ b/Source/Revit.IFC.Export/Exporter/PropertySet/PropertySetEntryMap.cs
@@ -73,12 +73,13 @@ public PropertySetEntryMap(string revitParameterName, BuiltInParameter builtInPa
/// The type of property.
/// The name of property to create.
/// True if it's appropriate to look for value in element type.
+ /// Indicates whether properties from the element's type should be added to the instance.
/// The created property handle.
public IFCAnyHandle ProcessEntry(IFCFile file, ExporterIFC exporterIFC, string owningPsetName,
IFCExportBodyParams extrusionCreationData, ElementOrConnector elementOrConnector,
ElementType elementType, IFCAnyHandle handle, PropertyType propertyType,
PropertyType propertyArgumentType, PropertyValueType valueType, Type propertyEnumerationType,
- string propertyName, bool lookInType)
+ string propertyName, bool lookInType, bool addTypePropertiesToInstance)
{
IFCAnyHandle propHnd = null;
@@ -93,7 +94,7 @@ public IFCAnyHandle ProcessEntry(IFCFile file, ExporterIFC exporterIFC, string o
Element element = elementOrConnector.Element;
propHnd = CreatePropertyFromElementOrSymbol(file, exporterIFC, owningPsetName, element,
elementType, propertyType, propertyArgumentType, valueType, propertyEnumerationType,
- propertyName, lookInType);
+ propertyName, lookInType, addTypePropertiesToInstance);
}
}
@@ -1091,10 +1092,11 @@ private static bool CollectTableDataFromElement(Element element, string revitPar
/// The element.
/// The element type, if it is appropriate to look in it for value.
/// True if it's appropriate to look for value in element type.
+ /// Indicates whether properties from the element's type should be added to the instance.
/// The property handle.
IFCAnyHandle CreatePropertyFromElementOrSymbol(IFCFile file, ExporterIFC exporterIFC, string owningPsetName, Element element, Element elementType,
PropertyType propertyType, PropertyType propertyArgumentType, PropertyValueType valueType, Type propertyEnumerationType, string propertyName,
- bool lookInType = false)
+ bool lookInType = false, bool addTypePropertiesToInstance = false)
{
// Pset from schedule will be created only on the instance and not on the type (type properties in the schedule will be added into the instance's pset
if ((element is ElementType || element is FamilySymbol) && lookInType)
@@ -1146,7 +1148,7 @@ IFCAnyHandle CreatePropertyFromElementOrSymbol(IFCFile file, ExporterIFC exporte
// Get the property from Type for this element if the pset is for schedule or
// if element doesn't have an associated type (e.g. IfcRoof)
- if (IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd) && (elementType != null) && lookInType)
+ if (IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd) && (elementType != null) && (lookInType || addTypePropertiesToInstance))
return CreatePropertyFromElementOrSymbol(file, exporterIFC, owningPsetName, elementType, null,
propertyType, propertyArgumentType, valueType, propertyEnumerationType, propertyName, false);
diff --git a/Source/Revit.IFC.Export/Exporter/RebarCouplerExporter.cs b/Source/Revit.IFC.Export/Exporter/RebarCouplerExporter.cs
index ba410d4b..12cb3b9d 100644
--- a/Source/Revit.IFC.Export/Exporter/RebarCouplerExporter.cs
+++ b/Source/Revit.IFC.Export/Exporter/RebarCouplerExporter.cs
@@ -109,11 +109,16 @@ public static void ExportCoupler(ExporterIFC exporterIFC, RebarCoupler coupler,
string origInstanceName = NamingUtil.GetNameOverride(coupler, NamingUtil.GetIFCName(coupler));
bool hasTypeInfo = !IFCAnyHandleUtil.IsNullOrHasNoValue(currentTypeInfo.Style);
-
+ bool bExportAsSingleIFCEntity = !ExporterCacheManager.ExportOptionsCache.ExportBarsInUniformSetsAsSeparateIFCEntities;
+ ISet representations = new HashSet() { };
+ string instanceGUID = null;
for (int idx = 0; idx < nCouplerQuantity; idx++)
{
- string instanceGUID = GUIDUtil.GenerateIFCGuidFrom(
- GUIDUtil.CreateGUIDString(coupler, "Fastener:" + (idx + 1).ToString()));
+ if (!bExportAsSingleIFCEntity)
+ instanceGUID = GUIDUtil.GenerateIFCGuidFrom(GUIDUtil.CreateGUIDString(coupler, "Fastener:" + (idx + 1).ToString()));
+ else
+ instanceGUID = GUIDUtil.GenerateIFCGuidFrom(GUIDUtil.CreateGUIDString(coupler, "Fastener"));
+
IFCAnyHandle style = currentTypeInfo.Style;
if (IFCAnyHandleUtil.IsNullOrHasNoValue(style))
@@ -127,50 +132,74 @@ public static void ExportCoupler(ExporterIFC exporterIFC, RebarCoupler coupler,
IFCAnyHandle contextOfItems3d = ExporterCacheManager.Get3DContextHandle(IFCRepresentationIdentifier.Body);
- ISet representations = new HashSet()
- { ExporterUtil.CreateDefaultMappedItem(file, repMapList[0], XYZ.Zero) };
-
- IList shapeReps = new List()
- { RepresentationUtil.CreateBodyMappedItemRep(exporterIFC, coupler, categoryId, contextOfItems3d, representations) };
-
- IFCAnyHandle productRepresentation = IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null, null, shapeReps);
-
Transform trf = coupler.GetCouplerPositionTransform(idx);
- using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, coupler, trf, null))
+ if (!bExportAsSingleIFCEntity)
{
- IFCAnyHandle instanceHandle = null;
- IFCExportInfoPair exportMechFastener = new IFCExportInfoPair(IFCEntityType.IfcMechanicalFastener, ifcEnumType);
- instanceHandle = IFCInstanceExporter.CreateGenericIFCEntity(exportMechFastener, exporterIFC, coupler, instanceGUID, ownerHistory,
- setter.LocalPlacement, productRepresentation);
- string instanceName = NamingUtil.GetNameOverride(instanceHandle, coupler, origInstanceName + ": " + idx);
- IFCAnyHandleUtil.OverrideNameAttribute(instanceHandle, instanceName);
-
- if (ExporterCacheManager.ExportOptionsCache.ExportAs4)
- {
- // In IFC4 NominalDiameter and NominalLength attributes have been deprecated. PredefinedType attribute was added.
- IFCAnyHandleUtil.SetAttribute(instanceHandle, "PredefinedType", Toolkit.IFC4.IFCMechanicalFastenerType.USERDEFINED);
- }
- else
- {
- IFCAnyHandleUtil.SetAttribute(instanceHandle, "NominalDiameter", familySymbol.get_Parameter(BuiltInParameter.COUPLER_WIDTH).AsDouble());
- IFCAnyHandleUtil.SetAttribute(instanceHandle, "NominalLength", familySymbol.get_Parameter(BuiltInParameter.COUPLER_LENGTH).AsDouble());
- }
+ representations = new HashSet() { ExporterUtil.CreateDefaultMappedItem(file, repMapList[0], XYZ.Zero) };
+ }
+ else
+ {
+ IFCAnyHandle axis1 = ExporterUtil.CreateDirection(file, trf.BasisX);
+ IFCAnyHandle axis2 = ExporterUtil.CreateDirection(file, trf.BasisY);
+ IFCAnyHandle axis3 = ExporterUtil.CreateDirection(file, trf.BasisZ);
+ IFCAnyHandle origin = ExporterUtil.CreateCartesianPoint(file, UnitUtil.ScaleLength(trf.Origin));
+ double scale = 1.0;
+ IFCAnyHandle mappingTarget = IFCInstanceExporter.CreateCartesianTransformationOperator3D(file, axis1, axis2, origin, scale, axis3);
+ representations.Add(IFCInstanceExporter.CreateMappedItem(file, repMapList[0], mappingTarget));
+ }
+
+ if (!bExportAsSingleIFCEntity || (bExportAsSingleIFCEntity && representations.Count == nCouplerQuantity))
+ {
+ IList shapeReps = new List()
+ { RepresentationUtil.CreateBodyMappedItemRep(exporterIFC, coupler, categoryId, contextOfItems3d, representations) };
- createdRebarCouplerHandles.Add(instanceHandle);
+ IFCAnyHandle productRepresentation = IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null, null, shapeReps);
- productWrapper.AddElement(coupler, instanceHandle, setter, null, true, exportType);
+ if (bExportAsSingleIFCEntity)
+ trf = Transform.Identity;
- if (hasTypeInfo)
+ using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, coupler, trf, null))
{
- ExporterCacheManager.TypeRelationsCache.Add(currentTypeInfo.Style, instanceHandle);
+ IFCAnyHandle instanceHandle = null;
+ IFCExportInfoPair exportMechFastener = new IFCExportInfoPair(IFCEntityType.IfcMechanicalFastener, ifcEnumType);
+ instanceHandle = IFCInstanceExporter.CreateGenericIFCEntity(exportMechFastener, exporterIFC, coupler, instanceGUID, ownerHistory,
+ setter.LocalPlacement, productRepresentation);
+
+ string instanceName = null;
+ if (!bExportAsSingleIFCEntity)
+ instanceName = NamingUtil.GetNameOverride(instanceHandle, coupler, origInstanceName + ": " + idx);
+ else
+ instanceName = NamingUtil.GetNameOverride(instanceHandle, coupler, origInstanceName);
+
+ IFCAnyHandleUtil.OverrideNameAttribute(instanceHandle, instanceName);
+
+ if (ExporterCacheManager.ExportOptionsCache.ExportAs4)
+ {
+ // In IFC4 NominalDiameter and NominalLength attributes have been deprecated. PredefinedType attribute was added.
+ IFCAnyHandleUtil.SetAttribute(instanceHandle, "PredefinedType", Toolkit.IFC4.IFCMechanicalFastenerType.USERDEFINED);
+ }
+ else
+ {
+ IFCAnyHandleUtil.SetAttribute(instanceHandle, "NominalDiameter", familySymbol.get_Parameter(BuiltInParameter.COUPLER_WIDTH).AsDouble());
+ IFCAnyHandleUtil.SetAttribute(instanceHandle, "NominalLength", familySymbol.get_Parameter(BuiltInParameter.COUPLER_LENGTH).AsDouble());
+ }
+
+ createdRebarCouplerHandles.Add(instanceHandle);
+
+ productWrapper.AddElement(coupler, instanceHandle, setter, null, true, exportType);
+
+ if (hasTypeInfo)
+ {
+ ExporterCacheManager.TypeRelationsCache.Add(currentTypeInfo.Style, instanceHandle);
+ }
}
}
}
string couplerGUID = GUIDUtil.CreateGUID(coupler);
- if (nCouplerQuantity > 1)
+ if (nCouplerQuantity > 1 && !bExportAsSingleIFCEntity)
{
// Create a group to hold all of the created IFC entities, if the coupler aren't already in an assembly.
// We want to avoid nested groups of groups of couplers.
diff --git a/Source/Revit.IFC.Export/Exporter/RebarExporter.cs b/Source/Revit.IFC.Export/Exporter/RebarExporter.cs
index 69df5f05..b751f9ae 100644
--- a/Source/Revit.IFC.Export/Exporter/RebarExporter.cs
+++ b/Source/Revit.IFC.Export/Exporter/RebarExporter.cs
@@ -477,12 +477,23 @@ private static ISet ExportRebar(ExporterIFC exporterIFC,
ElementId barLengthParamId = new ElementId(BuiltInParameter.REBAR_ELEM_LENGTH);
ParameterSet rebarElementParams = rebarElement.Parameters;
+
+ Rebar rebar = rebarElement as Rebar;
+ RebarInSystem rebarInSystem = rebarElement as RebarInSystem;
+
+ HashSet bodyItems = new HashSet() { };
+ string rebarName = null;
+ bool bExportAsSingleIFCEntity = false;
+
+ if ((!ExporterCacheManager.ExportOptionsCache.ExportBarsInUniformSetsAsSeparateIFCEntities) &&
+ ((rebar != null && !rebar.HasVariableLengthBars) || rebarInSystem != null))
+ bExportAsSingleIFCEntity = true;
+
for (int ii = 0; ii < numberOfBarPositions; ii++)
{
if (!DoesBarExistAtPosition(rebarItem, ii))
continue;
- Rebar rebar = rebarElement as Rebar;
if (rebar != null && rebar.CanHaveVaryingLengthBars)
{
baseCurves = GetRebarCenterlineCurves(rebar, true, false, false, MultiplanarOption.IncludeAllMultiplanarCurves, ii);
@@ -491,7 +502,6 @@ private static ISet ExportRebar(ExporterIFC exporterIFC,
barLength = barLengthParamVal.Value;
}
-
string rebarNameFormated = origRebarName;
if (rebar != null && rebar.CanBeMatchedWithMultipleShapes())
{
@@ -508,9 +518,12 @@ private static ISet ExportRebar(ExporterIFC exporterIFC,
int indexForNamingAndGUID = ii + itemIndex;
- string rebarName = NamingUtil.GetNameOverride(rebarElement, rebarNameFormated + ": " + indexForNamingAndGUID);
+ if (!bExportAsSingleIFCEntity)
+ rebarName = NamingUtil.GetNameOverride(rebarElement, rebarNameFormated + ": " + indexForNamingAndGUID);
+ else
+ rebarName = NamingUtil.GetNameOverride(rebarElement, rebarNameFormated);
- Transform barTrf = GetBarPositionTransform(rebarItem, ii);
+ Transform barTrf = GetBarPositionTransform(rebarItem, ii);
IList curves = new List();
double endParam = 0.0;
@@ -547,41 +560,49 @@ private static ISet ExportRebar(ExporterIFC exporterIFC,
// For IFC4 and Structural Exchange Requirement export, Entity type not allowed for RV: IfcPolyline
IFCAnyHandle compositeCurve = GeometryUtil.CreateCompositeOrIndexedCurve(exporterIFC, curves, null, null);
IFCAnyHandle sweptDiskSolid = IFCInstanceExporter.CreateSweptDiskSolid(file, compositeCurve, modelDiameter / 2, null, 0, endParam);
- HashSet bodyItems = new HashSet() { sweptDiskSolid };
RepresentationUtil.CreateStyledItemAndAssign(file, rebarElement.Document, materialId, sweptDiskSolid);
- IFCAnyHandle contextOfItems = ExporterCacheManager.Get3DContextHandle(IFCRepresentationIdentifier.Body);
- IFCAnyHandle shapeRep = RepresentationUtil.CreateAdvancedSweptSolidRep(exporterIFC,
- rebarElement, categoryId, contextOfItems, bodyItems, null);
- IList shapeReps = new List() { shapeRep };
- prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps);
-
- IFCAnyHandle copyLevelPlacement = (ii == 0) ? originalPlacement : ExporterUtil.CopyLocalPlacement(file, originalPlacement);
-
- string rebarGUID = (indexForNamingAndGUID < maxBarGUIDS) ?
- GUIDUtil.CreateSubElementGUID(rebarElement, indexForNamingAndGUID + (int)IFCReinforcingBarSubElements.BarStart - 1) :
- GUIDUtil.GenerateIFCGuidFrom(
- GUIDUtil.CreateGUIDString(rebarElement, indexForNamingAndGUID.ToString()));
- IFCAnyHandle elemHnd = IFCInstanceExporter.CreateReinforcingBar(exporterIFC, rebarElement, rebarGUID, ExporterCacheManager.OwnerHistoryHandle,
- copyLevelPlacement, prodRep, steelGrade, longitudinalBarNominalDiameter, longitudinalBarCrossSectionArea, barLength, role, null);
- IFCAnyHandleUtil.OverrideNameAttribute(elemHnd, rebarName);
- IFCExportInfoPair exportInfo = new IFCExportInfoPair(IFCEntityType.IfcReinforcingBar);
-
- // We will not add the element to the productWrapper here, but instead in the function that calls
- // ExportRebar. The reason for this is that we don't currently know if the handles such be associated
- // to the level or not, depending on whether they will or won't be grouped.
- createdRebars.Add(new DelayedProductWrapper(rebarElement, elemHnd, setter.LevelInfo, exportInfo));
-
- CacheSubelementParameterValues(rebarElement, rebarElementParams, ii, elemHnd);
-
- ExporterCacheManager.HandleToElementCache.Register(elemHnd, rebarElement.Id);
- CategoryUtil.CreateMaterialAssociation(exporterIFC, elemHnd, materialId);
-
- IFCAnyHandle typeHnd = ExporterUtil.CreateGenericTypeFromElement(rebarElement,
- exportInfo, file, productWrapper);
- if (!IFCAnyHandleUtil.IsNullOrHasNoValue(typeHnd))
+ if (!bExportAsSingleIFCEntity)
+ bodyItems = new HashSet() { sweptDiskSolid };
+ else
+ bodyItems.Add(sweptDiskSolid);
+
+ //for uniform sets we export only after we have all solids
+ if (!bExportAsSingleIFCEntity || (bExportAsSingleIFCEntity && bodyItems.Count == rebarQuantity))
{
- ExporterCacheManager.TypeRelationsCache.Add(typeHnd, elemHnd);
+ IFCAnyHandle contextOfItems = ExporterCacheManager.Get3DContextHandle(IFCRepresentationIdentifier.Body);
+ IFCAnyHandle shapeRep = RepresentationUtil.CreateAdvancedSweptSolidRep(exporterIFC,
+ rebarElement, categoryId, contextOfItems, bodyItems, null);
+ IList shapeReps = new List() { shapeRep };
+ prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps);
+
+ IFCAnyHandle copyLevelPlacement = (ii == 0 || bExportAsSingleIFCEntity) ? originalPlacement : ExporterUtil.CopyLocalPlacement(file, originalPlacement);
+
+ string rebarGUID = (indexForNamingAndGUID < maxBarGUIDS) ?
+ GUIDUtil.CreateSubElementGUID(rebarElement, indexForNamingAndGUID + (int)IFCReinforcingBarSubElements.BarStart - 1) :
+ GUIDUtil.GenerateIFCGuidFrom(
+ GUIDUtil.CreateGUIDString(rebarElement, indexForNamingAndGUID.ToString()));
+ IFCAnyHandle elemHnd = IFCInstanceExporter.CreateReinforcingBar(exporterIFC, rebarElement, rebarGUID, ExporterCacheManager.OwnerHistoryHandle,
+ copyLevelPlacement, prodRep, steelGrade, longitudinalBarNominalDiameter, longitudinalBarCrossSectionArea, barLength, role, null);
+ IFCAnyHandleUtil.OverrideNameAttribute(elemHnd, rebarName);
+ IFCExportInfoPair exportInfo = new IFCExportInfoPair(IFCEntityType.IfcReinforcingBar);
+
+ // We will not add the element to the productWrapper here, but instead in the function that calls
+ // ExportRebar. The reason for this is that we don't currently know if the handles such be associated
+ // to the level or not, depending on whether they will or won't be grouped.
+ createdRebars.Add(new DelayedProductWrapper(rebarElement, elemHnd, setter.LevelInfo, exportInfo));
+
+ CacheSubelementParameterValues(rebarElement, rebarElementParams, ii, elemHnd);
+
+ ExporterCacheManager.HandleToElementCache.Register(elemHnd, rebarElement.Id);
+ CategoryUtil.CreateMaterialAssociation(exporterIFC, elemHnd, materialId);
+
+ IFCAnyHandle typeHnd = ExporterUtil.CreateGenericTypeFromElement(rebarElement,
+ exportInfo, file, productWrapper);
+ if (!IFCAnyHandleUtil.IsNullOrHasNoValue(typeHnd))
+ {
+ ExporterCacheManager.TypeRelationsCache.Add(typeHnd, elemHnd);
+ }
}
}
}
diff --git a/Source/Revit.IFC.Export/Properties/AssemblyInfo.cs b/Source/Revit.IFC.Export/Properties/AssemblyInfo.cs
index 18a06945..066ccb6a 100644
--- a/Source/Revit.IFC.Export/Properties/AssemblyInfo.cs
+++ b/Source/Revit.IFC.Export/Properties/AssemblyInfo.cs
@@ -13,8 +13,8 @@
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-[assembly: AssemblyVersion("25.2.0.5")]
-[assembly: AssemblyFileVersion("25.2.0.5")]
+[assembly: AssemblyVersion("25.4.0.27")]
+[assembly: AssemblyFileVersion("25.4.0.27")]
// Version information can now be found in Source\Foundation\RevitENU\Version.cs
diff --git a/Source/Revit.IFC.Export/Utility/ElementFilteringUtil.cs b/Source/Revit.IFC.Export/Utility/ElementFilteringUtil.cs
index 26c0c9f1..c2331501 100644
--- a/Source/Revit.IFC.Export/Utility/ElementFilteringUtil.cs
+++ b/Source/Revit.IFC.Export/Utility/ElementFilteringUtil.cs
@@ -39,6 +39,43 @@ namespace Revit.IFC.Export.Utility
///
class ElementFilteringUtil
{
+ ///
+ /// Create the based export element collector used for filtering elements
+ ///
+ /// The document.
+ /// If false, don't use the filter view
+ /// even if it exists.
+ /// The FilteredElementCollector.
+ /// useFilterViewIfExists is intended to be false for cases
+ /// where we want to potentially export some invisible elements, such
+ /// as rooms in 3D views.
+ public static FilteredElementCollector GetExportElementCollector(
+ Document document, bool useFilterViewIfExists)
+ {
+ ExportOptionsCache exportOptionsCache = ExporterCacheManager.ExportOptionsCache;
+ ICollection idsToExport = exportOptionsCache.ElementsForExport;
+ if (idsToExport.Count > 0)
+ {
+ return new FilteredElementCollector(document, idsToExport);
+ }
+
+ View filterView = useFilterViewIfExists ?
+ exportOptionsCache.FilterViewForExport : null;
+
+ if (filterView == null)
+ {
+ return new FilteredElementCollector(document);
+ }
+
+ if (ExporterStateManager.CurrentLinkId != ElementId.InvalidElementId)
+ {
+ return new FilteredElementCollector(filterView.Document, filterView.Id,
+ ExporterStateManager.CurrentLinkId);
+ }
+
+ return new FilteredElementCollector(filterView.Document, filterView.Id);
+ }
+
///
/// Gets spatial element filter.
///
@@ -51,14 +88,29 @@ public static ElementFilter GetSpatialElementFilter(Document document, ExporterI
}
///
- /// Gets filter for non spatial elements.
+ /// Gets the filtered non-spatial elements.
///
/// The Revit document.
/// The ExporterIFC object.
/// The Element filter.
- public static ElementFilter GetNonSpatialElementFilter(Document document, ExporterIFC exporterIFC)
+ public static ISet GetNonSpatialElements(Document document, ExporterIFC exporterIFC)
{
- return GetExportFilter(document, exporterIFC, false);
+ ICollection nonSpatialElements;
+ if (ExporterCacheManager.ExportOptionsCache.ElementsForExport.Count > 0)
+ {
+ nonSpatialElements = ExporterCacheManager.ExportOptionsCache.ElementsForExport;
+ }
+ else
+ {
+ FilteredElementCollector otherElementCollector = GetExportElementCollector(document, true);
+ ElementFilter nonSpatialElementFilter = GetExportFilter(document, exporterIFC, false);
+ otherElementCollector.WherePasses(nonSpatialElementFilter);
+ nonSpatialElements = otherElementCollector.ToElementIds();
+ }
+
+ ExporterCacheManager.NonSpatialElements.UnionWith(nonSpatialElements);
+
+ return ExporterCacheManager.NonSpatialElements;
}
///
diff --git a/Source/Revit.IFC.Export/Utility/ExportOptionsCache.cs b/Source/Revit.IFC.Export/Utility/ExportOptionsCache.cs
index 7f1e68ff..ac7730e8 100644
--- a/Source/Revit.IFC.Export/Utility/ExportOptionsCache.cs
+++ b/Source/Revit.IFC.Export/Utility/ExportOptionsCache.cs
@@ -83,6 +83,8 @@ public IFCFileHeaderItem FileHeaderItem
///
public bool OwnerHistoryLastModified { get; private set; } = false;
+ public bool ExportBarsInUniformSetsAsSeparateIFCEntities { get; private set; } = false;
+
public KnownERNames ExchangeRequirement { get; set; } = KnownERNames.NotDefined;
public KnownFacilityTypes FacilityType { get; set; } = KnownFacilityTypes.Building;
@@ -273,6 +275,7 @@ public static ExportOptionsCache Create(ExporterIFC exporterIFC, View filterView
cache.ExportParts = (filterView != null && filterView.PartsVisibility == PartsVisibility.ShowPartsOnly);
cache.ExportPartsAsBuildingElementsOverride = null;
cache.ExportAnnotationsOverride = null;
+ cache.ExportCeilingGrids = false;
// We are going to default to "true" for IncludeSteelElements to allow the default API
// export to match the default UI.
@@ -365,6 +368,9 @@ public static ExportOptionsCache Create(ExporterIFC exporterIFC, View filterView
bool? ownerHistoryLastModified = OptionsUtil.GetNamedBooleanOption(options, "OwnerHistoryLastModified");
cache.OwnerHistoryLastModified = ownerHistoryLastModified.GetValueOrDefault(false);
+ bool? exportBarsInUniformSetsAsSeparateIFCEntities = OptionsUtil.GetNamedBooleanOption(options, "ExportBarsInUniformSetsAsSeparateIFCEntities");
+ cache.ExportBarsInUniformSetsAsSeparateIFCEntities = exportBarsInUniformSetsAsSeparateIFCEntities.GetValueOrDefault(false);
+
// "SingleElement" export option - useful for debugging - only one input element will be processed for export
if (options.TryGetValue("SingleElement", out string singleElementValue))
{
@@ -374,6 +380,14 @@ public static ExportOptionsCache Create(ExporterIFC exporterIFC, View filterView
ids.Add(elementId);
cache.ElementsForExport = ids;
}
+ else if (options.TryGetValue("SingleElementGeometry", out string singleElementGeometryValue))
+ {
+ ElementId elementId = ParseElementId(singleElementGeometryValue);
+
+ List ids = [elementId];
+ cache.ElementsForExport = ids;
+ cache.ExportGeometryOnly = true;
+ }
else if (options.TryGetValue("ElementsForExport", out string elementsToExportValue))
{
IList ids = ParseElementIds(elementsToExportValue);
@@ -387,6 +401,9 @@ public static ExportOptionsCache Create(ExporterIFC exporterIFC, View filterView
// "ExportAnnotations" override
cache.ExportAnnotationsOverride = OptionsUtil.GetNamedBooleanOption(options, "Export2DElements");
+ // "ExportAnnotations" override
+ cache.ExportCeilingGrids = OptionsUtil.GetNamedBooleanOption(options, "ExportCeilingGrids").GetValueOrDefault(false);
+
// "ExportSeparateParts" override
cache.ExportPartsAsBuildingElementsOverride = OptionsUtil.GetNamedBooleanOption(options, "ExportPartsAsBuildingElements");
@@ -816,11 +833,12 @@ public bool ExportAs2x3COBIE24DesignDeliverable
///
/// Cache variable for the export annotations override (if set independently via the UI or API inputs)
///
- private bool? ExportAnnotationsOverride
- {
- get;
- set;
- }
+ private bool? ExportAnnotationsOverride { get; set; } = null;
+
+ ///
+ /// Cache variable for the export ceiling grids override (if set independently via the UI or API inputs)
+ ///
+ public bool ExportCeilingGrids { get; set; } = false;
///
/// Identifies if the file version being exported supports annotations.
@@ -995,6 +1013,12 @@ public IList ElementsForExport
set;
}
+ ///
+ /// A bare-bones IFC export that include only BRep geometry, generally for
+ /// a specific set of elements.
+ ///
+ public bool ExportGeometryOnly { get; set; } = false;
+
///
/// The filter view for export.
///
diff --git a/Source/Revit.IFC.Export/Utility/ExporterCacheManager.cs b/Source/Revit.IFC.Export/Utility/ExporterCacheManager.cs
index 033718c8..22ee4102 100644
--- a/Source/Revit.IFC.Export/Utility/ExporterCacheManager.cs
+++ b/Source/Revit.IFC.Export/Utility/ExporterCacheManager.cs
@@ -168,6 +168,11 @@ public class ExporterCacheManager
///
static MEPCache m_MEPCache;
+ ///
+ /// Non-spatial Elements (e.g., Floor) for export.
+ ///
+ public static HashSet NonSpatialElements { get; private set; } = new();
+
static AttributeCache m_AttributeCache;
///
@@ -251,9 +256,20 @@ public static IFCAnyHandle Get3DContextHandle(IFCRepresentationIdentifier identi
if (Context3DHandles.TryGetValue(identifier, out IFCAnyHandle handle))
return handle;
- return null;
+ if (!Context3DHandles.TryGetValue(IFCRepresentationIdentifier.None, out IFCAnyHandle context3D))
+ return handle;
+
+ IFCGeometricProjection projection = (identifier == IFCRepresentationIdentifier.Axis) ?
+ IFCGeometricProjection.Graph_View : IFCGeometricProjection.Model_View;
+
+ IFCFile file = ExporterIFC.GetFile();
+ IFCAnyHandle context3DHandle = IFCInstanceExporter.CreateGeometricRepresentationSubContext(file,
+ identifier.ToString(), "Model", context3D, null, projection, null);
+ Set3DContextHandle(ExporterIFC, identifier, context3DHandle);
+ return context3DHandle;
}
+
///
/// Get the handle associated to a particular IfcGeometricRepresentationContext, or create it
/// if it doesn't exist.
@@ -524,6 +540,28 @@ public static IDictionary CanExportBeamGeometryAsExtrusionCache
}
}
+ private static bool? m_ExportCeilingGrids { get; set; } = null;
+
+ ///
+ /// Determines if we should export ceiling grids.
+ ///
+ /// True if the user has chosen to export ceiling grids and ceiling surface patterns are exported.
+ public static bool ExportCeilingGrids()
+ {
+ if (!ExportOptionsCache.ExportCeilingGrids)
+ {
+ return false;
+ }
+
+ if (!m_ExportCeilingGrids.HasValue)
+ {
+ m_ExportCeilingGrids = CategoryMappingTemplate?.GetMappingInfoById(Document,
+ new ElementId(BuiltInCategory.OST_CeilingsSurfacePattern), CustomSubCategoryId.None)?.IFCExportFlag ?? false;
+ }
+
+ return m_ExportCeilingGrids.Value;
+ }
+
public static IFCCategoryTemplate CategoryMappingTemplate
{
get
@@ -1540,6 +1578,7 @@ public static void Clear(bool fullClear)
ElementIdMaterialParameterCache.Clear();
m_ElementToHandleCache = null;
m_ElementTypeToHandleCache = null;
+ m_ExportCeilingGrids = null;
m_FabricAreaHandleCache = null;
m_FabricParamsCache = null;
m_FamilySymbolToTypeInfoCache = null;
@@ -1561,6 +1600,7 @@ public static void Clear(bool fullClear)
m_MaterialHandleCache = null;
MaterialRelationsCache = new MaterialRelationsCache();
m_MEPCache = null;
+ NonSpatialElements.Clear();
m_Object2DCurves = null;
m_PartExportedCache = null;
m_PresentationLayerSetCache = null;
diff --git a/Source/Revit.IFC.Export/Utility/ExporterUtil.cs b/Source/Revit.IFC.Export/Utility/ExporterUtil.cs
index f7acf557..3f818f4c 100644
--- a/Source/Revit.IFC.Export/Utility/ExporterUtil.cs
+++ b/Source/Revit.IFC.Export/Utility/ExporterUtil.cs
@@ -2040,6 +2040,9 @@ private static void ExportElementClassifications(ExporterIFC exporterIFC, Elemen
/// The ProductWrapper class that contains the associated IFC handles.
public static void ExportRelatedProperties(ExporterIFC exporterIFC, Element element, ProductWrapper productWrapper)
{
+ if (ExporterCacheManager.ExportOptionsCache.ExportGeometryOnly)
+ return;
+
ExportElementProperties(exporterIFC, element, productWrapper);
if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities && !(ExporterCacheManager.ExportOptionsCache.ExportAsCOBIE))
ExportElementQuantities(exporterIFC, element, productWrapper);
@@ -2941,10 +2944,10 @@ public static ElementId GetSingleMaterial(Element element)
/// Get Transform from an IfcLocalPlacement
///
/// Handle to the IfcLocalPlacement
+ /// If true, return the origin in Revit coordinates (feet). If false, in IFC coordinates.
/// Transform from the RelativePlacement attribute of the IfcLocalPlacement
- public static Transform GetTransformFromLocalPlacementHnd(IFCAnyHandle ecsHnd)
+ public static Transform GetTransformFromLocalPlacementHnd(IFCAnyHandle ecsHnd, bool unscaleOrigin)
{
- Transform ecsFromHnd = null;
if (!IFCAnyHandleUtil.IsTypeOf(ecsHnd, IFCEntityType.IfcLocalPlacement))
return null;
@@ -2967,29 +2970,29 @@ public static Transform GetTransformFromLocalPlacementHnd(IFCAnyHandle ecsHnd)
else
{
// Default Z-Direction
- zDirection = new XYZ(0.0, 0.0, 1.0);
+ zDirection = XYZ.BasisZ;
}
if (xDir != null)
{
IList xDirValues = IFCAnyHandleUtil.GetAggregateDoubleAttribute>(xDir, "DirectionRatios");
- xDirection = new XYZ(xDirValues[0], xDirValues[1], xDirValues[2]);
+ xDirection = new(xDirValues[0], xDirValues[1], xDirValues[2]);
}
else
{
// Default X-Direction
- xDirection = new XYZ(1.0, 0.0, 0.0);
+ xDirection = XYZ.BasisX;
}
XYZ yDirection = zDirection.CrossProduct(xDirection);
IList posCoords = IFCAnyHandleUtil.GetAggregateDoubleAttribute>(pos, "Coordinates");
- XYZ position = new XYZ(posCoords[0], posCoords[1], posCoords[2]);
+ XYZ position = new(posCoords[0], posCoords[1], posCoords[2]);
- ecsFromHnd = Transform.Identity;
+ Transform ecsFromHnd = Transform.Identity;
ecsFromHnd.BasisX = xDirection;
ecsFromHnd.BasisY = yDirection;
ecsFromHnd.BasisZ = zDirection;
- ecsFromHnd.Origin = position;
+ ecsFromHnd.Origin = unscaleOrigin ? UnitUtil.UnscaleLength(position) : position;
return ecsFromHnd;
}
@@ -3009,12 +3012,12 @@ public static Transform GetTotalTransformFromLocalPlacement(IFCAnyHandle localPl
if (!localPlacementHnd.IsTypeOf("IfcLocalPlacement"))
return totalTrf;
- totalTrf = GetTransformFromLocalPlacementHnd(localPlacementHnd);
+ totalTrf = GetTransformFromLocalPlacementHnd(localPlacementHnd, false);
IFCAnyHandle placementRelTo = IFCAnyHandleUtil.GetInstanceAttribute(localPlacementHnd, "PlacementRelTo");
while (!IFCAnyHandleUtil.IsNullOrHasNoValue(placementRelTo))
{
- Transform trf = GetTransformFromLocalPlacementHnd(placementRelTo);
+ Transform trf = GetTransformFromLocalPlacementHnd(placementRelTo, false);
if (trf == null)
return null; // the placementRelTo is not the type of IfcLocalPlacement, return null. We don't handle this
diff --git a/Source/Revit.IFC.Export/Utility/GeometryUtil.cs b/Source/Revit.IFC.Export/Utility/GeometryUtil.cs
index 7450fd51..50bb2e82 100644
--- a/Source/Revit.IFC.Export/Utility/GeometryUtil.cs
+++ b/Source/Revit.IFC.Export/Utility/GeometryUtil.cs
@@ -2183,9 +2183,11 @@ static IFCAnyHandle CreatePolyLineSegmentCommon(ExporterIFC exporterIFC, IListThe line handle.
public static IFCAnyHandle CreateLineSegment(ExporterIFC exporterIFC, Line line)
{
- List points = new List();
- points.Add(line.GetEndPoint(0));
- points.Add(line.GetEndPoint(1));
+ List points = new()
+ {
+ line.GetEndPoint(0),
+ line.GetEndPoint(1)
+ };
return CreatePolyLineSegmentCommon(exporterIFC, points);
}
diff --git a/Source/Revit.IFC.Export/Utility/IFCExportInfoPair.cs b/Source/Revit.IFC.Export/Utility/IFCExportInfoPair.cs
index 626a89b8..a3ee03d1 100644
--- a/Source/Revit.IFC.Export/Utility/IFCExportInfoPair.cs
+++ b/Source/Revit.IFC.Export/Utility/IFCExportInfoPair.cs
@@ -70,7 +70,7 @@ public string PredefinedType
// there are exceptions.
if (m_ExportType == IFCEntityType.UnKnown)
{
- newValidatedPredefinedType = IFCValidateEntry.GetValidIFCPredefinedType(value, IfcSchemaEntityTree.GetTypeNameFromInstanceName(m_ExportInstance.ToString()));
+ newValidatedPredefinedType = IFCValidateEntry.GetValidIFCPredefinedType(value, IfcSchemaEntityTree.GetTypeNameFromInstanceName(m_ExportInstance.ToString(), ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4));
}
else
{
@@ -324,7 +324,7 @@ public void SetByTypeName(string entityTypeName)
IList instNodes = IfcSchemaEntityTree.FindAllSuperTypes(ifcVersion, entityTypeName, "IfcProduct", "IfcGroup");
foreach (IfcSchemaEntityNode instNode in instNodes)
{
- typeName = IfcSchemaEntityTree.GetTypeNameFromInstanceName(instNode.Name);
+ typeName = IfcSchemaEntityTree.GetTypeNameFromInstanceName(instNode.Name, ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4);
IfcSchemaEntityNode node = theTree.Find(typeName);
if (node == null)
node = IfcSchemaEntityTree.FindNonAbsInstanceSuperType(ifcVersion, typeName);
diff --git a/Source/Revit.IFC.Export/Utility/PropertySetOptions.cs b/Source/Revit.IFC.Export/Utility/PropertySetOptions.cs
index 2e4cab63..aeb147fa 100644
--- a/Source/Revit.IFC.Export/Utility/PropertySetOptions.cs
+++ b/Source/Revit.IFC.Export/Utility/PropertySetOptions.cs
@@ -187,6 +187,8 @@ public string ExportUserDefinedPsetsFileName
protected set { m_ExportUserDefinedPsetsFileName = value; }
}
+ public bool UseTypePropertiesInInstacePSets { get; set; } = false;
+
///
/// Private default constructor.
///
@@ -222,6 +224,10 @@ public static PropertySetOptions Create(ExporterIFC exporterIFC, ExportOptionsCa
// "ExportUserDefinedPsets" override
propertySetOptions.ExportUserDefinedPsetsOverride = OptionsUtil.GetNamedBooleanOption(options, "ExportUserDefinedPsets");
+ // "UseTypePropertiesInInstacePSets"
+ propertySetOptions.UseTypePropertiesInInstacePSets =
+ OptionsUtil.GetNamedBooleanOption(options, "UseTypePropertiesInInstacePSets").GetValueOrDefault(false);
+
// "ExportUserDefinedPsetsFileName" override
propertySetOptions.ExportUserDefinedPsetsFileName = OptionsUtil.GetNamedStringOption(options, "ExportUserDefinedPsetsFileName");
diff --git a/Source/Revit.IFC.Export/Utility/RepresentationUtil.cs b/Source/Revit.IFC.Export/Utility/RepresentationUtil.cs
index 270a38be..ac7005af 100644
--- a/Source/Revit.IFC.Export/Utility/RepresentationUtil.cs
+++ b/Source/Revit.IFC.Export/Utility/RepresentationUtil.cs
@@ -557,12 +557,11 @@ public static IFCAnyHandle CreateAppropriateProductDefinitionShape(ExporterIFC e
GeometryElement geometryElement, BodyExporterOptions bodyExporterOptions, IList extraReps,
IFCExportBodyParams extrusionCreationData, bool allowOffsetTransform)
{
- BodyData bodyData;
BodyExporterOptions newBodyExporterOptions = new BodyExporterOptions(bodyExporterOptions);
newBodyExporterOptions.AllowOffsetTransform = allowOffsetTransform;
return CreateAppropriateProductDefinitionShape(exporterIFC, element, categoryId,
- geometryElement, newBodyExporterOptions, extraReps, extrusionCreationData, out bodyData);
+ geometryElement, newBodyExporterOptions, extraReps, extrusionCreationData, out _);
}
///
diff --git a/Source/Revit.IFC.Import.Core/Properties/AssemblyInfo.cs b/Source/Revit.IFC.Import.Core/Properties/AssemblyInfo.cs
index 959c17f2..7336569a 100644
--- a/Source/Revit.IFC.Import.Core/Properties/AssemblyInfo.cs
+++ b/Source/Revit.IFC.Import.Core/Properties/AssemblyInfo.cs
@@ -13,8 +13,8 @@
[assembly: AssemblyDescription("Revit.IFC.Import.Core")]
[assembly: AssemblyCompany("Autodesk")]
[assembly: AssemblyCopyright("@2012-2024 Autodesk, Inc. All rights reserved.")]
-[assembly: AssemblyVersion("25.2.0.5")]
-[assembly: AssemblyFileVersion("25.2.0.5")]
+[assembly: AssemblyVersion("25.4.0.27")]
+[assembly: AssemblyFileVersion("25.4.0.27")]
// Version information can now be found in Source\Foundation\RevitENU\Version.cs
//
diff --git a/Source/Revit.IFC.Import/Properties/AssemblyInfo.cs b/Source/Revit.IFC.Import/Properties/AssemblyInfo.cs
index f351ccce..7c05af6d 100644
--- a/Source/Revit.IFC.Import/Properties/AssemblyInfo.cs
+++ b/Source/Revit.IFC.Import/Properties/AssemblyInfo.cs
@@ -11,8 +11,8 @@
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-[assembly: AssemblyVersion("25.2.0.5")]
-[assembly: AssemblyFileVersion("25.2.0.5")]
+[assembly: AssemblyVersion("25.4.0.27")]
+[assembly: AssemblyFileVersion("25.4.0.27")]
diff --git a/VSProps/Revit.CSharp.Sdk.targets b/VSProps/Revit.CSharp.Sdk.targets
index 23a97a1b..ac3afefe 100644
--- a/VSProps/Revit.CSharp.Sdk.targets
+++ b/VSProps/Revit.CSharp.Sdk.targets
@@ -8,9 +8,6 @@
DEBUG;TRACE;$(DefineConstants)
-
- 7
- net8.0-windows