commit 1ccc4b3047702b4da6eabc4f6b3424510040e1c7
Author: GG Z <903524121@qq.com>
Date: Mon Jan 8 09:30:50 2024 +0800
添加项目文件。
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..1ff0c42
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,63 @@
+###############################################################################
+# Set default behavior to automatically normalize line endings.
+###############################################################################
+* text=auto
+
+###############################################################################
+# Set default behavior for command prompt diff.
+#
+# This is need for earlier builds of msysgit that does not have it on by
+# default for csharp files.
+# Note: This is only used by command line
+###############################################################################
+#*.cs diff=csharp
+
+###############################################################################
+# Set the merge driver for project and solution files
+#
+# Merging from the command prompt will add diff markers to the files if there
+# are conflicts (Merging from VS is not affected by the settings below, in VS
+# the diff markers are never inserted). Diff markers may cause the following
+# file extensions to fail to load in VS. An alternative would be to treat
+# these files as binary and thus will always conflict and require user
+# intervention with every merge. To do so, just uncomment the entries below
+###############################################################################
+#*.sln merge=binary
+#*.csproj merge=binary
+#*.vbproj merge=binary
+#*.vcxproj merge=binary
+#*.vcproj merge=binary
+#*.dbproj merge=binary
+#*.fsproj merge=binary
+#*.lsproj merge=binary
+#*.wixproj merge=binary
+#*.modelproj merge=binary
+#*.sqlproj merge=binary
+#*.wwaproj merge=binary
+
+###############################################################################
+# behavior for image files
+#
+# image files are treated as binary by default.
+###############################################################################
+#*.jpg binary
+#*.png binary
+#*.gif binary
+
+###############################################################################
+# diff behavior for common document formats
+#
+# Convert binary document formats to text before diffing them. This feature
+# is only available from the command line. Turn it on by uncommenting the
+# entries below.
+###############################################################################
+#*.doc diff=astextplain
+#*.DOC diff=astextplain
+#*.docx diff=astextplain
+#*.DOCX diff=astextplain
+#*.dot diff=astextplain
+#*.DOT diff=astextplain
+#*.pdf diff=astextplain
+#*.PDF diff=astextplain
+#*.rtf diff=astextplain
+#*.RTF diff=astextplain
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9491a2f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,363 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+
+# User-specific files
+*.rsuser
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Mono auto generated files
+mono_crash.*
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+[Ww][Ii][Nn]32/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+bld/
+[Bb]in/
+[Oo]bj/
+[Oo]ut/
+[Ll]og/
+[Ll]ogs/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUnit
+*.VisualState.xml
+TestResult.xml
+nunit-*.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# ASP.NET Scaffolding
+ScaffoldingReadMe.txt
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_h.h
+*.ilk
+*.meta
+*.obj
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*_wpftmp.csproj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Coverlet is a free, cross platform Code Coverage Tool
+coverage*.json
+coverage*.xml
+coverage*.info
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# NuGet Symbol Packages
+*.snupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+*.appxbundle
+*.appxupload
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+*- [Bb]ackup.rdl
+*- [Bb]ackup ([0-9]).rdl
+*- [Bb]ackup ([0-9][0-9]).rdl
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# CodeRush personal settings
+.cr/personal
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
+MigrationBackup/
+
+# Ionide (cross platform F# VS Code tools) working folder
+.ionide/
+
+# Fody - auto-generated XML schema
+FodyWeavers.xsd
\ No newline at end of file
diff --git a/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/AssemblyLoaderUtil.cs b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/AssemblyLoaderUtil.cs
new file mode 100644
index 0000000..cdb34fe
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/AssemblyLoaderUtil.cs
@@ -0,0 +1,148 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Threading;
+
+namespace KGdev.BI3D.Revit.Addin.MainWindow.External.Browser
+{
+ public class AssemblyLoaderUtil
+ {
+ public AssemblyLoaderUtil(string assemblyDir)
+ {
+ AssemblyDirectory = assemblyDir;
+ }
+
+ public string AssemblyDirectory { get; set; }
+
+ public void HookAssemblyResolve()
+ {
+ AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
+ }
+
+ ///
+ /// 加载目录下的所有程序集
+ ///
+ ///
+ ///
+ public List LoadAllRibbonAssemblies(string commandFolderPath)
+ {
+ var list = new List();
+ foreach (var assemblyFile in Directory.GetFiles(commandFolderPath, "*.dll"))
+ {
+ try
+ {
+ list.Add(Assembly.LoadFrom(assemblyFile));
+ }
+ catch
+ {
+ // ignored
+ }
+ }
+
+ return list;
+ }
+
+ /////
+ ///// 调用此方法解决UI程序集丢失
+ /////
+ /////
+ //public static void ResolveAssembly(Action action)
+ //{
+ // string addInPath = typeof(AssemblyLoaderUtil).Assembly.Location;
+ // string dirAssembly = Path.GetDirectoryName(addInPath);
+ // AssemblyLoaderUtil loaderUtil = new AssemblyLoaderUtil(dirAssembly);
+ // loaderUtil.HookAssemblyResolve();
+ // try
+ // {
+ // action();
+ // }
+ // catch (Exception ex)
+ // {
+ // MessageBox.Show(ex.InnerException?.ToString());
+ // }
+ // finally
+ // {
+ // loaderUtil.UnhookAssemblyResolve();
+ // }
+ //}
+
+ public void UnhookAssemblyResolve()
+ {
+ AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve;
+ }
+
+ private Assembly LoadAddin(string filePath)
+ {
+ Assembly result;
+ try
+ {
+ Monitor.Enter(this);
+ result = Assembly.LoadFile(filePath);
+ }
+ finally
+ {
+ Monitor.Exit(this);
+ }
+
+ return result;
+ }
+
+ private string SearchAssemblyFile(string assemblyName)
+ {
+ string[] array = { ".dll", ".exe" };
+ var str = assemblyName.Substring(0, assemblyName.IndexOf(','));
+ foreach (var str2 in array)
+ {
+ var text = AssemblyDirectory + "\\" + str + str2;
+ if (File.Exists(text))
+ {
+ return text;
+ }
+ }
+
+ return string.Empty;
+ }
+
+ private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
+ {
+ Assembly result;
+ _ = new AssemblyName(args.Name);
+ var text = SearchAssemblyFile(args.Name);
+ if (File.Exists(text))
+ {
+ result = LoadAddin(text);
+ }
+ else
+ {
+ if (string.IsNullOrEmpty(text))
+ {
+ var array = args.Name.Split(',');
+ var text2 = array[0];
+ if (array.Length > 1)
+ {
+ var text3 = array[2];
+ if (
+ text2.EndsWith(".resources", StringComparison.CurrentCultureIgnoreCase)
+ && !text3.EndsWith("neutral", StringComparison.CurrentCultureIgnoreCase)
+ )
+ {
+ text2 = text2.Substring(0, text2.Length - ".resources".Length);
+ }
+
+ text = SearchAssemblyFile(text2);
+ if (File.Exists(text))
+ {
+ return LoadAddin(text);
+ }
+ //text = this.SearchAssemblyFile(text2);
+ }
+ }
+
+ result = LoadAddin(text);
+ }
+
+ return result;
+ }
+ }
+}
diff --git a/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/BrowserConfiguration.cs b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/BrowserConfiguration.cs
new file mode 100644
index 0000000..726f300
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/BrowserConfiguration.cs
@@ -0,0 +1,25 @@
+using System;
+
+namespace KGdev.BI3D.Revit.Addin.MainWindow.External.Browser
+{
+ internal class BrowserConfiguration
+ {
+ public string Title { get; set; }
+
+ public string CachePath { get; set; }
+
+ public IntPtr MessageHandle { get; set; } = IntPtr.Zero;
+
+ public int ParentProcessId { get; set; } = -1;
+
+ public string Url { get; set; }
+
+ public string Net2JsObjectName { get; set; }
+
+ public string Net2JsUpdateStatePartialFunctionName { get; set; }
+
+ public string Js2NetObjectName { get; set; }
+
+ public string RevitVersion { get; set; }
+ }
+}
diff --git a/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/BrowserForm.Designer.cs b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/BrowserForm.Designer.cs
new file mode 100644
index 0000000..7376793
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/BrowserForm.Designer.cs
@@ -0,0 +1,55 @@
+namespace KGdev.BI3D.Revit.Addin.MainWindow.External.Browser
+{
+ internal partial class BrowserForm : global::System.Windows.Forms.Form
+ {
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && this.components != null)
+ {
+ this.components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ private void InitializeComponent()
+ {
+ global::System.ComponentModel.ComponentResourceManager componentResourceManager = new global::System.ComponentModel.ComponentResourceManager(typeof(global::KGdev.BI3D.Revit.Addin.MainWindow.External.Browser.BrowserForm));
+ this.panelBrowser = new global::System.Windows.Forms.Panel();
+ this.loader = new global::System.Windows.Forms.PictureBox();
+ this.panelBrowser.SuspendLayout();
+ ((global::System.ComponentModel.ISupportInitialize)this.loader).BeginInit();
+ base.SuspendLayout();
+ this.panelBrowser.Controls.Add(this.loader);
+ this.panelBrowser.Dock = global::System.Windows.Forms.DockStyle.Fill;
+ this.panelBrowser.Location = new global::System.Drawing.Point(0, 0);
+ this.panelBrowser.Name = "panelBrowser";
+ this.panelBrowser.Size = new global::System.Drawing.Size(800, 450);
+ this.panelBrowser.TabIndex = 0;
+ this.loader.BackColor = global::System.Drawing.Color.White;
+ this.loader.Dock = global::System.Windows.Forms.DockStyle.Fill;
+ this.loader.Image = (global::System.Drawing.Image)componentResourceManager.GetObject("loader.Image");
+ this.loader.Location = new global::System.Drawing.Point(0, 0);
+ this.loader.Name = "loader";
+ this.loader.Size = new global::System.Drawing.Size(800, 450);
+ this.loader.SizeMode = global::System.Windows.Forms.PictureBoxSizeMode.Zoom;
+ this.loader.TabIndex = 0;
+ this.loader.TabStop = false;
+ base.AutoScaleDimensions = new global::System.Drawing.SizeF(6f, 13f);
+ base.AutoScaleMode = global::System.Windows.Forms.AutoScaleMode.Font;
+ base.ClientSize = new global::System.Drawing.Size(800, 450);
+ base.Controls.Add(this.panelBrowser);
+ base.Icon = (global::System.Drawing.Icon)componentResourceManager.GetObject("$this.Icon");
+ base.Name = "BrowserForm";
+ this.Text = "3DBI";
+ this.panelBrowser.ResumeLayout(false);
+ ((global::System.ComponentModel.ISupportInitialize)this.loader).EndInit();
+ base.ResumeLayout(false);
+ }
+
+ private global::System.ComponentModel.IContainer components = null;
+
+ private global::System.Windows.Forms.Panel panelBrowser;
+
+ private global::System.Windows.Forms.PictureBox loader;
+ }
+}
diff --git a/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/BrowserForm.cs b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/BrowserForm.cs
new file mode 100644
index 0000000..776d859
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/BrowserForm.cs
@@ -0,0 +1,327 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Drawing;
+using System.IO;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Security;
+using System.Windows.Forms;
+using CefSharp;
+using CefSharp.WinForms;
+using KGdev.BI3D.Revit.Addin.MainWindow.External.Browser.Properties;
+
+namespace KGdev.BI3D.Revit.Addin.MainWindow.External.Browser
+{
+ internal partial class BrowserForm : Form
+ {
+ public BrowserForm(
+ BrowserConfiguration configuration,
+ BrowserFunctions functions,
+ Queue browserToRevitActions,
+ Queue revitToBrowserActions
+ )
+ {
+ this.configuration = configuration;
+ this.functions = functions;
+ this.browserToRevitActions = browserToRevitActions;
+ this.revitToBrowserActions = revitToBrowserActions;
+ //AssemblyLoaderUtil loaderUtil = new AssemblyLoaderUtil(
+ // Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
+ // );
+ //loaderUtil.HookAssemblyResolve();
+ //try
+ //{
+
+ //}
+ //catch (Exception ex)
+ //{
+ // MessageBox.Show(ex.Message);
+ //}
+ //finally
+ //{
+ // loaderUtil.UnhookAssemblyResolve();
+ //}
+ var dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+ //Assembly.LoadFrom(dir + "//CefSharp.Core.dll");
+ //Assembly.LoadFile(
+ // @"D:\Users\Zhanggg\Desktop\KGdev.BI3D.Revit\KGdev.BI3D.Revit.Addin.MainWindow.External.Browser\bin\Debug\net472\CefSharp.dll"
+ //);
+ //Assembly.LoadFile(
+ // @"D:\Users\Zhanggg\Desktop\KGdev.BI3D.Revit\KGdev.BI3D.Revit.Addin.MainWindow.External.Browser\bin\Debug\net472\CefSharp.Core.dll"
+ //);
+ //Assembly.LoadFile(
+ // @"D:\Users\Zhanggg\Desktop\KGdev.BI3D.Revit\KGdev.BI3D.Revit.Addin.MainWindow.External.Browser\bin\Debug\net472\CefSharp.WinForms.dll"
+ //);
+ base.Load += (object sender, EventArgs args) =>
+ {
+ this.CreateBrowser();
+
+ Size windowSize = Settings.Default.WindowSize;
+ bool flag2 = true;
+ if (flag2)
+ {
+ base.Size = Settings.Default.WindowSize;
+ }
+ base.FormClosing += this.Form_Browser_FormClosing;
+ base.FormClosed += this.Form_Browser_FormClosed;
+ };
+ this.InitializeComponent();
+ this.Text = configuration.Title;
+ bool flag = configuration.ParentProcessId > 0;
+ if (flag)
+ {
+ try
+ {
+ Process processById = Process.GetProcessById(configuration.ParentProcessId);
+ IntPtr mainWindowHandle = processById.MainWindowHandle;
+ BrowserForm.NativeMethod.SetWindowLongPtr64(base.Handle, -8, mainWindowHandle);
+ }
+ catch { }
+ }
+ this.SendMessage("handle:" + base.Handle.ToString());
+ this.actionTimer.Tick += this.Action_timer_Tick;
+ this.actionTimer.Start();
+ }
+
+ private void Action_timer_Tick(object sender, EventArgs e)
+ {
+ bool flag = this.browserToRevitActions.Count > 0;
+ if (flag)
+ {
+ string text = this.browserToRevitActions.Dequeue();
+ this.SendMessage(text);
+ }
+ bool flag2 = this.revitToBrowserActions.Count > 0;
+ if (flag2)
+ {
+ string text2 = this.revitToBrowserActions.Dequeue();
+ this.browser.ExecuteScriptAsync(
+ string.Concat(
+ new string[]
+ {
+ this.configuration.Net2JsObjectName,
+ ".",
+ this.configuration.Net2JsUpdateStatePartialFunctionName,
+ "(",
+ text2,
+ ")"
+ }
+ )
+ );
+ }
+ bool flag3 = this.configuration.ParentProcessId > 0;
+ if (flag3)
+ {
+ try
+ {
+ Process processById = Process.GetProcessById(
+ this.configuration.ParentProcessId
+ );
+ }
+ catch
+ {
+ base.Close();
+ }
+ }
+ }
+
+ private void SendMessage(string message)
+ {
+ BrowserForm.MyStruct myStruct;
+ myStruct.Message = message;
+ int num = Marshal.SizeOf(myStruct);
+ IntPtr intPtr = Marshal.AllocHGlobal(num);
+ try
+ {
+ Marshal.StructureToPtr(myStruct, intPtr, true);
+ BrowserForm.COPYDATASTRUCT copydatastruct = new BrowserForm.COPYDATASTRUCT
+ {
+ cbData = num,
+ lpData = intPtr
+ };
+ BrowserForm
+ .NativeMethod
+ .SendMessage(
+ this.configuration.MessageHandle,
+ 74,
+ base.Handle,
+ ref copydatastruct
+ );
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(intPtr);
+ }
+ }
+
+ protected override void WndProc(ref Message m)
+ {
+ bool flag = m.Msg == 74;
+ if (flag)
+ {
+ BrowserForm.COPYDATASTRUCT copydatastruct = (BrowserForm.COPYDATASTRUCT)
+ m.GetLParam(typeof(BrowserForm.COPYDATASTRUCT));
+ bool flag2 = copydatastruct.cbData == Marshal.SizeOf(typeof(BrowserForm.MyStruct));
+ if (flag2)
+ {
+ BrowserForm.MyStruct myStruct = (BrowserForm.MyStruct)
+ Marshal.PtrToStructure(copydatastruct.lpData, typeof(BrowserForm.MyStruct));
+ this.revitToBrowserActions.Enqueue(myStruct.Message);
+ base.Visible = true;
+ base.Activate();
+ }
+ }
+ base.WndProc(ref m);
+ }
+
+ private bool CreateBrowser()
+ {
+ CefSettings cefSettings = new CefSettings();
+ cefSettings.PackLoadingDisabled = false;
+ cefSettings.LogSeverity = LogSeverity.Disable;
+ cefSettings.BrowserSubprocessPath =
+ this.assemblyDirectory + "\\CefSharp.BrowserSubprocess.exe";
+ cefSettings.CachePath = this.configuration.CachePath;
+ cefSettings.IgnoreCertificateErrors = false;
+ cefSettings.PersistSessionCookies = true;
+ //Cef.EnableHighDPISupport();
+ //CefSharpSettings.LegacyJavascriptBindingEnabled = true;
+ CefSharpSettings.WcfTimeout = TimeSpan.Zero;
+ bool flag = !Cef.IsInitialized;
+ if (flag)
+ {
+ bool flag2 = !Cef.Initialize(cefSettings);
+ if (flag2)
+ {
+ MessageBox.Show("Failed to initialize the document browser component");
+ return false;
+ }
+ }
+ string text = (
+ this.configuration.Url.StartsWith("http")
+ ? this.configuration.Url
+ : Path.Combine(this.assemblyDirectory, this.configuration.Url)
+ );
+ this.browser = new ChromiumWebBrowser(text, null);
+ //this.browser.BrowserSettings.FileAccessFromFileUrls = CefState.Enabled;
+ //this.browser.BrowserSettings.UniversalAccessFromFileUrls = CefState.Enabled;
+ this.browser
+ .JavascriptObjectRepository
+ .Register(this.configuration.Js2NetObjectName, this.functions, true, null);
+ this.browser.BrowserSettings.Javascript = CefState.Enabled;
+ this.browser.BrowserSettings.JavascriptCloseWindows = CefState.Enabled;
+ this.browser.BrowserSettings.WebGl = CefState.Enabled;
+ //this.browser.BrowserSettings.ApplicationCache = CefState.Disabled;
+ this.browser.BrowserSettings.LocalStorage = CefState.Disabled;
+ this.browser.BrowserSettings.Databases = CefState.Disabled;
+ this.browser.LifeSpanHandler = new LifeSpanHandler();
+ this.browser.MenuHandler = new ContextMenuHandler();
+ this.browser.LoadingStateChanged += delegate(
+ object sender,
+ LoadingStateChangedEventArgs args
+ )
+ {
+ bool flag3 = !args.IsLoading;
+ if (flag3)
+ {
+ base.Invoke(
+ new MethodInvoker(
+ delegate
+ {
+ this.loader.Visible = false;
+ }
+ )
+ );
+ }
+ };
+ this.panelBrowser.Controls.Add(this.browser);
+ return true;
+ }
+
+ private void Form_Browser_FormClosing(object sender, FormClosingEventArgs e)
+ {
+ bool flag = base.WindowState == FormWindowState.Normal;
+ if (flag)
+ {
+ Settings.Default.WindowSize = base.Size;
+ }
+ else
+ {
+ Settings.Default.WindowSize = base.RestoreBounds.Size;
+ }
+ Settings.Default.Save();
+ }
+
+ private void Form_Browser_FormClosed(object sender, FormClosedEventArgs e)
+ {
+ bool isInitialized = Cef.IsInitialized;
+ if (isInitialized)
+ {
+ Cef.Shutdown();
+ }
+ this.SendMessage("close:");
+ }
+
+ private const int WM_COPYDATA = 74;
+
+ private const int WM_CLOSE = 16;
+
+ private const int MESSAGE_MAX_SIZE = 16777216;
+
+ private string assemblyDirectory = Path.GetDirectoryName(
+ new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath
+ );
+
+ private Queue browserToRevitActions;
+
+ private Queue revitToBrowserActions;
+
+ private ChromiumWebBrowser browser = null;
+
+ private Timer actionTimer = new Timer { Interval = 300 };
+
+ private readonly BrowserConfiguration configuration;
+
+ private readonly BrowserFunctions functions;
+
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ internal struct MyStruct
+ {
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16777216)]
+ public string Message;
+ }
+
+ internal struct COPYDATASTRUCT
+ {
+ public IntPtr dwData;
+
+ public int cbData;
+
+ public IntPtr lpData;
+ }
+
+ [SuppressUnmanagedCodeSecurity]
+ internal class NativeMethod
+ {
+ [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
+ public static extern IntPtr SendMessage(
+ IntPtr hWnd,
+ int Msg,
+ IntPtr wParam,
+ ref BrowserForm.COPYDATASTRUCT lParam
+ );
+
+ [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
+ public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
+
+ [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")]
+ public static extern IntPtr SetWindowLongPtr64(
+ IntPtr hWnd,
+ int nIndex,
+ IntPtr dwNewLong
+ );
+ }
+ }
+}
diff --git a/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/BrowserFunctions.cs b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/BrowserFunctions.cs
new file mode 100644
index 0000000..0693ddd
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/BrowserFunctions.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Dynamic;
+using Newtonsoft.Json;
+
+namespace KGdev.BI3D.Revit.Addin.MainWindow.External.Browser
+{
+ internal class BrowserFunctions
+ {
+ public BrowserFunctions(Queue callQueue)
+ {
+ this.callQueue = callQueue;
+ }
+
+ public void Execute(ExpandoObject obj)
+ {
+ string text = JsonConvert.SerializeObject(obj);
+ this.callQueue.Enqueue("execute:" + text);
+ }
+
+ private Queue callQueue;
+ }
+}
diff --git a/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/ContextMenuHandler.cs b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/ContextMenuHandler.cs
new file mode 100644
index 0000000..1cef8ad
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/ContextMenuHandler.cs
@@ -0,0 +1,49 @@
+using System;
+using CefSharp;
+
+namespace KGdev.BI3D.Revit.Addin.MainWindow.External.Browser
+{
+ public class ContextMenuHandler : IContextMenuHandler
+ {
+ public void OnBeforeContextMenu(
+ IWebBrowser browserControl,
+ IBrowser browser,
+ IFrame frame,
+ IContextMenuParams parameters,
+ IMenuModel model
+ )
+ {
+ model.Clear();
+ }
+
+ public bool OnContextMenuCommand(
+ IWebBrowser browserControl,
+ IBrowser browser,
+ IFrame frame,
+ IContextMenuParams parameters,
+ CefMenuCommand commandId,
+ CefEventFlags eventFlags
+ )
+ {
+ return false;
+ }
+
+ public void OnContextMenuDismissed(
+ IWebBrowser browserControl,
+ IBrowser browser,
+ IFrame frame
+ ) { }
+
+ public bool RunContextMenu(
+ IWebBrowser browserControl,
+ IBrowser browser,
+ IFrame frame,
+ IContextMenuParams parameters,
+ IMenuModel model,
+ IRunContextMenuCallback callback
+ )
+ {
+ return false;
+ }
+ }
+}
diff --git a/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser.csproj b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser.csproj
new file mode 100644
index 0000000..47e9b0a
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser.csproj
@@ -0,0 +1,62 @@
+
+
+
+ {6EF0F4D1-EDD2-498A-A9C7-13DAAF6C5361}
+ WinExe
+ KGdev.BI3D.Revit.Addin.MainWindow.External.Browser
+ KGdev.BI3D.Revit.Addin.MainWindow.External.Browser
+ False
+ 512
+ net472
+ True
+ x64
+
+
+ False
+
+
+ app.manifest
+ KGdev.BI3D.Revit.Addin.MainWindow.External.Browser.Program
+
+
+
+
+
+ Form
+
+
+ BrowserForm.cs
+
+
+
+
+
+
+
+ Settings.settings
+ True
+ True
+
+
+
+
+ C:\ProgramData\Autodesk\Revit\Addins\2020\3DBI for Revit\Newtonsoft.Json.dll
+
+
+
+
+
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/LifeSpanHandler.cs b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/LifeSpanHandler.cs
new file mode 100644
index 0000000..088386f
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/LifeSpanHandler.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Diagnostics;
+using CefSharp;
+
+namespace KGdev.BI3D.Revit.Addin.MainWindow.External.Browser
+{
+ public class LifeSpanHandler : ILifeSpanHandler
+ {
+ public bool OnBeforePopup(
+ IWebBrowser browserControl,
+ IBrowser browser,
+ IFrame frame,
+ string targetUrl,
+ string targetFrameName,
+ WindowOpenDisposition targetDisposition,
+ bool userGesture,
+ IPopupFeatures popupFeatures,
+ IWindowInfo windowInfo,
+ IBrowserSettings browserSettings,
+ ref bool noJavascriptAccess,
+ out IWebBrowser newBrowser
+ )
+ {
+ Process.Start(targetUrl);
+ newBrowser = null;
+ return true;
+ }
+
+ public void OnAfterCreated(IWebBrowser browserControl, IBrowser browser) { }
+
+ public bool DoClose(IWebBrowser browserControl, IBrowser browser)
+ {
+ return false;
+ }
+
+ public void OnBeforeClose(IWebBrowser browserControl, IBrowser browser) { }
+ }
+}
diff --git a/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/Program.cs b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/Program.cs
new file mode 100644
index 0000000..060e894
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/Program.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Windows.Forms;
+
+namespace KGdev.BI3D.Revit.Addin.MainWindow.External.Browser
+{
+ internal static class Program
+ {
+ [STAThread]
+ private static void Main(string[] args)
+ {
+ IntPtr zero = IntPtr.Zero;
+ bool flag = args.Length >= 1;
+ if (flag)
+ {
+ zero = new IntPtr(int.Parse(args[0]));
+ }
+ int num = -1;
+ bool flag2 = args.Length >= 2;
+ if (flag2)
+ {
+ num = int.Parse(args[1]);
+ }
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Queue queue = new Queue();
+ Queue queue2 = new Queue();
+ string text = Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
+ ".3dbi-for-revit",
+ "cache"
+ );
+ Directory.CreateDirectory(text);
+ BrowserConfiguration browserConfiguration = new BrowserConfiguration
+ {
+ Title = "3DBI",
+ CachePath = text,
+ MessageHandle = zero,
+ Url = Path.Combine(
+ Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
+ "root",
+ "index.html"
+ ),
+ Js2NetObjectName = "revit",
+ Net2JsObjectName = "fromRevit",
+ ParentProcessId = num,
+ Net2JsUpdateStatePartialFunctionName = "updatePartialState"
+ };
+ Application.Run(
+ new BrowserForm(browserConfiguration, new BrowserFunctions(queue), queue, queue2)
+ );
+ }
+ }
+}
diff --git a/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/Properties/AssemblyInfo.cs b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..2bc8d6f
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/Properties/AssemblyInfo.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Diagnostics;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.Versioning;
+
+[assembly: AssemblyVersion("1.3.0.0")]
+[assembly: AssemblyCompany("KGdev.BI3D.Revit.Addin.MainWindow.External.Browser")]
+[assembly: AssemblyConfiguration("Release 2020")]
+[assembly: AssemblyFileVersion("1.3.0")]
+[assembly: AssemblyInformationalVersion("1.3.0")]
+[assembly: AssemblyProduct("KGdev.BI3D.Revit.Addin.MainWindow.External.Browser")]
+[assembly: AssemblyTitle("KGdev.BI3D.Revit.Addin.MainWindow.External.Browser")]
diff --git a/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/Properties/Settings.Designer.cs b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..584fa30
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/Properties/Settings.Designer.cs
@@ -0,0 +1,54 @@
+using System;
+using System.CodeDom.Compiler;
+using System.Configuration;
+using System.Diagnostics;
+using System.Drawing;
+using System.Runtime.CompilerServices;
+
+namespace KGdev.BI3D.Revit.Addin.MainWindow.External.Browser.Properties
+{
+ [CompilerGenerated]
+ [GeneratedCode("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.6.0.0")]
+ internal sealed partial class Settings : ApplicationSettingsBase
+ {
+ public static Settings Default
+ {
+ get
+ {
+ return Settings.defaultInstance;
+ }
+ }
+
+ [UserScopedSetting]
+ [DebuggerNonUserCode]
+ [DefaultSettingValue("0, 0")]
+ public Point WindowLocation
+ {
+ get
+ {
+ return (Point)this["WindowLocation"];
+ }
+ set
+ {
+ this["WindowLocation"] = value;
+ }
+ }
+
+ [UserScopedSetting]
+ [DebuggerNonUserCode]
+ [DefaultSettingValue("1500, 800")]
+ public Size WindowSize
+ {
+ get
+ {
+ return (Size)this["WindowSize"];
+ }
+ set
+ {
+ this["WindowSize"] = value;
+ }
+ }
+
+ private static Settings defaultInstance = (Settings)SettingsBase.Synchronized(new Settings());
+ }
+}
diff --git a/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/Properties/Settings.settings b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/Properties/Settings.settings
new file mode 100644
index 0000000..98b9a2c
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/Properties/Settings.settings
@@ -0,0 +1,12 @@
+
+
+
+
+
+ 0, 0
+
+
+ 1500, 800
+
+
+
\ No newline at end of file
diff --git a/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/app.config b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/app.config
new file mode 100644
index 0000000..8f60dcb
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/app.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/app.manifest b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/app.manifest
new file mode 100644
index 0000000..f8f55e0
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/app.manifest
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/resources/logo.png b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/resources/logo.png
new file mode 100644
index 0000000..96d7893
Binary files /dev/null and b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/resources/logo.png differ
diff --git a/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/resources/logo512.png b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/resources/logo512.png
new file mode 100644
index 0000000..96d7893
Binary files /dev/null and b/KGdev.BI3D.Revit.Addin.MainWindow.External.Browser/resources/logo512.png differ
diff --git a/KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector/ExternalMainWindow.cs b/KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector/ExternalMainWindow.cs
new file mode 100644
index 0000000..7190520
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector/ExternalMainWindow.cs
@@ -0,0 +1,125 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Reflection;
+using System.Windows.Forms;
+using KGdev.BI3D.Revit.Common;
+using Newtonsoft.Json;
+
+namespace KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector
+{
+ public class ExternalMainWindow : IMainWindow
+ {
+ public bool IsVisible
+ {
+ get
+ {
+ bool flag = this.browserProcess == null;
+ bool flag2;
+ if (flag)
+ {
+ flag2 = false;
+ }
+ else
+ {
+ bool hasExited = this.browserProcess.HasExited;
+ if (hasExited)
+ {
+ flag2 = false;
+ }
+ else
+ {
+ bool flag3 = this.messageHandler.BrowserHandle == IntPtr.Zero;
+ flag2 = !flag3;
+ }
+ }
+ return flag2;
+ }
+ }
+
+ public ExternalMainWindow(IReduxReducer reducer)
+ {
+ this.reducer = reducer;
+ reducer.OnStateChanged += this.Reducer_OnStateChanged;
+ this.messageHandler.MessageReceivedEvent += this.MessageHandler_MessageReceivedEvent;
+ }
+
+ private void Reducer_OnStateChanged(object sender, Dictionary e)
+ {
+ string text = JsonConvert.SerializeObject(e);
+ this.messageHandler.Send(text);
+ }
+
+ private void MessageHandler_MessageReceivedEvent(object sender, MessageReceivedEventArgs e)
+ {
+ try
+ {
+ string message = e.Message;
+ Dictionary dictionary = JsonConvert.DeserializeObject<
+ Dictionary
+ >(message);
+ this.reducer.Reduce(dictionary);
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(
+ "Something went wrong when processing the request. Please contact info@kg-dev.be."
+ );
+ }
+ }
+
+ public void Close()
+ {
+ bool flag = this.browserProcess == null;
+ if (!flag)
+ {
+ bool hasExited = this.browserProcess.HasExited;
+ if (!hasExited)
+ {
+ this.browserProcess.Kill();
+ }
+ }
+ }
+
+ public void Show()
+ {
+ bool flag = !this.IsVisible;
+ if (flag)
+ {
+ this.CreateNew();
+ }
+ IntPtr browserHandle = this.messageHandler.BrowserHandle;
+ User32.SetForegroundWindow(browserHandle);
+ }
+
+ private void CreateNew()
+ {
+ Process process = new Process();
+ process.StartInfo.FileName = Path.Combine(
+ this.assemblyDirectory,
+ "KGdev.BI3D.Revit.Addin.MainWindow.External.Browser.exe"
+ );
+ process.StartInfo.Arguments = string.Format(
+ "{0} {1}",
+ this.messageHandler.Handle,
+ Process.GetCurrentProcess().Id
+ );
+ process.Start();
+ this.browserProcess = process;
+ }
+
+ private const string BROWSER_EXECUTABLE_RELATIVE_PATH =
+ "KGdev.BI3D.Revit.Addin.MainWindow.External.Browser.exe";
+
+ private readonly MessageHandler messageHandler = new MessageHandler();
+
+ private readonly string assemblyDirectory = Path.GetDirectoryName(
+ new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath
+ );
+
+ private Process browserProcess;
+
+ private IReduxReducer reducer;
+ }
+}
diff --git a/KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector/KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector.csproj b/KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector/KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector.csproj
new file mode 100644
index 0000000..06ec944
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector/KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector.csproj
@@ -0,0 +1,38 @@
+
+
+
+ {B4556B52-C073-4D6D-A1BE-BCEDEBE41056}
+ Library
+ KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector
+ KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector
+ False
+ 512
+ net472
+ True
+ x64
+
+
+ False
+
+
+
+
+
+ Form
+
+
+ MessageHandler.cs
+
+
+
+
+
+
+
+
+
+
+ C:\ProgramData\Autodesk\Revit\Addins\2020\3DBI for Revit\Newtonsoft.Json.dll
+
+
+
\ No newline at end of file
diff --git a/KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector/MessageHandler.Designer.cs b/KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector/MessageHandler.Designer.cs
new file mode 100644
index 0000000..45febf7
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector/MessageHandler.Designer.cs
@@ -0,0 +1,25 @@
+namespace KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector
+{
+ public partial class MessageHandler : global::System.Windows.Forms.Form
+ {
+ protected override void Dispose(bool disposing)
+ {
+ bool flag = disposing && this.components != null;
+ if (flag)
+ {
+ this.components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ private void InitializeComponent()
+ {
+ this.components = new global::System.ComponentModel.Container();
+ base.AutoScaleMode = global::System.Windows.Forms.AutoScaleMode.Font;
+ base.ClientSize = new global::System.Drawing.Size(800, 450);
+ this.Text = "MessageHandler";
+ }
+
+ private global::System.ComponentModel.IContainer components = null;
+ }
+}
diff --git a/KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector/MessageHandler.cs b/KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector/MessageHandler.cs
new file mode 100644
index 0000000..2738603
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector/MessageHandler.cs
@@ -0,0 +1,135 @@
+using System;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Drawing;
+using System.Runtime.InteropServices;
+using System.Security;
+using System.Windows.Forms;
+
+namespace KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector
+{
+ public partial class MessageHandler : Form
+ {
+ public IntPtr BrowserHandle { get; private set; }
+
+ [field: DebuggerBrowsable(DebuggerBrowsableState.Never)]
+ public event MessageHandler.MessageReceivedEventHandler MessageReceivedEvent;
+
+ public void Send(string message)
+ {
+ this.DoSend(message);
+ }
+
+ private void DoSend(string message)
+ {
+ MessageHandler.MessageStruct messageStruct = new MessageHandler.MessageStruct
+ {
+ Message = message
+ };
+ int num = Marshal.SizeOf(messageStruct);
+ IntPtr intPtr = Marshal.AllocHGlobal(num);
+ try
+ {
+ Marshal.StructureToPtr(messageStruct, intPtr, true);
+ MessageHandler.COPYDATASTRUCT copydatastruct =
+ default(MessageHandler.COPYDATASTRUCT);
+ copydatastruct.cbData = num;
+ copydatastruct.lpData = intPtr;
+ MessageHandler
+ .NativeMethod
+ .SendMessage(this.BrowserHandle, 74, base.Handle, ref copydatastruct);
+ int lastWin32Error = Marshal.GetLastWin32Error();
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(intPtr);
+ }
+ }
+
+ protected override void WndProc(ref Message m)
+ {
+ bool flag = m.Msg == 74;
+ if (flag)
+ {
+ MessageHandler.COPYDATASTRUCT copydatastruct = (MessageHandler.COPYDATASTRUCT)
+ m.GetLParam(typeof(MessageHandler.COPYDATASTRUCT));
+ bool flag2 =
+ copydatastruct.cbData == Marshal.SizeOf(typeof(MessageHandler.MessageStruct));
+ if (flag2)
+ {
+ MessageHandler.MessageStruct messageStruct = (MessageHandler.MessageStruct)
+ Marshal.PtrToStructure(
+ copydatastruct.lpData,
+ typeof(MessageHandler.MessageStruct)
+ );
+ bool flag3 = messageStruct.Message.StartsWith("handle:");
+ if (flag3)
+ {
+ this.BrowserHandle = new IntPtr(
+ int.Parse(messageStruct.Message.Replace("handle:", ""))
+ );
+ }
+ else
+ {
+ bool flag4 = messageStruct.Message.StartsWith("close:");
+ if (flag4)
+ {
+ this.BrowserHandle = IntPtr.Zero;
+ }
+ else
+ {
+ bool flag5 = messageStruct.Message.StartsWith("execute:");
+ if (flag5)
+ {
+ string text = messageStruct.Message.Replace("execute:", "");
+ MessageHandler.MessageReceivedEventHandler messageReceivedEvent =
+ this.MessageReceivedEvent;
+ if (messageReceivedEvent != null)
+ {
+ messageReceivedEvent(this, new MessageReceivedEventArgs(text));
+ }
+ }
+ }
+ }
+ }
+ }
+ base.WndProc(ref m);
+ }
+
+ private const int MESSAGE_MAX_SIZE = 16777216;
+
+ private Timer actionHandler = new Timer { Interval = 300 };
+
+ internal const int WM_COPYDATA = 74;
+
+ public delegate void MessageReceivedEventHandler(object sender, MessageReceivedEventArgs e);
+
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ internal struct MessageStruct
+ {
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16777216)]
+ public string Message;
+ }
+
+ internal struct COPYDATASTRUCT
+ {
+ public IntPtr dwData;
+
+ public int cbData;
+
+ public IntPtr lpData;
+ }
+
+ [SuppressUnmanagedCodeSecurity]
+ internal class NativeMethod
+ {
+ [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
+ public static extern IntPtr SendMessage(
+ IntPtr hWnd,
+ int Msg,
+ IntPtr wParam,
+ ref MessageHandler.COPYDATASTRUCT lParam
+ );
+ }
+ }
+}
diff --git a/KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector/MessageReceivedEventArgs.cs b/KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector/MessageReceivedEventArgs.cs
new file mode 100644
index 0000000..b70e571
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector/MessageReceivedEventArgs.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector
+{
+ public class MessageReceivedEventArgs
+ {
+ public string Message { get; }
+
+ public MessageReceivedEventArgs(string message)
+ {
+ this.Message = message;
+ }
+ }
+}
diff --git a/KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector/Properties/AssemblyInfo.cs b/KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..51908bc
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector/Properties/AssemblyInfo.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Diagnostics;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.Versioning;
+
+[assembly: AssemblyVersion("1.3.0.0")]
+[assembly: AssemblyCompany("KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector")]
+[assembly: AssemblyConfiguration("Release 2020")]
+[assembly: AssemblyFileVersion("1.3.0")]
+[assembly: AssemblyInformationalVersion("1.3.0")]
+[assembly: AssemblyProduct("KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector")]
+[assembly: AssemblyTitle("KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector")]
diff --git a/KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector/User32.cs b/KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector/User32.cs
new file mode 100644
index 0000000..4454a57
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector/User32.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector
+{
+ internal static class User32
+ {
+ [DllImport("user32.dll")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool SetForegroundWindow(IntPtr hWnd);
+ }
+}
diff --git a/KGdev.BI3D.Revit.Addin.sln b/KGdev.BI3D.Revit.Addin.sln
new file mode 100644
index 0000000..21e3d15
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin.sln
@@ -0,0 +1,91 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31903.59
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KGdev.BI3D.Revit.Addin", "KGdev.BI3D.Revit.Addin\KGdev.BI3D.Revit.Addin.csproj", "{05AEF857-F1AB-4D56-B104-4E53BC7AEC36}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KGdev.BI3D.Revit.ExporterV2", "KGdev.BI3D.Revit.ExporterV2\KGdev.BI3D.Revit.ExporterV2.csproj", "{BB5F900A-1B85-45E7-BF11-B332FD436D05}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KGdev.BI3D.Revit", "KGdev.BI3D.Revit\KGdev.BI3D.Revit.csproj", "{2D6C4C2D-1F14-49C3-BEBF-B997CD03047F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KGdev.BI3D.Revit.Common", "KGdev.BI3D.Revit.Common\KGdev.BI3D.Revit.Common.csproj", "{1124213F-BDC6-4A9D-BF39-7E916D3FBCA1}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KGdev.BI3D.Revit.DataExporter.JsonTable", "KGdev.BI3D.Revit.DataExporter.JsonTable\KGdev.BI3D.Revit.DataExporter.JsonTable.csproj", "{AF3ADBA9-E7CC-4D34-BF1B-12C2E6705953}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector", "KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector\KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector.csproj", "{B4556B52-C073-4D6D-A1BE-BCEDEBE41056}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KGdev.BI3D.Revit.Addin.MainWindow.External.Browser", "KGdev.BI3D.Revit.Addin.MainWindow.External.Browser\KGdev.BI3D.Revit.Addin.MainWindow.External.Browser.csproj", "{6EF0F4D1-EDD2-498A-A9C7-13DAAF6C5361}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {05AEF857-F1AB-4D56-B104-4E53BC7AEC36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {05AEF857-F1AB-4D56-B104-4E53BC7AEC36}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {05AEF857-F1AB-4D56-B104-4E53BC7AEC36}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {05AEF857-F1AB-4D56-B104-4E53BC7AEC36}.Debug|x64.Build.0 = Debug|Any CPU
+ {05AEF857-F1AB-4D56-B104-4E53BC7AEC36}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {05AEF857-F1AB-4D56-B104-4E53BC7AEC36}.Release|Any CPU.Build.0 = Release|Any CPU
+ {05AEF857-F1AB-4D56-B104-4E53BC7AEC36}.Release|x64.ActiveCfg = Release|x64
+ {05AEF857-F1AB-4D56-B104-4E53BC7AEC36}.Release|x64.Build.0 = Release|x64
+ {BB5F900A-1B85-45E7-BF11-B332FD436D05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BB5F900A-1B85-45E7-BF11-B332FD436D05}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BB5F900A-1B85-45E7-BF11-B332FD436D05}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {BB5F900A-1B85-45E7-BF11-B332FD436D05}.Debug|x64.Build.0 = Debug|Any CPU
+ {BB5F900A-1B85-45E7-BF11-B332FD436D05}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BB5F900A-1B85-45E7-BF11-B332FD436D05}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BB5F900A-1B85-45E7-BF11-B332FD436D05}.Release|x64.ActiveCfg = Release|Any CPU
+ {BB5F900A-1B85-45E7-BF11-B332FD436D05}.Release|x64.Build.0 = Release|Any CPU
+ {2D6C4C2D-1F14-49C3-BEBF-B997CD03047F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2D6C4C2D-1F14-49C3-BEBF-B997CD03047F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2D6C4C2D-1F14-49C3-BEBF-B997CD03047F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {2D6C4C2D-1F14-49C3-BEBF-B997CD03047F}.Debug|x64.Build.0 = Debug|Any CPU
+ {2D6C4C2D-1F14-49C3-BEBF-B997CD03047F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2D6C4C2D-1F14-49C3-BEBF-B997CD03047F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2D6C4C2D-1F14-49C3-BEBF-B997CD03047F}.Release|x64.ActiveCfg = Release|Any CPU
+ {2D6C4C2D-1F14-49C3-BEBF-B997CD03047F}.Release|x64.Build.0 = Release|Any CPU
+ {1124213F-BDC6-4A9D-BF39-7E916D3FBCA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1124213F-BDC6-4A9D-BF39-7E916D3FBCA1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1124213F-BDC6-4A9D-BF39-7E916D3FBCA1}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {1124213F-BDC6-4A9D-BF39-7E916D3FBCA1}.Debug|x64.Build.0 = Debug|Any CPU
+ {1124213F-BDC6-4A9D-BF39-7E916D3FBCA1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1124213F-BDC6-4A9D-BF39-7E916D3FBCA1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1124213F-BDC6-4A9D-BF39-7E916D3FBCA1}.Release|x64.ActiveCfg = Release|Any CPU
+ {1124213F-BDC6-4A9D-BF39-7E916D3FBCA1}.Release|x64.Build.0 = Release|Any CPU
+ {AF3ADBA9-E7CC-4D34-BF1B-12C2E6705953}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AF3ADBA9-E7CC-4D34-BF1B-12C2E6705953}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AF3ADBA9-E7CC-4D34-BF1B-12C2E6705953}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {AF3ADBA9-E7CC-4D34-BF1B-12C2E6705953}.Debug|x64.Build.0 = Debug|Any CPU
+ {AF3ADBA9-E7CC-4D34-BF1B-12C2E6705953}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AF3ADBA9-E7CC-4D34-BF1B-12C2E6705953}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AF3ADBA9-E7CC-4D34-BF1B-12C2E6705953}.Release|x64.ActiveCfg = Release|Any CPU
+ {AF3ADBA9-E7CC-4D34-BF1B-12C2E6705953}.Release|x64.Build.0 = Release|Any CPU
+ {B4556B52-C073-4D6D-A1BE-BCEDEBE41056}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B4556B52-C073-4D6D-A1BE-BCEDEBE41056}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B4556B52-C073-4D6D-A1BE-BCEDEBE41056}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B4556B52-C073-4D6D-A1BE-BCEDEBE41056}.Debug|x64.Build.0 = Debug|Any CPU
+ {B4556B52-C073-4D6D-A1BE-BCEDEBE41056}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B4556B52-C073-4D6D-A1BE-BCEDEBE41056}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B4556B52-C073-4D6D-A1BE-BCEDEBE41056}.Release|x64.ActiveCfg = Release|Any CPU
+ {B4556B52-C073-4D6D-A1BE-BCEDEBE41056}.Release|x64.Build.0 = Release|Any CPU
+ {6EF0F4D1-EDD2-498A-A9C7-13DAAF6C5361}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6EF0F4D1-EDD2-498A-A9C7-13DAAF6C5361}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6EF0F4D1-EDD2-498A-A9C7-13DAAF6C5361}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {6EF0F4D1-EDD2-498A-A9C7-13DAAF6C5361}.Debug|x64.Build.0 = Debug|Any CPU
+ {6EF0F4D1-EDD2-498A-A9C7-13DAAF6C5361}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6EF0F4D1-EDD2-498A-A9C7-13DAAF6C5361}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6EF0F4D1-EDD2-498A-A9C7-13DAAF6C5361}.Release|x64.ActiveCfg = Release|Any CPU
+ {6EF0F4D1-EDD2-498A-A9C7-13DAAF6C5361}.Release|x64.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {04C220AF-E9E5-48DB-BA11-5E2D13A88D79}
+ EndGlobalSection
+EndGlobal
diff --git a/KGdev.BI3D.Revit.Addin/Addin.cs b/KGdev.BI3D.Revit.Addin/Addin.cs
new file mode 100644
index 0000000..d5ccd5f
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin/Addin.cs
@@ -0,0 +1,154 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Windows.Media.Imaging;
+using Autodesk.Revit.ApplicationServices;
+using Autodesk.Revit.DB;
+using Autodesk.Revit.UI;
+using Autodesk.Revit.UI.Events;
+using KGdev.BI3D.Revit.Addin.Commands;
+using KGdev.BI3D.Revit.Addin.ExternalEvents;
+using KGdev.BI3D.Revit.Addin.MainWindow.External.BrowserConnector;
+using KGdev.BI3D.Revit.Common;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace KGdev.BI3D.Revit.Addin
+{
+ public class Addin : IExternalApplication
+ {
+ internal static IServiceProvider ServiceProvider { get; private set; }
+
+ public Result OnShutdown(UIControlledApplication application)
+ {
+ return 0;
+ }
+
+ public Result OnStartup(UIControlledApplication application)
+ {
+ Addin.ServiceProvider = this.BuildServiceProvider(application);
+ this.BuildUI(application);
+ this.AttachEventListeners(application);
+ return 0;
+ }
+
+ private void BuildUI(UIControlledApplication application)
+ {
+ string location = Assembly.GetExecutingAssembly().Location;
+ PushButtonData pushButtonData = new PushButtonData(
+ "3DBI",
+ "3DBI",
+ location,
+ typeof(OpenCloseMainDialogCommand).FullName
+ );
+ pushButtonData.ToolTip = "Show/Hide Main Window.";
+ pushButtonData.SetContextualHelp(
+ new ContextualHelp(
+ ContextualHelpType.Url,
+ "https://kg-dev.be/project/3dbi-for-revit"
+ )
+ );
+ pushButtonData.LargeImage = this.GetIcon("3dbi");
+ RibbonPanel ribbonPanel = application
+ .GetRibbonPanels(0)
+ .FirstOrDefault((RibbonPanel x) => x.Name == "KG-dev");
+ bool flag = ribbonPanel == null;
+ if (flag)
+ {
+ ribbonPanel = application.CreateRibbonPanel(0, "KG-dev");
+ }
+ ribbonPanel.AddItem(pushButtonData);
+ }
+
+ private IServiceProvider BuildServiceProvider(UIControlledApplication application)
+ {
+ ServiceCollection serviceCollection = new ServiceCollection();
+ serviceCollection.AddSingleton(_ =>
+ {
+ IMuidProvider requiredService = Extension
+ .Instance
+ .ServiceProvider
+ .GetRequiredService();
+ IGlobalStore requiredService2 = Extension
+ .Instance
+ .ServiceProvider
+ .GetRequiredService();
+ //IAuthProvider requiredService3 = Extension
+ // .Instance
+ // .ServiceProvider
+ // .GetRequiredService();
+ IConstantsProvider requiredService4 = Extension
+ .Instance
+ .ServiceProvider
+ .GetRequiredService();
+ IExporter requiredService5 = Extension
+ .Instance
+ .ServiceProvider
+ .GetRequiredService();
+ ExporterV1ExternalEventInvoker exporterV1ExternalEventInvoker =
+ new ExporterV1ExternalEventInvoker(requiredService5);
+ List requiredService6 = Extension
+ .Instance
+ .ServiceProvider
+ .GetRequiredService>();
+ return new MainDialogReduxReducer(
+ application,
+ requiredService2,
+ requiredService,
+ requiredService4,
+ //requiredService3,
+ exporterV1ExternalEventInvoker,
+ requiredService6
+ );
+ });
+ serviceCollection.AddSingleton(
+ (IServiceProvider provider) =>
+ {
+ IReduxReducer requiredService7 = provider.GetRequiredService();
+ return new ExternalMainWindow(requiredService7);
+ }
+ );
+ return serviceCollection.BuildServiceProvider();
+ }
+
+ private void AttachEventListeners(UIControlledApplication application)
+ {
+ application.Idling += this.Application_Idling;
+ }
+
+ private void Application_Idling(object sender, IdlingEventArgs e)
+ {
+ UIApplication uiapplication = sender as UIApplication;
+ if (uiapplication != null)
+ {
+ Application application = uiapplication.Application;
+ if (application != null)
+ {
+ DocumentSet documents = application.Documents;
+ if (documents.Size == 0)
+ {
+ if (Addin.ServiceProvider != null)
+ {
+ IMainWindow service = Addin.ServiceProvider.GetService();
+ if (service?.IsVisible == true)
+ {
+ service.Close();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private BitmapImage GetIcon(string name)
+ {
+ string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
+ string text = Path.Combine(directoryName, "Resources", string.Format("{0}.ico", name));
+ string localPath = new Uri(text).LocalPath;
+ return new BitmapImage(new Uri(localPath));
+ }
+
+ private const string RIBBON_PANEL_NAME = "KG-dev";
+ }
+}
diff --git a/KGdev.BI3D.Revit.Addin/AssemblyLoaderUtil.cs b/KGdev.BI3D.Revit.Addin/AssemblyLoaderUtil.cs
new file mode 100644
index 0000000..60e300d
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin/AssemblyLoaderUtil.cs
@@ -0,0 +1,148 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Threading;
+
+namespace KGdev.BI3D.Revit.Addin
+{
+ public class AssemblyLoaderUtil
+ {
+ public AssemblyLoaderUtil(string assemblyDir)
+ {
+ AssemblyDirectory = assemblyDir;
+ }
+
+ public string AssemblyDirectory { get; set; }
+
+ public void HookAssemblyResolve()
+ {
+ AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
+ }
+
+ ///
+ /// 加载目录下的所有程序集
+ ///
+ ///
+ ///
+ public List LoadAllRibbonAssemblies(string commandFolderPath)
+ {
+ var list = new List();
+ foreach (var assemblyFile in Directory.GetFiles(commandFolderPath, "*.dll"))
+ {
+ try
+ {
+ list.Add(Assembly.LoadFrom(assemblyFile));
+ }
+ catch
+ {
+ // ignored
+ }
+ }
+
+ return list;
+ }
+
+ /////
+ ///// 调用此方法解决UI程序集丢失
+ /////
+ /////
+ //public static void ResolveAssembly(Action action)
+ //{
+ // string addInPath = typeof(AssemblyLoaderUtil).Assembly.Location;
+ // string dirAssembly = Path.GetDirectoryName(addInPath);
+ // AssemblyLoaderUtil loaderUtil = new AssemblyLoaderUtil(dirAssembly);
+ // loaderUtil.HookAssemblyResolve();
+ // try
+ // {
+ // action();
+ // }
+ // catch (Exception ex)
+ // {
+ // MessageBox.Show(ex.InnerException?.ToString());
+ // }
+ // finally
+ // {
+ // loaderUtil.UnhookAssemblyResolve();
+ // }
+ //}
+
+ public void UnhookAssemblyResolve()
+ {
+ AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve;
+ }
+
+ private Assembly LoadAddin(string filePath)
+ {
+ Assembly result;
+ try
+ {
+ Monitor.Enter(this);
+ result = Assembly.LoadFile(filePath);
+ }
+ finally
+ {
+ Monitor.Exit(this);
+ }
+
+ return result;
+ }
+
+ private string SearchAssemblyFile(string assemblyName)
+ {
+ string[] array = { ".dll", ".exe" };
+ var str = assemblyName.Substring(0, assemblyName.IndexOf(','));
+ foreach (var str2 in array)
+ {
+ var text = AssemblyDirectory + "\\" + str + str2;
+ if (File.Exists(text))
+ {
+ return text;
+ }
+ }
+
+ return string.Empty;
+ }
+
+ private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
+ {
+ Assembly result;
+ _ = new AssemblyName(args.Name);
+ var text = SearchAssemblyFile(args.Name);
+ if (File.Exists(text))
+ {
+ result = LoadAddin(text);
+ }
+ else
+ {
+ if (string.IsNullOrEmpty(text))
+ {
+ var array = args.Name.Split(',');
+ var text2 = array[0];
+ if (array.Length > 1)
+ {
+ var text3 = array[2];
+ if (
+ text2.EndsWith(".resources", StringComparison.CurrentCultureIgnoreCase)
+ && !text3.EndsWith("neutral", StringComparison.CurrentCultureIgnoreCase)
+ )
+ {
+ text2 = text2.Substring(0, text2.Length - ".resources".Length);
+ }
+
+ text = SearchAssemblyFile(text2);
+ if (File.Exists(text))
+ {
+ return LoadAddin(text);
+ }
+ //text = this.SearchAssemblyFile(text2);
+ }
+ }
+
+ result = LoadAddin(text);
+ }
+
+ return result;
+ }
+ }
+}
diff --git a/KGdev.BI3D.Revit.Addin/Commands/OpenCloseMainDialogCommand.cs b/KGdev.BI3D.Revit.Addin/Commands/OpenCloseMainDialogCommand.cs
new file mode 100644
index 0000000..7a1a297
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin/Commands/OpenCloseMainDialogCommand.cs
@@ -0,0 +1,56 @@
+using System;
+using System.IO;
+using System.Reflection;
+using System.Windows;
+using Autodesk.Revit.Attributes;
+using Autodesk.Revit.DB;
+using Autodesk.Revit.UI;
+using KGdev.BI3D.Revit.Common;
+using KGdev.BI3D.Revit.ExporterV2;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace KGdev.BI3D.Revit.Addin.Commands
+{
+ [Transaction(TransactionMode.Manual)]
+ [Regeneration(0)]
+ public class OpenCloseMainDialogCommand : IExternalCommand
+ {
+ public Result Execute(
+ ExternalCommandData commandData,
+ ref string message,
+ ElementSet elements
+ )
+ {
+ //AssemblyLoaderUtil loaderUtil = new AssemblyLoaderUtil(
+ // Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
+ //);
+ //loaderUtil.HookAssemblyResolve();
+ try
+ {
+ //Exporter exporter = new Exporter();
+ IMainWindow requiredService = Addin
+ .ServiceProvider
+ .GetRequiredService();
+ bool isVisible = requiredService.IsVisible;
+ if (isVisible)
+ {
+ requiredService.Close();
+ }
+ else
+ {
+ requiredService.Show();
+ }
+ }
+ catch (Exception ex)
+ {
+ TaskDialog.Show("Error", ex.Message);
+ return Result.Failed;
+ }
+ //finally
+ //{
+ // loaderUtil.UnhookAssemblyResolve();
+ //}
+ return 0;
+ }
+ }
+}
diff --git a/KGdev.BI3D.Revit.Addin/ExternalEvents/ExporterV1ExternalEventInvoker.cs b/KGdev.BI3D.Revit.Addin/ExternalEvents/ExporterV1ExternalEventInvoker.cs
new file mode 100644
index 0000000..54fc882
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin/ExternalEvents/ExporterV1ExternalEventInvoker.cs
@@ -0,0 +1,154 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Autodesk.Revit.DB;
+using Autodesk.Revit.UI;
+using KGdev.BI3D.Revit.Common;
+using KGdev.BI3D.Revit.Common.Models;
+
+namespace KGdev.BI3D.Revit.Addin.ExternalEvents
+{
+ internal class ExporterV1ExternalEventInvoker
+ {
+ public IExporter ExporterV1 { get; private set; }
+
+ public ExporterV1ExternalEventInvoker(IExporter exporterV1)
+ {
+ this.ExporterV1 = exporterV1;
+ this.externalEventHandler =
+ new ExporterV1ExternalEventInvoker.ExporterV1ExternalEventHandler(exporterV1);
+ this.externalEvent = ExternalEvent.Create(this.externalEventHandler);
+ }
+
+ public void Export(
+ Dictionary exporterOptionValues,
+ Action, string> callback
+ )
+ {
+ this.externalEventHandler.ExporterOptionValues = exporterOptionValues;
+ this.externalEventHandler.Callback = callback;
+ this.externalEvent.Raise();
+ }
+
+ private ExporterV1ExternalEventInvoker.ExporterV1ExternalEventHandler externalEventHandler;
+
+ private ExternalEvent externalEvent;
+
+ private class ExporterV1ExternalEventHandler : IExternalEventHandler
+ {
+ public Dictionary ExporterOptionValues
+ {
+ get
+ {
+ object @lock = this._lock;
+ Dictionary dictionary;
+ lock (@lock)
+ {
+ dictionary = this.exporterOptionValues;
+ }
+ return dictionary;
+ }
+ set
+ {
+ object @lock = this._lock;
+ lock (@lock)
+ {
+ this.exporterOptionValues = value;
+ }
+ }
+ }
+
+ public Action, string> Callback
+ {
+ get
+ {
+ object @lock = this._lock;
+ Action, string> action;
+ lock (@lock)
+ {
+ action = this.callback;
+ }
+ return action;
+ }
+ set
+ {
+ object @lock = this._lock;
+ lock (@lock)
+ {
+ this.callback = value;
+ }
+ }
+ }
+
+ public ExporterV1ExternalEventHandler(IExporter exporterV1)
+ {
+ this.exporterV1 = exporterV1;
+ }
+
+ public void Execute(UIApplication app)
+ {
+ try
+ {
+ UIDocument activeUIDocument = app.ActiveUIDocument;
+ bool flag = activeUIDocument == null;
+ if (flag)
+ {
+ throw new Exception(
+ "There is no Document open in Revit, please open a document and select a 3D view prior to performing this action."
+ );
+ }
+ View3D view3D = activeUIDocument.ActiveView as View3D;
+ bool flag2 = view3D == null;
+ if (flag2)
+ {
+ throw new Exception(
+ "3DBI can only export 3d views. Please select a 3D view before exporting."
+ );
+ }
+ FileSaveDialog fileSaveDialog = new FileSaveDialog(
+ "3DBI Files (*.3dbi)|*.3dbi"
+ );
+ ItemSelectionDialogResult itemSelectionDialogResult = fileSaveDialog.Show();
+ bool flag3 = itemSelectionDialogResult == 0;
+ if (flag3)
+ {
+ string text = ModelPathUtils.ConvertModelPathToUserVisiblePath(
+ fileSaveDialog.GetSelectedModelPath()
+ );
+ text = Path.Combine(
+ Path.GetDirectoryName(text),
+ Path.GetFileNameWithoutExtension(text) + ".3dbi"
+ );
+ Dictionary dictionary = this.exporterV1.Export(
+ view3D,
+ text,
+ this.exporterOptionValues
+ );
+ bool flag4 = this.callback != null;
+ if (flag4)
+ {
+ this.callback(view3D.Document, dictionary, text);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ TaskDialog.Show("Error", ex.Message ?? "");
+ }
+ }
+
+ public string GetName()
+ {
+ return base.GetType().Name;
+ }
+
+ private readonly IExporter exporterV1;
+
+ private Dictionary exporterOptionValues;
+
+ private Action, string> callback;
+
+ private object _lock = new object();
+ }
+ }
+}
diff --git a/KGdev.BI3D.Revit.Addin/KGdev.BI3D.Revit.Addin.csproj b/KGdev.BI3D.Revit.Addin/KGdev.BI3D.Revit.Addin.csproj
new file mode 100644
index 0000000..ed3b19f
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin/KGdev.BI3D.Revit.Addin.csproj
@@ -0,0 +1,60 @@
+
+
+
+ {05AEF857-F1AB-4D56-B104-4E53BC7AEC36}
+ Library
+ KGdev.BI3D.Revit.Addin
+ KGdev.BI3D.Revit.Addin
+ False
+ 512
+ net472
+ True
+ x64
+
+
+ False
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+
+
+
+
+
+
+
+ C:\ProgramData\Autodesk\Revit\Addins\2020\3DBI for Revit\Microsoft.Extensions.DependencyInjection.dll
+
+
+ C:\ProgramData\Autodesk\Revit\Addins\2020\3DBI for Revit\Microsoft.Extensions.DependencyInjection.Abstractions.dll
+
+
+ C:\ProgramData\Autodesk\Revit\Addins\2020\3DBI for Revit\Newtonsoft.Json.dll
+
+
+
+ C:\Program Files\Autodesk\Revit 2018\RevitAPI.dll
+ False
+
+
+ C:\Program Files\Autodesk\Revit 2018\RevitAPIUI.dll
+ False
+
+
+
+
\ No newline at end of file
diff --git a/KGdev.BI3D.Revit.Addin/MainDialogReduxReducer.cs b/KGdev.BI3D.Revit.Addin/MainDialogReduxReducer.cs
new file mode 100644
index 0000000..5b39d42
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin/MainDialogReduxReducer.cs
@@ -0,0 +1,371 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using Autodesk.Revit.DB;
+using Autodesk.Revit.UI;
+using KGdev.BI3D.Revit.Addin.ExternalEvents;
+using KGdev.BI3D.Revit.Common;
+using KGdev.BI3D.Revit.Common.Models;
+using Newtonsoft.Json.Linq;
+
+namespace KGdev.BI3D.Revit.Addin
+{
+ internal class MainDialogReduxReducer : IReduxReducer
+ {
+ [field: DebuggerBrowsable(DebuggerBrowsableState.Never)]
+ public event EventHandler> OnStateChanged;
+
+ public MainDialogReduxReducer(
+ UIControlledApplication uiApplication,
+ IGlobalStore globalStore,
+ IMuidProvider muidProvider,
+ IConstantsProvider constantsProvider,
+ //IAuthProvider authProvider,
+ ExporterV1ExternalEventInvoker exporterInvoker,
+ List dataExporters
+ )
+ {
+ this.uiApplication = uiApplication;
+ this.globalStore = globalStore;
+ this.muidProvider = muidProvider;
+ this.constantsProvider = constantsProvider;
+ //this.authProvider = authProvider;
+ this.exporterInvoker = exporterInvoker;
+ this.dataExporters = dataExporters;
+ this.optionValues = globalStore.GetDefaultExporterChosenOptionValues();
+ }
+
+ public void Reduce(Dictionary action)
+ {
+ bool flag = !action.ContainsKey("type");
+ if (!flag)
+ {
+ object obj = action["type"];
+ object obj2 = obj;
+ string text = obj2 as string;
+ if (text != null)
+ {
+ if (!(text == "LOADED"))
+ {
+ if (!(text == "CAD_REQUEST_REFRESH_TOKEN"))
+ {
+ if (!(text == "CAD_REQUEST_PURCHASE_KEY"))
+ {
+ if (!(text == "CAD_REQUEST_EXPORT"))
+ {
+ if (!(text == "CAD_REQUEST_OPEN_VIEWER_AND_EXAMPLES_FOLDER"))
+ {
+ if (text == "CAD_REQUEST_UPDATE_OPTION")
+ {
+ this.DoUpdateOption(action);
+ }
+ }
+ else
+ {
+ string text2 = Path.Combine(
+ Path.GetDirectoryName(
+ Assembly.GetExecutingAssembly().Location
+ ),
+ this.constantsProvider.ViewerAndExamplesFolderName
+ );
+ Process.Start("explorer.exe", text2);
+ }
+ }
+ else
+ {
+ this.DoExport(action);
+ }
+ }
+ else
+ {
+ Process.Start(this.constantsProvider.PurchaseUrl);
+ }
+ }
+ else
+ {
+ this.DoRefresh(action);
+ }
+ }
+ else
+ {
+ this.DoLoaded();
+ }
+ }
+ }
+ }
+
+ private void DoLoaded()
+ {
+ this.UpdateStaticState();
+ this.UpdateOptionsState();
+ //this.UpdateAuthState();
+ //string key = this.globalStore.GetKey();
+ //string token = this.globalStore.GetToken();
+ //if (!string.IsNullOrWhiteSpace(token))
+ //{
+ // this.authProvider.TryUpdateToken(key);
+ // this.UpdateAuthState();
+ //}
+ }
+
+ private void DoRefresh(Dictionary action)
+ {
+ if (action.ContainsKey("key"))
+ {
+ string text = action["key"] as string;
+ text = text.Trim();
+ //this.globalStore.SetKey(text);
+ //this.authProvider.TryUpdateToken(text);
+ //this.UpdateAuthState();
+ }
+ }
+
+ private void DoExport(Dictionary action)
+ {
+ //string token = this.globalStore.GetToken();
+ //if (!string.IsNullOrWhiteSpace(token))
+ //{
+ //if ((bool)this.authProvider.ValidateToken(token))
+ //{
+ if (action.ContainsKey("options"))
+ {
+ JArray jarray = action["options"] as JArray;
+ Dictionary options = (
+ from x in jarray.Children()
+ select x.ToObject()
+ ).ToDictionary(
+ (MainDialogReduxStateOption x) => x.id,
+ (MainDialogReduxStateOption x) => x.value
+ );
+ this.exporterInvoker.Export(
+ options,
+ delegate(
+ Document document,
+ Dictionary exportedIds,
+ string path
+ )
+ {
+ foreach (IDataExporter dataExporter in this.dataExporters)
+ {
+ string text = "dataExporter." + dataExporter.Name;
+ if (options.ContainsKey(text) && (bool)options[text])
+ {
+ dataExporter.Export(
+ document,
+ exportedIds.Values.ToList(),
+ path
+ );
+ }
+ }
+ Dictionary dictionary = new Dictionary();
+ dictionary.Add("exportedIds", exportedIds.Keys);
+ dictionary.Add("showExportReport", true);
+ EventHandler> onStateChanged =
+ this.OnStateChanged;
+ if (onStateChanged != null)
+ {
+ onStateChanged(this, dictionary);
+ }
+ }
+ );
+ }
+ //}
+ //}
+ }
+
+ private void DoUpdateOption(Dictionary action)
+ {
+ if (action.ContainsKey("optionId"))
+ {
+ if (action.ContainsKey("value"))
+ {
+ string text = action["optionId"] as string;
+ object obj = action["value"];
+ bool flag3 = this.optionValues.ContainsKey(text);
+ if (flag3)
+ {
+ this.optionValues[text] = obj;
+ }
+ else
+ {
+ this.optionValues.Add(text, obj);
+ }
+ this.UpdateOptionsState();
+ this.globalStore.SetDefaultExporterChosenOptionValues(this.optionValues);
+ }
+ }
+ }
+
+ private void UpdateStaticState()
+ {
+ Dictionary dictionary = new Dictionary();
+ dictionary.Add("version", Assembly.GetExecutingAssembly().GetName().Version.ToString());
+ dictionary.Add("exportIntroText", this.exporterInvoker.ExporterV1.Description);
+ dictionary.Add("introText", "");
+ dictionary.Add(
+ "helpIntroText",
+ "3DBI is a custom visual (.pbiviz file) for Microsoft Power BI that can be loaded into Power BI desktop as well as Power BI online. The 3DBI visual as well as a dashboard with the visual preloaded can be found by clicking the following button:"
+ );
+ dictionary.Add(
+ "helpText",
+ "To insert your .3dbi file in Power BI, the custom 3DBI visual should be loaded into Power BI and placed on the canvas. Then, assign the correct ID field to the \"Object Identifiers\" field. This field should contain Revit Element Ids. The final step is to insert the .3dbi model you just exported (or are about to export) into the visual. You can do that by clicking the \"INSERT MODEL\" button in the visual in Power BI."
+ );
+ EventHandler> onStateChanged = this.OnStateChanged;
+ if (onStateChanged != null)
+ {
+ onStateChanged(this, dictionary);
+ }
+ }
+
+ private void UpdateAuthState()
+ {
+ Dictionary dictionary = new Dictionary();
+ string text = this.globalStore.GetKey();
+ string text2 = this.globalStore.GetToken();
+ bool flag = string.IsNullOrWhiteSpace(text);
+ if (flag)
+ {
+ text = this.constantsProvider.TrialKey;
+ bool flag2 = string.IsNullOrWhiteSpace(text2);
+ if (flag2)
+ {
+ text2 = "Please start your trial version or enter a valid activation key.";
+ }
+ }
+ dictionary.Add("activationKey", text);
+ dictionary.Add("activationToken", text2);
+ dictionary.Add("muid", this.muidProvider.GetMuid());
+ dictionary.Add("productId", this.constantsProvider.ProductId);
+ EventHandler> onStateChanged = this.OnStateChanged;
+ if (onStateChanged != null)
+ {
+ onStateChanged(this, dictionary);
+ }
+ }
+
+ private void UpdateOptionsState()
+ {
+ Dictionary dictionary = new Dictionary();
+ List list = new List();
+ dictionary.Add("options", list);
+ foreach (IOptionDefinition optionDefinition in this.exporterInvoker.ExporterV1.Options)
+ {
+ List list2 = list;
+ MainDialogReduxStateOption mainDialogReduxStateOption =
+ new MainDialogReduxStateOption();
+ mainDialogReduxStateOption.id = optionDefinition.Id;
+ mainDialogReduxStateOption.label = optionDefinition.Label;
+ mainDialogReduxStateOption.description = optionDefinition.Description;
+ mainDialogReduxStateOption.value = (
+ this.optionValues.ContainsKey(optionDefinition.Id)
+ ? this.optionValues[optionDefinition.Id]
+ : optionDefinition.DefaultValue
+ );
+ mainDialogReduxStateOption.type = MainDialogReduxStateOptionType.ByOptionValueType(
+ optionDefinition.OptionValueType
+ );
+ mainDialogReduxStateOption.options = optionDefinition
+ .PossibleValues
+ .Select(
+ (ISelectOptionDefinitionValue x) =>
+ new MainDialogReduxStateSelectOptionValue
+ {
+ label = x.Label,
+ value = x.Value
+ }
+ )
+ .ToList();
+ list2.Add(mainDialogReduxStateOption);
+ }
+ foreach (IDataExporter dataExporter in this.dataExporters)
+ {
+ string text = "dataExporter." + dataExporter.Name;
+ list.Add(
+ new MainDialogReduxStateOption
+ {
+ id = text,
+ label = dataExporter.Name,
+ description = dataExporter.Description,
+ type = MainDialogReduxStateOptionType.ByOptionValueType(
+ OptionValueType.BOOLEAN
+ ),
+ value = (
+ this.optionValues.ContainsKey(text) ? this.optionValues[text] : true
+ )
+ }
+ );
+ }
+ EventHandler> onStateChanged = this.OnStateChanged;
+ if (onStateChanged != null)
+ {
+ onStateChanged(this, dictionary);
+ }
+ }
+
+ private const string LOADED = "LOADED";
+
+ private const string CAD_REQUEST_REFRESH_TOKEN = "CAD_REQUEST_REFRESH_TOKEN";
+
+ private const string CAD_REQUEST_PURCHASE_KEY = "CAD_REQUEST_PURCHASE_KEY";
+
+ private const string CAD_REQUEST_EXPORT = "CAD_REQUEST_EXPORT";
+
+ private const string CAD_REQUEST_UPDATE_OPTION = "CAD_REQUEST_UPDATE_OPTION";
+
+ private const string CAD_REQUEST_OPEN_VIEWER_AND_EXAMPLES_FOLDER =
+ "CAD_REQUEST_OPEN_VIEWER_AND_EXAMPLES_FOLDER";
+
+ private const string STATE_KEY_VERSION = "version";
+
+ private const string STATE_KEY_ACTIVATION_KEY = "activationKey";
+
+ private const string STATE_KEY_ACTIVATION_TOKEN = "activationToken";
+
+ private const string STATE_KEY_MUID = "muid";
+
+ private const string STATE_KEY_PRODUCT_ID = "productId";
+
+ private const string STATE_KEY_OPTIONS = "options";
+
+ private const string STATE_KEY_EXPORT_INTRO_TEXT = "exportIntroText";
+
+ private const string STATE_KEY_EXPORTED_IDS = "exportedIds";
+
+ private const string STATE_KEY_SHOW_EXPORT_REPORT = "showExportReport";
+
+ private const string DATA_EXPORTER_AS_OPTION_ID_PREFIX = "dataExporter.";
+
+ private const string STATE_KEY_INTRO_TEXT = "introText";
+
+ private const string STATE_KEY_HELP_INTRO_TEXT = "helpIntroText";
+
+ private const string STATE_KEY_HELP_TEXT = "helpText";
+
+ private const string INTRO_TEXT = "";
+
+ private const string HELP_INTRO_TEXT =
+ "3DBI is a custom visual (.pbiviz file) for Microsoft Power BI that can be loaded into Power BI desktop as well as Power BI online. The 3DBI visual as well as a dashboard with the visual preloaded can be found by clicking the following button:";
+
+ private const string HELP_TEXT =
+ "To insert your .3dbi file in Power BI, the custom 3DBI visual should be loaded into Power BI and placed on the canvas. Then, assign the correct ID field to the \"Object Identifiers\" field. This field should contain Revit Element Ids. The final step is to insert the .3dbi model you just exported (or are about to export) into the visual. You can do that by clicking the \"INSERT MODEL\" button in the visual in Power BI.";
+
+ private readonly UIControlledApplication uiApplication;
+
+ private readonly IGlobalStore globalStore;
+
+ private readonly IMuidProvider muidProvider;
+
+ private readonly IConstantsProvider constantsProvider;
+
+ //private readonly IAuthProvider authProvider;
+
+ private readonly ExporterV1ExternalEventInvoker exporterInvoker;
+
+ private readonly List dataExporters;
+
+ private Dictionary optionValues = new Dictionary();
+ }
+}
diff --git a/KGdev.BI3D.Revit.Addin/MainDialogReduxStateOption.cs b/KGdev.BI3D.Revit.Addin/MainDialogReduxStateOption.cs
new file mode 100644
index 0000000..3d154d9
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin/MainDialogReduxStateOption.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+
+namespace KGdev.BI3D.Revit.Addin
+{
+ internal class MainDialogReduxStateOption
+ {
+ public string id { get; set; }
+
+ public string label { get; set; }
+
+ public string description { get; set; }
+
+ public string type { get; set; }
+
+ public object value { get; set; }
+
+ public List options { get; set; } =
+ new List();
+ }
+}
diff --git a/KGdev.BI3D.Revit.Addin/MainDialogReduxStateOptionType.cs b/KGdev.BI3D.Revit.Addin/MainDialogReduxStateOptionType.cs
new file mode 100644
index 0000000..1ab3229
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin/MainDialogReduxStateOptionType.cs
@@ -0,0 +1,32 @@
+using System;
+using KGdev.BI3D.Revit.Common;
+
+namespace KGdev.BI3D.Revit.Addin
+{
+ internal class MainDialogReduxStateOptionType
+ {
+ public static string ByOptionValueType(OptionValueType valueType)
+ {
+ string text;
+ switch (valueType)
+ {
+ case OptionValueType.STRING:
+ text = "string";
+ break;
+ case OptionValueType.BOOLEAN:
+ text = "boolean";
+ break;
+ case OptionValueType.NUMBER:
+ text = "number";
+ break;
+ case OptionValueType.SELECT:
+ text = "select";
+ break;
+ default:
+ text = "null";
+ break;
+ }
+ return text;
+ }
+ }
+}
diff --git a/KGdev.BI3D.Revit.Addin/MainDialogReduxStateSelectOptionValue.cs b/KGdev.BI3D.Revit.Addin/MainDialogReduxStateSelectOptionValue.cs
new file mode 100644
index 0000000..65fcf59
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin/MainDialogReduxStateSelectOptionValue.cs
@@ -0,0 +1,11 @@
+using System;
+
+namespace KGdev.BI3D.Revit.Addin
+{
+ internal class MainDialogReduxStateSelectOptionValue
+ {
+ public object value { get; set; }
+
+ public string label { get; set; }
+ }
+}
diff --git a/KGdev.BI3D.Revit.Addin/Properties/AssemblyInfo.cs b/KGdev.BI3D.Revit.Addin/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..9c39a03
--- /dev/null
+++ b/KGdev.BI3D.Revit.Addin/Properties/AssemblyInfo.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Diagnostics;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.Versioning;
+
+[assembly: AssemblyVersion("1.3.0.0")]
+[assembly: AssemblyCompany("KGdev.BI3D.Revit.Addin")]
+[assembly: AssemblyConfiguration("Release 2020")]
+[assembly: AssemblyFileVersion("1.3.0")]
+[assembly: AssemblyInformationalVersion("1.3.0")]
+[assembly: AssemblyProduct("KGdev.BI3D.Revit.Addin")]
+[assembly: AssemblyTitle("KGdev.BI3D.Revit.Addin")]
diff --git a/KGdev.BI3D.Revit.Addin/Resources/3dbi.ico b/KGdev.BI3D.Revit.Addin/Resources/3dbi.ico
new file mode 100644
index 0000000..1d0e1f0
Binary files /dev/null and b/KGdev.BI3D.Revit.Addin/Resources/3dbi.ico differ
diff --git a/KGdev.BI3D.Revit.Common/IAuthProvider.cs b/KGdev.BI3D.Revit.Common/IAuthProvider.cs
new file mode 100644
index 0000000..6e65beb
--- /dev/null
+++ b/KGdev.BI3D.Revit.Common/IAuthProvider.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace KGdev.BI3D.Revit.Common
+{
+ public interface IAuthProvider
+ {
+ bool TryUpdateToken(string key);
+
+ bool ValidateToken(string token);
+
+ bool IsTrial(string token);
+
+ int LicenseTypeInt(string token);
+ }
+}
diff --git a/KGdev.BI3D.Revit.Common/IBI3DViewsProvider.cs b/KGdev.BI3D.Revit.Common/IBI3DViewsProvider.cs
new file mode 100644
index 0000000..bd063a1
--- /dev/null
+++ b/KGdev.BI3D.Revit.Common/IBI3DViewsProvider.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using Autodesk.Revit.DB;
+
+namespace KGdev.BI3D.Revit.Common
+{
+ public interface IBI3DViewsProvider
+ {
+ View3D GetContextView3D(Document document);
+
+ List GetScenes(Document document);
+
+ string GetSceneName(View3D view3d);
+ }
+}
diff --git a/KGdev.BI3D.Revit.Common/IConstantsProvider.cs b/KGdev.BI3D.Revit.Common/IConstantsProvider.cs
new file mode 100644
index 0000000..516bdcd
--- /dev/null
+++ b/KGdev.BI3D.Revit.Common/IConstantsProvider.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace KGdev.BI3D.Revit.Common
+{
+ public interface IConstantsProvider
+ {
+ string ProductId { get; }
+
+ string PurchaseUrl { get; }
+
+ string ViewerAndExamplesFolderName { get; }
+
+ string TrialKey { get; }
+ }
+}
diff --git a/KGdev.BI3D.Revit.Common/IDataExporter.cs b/KGdev.BI3D.Revit.Common/IDataExporter.cs
new file mode 100644
index 0000000..eb0e436
--- /dev/null
+++ b/KGdev.BI3D.Revit.Common/IDataExporter.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using Autodesk.Revit.DB;
+using KGdev.BI3D.Revit.Common.Models;
+
+namespace KGdev.BI3D.Revit.Common
+{
+ public interface IDataExporter
+ {
+ string Name { get; }
+
+ string Description { get; }
+
+ string Extension { get; }
+
+ List Options { get; }
+
+ void Export(
+ Document rootDocument,
+ List exportedElementIdPaths,
+ string path
+ );
+ }
+}
diff --git a/KGdev.BI3D.Revit.Common/IElementIdProvider.cs b/KGdev.BI3D.Revit.Common/IElementIdProvider.cs
new file mode 100644
index 0000000..6885e6e
--- /dev/null
+++ b/KGdev.BI3D.Revit.Common/IElementIdProvider.cs
@@ -0,0 +1,10 @@
+using System;
+using KGdev.BI3D.Revit.Common.Models;
+
+namespace KGdev.BI3D.Revit.Common
+{
+ public interface IElementIdProvider
+ {
+ string GetElementId(LinkedElementIdPath elementIdPath);
+ }
+}
diff --git a/KGdev.BI3D.Revit.Common/IExporter.cs b/KGdev.BI3D.Revit.Common/IExporter.cs
new file mode 100644
index 0000000..9d02d76
--- /dev/null
+++ b/KGdev.BI3D.Revit.Common/IExporter.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using Autodesk.Revit.DB;
+using KGdev.BI3D.Revit.Common.Models;
+
+namespace KGdev.BI3D.Revit.Common
+{
+ public interface IExporter
+ {
+ string Description { get; }
+
+ List Options { get; }
+
+ Dictionary Export(
+ View3D objectsView,
+ string path,
+ Dictionary optionValues
+ );
+ }
+}
diff --git a/KGdev.BI3D.Revit.Common/IGlobalStore.cs b/KGdev.BI3D.Revit.Common/IGlobalStore.cs
new file mode 100644
index 0000000..116ed67
--- /dev/null
+++ b/KGdev.BI3D.Revit.Common/IGlobalStore.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+
+namespace KGdev.BI3D.Revit.Common
+{
+ public interface IGlobalStore
+ {
+ string GetToken();
+
+ void SetToken(string token);
+
+ string GetKey();
+
+ void SetKey(string key);
+
+ string GetAppTempDirectoryPath();
+
+ Dictionary GetDefaultExporterChosenOptionValues();
+
+ void SetDefaultExporterChosenOptionValues(Dictionary valuesDictionary);
+ }
+}
diff --git a/KGdev.BI3D.Revit.Common/ILinkedDocumentsUtilities.cs b/KGdev.BI3D.Revit.Common/ILinkedDocumentsUtilities.cs
new file mode 100644
index 0000000..e29a780
--- /dev/null
+++ b/KGdev.BI3D.Revit.Common/ILinkedDocumentsUtilities.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using Autodesk.Revit.DB;
+using KGdev.BI3D.Revit.Common.Models;
+
+namespace KGdev.BI3D.Revit.Common
+{
+ public interface ILinkedDocumentsUtilities
+ {
+ IList GetLinkedDocuments(
+ Document rootDocument,
+ Transform baseTransform,
+ bool includeThis,
+ List passedLinkInstanceId
+ );
+
+ Element GetElement(Document rootDocument, LinkedElementIdPath path);
+ }
+}
diff --git a/KGdev.BI3D.Revit.Common/IMainWindow.cs b/KGdev.BI3D.Revit.Common/IMainWindow.cs
new file mode 100644
index 0000000..33e9a88
--- /dev/null
+++ b/KGdev.BI3D.Revit.Common/IMainWindow.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace KGdev.BI3D.Revit.Common
+{
+ public interface IMainWindow
+ {
+ void Show();
+
+ void Close();
+
+ bool IsVisible { get; }
+ }
+}
diff --git a/KGdev.BI3D.Revit.Common/IMuidProvider.cs b/KGdev.BI3D.Revit.Common/IMuidProvider.cs
new file mode 100644
index 0000000..a2dcbd3
--- /dev/null
+++ b/KGdev.BI3D.Revit.Common/IMuidProvider.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace KGdev.BI3D.Revit.Common
+{
+ public interface IMuidProvider
+ {
+ string GetMuid();
+ }
+}
diff --git a/KGdev.BI3D.Revit.Common/IOptionDefinition.cs b/KGdev.BI3D.Revit.Common/IOptionDefinition.cs
new file mode 100644
index 0000000..a6d89f0
--- /dev/null
+++ b/KGdev.BI3D.Revit.Common/IOptionDefinition.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+
+namespace KGdev.BI3D.Revit.Common
+{
+ public interface IOptionDefinition
+ {
+ string Id { get; }
+
+ string Label { get; }
+
+ string Description { get; }
+
+ OptionValueType OptionValueType { get; }
+
+ List PossibleValues { get; }
+
+ object DefaultValue { get; }
+
+ double Min { get; }
+
+ double Max { get; }
+
+ double Step { get; }
+ }
+}
diff --git a/KGdev.BI3D.Revit.Common/IReduxReducer.cs b/KGdev.BI3D.Revit.Common/IReduxReducer.cs
new file mode 100644
index 0000000..3ec1ef1
--- /dev/null
+++ b/KGdev.BI3D.Revit.Common/IReduxReducer.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+
+namespace KGdev.BI3D.Revit.Common
+{
+ public interface IReduxReducer
+ {
+ event EventHandler> OnStateChanged;
+
+ void Reduce(Dictionary action);
+ }
+}
diff --git a/KGdev.BI3D.Revit.Common/ISelectOptionDefinitionValue.cs b/KGdev.BI3D.Revit.Common/ISelectOptionDefinitionValue.cs
new file mode 100644
index 0000000..bc7457d
--- /dev/null
+++ b/KGdev.BI3D.Revit.Common/ISelectOptionDefinitionValue.cs
@@ -0,0 +1,11 @@
+using System;
+
+namespace KGdev.BI3D.Revit.Common
+{
+ public interface ISelectOptionDefinitionValue
+ {
+ string Label { get; set; }
+
+ object Value { get; set; }
+ }
+}
diff --git a/KGdev.BI3D.Revit.Common/KGdev.BI3D.Revit.Common.csproj b/KGdev.BI3D.Revit.Common/KGdev.BI3D.Revit.Common.csproj
new file mode 100644
index 0000000..f4f89e4
--- /dev/null
+++ b/KGdev.BI3D.Revit.Common/KGdev.BI3D.Revit.Common.csproj
@@ -0,0 +1,42 @@
+
+
+
+ {1124213F-BDC6-4A9D-BF39-7E916D3FBCA1}
+ Library
+ KGdev.BI3D.Revit.Common
+ KGdev.BI3D.Revit.Common
+ False
+ 512
+ net472
+ x64
+
+
+ False
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ C:\Program Files\Autodesk\Revit 2018\RevitAPI.dll
+ False
+
+
+
\ No newline at end of file
diff --git a/KGdev.BI3D.Revit.Common/Models/LinkedDocumentInformation.cs b/KGdev.BI3D.Revit.Common/Models/LinkedDocumentInformation.cs
new file mode 100644
index 0000000..5217516
--- /dev/null
+++ b/KGdev.BI3D.Revit.Common/Models/LinkedDocumentInformation.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using Autodesk.Revit.DB;
+
+namespace KGdev.BI3D.Revit.Common.Models
+{
+ public class LinkedDocumentInformation
+ {
+ public Document Document { get; set; }
+
+ public Transform TransformToRoot { get; set; }
+
+ public List PassedLinkInstanceIds { get; set; } = new List();
+ }
+}
diff --git a/KGdev.BI3D.Revit.Common/Models/LinkedElementIdPath.cs b/KGdev.BI3D.Revit.Common/Models/LinkedElementIdPath.cs
new file mode 100644
index 0000000..dba6741
--- /dev/null
+++ b/KGdev.BI3D.Revit.Common/Models/LinkedElementIdPath.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Collections.Generic;
+using Autodesk.Revit.DB;
+
+namespace KGdev.BI3D.Revit.Common.Models
+{
+ public class LinkedElementIdPath
+ {
+ public List ElementIds { get; private set; } = new List();
+
+ public LinkedElementIdPath(IList elementIds)
+ {
+ this.ElementIds.AddRange(elementIds);
+ }
+
+ public override bool Equals(object obj)
+ {
+ LinkedElementIdPath linkedElementIdPath = obj as LinkedElementIdPath;
+ bool flag = linkedElementIdPath == null;
+ bool flag2;
+ if (flag)
+ {
+ flag2 = false;
+ }
+ else
+ {
+ bool flag3 = this.ElementIds.Count != linkedElementIdPath.ElementIds.Count;
+ if (flag3)
+ {
+ flag2 = false;
+ }
+ else
+ {
+ for (int i = 0; i < this.ElementIds.Count; i++)
+ {
+ int integerValue = this.ElementIds[i].IntegerValue;
+ int integerValue2 = linkedElementIdPath.ElementIds[i].IntegerValue;
+ bool flag4 = integerValue != integerValue2;
+ if (flag4)
+ {
+ return false;
+ }
+ }
+ flag2 = true;
+ }
+ }
+ return flag2;
+ }
+
+ public override int GetHashCode()
+ {
+ int num = this.ElementIds.Count.GetHashCode();
+ foreach (ElementId elementId in this.ElementIds)
+ {
+ num ^= elementId.IntegerValue.GetHashCode();
+ }
+ return num;
+ }
+ }
+}
diff --git a/KGdev.BI3D.Revit.Common/OptionValueType.cs b/KGdev.BI3D.Revit.Common/OptionValueType.cs
new file mode 100644
index 0000000..51a0d02
--- /dev/null
+++ b/KGdev.BI3D.Revit.Common/OptionValueType.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace KGdev.BI3D.Revit.Common
+{
+ public enum OptionValueType
+ {
+ STRING,
+ BOOLEAN,
+ NUMBER,
+ SELECT
+ }
+}
diff --git a/KGdev.BI3D.Revit.Common/Properties/AssemblyInfo.cs b/KGdev.BI3D.Revit.Common/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..507de4a
--- /dev/null
+++ b/KGdev.BI3D.Revit.Common/Properties/AssemblyInfo.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Diagnostics;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.Versioning;
+
+[assembly: AssemblyVersion("1.3.0.0")]
+[assembly: AssemblyCompany("KGdev.BI3D.Revit.Common")]
+[assembly: AssemblyConfiguration("Release 2020")]
+[assembly: AssemblyFileVersion("1.3.0")]
+[assembly: AssemblyInformationalVersion("1.3.0")]
+[assembly: AssemblyProduct("KGdev.BI3D.Revit.Common")]
+[assembly: AssemblyTitle("KGdev.BI3D.Revit.Common")]
diff --git a/KGdev.BI3D.Revit.DataExporter.JsonTable/JsonTableDataExporter.cs b/KGdev.BI3D.Revit.DataExporter.JsonTable/JsonTableDataExporter.cs
new file mode 100644
index 0000000..558df2b
--- /dev/null
+++ b/KGdev.BI3D.Revit.DataExporter.JsonTable/JsonTableDataExporter.cs
@@ -0,0 +1,399 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using Autodesk.Revit.DB;
+using KGdev.BI3D.Revit.Common;
+using KGdev.BI3D.Revit.Common.Models;
+using Newtonsoft.Json;
+
+namespace KGdev.BI3D.Revit.DataExporter.JsonTable
+{
+ public class JsonTableDataExporter : IDataExporter
+ {
+ public string Name
+ {
+ get { return ".json single elements array"; }
+ }
+
+ public string Description
+ {
+ get
+ {
+ return "Export data to a .json file representing a single table with all parameters of all exported elements as columns. The .json file will be placed next to the .3dbi file and will be named [FILENAME]_data.json.";
+ }
+ }
+
+ public string Extension
+ {
+ get { return "json"; }
+ }
+
+ public List Options { get; } = new List();
+
+ public JsonTableDataExporter(
+ ILinkedDocumentsUtilities linkedDocumentsUtilities,
+ IElementIdProvider elementIdProvider
+ )
+ {
+ this.linkedDocumentsUtilities = linkedDocumentsUtilities;
+ this.elementIdProvider = elementIdProvider;
+ }
+
+ public void Export(
+ Document rootDocument,
+ List exportedElementIdPaths,
+ string path
+ )
+ {
+ JsonTableDataExporterResult jsonTableDataExporterResult =
+ new JsonTableDataExporterResult();
+ path = Path.Combine(
+ Path.GetDirectoryName(path),
+ Path.GetFileNameWithoutExtension(path) + "_data." + this.Extension
+ );
+ Dictionary> dictionary =
+ new Dictionary>();
+ HashSet hashSet = new HashSet { "Id", "CategoryName" };
+ Dictionary dictionary2 = new Dictionary();
+ foreach (LinkedElementIdPath linkedElementIdPath in exportedElementIdPaths)
+ {
+ Element element = this.linkedDocumentsUtilities.GetElement(
+ rootDocument,
+ linkedElementIdPath
+ );
+ string elementId = this.elementIdProvider.GetElementId(linkedElementIdPath);
+ bool flag = element.Category == null;
+ if (!flag)
+ {
+ ElementId typeId = element.GetTypeId();
+ LinkedElementIdPath linkedElementIdPath2 = new LinkedElementIdPath(
+ linkedElementIdPath.ElementIds
+ );
+ int count = linkedElementIdPath2.ElementIds.Count;
+ linkedElementIdPath2.ElementIds.RemoveAt(count - 1);
+ linkedElementIdPath2.ElementIds.Add(typeId);
+ ElementType elementType =
+ this.linkedDocumentsUtilities.GetElement(rootDocument, linkedElementIdPath2)
+ as ElementType;
+ string elementId2 = this.elementIdProvider.GetElementId(linkedElementIdPath2);
+ bool flag2 = !dictionary2.ContainsKey(elementId2) && elementType != null;
+ if (flag2)
+ {
+ dictionary2.Add(elementId2, elementType);
+ }
+ this.StoreElementInCollection(element, elementId, dictionary, hashSet);
+ }
+ }
+ Action, Dictionary>> action =
+ null;
+ if (action == null)
+ {
+ action = delegate(
+ IEnumerable keys,
+ Dictionary> objects
+ )
+ {
+ foreach (string text3 in keys)
+ {
+ foreach (string text4 in objects.Keys)
+ {
+ Dictionary dictionary5 = objects[text4];
+ bool flag7 = !dictionary5.ContainsKey(text3);
+ if (flag7)
+ {
+ dictionary5.Add(text3, null);
+ }
+ }
+ }
+ };
+ }
+ List> list = dictionary
+ .Values
+ .ToList>();
+ bool flag3 = list.Count > 0;
+ if (flag3)
+ {
+ Dictionary dictionary3 = list[0];
+ foreach (string text in hashSet)
+ {
+ bool flag4 = !dictionary3.ContainsKey(text);
+ if (flag4)
+ {
+ dictionary3.Add(text, null);
+ }
+ }
+ }
+ jsonTableDataExporterResult.Objects.AddRange(list);
+ dictionary.Clear();
+ hashSet.Clear();
+ foreach (KeyValuePair keyValuePair in dictionary2)
+ {
+ this.StoreElementInCollection(
+ keyValuePair.Value,
+ keyValuePair.Key,
+ dictionary,
+ hashSet
+ );
+ }
+ list = dictionary.Values.ToList>();
+ bool flag5 = list.Count > 0;
+ if (flag5)
+ {
+ Dictionary dictionary4 = list[0];
+ foreach (string text2 in hashSet)
+ {
+ bool flag6 = !dictionary4.ContainsKey(text2);
+ if (flag6)
+ {
+ dictionary4.Add(text2, null);
+ }
+ }
+ }
+ jsonTableDataExporterResult.Types.AddRange(list);
+ JsonTableDataExporterResult jsonTableDataExporterResult2 = jsonTableDataExporterResult;
+ JsonTableDataExporterDocumentInfo jsonTableDataExporterDocumentInfo =
+ new JsonTableDataExporterDocumentInfo();
+ jsonTableDataExporterDocumentInfo.Path = rootDocument.PathName;
+ ProjectInfo projectInformation = rootDocument.ProjectInformation;
+ jsonTableDataExporterDocumentInfo.Address = (
+ (projectInformation != null) ? projectInformation.Address : null
+ );
+ ProjectInfo projectInformation2 = rootDocument.ProjectInformation;
+ jsonTableDataExporterDocumentInfo.Author = (
+ (projectInformation2 != null) ? projectInformation2.Author : null
+ );
+ ProjectInfo projectInformation3 = rootDocument.ProjectInformation;
+ jsonTableDataExporterDocumentInfo.BuildingName = (
+ (projectInformation3 != null) ? projectInformation3.BuildingName : null
+ );
+ ProjectInfo projectInformation4 = rootDocument.ProjectInformation;
+ jsonTableDataExporterDocumentInfo.ClientName = (
+ (projectInformation4 != null) ? projectInformation4.ClientName : null
+ );
+ ProjectInfo projectInformation5 = rootDocument.ProjectInformation;
+ jsonTableDataExporterDocumentInfo.IssueDate = (
+ (projectInformation5 != null) ? projectInformation5.IssueDate : null
+ );
+ ProjectInfo projectInformation6 = rootDocument.ProjectInformation;
+ jsonTableDataExporterDocumentInfo.Name = (
+ (projectInformation6 != null) ? projectInformation6.Name : null
+ );
+ ProjectInfo projectInformation7 = rootDocument.ProjectInformation;
+ jsonTableDataExporterDocumentInfo.Number = (
+ (projectInformation7 != null) ? projectInformation7.Number : null
+ );
+ ProjectInfo projectInformation8 = rootDocument.ProjectInformation;
+ jsonTableDataExporterDocumentInfo.OrganizationDescription = (
+ (projectInformation8 != null) ? projectInformation8.OrganizationDescription : null
+ );
+ ProjectInfo projectInformation9 = rootDocument.ProjectInformation;
+ jsonTableDataExporterDocumentInfo.OrganizationName = (
+ (projectInformation9 != null) ? projectInformation9.OrganizationName : null
+ );
+ ProjectInfo projectInformation10 = rootDocument.ProjectInformation;
+ jsonTableDataExporterDocumentInfo.Status = (
+ (projectInformation10 != null) ? projectInformation10.Status : null
+ );
+ jsonTableDataExporterResult2.DocumentInfo = jsonTableDataExporterDocumentInfo;
+ using (StreamWriter streamWriter = File.CreateText(path))
+ {
+ JsonSerializer jsonSerializer = new JsonSerializer();
+ jsonSerializer.Serialize(streamWriter, jsonTableDataExporterResult);
+ }
+ }
+
+ private void StoreElementInCollection(
+ Element element,
+ string id,
+ Dictionary> objectDictionaryByObjectId,
+ HashSet encounteredPropertyNames
+ )
+ {
+ Document document = element.Document;
+ string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(document.PathName);
+ bool flag = !objectDictionaryByObjectId.ContainsKey(id);
+ Dictionary dictionary;
+ if (flag)
+ {
+ dictionary = new Dictionary();
+ dictionary.Add("DocumentName", fileNameWithoutExtension);
+ dictionary.Add("Id", id);
+ dictionary.Add("ElementId", element.Id.IntegerValue);
+ Dictionary dictionary2 = dictionary;
+ string text = "CategoryName";
+ Category category = element.Category;
+ dictionary2.Add(text, (category != null) ? category.Name : null);
+ Dictionary dictionary3 = dictionary;
+ string text2 = "TypeId";
+ ElementId typeId = element.GetTypeId();
+ dictionary3.Add(text2, (typeId != null) ? typeId.IntegerValue.ToString() : null);
+ objectDictionaryByObjectId.Add(id, dictionary);
+ }
+ else
+ {
+ dictionary = objectDictionaryByObjectId[id];
+ }
+ foreach (object obj in element.Parameters)
+ {
+ Parameter parameter = (Parameter)obj;
+ object obj2 = null;
+ object obj3 = null;
+ string text3 = null;
+ switch (parameter.StorageType)
+ {
+ case StorageType.Integer:
+ obj2 = parameter.AsInteger();
+ break;
+ case StorageType.Double:
+ {
+ obj2 = parameter.AsDouble();
+ UnitType unitType = parameter.Definition.UnitType;
+ bool flag2 = UnitUtils.IsValidUnitType(unitType);
+ if (flag2)
+ {
+ DisplayUnitType displayUnits = document
+ .GetUnits()
+ .GetFormatOptions(unitType)
+ .DisplayUnits;
+ text3 = displayUnits.ToString();
+ obj3 = UnitUtils.ConvertFromInternalUnits(
+ parameter.AsDouble(),
+ displayUnits
+ );
+ }
+ break;
+ }
+ case StorageType.String:
+ obj2 = parameter.AsString();
+ break;
+ case StorageType.ElementId:
+ {
+ ElementId elementId = parameter.AsElementId();
+ Element element2 = document.GetElement(elementId);
+ obj2 = ((element2 != null) ? element2.Name : "");
+ break;
+ }
+ }
+ int num = 2;
+ string text4 = "Parameter." + parameter.Definition.Name;
+ while (dictionary.ContainsKey(text4))
+ {
+ text4 = string.Format(
+ "{0}{1}.{2}",
+ "Parameter.",
+ parameter.Definition.Name,
+ num
+ );
+ num++;
+ }
+ dictionary.Add(text4, obj2);
+ bool flag3 = !encounteredPropertyNames.Contains(text4);
+ if (flag3)
+ {
+ encounteredPropertyNames.Add(text4);
+ }
+ bool flag4 = obj3 != null;
+ if (flag4)
+ {
+ text4 = text4 + "." + text3;
+ bool flag5 = !encounteredPropertyNames.Contains(text4);
+ if (flag5)
+ {
+ encounteredPropertyNames.Add(text4);
+ }
+ bool flag6 = !dictionary.ContainsKey(text4);
+ if (flag6)
+ {
+ dictionary.Add(text4, obj3);
+ }
+ }
+ }
+ IEnumerable enumerable =
+ from p in element.GetType().GetProperties()
+ where p.GetIndexParameters().Length == 0
+ select p;
+ foreach (PropertyInfo propertyInfo in enumerable)
+ {
+ string text5 = "Property." + propertyInfo.Name;
+ bool flag7 = dictionary.ContainsKey(text5);
+ if (!flag7)
+ {
+ object obj4 = null;
+ try
+ {
+ obj4 = propertyInfo.GetValue(element);
+ }
+ catch
+ {
+ continue;
+ }
+ bool flag8 = !encounteredPropertyNames.Contains(text5);
+ if (flag8)
+ {
+ encounteredPropertyNames.Add(text5);
+ }
+ bool flag9 = obj4 == null;
+ if (flag9)
+ {
+ dictionary.Add(text5, null);
+ }
+ else
+ {
+ Type type = obj4.GetType();
+ bool isValueType = type.IsValueType;
+ if (isValueType)
+ {
+ dictionary.Add(text5, obj4);
+ }
+ else
+ {
+ ElementId elementId2 = obj4 as ElementId;
+ bool flag10 = null != elementId2;
+ if (flag10)
+ {
+ dictionary.Add(text5, elementId2.IntegerValue.ToString());
+ }
+ else
+ {
+ Element element3 = obj4 as Element;
+ bool flag11 = element3 != null;
+ if (flag11)
+ {
+ dictionary.Add(text5, element3.Id.IntegerValue.ToString());
+ }
+ else
+ {
+ dictionary.Add(text5, obj4.ToString());
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private const string ID_KEY = "Id";
+
+ private const string ELEMENT_ID_KEY = "ElementId";
+
+ private const string CATEGORY_NAME_KEY = "CategoryName";
+
+ private const string TYPE_ID_NAME_KEY = "TypeId";
+
+ private const string ELEMENT_DOCUMENT_NAME_KEY = "DocumentName";
+
+ private const string PARAMETER_PREFIX = "Parameter.";
+
+ private const string PARAMETER_BUILTIN_PREFIX = "BuiltIn.";
+
+ private const string PROPERTY_PREFIX = "Property.";
+
+ private const string FILE_SUFFIX = "_data";
+
+ private readonly ILinkedDocumentsUtilities linkedDocumentsUtilities;
+
+ private readonly IElementIdProvider elementIdProvider;
+ }
+}
diff --git a/KGdev.BI3D.Revit.DataExporter.JsonTable/JsonTableDataExporterDocumentInfo.cs b/KGdev.BI3D.Revit.DataExporter.JsonTable/JsonTableDataExporterDocumentInfo.cs
new file mode 100644
index 0000000..aa32db1
--- /dev/null
+++ b/KGdev.BI3D.Revit.DataExporter.JsonTable/JsonTableDataExporterDocumentInfo.cs
@@ -0,0 +1,29 @@
+using System;
+
+namespace KGdev.BI3D.Revit.DataExporter.JsonTable
+{
+ internal class JsonTableDataExporterDocumentInfo
+ {
+ public string Path { get; set; }
+
+ public string OrganizationDescription { get; set; }
+
+ public string OrganizationName { get; set; }
+
+ public string BuildingName { get; set; }
+
+ public string Author { get; set; }
+
+ public string Number { get; set; }
+
+ public string Name { get; set; }
+
+ public string Address { get; set; }
+
+ public string ClientName { get; set; }
+
+ public string Status { get; set; }
+
+ public string IssueDate { get; set; }
+ }
+}
diff --git a/KGdev.BI3D.Revit.DataExporter.JsonTable/JsonTableDataExporterResult.cs b/KGdev.BI3D.Revit.DataExporter.JsonTable/JsonTableDataExporterResult.cs
new file mode 100644
index 0000000..32f47f8
--- /dev/null
+++ b/KGdev.BI3D.Revit.DataExporter.JsonTable/JsonTableDataExporterResult.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+
+namespace KGdev.BI3D.Revit.DataExporter.JsonTable
+{
+ internal class JsonTableDataExporterResult
+ {
+ public JsonTableDataExporterDocumentInfo DocumentInfo { get; set; }
+
+ public List> Objects { get; } =
+ new List>();
+
+ public List> Types { get; } =
+ new List>();
+ }
+}
diff --git a/KGdev.BI3D.Revit.DataExporter.JsonTable/KGdev.BI3D.Revit.DataExporter.JsonTable.csproj b/KGdev.BI3D.Revit.DataExporter.JsonTable/KGdev.BI3D.Revit.DataExporter.JsonTable.csproj
new file mode 100644
index 0000000..5781898
--- /dev/null
+++ b/KGdev.BI3D.Revit.DataExporter.JsonTable/KGdev.BI3D.Revit.DataExporter.JsonTable.csproj
@@ -0,0 +1,36 @@
+
+
+
+ {AF3ADBA9-E7CC-4D34-BF1B-12C2E6705953}
+ Library
+ KGdev.BI3D.Revit.DataExporter.JsonTable
+ KGdev.BI3D.Revit.DataExporter.JsonTable
+ False
+ 512
+ net472
+ x64
+
+
+ False
+
+
+
+
+
+
+
+
+
+
+
+
+
+ C:\ProgramData\Autodesk\Revit\Addins\2020\3DBI for Revit\Newtonsoft.Json.dll
+
+
+ C:\Program Files\Autodesk\Revit 2018\RevitAPI.dll
+ False
+
+
+
+
\ No newline at end of file
diff --git a/KGdev.BI3D.Revit.DataExporter.JsonTable/Properties/AssemblyInfo.cs b/KGdev.BI3D.Revit.DataExporter.JsonTable/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..0a789fe
--- /dev/null
+++ b/KGdev.BI3D.Revit.DataExporter.JsonTable/Properties/AssemblyInfo.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Diagnostics;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.Versioning;
+
+[assembly: AssemblyVersion("1.3.0.0")]
+[assembly: AssemblyCompany("KGdev.BI3D.Revit.DataExporter.JsonTable")]
+[assembly: AssemblyConfiguration("Release 2020")]
+[assembly: AssemblyFileVersion("1.3.0")]
+[assembly: AssemblyInformationalVersion("1.3.0")]
+[assembly: AssemblyProduct("KGdev.BI3D.Revit.DataExporter.JsonTable")]
+[assembly: AssemblyTitle("KGdev.BI3D.Revit.DataExporter.JsonTable")]
diff --git a/KGdev.BI3D.Revit.ExporterV2/Edge.cs b/KGdev.BI3D.Revit.ExporterV2/Edge.cs
new file mode 100644
index 0000000..72a1037
--- /dev/null
+++ b/KGdev.BI3D.Revit.ExporterV2/Edge.cs
@@ -0,0 +1,11 @@
+using System;
+
+namespace KGdev.BI3D.Revit.ExporterV2
+{
+ internal struct Edge
+ {
+ public int LargestIndex;
+
+ public int SmallestIndex;
+ }
+}
diff --git a/KGdev.BI3D.Revit.ExporterV2/Exporter.cs b/KGdev.BI3D.Revit.ExporterV2/Exporter.cs
new file mode 100644
index 0000000..63f2924
--- /dev/null
+++ b/KGdev.BI3D.Revit.ExporterV2/Exporter.cs
@@ -0,0 +1,530 @@
+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"
+ }
+ };
+ }
+}
diff --git a/KGdev.BI3D.Revit.ExporterV2/GeometryRetriever.cs b/KGdev.BI3D.Revit.ExporterV2/GeometryRetriever.cs
new file mode 100644
index 0000000..47cfcf8
--- /dev/null
+++ b/KGdev.BI3D.Revit.ExporterV2/GeometryRetriever.cs
@@ -0,0 +1,290 @@
+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;
+ }
+}
diff --git a/KGdev.BI3D.Revit.ExporterV2/GeometryRetrieverResult.cs b/KGdev.BI3D.Revit.ExporterV2/GeometryRetrieverResult.cs
new file mode 100644
index 0000000..1b97e4e
--- /dev/null
+++ b/KGdev.BI3D.Revit.ExporterV2/GeometryRetrieverResult.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using KGdev.BI3D.Revit.Common.Models;
+
+namespace KGdev.BI3D.Revit.ExporterV2
+{
+ internal class GeometryRetrieverResult
+ {
+ public List Positions { get; } = new List();
+
+ public List Indices { get; } = new List();
+
+ public List Colors { get; } = new List();
+
+ public List ColorIndices { get; } = new List();
+
+ public List Ids { get; } = new List { "" };
+
+ public Dictionary ExportedElementIdPathById { get; } =
+ new Dictionary();
+
+ public List IdIndices { get; } = new List();
+ }
+}
diff --git a/KGdev.BI3D.Revit.ExporterV2/HasherInput.cs b/KGdev.BI3D.Revit.ExporterV2/HasherInput.cs
new file mode 100644
index 0000000..b9ecc8a
--- /dev/null
+++ b/KGdev.BI3D.Revit.ExporterV2/HasherInput.cs
@@ -0,0 +1,11 @@
+using System;
+
+namespace KGdev.BI3D.Revit.ExporterV2
+{
+ internal class HasherInput
+ {
+ public string HexSha512Hash { get; set; }
+
+ public string Token { get; set; }
+ }
+}
diff --git a/KGdev.BI3D.Revit.ExporterV2/HasherOutput.cs b/KGdev.BI3D.Revit.ExporterV2/HasherOutput.cs
new file mode 100644
index 0000000..3669e03
--- /dev/null
+++ b/KGdev.BI3D.Revit.ExporterV2/HasherOutput.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace KGdev.BI3D.Revit.ExporterV2
+{
+ internal class HasherOutput
+ {
+ public string Signature { get; set; }
+ }
+}
diff --git a/KGdev.BI3D.Revit.ExporterV2/KGdev.BI3D.Revit.ExporterV2.csproj b/KGdev.BI3D.Revit.ExporterV2/KGdev.BI3D.Revit.ExporterV2.csproj
new file mode 100644
index 0000000..6fe264c
--- /dev/null
+++ b/KGdev.BI3D.Revit.ExporterV2/KGdev.BI3D.Revit.ExporterV2.csproj
@@ -0,0 +1,46 @@
+
+
+
+ {BB5F900A-1B85-45E7-BF11-B332FD436D05}
+ Library
+ KGdev.BI3D.Revit.ExporterV2
+ KGdev.BI3D.Revit.ExporterV2
+ False
+ 512
+ net472
+ x64
+
+
+ False
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ C:\ProgramData\Autodesk\Revit\Addins\2020\3DBI for Revit\Newtonsoft.Json.dll
+
+
+ C:\Program Files\Autodesk\Revit 2018\RevitAPI.dll
+ False
+
+
+
+
+
\ No newline at end of file
diff --git a/KGdev.BI3D.Revit.ExporterV2/OptionDefinition.cs b/KGdev.BI3D.Revit.ExporterV2/OptionDefinition.cs
new file mode 100644
index 0000000..8b0af57
--- /dev/null
+++ b/KGdev.BI3D.Revit.ExporterV2/OptionDefinition.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using KGdev.BI3D.Revit.Common;
+
+namespace KGdev.BI3D.Revit.ExporterV2
+{
+ internal class OptionDefinition : IOptionDefinition
+ {
+ public string Id { get; set; }
+
+ public string Label { get; set; }
+
+ public string Description { get; set; }
+
+ public OptionValueType OptionValueType { get; set; }
+
+ public List PossibleValues { get; set; } =
+ new List();
+
+ public object DefaultValue { get; set; }
+
+ public double Min { get; set; }
+
+ public double Max { get; set; }
+
+ public double Step { get; set; }
+ }
+}
diff --git a/KGdev.BI3D.Revit.ExporterV2/Position.cs b/KGdev.BI3D.Revit.ExporterV2/Position.cs
new file mode 100644
index 0000000..01e3f01
--- /dev/null
+++ b/KGdev.BI3D.Revit.ExporterV2/Position.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace KGdev.BI3D.Revit.ExporterV2
+{
+ internal struct Position
+ {
+ public float X;
+
+ public float Y;
+
+ public float Z;
+ }
+}
diff --git a/KGdev.BI3D.Revit.ExporterV2/Properties/AssemblyInfo.cs b/KGdev.BI3D.Revit.ExporterV2/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..73d283c
--- /dev/null
+++ b/KGdev.BI3D.Revit.ExporterV2/Properties/AssemblyInfo.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Diagnostics;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.Versioning;
+
+[assembly: AssemblyVersion("1.3.0.0")]
+[assembly: AssemblyCompany("KGdev.BI3D.Revit.ExporterV2")]
+[assembly: AssemblyConfiguration("Release 2020")]
+[assembly: AssemblyFileVersion("1.3.0")]
+[assembly: AssemblyInformationalVersion("1.3.0")]
+[assembly: AssemblyProduct("KGdev.BI3D.Revit.ExporterV2")]
+[assembly: AssemblyTitle("KGdev.BI3D.Revit.ExporterV2")]
diff --git a/KGdev.BI3D.Revit.ExporterV2/RGBA.cs b/KGdev.BI3D.Revit.ExporterV2/RGBA.cs
new file mode 100644
index 0000000..db72518
--- /dev/null
+++ b/KGdev.BI3D.Revit.ExporterV2/RGBA.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace KGdev.BI3D.Revit.ExporterV2
+{
+ internal struct RGBA
+ {
+ public byte R;
+
+ public byte G;
+
+ public byte B;
+
+ public byte A;
+ }
+}
diff --git a/KGdev.BI3D.Revit.ExporterV2/RoomGeometryRetriever.cs b/KGdev.BI3D.Revit.ExporterV2/RoomGeometryRetriever.cs
new file mode 100644
index 0000000..2b9fbc3
--- /dev/null
+++ b/KGdev.BI3D.Revit.ExporterV2/RoomGeometryRetriever.cs
@@ -0,0 +1,266 @@
+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 linkedParentElementIds
+ )
+ {
+ this.indexForPosition = new Dictionary();
+ for (int i = 0; i < resultContainer.Positions.Count; i++)
+ {
+ Position position = resultContainer.Positions[i];
+ this.indexForPosition.Add(position, i);
+ }
+ this.indexForId = new Dictionary();
+ 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();
+ 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.OST_MEPSpaces,
+ BuiltInCategory.OST_Rooms
+ }
+ );
+ List list = new FilteredElementCollector(document)
+ .WherePasses(elementMulticategoryFilter)
+ .WhereElementIsNotElementType()
+ .ToList();
+ 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(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> dictionary =
+ new Dictionary>();
+ IList 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 list2 = new List
+ {
+ 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());
+ }
+ 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 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 indexForPosition;
+
+ private Dictionary indexForId;
+
+ private Dictionary indexForColor;
+ }
+}
diff --git a/KGdev.BI3D.Revit.ExporterV2/SelectOptionDefinitionValue.cs b/KGdev.BI3D.Revit.ExporterV2/SelectOptionDefinitionValue.cs
new file mode 100644
index 0000000..bae96c6
--- /dev/null
+++ b/KGdev.BI3D.Revit.ExporterV2/SelectOptionDefinitionValue.cs
@@ -0,0 +1,12 @@
+using System;
+using KGdev.BI3D.Revit.Common;
+
+namespace KGdev.BI3D.Revit.ExporterV2
+{
+ internal class SelectOptionDefinitionValue : ISelectOptionDefinitionValue
+ {
+ public string Label { get; set; }
+
+ public object Value { get; set; }
+ }
+}
diff --git a/KGdev.BI3D.Revit.ExporterV2/XYZExtensions.cs b/KGdev.BI3D.Revit.ExporterV2/XYZExtensions.cs
new file mode 100644
index 0000000..6ff6bbc
--- /dev/null
+++ b/KGdev.BI3D.Revit.ExporterV2/XYZExtensions.cs
@@ -0,0 +1,18 @@
+using System;
+using Autodesk.Revit.DB;
+
+namespace KGdev.BI3D.Revit.ExporterV2
+{
+ internal static class XYZExtensions
+ {
+ public static Position To3DBIPosition(this XYZ revitXYZ)
+ {
+ return new Position
+ {
+ X = (float)(-(float)revitXYZ.X * 12.0),
+ Y = (float)(revitXYZ.Z * 12.0),
+ Z = (float)(revitXYZ.Y * 12.0)
+ };
+ }
+ }
+}
diff --git a/KGdev.BI3D.Revit/Extension.cs b/KGdev.BI3D.Revit/Extension.cs
new file mode 100644
index 0000000..cb65014
--- /dev/null
+++ b/KGdev.BI3D.Revit/Extension.cs
@@ -0,0 +1,117 @@
+using System;
+using System.Collections.Generic;
+using KGdev.BI3D.Revit.Common;
+using KGdev.BI3D.Revit.DataExporter.JsonTable;
+using KGdev.BI3D.Revit.ExporterV2;
+using KGdev.BI3D.Revit.Implementations;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace KGdev.BI3D.Revit
+{
+ public class Extension
+ {
+ public static Extension Instance
+ {
+ get
+ {
+ object obj = Extension.instanceLock;
+ Extension extension;
+ lock (obj)
+ {
+ if (Extension.instance == null)
+ {
+ Extension.instance = new Extension();
+ }
+ extension = Extension.instance;
+ }
+ return extension;
+ }
+ }
+
+ public IServiceProvider ServiceProvider { get; private set; }
+
+ private Extension()
+ {
+ this.ServiceProvider = this.BuildServiceProvider();
+ }
+
+ private IServiceProvider BuildServiceProvider()
+ {
+ ServiceCollection serviceCollection = new ServiceCollection();
+ serviceCollection.AddTransient(
+ (IServiceProvider _) => new DefaultBI3DViewsProvider()
+ );
+ serviceCollection.AddTransient(
+ (IServiceProvider _) => new DefaultElementIdProvider()
+ );
+ serviceCollection.AddTransient<
+ ILinkedDocumentsUtilities,
+ DefaultLinkedDocumentUtilities
+ >((IServiceProvider _) => new DefaultLinkedDocumentUtilities());
+ serviceCollection.AddTransient(
+ (IServiceProvider provider) =>
+ {
+ IBI3DViewsProvider requiredService =
+ provider.GetRequiredService();
+ IElementIdProvider requiredService2 =
+ provider.GetRequiredService();
+ IGlobalStore requiredService3 = provider.GetRequiredService();
+ ILinkedDocumentsUtilities requiredService4 =
+ provider.GetRequiredService();
+ //IAuthProvider requiredService5 = provider.GetRequiredService();
+ IElementIdProvider requiredService6 =
+ provider.GetRequiredService();
+ return new Exporter(
+ requiredService,
+ requiredService3,
+ requiredService4,
+ //requiredService5,
+ requiredService6
+ );
+ }
+ );
+ serviceCollection.AddTransient(
+ (IServiceProvider provider) =>
+ {
+ ILinkedDocumentsUtilities requiredService7 =
+ provider.GetRequiredService();
+ IElementIdProvider requiredService8 =
+ provider.GetRequiredService();
+ return new List
+ {
+ new JsonTableDataExporter(requiredService7, requiredService8)
+ };
+ }
+ );
+ serviceCollection.AddTransient(
+ (IServiceProvider _) => new DefaultGlobalStore()
+ );
+ serviceCollection.AddTransient(
+ (IServiceProvider _) => new DefaultMuidProvider()
+ );
+ serviceCollection.AddTransient(
+ (IServiceProvider _) => new DefaultConstantsProvider()
+ );
+ //serviceCollection.AddTransient(
+ // (IServiceProvider provider) =>
+ // {
+ // IMuidProvider requiredService9 = provider.GetRequiredService();
+ // IConstantsProvider requiredService10 =
+ // provider.GetRequiredService();
+ // IGlobalStore requiredService11 = provider.GetRequiredService();
+ // return new DefaultAuthProvider(
+ // requiredService10.ProductId,
+ // requiredService9,
+ // requiredService11
+ // );
+ // }
+ //);
+
+ return serviceCollection.BuildServiceProvider();
+ }
+
+ private static Extension instance;
+
+ private static object instanceLock = new object();
+ }
+}
diff --git a/KGdev.BI3D.Revit/Implementations/DefaultAuthProvider.cs b/KGdev.BI3D.Revit/Implementations/DefaultAuthProvider.cs
new file mode 100644
index 0000000..e5f0576
--- /dev/null
+++ b/KGdev.BI3D.Revit/Implementations/DefaultAuthProvider.cs
@@ -0,0 +1,482 @@
+using System;
+using System.IdentityModel.Tokens.Jwt;
+using System.Net.Http;
+using System.Security.Cryptography;
+using KGdev.BI3D.Revit.Common;
+using Microsoft.IdentityModel.Tokens;
+using Newtonsoft.Json.Linq;
+
+namespace KGdev.BI3D.Revit.Implementations
+{
+ internal class DefaultAuthProvider : IAuthProvider
+ {
+ public DefaultAuthProvider(
+ string productId,
+ IMuidProvider muidProvider,
+ IGlobalStore globalStore
+ )
+ {
+ this.productId = productId;
+ this.muidProvider = muidProvider;
+ this.globalStore = globalStore;
+ }
+
+ public bool IsTrial(string token)
+ {
+ JwtSecurityToken securityToken = this.GetSecurityToken(token);
+ bool flag = !securityToken.Payload.ContainsKey("META_LICENSE_TYPE");
+ bool flag2;
+ if (flag)
+ {
+ flag2 = false;
+ }
+ else
+ {
+ string text = securityToken.Payload["META_LICENSE_TYPE"].ToString();
+ flag2 = text == "TRIAL";
+ }
+ return flag2;
+ }
+
+ public int LicenseTypeInt(string token)
+ {
+ int num = 1;
+ JwtSecurityToken securityToken = this.GetSecurityToken(token);
+ bool flag = securityToken.Payload.ContainsKey("META_LICENSE_TYPE");
+ if (flag)
+ {
+ string text = securityToken.Payload["META_LICENSE_TYPE"].ToString();
+ bool flag2 = text == "TRIAL";
+ if (flag2)
+ {
+ num = 0;
+ }
+ else
+ {
+ bool flag3 = text == "PERSONAL";
+ if (flag3)
+ {
+ num = 1;
+ }
+ else
+ {
+ bool flag4 = text == "REVIEW";
+ if (flag4)
+ {
+ num = 2;
+ }
+ else
+ {
+ bool flag5 = text == "ENTERPRISE";
+ if (flag5)
+ {
+ num = 3;
+ }
+ else
+ {
+ bool flag6 = text == "ROYALTY_FREE";
+ if (flag6)
+ {
+ num = 4;
+ }
+ }
+ }
+ }
+ }
+ }
+ return num;
+ }
+
+ public bool TryUpdateToken(string key)
+ {
+ bool flag2;
+ try
+ {
+ string muid = this.muidProvider.GetMuid();
+ string text = string.Concat(
+ new string[]
+ {
+ "https://consumer.licensing.kg-dev.be/api/LicenseToken?key=",
+ key,
+ "&client=",
+ muid,
+ "&productreference=",
+ this.productId
+ }
+ );
+ HttpClient httpClient = new HttpClient();
+ HttpResponseMessage result = httpClient.GetAsync(text).Result;
+ string result2 = result.Content.ReadAsStringAsync().Result;
+ JObject jobject = null;
+ try
+ {
+ jobject = JObject.Parse(result2);
+ }
+ catch
+ {
+ throw new Exception("Failed to parse: " + result2);
+ }
+ JToken jtoken = null;
+ jobject.TryGetValue("token", out jtoken);
+ bool flag = jtoken == null;
+ if (flag)
+ {
+ throw new Exception("Response does not contain a token.");
+ }
+ string text2 = jtoken.Value();
+ this.globalStore.SetToken(text2);
+ flag2 = true;
+ }
+ catch (Exception ex)
+ {
+ string token = this.globalStore.GetToken();
+ bool flag3 = this.ValidateToken(token);
+ bool flag4 = !flag3;
+ if (flag4)
+ {
+ this.globalStore.SetToken(
+ (ex.InnerException != null) ? ex.InnerException.Message : ex.Message
+ );
+ }
+ flag2 = false;
+ }
+ return flag2;
+ }
+
+ public bool ValidateToken(string token)
+ {
+ bool flag3;
+ try
+ {
+ JwtSecurityToken securityToken = this.GetSecurityToken(token);
+ bool flag = !securityToken.Payload.ContainsKey("certserialnumber");
+ if (flag)
+ {
+ throw new Exception("No certserialnumber given.");
+ }
+ string text = securityToken.Payload["certserialnumber"].ToString();
+ string muid = this.muidProvider.GetMuid();
+ bool flag2 =
+ string.IsNullOrWhiteSpace(muid)
+ || string.IsNullOrWhiteSpace(text)
+ || muid != text;
+ if (flag2)
+ {
+ throw new Exception("Not Licensed.");
+ }
+ flag3 = true;
+ }
+ catch (Exception ex)
+ {
+ flag3 = false;
+ }
+ return flag3;
+ }
+
+ private JwtSecurityToken GetSecurityToken(string token)
+ {
+ RSAParameters rsaparameters = new RSAParameters
+ {
+ Modulus = new byte[]
+ {
+ 158,
+ 172,
+ 231,
+ 226,
+ 231,
+ 91,
+ 212,
+ 107,
+ 240,
+ 26,
+ 173,
+ 150,
+ 233,
+ 20,
+ 187,
+ 54,
+ 239,
+ 143,
+ 195,
+ 143,
+ 77,
+ 126,
+ 138,
+ 22,
+ 181,
+ 236,
+ 24,
+ 20,
+ 3,
+ 224,
+ 189,
+ 11,
+ 236,
+ 47,
+ 58,
+ 114,
+ 141,
+ 189,
+ 239,
+ 40,
+ 208,
+ 181,
+ 43,
+ 209,
+ 40,
+ 144,
+ 218,
+ 84,
+ 117,
+ 207,
+ 2,
+ 190,
+ 103,
+ 137,
+ 213,
+ 129,
+ 224,
+ 241,
+ 173,
+ 144,
+ 242,
+ 6,
+ 86,
+ 156,
+ 183,
+ 160,
+ 59,
+ 192,
+ 96,
+ 122,
+ 33,
+ 215,
+ 20,
+ 8,
+ 55,
+ 189,
+ 92,
+ 8,
+ 165,
+ 48,
+ 126,
+ 0,
+ 64,
+ 161,
+ 240,
+ 3,
+ 79,
+ 196,
+ 238,
+ 226,
+ 193,
+ 246,
+ 133,
+ 181,
+ 43,
+ 214,
+ 147,
+ 31,
+ 132,
+ 157,
+ 19,
+ 22,
+ 43,
+ 246,
+ 5,
+ 40,
+ 172,
+ 79,
+ 98,
+ 121,
+ 66,
+ 46,
+ 99,
+ 251,
+ 194,
+ 237,
+ 108,
+ 235,
+ 179,
+ 75,
+ 225,
+ 166,
+ 206,
+ 215,
+ 115,
+ 17,
+ 145,
+ 188,
+ 36,
+ 129,
+ 49,
+ 216,
+ 240,
+ 177,
+ 91,
+ 216,
+ 59,
+ 200,
+ 166,
+ 108,
+ 195,
+ 105,
+ 248,
+ 137,
+ 61,
+ 159,
+ 167,
+ 40,
+ 18,
+ 154,
+ 190,
+ 40,
+ 136,
+ 32,
+ 59,
+ 239,
+ 40,
+ 239,
+ 130,
+ 32,
+ 223,
+ 81,
+ 167,
+ 30,
+ 201,
+ 151,
+ 86,
+ 95,
+ 128,
+ 35,
+ 1,
+ 215,
+ 128,
+ 178,
+ 21,
+ 169,
+ 28,
+ 71,
+ 154,
+ 139,
+ 91,
+ 52,
+ 27,
+ 87,
+ 31,
+ 58,
+ 21,
+ 169,
+ 159,
+ 156,
+ 189,
+ 84,
+ 79,
+ 185,
+ 120,
+ 109,
+ 24,
+ 83,
+ 220,
+ 122,
+ 68,
+ 213,
+ 220,
+ 50,
+ 56,
+ 188,
+ 176,
+ 52,
+ 140,
+ 54,
+ 64,
+ 161,
+ 31,
+ 55,
+ 246,
+ 32,
+ 246,
+ 141,
+ 186,
+ 183,
+ 107,
+ 102,
+ 235,
+ 139,
+ 147,
+ 81,
+ 15,
+ 231,
+ 44,
+ 193,
+ 7,
+ 117,
+ 251,
+ byte.MaxValue,
+ 53,
+ 98,
+ 187,
+ 41,
+ 213,
+ 157,
+ 92,
+ byte.MaxValue,
+ 222,
+ 71,
+ 7,
+ 69,
+ 85,
+ 225,
+ 237,
+ 117,
+ 142,
+ 164,
+ 48,
+ 96,
+ 220,
+ 191
+ },
+ Exponent = new byte[] { 1, 0, 1 }
+ };
+ RSACryptoServiceProvider rsacryptoServiceProvider = new RSACryptoServiceProvider(2048);
+ rsacryptoServiceProvider.ImportParameters(rsaparameters);
+ RsaSecurityKey rsaSecurityKey = new RsaSecurityKey(rsacryptoServiceProvider);
+ TokenValidationParameters tokenValidationParameters = new TokenValidationParameters
+ {
+ IssuerSigningKey = rsaSecurityKey,
+ RequireSignedTokens = true,
+ RequireExpirationTime = true,
+ ValidateLifetime = true,
+ ValidateAudience = true,
+ ValidAudiences = new string[] { this.productId },
+ ValidateIssuer = false
+ };
+ JwtSecurityTokenHandler jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
+ SecurityToken securityToken;
+ jwtSecurityTokenHandler.ValidateToken(
+ token,
+ tokenValidationParameters,
+ out securityToken
+ );
+ return (JwtSecurityToken)securityToken;
+ }
+
+ private const string LICENSE_TYPE_CLAIM_NAME = "META_LICENSE_TYPE";
+
+ private const string TRIAL = "TRIAL";
+
+ private const string PERSONAL = "PERSONAL";
+
+ private const string REVIEW = "REVIEW";
+
+ private const string ENTERPRISE = "ENTERPRISE";
+
+ private const string ROYALTY_FREE = "ROYALTY_FREE";
+
+ private readonly string productId;
+
+ private readonly IMuidProvider muidProvider;
+
+ private readonly IGlobalStore globalStore;
+ }
+}
diff --git a/KGdev.BI3D.Revit/Implementations/DefaultBI3DViewsProvider.cs b/KGdev.BI3D.Revit/Implementations/DefaultBI3DViewsProvider.cs
new file mode 100644
index 0000000..6262ce8
--- /dev/null
+++ b/KGdev.BI3D.Revit/Implementations/DefaultBI3DViewsProvider.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Autodesk.Revit.DB;
+using KGdev.BI3D.Revit.Common;
+
+namespace KGdev.BI3D.Revit.Implementations
+{
+ internal class DefaultBI3DViewsProvider : IBI3DViewsProvider
+ {
+ public View3D GetContextView3D(Document document)
+ {
+ Element element2 = (
+ from element in new FilteredElementCollector(document)
+ .WhereElementIsNotElementType()
+ .OfCategory(BuiltInCategory.OST_Views)
+ .OfClass(typeof(View3D))
+ where element.Name == "3DBI-Context"
+ select element
+ ).FirstOrDefault();
+ return element2 as View3D;
+ }
+
+ public List GetScenes(Document document)
+ {
+ return new FilteredElementCollector(document)
+ .OfCategory(BuiltInCategory.OST_Views)
+ .WhereElementIsNotElementType()
+ .OfClass(typeof(View3D))
+ .Cast()
+ .Where(
+ delegate(View3D v)
+ {
+ bool flag;
+ try
+ {
+ flag = v.IsPerspective && v.Name.StartsWith("3DBI_");
+ }
+ catch
+ {
+ flag = false;
+ }
+ return flag;
+ }
+ )
+ .ToList();
+ }
+
+ public string GetSceneName(View3D view)
+ {
+ return view.Name.StartsWith("3DBI_") ? view.Name.Substring("3DBI_".Length) : view.Name;
+ }
+
+ private const string CONTEXT_VIEW_NAME = "3DBI-Context";
+
+ private const string VIEW_IS_SCENE_PREFIX = "3DBI_";
+ }
+}
diff --git a/KGdev.BI3D.Revit/Implementations/DefaultConstantsProvider.cs b/KGdev.BI3D.Revit/Implementations/DefaultConstantsProvider.cs
new file mode 100644
index 0000000..39b474d
--- /dev/null
+++ b/KGdev.BI3D.Revit/Implementations/DefaultConstantsProvider.cs
@@ -0,0 +1,16 @@
+using System;
+using KGdev.BI3D.Revit.Common;
+
+namespace KGdev.BI3D.Revit.Implementations
+{
+ public class DefaultConstantsProvider : IConstantsProvider
+ {
+ public string ProductId { get; } = "3DBI_REVIT";
+
+ public string PurchaseUrl { get; } = "https://kg-dev.be/project/3dbi-for-revit";
+
+ public string ViewerAndExamplesFolderName { get; } = "3dbi_viewer_and_examples";
+
+ public string TrialKey { get; } = "3DBI-REVIT-TRIAL-14DAYS";
+ }
+}
diff --git a/KGdev.BI3D.Revit/Implementations/DefaultElementIdProvider.cs b/KGdev.BI3D.Revit/Implementations/DefaultElementIdProvider.cs
new file mode 100644
index 0000000..18e7e8c
--- /dev/null
+++ b/KGdev.BI3D.Revit/Implementations/DefaultElementIdProvider.cs
@@ -0,0 +1,17 @@
+using System;
+using Autodesk.Revit.DB;
+using KGdev.BI3D.Revit.Common;
+using KGdev.BI3D.Revit.Common.Models;
+
+namespace KGdev.BI3D.Revit.Implementations
+{
+ internal class DefaultElementIdProvider : IElementIdProvider
+ {
+ public string GetElementId(LinkedElementIdPath elementIdPath)
+ {
+ return string.Join("-", elementIdPath.ElementIds);
+ }
+
+ private const string SEPARATOR = "-";
+ }
+}
diff --git a/KGdev.BI3D.Revit/Implementations/DefaultGlobalStore.cs b/KGdev.BI3D.Revit/Implementations/DefaultGlobalStore.cs
new file mode 100644
index 0000000..1903347
--- /dev/null
+++ b/KGdev.BI3D.Revit/Implementations/DefaultGlobalStore.cs
@@ -0,0 +1,104 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using KGdev.BI3D.Revit.Common;
+using Newtonsoft.Json;
+
+namespace KGdev.BI3D.Revit.Implementations
+{
+ internal class DefaultGlobalStore : IGlobalStore
+ {
+ public string GetKey()
+ {
+ return this.Read("key");
+ }
+
+ public string GetToken()
+ {
+ return this.Read("token");
+ }
+
+ public void SetKey(string key)
+ {
+ this.Write("key", key);
+ }
+
+ public void SetToken(string token)
+ {
+ this.Write("token", token);
+ }
+
+ public string GetAppTempDirectoryPath()
+ {
+ return this.BuildFolderPath();
+ }
+
+ public Dictionary GetDefaultExporterChosenOptionValues()
+ {
+ Dictionary dictionary = new Dictionary();
+ string text = this.Read("defaultOptionValues");
+ try
+ {
+ dictionary = JsonConvert.DeserializeObject>(text);
+ }
+ catch { }
+ return dictionary;
+ }
+
+ public void SetDefaultExporterChosenOptionValues(
+ Dictionary valuesDictionary
+ )
+ {
+ string text = JsonConvert.SerializeObject(valuesDictionary);
+ this.Write("defaultOptionValues", text);
+ }
+
+ private string Read(string key)
+ {
+ string text = this.BuildPath(key);
+ bool flag = !File.Exists(text);
+ string text2;
+ if (flag)
+ {
+ text2 = null;
+ }
+ else
+ {
+ text2 = File.ReadAllText(text);
+ }
+ return text2;
+ }
+
+ private void Write(string key, string value)
+ {
+ string text = this.BuildPath(key);
+ File.WriteAllText(text, value);
+ }
+
+ private string BuildFolderPath()
+ {
+ string folderPath = Environment.GetFolderPath(
+ Environment.SpecialFolder.LocalApplicationData
+ );
+ string text = Path.Combine(folderPath, ".3dbi-for-revit");
+ Directory.CreateDirectory(text);
+ return text;
+ }
+
+ private string BuildPath(string key)
+ {
+ string text = this.BuildFolderPath();
+ return Path.Combine(text, key + ".setting");
+ }
+
+ private const string DIRECTORY_NAME = ".3dbi-for-revit";
+
+ private const string SETTINGS_FILE_EXTENSION = ".setting";
+
+ private const string KEY_KEY = "key";
+
+ private const string KEY_TOKEN = "token";
+
+ private const string KEY_DEFAULT_OPTION_VALUES = "defaultOptionValues";
+ }
+}
diff --git a/KGdev.BI3D.Revit/Implementations/DefaultLinkedDocumentUtilities.cs b/KGdev.BI3D.Revit/Implementations/DefaultLinkedDocumentUtilities.cs
new file mode 100644
index 0000000..f896720
--- /dev/null
+++ b/KGdev.BI3D.Revit/Implementations/DefaultLinkedDocumentUtilities.cs
@@ -0,0 +1,86 @@
+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.Implementations
+{
+ internal class DefaultLinkedDocumentUtilities : ILinkedDocumentsUtilities
+ {
+ public Element GetElement(Document rootDocument, LinkedElementIdPath path)
+ {
+ Document document = rootDocument;
+ Queue queue = new Queue(path.ElementIds);
+ Element element = null;
+ while (queue.Count > 0)
+ {
+ ElementId elementId = queue.Dequeue();
+ bool flag = queue.Count == 0;
+ if (flag)
+ {
+ element = document.GetElement(elementId);
+ }
+ else
+ {
+ RevitLinkInstance revitLinkInstance =
+ document.GetElement(elementId) as RevitLinkInstance;
+ document = revitLinkInstance.GetLinkDocument();
+ }
+ }
+ return element;
+ }
+
+ public IList GetLinkedDocuments(
+ Document rootDocument,
+ Transform baseTransform,
+ bool includeThis,
+ List passedLinkInstanceIds
+ )
+ {
+ List list = new List();
+ if (includeThis)
+ {
+ list.Add(
+ new LinkedDocumentInformation
+ {
+ Document = rootDocument,
+ TransformToRoot = baseTransform,
+ PassedLinkInstanceIds = passedLinkInstanceIds
+ }
+ );
+ }
+ IEnumerable enumerable = new FilteredElementCollector(rootDocument)
+ .OfCategory(BuiltInCategory.OST_RvtLinks)
+ .OfClass(typeof(RevitLinkInstance))
+ .Cast();
+ foreach (RevitLinkInstance revitLinkInstance in enumerable)
+ {
+ bool flag = !revitLinkInstance.IsValidObject;
+ if (!flag)
+ {
+ Document linkDocument = revitLinkInstance.GetLinkDocument();
+ bool flag2 = linkDocument == null || !linkDocument.IsValidObject;
+ if (!flag2)
+ {
+ Transform transform = baseTransform.Multiply(
+ revitLinkInstance.GetTransform()
+ );
+ List list2 = new List();
+ list2.AddRange(passedLinkInstanceIds);
+ list2.Add(revitLinkInstance.Id);
+ IList linkedDocuments = this.GetLinkedDocuments(
+ linkDocument,
+ transform,
+ true,
+ list2
+ );
+ list.AddRange(linkedDocuments);
+ }
+ }
+ }
+ return list;
+ }
+ }
+}
diff --git a/KGdev.BI3D.Revit/Implementations/DefaultMuidProvider.cs b/KGdev.BI3D.Revit/Implementations/DefaultMuidProvider.cs
new file mode 100644
index 0000000..9d88fef
--- /dev/null
+++ b/KGdev.BI3D.Revit/Implementations/DefaultMuidProvider.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using KGdev.BI3D.Revit.Common;
+
+namespace KGdev.BI3D.Revit.Implementations
+{
+ internal class DefaultMuidProvider : IMuidProvider
+ {
+ public string GetMuid()
+ {
+ string text = "wmic";
+ bool flag = File.Exists("C:\\Windows\\System32\\wbem\\WMIC.exe");
+ if (flag)
+ {
+ text = "C:\\Windows\\System32\\wbem\\WMIC.exe";
+ }
+ else
+ {
+ bool flag2 = File.Exists("C:\\Windows\\System32\\WMIC.exe");
+ if (flag2)
+ {
+ text = "C:\\Windows\\System32\\WMIC.exe";
+ }
+ }
+ Process process = new Process
+ {
+ StartInfo = new ProcessStartInfo
+ {
+ FileName = text,
+ Arguments = "path win32_computersystemproduct get uuid /Value",
+ UseShellExecute = false,
+ RedirectStandardOutput = true,
+ CreateNoWindow = true
+ }
+ };
+ process.Start();
+ string text2 = process.StandardOutput.ReadToEnd();
+ process.WaitForExit();
+ return text2.Trim().Split(new char[] { '=' }).Last();
+ }
+ }
+}
diff --git a/KGdev.BI3D.Revit/KGdev.BI3D.Revit.csproj b/KGdev.BI3D.Revit/KGdev.BI3D.Revit.csproj
new file mode 100644
index 0000000..3d46372
--- /dev/null
+++ b/KGdev.BI3D.Revit/KGdev.BI3D.Revit.csproj
@@ -0,0 +1,56 @@
+
+
+
+ {2D6C4C2D-1F14-49C3-BEBF-B997CD03047F}
+ Library
+ KGdev.BI3D.Revit
+ KGdev.BI3D.Revit
+ False
+ 512
+ net472
+ x64
+
+
+ False
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ C:\ProgramData\Autodesk\Revit\Addins\2020\3DBI for Revit\Microsoft.Extensions.DependencyInjection.dll
+
+
+ C:\ProgramData\Autodesk\Revit\Addins\2020\3DBI for Revit\Microsoft.Extensions.DependencyInjection.Abstractions.dll
+
+
+ C:\ProgramData\Autodesk\Revit\Addins\2020\3DBI for Revit\Microsoft.IdentityModel.Tokens.dll
+
+
+ C:\ProgramData\Autodesk\Revit\Addins\2020\3DBI for Revit\Newtonsoft.Json.dll
+
+
+ C:\Program Files\Autodesk\Revit 2018\RevitAPI.dll
+ False
+
+
+
+ C:\ProgramData\Autodesk\Revit\Addins\2020\3DBI for Revit\System.IdentityModel.Tokens.Jwt.dll
+
+
+
+
\ No newline at end of file
diff --git a/KGdev.BI3D.Revit/Properties/AssemblyInfo.cs b/KGdev.BI3D.Revit/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..62525d3
--- /dev/null
+++ b/KGdev.BI3D.Revit/Properties/AssemblyInfo.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Diagnostics;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.Versioning;
+
+[assembly: AssemblyVersion("1.3.0.0")]
+[assembly: AssemblyCompany("KGdev.BI3D.Revit")]
+[assembly: AssemblyConfiguration("Release 2020")]
+[assembly: AssemblyFileVersion("1.3.0")]
+[assembly: AssemblyInformationalVersion("1.3.0")]
+[assembly: AssemblyProduct("KGdev.BI3D.Revit")]
+[assembly: AssemblyTitle("KGdev.BI3D.Revit")]
diff --git a/Resources/3dbi.ico b/Resources/3dbi.ico
new file mode 100644
index 0000000..1d0e1f0
Binary files /dev/null and b/Resources/3dbi.ico differ