-
Notifications
You must be signed in to change notification settings - Fork 14
/
ActiveViewVisibilityContext.cs
225 lines (174 loc) · 8.44 KB
/
ActiveViewVisibilityContext.cs
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
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
/*
* This file is part of the Buildings and Habitats object Model (BHoM)
* Copyright (c) 2015 - 2023, the respective contributors. All rights reserved.
*
* Each contributor holds copyright over their respective contributions.
* The project versioning (Git) records all such contribution source information.
*
*
* The BHoM is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3.0 of the License, or
* (at your option) any later version.
*
* The BHoM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this code. If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
*/
using Autodesk.Revit.DB;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
namespace BH.Revit.Engine.Core
{
[Description("Class used to extract elements visible in the active view of the host document if that view is of 3d type. See " + nameof(Query.ElementIdsByVisibleInActiveView) + " for usage example.")]
public class ActiveViewVisibilityContext : IExportContext
{
/***************************************************/
/**** Constructor ****/
/***************************************************/
[Description("hostDocument refers to the document that owns the active view. targetDocument can take three values:" +
"\n- same as hostDocument - visible elements of the host document are then collected" +
"\n- document linked in the host document - elements of that linked document visible in the active view of the host document are then collected" +
"\n- null - all elements of all documents, host and links, are then collected")]
public ActiveViewVisibilityContext(Document hostDocument, Document targetDocument)
{
m_HostDocument = hostDocument;
m_TargetDocument = targetDocument;
m_Documents.Push(hostDocument);
m_DocumentLookup[hostDocument.PathName] = hostDocument;
m_Elements.Add(hostDocument.PathName, new HashSet<ElementId>());
}
/***************************************************/
/**** Public methods ****/
/***************************************************/
[Description("Returns ids of all elements visible in the active view of the host document. The ids are grouped by document they belong to.")]
public Dictionary<Document, HashSet<ElementId>> GetAllElementsVisibleInActiveView()
{
if (m_TargetDocument != null)
{
BH.Engine.Base.Compute.RecordError($"The context has been processed with a single target document. Please run again making sure that the target document parameter in the context constructor is null.");
return null;
}
else
return m_DocumentLookup.ToDictionary(x => x.Value, x => m_Elements[x.Key]);
}
/***************************************************/
[Description("Returns ids of given target document's elements visible in the active view of the host document.")]
public HashSet<ElementId> GetElementsVisibleInActiveView(Document targetDocument)
{
HashSet<ElementId> result = null;
if (!m_Elements.TryGetValue(targetDocument?.PathName, out result))
BH.Engine.Base.Compute.RecordError($"Document {targetDocument.Title} has not been processed in the context. Please run again making sure the document is passed as target document in the context constructor or the target document parameter is null.");
return result;
}
/***************************************************/
public void Finish()
{
}
/***************************************************/
public bool IsCanceled()
{
return false;
}
/***************************************************/
public RenderNodeAction OnElementBegin(ElementId elementId)
{
Document doc = m_Documents.Peek();
m_Elements[doc.PathName].Add(elementId);
Element element = doc.GetElement(elementId);
if (element is RevitLinkInstance)
{
RevitLinkInstance linkInstance = (RevitLinkInstance)element;
if (m_TargetDocument == null || m_TargetDocument.PathName == linkInstance.GetLinkDocument().PathName)
{
m_DocumentLookup[linkInstance.Document.PathName] = linkInstance.Document;
return RenderNodeAction.Proceed;
}
}
return RenderNodeAction.Skip;
}
/***************************************************/
public void OnElementEnd(ElementId elementId)
{
}
/***************************************************/
public RenderNodeAction OnFaceBegin(FaceNode node)
{
return RenderNodeAction.Skip;
}
/***************************************************/
public void OnFaceEnd(FaceNode node)
{
}
/***************************************************/
public RenderNodeAction OnInstanceBegin(InstanceNode node)
{
return RenderNodeAction.Skip;
}
/***************************************************/
public void OnInstanceEnd(InstanceNode node)
{
}
/***************************************************/
public void OnLight(LightNode node)
{
}
/***************************************************/
public RenderNodeAction OnLinkBegin(LinkNode node)
{
Document doc = node.GetDocument();
m_Documents.Push(doc);
if (!m_Elements.ContainsKey(doc.PathName))
m_Elements[doc.PathName] = new HashSet<ElementId>();
return RenderNodeAction.Proceed;
}
/***************************************************/
public void OnLinkEnd(LinkNode node)
{
m_Documents.Pop();
}
/***************************************************/
public void OnMaterial(MaterialNode node)
{
}
/***************************************************/
public void OnPolymesh(PolymeshTopology node)
{
}
/***************************************************/
public void OnRPC(RPCNode node)
{
}
/***************************************************/
public RenderNodeAction OnViewBegin(ViewNode node)
{
if (node.ViewId == m_HostDocument.ActiveView.Id)
return RenderNodeAction.Proceed;
else
return RenderNodeAction.Skip;
}
/***************************************************/
public void OnViewEnd(ElementId elementId)
{
}
/***************************************************/
public bool Start()
{
return true;
}
/***************************************************/
/**** Private fields ****/
/***************************************************/
private Document m_HostDocument;
private Document m_TargetDocument;
private Stack<Document> m_Documents = new Stack<Document>();
private Dictionary<string, Document> m_DocumentLookup = new Dictionary<string, Document>();
private Dictionary<string, HashSet<ElementId>> m_Elements = new Dictionary<string, HashSet<ElementId>>();
/***************************************************/
}
}