public bool AppendIfcProductType(Type t) { if (!t.IsSubclassOf(typeof(IIfcProduct))) { throw new ArgumentException($"Expecting sub-classes of IfcProduct"); } return(CopyExpressType.Add(t.XLabel().LocalName)); }
/// <summary> /// Runs the model ingest & merge procedure. /// </summary> /// <param name="progressAction">The action to take on progress</param> /// <param name="cancellationPending">The indicator of a pending cancel</param> public void RunModelMerge(ReportProgressDelegate progressAction = null, Func <bool> cancellationPending = null) { var candidateInstances = Models.SelectMany(m => m.Instances).OfType <IIfcProduct>(); long totalCount = Models.Select(m => m.Instances.Count).Sum(); long currentCount = 0; int recentPercentage = 0; Builder.Wrap(s => { Dictionary <IIfcProduct, XbimMatrix3D> t2Inv = new Dictionary <IIfcProduct, XbimMatrix3D>(); progressAction?.Invoke(0, $"Start injection into ${s.FileName}"); foreach (var i in candidateInstances) { ++currentCount; if (cancellationPending?.Invoke() ?? false) { Logger?.LogInformation($"Canceling model ingest of {s.FileName}"); // Don't apply changes return(false); } if (CopyExpressType.Contains(i.XLabel().LocalName)) { var newProduct = s.InsertCopy(i, HandleMapOf(i), PropertyTransform, true, false); if (i.ObjectPlacement is IIfcGridPlacement gp) { // Since grids are products, they were to be embedded into the model too Logger?.LogWarning($"Can't transfer grid placement #{gp.EntityLabel}. Replacing #{newProduct.EntityLabel} of {i.ExpressType} with local placement."); } // Get original aggregated transformation var t1 = PlacementOf(i); // Get container transformation var container = FindContainer(i); XbimMatrix3D t2; if (t2Inv.TryGetValue(container, out t2)) { // Compute inv of container local placement t2 = PlacementOf(container); t2.Invert(); t2Inv.Add(container, t2); } // New placement based on given global transformation var c2 = t2 * t1; var placement = s.NewLocalPlacement(c2, true); // Relate to product and container newProduct.ObjectPlacement = placement; s.NewContains(container).RelatedElements.Add(newProduct); } int percentage = (int)Math.Ceiling(100.0 * currentCount / totalCount); if (recentPercentage < percentage) { progressAction?.Invoke(recentPercentage = percentage, null); } } progressAction?.Invoke(100, $"Finalized injection into ${s.FileName}"); // Apply changes return(true); }); }