291 lines
10 KiB
C#
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;
|
|||
|
|
}
|
|||
|
|
}
|