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(); this.linkIdStack = new Stack(); this.transformationStack = new Stack(); this.transformationStack.Push(this.baseTransform); this.indexForPosition = new Dictionary(); 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(); 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(); 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 list = ( from p in node.GetPoints() select currentTransformation.OfPoint(p) into x select x.To3DBIPosition() ).ToList(); List> list2 = ( from f in node.GetFacets() select new List { (uint)f.V1, (uint)f.V2, (uint)f.V3 } ).ToList>(); Dictionary> dictionary = new Dictionary>(); for (int i = 0; i < list2.Count; i++) { List 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 list4 = new List { 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()); } 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 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(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 elementIdStack = null; private Stack transformationStack = null; private Stack linkIdStack = null; private RGBA lastColor = default(RGBA); private Dictionary indexForPosition; private Dictionary indexForId; private Dictionary indexForColor; } }