/// <summary> /// DocumentChanged Handler /// </summary> /// <remarks> /// It monitors changes to the element that is being analyzed. /// If the element was changed, we ask it to restart the analysis. /// If the element was deleted, we ask the analyzer to stop. /// </remarks> /// public void DocChangedHandler(object sender, DocumentChangedEventArgs args) { if (m_analyzer != null) { // first we check if the element was deleted ICollection <ElementId> elems = args.GetDeletedElementIds(); if (elems.Contains(m_analyzer.AnalyzedElementId)) { m_analyzer.StopCalculation(); m_analyzer = null; // if we've stopped, we do not need events anymore UnsubscribeFromIdling(sender as UIApplication); UnsubscribeFromChanges(sender as UIApplication); } else // not deleted? what about changed? { elems = args.GetModifiedElementIds(); if (elems.Contains(m_analyzer.AnalyzedElementId)) { m_analyzer.RestartCalculation(); } } } else // no analyzer => no need for the events anymore { UnsubscribeFromIdling(sender as UIApplication); UnsubscribeFromChanges(sender as UIApplication); } }
/// <summary> /// Kicking off an analysis of a wall face. /// </summary> /// <remarks> /// After successfully starting a new application /// the method subscribe to the Idling event in order to /// periodically fetch data from the analyzer to Revit. /// It also subscribes to DocumentChange to monitor /// eventual changes to the element being analyzed. /// </remarks> /// public void RunAnalyzer(UIApplication uiapp, String sref) { if (uiapp.ActiveUIDocument != null) { // we could have our document ready with a display style // but here we create our display style pro grammatically View view = uiapp.ActiveUIDocument.ActiveView; SetupDisplayStyle(view); // setting up a new analyzer, // then initializing it and starting it m_analyzer = new FaceAnalyzer(view, sref); m_analyzer.Initialize(); // if we the calculating when off successfully // we know we need to subscribe to Idling // to get the results as they'll keep pouring in if (m_analyzer.StartCalculation()) { SubscribeToIdling(uiapp); SubscribeToChanges(uiapp); } } }
/// <summary> /// Idling Handler /// </summary> /// <remarks> /// It reaches out to the analyzer and ask it to update /// the results in Revit if more data has been calculated /// since the last time we asked. /// <para> /// If there is no more data available, we unsubscribe /// from the Idling event, for we do not need it anymore. /// </para> /// </remarks> /// public void IdlingHandler(object sender, IdlingEventArgs args) { bool processing = false; if (m_analyzer != null) { UIApplication uiapp = sender as UIApplication; if (uiapp.ActiveUIDocument != null) { // In order for the analysis to appear correctly in the view // we seem to need the mechanism of a transaction to be run // even though the results are not really parts of the document. using (Transaction trans = new Transaction(uiapp.ActiveUIDocument.Document)) { trans.Start("bogus transaction"); processing = m_analyzer.UpdateResults(); trans.Commit(); } // In our case, we want Revit to get back to as as soon as possible args.SetRaiseWithoutDelay(); } } // We do not need the event once the analysis is over if (!processing) { UnsubscribeFromIdling(sender as UIApplication); m_analyzer = null; } }