public IfcSceneExportSettings(IfcSceneExportSettings settings) { foreach (var prop in GetType().GetProperties()) { prop.SetValue(this, prop.GetValue(settings)); } }
private SceneModel CreateNew(IIfcProject p, IfcSceneExportSettings settings) { return(new SceneModel() { Name = p?.Name, Id = p?.GlobalId.ToGlobalUniqueId(), UnitsPerMeter = settings.UnitsPerMeter, Stamp = Timestamp.FromDateTime(DateTime.Now.ToUniversalTime()) }); }
internal IfcSceneExportSummary(IModel model, IfcSceneExportSettings settings) { Model = model; AppliedSettings = settings; Context = new SortedDictionary <int, Tuple <SceneContext, XbimMatrix3D> >(); ComponentCache = new Dictionary <int, Component>(); Scale = settings.UnitsPerMeter / model.ModelFactors.OneMeter; var p = model.Instances.OfType <IIfcProject>().First(); Scene = CreateNew(p, settings); var instanceContexts = settings.UserRepresentationContext.Select(c => new SceneContext { Name = c.Name, // Given in DEG => use as it is FDeflection = p.Model.ModelFactors.DeflectionAngle, // Given internally in model units => convert to meter FTolerance = model.ModelFactors.LengthToMetresConversionFactor * p.Model.ModelFactors.DeflectionTolerance, }).ToArray(); Scene.Contexts.AddRange(instanceContexts); settings.UserRepresentationContext = instanceContexts; }
// Runs the scene model export private IfcSceneExportSummary DoSceneModelTransfer(IModel model, IfcSceneExportSettings settings, CancelableProgressing progressing) { // Generate new summary var summary = new IfcSceneExportSummary(model, settings); // Transfer materials var materials = StylesToMaterial(model).ToDictionary(m => m.Id.Nid); summary.Scene.Materials.AddRange(materials.Values); Logger?.LogInformation("Starting model tesselation of {0}", model.Header.Name); // Retrieve enumeration of components having a geomety within given contexts var sceneRepresentations = TesselatorInstance.Tesselate(model, summary, progressing); Logger?.LogInformation("Starting model export of {0}", model.Header.Name); // Run transfer and log parents var parents = new HashSet <int>(); foreach (var sr in sceneRepresentations) { var p = model.Instances[sr.EntityLabel] as IIfcProduct; if (progressing?.State.IsAboutCancelling ?? false) { Logger?.LogInformation("Canceled model export of '{0}'", model.Header.FileName); progressing.State.MarkCanceled(); break; } Component c; if (!summary.ComponentCache.TryGetValue(p.EntityLabel, out c)) { int?optParent; c = CreateComponent(p, Enumerable.Empty <Classifier>(), out optParent); summary.ComponentCache.Add(p.EntityLabel, c); summary.Scene.Components.Add(c); if (optParent.HasValue) { parents.Add(optParent.Value); } } c.Representations.AddRange(sr.Representations); } // Check for remaining components (i.e. missing parents without geometry) parents.RemoveWhere(id => summary.ComponentCache.ContainsKey(id)); Queue <int> missingInstance = new Queue <int>(parents); while (missingInstance.Count > 0) { if (progressing?.State.IsAboutCancelling ?? false) { if (!progressing.State.IsCanceled) { Logger?.LogInformation("Canceled model export of '{0}'", model.Header.FileName); progressing.State.MarkCanceled(); } break; } if (model.Instances[missingInstance.Dequeue()] is IIfcProduct product) { Component c; if (!summary.ComponentCache.TryGetValue(product.EntityLabel, out c)) { int?optParent; c = CreateComponent(product, Enumerable.Empty <Classifier>(), out optParent); summary.ComponentCache.Add(product.EntityLabel, c); if (optParent.HasValue && !summary.ComponentCache.ContainsKey(optParent.Value)) { // Enqueue missing parents missingInstance.Enqueue(optParent.Value); } summary.Scene.Components.Add(c); } } } // Add default materials where required summary.Scene.Materials.AddRange( DefaultMaterials( model, summary.Scene.Components .SelectMany(c => c.Representations) .SelectMany(r => r.Bodies) .Select(b => b.Material) .Where(m => 0 > m.Nid) .Distinct() ) ); return(summary); }