-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclean_diff.txt
More file actions
206 lines (187 loc) · 21.2 KB
/
Copy pathclean_diff.txt
File metadata and controls
206 lines (187 loc) · 21.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
diff --git a/decoded_addchecked.cs b/FilterPlus/ViewModels/SelectionFilterViewModel.cs
index 271b774..b7a1d92 100644
--- a/decoded_addchecked.cs
+++ b/FilterPlus/ViewModels/SelectionFilterViewModel.cs
@@ -1,4 +1,4 @@
-´╗┐using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using FilterPlus.Models;
using FilterPlus.Services;
@@ -81,7 +81,7 @@ public partial class SelectionFilterViewModel : ObservableObject
private List<string> _activeGroupings = new List<string>();
[ObservableProperty] private SelectionScope _currentScope = SelectionScope.CurrentSelection;
- private HashSet<Autodesk.Revit.DB.ElementId> _persistentCheckedIds = new();
+ private HashSet<Autodesk.Revit.DB.ElementId> _persistentCheckedIds = new(new ElementIdEqualityComparer());
[RelayCommand]
private void ExpandAll()
@@ -252,7 +252,7 @@ public partial class SelectionFilterViewModel : ObservableObject
}
/// <summary>
- /// Called when scope radio button changes. NO Revit API calls here ÔÇô uses pre-fetched data.
+ /// Called when scope radio button changes. NO Revit API calls here ÔÇô uses pre-fetched data.
/// </summary>
partial void OnCurrentScopeChanged(SelectionScope value)
{
@@ -627,6 +627,12 @@ public partial class SelectionFilterViewModel : ObservableObject
_pickElementsEvent = externalEvent;
}
+ public void SetActionEventHandler(FilterPlus.Services.ActionEventHandler handler, Autodesk.Revit.UI.ExternalEvent externalEvent)
+ {
+ _actionHandler = handler;
+ _actionExternalEvent = externalEvent;
+ }
+
[RelayCommand]
private void PickElements()
{
@@ -694,18 +700,18 @@ public partial class SelectionFilterViewModel : ObservableObject
{
try
{
- // ├ö├Â├ç├ö├Â├ç 1. Actualizar el estado persistente de IDs marcados ├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç
+ // ÔöÇÔöÇ 1. Actualizar el estado persistente de IDs marcados ÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇ
UpdatePersistentCheckedIdsFromTree();
var finalIds = _persistentCheckedIds.ToList();
StatusMessage = $"Seleccionados: {finalIds.Count}";
- // ├ö├Â├ç├ö├Â├ç 2. Aplicar la selecciÔö£Ôöén en Revit ├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç
+ // ÔöÇÔöÇ 2. Aplicar la selecci├│n en Revit ÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇ
_selectionService.SetSelection(finalIds);
- // ├ö├Â├ç├ö├Â├ç 4. Reconstruir _currentSelectionElements desde TODOS los scopes ├ö├Â├ç├ö├Â├ç├ö├Â├ç├ö├Â├ç
+ // ÔöÇÔöÇ 4. Reconstruir _currentSelectionElements desde TODOS los scopes ÔöÇÔöÇÔöÇÔöÇ
// Buscamos el ElementModel de cada ID seleccionado en el pool completo,
- // asÔö£┬í no se pierden elementos que no estuvieran en el scope activo actual.
+ // así no se pierden elementos que no estuvieran en el scope activo actual.
var allKnownById = _currentSelectionElements
.Concat(_elementsVisibleInViewElements)
.Concat(_elementsBelongingToViewElements)
@@ -805,13 +811,25 @@ public partial class SelectionFilterViewModel : ObservableObject
FilterText = string.Empty;
}
+ private FilterPlus.Services.ActionEventHandler _actionHandler;
+ private Autodesk.Revit.UI.ExternalEvent _actionExternalEvent;
+
[RelayCommand]
private void ApplyIncreaseChecked()
{
- try
+ if (_actionHandler == null || _actionExternalEvent == null)
+ {
+ LoggerService.LogError("ApplyIncreaseChecked", new System.InvalidOperationException("ActionEventHandler not initialized."));
+ return;
+ }
+
+ LoggerService.LogInfo($"[ApplyIncreaseChecked] START. Current Scope in Select: {CurrentScope}. _activeElements count: {(_activeElements?.Count ?? 0)}.");
+ StatusMessage = "Processing...";
+
+ _actionHandler.Raise(() =>
{
- TreeItemViewModel.IsBulkUpdating = true;
- LoggerService.LogInfo($"[ApplyIncreaseChecked] START. Current Scope in Select: {CurrentScope}. _activeElements count: {(_activeElements?.Count ?? 0)}.");
+ try
+ {
// 1. Get currently checked ElementIds from the tree
var currentCheckedIds = new List<Autodesk.Revit.DB.ElementId>();
@@ -856,12 +874,15 @@ public partial class SelectionFilterViewModel : ObservableObject
LoggerService.LogInfo($"[ApplyIncreaseChecked] Domain: All Model. Collector count: {domainElements.Count}.");
}
- var targetIds = new HashSet<Autodesk.Revit.DB.ElementId>();
+ var targetIds = new HashSet<Autodesk.Revit.DB.ElementId>(new ElementIdEqualityComparer());
// 3. Apply WHAT rules
if (IncreaseWhatSameCategory)
{
- var targetCatIds = sourceElements.Select(e => e.Category?.Id).Where(id => id != null).ToHashSet();
+ var targetCatIds = new HashSet<Autodesk.Revit.DB.ElementId>(
+ sourceElements.Select(e => e.Category?.Id).Where(id => id != null),
+ new ElementIdEqualityComparer()
+ );
foreach (var el in domainElements)
{
if (el.Category != null && targetCatIds.Contains(el.Category.Id))
@@ -872,7 +893,7 @@ public partial class SelectionFilterViewModel : ObservableObject
if (IncreaseWhatSameFamily || IncreaseWhatSameType)
{
var targetFamilyNames = new HashSet<string>();
- var targetTypeIds = new HashSet<Autodesk.Revit.DB.ElementId>();
+ var targetTypeIds = new HashSet<Autodesk.Revit.DB.ElementId>(new ElementIdEqualityComparer());
foreach (var el in sourceElements)
{
@@ -1050,10 +1071,13 @@ public partial class SelectionFilterViewModel : ObservableObject
}
// 4. Unify with current and other scopes
- var activeElementIds = _activeElements?.Select(e => e.Id).ToHashSet() ?? new HashSet<Autodesk.Revit.DB.ElementId>();
+ var activeElementIds = new HashSet<Autodesk.Revit.DB.ElementId>(
+ _activeElements?.Select(e => e.Id) ?? System.Linq.Enumerable.Empty<Autodesk.Revit.DB.ElementId>(),
+ new ElementIdEqualityComparer()
+ );
var idsFromOtherScopes = _persistentCheckedIds.Where(id => !activeElementIds.Contains(id)).ToList();
- var finalCheckedIds = new HashSet<Autodesk.Revit.DB.ElementId>();
+ var finalCheckedIds = new HashSet<Autodesk.Revit.DB.ElementId>(new ElementIdEqualityComparer());
if (IncreaseHowAddToCurrent)
{
foreach (var id in currentCheckedIds) finalCheckedIds.Add(id);
@@ -1070,7 +1094,7 @@ public partial class SelectionFilterViewModel : ObservableObject
// 5. Exclusions (UNSELECT ELEMENTS IF) - applies to the unified finalCheckedIds to purge the selection
if (IncreaseUnselectBelongsToGroup || IncreaseUnselectBelongsToAssembly)
{
- var purgedCheckedIds = new HashSet<Autodesk.Revit.DB.ElementId>();
+ var purgedCheckedIds = new HashSet<Autodesk.Revit.DB.ElementId>(new ElementIdEqualityComparer());
foreach (var id in finalCheckedIds)
{
var el = doc.GetElement(id);
@@ -1094,7 +1118,10 @@ public partial class SelectionFilterViewModel : ObservableObject
LoggerService.LogInfo($"[ApplyIncreaseChecked] Final checked IDs unified (including other scopes): {finalCheckedIds.Count}. IDs: {string.Join(", ", finalCheckedIds)}");
// 6. Inject newly matched elements into _activeElements (if they aren't already in it)
- var activeIds = _activeElements.Select(e => e.Id).ToHashSet();
+ var activeIds = new HashSet<Autodesk.Revit.DB.ElementId>(
+ _activeElements.Select(e => e.Id),
+ new ElementIdEqualityComparer()
+ );
LoggerService.LogInfo($"[ApplyIncreaseChecked] Explorer tree currently has {activeIds.Count} active IDs.");
// Build a unified dictionary of all pre-fetched element models for O(1) reuse
@@ -1104,7 +1131,7 @@ public partial class SelectionFilterViewModel : ObservableObject
.Concat(_currentSelectionElements)
.GroupBy(e => e.Id)
.Select(g => g.First())
- .ToDictionary(e => e.Id);
+ .ToDictionary(e => e.Id, new ElementIdEqualityComparer());
LoggerService.LogInfo($"[ApplyIncreaseChecked] Pre-fetched scopes unified cache has {allKnownById.Count} elements.");
@@ -1170,13 +1197,14 @@ public partial class SelectionFilterViewModel : ObservableObject
catch (System.Exception ex)
{
LoggerService.LogError("[ApplyIncreaseChecked] EXCEPTION", ex);
- StatusMessage = "Error al expandir selecciÔö£Ôöén.";
+ StatusMessage = "Error al expandir selecci├│n.";
}
finally
{
TreeItemViewModel.IsBulkUpdating = false;
}
- }
+ }, _actionExternalEvent);
+}
private void FilterNode(TreeItemViewModel node, string searchText, System.Text.RegularExpressions.Regex searchRegex, bool isEmpty)
{
@@ -1245,3 +1273,22 @@ public partial class SelectionFilterViewModel : ObservableObject
}
}
}
+
+/// <summary>
+/// Custom equality comparer for ElementId to prevent reference-equality issues in Revit API.
+/// </summary>
+public class ElementIdEqualityComparer : IEqualityComparer<Autodesk.Revit.DB.ElementId>
+{
+ public bool Equals(Autodesk.Revit.DB.ElementId x, Autodesk.Revit.DB.ElementId y)
+ {
+ if (x == null && y == null) return true;
+ if (x == null || y == null) return false;
+ return x.Value == y.Value;
+ }
+
+ public int GetHashCode(Autodesk.Revit.DB.ElementId obj)
+ {
+ if (obj == null) return 0;
+ return obj.Value.GetHashCode();
+ }
+}