using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Reflection; using System.Security.Cryptography; using System.Text; using Autodesk.Revit.DB; using KGdev.BI3D.Revit.Common; using KGdev.BI3D.Revit.Common.Models; using Newtonsoft.Json; namespace KGdev.BI3D.Revit.ExporterV2 { public class Exporter : IExporter { public List Options { get { return new List(this.options); } } public string Description { get { return "Export all objects visible in the active view to 3DBI."; } } public Exporter( IBI3DViewsProvider viewsProvider, IGlobalStore globalStore, ILinkedDocumentsUtilities linkedDocumentsUtilities, //IAuthProvider authProvider, IElementIdProvider elementIdProvider ) { this.viewsProvider = viewsProvider; this.globalStore = globalStore; this.linkedDocumentsUtilities = linkedDocumentsUtilities; //this.authProvider = authProvider; this.elementIdProvider = elementIdProvider; } public Dictionary Export( View3D objectsView, string path, Dictionary optionValues ) { //if (!this.authProvider.ValidateToken(this.globalStore.GetToken())) //{ // throw new Exception("Failed to authorize."); //} Document document = objectsView.Document; GeometryRetrieverResult geometryRetrieverResult = new GeometryRetrieverResult(); Transform transform = Transform.Identity; if (optionValues.ContainsKey("origin_provider")) { string text = optionValues["origin_provider"].ToString(); bool flag4 = "project_basepoint" == text; if (flag4) { Element element = new FilteredElementCollector(document) .OfCategory(BuiltInCategory.OST_ProjectBasePoint) .FirstElement(); bool flag5 = element != null; if (flag5) { BoundingBoxXYZ boundingBoxXYZ = element.get_BoundingBox(objectsView); XYZ min = boundingBoxXYZ.Min; transform = Transform.CreateTranslation(min.Multiply(-1.0)); } } } bool flag6 = optionValues.ContainsKey("export_context"); if (flag6) { if ((bool)optionValues["export_context"]) { View3D contextView3D = this.viewsProvider.GetContextView3D(document); bool flag9 = contextView3D != null; if (flag9) { GeometryRetriever geometryRetriever = new GeometryRetriever( document, false, transform, geometryRetrieverResult, this.elementIdProvider ); new CustomExporter(document, geometryRetriever) { ShouldStopOnError = false }.Export(new List { contextView3D.Id }); } } } GeometryRetriever geometryRetriever2 = new GeometryRetriever( document, true, transform, geometryRetrieverResult, this.elementIdProvider ); new CustomExporter(document, geometryRetriever2) { ShouldStopOnError = false }.Export( new List { objectsView.Id } ); if (optionValues.ContainsKey("include_context_rooms")) { if ((bool)optionValues["include_context_rooms"]) { RoomGeometryRetriever roomGeometryRetriever = new RoomGeometryRetriever(); IList linkedDocuments = this.linkedDocumentsUtilities.GetLinkedDocuments( document, transform, true, new List() ); foreach (LinkedDocumentInformation linkedDocumentInformation in linkedDocuments) { roomGeometryRetriever.Start( linkedDocumentInformation.Document, false, linkedDocumentInformation.TransformToRoot, geometryRetrieverResult, this.elementIdProvider, linkedDocumentInformation.PassedLinkInstanceIds ); } } } if (optionValues.ContainsKey("include_business_rooms")) { if ((bool)optionValues["include_business_rooms"]) { RoomGeometryRetriever roomGeometryRetriever2 = new RoomGeometryRetriever(); IList linkedDocuments2 = this.linkedDocumentsUtilities.GetLinkedDocuments( document, transform, true, new List() ); foreach ( LinkedDocumentInformation linkedDocumentInformation2 in linkedDocuments2 ) { roomGeometryRetriever2.Start( linkedDocumentInformation2.Document, true, linkedDocumentInformation2.TransformToRoot, geometryRetrieverResult, this.elementIdProvider, linkedDocumentInformation2.PassedLinkInstanceIds ); } } } using (MemoryStream memoryStream = new MemoryStream()) { byte[] bytes = Encoding.UTF8.GetBytes("3dbi"); memoryStream.Write(bytes, 0, bytes.Length); byte[] bytes2 = BitConverter.GetBytes(2U); bool isLittleEndian = BitConverter.IsLittleEndian; if (isLittleEndian) { Array.Reverse(bytes2); } memoryStream.Write(bytes2, 0, bytes2.Length); long num = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); byte[] bytes3 = BitConverter.GetBytes((uint)num); bool isLittleEndian2 = BitConverter.IsLittleEndian; if (isLittleEndian2) { Array.Reverse(bytes3); } memoryStream.Write(bytes3, 0, bytes3.Length); //int num2 = this.authProvider.LicenseTypeInt(this.globalStore.GetToken()); //byte[] bytes4 = BitConverter.GetBytes((uint)num2); //bool isLittleEndian3 = BitConverter.IsLittleEndian; //if (isLittleEndian3) //{ // Array.Reverse(bytes4); //} //memoryStream.Write(bytes4, 0, bytes4.Length); byte[] bytes5 = BitConverter.GetBytes((uint)geometryRetrieverResult.Ids.Count); bool isLittleEndian4 = BitConverter.IsLittleEndian; if (isLittleEndian4) { Array.Reverse(bytes5); } memoryStream.Write(bytes5, 0, bytes5.Length); foreach (string text2 in geometryRetrieverResult.Ids) { byte[] bytes6 = Encoding.UTF8.GetBytes(text2); byte[] bytes7 = BitConverter.GetBytes((uint)bytes6.Length); bool isLittleEndian5 = BitConverter.IsLittleEndian; if (isLittleEndian5) { Array.Reverse(bytes7); } memoryStream.Write(bytes7, 0, bytes7.Length); memoryStream.Write(bytes6, 0, bytes6.Length); } string text3 = Convert.ToBase64String(memoryStream.ToArray()); SHA512Managed sha512Managed = new SHA512Managed(); byte[] array = sha512Managed.ComputeHash(Encoding.UTF8.GetBytes(text3)); HasherInput hasherInput = new HasherInput { Token = this.globalStore.GetToken(), HexSha512Hash = BitConverter.ToString(array).Replace("-", "") }; string text4 = Path.Combine( this.globalStore.GetAppTempDirectoryPath(), "v1hin.temp" ); string text5 = JsonConvert.SerializeObject(hasherInput); File.WriteAllText(text4, text5); string text6 = ""; using (Process process = new Process()) { process.StartInfo.FileName = "\"" + Path.Combine( Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "KGdev.BI3D.Hasher.V1.exe" ) + "\""; process.StartInfo.Arguments = string.Format( "\"{0}\"", text4.Replace("\\\\", "/") ); process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardOutput = true; process.Start(); text6 = process.StandardOutput.ReadToEnd(); process.WaitForExit(); } string[] array2 = text6.Split( new string[] { "signature:" }, StringSplitOptions.None ); bool flag16 = array2.Length != 2; if (flag16) { throw new Exception(text6); } text6 = array2[1]; byte[] bytes8 = BitConverter.GetBytes((uint)text6.Length); bool isLittleEndian6 = BitConverter.IsLittleEndian; if (isLittleEndian6) { Array.Reverse(bytes8); } memoryStream.Write(bytes8, 0, bytes8.Length); byte[] bytes9 = Encoding.UTF8.GetBytes(text6); memoryStream.Write(bytes9, 0, bytes9.Length); byte[] bytes10 = BitConverter.GetBytes((uint)geometryRetrieverResult.Colors.Count); bool isLittleEndian7 = BitConverter.IsLittleEndian; if (isLittleEndian7) { Array.Reverse(bytes10); } memoryStream.Write(bytes10, 0, bytes10.Length); foreach (RGBA rgba in geometryRetrieverResult.Colors) { byte[] array3 = new byte[] { rgba.R, rgba.G, rgba.B, rgba.A }; memoryStream.Write(array3, 0, 4); } byte[] bytes11 = BitConverter.GetBytes( (uint)geometryRetrieverResult.Positions.Count ); bool isLittleEndian8 = BitConverter.IsLittleEndian; if (isLittleEndian8) { Array.Reverse(bytes11); } memoryStream.Write(bytes11, 0, bytes11.Length); foreach (Position position in geometryRetrieverResult.Positions) { float[] array4 = new float[] { position.X, position.Y, position.Z }; foreach (float num3 in array4) { byte[] bytes12 = BitConverter.GetBytes(num3); bool isLittleEndian9 = BitConverter.IsLittleEndian; if (isLittleEndian9) { Array.Reverse(bytes12); } memoryStream.Write(bytes12, 0, bytes12.Length); } } byte[] bytes13 = BitConverter.GetBytes((uint)geometryRetrieverResult.Indices.Count); bool isLittleEndian10 = BitConverter.IsLittleEndian; if (isLittleEndian10) { Array.Reverse(bytes13); } memoryStream.Write(bytes13, 0, bytes13.Length); foreach (int num4 in geometryRetrieverResult.Indices) { byte[] bytes14 = BitConverter.GetBytes(num4); bool isLittleEndian11 = BitConverter.IsLittleEndian; if (isLittleEndian11) { Array.Reverse(bytes14); } memoryStream.Write(bytes14, 0, bytes14.Length); } byte[] bytes15 = BitConverter.GetBytes( (uint)geometryRetrieverResult.ColorIndices.Count ); bool isLittleEndian12 = BitConverter.IsLittleEndian; if (isLittleEndian12) { Array.Reverse(bytes15); } memoryStream.Write(bytes15, 0, bytes15.Length); foreach (uint num5 in geometryRetrieverResult.ColorIndices) { byte[] bytes16 = BitConverter.GetBytes(num5); bool isLittleEndian13 = BitConverter.IsLittleEndian; if (isLittleEndian13) { Array.Reverse(bytes16); } memoryStream.Write(bytes16, 0, bytes16.Length); } byte[] bytes17 = BitConverter.GetBytes( (uint)geometryRetrieverResult.IdIndices.Count ); bool isLittleEndian14 = BitConverter.IsLittleEndian; if (isLittleEndian14) { Array.Reverse(bytes17); } memoryStream.Write(bytes17, 0, bytes17.Length); foreach (uint num6 in geometryRetrieverResult.IdIndices) { byte[] bytes18 = BitConverter.GetBytes(num6); bool isLittleEndian15 = BitConverter.IsLittleEndian; if (isLittleEndian15) { Array.Reverse(bytes18); } memoryStream.Write(bytes18, 0, bytes18.Length); } bool flag17 = optionValues.ContainsKey("include_scenes") && (bool)optionValues["include_scenes"]; if (flag17) { List scenes = this.viewsProvider.GetScenes(document); byte[] bytes19 = BitConverter.GetBytes((uint)scenes.Count); bool isLittleEndian16 = BitConverter.IsLittleEndian; if (isLittleEndian16) { Array.Reverse(bytes19); } memoryStream.Write(bytes19, 0, bytes19.Length); foreach (View3D view3D in scenes) { string sceneName = this.viewsProvider.GetSceneName(view3D); byte[] bytes20 = Encoding.UTF8.GetBytes(sceneName); byte[] bytes21 = BitConverter.GetBytes((uint)bytes20.Length); bool isLittleEndian17 = BitConverter.IsLittleEndian; if (isLittleEndian17) { Array.Reverse(bytes21); } memoryStream.Write(bytes21, 0, bytes21.Length); memoryStream.Write(bytes20, 0, bytes20.Length); ViewOrientation3D orientation = view3D.GetOrientation(); Position position2 = orientation.EyePosition.To3DBIPosition(); Position position3 = ( orientation.EyePosition + orientation.ForwardDirection * 82.0 ).To3DBIPosition(); float[] array6 = new float[] { position2.X, position2.Y, position2.Z, position3.X, position3.Y, position3.Z }; foreach (float num7 in array6) { byte[] bytes22 = BitConverter.GetBytes(num7); bool isLittleEndian18 = BitConverter.IsLittleEndian; if (isLittleEndian18) { Array.Reverse(bytes22); } memoryStream.Write(bytes22, 0, bytes22.Length); } } } else { byte[] bytes23 = BitConverter.GetBytes(0U); bool isLittleEndian19 = BitConverter.IsLittleEndian; if (isLittleEndian19) { Array.Reverse(bytes23); } memoryStream.Write(bytes23, 0, bytes23.Length); } using (FileStream fileStream = new FileStream(path, FileMode.OpenOrCreate)) { using ( ZipArchive zipArchive = new ZipArchive( fileStream, ZipArchiveMode.Create, false ) ) { ZipArchiveEntry zipArchiveEntry = zipArchive.CreateEntry("v2.3dbi"); using (Stream stream = zipArchiveEntry.Open()) { memoryStream.Position = 0L; memoryStream.CopyTo(stream); } } } } return geometryRetrieverResult.ExportedElementIdPathById; } private const string HASHER_INPUT_FILE_NAME = "v1hin.temp"; private const string FILE_HEADER = "3dbi"; private const uint FILE_VERSION = 2U; private const string ZIP_ENTRY_NAME = "v2.3dbi"; private const string HASHER_EXECUTABLE_NAME = "KGdev.BI3D.Hasher.V1.exe"; private const string OPTION_ID_EXPORT_CONTEXT = "export_context"; private const string OPTION_ID_INCLUDE_CONTEXT_ROOMS = "include_context_rooms"; private const string OPTION_ID_INCLUDE_BUSINESS_ROOMS = "include_business_rooms"; private const string OPTION_ID_INCLUDE_SCENES = "include_scenes"; private const string OPTION_ID_ORIGIN_PROVIDER = "origin_provider"; private const string OPTION_SELECT_VALUE_ID_DEFAULT_ORIGIN = "default_origin"; private const string OPTION_SELECT_VALUE_ID_PROJECT_BASEPOINT = "project_basepoint"; private const string DESCRIPTION = "Export all objects visible in the active view to 3DBI."; private const double SCENES_TARGET_DISTANCE_FEET = 82.0; private readonly IBI3DViewsProvider viewsProvider; private readonly IGlobalStore globalStore; private readonly ILinkedDocumentsUtilities linkedDocumentsUtilities; //private readonly IAuthProvider authProvider; private readonly IElementIdProvider elementIdProvider; private List options = new List { new OptionDefinition { Id = "export_context", OptionValueType = OptionValueType.BOOLEAN, Label = "Export Context", Description = "Export objects that are visible in the \"3DBI-Context\" view as Context Objects. Context Objects are static objects that are always visible.", DefaultValue = true }, new OptionDefinition { Id = "include_business_rooms", OptionValueType = OptionValueType.BOOLEAN, Label = "Include Rooms & Spaces", Description = "Export rooms and spaces as Business Objects. All rooms in the active document will be exported and have their Element Id assigned as Object Identifier.", DefaultValue = true }, new OptionDefinition { Id = "include_context_rooms", OptionValueType = OptionValueType.BOOLEAN, Label = "Include Rooms & Spaces as Context", Description = "Export rooms and spaces as Context Objects. Context Objects are static objects that are always visible.", DefaultValue = false }, new OptionDefinition { Id = "include_scenes", OptionValueType = OptionValueType.BOOLEAN, Label = "Export Scenes", Description = "Export camera positions of all perspective views with a \"3DBI_\" prefix in their name as 3dbi scenes.", DefaultValue = false }, new OptionDefinition { Id = "origin_provider", OptionValueType = OptionValueType.SELECT, Label = "Model Origin", Description = "Specify which origin (point 0, 0, 0) to use.", PossibleValues = new List { new SelectOptionDefinitionValue { Value = "default_origin", Label = "Default Origin" }, new SelectOptionDefinitionValue { Value = "project_basepoint", Label = "Project Basepoint" } }, DefaultValue = "default_origin" } }; } }