267 lines
15 KiB
C#
267 lines
15 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 RoomGeometryRetriever
|
|
{
|
|
public bool Start(
|
|
Document document,
|
|
bool assignId,
|
|
Transform baseTransform,
|
|
GeometryRetrieverResult resultContainer,
|
|
IElementIdProvider elementIdProvider,
|
|
List<ElementId> linkedParentElementIds
|
|
)
|
|
{
|
|
this.indexForPosition = new Dictionary<Position, int>();
|
|
for (int i = 0; i < resultContainer.Positions.Count; i++)
|
|
{
|
|
Position position = resultContainer.Positions[i];
|
|
this.indexForPosition.Add(position, i);
|
|
}
|
|
this.indexForId = new Dictionary<string, uint>();
|
|
uint num = 0U;
|
|
while ((ulong)num < (ulong)((long)resultContainer.Ids.Count))
|
|
{
|
|
string text = 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)resultContainer.Colors.Count))
|
|
{
|
|
RGBA rgba = resultContainer.Colors[(int)num2];
|
|
this.indexForColor.Add(rgba, num2);
|
|
num2 += 1U;
|
|
}
|
|
ElementMulticategoryFilter elementMulticategoryFilter = new ElementMulticategoryFilter(
|
|
new List<BuiltInCategory>
|
|
{
|
|
BuiltInCategory.OST_MEPSpaces,
|
|
BuiltInCategory.OST_Rooms
|
|
}
|
|
);
|
|
List<Element> list = new FilteredElementCollector(document)
|
|
.WherePasses(elementMulticategoryFilter)
|
|
.WhereElementIsNotElementType()
|
|
.ToList<Element>();
|
|
SpatialElementGeometryCalculator spatialElementGeometryCalculator =
|
|
new SpatialElementGeometryCalculator(
|
|
document,
|
|
new SpatialElementBoundaryOptions
|
|
{
|
|
SpatialElementBoundaryLocation = 0,
|
|
StoreFreeBoundaryFaces = true
|
|
}
|
|
);
|
|
foreach (Element element in list)
|
|
{
|
|
SpatialElement spatialElement = element as SpatialElement;
|
|
bool flag = spatialElement == null;
|
|
if (!flag)
|
|
{
|
|
bool flag2 = spatialElement.Location == null;
|
|
if (!flag2)
|
|
{
|
|
bool flag3 = spatialElement.Area <= 0.0;
|
|
if (!flag3)
|
|
{
|
|
SpatialElementGeometryResults spatialElementGeometryResults;
|
|
try
|
|
{
|
|
spatialElementGeometryResults =
|
|
spatialElementGeometryCalculator.CalculateSpatialElementGeometry(
|
|
spatialElement
|
|
);
|
|
}
|
|
catch
|
|
{
|
|
continue;
|
|
}
|
|
bool flag4 = spatialElementGeometryResults == null;
|
|
if (!flag4)
|
|
{
|
|
string text2 = "";
|
|
if (assignId)
|
|
{
|
|
LinkedElementIdPath linkedElementIdPath =
|
|
new LinkedElementIdPath(
|
|
new List<ElementId>(linkedParentElementIds)
|
|
{
|
|
spatialElement.Id
|
|
}
|
|
);
|
|
text2 = elementIdProvider.GetElementId(linkedElementIdPath);
|
|
resultContainer
|
|
.ExportedElementIdPathById
|
|
.Add(text2, linkedElementIdPath);
|
|
}
|
|
Solid geometry = spatialElementGeometryResults.GetGeometry();
|
|
FaceArray faces = geometry.Faces;
|
|
foreach (object obj in faces)
|
|
{
|
|
Face face = (Face)obj;
|
|
Dictionary<Edge, List<int>> dictionary =
|
|
new Dictionary<Edge, List<int>>();
|
|
IList<SpatialElementBoundarySubface> boundaryFaceInfo =
|
|
spatialElementGeometryResults.GetBoundaryFaceInfo(face);
|
|
foreach (
|
|
SpatialElementBoundarySubface spatialElementBoundarySubface in boundaryFaceInfo
|
|
)
|
|
{
|
|
Face subface = spatialElementBoundarySubface.GetSubface();
|
|
bool flag5 = null == subface;
|
|
if (!flag5)
|
|
{
|
|
Mesh mesh = subface.Triangulate();
|
|
bool flag6 = null == mesh;
|
|
if (!flag6)
|
|
{
|
|
for (int j = 0; j < mesh.NumTriangles; j++)
|
|
{
|
|
MeshTriangle meshTriangle = mesh.get_Triangle(
|
|
j
|
|
);
|
|
for (int k = 0; k < 3; k++)
|
|
{
|
|
Position position2 = baseTransform
|
|
.OfPoint(meshTriangle.get_Vertex(k))
|
|
.To3DBIPosition();
|
|
bool flag7 =
|
|
!this.indexForPosition.ContainsKey(
|
|
position2
|
|
);
|
|
if (flag7)
|
|
{
|
|
resultContainer
|
|
.Positions
|
|
.Add(position2);
|
|
this.indexForPosition.Add(
|
|
position2,
|
|
resultContainer.Positions.Count - 1
|
|
);
|
|
}
|
|
int num3 = this.indexForPosition[position2];
|
|
resultContainer.Indices.Add(num3);
|
|
int num4 = ((k == 2) ? 0 : (k + 1));
|
|
Position position3 = baseTransform
|
|
.OfPoint(meshTriangle.get_Vertex(num4))
|
|
.To3DBIPosition();
|
|
bool flag8 =
|
|
!this.indexForPosition.ContainsKey(
|
|
position3
|
|
);
|
|
if (flag8)
|
|
{
|
|
resultContainer
|
|
.Positions
|
|
.Add(position3);
|
|
this.indexForPosition.Add(
|
|
position3,
|
|
resultContainer.Positions.Count - 1
|
|
);
|
|
}
|
|
int num5 = this.indexForPosition[position3];
|
|
List<int> list2 = new List<int>
|
|
{
|
|
num3,
|
|
num5
|
|
};
|
|
list2.Sort();
|
|
Edge edge = new Edge
|
|
{
|
|
LargestIndex = list2[1],
|
|
SmallestIndex = list2[0]
|
|
};
|
|
bool flag9 = !dictionary.ContainsKey(edge);
|
|
if (flag9)
|
|
{
|
|
dictionary.Add(edge, new List<int>());
|
|
}
|
|
dictionary[edge].Add(
|
|
resultContainer.Indices.Count - 1
|
|
);
|
|
bool flag10 = !this.indexForId.ContainsKey(
|
|
text2
|
|
);
|
|
if (flag10)
|
|
{
|
|
resultContainer.Ids.Add(text2);
|
|
this.indexForId.Add(
|
|
text2,
|
|
(uint)(
|
|
resultContainer.Ids.Count - 1
|
|
)
|
|
);
|
|
}
|
|
uint num6 = this.indexForId[text2];
|
|
resultContainer.IdIndices.Add(num6);
|
|
bool flag11 =
|
|
!this.indexForColor.ContainsKey(
|
|
this.ROOM_COLOR
|
|
);
|
|
if (flag11)
|
|
{
|
|
resultContainer
|
|
.Colors
|
|
.Add(this.ROOM_COLOR);
|
|
this.indexForColor.Add(
|
|
this.ROOM_COLOR,
|
|
(uint)(
|
|
resultContainer.Colors.Count - 1
|
|
)
|
|
);
|
|
}
|
|
uint num7 = this.indexForColor[
|
|
this.ROOM_COLOR
|
|
];
|
|
resultContainer.ColorIndices.Add(num7);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
foreach (Edge edge2 in dictionary.Keys)
|
|
{
|
|
List<int> list3 = dictionary[edge2];
|
|
bool flag12 = list3.Count > 1;
|
|
if (flag12)
|
|
{
|
|
foreach (int num8 in list3)
|
|
{
|
|
resultContainer.Indices[num8] =
|
|
resultContainer.Indices[num8] * -1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private RGBA ROOM_COLOR = new RGBA
|
|
{
|
|
R = byte.MaxValue,
|
|
G = byte.MaxValue,
|
|
B = byte.MaxValue,
|
|
A = 100
|
|
};
|
|
|
|
private Dictionary<Position, int> indexForPosition;
|
|
|
|
private Dictionary<string, uint> indexForId;
|
|
|
|
private Dictionary<RGBA, uint> indexForColor;
|
|
}
|
|
}
|