diff --git a/Converters/Civil3d/Speckle.Converters.Civil3dShared/Helpers/DisplayValueExtractor.cs b/Converters/Civil3d/Speckle.Converters.Civil3dShared/Helpers/DisplayValueExtractor.cs index 2c3c2ebfb..495915200 100644 --- a/Converters/Civil3d/Speckle.Converters.Civil3dShared/Helpers/DisplayValueExtractor.cs +++ b/Converters/Civil3d/Speckle.Converters.Civil3dShared/Helpers/DisplayValueExtractor.cs @@ -32,7 +32,7 @@ IConverterSettingsStore converterSettings _converterSettings = converterSettings; } - public List? GetDisplayValue(CDB.Entity entity) + public IEnumerable GetDisplayValue(CDB.Entity entity) { switch (entity) { @@ -40,28 +40,32 @@ IConverterSettingsStore converterSettings SOG.Polyline featurelinePolyline = _pointCollectionConverter.Convert( featureline.GetPoints(Autodesk.Civil.FeatureLinePointType.PIPoint) ); - return new() { featurelinePolyline }; + yield return featurelinePolyline; + break; // pipe networks: https://help.autodesk.com/view/CIV3D/2025/ENU/?guid=ade47b62-debf-f899-9b94-5645a620ab4f case CDB.Part part: SOG.Mesh partMesh = _solidConverter.Convert(part.Solid3dBody); - return new() { partMesh }; + yield return partMesh; + break; // surfaces: https://help.autodesk.com/view/CIV3D/2025/ENU/?guid=d741aa49-e7da-9513-6b0b-226ebe3fa43f // POC: volume surfaces not supported case CDB.TinSurface tinSurface: SOG.Mesh tinSurfaceMesh = _tinSurfaceConverter.Convert(tinSurface); - return new() { tinSurfaceMesh }; + yield return tinSurfaceMesh; + break; case CDB.GridSurface gridSurface: SOG.Mesh gridSurfaceMesh = _gridSurfaceConverter.Convert(gridSurface); - return new() { gridSurfaceMesh }; + yield return gridSurfaceMesh; + break; // Corridors are complicated: their display values are extracted in the CorridorHandler when processing corridor children, since they are attached to the corridor subassemblies. case CDB.Corridor: - return new(); + yield break; default: - return null; + yield break; } } @@ -73,14 +77,13 @@ IConverterSettingsStore converterSettings /// List of simple curves: lines, polylines, and arcs. /// Null if no suitable display curves were found. /// - public List? ProcessICurvesForDisplay(List? iCurves) + public IEnumerable ProcessICurvesForDisplay(List? iCurves) { if (iCurves is null) { - return null; + yield break; } - List result = new(); foreach (ICurve curve in iCurves) { switch (curve) @@ -88,18 +91,16 @@ IConverterSettingsStore converterSettings case SOG.Line: case SOG.Polyline: case SOG.Arc: - result.Add((Base)curve); + yield return (Base)curve; break; case SOG.Polycurve polycurve: - List? processedSegments = ProcessICurvesForDisplay(polycurve.segments); - if (processedSegments is not null) + IEnumerable processedSegments = ProcessICurvesForDisplay(polycurve.segments); + foreach (Base processedSegment in processedSegments) { - result.AddRange(processedSegments); + yield return processedSegment; } break; } } - - return result.Count > 0 ? result : null; } } diff --git a/Converters/Civil3d/Speckle.Converters.Civil3dShared/ToSpeckle/BuiltElements/CivilEntityToSpeckleTopLevelConverter.cs b/Converters/Civil3d/Speckle.Converters.Civil3dShared/ToSpeckle/BuiltElements/CivilEntityToSpeckleTopLevelConverter.cs index 02df1472e..1960ea1b3 100644 --- a/Converters/Civil3d/Speckle.Converters.Civil3dShared/ToSpeckle/BuiltElements/CivilEntityToSpeckleTopLevelConverter.cs +++ b/Converters/Civil3d/Speckle.Converters.Civil3dShared/ToSpeckle/BuiltElements/CivilEntityToSpeckleTopLevelConverter.cs @@ -61,11 +61,14 @@ public Base Convert(CDB.Entity target) // extract display value. // If object has no display but has basecurves, use basecurves for display instead (for viewer selection) - List? display = - _displayValueExtractor.GetDisplayValue(target) ?? _displayValueExtractor.ProcessICurvesForDisplay(baseCurves); - if (display is not null) + List displayValue = _displayValueExtractor.GetDisplayValue(target).ToList(); + if (displayValue.Count == 0) { - civilObject["displayValue"] = display; + displayValue = _displayValueExtractor.ProcessICurvesForDisplay(baseCurves).ToList(); + } + if (displayValue.Count > 0) + { + civilObject["displayValue"] = displayValue; } // add any additional class properties @@ -80,60 +83,69 @@ public Base Convert(CDB.Entity target) // determine if this entity has any children elements that need to be converted. // this is a bespoke method by class type. - List? children = null; - switch (target) + var children = GetEntityChildren(target).ToList(); + if (children.Count > 0) + { + civilObject["elements"] = children; + } + + return civilObject; + } + + private IEnumerable GetEntityChildren(CDB.Entity entity) + { + switch (entity) { case CDB.Alignment alignment: - children = GetAlignmentChildren(alignment); + var alignmentChildren = GetAlignmentChildren(alignment); + foreach (var child in alignmentChildren) + { + yield return child; + } break; case CDB.Corridor corridor: - children = _corridorHandler.GetCorridorChildren(corridor); + var corridorChildren = _corridorHandler.GetCorridorChildren(corridor); + foreach (var child in corridorChildren) + { + yield return child; + } break; case CDB.Site site: - children = GetSiteChildren(site); + var siteChildren = GetSiteChildren(site).ToList(); + foreach (var child in siteChildren) + { + yield return child; + } break; } - - if (children is not null) - { - civilObject["elements"] = children; - } - - return civilObject; } - private List? GetSiteChildren(CDB.Site site) + private IEnumerable GetSiteChildren(CDB.Site site) { - List parcels = new(); using (var tr = _settingsStore.Current.Document.Database.TransactionManager.StartTransaction()) { foreach (ADB.ObjectId parcelId in site.GetParcelIds()) { var parcel = (CDB.Parcel)tr.GetObject(parcelId, ADB.OpenMode.ForRead); - parcels.Add(Convert(parcel)); + yield return Convert(parcel); } tr.Commit(); } - - return parcels.Count > 0 ? parcels : null; } - private List? GetAlignmentChildren(CDB.Alignment alignment) + private IEnumerable GetAlignmentChildren(CDB.Alignment alignment) { - List profiles = new(); using (var tr = _settingsStore.Current.Document.Database.TransactionManager.StartTransaction()) { foreach (ADB.ObjectId profileId in alignment.GetProfileIds()) { var profile = (CDB.Profile)tr.GetObject(profileId, ADB.OpenMode.ForRead); - profiles.Add(Convert(profile)); + yield return Convert(profile); } tr.Commit(); } - - return profiles.Count > 0 ? profiles : null; } }