Skip to content

Commit

Permalink
Merge pull request #595 from Autodesk/Unexected_error_22_6_1
Browse files Browse the repository at this point in the history
Unexpected error 22 6 1
  • Loading branch information
WawanSolihin committed Feb 17, 2023
2 parents 2aabdc5 + 7c4d8bb commit 25054b2
Showing 1 changed file with 143 additions and 66 deletions.
209 changes: 143 additions & 66 deletions Source/Revit.IFC.Export/Exporter/Exporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4199,29 +4199,140 @@ private void CreateGlobalCartesianOrigin(ExporterIFC exporterIFC)
ExporterIFCUtils.SetGlobal2DOriginHandle(origin2d);
}

private HashSet<IFCAnyHandle> RemoveContainedHandlesFromSet(ICollection<IFCAnyHandle> initialSet)
private static bool ValidateContainedHandle(IFCAnyHandle initialHandle)
{
if (ExporterCacheManager.ElementsInAssembliesCache.Contains(initialHandle))
return false;

try
{
if (!IFCAnyHandleUtil.HasRelDecomposes(initialHandle))
return true;
}
catch
{
}

return false;
}

/// <summary>
/// Remove contained or invalid handles from this set.
/// </summary>
/// <param name="initialSet">The initial set that may have contained or invalid handles.</param>
/// <returns>A cleaned set.</returns>
public static HashSet<IFCAnyHandle> RemoveContainedHandlesFromSet(ICollection<IFCAnyHandle> initialSet)
{
HashSet<IFCAnyHandle> filteredSet = new HashSet<IFCAnyHandle>();

if (initialSet != null)
{
foreach (IFCAnyHandle initialHandle in initialSet)
{
if (ExporterCacheManager.ElementsInAssembliesCache.Contains(initialHandle))
continue;
if (ValidateContainedHandle(initialHandle))
filteredSet.Add(initialHandle);
}
}

try
return filteredSet;
}

private class IFCLevelExportInfo
{
public IFCLevelExportInfo() { }

public IDictionary<ElementId, IList<IFCLevelInfo>> LevelMapping { get; set; } =
new Dictionary<ElementId, IList<IFCLevelInfo>>();

public IList<IFCLevelInfo> OrphanedLevelInfos { get; set; } = new List<IFCLevelInfo>();

public void UnionLevelInfoRelated(ElementId toLevelId, IFCLevelInfo fromLevel)
{
if (fromLevel == null)
return;

if (toLevelId == ElementId.InvalidElementId)
{
OrphanedLevelInfos.Add(fromLevel);
return;
}

IList<IFCLevelInfo> levelMappingList;
if (!LevelMapping.TryGetValue(toLevelId, out levelMappingList))
{
levelMappingList = new List<IFCLevelInfo>();
LevelMapping[toLevelId] = levelMappingList;
}
levelMappingList.Add(fromLevel);
}

public void TransferOrphanedLevelInfo(ElementId toLevelId)
{
if (toLevelId == ElementId.InvalidElementId)
return;

if (OrphanedLevelInfos.Count == 0)
return;

IList<IFCLevelInfo> toLevelMappingList;
if (!LevelMapping.TryGetValue(toLevelId, out toLevelMappingList))
{
toLevelMappingList = new List<IFCLevelInfo>();
LevelMapping[toLevelId] = toLevelMappingList;
}

foreach (IFCLevelInfo orphanedLevelInfo in OrphanedLevelInfos)
{
toLevelMappingList.Add(orphanedLevelInfo);
}
OrphanedLevelInfos.Clear();
}

public Tuple<HashSet<IFCAnyHandle>, HashSet<IFCAnyHandle>> CollectValidHandlesForLevel(
ElementId levelId, IFCLevelInfo levelInfo)
{
if (levelId == ElementId.InvalidElementId || levelInfo == null)
return null;

HashSet<IFCAnyHandle> levelRelatedProducts = new HashSet<IFCAnyHandle>();
levelRelatedProducts.UnionWith(levelInfo.GetRelatedProducts());

HashSet<IFCAnyHandle> levelRelatedElements = new HashSet<IFCAnyHandle>();
levelRelatedElements.UnionWith(levelInfo.GetRelatedElements());

IList<IFCLevelInfo> levelMappingList;
if (LevelMapping.TryGetValue(levelId, out levelMappingList))
{
foreach (IFCLevelInfo containedLevelInfo in levelMappingList)
{
if (!IFCAnyHandleUtil.HasRelDecomposes(initialHandle))
filteredSet.Add(initialHandle);
if (containedLevelInfo != null)
{
levelRelatedProducts.UnionWith(containedLevelInfo.GetRelatedProducts());
levelRelatedElements.UnionWith(containedLevelInfo.GetRelatedElements());
}
}
catch
}

return Tuple.Create(RemoveContainedHandlesFromSet(levelRelatedProducts),
RemoveContainedHandlesFromSet(levelRelatedElements));
}

public HashSet<IFCAnyHandle> CollectOrphanedHandles()
{
HashSet<IFCAnyHandle> orphanedHandles = new HashSet<IFCAnyHandle>();
foreach (IFCLevelInfo containedLevelInfo in OrphanedLevelInfos)
{
if (containedLevelInfo != null)
{
orphanedHandles.UnionWith(containedLevelInfo.GetRelatedProducts());
orphanedHandles.UnionWith(containedLevelInfo.GetRelatedElements());
}
}
}

return filteredSet;
// RemoveContainedHandlesFromSet will be called before these are used, so
// don't bother doing it twice.
return orphanedHandles;
}
}

/// <summary>
Expand All @@ -4235,66 +4346,33 @@ private void RelateLevels(ExporterIFC exporterIFC, Document document)
IList<ElementId> levelIds = ExporterCacheManager.LevelInfoCache.LevelsByElevation;
IFCFile file = exporterIFC.GetFile();

ElementId lastValidLevelId = ElementId.InvalidElementId;
IFCLevelExportInfo levelInfoMapping = new IFCLevelExportInfo();

for (int ii = 0; ii < levelIds.Count; ii++)
{
ElementId levelId = levelIds[ii];
IFCLevelInfo levelInfo = ExporterCacheManager.LevelInfoCache.GetLevelInfo(exporterIFC, levelId);
if (levelInfo == null)
continue;

// remove products that are aggregated (e.g., railings in stairs).
Element level = document.GetElement(levelId);

ICollection<IFCAnyHandle> relatedProductsToCheck = levelInfo.GetRelatedProducts();
ICollection<IFCAnyHandle> relatedElementsToCheck = levelInfo.GetRelatedElements();

// get coincident levels, if any.
double currentElevation = levelInfo.Elevation;
levelInfoMapping.TransferOrphanedLevelInfo(levelId);
int nextLevelIdx = ii + 1;
for (int jj = ii + 1; jj < levelIds.Count; jj++, nextLevelIdx++)
{
ElementId nextLevelId = levelIds[jj];
IFCLevelInfo levelInfo2 = ExporterCacheManager.LevelInfoCache.GetLevelInfo(exporterIFC, nextLevelId);
if (levelInfo2 == null)
continue;

if (MathUtil.IsAlmostEqual(currentElevation, levelInfo2.Elevation))
{
foreach (IFCAnyHandle relatedProduct in levelInfo2.GetRelatedProducts())
relatedProductsToCheck.Add(relatedProduct);

foreach (IFCAnyHandle relatedElement in levelInfo2.GetRelatedElements())
relatedElementsToCheck.Add(relatedElement);
}
else
break;
}

// We may get stale handles in here; protect against this.
HashSet<IFCAnyHandle> relatedProducts = RemoveContainedHandlesFromSet(relatedProductsToCheck);
HashSet<IFCAnyHandle> relatedElements = RemoveContainedHandlesFromSet(relatedElementsToCheck);

// skip coincident levels, if any.
for (int jj = ii + 1; jj < nextLevelIdx; jj++)
{
ElementId nextLevelId = levelIds[jj];
IFCLevelInfo levelInfo2 = ExporterCacheManager.LevelInfoCache.GetLevelInfo(exporterIFC, nextLevelId);
if (levelInfo2 == null)
continue;
Tuple<HashSet<IFCAnyHandle>, HashSet<IFCAnyHandle>> productsAndElements =
levelInfoMapping.CollectValidHandlesForLevel(levelId, levelInfo);

if (!levelInfo.GetBuildingStorey().Equals(levelInfo2.GetBuildingStorey()))
IFCAnyHandleUtil.Delete(levelInfo2.GetBuildingStorey());
}
ii = nextLevelIdx - 1;
HashSet<IFCAnyHandle> relatedProducts = productsAndElements.Item1;
HashSet<IFCAnyHandle> relatedElements = productsAndElements.Item2;

if (relatedProducts.Count == 0 && relatedElements.Count == 0)
IFCAnyHandleUtil.Delete(levelInfo.GetBuildingStorey());
else
using (ProductWrapper productWrapper = ProductWrapper.Create(exporterIFC, false))
{
// We have decided to keep the level - export properties, quantities and classifications.
using (ProductWrapper productWrapper = ProductWrapper.Create(exporterIFC, false))
IFCAnyHandle buildingStoreyHandle = levelInfo.GetBuildingStorey();
if (!buildingStories.Contains(buildingStoreyHandle))
{
IFCAnyHandle buildingStoreyHandle = levelInfo.GetBuildingStorey();
buildingStories.Add(buildingStoreyHandle);
IFCExportInfoPair exportInfo = new IFCExportInfoPair(IFCEntityType.IfcBuildingStorey);

Expand All @@ -4307,24 +4385,18 @@ private void RelateLevels(ExporterIFC exporterIFC, Document document)

if (relatedProducts.Count > 0)
{
HashSet<IFCAnyHandle> buildingProducts = RemoveContainedHandlesFromSet(relatedProducts);
if (buildingProducts.Count > 0)
{
IFCAnyHandle buildingStorey = levelInfo.GetBuildingStorey();
string guid = GUIDUtil.CreateSubElementGUID(level, (int)IFCBuildingStoreySubElements.RelAggregates);
ExporterCacheManager.ContainmentCache.AddRelations(buildingStorey, guid, relatedProducts);
}
IFCAnyHandle buildingStorey = levelInfo.GetBuildingStorey();
string guid = GUIDUtil.CreateSubElementGUID(level, (int)IFCBuildingStoreySubElements.RelAggregates);
ExporterCacheManager.ContainmentCache.AddRelations(buildingStorey, guid, relatedProducts);
}

if (relatedElements.Count > 0)
{
HashSet<IFCAnyHandle> buildingElements = RemoveContainedHandlesFromSet(relatedElements);
if (buildingElements.Count > 0)
{
string guid = GUIDUtil.CreateSubElementGUID(level, (int)IFCBuildingStoreySubElements.RelContainedInSpatialStructure);
IFCInstanceExporter.CreateRelContainedInSpatialStructure(file, guid, ExporterCacheManager.OwnerHistoryHandle, null, null, buildingElements, levelInfo.GetBuildingStorey());
}
string guid = GUIDUtil.CreateSubElementGUID(level, (int)IFCBuildingStoreySubElements.RelContainedInSpatialStructure);
IFCInstanceExporter.CreateRelContainedInSpatialStructure(file, guid, ExporterCacheManager.OwnerHistoryHandle, null, null, relatedElements, levelInfo.GetBuildingStorey());
}

ii = nextLevelIdx - 1;
}

if (buildingStories.Count > 0)
Expand All @@ -4334,6 +4406,11 @@ private void RelateLevels(ExporterIFC exporterIFC, Document document)
string guid = GUIDUtil.CreateSubElementGUID(projectInfo, (int)IFCProjectSubElements.RelAggregatesBuildingStories);
ExporterCacheManager.ContainmentCache.AddRelations(buildingHnd, guid, buildingStories);
}

// We didn't find a level for this. Put it in the IfcBuilding, IfcSite, or IfcProject later.
HashSet<IFCAnyHandle> orphanedHandles = levelInfoMapping.CollectOrphanedHandles();

ExporterCacheManager.LevelInfoCache.OrphanedElements.UnionWith(orphanedHandles);
}

/// <summary>
Expand Down

0 comments on commit 25054b2

Please sign in to comment.