Hi, i try to create a code to export rooms to individual ifc's. everthing works except that the exporter ifc's containing alle elemtns in the model and not only the elements in the 3dviews.
someone a idea?
using System;
using System.Collections.Generic;
using System.IO;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB.IFC;
using System.Linq;
using BIM.IFC.Export.UI;
namespace S3E.Export1
{
public class Create3DViewsHandler : IExternalEventHandler
{
public Document Doc { get; set; }
public List<Room> SelectedRooms { get; set; }
public string SelectedFolderPath { get; set; }
public void Execute(UIApplication app)
{
using (Transaction trans = new Transaction(Doc, "Maak 3D Views voor Geselecteerde Kamers"))
{
if (trans.Start() == TransactionStatus.Started)
{
ViewFamilyType viewFamilyType = new FilteredElementCollector(Doc)
.OfClass(typeof(ViewFamilyType))
.Cast<ViewFamilyType>()
.FirstOrDefault(x => x.ViewFamily == ViewFamily.ThreeDimensional);
foreach (Room room in SelectedRooms)
{
if (viewFamilyType != null)
{
string viewName = $"{room.Number} - {room.Name}";
var existingView = new FilteredElementCollector(Doc)
.OfClass(typeof(View3D))
.Cast<View3D>()
.FirstOrDefault(v => v.Name.Equals(viewName));
if (existingView == null)
{
BoundingBoxXYZ roomBox = room.get_BoundingBox(null);
if (roomBox != null)
{
View3D newView = View3D.CreateIsometric(Doc, viewFamilyType.Id);
newView.Name = viewName;
BoundingBoxXYZ adjustedBox = AdjustBoundingBox(roomBox);
newView.SetSectionBox(adjustedBox);
ExportToIFC(newView, viewName);
}
}
}
}
trans.Commit();
}
}
}
private BoundingBoxXYZ AdjustBoundingBox(BoundingBoxXYZ originalBox)
{
XYZ min = originalBox.Min - new XYZ(1, 1, 1);
XYZ max = originalBox.Max + new XYZ(1, 1, 1);
return new BoundingBoxXYZ { Min = min, Max = max };
}
private void ExportToIFC(View3D view, string viewName)
{
IFCExportConfiguration myIFCExportConfiguration = IFCExportConfiguration.CreateDefaultConfiguration();
myIFCExportConfiguration.VisibleElementsOfCurrentView = true;
myIFCExportConfiguration.UseActiveViewGeometry = true;
myIFCExportConfiguration.ExportRoomsInView = true;
IFCExportOptions exportOptions = new IFCExportOptions();
ElementId ExportViewId = view.Id;
myIFCExportConfiguration.UpdateOptions(exportOptions, ExportViewId);
string directoryPath = SelectedFolderPath;
Doc.Export(directoryPath, $"{viewName}.ifc", exportOptions);
}
public string GetName()
{
return "Create 3D Views and Export IFC Handler";
}
}
}
Solved! Go to Solution.
Solved by sven_schippers_92. Go to Solution.
For each room, you appear to create a new view. In each such view, you could hide all undesired elements before exporting by using the HideElements method or other similar API calls on the View class:
Thanks Jeremy,
I'm going to try this approach for now, I haven't had any luck with it yet, I'll keep you updated.
Hello everyone,
I managed to succeed by adopting a different approach in passing the view.iD to the exporter. Please see the accompanying code for this.
public class Create3DViewsHandler : IExternalEventHandler
{
private Document _doc;
private List<Room> _selectedRooms;
private string _selectedFolderPath;
public void Initialize(Document doc, List<Room> selectedRooms, string selectedFolderPath)
{
_doc = doc;
_selectedRooms = selectedRooms;
_selectedFolderPath = selectedFolderPath;
}
public void Execute(UIApplication app)
{
Create3DViewsForSelectedRooms();
var createdViewsInfo = Get3DViewIdsAndNames();
if (!createdViewsInfo.Any())
{
TaskDialog.Show("Fout", "Geen 3D-views aangemaakt of gevonden.");
return;
}
ShowCreatedViewIdsMessage(createdViewsInfo);
Export3DViewsToIFC(createdViewsInfo.Select(v => v.Id).ToList(), app);
}
private List<(ElementId Id, string Name)> Get3DViewIdsAndNames()
{
var viewInfo = new List<(ElementId, string)>();
var views = new FilteredElementCollector(_doc)
.OfClass(typeof(View3D))
.Cast<View3D>()
.Where(v => !v.IsTemplate && _selectedRooms.Any(r => v.Name.Contains(r.Number)))
.ToList();
foreach (var view in views)
{
viewInfo.Add((view.Id, view.Name));
}
return viewInfo;
}
private void ShowCreatedViewIdsMessage(List<(ElementId Id, string Name)> viewInfo)
{
string message = "Aangemaakte 3D Views:\n" + string.Join("\n", viewInfo.Select(vi => $"{vi.Name} (ID: {vi.Id})"));
TaskDialog.Show("Aangemaakte Views", message);
}
private void Create3DViewsForSelectedRooms()
{
if (!_selectedRooms.Any())
{
TaskDialog.Show("Fout", "Geen kamers geselecteerd.");
return;
}
using (Transaction trans = new Transaction(_doc, "Maak 3D Views voor Geselecteerde Kamers"))
{
trans.Start();
foreach (Room room in _selectedRooms)
{
string viewName = $"Kamer {room.Number} - {room.Name}";
if (!ViewNameExists(viewName))
{
Create3DView(room, viewName); // Aangeroepen binnen de transactie
}
}
trans.Commit();
}
}
private bool ViewNameExists(string viewName)
{
return new FilteredElementCollector(_doc)
.OfClass(typeof(View3D))
.Cast<View3D>()
.Any(v => v.Name.Equals(viewName));
}
private void Create3DView(Room room, string viewName)
{
ViewFamilyType viewFamilyType = new FilteredElementCollector(_doc)
.OfClass(typeof(ViewFamilyType))
.Cast<ViewFamilyType>()
.FirstOrDefault(x => x.ViewFamily == ViewFamily.ThreeDimensional);
if (viewFamilyType != null)
{
View3D newView = View3D.CreateIsometric(_doc, viewFamilyType.Id);
newView.Name = viewName;
BoundingBoxXYZ boundingBox = room.get_BoundingBox(null);
if (boundingBox != null)
{
// Vergroot de BoundingBox in de X- en Y-richting met 100mm
double extension = 0.35; // 100mm in meters
BoundingBoxXYZ expandedBoundingBox = new BoundingBoxXYZ
{
Min = new XYZ(boundingBox.Min.X - extension, boundingBox.Min.Y - extension, boundingBox.Min.Z),
Max = new XYZ(boundingBox.Max.X + extension, boundingBox.Max.Y + extension, boundingBox.Max.Z)
};
newView.SetSectionBox(expandedBoundingBox);
}
}
}
private List<ElementId> Get3DViewIds()
{
List<ElementId> viewIds = new List<ElementId>();
var views = new FilteredElementCollector(_doc)
.OfClass(typeof(View3D))
.Cast<View3D>()
.Where(v => !v.IsTemplate && _selectedRooms.Any(r => v.Name.Contains(r.Number)))
.ToList();
foreach (var view in views)
{
viewIds.Add(view.Id);
}
return viewIds;
}
private void ShowCreatedViewIdsMessage(List<ElementId> viewIds)
{
string message = "Aangemaakte 3D View IDs:\n" + string.Join("\n", viewIds.Select(id => id.ToString()));
TaskDialog.Show("Aangemaakte Views", message);
}
private void Export3DViewsToIFC(List<ElementId> viewIds, UIApplication uiApp)
{
Document doc = uiApp.ActiveUIDocument.Document;
IFCExportOptions ifcOptions = new IFCExportOptions();
ifcOptions.AddOption("ExportIFCCommonPropertySets", "true");
ifcOptions.AddOption("UseActiveViewGeometry", "true");
ifcOptions.AddOption("SplitWallsAndColumns", "true");
foreach (ElementId viewId in viewIds)
{
View3D view = doc.GetElement(viewId) as View3D;
if (view != null)
{
ifcOptions.AddOption("ActiveViewId", viewId.ToString());
ifcOptions.FilterViewId = viewId;
string fileName = $"{view.Name}.ifc";
string filePath = Path.Combine(_selectedFolderPath, fileName);
using (Transaction trans = new Transaction(doc, "Export IFC"))
{
trans.Start();
try
{
doc.Export(_selectedFolderPath, fileName, ifcOptions);
trans.Commit();
}
catch (Exception ex)
{
trans.RollBack();
TaskDialog.Show("Export Error", $"Failed to export view ID {viewId}: {ex.Message}");
}
}
}
else
{
TaskDialog.Show("Error", $"View with ID {viewId} could not be found.");
}
}
}
public string GetName()
{
return "Create and Export 3D Views";
}
}
}
@jeremy_tammik thx for the help!
Can't find what you're looking for? Ask the community or share your knowledge.