diff --git a/CHANGELOG.md b/CHANGELOG.md index 16f46a7bf4..9ddfaeb760 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,7 @@ - -## 0.3.8 -* Upgrade Greg, GregRevitOAuth, and RestSharp to RestSharp 106.12.0 to address a security issue. - -## 0.3.7 * Add Transaction controls - "Sync with Revit" Toggle button. +* Upgrade Greg, GregRevitOAuth, and RestSharp to RestSharp 106.12.0 to address a security issue. +* Keep ElementBinding when set Transaction disabled. ## 0.3.6 * Upgrade DynamoRevit to 2.13.0. diff --git a/src/DynamoRevit/DynamoRevit.cs b/src/DynamoRevit/DynamoRevit.cs index c07edaed2b..3f2be47476 100644 --- a/src/DynamoRevit/DynamoRevit.cs +++ b/src/DynamoRevit/DynamoRevit.cs @@ -576,16 +576,18 @@ private static void AddSyncWithRevitControls(DynamoView dynamoView) var runsettingStackPanel = runsettingsGrid.Children.OfType().FirstOrDefault(); var srcDic = Dynamo.UI.SharedDictionaryManager.DynamoModernDictionary; + if (TransactionManager.Instance.DisableTransactions) + TransactionManager.Instance.DisableTransactions = false; var toggleItem = new System.Windows.Controls.Primitives.ToggleButton { Width = 40, Height = 20, - IsChecked = true, + IsChecked = !TransactionManager.Instance.DisableTransactions, VerticalContentAlignment = System.Windows.VerticalAlignment.Center, ToolTip = Resources.SyncWithRevitToolTip }; - + toggleItem.SetValue(System.Windows.Controls.Primitives.ToggleButton.StyleProperty, srcDic["EllipseToggleButton1"]); toggleItem.Click += OnReadOnlyModeToggleChecked; diff --git a/src/Libraries/RevitNodes/Elements/AbstractFamilyInstance.cs b/src/Libraries/RevitNodes/Elements/AbstractFamilyInstance.cs index 2653a8dff7..6d0dd778bb 100644 --- a/src/Libraries/RevitNodes/Elements/AbstractFamilyInstance.cs +++ b/src/Libraries/RevitNodes/Elements/AbstractFamilyInstance.cs @@ -1,4 +1,5 @@ using Autodesk.DesignScript.Runtime; +using Autodesk.Revit.DB; using Revit.GeometryConversion; using RevitServices.Persistence; using RevitServices.Transactions; diff --git a/src/Libraries/RevitNodes/Elements/AdaptiveComponent.cs b/src/Libraries/RevitNodes/Elements/AdaptiveComponent.cs index 014a9a704b..c9165b1d6d 100644 --- a/src/Libraries/RevitNodes/Elements/AdaptiveComponent.cs +++ b/src/Libraries/RevitNodes/Elements/AdaptiveComponent.cs @@ -29,7 +29,7 @@ public class AdaptiveComponent : AbstractFamilyInstance /// private AdaptiveComponent(Autodesk.Revit.DB.FamilyInstance familyInstance) { - SafeInit(() => InitAdaptiveComponent(familyInstance)); + SafeInit(() => InitAdaptiveComponent(familyInstance), true); } /// @@ -64,9 +64,7 @@ private AdaptiveComponent(double[] parms, Reference c, FamilyType ft) /// private void InitAdaptiveComponent(Autodesk.Revit.DB.FamilyInstance familyInstance) { - TransactionManager.Instance.EnsureInTransaction(Document); InternalSetFamilyInstance(familyInstance); - TransactionManager.Instance.TransactionTaskDone(); } /// @@ -511,11 +509,24 @@ private static AdaptiveComponent[] InternalByPoints(Point[][] points, FamilyType if (oldInstances != null) countOfOldInstances = oldInstances.Count(); int reusableCount = Math.Min(countToBeCreated, countOfOldInstances); - TransactionManager.Instance.EnsureInTransaction(Document); - List instances = new List(); List components = new List(); + if (TransactionManager.Instance.DisableTransactions) + { + if(oldInstances != null) + { + foreach (var instance in oldInstances) + { + var adpCom = new AdaptiveComponent(instance); + components.Add(adpCom); + } + return components.ToArray(); + } + } + + TransactionManager.Instance.EnsureInTransaction(Document); + try { // Reuse the adaptive components that can be reused if possible diff --git a/src/Libraries/RevitNodes/Elements/Ceiling.cs b/src/Libraries/RevitNodes/Elements/Ceiling.cs index 29b7afb22c..de24f99272 100644 --- a/src/Libraries/RevitNodes/Elements/Ceiling.cs +++ b/src/Libraries/RevitNodes/Elements/Ceiling.cs @@ -117,7 +117,8 @@ public static Ceiling ByOutlineTypeAndLevel(Curve[] outlineCurves, CeilingType c } var ceiling = ByOutlineTypeAndLevel(PolyCurve.ByJoinedCurves(outlineCurves), ceilingType, level); - DocumentManager.Regenerate(); + if (!TransactionManager.Instance.DisableTransactions) + DocumentManager.Regenerate(); return ceiling; } @@ -161,7 +162,8 @@ public static Ceiling ByOutlineTypeAndLevel(PolyCurve outline, CeilingType ceili } var ceiling = new Ceiling(loops, ceilingType.InternalCeilingType, level.InternalLevel); - DocumentManager.Regenerate(); + if (!TransactionManager.Instance.DisableTransactions) + DocumentManager.Regenerate(); return ceiling; } diff --git a/src/Libraries/RevitNodes/Elements/Element.cs b/src/Libraries/RevitNodes/Elements/Element.cs index aa1abf303d..b023ba6842 100644 --- a/src/Libraries/RevitNodes/Elements/Element.cs +++ b/src/Libraries/RevitNodes/Elements/Element.cs @@ -30,6 +30,20 @@ public abstract class Element : IDisposable, IGraphicItem, IFormattable /// protected void SafeInit(Action init) { + if(TransactionManager.Instance.DisableTransactions) + { + var elementManager = ElementIDLifecycleManager.GetInstance(); + var element = ElementBinder.GetElementFromTrace(Document); + int count = elementManager.GetRegisteredCount(element.Id.IntegerValue); + + if (element != null) + { + SetInternalElement(element); + if (count > 0) + elementManager.UnRegisterAssociation(Id, this); + return; + } + } TransactionManager.Instance.EnsureInTransaction(DocumentManager.Instance.CurrentDBDocument); SafeInitImpl(init); @@ -205,9 +219,21 @@ public bool AreJoined(Element otherElement) /// A reference to the element /// [SupressImportIntoVM] - public abstract Autodesk.Revit.DB.Element InternalElement + public virtual Autodesk.Revit.DB.Element InternalElement { get; + set; + } + + /// + /// Set Internal Element from a exsiting element. + /// + /// + internal void SetInternalElement(Autodesk.Revit.DB.Element element) + { + InternalElement = element; + InternalElementId = element.Id; + InternalUniqueId = element.UniqueId; } private ElementId internalId; @@ -284,6 +310,14 @@ public virtual void Dispose() bool didRevitDelete = ElementIDLifecycleManager.GetInstance().IsRevitDeleted(Id); var elementManager = ElementIDLifecycleManager.GetInstance(); + + if (TransactionManager.Instance.DisableTransactions) + { + int count = elementManager.GetRegisteredCount(Id); + if(count > 0) + elementManager.UnRegisterAssociation(Id, this); + return; + } int remainingBindings = elementManager.UnRegisterAssociation(Id, this); // Do not delete Revit owned elements @@ -302,7 +336,8 @@ public virtual void Dispose() throw new InvalidOperationException(string.Format(Properties.Resources.CantCloseLastOpenView, this.ToString())); } } - DocumentManager.Instance.DeleteElement(new ElementUUID(InternalUniqueId)); + if(!TransactionManager.Instance.DisableTransactions) + DocumentManager.Instance.DeleteElement(new ElementUUID(InternalUniqueId)); } else { diff --git a/src/Libraries/RevitNodes/Elements/Floor.cs b/src/Libraries/RevitNodes/Elements/Floor.cs index 9fb66904e6..55b1e9dfd3 100644 --- a/src/Libraries/RevitNodes/Elements/Floor.cs +++ b/src/Libraries/RevitNodes/Elements/Floor.cs @@ -126,7 +126,8 @@ public static Floor ByOutlineTypeAndLevel(Curve[] outlineCurves, FloorType floor } var floor = ByOutlineTypeAndLevel(PolyCurve.ByJoinedCurves(outlineCurves), floorType, level); - DocumentManager.Regenerate(); + if (!TransactionManager.Instance.DisableTransactions) + DocumentManager.Regenerate(); return floor; } @@ -173,7 +174,8 @@ public static Floor ByOutlineTypeAndLevel(PolyCurve outline, FloorType floorType } var floor = new Floor(loops, floorType.InternalFloorType, level.InternalLevel, offset); - DocumentManager.Regenerate(); + if(!TransactionManager.Instance.DisableTransactions) + DocumentManager.Regenerate(); return floor; } diff --git a/src/Libraries/RevitNodes/Elements/PathOfTravel.cs b/src/Libraries/RevitNodes/Elements/PathOfTravel.cs index 033ab0e3e7..059f7e24bc 100644 --- a/src/Libraries/RevitNodes/Elements/PathOfTravel.cs +++ b/src/Libraries/RevitNodes/Elements/PathOfTravel.cs @@ -300,12 +300,26 @@ internal static PathOfTravel FromExisting(RvtAnalysis.PathOfTravel rvtPathOfTrav /// /// Floor plan view for which rooms will be used to retrieve longest paths to the given exit points. /// List of end (exit) points. - /// List of PathOfTravel elements corresponding to the longest of shortest exit paths from rooms.List of PathOfTravel elements corresponding to the longest of shortest exit paths from rooms. /// private static PathOfTravel[] InternalLongestOfShortestExitPaths(Rvt.View rvtView, IEnumerable endPoints) { List pathsOfTravel = new List(); + if(TransactionManager.Instance.DisableTransactions) + { + IEnumerable persistRvtElements = ElementBinder.GetElementsFromTrace(Document); + if(persistRvtElements != null) + { + foreach (var ele in persistRvtElements) + { + var persisEle = new PathOfTravel(ele); + pathsOfTravel.Add(persisEle); + } + + return pathsOfTravel.ToArray(); + } + } TransactionManager.Instance.EnsureInTransaction(Document); try @@ -374,6 +388,21 @@ private static PathOfTravel[] InternalByViewEndPoints(Rvt.View rvtView, IEnumera { List pathsOfTravel = new List(); + if(TransactionManager.Instance.DisableTransactions) + { + IEnumerable persistRvtElements = ElementBinder.GetElementsFromTrace(Document); + if(persistRvtElements != null) + { + foreach (var ele in persistRvtElements) + { + var persisEle = new PathOfTravel(ele); + pathsOfTravel.Add(persisEle); + } + + return pathsOfTravel.ToArray(); + } + } + TransactionManager.Instance.EnsureInTransaction(Document); try diff --git a/src/Libraries/RevitNodes/Elements/RevisionCloud.cs b/src/Libraries/RevitNodes/Elements/RevisionCloud.cs index d780d23a3a..298c4dbc02 100644 --- a/src/Libraries/RevitNodes/Elements/RevisionCloud.cs +++ b/src/Libraries/RevitNodes/Elements/RevisionCloud.cs @@ -66,7 +66,7 @@ private RevisionCloud(Autodesk.Revit.DB.View view, List /// /// Set the internal Element, ElementId, and UniqueId /// - /// + /// private void InternalSetElement(Autodesk.Revit.DB.RevisionCloud element) { InternalRevitElement = element; diff --git a/src/Libraries/RevitNodes/Elements/Roof.cs b/src/Libraries/RevitNodes/Elements/Roof.cs index 8e9be6f0b4..a3c4cb9e17 100644 --- a/src/Libraries/RevitNodes/Elements/Roof.cs +++ b/src/Libraries/RevitNodes/Elements/Roof.cs @@ -130,7 +130,7 @@ private void InitRoof(CurveArray curves, Autodesk.Revit.DB.Level level, Autodesk /// /// Set the InternalRoof property and the associated element id and unique id /// - /// + /// private void InternalSetRoof(Autodesk.Revit.DB.RoofBase roof) { InternalRoof = roof; @@ -165,7 +165,8 @@ public static Roof ByOutlineTypeAndLevel(Curve[] outline, RoofType roofType, Lev }); var roof = new Roof(ca, level.InternalLevel,roofType.InternalRoofType); - DocumentManager.Regenerate(); + if (!TransactionManager.Instance.DisableTransactions) + DocumentManager.Regenerate(); return roof; } @@ -194,7 +195,8 @@ public static Roof ByOutlineExtrusionTypeAndLevel(PolyCurve outline, RoofType ro }); var roof = new Roof(ca, plane.InternalReferencePlane, level.InternalLevel, roofType.InternalRoofType, extrusionStart, extrusionEnd); - DocumentManager.Regenerate(); + if (!TransactionManager.Instance.DisableTransactions) + DocumentManager.Regenerate(); return roof; } diff --git a/src/Libraries/RevitNodes/Elements/Room.cs b/src/Libraries/RevitNodes/Elements/Room.cs index 0f55c1148d..197a5f188a 100644 --- a/src/Libraries/RevitNodes/Elements/Room.cs +++ b/src/Libraries/RevitNodes/Elements/Room.cs @@ -33,7 +33,7 @@ public override Autodesk.Revit.DB.Element InternalElement { get { return InternalRevitElement; } } - + #endregion #region Private constructors diff --git a/src/Libraries/RevitNodes/Elements/Views/Sheet.cs b/src/Libraries/RevitNodes/Elements/Views/Sheet.cs index b28407d482..7e382e39d5 100644 --- a/src/Libraries/RevitNodes/Elements/Views/Sheet.cs +++ b/src/Libraries/RevitNodes/Elements/Views/Sheet.cs @@ -398,12 +398,12 @@ private void InternalAddViewsToSheetView(IEnumerable vie /// /// Set the InternalViewSheet property and the associated element id and unique id /// - /// - private void InternalSetViewSheet(Autodesk.Revit.DB.ViewSheet floor) + /// + private void InternalSetViewSheet(Autodesk.Revit.DB.ViewSheet viewSheet) { - this.InternalViewSheet = floor; - this.InternalElementId = floor.Id; - this.InternalUniqueId = floor.UniqueId; + this.InternalViewSheet = viewSheet; + this.InternalElementId = viewSheet.Id; + this.InternalUniqueId = viewSheet.UniqueId; } /// @@ -737,9 +737,20 @@ public static Sheet DuplicateSheet(Sheet sheet, bool duplicateWithContents = fal Sheet newSheet = null; + if(TransactionManager.Instance.DisableTransactions) + { + var oldSheet = ElementBinder.GetElementFromTrace(Document); + if(oldSheet != null) + { + newSheet = new Sheet(oldSheet); + + return newSheet; + } + } + try { - RevitServices.Transactions.TransactionManager.Instance.EnsureInTransaction(Application.Document.Current.InternalDocument); + TransactionManager.Instance.EnsureInTransaction(Application.Document.Current.InternalDocument); var oldElements = ElementBinder.GetElementsFromTrace(Document); List elementIds = new List(); diff --git a/src/Libraries/RevitServices/Persistence/ElementIDLifecycleManager.cs b/src/Libraries/RevitServices/Persistence/ElementIDLifecycleManager.cs index 8da651b0f9..368116357f 100644 --- a/src/Libraries/RevitServices/Persistence/ElementIDLifecycleManager.cs +++ b/src/Libraries/RevitServices/Persistence/ElementIDLifecycleManager.cs @@ -101,7 +101,9 @@ public int UnRegisterAssociation(T elementID, Object wrapper) if (existingWrappers.Contains(wrapper)) { int index = existingWrappers.FindIndex((x) => object.ReferenceEquals(x, wrapper)); - existingWrappers.RemoveAt(index); + if(index != -1) + existingWrappers.RemoveAt(index); + if (existingWrappers.Count == 0) { wrappers.Remove(elementID);