Files
KGdev.BI3D.Revit.Addin/KGdev.BI3D.Revit.ExporterV2/GeometryRetriever.cs
2024-01-08 09:30:50 +08:00

291 lines
10 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using KGdev.BI3D.Revit.Common;
using KGdev.BI3D.Revit.Common.Models;
namespace KGdev.BI3D.Revit.ExporterV2
{
internal class GeometryRetriever : IExportContext
{
private Transform CurrentTransform
{
get { return this.transformationStack.Peek(); }
}
public GeometryRetriever(
Document document,
bool assignId,
Transform baseTransform,
GeometryRetrieverResult resultContainer,
IElementIdProvider elementIdProvider
)
{
this.document = document;
this.assignId = assignId;
this.baseTransform = baseTransform;
this.resultContainer = resultContainer;
this.elementIdProvider = elementIdProvider;
}
public bool IsCanceled()
{
return false;
}
public bool Start()
{
this.elementIdStack = new Stack<ElementId>();
this.linkIdStack = new Stack<ElementId>();
this.transformationStack = new Stack<Transform>();
this.transformationStack.Push(this.baseTransform);
this.indexForPosition = new Dictionary<Position, int>();
for (int i = 0; i < this.resultContainer.Positions.Count; i++)
{
Position position = this.resultContainer.Positions[i];
this.indexForPosition.Add(position, i);
}
this.indexForId = new Dictionary<string, uint>();
uint num = 0U;
while ((ulong)num < (ulong)((long)this.resultContainer.Ids.Count))
{
string text = this.resultContainer.Ids[(int)num];
this.indexForId.Add(text, num);
num += 1U;
}
this.indexForColor = new Dictionary<RGBA, uint>();
uint num2 = 0U;
while ((ulong)num2 < (ulong)((long)this.resultContainer.Colors.Count))
{
RGBA rgba = this.resultContainer.Colors[(int)num2];
this.indexForColor.Add(rgba, num2);
num2 += 1U;
}
return true;
}
public void Finish() { }
public RenderNodeAction OnViewBegin(ViewNode node)
{
return 0;
}
public void OnViewEnd(ElementId elementId) { }
public RenderNodeAction OnElementBegin(ElementId elementId)
{
this.elementIdStack.Push(elementId);
return 0;
}
public void OnElementEnd(ElementId elementId)
{
this.elementIdStack.Pop();
}
public RenderNodeAction OnLinkBegin(LinkNode node)
{
this.transformationStack.Push(
this.transformationStack.Peek().Multiply(node.GetTransform())
);
this.linkIdStack.Push(this.elementIdStack.Peek());
return 0;
}
public void OnLinkEnd(LinkNode node)
{
this.transformationStack.Pop();
this.linkIdStack.Pop();
}
public RenderNodeAction OnInstanceBegin(InstanceNode node)
{
this.transformationStack.Push(
this.transformationStack.Peek().Multiply(node.GetTransform())
);
return 0;
}
public void OnInstanceEnd(InstanceNode node)
{
this.transformationStack.Pop();
}
public void OnMaterial(MaterialNode node)
{
bool isValid = node.Color.IsValid;
if (isValid)
{
this.lastColor = new RGBA
{
R = node.Color.Red,
G = node.Color.Green,
B = node.Color.Blue,
A = (byte)Math.Round((1.0 - node.Transparency) * 255.0)
};
}
else
{
this.lastColor = this.INVALID_COLOR;
}
}
public RenderNodeAction OnFaceBegin(FaceNode node)
{
return 0;
}
public void OnFaceEnd(FaceNode node) { }
public void OnPolymesh(PolymeshTopology node)
{
ElementId elementId = this.elementIdStack.Peek();
string text = "";
bool flag = this.assignId;
if (flag)
{
LinkedElementIdPath currentElementIdPath = this.GetCurrentElementIdPath();
text = this.elementIdProvider.GetElementId(currentElementIdPath);
bool flag2 = !this.resultContainer.ExportedElementIdPathById.ContainsKey(text);
if (flag2)
{
this.resultContainer.ExportedElementIdPathById.Add(text, currentElementIdPath);
}
}
Transform currentTransformation = this.transformationStack.Peek();
List<Position> list = (
from p in node.GetPoints()
select currentTransformation.OfPoint(p) into x
select x.To3DBIPosition()
).ToList<Position>();
List<List<uint>> list2 = (
from f in node.GetFacets()
select new List<uint> { (uint)f.V1, (uint)f.V2, (uint)f.V3 }
).ToList<List<uint>>();
Dictionary<Edge, List<int>> dictionary = new Dictionary<Edge, List<int>>();
for (int i = 0; i < list2.Count; i++)
{
List<uint> list3 = list2[i];
for (int j = 0; j < list3.Count; j++)
{
int num = (
(currentTransformation.Determinant < 0.0) ? (list3.Count - (j + 1)) : j
);
uint num2 = list3[num];
Position position = list[(int)num2];
bool flag3 = !this.indexForPosition.ContainsKey(position);
if (flag3)
{
this.resultContainer.Positions.Add(position);
this.indexForPosition.Add(
position,
this.resultContainer.Positions.Count - 1
);
}
int num3 = this.indexForPosition[position];
this.resultContainer.Indices.Add(num3);
int num4 = ((j == list3.Count - 1) ? 0 : (j + 1));
uint num5 = list3[num4];
Position position2 = list[(int)num5];
bool flag4 = !this.indexForPosition.ContainsKey(position2);
if (flag4)
{
this.resultContainer.Positions.Add(position2);
this.indexForPosition.Add(
position2,
this.resultContainer.Positions.Count - 1
);
}
int num6 = this.indexForPosition[position2];
List<int> list4 = new List<int> { num3, num6 };
list4.Sort();
Edge edge = new Edge { LargestIndex = list4[1], SmallestIndex = list4[0] };
bool flag5 = !dictionary.ContainsKey(edge);
if (flag5)
{
dictionary.Add(edge, new List<int>());
}
dictionary[edge].Add(this.resultContainer.Indices.Count - 1);
bool flag6 = !this.indexForColor.ContainsKey(this.lastColor);
if (flag6)
{
this.resultContainer.Colors.Add(this.lastColor);
this.indexForColor.Add(
this.lastColor,
(uint)(this.resultContainer.Colors.Count - 1)
);
}
uint num7 = this.indexForColor[this.lastColor];
this.resultContainer.ColorIndices.Add(num7);
bool flag7 = !this.indexForId.ContainsKey(text);
if (flag7)
{
this.resultContainer.Ids.Add(text);
this.indexForId.Add(text, (uint)(this.resultContainer.Ids.Count - 1));
}
uint num8 = this.indexForId[text];
this.resultContainer.IdIndices.Add(num8);
}
}
foreach (Edge edge2 in dictionary.Keys)
{
List<int> list5 = dictionary[edge2];
bool flag8 = list5.Count > 1;
if (flag8)
{
foreach (int num9 in list5)
{
this.resultContainer.Indices[num9] =
this.resultContainer.Indices[num9] * -1;
}
}
}
}
public void OnLight(LightNode node) { }
public void OnRPC(RPCNode node) { }
private LinkedElementIdPath GetCurrentElementIdPath()
{
return new LinkedElementIdPath(
new List<ElementId>(this.linkIdStack) { this.elementIdStack.Peek() }
);
}
private readonly RGBA INVALID_COLOR = new RGBA
{
A = byte.MaxValue,
R = byte.MaxValue,
G = 0,
B = 0
};
private readonly Document document;
private readonly bool assignId;
private readonly Transform baseTransform;
private readonly IElementIdProvider elementIdProvider;
private GeometryRetrieverResult resultContainer;
private Stack<ElementId> elementIdStack = null;
private Stack<Transform> transformationStack = null;
private Stack<ElementId> linkIdStack = null;
private RGBA lastColor = default(RGBA);
private Dictionary<Position, int> indexForPosition;
private Dictionary<string, uint> indexForId;
private Dictionary<RGBA, uint> indexForColor;
}
}