Beispiel #1
0
        protected TransformResult.Code DoTransform(T package, CancelableProgressing progress)
        {
            foreach (var instance in package.Source.Instances)
            {
                if (progress?.State.IsAboutCancelling ?? false)
                {
                    return(TransformResult.Code.Canceled);
                }

                switch (PassInstance(instance, package))
                {
                case TransformActionType.Copy:
                    Copy(instance, package, false, progress);
                    break;

                case TransformActionType.CopyWithInverse:
                    Copy(instance, package, true, progress);
                    break;

                case TransformActionType.Delegate:
                    DelegateCopy(instance, package, progress);
                    break;

                case TransformActionType.Drop:
                    package.Log?.Add(new TransformLogEntry(new XbimInstanceHandle(instance), TransformAction.NotTransferred));
                    break;
                }

                progress?.NotifyOnProgressChange(1, Name);
            }
            return(TransformResult.Code.Finished);
        }
Beispiel #2
0
        public async Task RemoveByName()
        {
            IfcStore.ModelProviderFactory.UseMemoryModelProvider();
            using (var source = IfcStore.Open(@"Resources\Ifc4-Storey-With-4Walls.ifc"))
            {
                var stampBefore = SchemaValidator.OfModel(source);
                Assert.IsTrue(stampBefore.IsCompliantToSchema);

                Assert.AreEqual(4, source.Instances
                                .OfType <IIfcPropertySet>()
                                .Where(s => s.Name == "AllplanAttributes")
                                .Count());

                var request = new IfcPropertySetRemovalRequest(this.TestLoggerFactory)
                {
                    ExludePropertySetByName     = new string[] { "AllplanAttributes" },
                    IsNameMatchingCaseSensitive = false,
                    // Common config
                    IsLogEnabled      = true,
                    TargetStoreType   = Xbim.IO.XbimStoreType.InMemoryModel,
                    EditorCredentials = EditorCredentials
                };

                var cp = new CancelableProgressing(true);
                cp.OnProgressChange += (sender, e) => TestLogger.LogDebug($"State {e.State}: Percentage = {e.Percentage}; State object = {e.StateObject}");

                using (var result = await request.Run(source, cp))
                {
                    if (null != result.Cause)
                    {
                        TestLogger?.LogError("Exception: {0}, {1}, {2}", result.Cause, result.Cause.Message, result.Cause.StackTrace);
                    }

                    Assert.AreEqual(TransformResult.Code.Finished, result.ResultCode);
                    Assert.AreEqual(0, result.Target.Instances
                                    .OfType <IIfcPropertySet>()
                                    .Where(s => s.Name == "AllplanAttributes")
                                    .Count());

                    var pset = result.Target.Instances
                               .OfType <IIfcPropertySet>()
                               .Where(s => s.Name == "AllplanAttributes Copy")
                               .ToArray();

                    Assert.AreEqual(4, pset.Length);
                    Assert.IsTrue(pset.All(p => p.Properties <IIfcProperty>().Count() == 3));

                    var stampAfter = SchemaValidator.OfModel(result.Target);
                    Assert.IsTrue(stampAfter.IsCompliantToSchema);

                    Assert.IsTrue(cp.State.State.HasFlag(ProgressTokenState.IsTerminated));

                    result.Target.SaveAsIfc(new FileStream("Ifc4-Storey-With-4Walls-AllplanAttributes-Copy-1.ifc", FileMode.Create));
                }
            }
        }
Beispiel #3
0
 private TransformResult CreateResultFromCode(TransformResult.Code code, CancelableProgressing cp)
 {
     if (cp?.State.IsAboutCancelling ?? false)
     {
         cp.State.MarkCanceled();
     }
     if (cp?.State.HasErrors ?? false)
     {
         cp.State.MarkBroken();
     }
     return(new TransformResult(code));
 }
Beispiel #4
0
        protected Func <TransformResult> FastForward(IModel source, CancelableProgressing progress)
        {
            if (!progress?.State.IsAlive ?? false)
            {
                throw new NotSupportedException($"Progress monitor already terminated.");
            }

            return(() =>
            {
                progress?.State.MarkTerminated();
                progress?.NotifyOnProgressEnd($"Running fast forward '{Name}' model copy ...");
                return new TransformResult(TransformResult.Code.Finished, CreateTransformPackage(source, source));
            });
        }
Beispiel #5
0
        public async Task KeepOrRemoveByName()
        {
            IfcStore.ModelProviderFactory.UseMemoryModelProvider();
            using (var source = IfcStore.Open(@"Resources\Ifc4-SampleHouse.ifc"))
            {
                var stampBefore = SchemaValidator.OfModel(source);
                Assert.IsTrue(stampBefore.IsCompliantToSchema);

                var request = new IfcPropertySetRemovalRequest(this.TestLoggerFactory)
                {
                    ExludePropertySetByName     = new string[] { "Other" },
                    IncludePropertySetByName    = new string[] { "Pset_SpaceCommon", "Other" },
                    IsNameMatchingCaseSensitive = false,
                    FilterRuleStrategy          = FilterRuleStrategyType.ExcludeBeforeInclude,
                    // Common config
                    IsLogEnabled      = true,
                    TargetStoreType   = Xbim.IO.XbimStoreType.InMemoryModel,
                    EditorCredentials = EditorCredentials
                };

                var cp = new CancelableProgressing(true);
                cp.OnProgressChange += (sender, e) => TestLogger.LogDebug($"State {e.State}: Percentage = {e.Percentage}; State object = {e.StateObject}");

                using (var result = await request.Run(source, cp))
                {
                    if (null != result.Cause)
                    {
                        TestLogger?.LogError("Exception: {0}, {1}, {2}", result.Cause, result.Cause.Message, result.Cause.StackTrace);
                    }

                    var psetsRemaining = result.Target.Instances
                                         .OfType <IIfcPropertySet>()
                                         .Select(s => s.Name.ToString())
                                         .Distinct()
                                         .ToArray();

                    Assert.AreEqual(TransformResult.Code.Finished, result.ResultCode);
                    Assert.AreEqual(1, psetsRemaining.Length);
                    Assert.IsTrue(string.Equals("Pset_SpaceCommon", psetsRemaining[0], StringComparison.OrdinalIgnoreCase));

                    var stampAfter = SchemaValidator.OfModel(result.Target);

                    Assert.IsTrue(stampAfter.IsCompliantToSchema);
                    Assert.IsTrue(cp.State.State.HasFlag(ProgressTokenState.IsTerminated));

                    result.Target.SaveAsIfc(new FileStream("Ifc4-SampleHouse-Pset_SpaceCommon-Other.ifc", FileMode.Create));
                }
            }
        }
Beispiel #6
0
        public async Task OffsetShiftAndRotateTest2_New()
        {
            IfcStore.ModelProviderFactory.UseMemoryModelProvider();
            using (var source = IfcStore.Open(@"Resources\Ifc4-SampleHouse.ifc"))
            {
                var stampBefore = SchemaValidator.OfModel(source);

                var testConfig = IfcAxisAlignment.LoadFromFile(@"Resources\IfcAlignmentTestAxis2.xml");
                Assert.IsNotNull(testConfig);
                Assert.IsNotNull(testConfig.SourceReferenceAxis);
                Assert.IsNotNull(testConfig.TargetReferenceAxis);

                var request = new IfcPlacementTransformRequest(this.TestLoggerFactory)
                {
                    AxisAlignment     = testConfig,
                    PlacementStrategy = IfcPlacementStrategy.NewRootPlacement,
                    // Common config
                    IsLogEnabled      = true,
                    TargetStoreType   = Xbim.IO.XbimStoreType.InMemoryModel,
                    EditorCredentials = EditorCredentials
                };

                using (var cp = new CancelableProgressing(true))
                {
                    cp.OnProgressChange += (s, o) => TestLogger.LogDebug($"State {o.State}: Percentage = {o.Percentage}; State object = {o.StateObject}");

                    using (var result = await request.Run(source, cp))
                    {
                        if (null != result.Cause)
                        {
                            TestLogger?.LogError("Exception: {0}, {1}, {2}", result.Cause, result.Cause.Message, result.Cause.StackTrace);
                        }

                        var rootPlacement = result.Target.Instances.OfType <IIfcLocalPlacement>().Where(i => i.PlacementRelTo == null).FirstOrDefault();
                        Assert.IsNotNull(rootPlacement.PlacesObject);
                        Assert.IsFalse(rootPlacement.PlacesObject.Any(), "Root has no objects");

                        //Assert.AreEqual(TransformResult.Code.Finished, result.ResultCode);
                        // TODO Specific tests

                        var stampAfter = SchemaValidator.OfModel(result.Target);
                        //Assert.AreEqual(stampBefore, stampAfter);

                        result.Target.SaveAsIfc(new FileStream("Ifc4-SampleHouse-Transformed.ifc", FileMode.Create));
                    }
                }
            }
        }
Beispiel #7
0
 /// <summary>
 /// Runs the model transformation.
 /// </summary>
 /// <param name="model">The IFC model</param>
 /// <returns>A scene</returns>
 public Task <IfcSceneExportSummary> Run(IModel model, CancelableProgressing monitor)
 {
     return(Task.Run(() =>
     {
         try
         {
             return DoSceneModelTransfer(model, new IfcSceneExportSettings(Settings), monitor);
         }
         catch (Exception e)
         {
             monitor?.State.MarkBroken();
             Logger.LogError("{0}: {1} [{2}]", e.GetType().Name, e.Message, e.StackTrace);
             return new IfcSceneExportSummary(model, Settings)
             {
                 FailureReason = e
             };
         }
     }));
 }
Beispiel #8
0
        internal void Prepare(CancelableProgressing cancelableProgress)
        {
            PlacementTree = new XbimPlacementTree(Source, false);
            SourceRootPlacementsLabels = Source.Instances
                                         .OfType <IIfcLocalPlacement>()
                                         .Where(p => p.PlacementRelTo == null).Select(p => p.EntityLabel).ToArray();
            Array.Sort(SourceRootPlacementsLabels);

            switch (AppliedPlacementStrategy)
            {
            case IfcPlacementStrategy.NewRootPlacement:
                if (Source.SchemaVersion == Xbim.Common.Step21.XbimSchemaVersion.Ifc2X3)
                {
                    throw new NotSupportedException("IFC2x3 doesn't support new placements without object context. Consider using 'IfcPlacementStrategy.ChangeRootPlacements'");
                }
                // Shift is absorbed by new placement
                SingletonShift = XbimVector3D.Zero;
                break;

            case IfcPlacementStrategy.ChangeRootPlacements:
                if (SourceRootPlacementsLabels.Length > 1)
                {       // Mean, if more than one
                    var entireTranslation = SourceRootPlacementsLabels.Select(l => PlacementTree[l].Translation).Aggregate((a, b) => a + b);
                    SingletonShift = entireTranslation * (1.0 / SourceRootPlacementsLabels.Length);
                }
                else
                {       // Precise offset of singleton root
                    SingletonShift = PlacementTree[SourceRootPlacementsLabels[0]].Translation;
                }

                AppliedAxisAlignment.SourceReferenceAxis.Translate(SingletonShift, -UnitsPerMeterSource);

                break;

            default:
                throw new NotImplementedException($"Missing '{AppliedPlacementStrategy}'");
            }
        }
Beispiel #9
0
        private async Task TestIfcModelExport(string fileName, IfcSceneExportSettings settings)
        {
            IfcSceneExportSummary result;

            using (var store = IfcStore.Open(fileName))
            {
                var exporter = new IfcSceneExporter(new XbimTesselationContext(TestLoggerFactory), TestLoggerFactory);
                exporter.Settings = settings;

                using (var monitor = new CancelableProgressing(true))
                {
                    result = await exporter.Run(store, monitor);
                }
            }

            Assert.IsNotNull(result, "Result exists");
            Assert.IsTrue(result.ComponentCache.Count > 0, "There are exported components");
            Assert.IsTrue(result.ComponentCache.Values
                          .All(c => c.Representations.SelectMany(r => r.Bodies).All(b => b.Faces.Count > 0)), "All bodies have faces");
            // Show default values too
            var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true));

            using (var jsonStream = File.CreateText($"{Path.GetFileNameWithoutExtension(fileName)}.json"))
            {
                var json = formatter.Format(result.Scene);
                jsonStream.WriteLine(json);
                jsonStream.Close();
                TestLogger.LogInformation($"JSON example has been written.");
            }

            using (var binStream = File.Create($"{Path.GetFileNameWithoutExtension(fileName)}.scene"))
            {
                var binScene = result.Scene.ToByteArray();
                binStream.Write(binScene, 0, binScene.Length);
                TestLogger.LogInformation($"Binary scene of {binScene.Length} bytes has been written.");
            }
        }
Beispiel #10
0
        protected IfcStore CreateTargetModel(IModel sourcePattern, CancelableProgressing progress)
        {
            var storeType = TargetStoreType ?? DetectStorageType(sourcePattern);

            progress?.NotifyOnProgressChange($"Starting '{Name}' with '{storeType}' model implementation ...");
            IfcStore target;

            if (null == EditorCredentials)
            {
                target = IfcStore.Create(sourcePattern.SchemaVersion, storeType);
            }
            else
            {
                target = IfcStore.Create(EditorCredentials, sourcePattern.SchemaVersion, storeType);
            }

            // Set model factors
            target.ModelFactors.Initialise(
                sourcePattern.ModelFactors.AngleToRadiansConversionFactor,
                sourcePattern.ModelFactors.LengthToMetresConversionFactor,
                sourcePattern.ModelFactors.Precision);

            return(target);
        }
Beispiel #11
0
 /// <summary>
 /// Creates a new transformation task and starts it.
 /// </summary>
 /// <param name="aSource">The source model</param>
 /// <param name="progressReceiver">The progress receiver</param>
 /// <returns></returns>
 public Task <TransformResult> Run(IModel aSource, CancelableProgressing cancelableProgressing)
 {
     cancelableProgressing?.NotifyProgressEstimateChange(aSource.Instances.Count);
     return(Task.Run(PrepareInternally(aSource, cancelableProgressing)));
 }
Beispiel #12
0
        /// <summary>
        /// Runs tessselation with Xbim scene context
        /// </summary>
        /// <param name="model">The model to be exported</param>
        /// <param name="summary">The scene export summary</param>
        /// <param name="monitor">The progress emitter instance</param>
        /// <returns>An enumerable of tesselated product representations</returns>
        public IEnumerable <IfcProductSceneRepresentation> Tesselate(IModel model, IfcSceneExportSummary summary, CancelableProgressing monitor)
        {
            ReadGeometryStore(model, monitor);

            short[] excludeTypeId = ExcludeExpressType.Select(t => model.Metadata.ExpressTypeId(t.ExpressName)).ToArray();
            Array.Sort(excludeTypeId);

            // Start reading the geometry store built before
            using (var gReader = model.GeometryStore.BeginRead())
            {
                int totalCount   = gReader.ShapeGeometries.Count();
                int currentCount = 0;
                // Product label vs. Component and candidate shape labels
                var packageCache = new SortedDictionary <int, TesselationPackage>();
                // Compute contexts
                ComputeContextTransforms(gReader, summary, ContextsCreateFromSettings(gReader, summary));

                monitor?.NotifyProgressEstimateUpdate(totalCount);

                foreach (var geometry in gReader.ShapeGeometries)
                {
                    if (monitor?.State.IsAboutCancelling ?? false)
                    {
                        monitor.State.MarkCanceled();
                        break;
                    }

                    currentCount++;

                    monitor?.State.UpdateDone(currentCount, "Running tesselation...");
                    monitor?.NotifyOnProgressChange();

                    if (geometry.ShapeData.Length <= 0)
                    {
                        // No geometry
                        continue;
                    }

                    var shapes = gReader.ShapeInstancesOfGeometry(geometry.ShapeLabel)
                                 .Where(i => 0 > Array.BinarySearch(excludeTypeId, i.IfcTypeId) &&
                                        i.RepresentationType == XbimGeometryRepresentationType.OpeningsAndAdditionsIncluded);

                    if (!shapes.Any())
                    {
                        // No shape instances
                        continue;
                    }

                    using (var ms = new MemoryStream(((IXbimShapeGeometryData)geometry).ShapeData))
                    {
                        using (var br = new BinaryReader(ms))
                        {
                            XbimShapeTriangulation tr = br.ReadShapeTriangulation();
                            foreach (XbimShapeInstance shape in shapes)
                            {
                                if (monitor?.State.IsAboutCancelling ?? false)
                                {
                                    monitor.State.MarkCanceled();
                                    break;
                                }

                                var product = model.Instances[shape.IfcProductLabel] as IIfcProduct;

                                // Try first to find the referenced component
                                TesselationPackage pkg;
                                if (!packageCache.TryGetValue(shape.IfcProductLabel, out pkg))
                                {
                                    // New component ToDo shape tuple built from component and todo ShapeGeometryLabel
                                    pkg = new TesselationPackage(gReader.ShapeInstancesOfEntity(product));
                                    packageCache[shape.IfcProductLabel] = pkg;
                                }

                                var ctx = summary.ContextOf(shape.RepresentationContext);
                                if (null == ctx)
                                {
                                    Logger?.LogWarning($"Shape of representation #{shape.RepresentationContext} of product #{product.EntityLabel} out of context scope. Skipped.");
                                    continue;
                                }

                                // Check for representation
                                var representation = GetOrCreateRepresentation(summary, shape, pkg);

                                if (!pkg.IsShapeGeometryDone(geometry))
                                {
                                    AppendVertices(representation, summary, tr.Vertices);
                                }

                                // TODO Use "bias" definition to adjust biased local offsets
                                var body = new FaceBody
                                {
                                    Material = new RefId {
                                        Nid = shape.StyleLabel > 0 ? shape.StyleLabel : shape.IfcTypeId * -1
                                    },
                                    Transform = CreateTransform(summary, shape),
                                    PtSet     = (uint)representation.Points.Count - 1,
                                };

                                foreach (var face in tr.Faces)
                                {
                                    if (face.Indices.Count % 3 != 0)
                                    {
                                        throw new NotSupportedException("Expecting triangular meshes only");
                                    }

                                    // Translate Xbim face definition
                                    var bodyFace = new Face
                                    {
                                        IsPlanar = face.IsPlanar,
                                        Mesh     = new Mesh
                                        {
                                            Type   = FacetType.TriMesh,
                                            Orient = Orientation.Ccw
                                        }
                                    };

                                    switch (face.NormalCount)
                                    {
                                    case 0:
                                        // No normals at all
                                        break;

                                    case 1:
                                        // Single normal
                                        bodyFace.IsPlanar = true;
                                        face.Normals[0].Normal.AppendTo(bodyFace.Mesh.Normal);
                                        break;

                                    default:
                                        // No planar face
                                        if (face.NormalCount != face.Indices.Count)
                                        {
                                            throw new NotSupportedException($"Incorrect count of normals per face mesh (expecting {face.Indices.Count}, have {face.NormalCount}");
                                        }

                                        foreach (var n in face.Normals.Select(n => n.Normal))
                                        {
                                            n.AppendTo(bodyFace.Mesh.Normal);
                                        }

                                        break;
                                    }

                                    bodyFace.Mesh.Vertex.AddRange(face.Indices.Select(i => (uint)i));
                                    body.Faces.Add(bodyFace);
                                }

                                // Add body to known component
                                representation.Bodies.Add(body);
                                // Remove geometry label from todo list
                                pkg.RemoveDone(shape);

                                // If no shape instances left
                                if (pkg.IsDone)
                                {
                                    yield return(pkg.ToSceneRepresentation(shape.IfcProductLabel));

                                    packageCache.Remove(shape.IfcProductLabel);
                                }
                            }
                        }
                    }
                }

                // Return most recent
                if (packageCache.Count > 0)
                {
                    Logger?.LogWarning($"Detected {packageCache.Count} unfinished geometry entries. Missing shapes.");
                    foreach (var e in packageCache)
                    {
                        // Announce missing components even if unfinished due to some reason
                        Logger?.LogWarning($"IfcProduct #{e.Key} misses {e.Value.CountOpenInstances} shape(s).");
                        yield return(e.Value.ToSceneRepresentation(e.Key));
                    }
                }
            }

            monitor?.NotifyOnProgressChange("Done tesselation.");
        }
Beispiel #13
0
        /// <summary>
        /// Reads the geometry from model if empty.
        /// </summary>
        /// <param name="model">The model</param>
        /// <param name="progressing">The progress emitter</param>
        /// <param name="forceUpdate">Whether to force an update of geometry store anyway</param>
        /// <returns>The given udpated state or a new state</returns>
        public IEnumerable <IIfcRepresentationContext> ReadGeometryStore(IModel model, CancelableProgressing progressing, bool forceUpdate = false)
        {
            // Use Xbim Model Context for geometry creation
            if (forceUpdate || (model.GeometryStore?.IsEmpty ?? false))
            {
                progressing?.NotifyProgressEstimateUpdate(100);
                ReportProgressDelegate progressDelegate = (percent, userState) =>
                {
                    progressing?.State.UpdateDone(percent, userState.ToString());
                    progressing?.NotifyOnProgressChange();
                };

                var context = new Xbim3DModelContext(model, "model", null, Logger);
                context.CreateContext(progressDelegate, false);
                return(context.Contexts);
            }
            else
            {
                return(model.GeometryStore.BeginRead().ContextIds
                       .Select(label => model.Instances[label])
                       .Cast <IIfcRepresentationContext>());
            }
        }
Beispiel #14
0
 protected IPersistEntity Copy(IPersistEntity instance, T package, bool withInverse, CancelableProgressing cp)
 {
     package.Log?.Add(new TransformLogEntry(new XbimInstanceHandle(instance), TransformAction.Transferred));
     try
     {
         return(package.Target.InsertCopy(instance, package.Map, (p, o) => PropertyTransform(p, o, package, cp), withInverse, false));
     }
     catch (Exception e)
     {
         Log?.LogError("Exception at #{2}{3}: '{0}' with '{1}'.", e.GetType().Name, e.Message, instance.EntityLabel, instance.ExpressType.Name);
         throw e;
     }
 }
Beispiel #15
0
 protected override IPersistEntity DelegateCopy(IPersistEntity instance, IfcPlacementTransformPackage package, CancelableProgressing cp)
 {
     if (instance is IIfcLocalPlacement p)
     {
         Log?.LogInformation($"Changing placement '{p}'");
         // Don't copy inverse references (products and children)
         var targetPlacement = Copy(instance, package, false, cp) as IIfcLocalPlacement;
         package.HandlePlacementCopy(p, targetPlacement);
         return(targetPlacement);
     }
     else
     {
         throw new NotSupportedException($"Illegal handling of '{instance}' requested.");
     }
 }
Beispiel #16
0
 protected override TransformResult.Code DoPreprocessTransform(IfcPlacementTransformPackage package, CancelableProgressing progress)
 {
     Log?.LogInformation("({0}) Applying '{1}' strategy to model.", Name, PlacementStrategy);
     package.Prepare(progress);
     Log?.LogInformation("({0}) Got singleton offset shift of {1} [m].", Name, package.SingletonShift * (1 / package.UnitsPerMeterSource));
     return(TransformResult.Code.Finished);
 }
Beispiel #17
0
 protected override IPersistEntity DelegateCopy(IPersistEntity instance, IfcMetadataTransformPackage package, CancelableProgressing cp)
 {
     return(base.DelegateCopy(instance, package, cp));
 }
Beispiel #18
0
 protected virtual IPersistEntity DelegateCopy(IPersistEntity instance, T package, CancelableProgressing cp)
 {
     return(Copy(instance, package, true, cp));
 }
Beispiel #19
0
 protected virtual TransformResult.Code DoPostTransform(T package, CancelableProgressing progress)
 {
     return(TransformResult.Code.Finished);
 }
Beispiel #20
0
 /// <summary>
 /// Delegate handling the instance's property transformation. By default all properties (relations and data) are
 /// forwarded as they are into the transformation queue.
 /// </summary>
 /// <param name="property">The meta property descriptor</param>
 /// <param name="hostObject">The hosting object</param>
 /// <param name="package">The task's work package</param>
 /// <param name="cp">Cancelable progress monitor</param>
 /// <returns></returns>
 protected virtual object PropertyTransform(ExpressMetaProperty property, object hostObject, T package, CancelableProgressing cp)
 {
     if (cp?.State.IsAboutCancelling ?? false)
     {
         return(null);
     }
     else
     {
         return(property?.PropertyInfo.GetValue(hostObject));
     }
 }
Beispiel #21
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);
        }
Beispiel #22
0
 /// <summary>
 /// Creates a new transformation task but doesn't start it.
 /// </summary>
 /// <param name="aSource">The source model</param>
 /// <param name="progressing">The porgressing token</param>
 /// <returns></returns>
 public Task <TransformResult> Prepare(IModel aSource, out CancelableProgressing progressing)
 {
     progressing = new CancelableProgressing(true);
     progressing.NotifyProgressEstimateChange(aSource.Instances.Count);
     return(new Task <TransformResult>(PrepareInternally(aSource, progressing)));
 }
Beispiel #23
0
        protected Func <TransformResult> PrepareInternally(IModel aSource, CancelableProgressing cp)
        {
            if (!cp?.State.IsAlive ?? false)
            {
                throw new NotSupportedException($"Progress monitor already terminated.");
            }

            return(() =>
            {
                List <TransformLogEntry> logEntries = new List <TransformLogEntry>();
                IfcStore target = CreateTargetModel(aSource, cp);

                using (ITransaction txStore = target.BeginTransaction(Name))
                {
                    try
                    {
                        T package = CreateTransformPackage(aSource, target);
                        if (!IsLogEnabled)
                        {
                            package.Log = null;
                        }

                        TransformResult.Code code;
                        cp?.NotifyOnProgressChange($"Preparing '{Name}' ...");
                        if (TransformResult.Code.Finished != (code = DoPreprocessTransform(package, cp)))
                        {
                            return CreateResultFromCode(code, cp);
                        }
                        cp?.NotifyOnProgressChange(0, $"Preparation done.");

                        cp?.NotifyOnProgressChange($"Running '{Name}' ...");
                        if (TransformResult.Code.Finished != (code = DoTransform(package, cp)))
                        {
                            return CreateResultFromCode(code, cp);
                        }
                        cp?.NotifyOnProgressChange(0, $"Transformation done.");

                        cp?.NotifyOnProgressChange($"Post processing '{Name}' ...");
                        if (TransformResult.Code.Finished != (code = DoPostTransform(package, cp)))
                        {
                            return CreateResultFromCode(code, cp);
                        }
                        cp?.NotifyOnProgressChange(0, $"Post-processing done.");

                        txStore.Commit();
                        return new TransformResult(code, package);
                    }
                    catch (Exception e)
                    {
                        cp?.State.MarkBroken();
                        txStore.RollBack();
                        return new TransformResult(TransformResult.Code.ExitWithError, e);
                    }
                    finally
                    {
                        cp?.State.MarkTerminated();
                        cp?.NotifyOnProgressEnd($"Transform '{Name}' has been finalized.");
                    }
                }
            });
        }