private void RefencedModels_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { if (e.Action == NotifyCollectionChangedAction.Add && e.NewItems.Count > 0) { var refModel = e.NewItems[0] as XbimReferencedModel; var vm = HierarchySource.Cast <XbimModelViewModel>().FirstOrDefault(); vm?.AddRefModel(new XbimRefModelViewModel(refModel, null)); } else if (e.Action == NotifyCollectionChangedAction.Remove) { foreach (XbimReferencedModel refModel in e.OldItems) { XbimModelViewModel vm = HierarchySource.Cast <XbimModelViewModel>().FirstOrDefault(); if (vm != null) { var modelVm = vm.Children.FirstOrDefault(m => { var xbimRefModelViewModel = m as XbimRefModelViewModel; return(xbimRefModelViewModel != null && xbimRefModelViewModel.RefModel == refModel); }) as XbimRefModelViewModel; vm.RemoveRefModel(modelVm); } } } }
public IXbimViewModel FindItemBreadthFirst(IPersistEntity entity) { Queue <IXbimViewModel> queue = new Queue <IXbimViewModel>(); foreach (var item in HierarchySource.OfType <IXbimViewModel>()) { queue.Enqueue(item); } IXbimViewModel current = queue.Dequeue(); while (current != null) { if (IsMatch(current, entity)) { return(current); } foreach (var item in current.Children) { queue.Enqueue(item); } if (!queue.Any()) { return(null); } current = queue.Dequeue(); } return(null); }
// todo: bonghi: this one is too slow on Architettonico_def.xBIM, so I'm patching it for a specific hierarchy, but it needs serious redesign for efficiency private void Select(IPersistEntity newVal, bool tryOptimise = true) { if (ViewDefinition == XbimViewType.SpatialStructure && tryOptimise) { /* * We know that the structure in this case looks like: * * XbimModelViewModel * model.project.GetSpatialStructuralElements (into SpatialViewModel) * model.RefencedModels (into XbimRefModelViewModel) * model.project.GetSpatialStructuralElements (into SpatialViewModel) * * SpatialViewModel * SpatialViewModel * ContainedElementsViewModel * IfcProductModelView * IfcProductModelView * * If a model is a product then find its space with breadth first then expand to it with depth first. * todo: bonghi: this is still not optimal, because it can only point to simple IPersistEntity and not intermediate IXbimViewModels. * */ var p = newVal as IIfcProduct; if (p != null) { var found = FindUnderContainingSpace(newVal, p); // direct search if (found == null) { // search for composed object var decomp = p.Decomposes.FirstOrDefault(); if (decomp?.RelatingObject is IIfcProduct) // { found = FindUnderContainingSpace(newVal, (IIfcProduct)(decomp.RelatingObject)); // direct search of parent through containing space if (found != null) { found = FindItemDepthFirst(found, newVal); // then search for the child } } else { // do basic search Select(newVal, false); } } if (found != null) { Highlight(found); return; } } // if optimised search fails revert to brute force expansion Select(newVal, false); } else { foreach (var item in HierarchySource.OfType <IXbimViewModel>()) { IXbimViewModel toSelect = FindItemDepthFirst(item, newVal); if (toSelect != null) { Highlight(toSelect); return; } } } }