Skip to content

Commit 25054b2

Browse files
authored
Merge pull request #595 from Autodesk/Unexected_error_22_6_1
Unexpected error 22 6 1
2 parents 2aabdc5 + 7c4d8bb commit 25054b2

File tree

1 file changed

+143
-66
lines changed

1 file changed

+143
-66
lines changed

Source/Revit.IFC.Export/Exporter/Exporter.cs

+143-66
Original file line numberDiff line numberDiff line change
@@ -4199,29 +4199,140 @@ private void CreateGlobalCartesianOrigin(ExporterIFC exporterIFC)
41994199
ExporterIFCUtils.SetGlobal2DOriginHandle(origin2d);
42004200
}
42014201

4202-
private HashSet<IFCAnyHandle> RemoveContainedHandlesFromSet(ICollection<IFCAnyHandle> initialSet)
4202+
private static bool ValidateContainedHandle(IFCAnyHandle initialHandle)
4203+
{
4204+
if (ExporterCacheManager.ElementsInAssembliesCache.Contains(initialHandle))
4205+
return false;
4206+
4207+
try
4208+
{
4209+
if (!IFCAnyHandleUtil.HasRelDecomposes(initialHandle))
4210+
return true;
4211+
}
4212+
catch
4213+
{
4214+
}
4215+
4216+
return false;
4217+
}
4218+
4219+
/// <summary>
4220+
/// Remove contained or invalid handles from this set.
4221+
/// </summary>
4222+
/// <param name="initialSet">The initial set that may have contained or invalid handles.</param>
4223+
/// <returns>A cleaned set.</returns>
4224+
public static HashSet<IFCAnyHandle> RemoveContainedHandlesFromSet(ICollection<IFCAnyHandle> initialSet)
42034225
{
42044226
HashSet<IFCAnyHandle> filteredSet = new HashSet<IFCAnyHandle>();
42054227

42064228
if (initialSet != null)
42074229
{
42084230
foreach (IFCAnyHandle initialHandle in initialSet)
42094231
{
4210-
if (ExporterCacheManager.ElementsInAssembliesCache.Contains(initialHandle))
4211-
continue;
4232+
if (ValidateContainedHandle(initialHandle))
4233+
filteredSet.Add(initialHandle);
4234+
}
4235+
}
42124236

4213-
try
4237+
return filteredSet;
4238+
}
4239+
4240+
private class IFCLevelExportInfo
4241+
{
4242+
public IFCLevelExportInfo() { }
4243+
4244+
public IDictionary<ElementId, IList<IFCLevelInfo>> LevelMapping { get; set; } =
4245+
new Dictionary<ElementId, IList<IFCLevelInfo>>();
4246+
4247+
public IList<IFCLevelInfo> OrphanedLevelInfos { get; set; } = new List<IFCLevelInfo>();
4248+
4249+
public void UnionLevelInfoRelated(ElementId toLevelId, IFCLevelInfo fromLevel)
4250+
{
4251+
if (fromLevel == null)
4252+
return;
4253+
4254+
if (toLevelId == ElementId.InvalidElementId)
4255+
{
4256+
OrphanedLevelInfos.Add(fromLevel);
4257+
return;
4258+
}
4259+
4260+
IList<IFCLevelInfo> levelMappingList;
4261+
if (!LevelMapping.TryGetValue(toLevelId, out levelMappingList))
4262+
{
4263+
levelMappingList = new List<IFCLevelInfo>();
4264+
LevelMapping[toLevelId] = levelMappingList;
4265+
}
4266+
levelMappingList.Add(fromLevel);
4267+
}
4268+
4269+
public void TransferOrphanedLevelInfo(ElementId toLevelId)
4270+
{
4271+
if (toLevelId == ElementId.InvalidElementId)
4272+
return;
4273+
4274+
if (OrphanedLevelInfos.Count == 0)
4275+
return;
4276+
4277+
IList<IFCLevelInfo> toLevelMappingList;
4278+
if (!LevelMapping.TryGetValue(toLevelId, out toLevelMappingList))
4279+
{
4280+
toLevelMappingList = new List<IFCLevelInfo>();
4281+
LevelMapping[toLevelId] = toLevelMappingList;
4282+
}
4283+
4284+
foreach (IFCLevelInfo orphanedLevelInfo in OrphanedLevelInfos)
4285+
{
4286+
toLevelMappingList.Add(orphanedLevelInfo);
4287+
}
4288+
OrphanedLevelInfos.Clear();
4289+
}
4290+
4291+
public Tuple<HashSet<IFCAnyHandle>, HashSet<IFCAnyHandle>> CollectValidHandlesForLevel(
4292+
ElementId levelId, IFCLevelInfo levelInfo)
4293+
{
4294+
if (levelId == ElementId.InvalidElementId || levelInfo == null)
4295+
return null;
4296+
4297+
HashSet<IFCAnyHandle> levelRelatedProducts = new HashSet<IFCAnyHandle>();
4298+
levelRelatedProducts.UnionWith(levelInfo.GetRelatedProducts());
4299+
4300+
HashSet<IFCAnyHandle> levelRelatedElements = new HashSet<IFCAnyHandle>();
4301+
levelRelatedElements.UnionWith(levelInfo.GetRelatedElements());
4302+
4303+
IList<IFCLevelInfo> levelMappingList;
4304+
if (LevelMapping.TryGetValue(levelId, out levelMappingList))
4305+
{
4306+
foreach (IFCLevelInfo containedLevelInfo in levelMappingList)
42144307
{
4215-
if (!IFCAnyHandleUtil.HasRelDecomposes(initialHandle))
4216-
filteredSet.Add(initialHandle);
4308+
if (containedLevelInfo != null)
4309+
{
4310+
levelRelatedProducts.UnionWith(containedLevelInfo.GetRelatedProducts());
4311+
levelRelatedElements.UnionWith(containedLevelInfo.GetRelatedElements());
4312+
}
42174313
}
4218-
catch
4314+
}
4315+
4316+
return Tuple.Create(RemoveContainedHandlesFromSet(levelRelatedProducts),
4317+
RemoveContainedHandlesFromSet(levelRelatedElements));
4318+
}
4319+
4320+
public HashSet<IFCAnyHandle> CollectOrphanedHandles()
4321+
{
4322+
HashSet<IFCAnyHandle> orphanedHandles = new HashSet<IFCAnyHandle>();
4323+
foreach (IFCLevelInfo containedLevelInfo in OrphanedLevelInfos)
4324+
{
4325+
if (containedLevelInfo != null)
42194326
{
4327+
orphanedHandles.UnionWith(containedLevelInfo.GetRelatedProducts());
4328+
orphanedHandles.UnionWith(containedLevelInfo.GetRelatedElements());
42204329
}
42214330
}
4222-
}
42234331

4224-
return filteredSet;
4332+
// RemoveContainedHandlesFromSet will be called before these are used, so
4333+
// don't bother doing it twice.
4334+
return orphanedHandles;
4335+
}
42254336
}
42264337

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

4349+
ElementId lastValidLevelId = ElementId.InvalidElementId;
4350+
IFCLevelExportInfo levelInfoMapping = new IFCLevelExportInfo();
4351+
42384352
for (int ii = 0; ii < levelIds.Count; ii++)
42394353
{
42404354
ElementId levelId = levelIds[ii];
42414355
IFCLevelInfo levelInfo = ExporterCacheManager.LevelInfoCache.GetLevelInfo(exporterIFC, levelId);
42424356
if (levelInfo == null)
42434357
continue;
42444358

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

4248-
ICollection<IFCAnyHandle> relatedProductsToCheck = levelInfo.GetRelatedProducts();
4249-
ICollection<IFCAnyHandle> relatedElementsToCheck = levelInfo.GetRelatedElements();
4250-
4251-
// get coincident levels, if any.
4252-
double currentElevation = levelInfo.Elevation;
4361+
levelInfoMapping.TransferOrphanedLevelInfo(levelId);
42534362
int nextLevelIdx = ii + 1;
4254-
for (int jj = ii + 1; jj < levelIds.Count; jj++, nextLevelIdx++)
4255-
{
4256-
ElementId nextLevelId = levelIds[jj];
4257-
IFCLevelInfo levelInfo2 = ExporterCacheManager.LevelInfoCache.GetLevelInfo(exporterIFC, nextLevelId);
4258-
if (levelInfo2 == null)
4259-
continue;
4260-
4261-
if (MathUtil.IsAlmostEqual(currentElevation, levelInfo2.Elevation))
4262-
{
4263-
foreach (IFCAnyHandle relatedProduct in levelInfo2.GetRelatedProducts())
4264-
relatedProductsToCheck.Add(relatedProduct);
4265-
4266-
foreach (IFCAnyHandle relatedElement in levelInfo2.GetRelatedElements())
4267-
relatedElementsToCheck.Add(relatedElement);
4268-
}
4269-
else
4270-
break;
4271-
}
42724363

42734364
// We may get stale handles in here; protect against this.
4274-
HashSet<IFCAnyHandle> relatedProducts = RemoveContainedHandlesFromSet(relatedProductsToCheck);
4275-
HashSet<IFCAnyHandle> relatedElements = RemoveContainedHandlesFromSet(relatedElementsToCheck);
4276-
4277-
// skip coincident levels, if any.
4278-
for (int jj = ii + 1; jj < nextLevelIdx; jj++)
4279-
{
4280-
ElementId nextLevelId = levelIds[jj];
4281-
IFCLevelInfo levelInfo2 = ExporterCacheManager.LevelInfoCache.GetLevelInfo(exporterIFC, nextLevelId);
4282-
if (levelInfo2 == null)
4283-
continue;
4365+
Tuple<HashSet<IFCAnyHandle>, HashSet<IFCAnyHandle>> productsAndElements =
4366+
levelInfoMapping.CollectValidHandlesForLevel(levelId, levelInfo);
42844367

4285-
if (!levelInfo.GetBuildingStorey().Equals(levelInfo2.GetBuildingStorey()))
4286-
IFCAnyHandleUtil.Delete(levelInfo2.GetBuildingStorey());
4287-
}
4288-
ii = nextLevelIdx - 1;
4368+
HashSet<IFCAnyHandle> relatedProducts = productsAndElements.Item1;
4369+
HashSet<IFCAnyHandle> relatedElements = productsAndElements.Item2;
42894370

4290-
if (relatedProducts.Count == 0 && relatedElements.Count == 0)
4291-
IFCAnyHandleUtil.Delete(levelInfo.GetBuildingStorey());
4292-
else
4371+
using (ProductWrapper productWrapper = ProductWrapper.Create(exporterIFC, false))
42934372
{
4294-
// We have decided to keep the level - export properties, quantities and classifications.
4295-
using (ProductWrapper productWrapper = ProductWrapper.Create(exporterIFC, false))
4373+
IFCAnyHandle buildingStoreyHandle = levelInfo.GetBuildingStorey();
4374+
if (!buildingStories.Contains(buildingStoreyHandle))
42964375
{
4297-
IFCAnyHandle buildingStoreyHandle = levelInfo.GetBuildingStorey();
42984376
buildingStories.Add(buildingStoreyHandle);
42994377
IFCExportInfoPair exportInfo = new IFCExportInfoPair(IFCEntityType.IfcBuildingStorey);
43004378

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

43084386
if (relatedProducts.Count > 0)
43094387
{
4310-
HashSet<IFCAnyHandle> buildingProducts = RemoveContainedHandlesFromSet(relatedProducts);
4311-
if (buildingProducts.Count > 0)
4312-
{
4313-
IFCAnyHandle buildingStorey = levelInfo.GetBuildingStorey();
4314-
string guid = GUIDUtil.CreateSubElementGUID(level, (int)IFCBuildingStoreySubElements.RelAggregates);
4315-
ExporterCacheManager.ContainmentCache.AddRelations(buildingStorey, guid, relatedProducts);
4316-
}
4388+
IFCAnyHandle buildingStorey = levelInfo.GetBuildingStorey();
4389+
string guid = GUIDUtil.CreateSubElementGUID(level, (int)IFCBuildingStoreySubElements.RelAggregates);
4390+
ExporterCacheManager.ContainmentCache.AddRelations(buildingStorey, guid, relatedProducts);
43174391
}
43184392

43194393
if (relatedElements.Count > 0)
43204394
{
4321-
HashSet<IFCAnyHandle> buildingElements = RemoveContainedHandlesFromSet(relatedElements);
4322-
if (buildingElements.Count > 0)
4323-
{
4324-
string guid = GUIDUtil.CreateSubElementGUID(level, (int)IFCBuildingStoreySubElements.RelContainedInSpatialStructure);
4325-
IFCInstanceExporter.CreateRelContainedInSpatialStructure(file, guid, ExporterCacheManager.OwnerHistoryHandle, null, null, buildingElements, levelInfo.GetBuildingStorey());
4326-
}
4395+
string guid = GUIDUtil.CreateSubElementGUID(level, (int)IFCBuildingStoreySubElements.RelContainedInSpatialStructure);
4396+
IFCInstanceExporter.CreateRelContainedInSpatialStructure(file, guid, ExporterCacheManager.OwnerHistoryHandle, null, null, relatedElements, levelInfo.GetBuildingStorey());
43274397
}
4398+
4399+
ii = nextLevelIdx - 1;
43284400
}
43294401

43304402
if (buildingStories.Count > 0)
@@ -4334,6 +4406,11 @@ private void RelateLevels(ExporterIFC exporterIFC, Document document)
43344406
string guid = GUIDUtil.CreateSubElementGUID(projectInfo, (int)IFCProjectSubElements.RelAggregatesBuildingStories);
43354407
ExporterCacheManager.ContainmentCache.AddRelations(buildingHnd, guid, buildingStories);
43364408
}
4409+
4410+
// We didn't find a level for this. Put it in the IfcBuilding, IfcSite, or IfcProject later.
4411+
HashSet<IFCAnyHandle> orphanedHandles = levelInfoMapping.CollectOrphanedHandles();
4412+
4413+
ExporterCacheManager.LevelInfoCache.OrphanedElements.UnionWith(orphanedHandles);
43374414
}
43384415

43394416
/// <summary>

0 commit comments

Comments
 (0)