Beispiel #1
0
 public IfcSceneExportSettings(IfcSceneExportSettings settings)
 {
     foreach (var prop in GetType().GetProperties())
     {
         prop.SetValue(this, prop.GetValue(settings));
     }
 }
Beispiel #2
0
 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())
     });
 }
Beispiel #3
0
        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;
        }
Beispiel #4
0
        // 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);
        }