mengxiangge 5 лет назад
Родитель
Сommit
94a210b72e
52 измененных файлов с 2949 добавлено и 39 удалено
  1. 11 3
      .gitignore
  2. BIN
      JBIM/Dlls/RevitAddInUtility.dll
  3. BIN
      JBIM/Dlls/RevitNET.dll
  4. BIN
      JBIM/Dlls/SAGA.DotNetUtils.dll
  5. 14 0
      JBIM/ExportStart/App.config
  6. 180 0
      JBIM/ExportStart/DocumentExtension.cs
  7. 90 0
      JBIM/ExportStart/ExportStart.csproj
  8. 76 0
      JBIM/ExportStart/Program.cs
  9. 36 0
      JBIM/ExportStart/Properties/AssemblyInfo.cs
  10. 4 0
      JBIM/ExportStart/ReadMe.txt
  11. 111 0
      JBIM/ExportStart/RevitCoreContext.cs
  12. 60 0
      JBIM/ExportStart/RevitVisionUtil.cs
  13. 13 1
      JBIM/JBIM.sln
  14. BIN
      JBIM/MBIResource/DataCheck/垃圾数据检查结果输出-模版.xlsx
  15. BIN
      JBIM/MBIResource/DataCheck/模型检查结果输出格式-模版.xlsx
  16. 35 35
      JBIM/RevitToJBim/TestExport.cs
  17. 83 0
      JBIM/ServiceDataCheck/CheckFactory.cs
  18. 31 0
      JBIM/ServiceDataCheck/Common/MBIConst.cs
  19. 36 0
      JBIM/ServiceDataCheck/Common/RegexConstPattern.cs
  20. 59 0
      JBIM/ServiceDataCheck/DataCheck.Mode/CheckBase.cs
  21. 52 0
      JBIM/ServiceDataCheck/DataCheck.Mode/ColumnCheck.cs
  22. 24 0
      JBIM/ServiceDataCheck/DataCheck.Mode/ColumnCheckResult.cs
  23. 161 0
      JBIM/ServiceDataCheck/DataCheck.Mode/ConnectorCheck.cs
  24. 23 0
      JBIM/ServiceDataCheck/DataCheck.Mode/ConnectorCheckResult.cs
  25. 258 0
      JBIM/ServiceDataCheck/DataCheck.Mode/ElementRangeCheck.cs
  26. 35 0
      JBIM/ServiceDataCheck/DataCheck.Mode/ElementRangeCheckResult.cs
  27. 69 0
      JBIM/ServiceDataCheck/DataCheck.Mode/EquipInSpaceCheck.cs
  28. 31 0
      JBIM/ServiceDataCheck/DataCheck.Mode/EquipInSpaceCheckResult.cs
  29. 55 0
      JBIM/ServiceDataCheck/DataCheck.Mode/EquipPartLocationCheck.cs
  30. 27 0
      JBIM/ServiceDataCheck/DataCheck.Mode/EquipPartLocationCheckResult.cs
  31. 78 0
      JBIM/ServiceDataCheck/DataCheck.Mode/FamilyNameCheck.cs
  32. 19 0
      JBIM/ServiceDataCheck/DataCheck.Mode/FamilyNameCheckResult.cs
  33. 78 0
      JBIM/ServiceDataCheck/DataCheck.Mode/ParameterIntegrityCheck.cs
  34. 20 0
      JBIM/ServiceDataCheck/DataCheck.Mode/ParameterIntegrityCheckResult.cs
  35. 35 0
      JBIM/ServiceDataCheck/DataCheck.Mode/ResultBase.cs
  36. 17 0
      JBIM/ServiceDataCheck/DataCheck.Mode/ResultState.cs
  37. 90 0
      JBIM/ServiceDataCheck/DataCheck.Mode/SagaCheck.cs
  38. 19 0
      JBIM/ServiceDataCheck/DataCheck.Mode/SagaCheckResult.cs
  39. 92 0
      JBIM/ServiceDataCheck/DataCheck.Mode/SystemNameCheck.cs
  40. 24 0
      JBIM/ServiceDataCheck/DataCheck.Mode/SystemNameCheckResult.cs
  41. 125 0
      JBIM/ServiceDataCheck/DataCheck.Mode/SystemReferEquipCheck.cs
  42. 37 0
      JBIM/ServiceDataCheck/DataCheck.Mode/SystemReferEquipCheckResult.cs
  43. 45 0
      JBIM/ServiceDataCheck/DataCheck.Mode/UnitCheck.cs
  44. 19 0
      JBIM/ServiceDataCheck/DataCheck.Mode/UnitCheckResult.cs
  45. 33 0
      JBIM/ServiceDataCheck/DocumentUtils.cs
  46. 38 0
      JBIM/ServiceDataCheck/Extend/DocExtend.cs
  47. 239 0
      JBIM/ServiceDataCheck/Extend/ElementExtend.cs
  48. 36 0
      JBIM/ServiceDataCheck/Properties/AssemblyInfo.cs
  49. 117 0
      JBIM/ServiceDataCheck/ServiceDataCheck.csproj
  50. 42 0
      JBIM/ServiceDataCheck/TestCommand.cs
  51. 166 0
      JBIM/ServiceDataCheck/Utils/DataCheckRule.cs
  52. 6 0
      JBIM/ServiceDataCheck/packages.config

+ 11 - 3
.gitignore

@@ -3,9 +3,17 @@
 ################################################################################
 
 /JBIM/.vs/JBIM/v15
-/JBIM/RevitExport/obj/Debug
-/JBIM/JBIM/obj/Debug
-/JBIM/RevitToJBim/obj/Debug
+/JBIM/RevitExport/obj/
+/JBIM/RevitToJBim/obj/
 /JBIM/JBIM/bin/Debug
 /JBIM/RevitToJBim/bin/Debug
 /JBIM/RevitExport/bin
+/JBIM/ExportStart/bin
+/JBIM/ExportStart/obj
+/JBIM/JBIM/bin/
+/JBIM/JBIM/obj/
+/JBIM/OutputDll
+/JBIM/packages
+/JBIM/RevitExport/obj/
+/JBIM/ServiceDataCheck/obj
+/JBIM/RevitToJBim/bin/x64/Debug

BIN
JBIM/Dlls/RevitAddInUtility.dll


BIN
JBIM/Dlls/RevitNET.dll


BIN
JBIM/Dlls/SAGA.DotNetUtils.dll


+ 14 - 0
JBIM/ExportStart/App.config

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+    <startup> 
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
+    </startup>
+  <runtime>
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <dependentAssembly>
+        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-11.0.0.0" newVersion="11.0.0.0" />
+      </dependentAssembly>
+    </assemblyBinding>
+  </runtime>
+</configuration>

+ 180 - 0
JBIM/ExportStart/DocumentExtension.cs

@@ -0,0 +1,180 @@
+/* ==============================================================================
+ * 功能描述:DocumentExtension  
+ * 创 建 者:Garrett
+ * 创建日期:2019/6/27 11:11:17
+ * ==============================================================================*/
+using Autodesk.Revit.DB;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ExportStart
+{
+    public static class DocumentExtension
+    {
+        public static void Invoke(this Document doc, Action<Transaction> action, string name = "default")
+        {
+            using (var tr = new Transaction(doc, name))
+            {
+                tr.Start();
+
+                action(tr);
+
+                var status = tr.GetStatus();
+
+                switch (status)
+                {
+                    case TransactionStatus.Started:
+                        tr.Commit();
+                        return;
+                    case TransactionStatus.Committed:
+                    case TransactionStatus.RolledBack:
+                        return;
+                    case TransactionStatus.Error:
+                        tr.RollBack();
+                        return;
+                    default:
+                        return;
+                }
+            }
+        }
+
+        public static TResult Invoke<TResult>(this Document doc, Func<Transaction, TResult> func, string name = "default")
+        {
+            using (var tr = new Transaction(doc, name))
+            {
+                tr.Start();
+
+                var result = func(tr);
+
+                var status = tr.GetStatus();
+                switch (status)
+                {
+                    case TransactionStatus.Started:
+                        tr.Commit();
+                        return result;
+                    case TransactionStatus.Committed:
+                    case TransactionStatus.RolledBack:
+                        return result;
+                    case TransactionStatus.Error:
+                        tr.RollBack();
+                        return result;
+                    default:
+                        return result;
+                }
+            }
+        }
+
+        public static void InvokeSub(this Document doc, Action<SubTransaction> action)
+        {
+            using (var tr = new SubTransaction(doc))
+            {
+                tr.Start();
+
+                action(tr);
+
+                var status = tr.GetStatus();
+                switch (status)
+                {
+                    case TransactionStatus.Started:
+                        tr.Commit();
+                        return;
+                    case TransactionStatus.Committed:
+                    case TransactionStatus.RolledBack:
+                        break;
+                    case TransactionStatus.Error:
+                        tr.RollBack();
+                        return;
+                    default:
+                        return;
+                }
+            }
+        }
+
+
+        public static TResult InvokeSub<TResult>(this Document doc, Func<SubTransaction, TResult> func)
+        {
+            using (var tr = new SubTransaction(doc))
+            {
+                tr.Start();
+
+                var result = func(tr);
+
+                var status = tr.GetStatus();
+                switch (status)
+                {
+                    case TransactionStatus.Started:
+                        tr.Commit();
+                        return result;
+                    case TransactionStatus.Committed:
+                    case TransactionStatus.RolledBack:
+                        return result;
+                    case TransactionStatus.Error:
+                        tr.RollBack();
+                        return result;
+                    default:
+                        return result;
+                }
+            }
+        }
+
+        public static void InvokeGroup(this Document doc, Action<TransactionGroup> action, string name = "default")
+        {
+            using (var tr = new TransactionGroup(doc, name))
+            {
+                tr.Start();
+
+                action(tr);
+
+                var status = tr.GetStatus();
+                switch (status)
+                {
+                    case TransactionStatus.Started:
+                        tr.Commit();
+                        return;
+                    case TransactionStatus.Committed:
+                    case TransactionStatus.RolledBack:
+                        break;
+                    case TransactionStatus.Error:
+                        tr.RollBack();
+                        return;
+                    default:
+                        return;
+                }
+            }
+        }
+
+        public static TResult InvokeGroup<TResult>(this Document doc, Func<TransactionGroup, TResult> func, string name = "default")
+        {
+            using (var tr = new TransactionGroup(doc, name))
+            {
+                tr.Start();
+
+                var result = func(tr);
+
+                var status = tr.GetStatus();
+                switch (status)
+                {
+                    case TransactionStatus.Started:
+                        tr.Commit();
+                        return result;
+                    case TransactionStatus.Committed:
+                    case TransactionStatus.RolledBack:
+                        return result;
+                    case TransactionStatus.Error:
+                        tr.RollBack();
+                        return result;
+                    default:
+                        return result;
+                }
+            }
+        }
+
+        public static FilteredElementCollector QueryByType<T>(this Document doc) where T : Element
+        {
+            return new FilteredElementCollector(doc).OfClass(typeof(T));
+        }
+    }
+}

+ 90 - 0
JBIM/ExportStart/ExportStart.csproj

@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{003C65AE-6802-4142-97FE-611C23E3676D}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>ExportStart</RootNamespace>
+    <AssemblyName>ExportStart</AssemblyName>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+    <TargetFrameworkProfile />
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>x64</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\OutputDll\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\OutputDll\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+    <PlatformTarget>x64</PlatformTarget>
+    <OutputPath>bin\x64\Debug\</OutputPath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+    <PlatformTarget>x64</PlatformTarget>
+    <OutputPath>bin\x64\Release\</OutputPath>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="RevitAddInUtility">
+      <HintPath>..\Dlls\RevitAddInUtility.dll</HintPath>
+    </Reference>
+    <Reference Include="RevitAPI">
+      <HintPath>..\Dlls\RevitAPI.dll</HintPath>
+    </Reference>
+    <Reference Include="RevitNET">
+      <HintPath>..\Dlls\RevitNET.dll</HintPath>
+    </Reference>
+    <Reference Include="SAGA.DotNetUtils, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\RevitExport\bin\x64\Debug\SAGA.DotNetUtils.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="DocumentExtension.cs" />
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="RevitCoreContext.cs" />
+    <Compile Include="RevitVisionUtil.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\RevitToJBim\RevitToJBim.csproj">
+      <Project>{f83397d2-c35a-4f5c-8daf-e9de1e2d2ad5}</Project>
+      <Name>RevitToJBim</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\ServiceDataCheck\ServiceDataCheck.csproj">
+      <Project>{7b748b09-dc20-4406-85a3-101e7833f8ce}</Project>
+      <Name>ServiceDataCheck</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="ReadMe.txt" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>

+ 76 - 0
JBIM/ExportStart/Program.cs

@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using Autodesk.Revit.DB;
+using Autodesk.Revit.DB.Mechanical;
+using Autodesk.RevitAddIns;
+using ServiceRevitLib;
+
+//using RevitToJBim.Common;
+
+namespace ExportStart
+{
+    class Program
+    {
+        static Program()
+        {
+            RevitCoreContext.Instance.Run();
+        }
+        [STAThread]
+        static void Main(string[] args)
+        {
+            string path = @"C:\Users\SAGACLOUD\Desktop\数据检查\test.rvt";
+            //path = @"C:\Users\SAGACLOUD\Desktop\数据检查\testR18.rvt";
+            //path = @"C:\Users\SAGACLOUD\Desktop\数据检查\testR16.rvt";
+            //path = @"D:\测试模型\OLD\机电模型2015.09.06\F5机电(改位置)\revit\5风管.rvt";
+            string command = "Export";
+
+            var app = RevitCoreContext.Instance.Application;
+            var doc = app.OpenDocumentFile(path);
+            //Export(doc);
+            Check(doc);
+            //Console.WriteLine("RevitVision:"+RevitVisionUtil.GetRevitVision(path));
+            Console.ReadKey();
+        }
+
+        public static void Export(Document doc)
+        {
+            try
+            {
+                Console.WriteLine("Start Export");
+                RevitToJBim.TestExport.Document = doc;
+                RevitToJBim.TestExport.Export();
+
+                Console.WriteLine("End Export");
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine("导出失败");
+                Console.WriteLine(e.StackTrace);
+            }
+        }
+
+
+        public static void Check(Document doc)
+        {
+            try
+            {
+                Console.WriteLine("Start DataCheck");
+                ServiceDataCheckTest.Check(doc);
+
+                Console.WriteLine("End DataCheck");
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine("导出失败");
+                Console.WriteLine(e.StackTrace);
+            }
+        }
+
+
+    }
+}

+ 36 - 0
JBIM/ExportStart/Properties/AssemblyInfo.cs

@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("ExportStart")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ExportStart")]
+[assembly: AssemblyCopyright("Copyright ©  2019")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("003c65ae-6802-4142-97fe-611c23e3676d")]
+
+// 程序集的版本信息由下列四个值组成: 
+//
+//      主版本
+//      次版本
+//      生成号
+//      修订号
+//
+// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
+// 方法是按如下所示使用“*”: :
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 4 - 0
JBIM/ExportStart/ReadMe.txt

@@ -0,0 +1,4 @@
+RevitNet使用注意:
+Main方法加[STAThread]标记
+平台目标 当前项目改为:X64
+目标框架 注意与引用的项目一致

+ 111 - 0
JBIM/ExportStart/RevitCoreContext.cs

@@ -0,0 +1,111 @@
+/* ==============================================================================
+ * 功能描述:RevitCoreContext  
+ * 创 建 者:Garrett
+ * 创建日期:2019/6/27 11:10:20
+ * ==============================================================================*/
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net.Mime;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using Autodesk.Revit;
+using Autodesk.Revit.ApplicationServices;
+using Autodesk.Revit.DB;
+using Autodesk.RevitAddIns;
+
+namespace ExportStart
+{
+    public class RevitCoreContext
+    {
+        // 此路径为动态反射搜索路径 、 此路径可为任意路径(只要路径下有RevitNET 所需依赖项即可,完整依赖项可在 Naviswork 2016 下面找到)
+
+        static readonly string[] Searchs = RevitProductUtility.GetAllInstalledRevitProducts().Where(t => t.Name == "Revit 2017").Select(x => x.InstallLocation).ToArray();
+
+        static readonly object lockobj = new object();
+
+        static RevitCoreContext _instance;
+
+        private Product _product;
+
+        public Application Application { get => _product.Application; }
+
+        public static RevitCoreContext Instance
+        {
+            get
+            {
+                if (_instance == null)
+                {
+                    lock (lockobj)
+                    {
+                        if (_instance == null)
+                        {
+                            _instance = new RevitCoreContext();
+                        }
+                    }
+                }
+
+                return _instance;
+            }
+        }
+
+        static RevitCoreContext()
+        {
+            AddEnvironmentPaths(Searchs);
+
+            AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
+        }
+
+        public void Run()
+        {
+            _product = Product.GetInstalledProduct();
+
+            var clientId = new ClientApplicationId(Guid.NewGuid(), "DotNet", "BIMAPI");
+
+            // I am authorized by Autodesk to use this UI-less functionality. 必须是此字符串。 Autodesk 规定的.
+
+            _product.Init(clientId, "I am authorized by Autodesk to use this UI-less functionality.");
+        }
+
+        public void Stop()
+        {
+            _product?.Exit();
+        }
+
+        static void AddEnvironmentPaths(params string[] paths)
+        {
+            var path = new[] { Environment.GetEnvironmentVariable("PATH") ?? string.Empty };
+
+            var newPath = string.Join(System.IO.Path.PathSeparator.ToString(), path.Concat(paths));
+
+            Environment.SetEnvironmentVariable("PATH", newPath);
+        }
+
+        private static Assembly OnAssemblyResolve(object sender, ResolveEventArgs args)
+        {
+            var assemblyName = new AssemblyName(args.Name);
+
+            foreach (var item in Searchs)
+            {
+                var file = string.Format("{0}.dll", System.IO.Path.Combine(item, assemblyName.Name));
+
+                if (File.Exists(file))
+                {
+                    NeedAssemblys.Add(assemblyName.Name);
+                    return Assembly.LoadFile(file);
+                }
+            }
+
+            return args.RequestingAssembly;
+        }
+        public static List<string> NeedAssemblys = new List<string>();
+
+        public static void PrintAllAssemblys()
+        {
+            string str = string.Join("\r\n", NeedAssemblys);
+            Console.WriteLine(str);
+        }
+    }
+}

+ 60 - 0
JBIM/ExportStart/RevitVisionUtil.cs

@@ -0,0 +1,60 @@
+/* ==============================================================================
+ * 功能描述:RevitVisionUtil  
+ * 创 建 者:Garrett
+ * 创建日期:2019/6/28 9:25:34
+ * ==============================================================================*/
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+namespace ExportStart
+{
+    /// <summary>
+    /// RevitVisionUtil
+    /// </summary>
+    public class RevitVisionUtil
+    {
+        /// <summary>
+        /// 获取Revit文件的版本
+        /// </summary>
+        /// <param name="path">文件路径</param>
+        /// <returns></returns>
+        public static string GetRevitVision(string path)
+        {
+            string revitVision = null;
+            FileStream stream = new FileStream(path, FileMode.Open);
+
+            int size = 1024 * 1024;
+            byte[] bytes = new byte[size];
+
+            
+            while (stream.Read(bytes, 0, size) > 0)
+            {
+                string str = Encoding.Unicode.GetString(bytes);
+                //if (str.Contains("2014"))
+                //{
+                //    revitVision = "2014";
+
+                //    File.WriteAllText(@"D:\abc.txt", str);
+                //    System.Diagnostics.Process.Start("notepad.exe", path);
+                //    break;
+                //}
+
+                string pattern = @"Autodesk Revit \d{4}";
+                var match = Regex.Match(str, pattern);
+                if (match.Success)
+                {
+                    revitVision = match.Value.Substring(match.Length - 4, 4);
+
+                    //File.WriteAllText(@"D:\abc.txt", str);
+                    break;
+                }
+            }
+            return revitVision;
+        }
+    }
+}

+ 13 - 1
JBIM/JBIM.sln

@@ -1,7 +1,7 @@
 
 Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio 15
-VisualStudioVersion = 15.0.28010.2050
+VisualStudioVersion = 15.0.26730.3
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JBIM", "JBIM\JBIM.csproj", "{A6A90BFE-126D-4499-860A-F0E2C40EBB23}"
 EndProject
@@ -9,6 +9,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RevitExport", "RevitExport\
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RevitToJBim", "RevitToJBim\RevitToJBim.csproj", "{F83397D2-C35A-4F5C-8DAF-E9DE1E2D2AD5}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExportStart", "ExportStart\ExportStart.csproj", "{003C65AE-6802-4142-97FE-611C23E3676D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceDataCheck", "ServiceDataCheck\ServiceDataCheck.csproj", "{7B748B09-DC20-4406-85A3-101E7833F8CE}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -27,6 +31,14 @@ Global
 		{F83397D2-C35A-4F5C-8DAF-E9DE1E2D2AD5}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{F83397D2-C35A-4F5C-8DAF-E9DE1E2D2AD5}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{F83397D2-C35A-4F5C-8DAF-E9DE1E2D2AD5}.Release|Any CPU.Build.0 = Release|Any CPU
+		{003C65AE-6802-4142-97FE-611C23E3676D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{003C65AE-6802-4142-97FE-611C23E3676D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{003C65AE-6802-4142-97FE-611C23E3676D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{003C65AE-6802-4142-97FE-611C23E3676D}.Release|Any CPU.Build.0 = Release|Any CPU
+		{7B748B09-DC20-4406-85A3-101E7833F8CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{7B748B09-DC20-4406-85A3-101E7833F8CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{7B748B09-DC20-4406-85A3-101E7833F8CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{7B748B09-DC20-4406-85A3-101E7833F8CE}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

BIN
JBIM/MBIResource/DataCheck/垃圾数据检查结果输出-模版.xlsx


BIN
JBIM/MBIResource/DataCheck/模型检查结果输出格式-模版.xlsx


+ 35 - 35
JBIM/RevitToJBim/TestExport.cs

@@ -46,42 +46,42 @@ namespace RevitToJBim
             System.Diagnostics.Process.Start("notepad.exe", path);
         }
     }
-    /// <summary>
-    /// 测试提取数据
-    /// </summary>
-    [Transaction(TransactionMode.Manual)]
-    [Regeneration(RegenerationOption.Manual)]
-    public class PickDataCommand : IExternalCommand, IExternalCommandAvailability
-    {
+    ///// <summary>
+    ///// 测试提取数据
+    ///// </summary>
+    //[Transaction(TransactionMode.Manual)]
+    //[Regeneration(RegenerationOption.Manual)]
+    //public class PickDataCommand : IExternalCommand, IExternalCommandAvailability
+    //{
 
-        public  Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
-        {
-            try
-            {
-                TestExport.Document = commandData.Application.ActiveUIDocument.Document;
-                TestExport.Export();
-                TaskDialog dialog = new TaskDialog("导出");
-                dialog.MainInstruction ="导出成功";
-                dialog.Show();
-            }
-            catch (Exception e)
-            {
-                TaskDialog dialog = new TaskDialog("导出");
-                dialog.MainInstruction =e.Message+"\n\t"+ e.StackTrace.ToString();
-                dialog.Show();
-                return Result.Cancelled;
-            }
-            return Result.Succeeded;
-        }
+    //    public  Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
+    //    {
+    //        try
+    //        {
+    //            TestExport.Document = commandData.Application.ActiveUIDocument.Document;
+    //            TestExport.Export();
+    //            TaskDialog dialog = new TaskDialog("导出");
+    //            dialog.MainInstruction ="导出成功";
+    //            dialog.Show();
+    //        }
+    //        catch (Exception e)
+    //        {
+    //            TaskDialog dialog = new TaskDialog("导出");
+    //            dialog.MainInstruction =e.Message+"\n\t"+ e.StackTrace.ToString();
+    //            dialog.Show();
+    //            return Result.Cancelled;
+    //        }
+    //        return Result.Succeeded;
+    //    }
 
 
-        /// <summary>
-        /// Onlys show the dialog when a document is open, as Dockable dialogs are only available
-        /// when a document is open.
-        /// </summary>
-        public  bool IsCommandAvailable(UIApplication applicationData, CategorySet selectedCategories)
-        {
-            return false;
-        }
-    }
+    //    /// <summary>
+    //    /// Onlys show the dialog when a document is open, as Dockable dialogs are only available
+    //    /// when a document is open.
+    //    /// </summary>
+    //    public  bool IsCommandAvailable(UIApplication applicationData, CategorySet selectedCategories)
+    //    {
+    //        return false;
+    //    }
+    //}
 }

+ 83 - 0
JBIM/ServiceDataCheck/CheckFactory.cs

@@ -0,0 +1,83 @@
+/* ==============================================================================
+ * 功能描述:CheckFactory  
+ * 创 建 者:Garrett
+ * 创建日期:2019/6/11 16:26:56
+ * ==============================================================================*/
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using ServiceRevitLib.Mode;
+using Autodesk.Revit.DB;
+using ServiceRevitLib.Extend;
+
+namespace ServiceRevitLib
+{
+    /// <summary>
+    /// CheckFactory
+    /// </summary>
+    public class CheckFactory:ResultBase
+    {
+        public CheckFactory()
+        {
+            Content=new List<CheckBase>();
+        }
+
+      
+
+        #region 序列化的属性
+
+        public List<CheckBase> Content { get; set; }
+
+        public string FloorName { get; set; }
+
+        #endregion
+
+        #region Method
+        /// <summary>
+        /// 由传入字符串获取检查项
+        /// 传入的检查列表使用“,”进行分割
+        /// </summary>
+        /// <param name="checkItemStrs"></param>
+        public void SetCheckItems(string str)
+        {
+            var checkItemStrs= str.Split(',');
+            var nameSpace = typeof(CheckBase).Namespace;
+            foreach (string itemStr in checkItemStrs)
+            {
+                //子类与父类应该使用同一命名空间;如果为Program+BaseClass格式,会出错; 如果出现此情况,请更改方法
+                string fullPath = nameSpace + "." + itemStr;
+                Assembly tempAsembly = Assembly.GetExecutingAssembly();
+                var check = (tempAsembly.CreateInstance(fullPath)) as CheckBase;
+
+                Content.Add(check);
+            }
+        }
+
+        public void Check(Document doc)
+        {
+            FloorName = doc.PathName;
+            //Document doc = DocumentUtils.GetDocument(path);
+            try
+            {
+                Content.ForEach(t => t.SetDoc(doc));
+                Content.ForEach(t => t.Check());
+            }
+            catch (Exception e)
+            {
+                ResultMsg = e.Message;
+                Result = ResultState.Failure;
+            }
+            finally
+            {
+                //doc.CloseExt();
+            }
+        }
+
+        #endregion
+
+    }
+}

+ 31 - 0
JBIM/ServiceDataCheck/Common/MBIConst.cs

@@ -0,0 +1,31 @@
+/* ==============================================================================
+ * 功能描述:MBIConst  
+ * 创 建 者:Garrett
+ * 创建日期:2018/3/13 19:31:08
+ * ==============================================================================*/
+
+using System.IO;
+using SAGA.DotNetUtils;
+
+namespace ServiceRevitLib.Common
+{
+    /// <summary>
+    /// MBIConst
+    /// </summary>
+    public class MBIConst
+    {
+        public static readonly string MBITempSettingPath = Path.Combine(AppBaseInfo.AppTempFilePath, "MBI\\SettingsTemp");
+        
+        public static readonly string MBIResourcePath = Path.Combine(AppBaseInfo.AppRunPath, "MBIResource");
+        public static readonly string EmptyFilePath = Path.Combine(MBIResourcePath, "EmptyFile\\EmptyProject.rvt");
+
+        /// <summary>
+        /// 设备本地编码
+        /// </summary>
+        public readonly static string EquipLocalID = "设备本地编码";
+        /// <summary>
+        /// 设备本地名称
+        /// </summary>
+        public readonly static string EquipLocalName = "设备本地名称";
+    }
+}

+ 36 - 0
JBIM/ServiceDataCheck/Common/RegexConstPattern.cs

@@ -0,0 +1,36 @@
+/* ==============================================================================
+ * 功能描述:RegexPatten  
+ * 创 建 者:Garrett
+ * 创建日期:2019/5/29 14:12:17
+ * ==============================================================================*/
+
+namespace ServiceRevitLib.Common
+{
+    /// <summary>
+    /// RegexPatten
+    /// </summary>
+    class RegexConstPattern
+    {
+        public const string IsSpaceId = @"^Si\S*";
+        public const string IsEquipId = @"^Eq\S*";
+        public const string IsEquipPartId = @"^Ec\S*";
+        public const string IsBeaconId = @"^VOBc\S*";
+        
+
+        public const string IsEquip = @"^[A-Z]{4}\s*-\s*\S*";
+        public const string IsEquipPart = @"^[A-Z]{6}\s*-\s*\S*";
+        public const string IsBeacon = @"^Beacon$";
+
+        public const string IsMBILevel = @"^([BF][1-9]\d*M?\d?|RFM?\d?)$";
+        public const string IsMBIView = @"^([BF][1-9]\d*M?\d?|RFM?\d?)-saga$";
+        public const string IsSandwich = @"^([BF][1-9]\d*M\d?|RFM\d?)$";
+
+        public const string IsRF = @"^RF(-saga)?$";
+        public const string IsRFM = @"^RFM\d*$";
+        public const string IsOnground = @"^F\s*";
+        public const string IsUnderground = @"^B\s*";
+
+        public const string IsPhoneNumber = @"^1[3|4|5|7|8][0-9]\d{8}$";
+
+    }
+}

+ 59 - 0
JBIM/ServiceDataCheck/DataCheck.Mode/CheckBase.cs

@@ -0,0 +1,59 @@
+/* ==============================================================================
+ * 功能描述:CheckBase  
+ * 创 建 者:Garrett
+ * 创建日期:2019/6/11 16:01:26
+ * ==============================================================================*/
+
+using System;
+using System.Collections.Generic;
+using Autodesk.Revit.DB;
+using Newtonsoft.Json;
+
+
+namespace ServiceRevitLib.Mode
+{
+    /// <summary>
+    /// CheckBase
+    /// </summary>
+    public class CheckBase:ResultBase
+    {
+        public CheckBase()
+        {
+            Content=new List<ResultBase>();
+        }
+        private string m_Name;
+        /// <summary>
+        /// 检查项名称
+        /// </summary>
+        public string Name
+        {
+            get { return this.GetType().Name; }
+        }
+
+
+        public List<ResultBase> Content { get; set; }
+        /// <summary>
+        /// 关联表的名称
+        /// </summary>
+        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
+        public string ReferenceSheet { get; set; }
+
+
+        #region Method
+        
+        protected Document m_Doc { get; set; }
+
+        public void SetDoc(Document doc)
+        {
+            m_Doc = doc;
+        }
+        public virtual void Check()
+        {
+            if(m_Doc==null)throw new NullReferenceException();
+
+            Console.WriteLine(this.Name + "Checked");
+        }
+
+        #endregion
+    }
+}

+ 52 - 0
JBIM/ServiceDataCheck/DataCheck.Mode/ColumnCheck.cs

@@ -0,0 +1,52 @@
+/* ==============================================================================
+ * 功能描述:SagaCheck  
+ * 创 建 者:Garrett
+ * 创建日期:2019/6/11 16:09:09
+ * ==============================================================================*/
+
+using System;
+using System.Linq;
+using System.Text.RegularExpressions;
+using Autodesk.Revit.DB;
+using SAGA.DotNetUtils.Extend;
+using ServiceRevitLib.Common;
+using SAGA.RevitUtils.Extends;
+using ServiceRevitLib.Extend;
+
+namespace ServiceRevitLib.Mode
+{
+    /// <summary>
+    /// SagaCheck
+    /// </summary>
+    class ColumnCheck : CheckBase
+    {
+        public override void Check()
+        {
+            base.Check();
+
+            #region
+
+            var document = m_Doc;
+            var elements = document.GetElements<FamilyInstance>(BuiltInCategory.OST_StructuralColumns);
+            foreach (FamilyInstance fi in elements)
+            {
+                var result = new ColumnCheckResult();
+                result.FamilyName = fi.GetFamilyName();
+                result.Id = fi.Id.ToString();
+                var roomBoundaries = fi.GetParameterInteger(BuiltInParameter.WALL_ATTR_ROOM_BOUNDING);
+                if (roomBoundaries == 1)
+                {
+                    result.Result = ResultState.Success;
+                }
+                else
+                {
+                    result.Result = ResultState.Failure;
+                    result.ResultMsg = "柱的房间边界属性 未勾选";
+                }
+                Content.Add(result);
+            }
+            #endregion
+
+        }
+    }
+}

+ 24 - 0
JBIM/ServiceDataCheck/DataCheck.Mode/ColumnCheckResult.cs

@@ -0,0 +1,24 @@
+/* ==============================================================================
+ * 功能描述:SagaCheckResult  
+ * 创 建 者:Garrett
+ * 创建日期:2019/5/31 16:20:46
+ * ==============================================================================*/
+
+namespace ServiceRevitLib.Mode
+{
+    /// <summary>
+    /// SagaCheckResult
+    /// </summary>
+    class ColumnCheckResult : ResultBase
+    {
+        /// <summary>
+        /// id
+        /// </summary>
+        public string Id { get; set; }
+        /// <summary>
+        /// 族名称
+        /// </summary>
+        public string FamilyName { get; set; }
+        
+    }
+}

+ 161 - 0
JBIM/ServiceDataCheck/DataCheck.Mode/ConnectorCheck.cs

@@ -0,0 +1,161 @@
+/* ==============================================================================
+ * 功能描述:SagaCheck  
+ * 创 建 者:Garrett
+ * 创建日期:2019/6/11 16:09:09
+ * ==============================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+using Autodesk.Revit.DB;
+using SAGA.DotNetUtils.Extend;
+using ServiceRevitLib.Common;
+using SAGA.RevitUtils.Extends;
+using SAGA.RevitUtils.MEP;
+using ServiceRevitLib.Extend;
+using ServiceRevitLib.Utils;
+
+namespace ServiceRevitLib.Mode
+{
+    /// <summary>
+    /// SagaCheck
+    /// </summary>
+    class ConnectorCheck : CheckBase
+    {
+        public ConnectorCheck()
+        {
+            ReferenceSheet = "参考-连接件对照表";
+        }
+        public override void Check()
+        {
+            base.Check();
+
+            #region
+
+            bool unitResult = true;
+            m_ProDefineConnectors = GetPreDefineConnectors();
+            var elements = m_Doc.GetEqEcElements();
+
+            foreach (var element in elements)
+            {
+                //检查设备或者部件
+                var result = GetCheckResult(element);
+                if (result == null) continue;
+                Content.Add(result);
+            }
+            #endregion
+
+        }
+        
+
+        private string m_HaveConnectorSing = "√";
+        private List<DCR_Connector> m_ProDefineConnectors;
+
+        public List<DCR_Connector> GetPreDefineConnectors()
+        {
+            var list = new List<DCR_Connector>();
+            var alllist = DataCheckRule.GetPreDefineConnectors();
+            foreach (DCR_Connector connector in alllist)
+            {
+                var pipeType = connector.PipeConnector;
+                var hvacType = connector.HvacConnector;
+                if (pipeType == m_HaveConnectorSing || hvacType == m_HaveConnectorSing)
+                {
+                    list.Add(connector);
+                    if (connector.PName.IsNotNullEmpty() && connector.PCode.IsNotNullEmpty())
+                    {
+                        //部件单独提出来当做一项
+                        var pconnector = new DCR_Connector()
+                        {
+                            Code = connector.PCode,
+                            Name = connector.Name,
+                            PipeConnector = connector.PipeConnector,
+                            HvacConnector = connector.HvacConnector
+                        };
+                        list.Add(pconnector);
+                    }
+                }
+            }
+            return list;
+        }
+        /// <summary>
+        /// 获取检测结果
+        /// </summary>
+        /// <param name="fi"></param>
+        /// <returns></returns>
+        private ConnectorCheckResult GetCheckResult(Element element)
+        {
+            if (element == null) return null;
+            var result = new ConnectorCheckResult();
+            var code = element.GetFamilyCode();
+            var defineConType = GetDefineConType(code);
+            if (defineConType == null) return null;
+            result.FamilyName = element.GetFamilyName();
+            result.Id = element.Id.ToString();
+            result.Result = ResultState.Success;
+            CheckConType(result, element, defineConType.Item1);
+            CheckConType(result, element, defineConType.Item2);
+            return result;
+        }
+        /// <summary>
+        /// 获取定义的风和水连接件类型
+        /// </summary>
+        /// <param name="code"></param>
+        /// <returns></returns>
+        private Tuple<Domain, Domain> GetDefineConType(string code)
+        {
+            var item = m_ProDefineConnectors.FirstOrDefault(t => t.Code == code);
+            if (item == null) return null;
+            var pipeType = item.PipeConnector;
+            var hvacType = item.HvacConnector;
+
+            var pipeConType = pipeType == m_HaveConnectorSing ? Domain.DomainPiping : Domain.DomainUndefined;
+            var hvacConType = hvacType == m_HaveConnectorSing ? Domain.DomainHvac : Domain.DomainUndefined;
+            return new Tuple<Domain, Domain>(pipeConType, hvacConType);
+        }
+        /// <summary>
+        /// 检查连接件类型是否存在
+        /// </summary>
+        /// <param name="result"></param>
+        /// <param name="domain"></param>
+        private void CheckConType(ConnectorCheckResult result, Element fi, Domain domain)
+        {
+            if (domain != Domain.DomainUndefined)
+            {
+                var connectors = fi.GetConnectors(domain);
+                var domainStr = DomainToString(domain);
+                if (connectors.Any())
+                {
+                    if (connectors.All(t => t.IsConnected)) return;
+                    result.Result = ResultState.Failure;
+                    result.ResultMsg += $"发现 {domainStr}连接件未连接;";
+                }
+                else
+                {
+                    result.Result = ResultState.Failure;
+                    result.ResultMsg += $"缺少 {domainStr} 连接件;";
+                }
+            }
+        }
+
+        private string DomainToString(Domain domain)
+        {
+            string str = "";
+            switch (domain)
+            {
+                case Domain.DomainPiping:
+                    str = "水管";
+                    break;
+                case Domain.DomainHvac:
+                    str = "风管";
+                    break;
+                default:
+                    str = "未知";
+                    break;
+
+            }
+            return str;
+        }
+    }
+}

+ 23 - 0
JBIM/ServiceDataCheck/DataCheck.Mode/ConnectorCheckResult.cs

@@ -0,0 +1,23 @@
+/* ==============================================================================
+ * 功能描述:SagaCheckResult  
+ * 创 建 者:Garrett
+ * 创建日期:2019/5/31 16:20:46
+ * ==============================================================================*/
+
+namespace ServiceRevitLib.Mode
+{
+    /// <summary>
+    /// SagaCheckResult
+    /// </summary>
+    class ConnectorCheckResult : ResultBase
+    {
+        /// <summary>
+        /// id
+        /// </summary>
+        public string Id { get; set; }
+        /// <summary>
+        /// 族名称
+        /// </summary>
+        public string FamilyName { get; set; }
+    }
+}

+ 258 - 0
JBIM/ServiceDataCheck/DataCheck.Mode/ElementRangeCheck.cs

@@ -0,0 +1,258 @@
+/* ==============================================================================
+ * 功能描述:SagaCheck  
+ * 创 建 者:Garrett
+ * 创建日期:2019/6/11 16:09:09
+ * ==============================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text.RegularExpressions;
+using Autodesk.Revit.DB;
+using Autodesk.Revit.DB.Mechanical;
+using SAGA.DotNetUtils.Extend;
+using ServiceRevitLib.Common;
+using SAGA.RevitUtils.Extends;
+using ServiceRevitLib.Extend;
+
+namespace ServiceRevitLib.Mode
+{
+    /// <summary>
+    /// SagaCheck
+    /// </summary>
+    class ElementRangeCheck : CheckBase
+    {
+        #region 序列化属性
+        private double m_Redundant = 500;
+        /// <summary>
+        /// 高度冗余
+        /// </summary>
+        public double Redundant
+        {
+            get { return m_Redundant; }
+            set { m_Redundant = value; }
+        }
+
+
+        private double m_baseLevel;
+        /// <summary>
+        /// 底部标高
+        /// </summary>
+        public double BaseLevel
+        {
+            get { return m_baseLevel; }
+        }
+
+        private List<double> m_topLevels = new List<double>();
+
+        /// <summary>
+        /// 顶部标高(夹层可能涉及多个顶)
+        /// </summary>
+        public string TopLevels
+        {
+            get { return string.Join(";", m_topLevels); }
+        }
+
+        #endregion
+        public override void Check()
+        {
+            base.Check();
+
+            #region
+
+            var document = m_Doc;
+            if (!SetFloorBaseTopRange()) return;
+            var elements = document.GetAllElements();
+            foreach (var element in elements)
+            {
+                var result = GetCheckResult(element);
+                if (result != null)
+                    Content.Add(result);
+            }
+
+
+            #endregion
+        }
+
+        /// <summary>
+        /// 设置当前楼层底部和顶部范围
+        /// </summary>
+        /// <param name="doc"></param>
+        /// <param name="result"></param>
+        private bool SetFloorBaseTopRange()
+        {
+            bool rt = true;
+            var document = m_Doc;
+            try
+            {
+                var sagaPlans = document.GetElements<ViewPlan>()
+                    .Where(t => t.ViewType == ViewType.FloorPlan && t.Name.Contains("-saga")).ToList();
+                var curFloor = sagaPlans.FirstOrDefault();
+                if (sagaPlans.Count != 1 || curFloor == null)
+                {
+                    Result = ResultState.Failure;
+                    ResultMsg = "Saga标记不合法,请修正后再进行检查";
+
+                    return false;
+                }
+
+                //设置楼层底部高度
+                m_baseLevel = curFloor.GenLevel.Elevation.FromApi().Round(2);
+
+                //设置楼层顶部高度
+                var levels = m_Doc.GetLevels();
+                var mbiLevels = levels.Where(t => Regex.IsMatch(t.Name, $"{RegexConstPattern.IsMBILevel}") && t.Elevation.IsThan(m_baseLevel)).ToList();
+                foreach (Level level in mbiLevels)
+                {
+                    m_topLevels.Add(level.Elevation.FromApi().Round(2));
+                    if (!Regex.IsMatch(level.Name, $"{RegexConstPattern.IsSandwich}"))
+                    {
+                        break;
+                    }
+                }
+                //当前层为屋顶或屋顶夹层时,顶部限制设置为正无穷
+                if (Regex.IsMatch(curFloor.GenLevel.Name, $"{RegexConstPattern.IsRF}|{RegexConstPattern.IsRFM}"))
+                {
+                    m_topLevels.Add(double.MaxValue);
+                }
+
+
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine(e);
+                rt = false;
+            }
+            return rt;
+        }
+
+        /// <summary>
+        /// 获取检测结果
+        /// </summary>
+        /// <param name="element"></param>
+        /// <returns></returns>
+        private ElementRangeCheckResult GetCheckResult(Element element)
+        {
+            var result = new ElementRangeCheckResult();
+            result.Id = element.Id.ToString();
+            result.FamilyName = element.GetFamilyName();
+            try
+            {
+                double zb = 0, zt = 0;
+                bool rb = false, rt = false;
+                //需要识别判定的构件
+                DCElementType type = DCElementType.None;
+                bool isBoxInst = false;
+                if (element is Wall wall)
+                {
+                    isBoxInst = true;
+                    zb = wall.GetBaseStaticHeight();
+                    zt = wall.GetTopStaticHeight();
+                    type = DCElementType.Wall;
+                }
+                else if (element.IsSpace())
+                {
+                    var space = element as Space;
+                    isBoxInst = true;
+                    zb = space.GetBaseStaticHeight();
+                    zt = space.GetTopStaticHeight();
+                    type = DCElementType.Space;
+                }
+                else if (element is FamilyInstance)
+                {
+                    if (element.IsAllColumn())
+                    {
+                        var fi = element as FamilyInstance;
+                        isBoxInst = true;
+                        zb = fi.GetBaseStaticHeight();
+                        zt = fi.GetTopStaticHeight();
+                        type = DCElementType.Column;
+                    }
+                    else if (element.IsEquipment() || element.IsEquipmentPart() || element.IsBeacon())
+                    {
+                        zb = element.GetLocationPointMBIXYZ().Z;
+                        type = GetRType(element);
+                    }
+                }
+
+                if (type==DCElementType.None) return null;
+                
+                //冗余,使用时,统一使用单位mm
+                double w = Redundant;
+                zb = zb.FromApi().Round(2);
+                zt = zt.FromApi().Round(2);
+                //构件类型
+                result.Type = type.GetDescription();
+                if (isBoxInst)
+                {
+                    rb = zb.IsBetween(m_baseLevel - w, m_baseLevel);
+                    rt = m_topLevels.Any(t => zt.IsBetween(t - w, t));
+                    string ttip = rb ? "" : "底部";
+                    string ttop = rt ? "" : rb ? "和顶部" : "顶部";
+                    result.HeightRange = $"{zb},{zt}";
+                    result.Result = (rb && rt)?ResultState.Success:ResultState.Failure;
+                    result.ResultMsg = rb && rt ? "" : $"构件范围不满足要求;请检查构件{ttip}{ttop}";
+                }
+                else
+                {
+                    rb = m_topLevels.Any(t => zb.IsBetween(m_baseLevel, t));
+                    result.HeightRange = $"{zb}";
+                    result.Result = (rb) ? ResultState.Success : ResultState.Failure;
+                    result.ResultMsg = rb? "" : $"构件范围不满足要求;请检查构件位置";
+                }
+            }
+            catch (Exception e)
+            {
+                result.Result = ResultState.Failure;
+                result.ResultMsg = "构件范围检查异常";
+            }
+
+
+            return result;
+        }
+
+        /// <summary>
+        /// 获取构件类型
+        /// </summary>
+        /// <param name="fi"></param>
+        /// <returns></returns>
+        private DCElementType GetRType(Element fi)
+        {
+            DCElementType name = DCElementType.None;
+            if (fi.IsEquipment())
+            {
+                name = DCElementType.Equipment;
+            }
+            else if (fi.IsEquipmentPart())
+            {
+                name = DCElementType.EuipmentPart;
+            }
+            else if (fi.IsBeacon())
+            {
+                name = DCElementType.Beacon;
+            }
+            return name;
+        }
+        /// <summary>
+        /// DCElementType
+        /// </summary>
+        public enum DCElementType
+        {
+            [Description("未知")]
+            None,
+            [Description("墙")]
+            Wall,
+            [Description("柱")]
+            Column,
+            [Description("空间")]
+            Space,
+            [Description("设备")]
+            Equipment,
+            [Description("部件")]
+            EuipmentPart,
+            [Description("信标")]
+            Beacon
+        }
+    }
+}

+ 35 - 0
JBIM/ServiceDataCheck/DataCheck.Mode/ElementRangeCheckResult.cs

@@ -0,0 +1,35 @@
+/* ==============================================================================
+ * 功能描述:SagaCheckResult  
+ * 创 建 者:Garrett
+ * 创建日期:2019/5/31 16:20:46
+ * ==============================================================================*/
+
+using Newtonsoft.Json;
+
+namespace ServiceRevitLib.Mode
+{
+    /// <summary>
+    /// SagaCheckResult
+    /// </summary>
+    class ElementRangeCheckResult : ResultBase
+    {
+        /// <summary>
+        /// id
+        /// </summary>
+        public string Id { get; set; }
+        /// <summary>
+        /// 族名称
+        /// </summary>
+        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
+        public string FamilyName { get; set; }
+
+        /// <summary>
+        /// 构件类型
+        /// </summary>
+        public string Type { get; set; }
+        /// <summary>
+        /// 高度范围(单位英寸)
+        /// </summary>
+        public string HeightRange { get; set; }
+    }
+}

+ 69 - 0
JBIM/ServiceDataCheck/DataCheck.Mode/EquipInSpaceCheck.cs

@@ -0,0 +1,69 @@
+/* ==============================================================================
+ * 功能描述:SagaCheck  
+ * 创 建 者:Garrett
+ * 创建日期:2019/6/11 16:09:09
+ * ==============================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+using Autodesk.Revit.DB;
+using Autodesk.Revit.DB.Mechanical;
+using SAGA.DotNetUtils.Extend;
+using ServiceRevitLib.Common;
+using SAGA.RevitUtils.Extends;
+using ServiceRevitLib.Extend;
+
+namespace ServiceRevitLib.Mode
+{
+    /// <summary>
+    /// SagaCheck
+    /// </summary>
+    class EquipInSpaceCheck : CheckBase
+    {
+        public override void Check()
+        {
+            base.Check();
+
+            #region
+
+            var document = m_Doc;
+            var elements = document.GetEqEcElements();
+            var rspaces = document.GetSpaces().Where(t => t.IsValidObject).ToList();
+            foreach (Element fi in elements)
+            {
+                var result = GetCheckResult(fi, rspaces);
+                Content.Add(result);
+            }
+
+            #endregion
+
+        }
+
+        /// <summary>
+        /// 获取检测结果
+        /// </summary>
+        /// <param name="fi"></param>
+        /// <returns></returns>
+        private EquipInSpaceCheckResult GetCheckResult(Element fi, List<Space> spaces)
+        {
+            var result = new EquipInSpaceCheckResult();
+            result.FamilyName = fi.GetFamilyName();
+            result.Id = fi.Id.ToString();
+            var space = fi.GetReferenceSpace(spaces);
+            if (space != null)
+            {
+                result.SpaceId = space.Id.ToString();
+                result.Result = ResultState.Success;
+            }
+            else
+            {
+                result.Result = ResultState.Failure;
+                result.ResultMsg = "请检查设备是否在空间中";
+            }
+
+            return result;
+        }
+    }
+}

+ 31 - 0
JBIM/ServiceDataCheck/DataCheck.Mode/EquipInSpaceCheckResult.cs

@@ -0,0 +1,31 @@
+/* ==============================================================================
+ * 功能描述:SagaCheckResult  
+ * 创 建 者:Garrett
+ * 创建日期:2019/5/31 16:20:46
+ * ==============================================================================*/
+
+using Newtonsoft.Json;
+
+namespace ServiceRevitLib.Mode
+{
+    /// <summary>
+    /// SagaCheckResult
+    /// </summary>
+    class EquipInSpaceCheckResult : ResultBase
+    {
+        /// <summary>
+        /// id
+        /// </summary>
+        public string Id { get; set; }
+        /// <summary>
+        /// 族名称
+        /// </summary>
+        public string FamilyName { get; set; }
+        /// <summary>
+        /// 所在空间id
+        /// </summary>
+        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
+        public string SpaceId { get; set; }
+
+    }
+}

+ 55 - 0
JBIM/ServiceDataCheck/DataCheck.Mode/EquipPartLocationCheck.cs

@@ -0,0 +1,55 @@
+/* ==============================================================================
+ * 功能描述:SagaCheck  
+ * 创 建 者:Garrett
+ * 创建日期:2019/6/11 16:09:09
+ * ==============================================================================*/
+
+using System;
+using System.Linq;
+using System.Text.RegularExpressions;
+using Autodesk.Revit.DB;
+using SAGA.DotNetUtils.Extend;
+using ServiceRevitLib.Common;
+using SAGA.RevitUtils.Extends;
+using ServiceRevitLib.Extend;
+
+namespace ServiceRevitLib.Mode
+{
+    /// <summary>
+    /// SagaCheck
+    /// </summary>
+    class EquipPartLocationCheck : CheckBase
+    {
+        public override void Check()
+        {
+            base.Check();
+
+            #region
+            
+            var document = m_Doc;
+            var elements = document.GetEqEcElements();
+            var parts = elements.Where(t => t.IsEquipmentPart());
+            foreach (Element fi in parts)
+            {
+                var result = new EquipPartLocationCheckResult();
+                result.PartFamilyName = fi.GetFamilyName();
+                result.PartId = fi.Id.ToString();
+                var partParent = fi.GetPartParent();
+                if (partParent == null)
+                {
+                    result.Result = ResultState.Failure;
+                    result.ResultMsg = "未与设备相交,请检查";
+                }
+                else
+                {
+                    result.RefId = partParent.Id.ToString();
+                    result.Result = ResultState.Success;
+                }
+                Content.Add(result);
+            }
+
+            #endregion
+
+        }
+    }
+}

+ 27 - 0
JBIM/ServiceDataCheck/DataCheck.Mode/EquipPartLocationCheckResult.cs

@@ -0,0 +1,27 @@
+/* ==============================================================================
+ * 功能描述:SagaCheckResult  
+ * 创 建 者:Garrett
+ * 创建日期:2019/5/31 16:20:46
+ * ==============================================================================*/
+
+namespace ServiceRevitLib.Mode
+{
+    /// <summary>
+    /// SagaCheckResult
+    /// </summary>
+    class EquipPartLocationCheckResult : ResultBase
+    {
+        /// <summary>
+        /// 部件id
+        /// </summary>
+        public string PartId { get; set; }
+        /// <summary>
+        /// 部件族名称
+        /// </summary>
+        public string PartFamilyName { get; set; }
+        /// <summary>
+        /// 关联设备id
+        /// </summary>
+        public string RefId { get; set; }
+    }
+}

+ 78 - 0
JBIM/ServiceDataCheck/DataCheck.Mode/FamilyNameCheck.cs

@@ -0,0 +1,78 @@
+/* ==============================================================================
+ * 功能描述:SagaCheck  
+ * 创 建 者:Garrett
+ * 创建日期:2019/6/11 16:09:09
+ * ==============================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+using Autodesk.Revit.DB;
+using SAGA.DotNetUtils.Extend;
+using ServiceRevitLib.Common;
+using SAGA.RevitUtils.Extends;
+using ServiceRevitLib.Extend;
+using ServiceRevitLib.Utils;
+
+namespace ServiceRevitLib.Mode
+{
+    /// <summary>
+    /// SagaCheck
+    /// </summary>
+    class FamilyNameCheck : CheckBase
+    {
+        public FamilyNameCheck()
+        {
+            ReferenceSheet = "参考-revit分类";
+        }
+        public override void Check()
+        {
+            base.Check();
+
+            #region
+            
+            var ccategories = DataCheckRule.GetCodeCheckCategories();
+            var categories = m_Doc.Settings.Categories;
+            foreach (DCR_CodeCheckCategory ccategory in ccategories)
+            {
+                try
+                {
+                    var category = categories.get_Item(ccategory.Name);
+                    if (category == null) continue;
+                    BuiltInCategory builtInCategory = (BuiltInCategory)category.Id.IntegerValue;
+                    var elements = m_Doc.GetElements<FamilyInstance>(builtInCategory);
+                    var groupByFamily = elements.GroupBy(t => t.GetFamilyName());
+                    foreach (IGrouping<string, FamilyInstance> grouping in groupByFamily)
+                    {
+                        var subElements = grouping.ToList();
+                        var subElement = subElements.FirstOrDefault();
+                        if (subElement is FamilyInstance fi)
+                        {
+                            var result = new FamilyNameCheckResult();
+                            result.FamilyName = grouping.Key;
+                            if (fi.IsEquipment()|| fi.IsEquipmentPart()|| fi.IsBeacon())
+                            {
+                                result.Result = ResultState.Success;
+                            }
+                            else
+                            {
+                                result.Result = ResultState.Failure;
+                                result.ResultMsg = "请检查族名称编码是否符合要求";
+                            }
+                            Content.Add(result);
+                        }
+                    }
+                }
+                catch (Exception e)
+                {
+                    Console.WriteLine(e);
+                }
+            }
+
+            #endregion
+
+        }
+        
+    }
+}

+ 19 - 0
JBIM/ServiceDataCheck/DataCheck.Mode/FamilyNameCheckResult.cs

@@ -0,0 +1,19 @@
+/* ==============================================================================
+ * 功能描述:SagaCheckResult  
+ * 创 建 者:Garrett
+ * 创建日期:2019/5/31 16:20:46
+ * ==============================================================================*/
+
+namespace ServiceRevitLib.Mode
+{
+    /// <summary>
+    /// SagaCheckResult
+    /// </summary>
+    class FamilyNameCheckResult : ResultBase
+    {
+        /// <summary>
+        /// 族名称
+        /// </summary>
+        public string FamilyName { get; set; }
+    }
+}

+ 78 - 0
JBIM/ServiceDataCheck/DataCheck.Mode/ParameterIntegrityCheck.cs

@@ -0,0 +1,78 @@
+/* ==============================================================================
+ * 功能描述:SagaCheck  
+ * 创 建 者:Garrett
+ * 创建日期:2019/6/11 16:09:09
+ * ==============================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+using Autodesk.Revit.DB;
+using SAGA.DotNetUtils.Extend;
+using ServiceRevitLib.Common;
+using SAGA.RevitUtils.Extends;
+using ServiceRevitLib.Extend;
+
+namespace ServiceRevitLib.Mode
+{
+    /// <summary>
+    /// SagaCheck
+    /// </summary>
+    class ParameterIntegrityCheck : CheckBase
+    {
+        public override void Check()
+        {
+            base.Check();
+
+            #region
+
+            var doc = m_Doc;
+            var instances = doc.GetEqEcElements();
+            var familyGroups = instances.GroupBy(t => t.GetFamilyName());
+            foreach (IGrouping<string, Element> familyGroup in familyGroups)
+            {
+                Element fi = familyGroup.FirstOrDefault();
+                if (fi == null) continue;
+                var result = GetCheckResult(fi);
+                if (result == null) continue;
+                result.FamilyName = familyGroup.Key;
+                Content.Add(result);
+            }
+
+            #endregion
+
+        }
+
+
+        /// <summary>
+        /// 获取检测结果
+        /// </summary>
+        /// <param name="fi"></param>
+        /// <returns></returns>
+        private ParameterIntegrityCheckResult GetCheckResult(Element fi)
+        {
+            //检查项
+            var checkParamNames = new List<string>() { MBIConst.EquipLocalName, MBIConst.EquipLocalID };
+
+            var result = new ParameterIntegrityCheckResult();
+            List<string> list = new List<string>();
+            foreach (var paramName in checkParamNames)
+            {
+                var parameter = fi.GetParameter(paramName);
+                if (parameter == null)
+                    list.Add(paramName);
+            }
+            if (list.Any())
+            {
+                result.Result = ResultState.Failure;
+                result.ResultMsg = $"缺失的参数为:{string.Join("、", list)}";
+            }
+            else
+            {
+                result.Result = ResultState.Success;
+            }
+            return result;
+        }
+    }
+}

+ 20 - 0
JBIM/ServiceDataCheck/DataCheck.Mode/ParameterIntegrityCheckResult.cs

@@ -0,0 +1,20 @@
+/* ==============================================================================
+ * 功能描述:SagaCheckResult  
+ * 创 建 者:Garrett
+ * 创建日期:2019/5/31 16:20:46
+ * ==============================================================================*/
+
+namespace ServiceRevitLib.Mode
+{
+    /// <summary>
+    /// SagaCheckResult
+    /// </summary>
+    class ParameterIntegrityCheckResult : ResultBase
+    {
+        /// <summary>
+        /// 族名称
+        /// </summary>
+        public string FamilyName { get; set; }
+        
+    }
+}

+ 35 - 0
JBIM/ServiceDataCheck/DataCheck.Mode/ResultBase.cs

@@ -0,0 +1,35 @@
+/* ==============================================================================
+ * 功能描述:
+ * 创 建 者:Garrett
+ * 创建日期:2019/5/31 16:24:04
+ * ==============================================================================*/
+
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
+
+namespace ServiceRevitLib.Mode
+{
+    /// <summary>
+    /// CheckResultBase
+    /// </summary>
+    public class ResultBase
+    {
+        public ResultBase()
+        {
+            Result = ResultState.Success;
+        }
+        /// <summary>
+        /// 成功或失败结果描述
+        /// </summary>
+        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
+        public string ResultMsg { get; set; }
+
+        /// <summary>
+        /// 结果
+        /// </summary>
+        [JsonConverter(typeof(StringEnumConverter))]
+        public ResultState Result { get; set; }
+
+
+    }
+}

+ 17 - 0
JBIM/ServiceDataCheck/DataCheck.Mode/ResultState.cs

@@ -0,0 +1,17 @@
+/* ==============================================================================
+ * 功能描述:结果的状态
+ * 创 建 者:Garrett
+ * 创建日期:2019/5/31 16:29:04
+ * ==============================================================================*/
+
+namespace ServiceRevitLib.Mode
+{
+    /// <summary>
+    /// ResultState
+    /// </summary>
+    public enum ResultState
+    {
+        Failure=0,
+        Success,
+    }
+}

+ 90 - 0
JBIM/ServiceDataCheck/DataCheck.Mode/SagaCheck.cs

@@ -0,0 +1,90 @@
+/* ==============================================================================
+ * 功能描述:SagaCheck  
+ * 创 建 者:Garrett
+ * 创建日期:2019/6/11 16:09:09
+ * ==============================================================================*/
+
+using System;
+using System.Linq;
+using System.Text.RegularExpressions;
+using Autodesk.Revit.DB;
+using SAGA.DotNetUtils.Extend;
+using ServiceRevitLib.Common;
+using SAGA.RevitUtils.Extends;
+
+namespace ServiceRevitLib.Mode
+{
+    /// <summary>
+    /// SagaCheck
+    /// </summary>
+    class SagaCheck : CheckBase
+    {
+        public override void Check()
+        {
+            base.Check();
+
+            #region
+
+            string resultMsg = null;
+            ResultState resultState = 0;
+            string planName = "";
+
+            //判断是否存在Saga标记
+            var document = m_Doc;
+            var sagaPlans = document.GetElements<ViewPlan>()
+                .Where(t => t.ViewType == ViewType.FloorPlan && t.Name.Contains("-saga")).ToList();
+            if (sagaPlans.Count == 0)
+            {
+                resultState = ResultState.Failure;
+                resultMsg = "缺少saga标记";
+            }
+            else if (sagaPlans.Count() >= 2)
+            {
+                resultState = ResultState.Failure;
+                resultMsg = "有多个saga标记";
+            }
+            else
+            {
+                //只有一个saga标记
+                var sagaPlan = sagaPlans.FirstOrDefault();
+                if (sagaPlan != null)
+                {
+                    planName = sagaPlan.Name;
+                    //打标记的楼层名称必需为指定格式;B1,B1M,F1,F1M,RFM,RF
+                    if (Regex.IsMatch(planName, $"{RegexConstPattern.IsMBIView}"))
+                    {
+                        var rfLevel = document.GetLevels().FirstOrDefault(t =>
+                            System.Text.RegularExpressions.Regex.IsMatch(t.Name, $"{RegexConstPattern.IsRF}"));
+                        if (rfLevel == null)
+                        {
+                            resultState = ResultState.Failure;
+                            resultMsg = $"缺少RF标高";
+                        }
+                        else
+                        {
+                            if (rfLevel.Elevation.IsThanEq(sagaPlan.GenLevel.Elevation))
+                            {
+                                resultState = ResultState.Success;
+                            }
+                            else
+                            {
+                                resultState = ResultState.Failure;
+                                resultMsg = $"RF标高的位置不正确,请检查";
+                            }
+                        }
+                    }
+                    else
+                    {
+                        resultState = ResultState.Failure;
+                        resultMsg = $"楼层 {planName} 不符合楼层命名规范";
+                    }
+                }
+            }
+
+            Content.Add(new SagaCheckResult() {PlanName = planName, Result = resultState, ResultMsg = resultMsg});
+
+            #endregion
+
+        }
+    }
+}

+ 19 - 0
JBIM/ServiceDataCheck/DataCheck.Mode/SagaCheckResult.cs

@@ -0,0 +1,19 @@
+/* ==============================================================================
+ * 功能描述:SagaCheckResult  
+ * 创 建 者:Garrett
+ * 创建日期:2019/5/31 16:20:46
+ * ==============================================================================*/
+
+namespace ServiceRevitLib.Mode
+{
+    /// <summary>
+    /// SagaCheckResult
+    /// </summary>
+    class SagaCheckResult: ResultBase
+    {
+        /// <summary>
+        /// Saga视图的名称
+        /// </summary>
+        public string PlanName { get; set; }
+    }
+}

+ 92 - 0
JBIM/ServiceDataCheck/DataCheck.Mode/SystemNameCheck.cs

@@ -0,0 +1,92 @@
+/* ==============================================================================
+ * 功能描述:SagaCheck  
+ * 创 建 者:Garrett
+ * 创建日期:2019/6/11 16:09:09
+ * ==============================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+using Autodesk.Revit.DB;
+using Autodesk.Revit.DB.Mechanical;
+using SAGA.DotNetUtils.Extend;
+using ServiceRevitLib.Common;
+using SAGA.RevitUtils.Extends;
+using SAGA.RevitUtils.MEP;
+using ServiceRevitLib.Extend;
+using ServiceRevitLib.Utils;
+
+namespace ServiceRevitLib.Mode
+{
+    /// <summary>
+    /// SagaCheck
+    /// </summary>
+    class SystemNameCheck : CheckBase
+    {
+        public SystemNameCheck()
+        {
+            ReferenceSheet = "参考-可识别的系统名称";
+        }
+        public override void Check()
+        {
+            base.Check();
+
+            #region
+
+            m_MEPSystems = DataCheckRule.GetMepSystems();
+
+            var mepsystemTypes = new List<MEPSystemType>();
+            mepsystemTypes.AddRange(m_Doc.GetMechanicalSystemTypes());
+            mepsystemTypes.AddRange(m_Doc.GetPipingSystemTypes());
+            foreach (var t in mepsystemTypes)
+            {
+                var result = GetCheckResult(t);
+                Content.Add(result);
+            }
+
+            #endregion
+
+        }
+        private List<DCR_MEPSystem> m_MEPSystems;
+
+        /// <summary>
+        /// 获取检测结果
+        /// </summary>
+        /// <param name="fi"></param>
+        /// <returns></returns>
+        private SystemNameCheckResult GetCheckResult(MEPSystemType system)
+        {
+            var result = new SystemNameCheckResult();
+            string systemName = system.Name;
+            result.SystemName = systemName;
+            result.SystemType = system is MechanicalSystemType ? "风管系统" : "管道系统";
+            
+            var item = m_MEPSystems.Where(t => SystemNameIsEqual(systemName, t.Name));
+            if (item.Any())
+            {
+                result.Result = ResultState.Success;
+            }
+            else
+            {
+                result.Result = ResultState.Failure;
+                result.ResultMsg = $"未知的系统名称,请按照系统类型命名规范修改";
+            }
+            
+            return result;
+        }
+        /// <summary>
+        /// 系统名称相等,模型中的系统名称包含就定义名称即可
+        /// </summary>
+        /// <param name="originName"></param>
+        /// <param name="targetName"></param>
+        /// <returns></returns>
+        private bool SystemNameIsEqual(string originName, string targetName)
+        {
+            bool result = false;
+            string n1 = originName.ToLower();
+            string n2 = targetName.ToLower();
+            return n1.Equals(n2);
+        }
+    }
+}

+ 24 - 0
JBIM/ServiceDataCheck/DataCheck.Mode/SystemNameCheckResult.cs

@@ -0,0 +1,24 @@
+/* ==============================================================================
+ * 功能描述:SagaCheckResult  
+ * 创 建 者:Garrett
+ * 创建日期:2019/5/31 16:20:46
+ * ==============================================================================*/
+
+namespace ServiceRevitLib.Mode
+{
+    /// <summary>
+    /// SagaCheckResult
+    /// </summary>
+    class SystemNameCheckResult : ResultBase
+    {
+        /// <summary>
+        /// 系统名称
+        /// </summary>
+        public string SystemName { get; set; }
+        /// <summary>
+        /// 系统类型
+        /// </summary>
+        public string SystemType { get; set; }
+        
+    }
+}

+ 125 - 0
JBIM/ServiceDataCheck/DataCheck.Mode/SystemReferEquipCheck.cs

@@ -0,0 +1,125 @@
+/* ==============================================================================
+ * 功能描述:SagaCheck  
+ * 创 建 者:Garrett
+ * 创建日期:2019/6/11 16:09:09
+ * ==============================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+using Autodesk.Revit.DB;
+using SAGA.DotNetUtils.Extend;
+using SAGA.DotNetUtils.Logger;
+using ServiceRevitLib.Common;
+using SAGA.RevitUtils.Extends;
+using SAGA.RevitUtils.MEP;
+using ServiceRevitLib.Extend;
+using ServiceRevitLib.Utils;
+
+namespace ServiceRevitLib.Mode
+{
+    /// <summary>
+    /// SagaCheck
+    /// </summary>
+    class SystemReferEquipCheck : CheckBase
+    {
+        public SystemReferEquipCheck()
+        {
+            ReferenceSheet = "参考-管网及相关设备";
+        }
+        public override void Check()
+        {
+            base.Check();
+
+            #region
+
+            m_EquipReferSystems = DataCheckRule.GetEquipReferSystems();
+
+            var elements = m_Doc.GetEqEcElements();
+            foreach (Element element in elements)
+            {
+                var result = GetCheckResult(element);
+                if (result == null) continue;
+                Content.Add(result);
+            }
+
+            #endregion
+
+        }
+
+        private List<DCR_EquipReferSystem> m_EquipReferSystems;
+     
+
+        /// <summary>
+        /// 获取检测结果
+        /// </summary>
+        /// <param name="fi"></param>
+        /// <returns></returns>
+        private SystemReferEquipCheckResult GetCheckResult(Element element)
+        {
+            var result = new SystemReferEquipCheckResult();
+            var code = element.GetFamilyCode();
+            // 可以与设备连接的系统
+            var referSystems = m_EquipReferSystems.FirstOrDefault(t => t.EquipName == code)?.Systems ?? new List<string>();
+            if (referSystems.Count == 0) return null;
+
+            result.FamilyName = element.GetFamilyName();
+            result.Id = element.Id.ToString();
+
+            var tuple = CheckConType(element, referSystems);
+            if (tuple.Item2.Any())
+            {
+                result.ResultMsg = $"连接件所连接的管道系统与规范不一致,请检查";
+                result.UnPassSystems += string.Join("、", tuple.Item2.ToArray());
+                result.Result = ResultState.Failure;
+            }
+            else
+            {
+                result.Result = ResultState.Success;
+            }
+            result.PassSystems += string.Join("、", tuple.Item1.ToArray());
+
+            return result;
+        }
+
+        /// <summary>
+        /// 检查连接件连接的管道系统是否符合规范
+        /// </summary>
+        /// <param name="result">符合要求的系统名称</param>
+        /// <param name="domain">不符合要求的系统名称</param>
+        private Tuple<List<string>, List<string>> CheckConType(Element element, List<string> referSystems)
+        {
+            List<string> passList = new List<string>();
+            List<string> unpassList = new List<string>();
+
+            var connectors = element.GetAllConnectors();
+            foreach (Connector connector in connectors)
+            {
+                try
+                {
+                    var mepSystem = connector.MEPSystem;
+                    if (mepSystem == null) continue;
+                    var elementId = mepSystem.GetTypeId();
+                    var type = element.Document.GetElement(elementId);
+                    if (!referSystems.Contains(type.Name))
+                    {
+                        unpassList.Add(type.Name);
+                    }
+                    else
+                    {
+                        passList.Add(type.Name);
+                    }
+                }
+                catch (Exception e)
+                {
+                    Log4Net.Info($"读取连接件系统错误。Id:{element.Id},Path:{element.Document.PathName}");
+                }
+            }
+
+            return new Tuple<List<string>, List<string>>(passList, unpassList);
+        }
+
+
+    }
+}

+ 37 - 0
JBIM/ServiceDataCheck/DataCheck.Mode/SystemReferEquipCheckResult.cs

@@ -0,0 +1,37 @@
+/* ==============================================================================
+ * 功能描述:SagaCheckResult  
+ * 创 建 者:Garrett
+ * 创建日期:2019/5/31 16:20:46
+ * ==============================================================================*/
+
+using Newtonsoft.Json;
+
+namespace ServiceRevitLib.Mode
+{
+    /// <summary>
+    /// SagaCheckResult
+    /// </summary>
+    class SystemReferEquipCheckResult : ResultBase
+    {
+        /// <summary>
+        /// id
+        /// </summary>
+        public string Id { get; set; }
+        /// <summary>
+        /// 族名称
+        /// </summary>
+        public string FamilyName { get; set; }
+
+        /// <summary>
+        /// 合法的系统名称集合
+        /// </summary>
+        public string PassSystems { get; set; }
+        /// <summary>
+        /// 不合法的系统名称集合
+        /// </summary>
+        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
+        public string UnPassSystems { get; set; }
+
+
+    }
+}

+ 45 - 0
JBIM/ServiceDataCheck/DataCheck.Mode/UnitCheck.cs

@@ -0,0 +1,45 @@
+/* ==============================================================================
+ * 功能描述:SagaCheck  
+ * 创 建 者:Garrett
+ * 创建日期:2019/6/11 16:09:09
+ * ==============================================================================*/
+
+using System;
+using Autodesk.Revit.DB;
+
+namespace ServiceRevitLib.Mode
+{
+    /// <summary>
+    /// SagaCheck
+    /// </summary>
+    class UnitCheck : CheckBase
+    {
+        public override void Check()
+        {
+            base.Check();
+
+            #region
+
+            string resultMsg =null;
+            ResultState resultState = ResultState.Failure;
+            string unit = "";
+            
+            var formatOptions = m_Doc.GetUnits().GetFormatOptions(UnitType.UT_Length);
+            var ismmUnit= formatOptions.DisplayUnits == DisplayUnitType.DUT_MILLIMETERS;
+            unit = formatOptions.DisplayUnits.ToString();
+            if (!ismmUnit)
+            {
+                resultMsg = "单位异常,请修改长度单位为毫米(mm)";
+                resultState = ResultState.Failure;
+            }
+            else
+            {
+                resultState = ResultState.Success;
+            }
+
+            Content.Add(new UnitCheckResult() { Unit = unit, Result = resultState, ResultMsg = resultMsg });
+
+            #endregion
+        }
+    }
+}

+ 19 - 0
JBIM/ServiceDataCheck/DataCheck.Mode/UnitCheckResult.cs

@@ -0,0 +1,19 @@
+/* ==============================================================================
+ * 功能描述:SagaCheckResult  
+ * 创 建 者:Garrett
+ * 创建日期:2019/5/31 16:20:46
+ * ==============================================================================*/
+
+namespace ServiceRevitLib.Mode
+{
+    /// <summary>
+    /// SagaCheckResult
+    /// </summary>
+    class UnitCheckResult : ResultBase
+    {
+        /// <summary>
+        /// 项目单位
+        /// </summary>
+        public string Unit { get; set; }
+    }
+}

+ 33 - 0
JBIM/ServiceDataCheck/DocumentUtils.cs

@@ -0,0 +1,33 @@
+/* ==============================================================================
+ * 功能描述:DocumentUtils  
+ * 创 建 者:Garrett
+ * 创建日期:2019/5/31 17:06:30
+ * ==============================================================================*/
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Autodesk.Revit.DB;
+using SAGA.RevitUtils.Extends;
+
+namespace ServiceRevitLib
+{
+    /// <summary>
+    /// DocumentUtils
+    /// </summary>
+    class DocumentUtils
+    {
+        /// <summary>
+        /// 由路径获取Doc,
+        /// 获取Doc的方法可以更改,可用RevitNet
+        /// </summary>
+        /// <param name="filePath"></param>
+        /// <returns></returns>
+        public static Document GetDocument(string filePath)
+        {
+            
+            return ExternalDataWrapper.Current.App.OpenDocumentFile(filePath); ;
+        }
+    }
+}

+ 38 - 0
JBIM/ServiceDataCheck/Extend/DocExtend.cs

@@ -0,0 +1,38 @@
+/* ==============================================================================
+ * 功能描述:DocExtend  
+ * 创 建 者:Garrett
+ * 创建日期:2018/6/11 16:00:53
+ * ==============================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text.RegularExpressions;
+using Autodesk.Revit.DB;
+using SAGA.DotNetUtils;
+using SAGA.RevitUtils.Extends;
+using ServiceRevitLib.Common;
+
+namespace ServiceRevitLib.Extend
+{
+    /// <summary>
+    /// DocExtend
+    /// </summary>
+    public static class DocExtend
+    {
+        /// <summary>
+        /// 获取所有的Docment中,设备或者部件
+        /// </summary>
+        /// <param name="doc"></param>
+        /// <param name="bic"></param>
+        /// <returns></returns>
+        public static List<Element> GetEqEcElements(this Document doc)
+        {
+            List<Element> elements = new List<Element>();
+            //elements.AddRange(doc.GetElements(typeof(Wall)));
+            elements.AddRange(doc.GetElements(typeof(FamilyInstance)));
+            return elements.Where(t=>t.IsMbiEquipment()).ToList();
+        }
+    }
+}

+ 239 - 0
JBIM/ServiceDataCheck/Extend/ElementExtend.cs

@@ -0,0 +1,239 @@
+/* ==============================================================================
+ * 功能描述:ElementExtend  
+ * 创 建 者:Garrett
+ * 创建日期:2018/5/28 16:41:22
+ * ==============================================================================*/
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+using Autodesk.Revit.DB;
+using Autodesk.Revit.DB.Mechanical;
+using SAGA.DotNetUtils;
+using SAGA.DotNetUtils.Extend;
+using SAGA.RevitUtils.Extends;
+using ServiceRevitLib.Common;
+
+namespace ServiceRevitLib.Extend
+{
+    /// <summary>
+    /// ElementExtend
+    /// </summary>
+    public static class ElementExtend
+    {
+        /// <summary>
+        /// 判断是否为设备 设备族为4位
+        /// ATVR - 多联机 - 室内机 - 双向气流 - 天花板嵌入式
+        /// </summary>
+        /// <param name="fi"></param>
+        /// <returns></returns>
+        public static bool IsEquipment(this Element element)
+        {
+            bool result = false;
+            //if (element is Wall wall)
+            //{//添加幕墙识别
+            //    result = wall.WallType.Kind == WallKind.Curtain;
+
+            //}
+            //else
+            if (element is FamilyInstance fi)
+            {
+                var family = fi.GetFamilyName();
+                result = Regex.IsMatch(family, $"{RegexConstPattern.IsEquip}");
+            }
+
+            return result;
+        }
+        /// <summary>
+        /// 判断是否为设备部件 设备族为6位
+        /// </summary>
+        /// <param name="fi"></param>
+        /// <returns></returns>
+        public static bool IsEquipmentPart(this Element element)
+        {
+            bool result = false;
+            if (element is FamilyInstance fi)
+            {
+                var family = fi.GetFamilyName();
+                result = Regex.IsMatch(family, $"{RegexConstPattern.IsEquipPart}");
+            }
+
+            return result;
+        }
+        /// <summary>
+        /// 广义mbi设备包含设备和部件
+        /// </summary>
+        /// <param name="family"></param>
+        /// <returns></returns>
+        public static bool IsMbiEquipment(this Element element)
+        {
+            return element.IsEquipment()||element.IsEquipmentPart();
+        }
+        /// <summary>
+        /// 判断是否为信标
+        /// </summary>
+        /// <param name="elem"></param>
+        /// <returns></returns>
+        public static bool IsBeacon(this Element elem)
+        {
+            var family = elem.GetFamilyName();
+            return family != null && (Regex.IsMatch(family, RegexConstPattern.IsBeacon));
+        }
+
+        /// <summary>
+        /// 判断是否为空间,判断周长是否为零
+        /// 如果周长为零,是删除的空间
+        /// </summary>
+        /// <param name="elem"></param>
+        /// <param name="ischeckzero">是否检查周长为零</param>
+        /// <returns></returns>
+        public static bool IsSpace(this Element elem, bool ischeckzero = true)
+        {
+            var isspace = false;
+            if (elem is Space space)
+            {
+                //空间比较特殊,周长为零就相当于删除
+                isspace = !ischeckzero || !(space.IsDeleteSpace());
+                //限制所用空间的阶段
+                //isspace = isspace && space.IsPhase1Space();
+            }
+
+            return isspace;
+        }
+        /// <summary>
+        /// 获取MBI的定位点
+        /// </summary>
+        /// <param name="element"></param>
+        /// <returns></returns>
+        public static XYZ GetLocationPointMBIXYZ(this Element element)
+        {
+            ////定位点不可靠,未来可能会更改为Box的中心点
+            //XYZ bimXyz = element.GetLocationPoint();
+            //if (element is FamilyInstance fi)
+            //{
+            //    var family = fi.GetFamily();
+            //    if (family.IsInPlace)
+            //    {
+            //        bimXyz = fi.GetBoxCenter();
+            //    }
+            //}
+            //定位点改为Box中心点 
+            XYZ bimXyz = element.GetBoxCenter();
+
+            return bimXyz;
+        }
+        /// <summary>
+        /// 获取MBI存储的位置信息
+        /// </summary>
+        /// <returns></returns>
+        public static string GetLocationPointMBI(this Element element)
+        {
+            string str = ",,";
+            XYZ bimXyz = element.GetLocationPointMBIXYZ();
+            if (bimXyz != null)
+            {
+                str = bimXyz.FromApi().ToString(null);
+            };
+            //JObject jObject = new JObject();
+            //jObject.Add("X", bimXyz.X);
+            //jObject.Add("Y", bimXyz.Y);
+            //jObject.Add("Z", bimXyz.Z);
+            //return (new JArray(jObject)).ToString();
+            return str;
+        }
+        /// <summary>
+        /// 获取MBI存储的位置信息
+        /// </summary>
+        /// <returns></returns>
+        public static XYZ ToXyz(this string xyzstr)
+        {
+            XYZ xyz = null;
+            var strs = xyzstr.Split(',');
+            if (strs.Length == 3)
+            {
+                xyz = new XYZ(strs[0].ToDouble(), strs[1].ToDouble(), strs[2].ToDouble());
+            }
+            //JObject jObject = new JObject();
+            //jObject.Add("X", bimXyz.X);
+            //jObject.Add("Y", bimXyz.Y);
+            //jObject.Add("Z", bimXyz.Z);
+            //return (new JArray(jObject)).ToString();
+            return xyz;
+        }
+
+        /// <summary>
+        /// 获取设备的种族类型编码 ATFC
+        /// 族名称的命名规则:ATFC-风机盘管
+        /// </summary>
+        /// <returns></returns>
+        public static string GetFamilyCode(this Element element)
+        {          
+            string code = "";
+            if (element is FamilyInstance fi)
+            {
+                string familyName = fi.GetFamilyName();
+                if (familyName == null) return code;
+                //族名称的命名规则:ATFC-风机盘管
+                int index = familyName.IndexOf('-');
+                if (index != -1 && index + 1 != familyName.Length)
+                    code = familyName.Substring(0, familyName.IndexOf('-'));
+                //移除前面和后面的空格
+                code = code.Trim();
+            }
+
+            return code;
+        }
+
+        public static string GetFamilyName(this Element element)
+        {
+            return element.GetFamily()?.Name;
+        }
+        /// <summary>
+        /// 获取关联的空间
+        /// </summary>
+        /// <param name="fi"></param>
+        /// <returns></returns>
+        public static Space GetReferenceSpace(this Element element, List<Space> spaces = null)
+        {
+            Space space = null;
+            if (element is FamilyInstance fi)
+            {
+                space = fi.Space;
+                if (space != null) return space;
+                if (spaces == null)
+                    spaces = fi.Document.GetSpaces().Where(t => t.IsValidObject).ToList();
+                var origin1 = fi.GetLocationPointMBIXYZ();
+                foreach (Space tempSpace in spaces)
+                {
+                    //没有Space属性,取定位点,判断定位点所在空间
+                    if (tempSpace.IsPointInSpace(origin1))
+                    {
+                        space = tempSpace;
+                        break;
+                    }
+                }
+            }else if (element is Wall wall)
+            {
+                if (wall.IsCurtaiWall())
+                    space = null;
+            }
+
+            return space;
+        }
+
+        /// <summary>
+        /// 获取部件所关联的设备
+        /// </summary>
+        /// <param name="fi"></param>
+        /// <returns></returns>
+        public static Element GetPartParent(this Element element)
+        {
+            string code = element?.GetFamily().Name.Substring(0, 4); ;
+            if (code.IsNullOrEmpty()) return null;
+            //构件所关联的设备
+            var parentInst = element?.Document.GetElements(new ElementIntersectsElementFilter(element))
+                .FirstOrDefault(t => !t.Id.IsEqual(element.Id) && t.GetFamilyCode() == code);
+            return parentInst;
+        }
+    }
+}

+ 36 - 0
JBIM/ServiceDataCheck/Properties/AssemblyInfo.cs

@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("ServiceRevitLib")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ServiceRevitLib")]
+[assembly: AssemblyCopyright("Copyright ©  2019")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("7b748b09-dc20-4406-85a3-101e7833f8ce")]
+
+// 程序集的版本信息由下列四个值组成: 
+//
+//      主版本
+//      次版本
+//      生成号
+//      修订号
+//
+// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
+// 方法是按如下所示使用“*”: :
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 117 - 0
JBIM/ServiceDataCheck/ServiceDataCheck.csproj

@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{7B748B09-DC20-4406-85A3-101E7833F8CE}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <RootNamespace>ServiceRevitLib</RootNamespace>
+    <AssemblyName>ServiceRevitLib</AssemblyName>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\OutputDll\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\OutputDll\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup>
+    <StartupObject />
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
+      <HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
+    </Reference>
+    <Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+      <HintPath>..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
+    </Reference>
+    <Reference Include="NPOI, Version=2.2.1.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
+      <HintPath>..\packages\NPOI.2.2.1\lib\net40\NPOI.dll</HintPath>
+    </Reference>
+    <Reference Include="NPOI.OOXML, Version=2.2.1.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
+      <HintPath>..\packages\NPOI.2.2.1\lib\net40\NPOI.OOXML.dll</HintPath>
+    </Reference>
+    <Reference Include="NPOI.OpenXml4Net, Version=2.2.1.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
+      <HintPath>..\packages\NPOI.2.2.1\lib\net40\NPOI.OpenXml4Net.dll</HintPath>
+    </Reference>
+    <Reference Include="NPOI.OpenXmlFormats, Version=2.2.1.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
+      <HintPath>..\packages\NPOI.2.2.1\lib\net40\NPOI.OpenXmlFormats.dll</HintPath>
+    </Reference>
+    <Reference Include="RevitAPI">
+      <HintPath>..\Dlls\RevitAPI.dll</HintPath>
+    </Reference>
+    <Reference Include="SAGA.DotNetUtils">
+      <HintPath>..\Dlls\SAGA.DotNetUtils.dll</HintPath>
+    </Reference>
+    <Reference Include="SAGA.RevitUtils">
+      <HintPath>..\Dlls\SAGA.RevitUtils.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xml" />
+    <Reference Include="UIFramework">
+      <HintPath>E:\Program Files\Autodesk\Revit 2017\UIFramework.dll</HintPath>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="CheckFactory.cs" />
+    <Compile Include="Common\MBIConst.cs" />
+    <Compile Include="Common\RegexConstPattern.cs" />
+    <Compile Include="DocumentUtils.cs" />
+    <Compile Include="Extend\DocExtend.cs" />
+    <Compile Include="Extend\ElementExtend.cs" />
+    <Compile Include="DataCheck.Mode\CheckBase.cs" />
+    <Compile Include="DataCheck.Mode\EquipInSpaceCheck.cs" />
+    <Compile Include="DataCheck.Mode\SystemReferEquipCheck.cs" />
+    <Compile Include="DataCheck.Mode\ParameterIntegrityCheck.cs" />
+    <Compile Include="DataCheck.Mode\SystemNameCheck.cs" />
+    <Compile Include="DataCheck.Mode\EquipInSpaceCheckResult.cs" />
+    <Compile Include="DataCheck.Mode\SystemReferEquipCheckResult.cs" />
+    <Compile Include="DataCheck.Mode\ParameterIntegrityCheckResult.cs" />
+    <Compile Include="DataCheck.Mode\SystemNameCheckResult.cs" />
+    <Compile Include="DataCheck.Mode\ResultBase.cs" />
+    <Compile Include="DataCheck.Mode\ResultState.cs" />
+    <Compile Include="DataCheck.Mode\EquipPartLocationCheck.cs" />
+    <Compile Include="DataCheck.Mode\ColumnCheck.cs" />
+    <Compile Include="DataCheck.Mode\ElementRangeCheck.cs" />
+    <Compile Include="DataCheck.Mode\ConnectorCheck.cs" />
+    <Compile Include="DataCheck.Mode\FamilyNameCheck.cs" />
+    <Compile Include="DataCheck.Mode\EquipPartLocationCheckResult.cs" />
+    <Compile Include="DataCheck.Mode\ColumnCheckResult.cs" />
+    <Compile Include="DataCheck.Mode\ElementRangeCheckResult.cs" />
+    <Compile Include="DataCheck.Mode\ConnectorCheckResult.cs" />
+    <Compile Include="DataCheck.Mode\FamilyNameCheckResult.cs" />
+    <Compile Include="DataCheck.Mode\UnitCheck.cs" />
+    <Compile Include="DataCheck.Mode\SagaCheck.cs" />
+    <Compile Include="DataCheck.Mode\UnitCheckResult.cs" />
+    <Compile Include="DataCheck.Mode\SagaCheckResult.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="TestCommand.cs" />
+    <Compile Include="Utils\DataCheckRule.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>

+ 42 - 0
JBIM/ServiceDataCheck/TestCommand.cs

@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using Autodesk.Revit.Attributes;
+using Autodesk.Revit.DB;
+using Autodesk.Revit.UI;
+using Newtonsoft.Json;
+using SAGA.DotNetUtils.Data;
+using SAGA.DotNetUtils.Geometry;
+using SAGA.RevitUtils;
+using SAGA.RevitUtils.Extends;
+
+namespace ServiceRevitLib
+{
+    #region 测试命令
+
+    public class ServiceDataCheckTest
+    {
+        public static void Check(Document doc)
+        {
+            try
+            {
+                var factory = new CheckFactory();
+                factory.SetCheckItems("SagaCheck,UnitCheck,FamilyNameCheck,EquipPartLocationCheck,ColumnCheck,ElementRangeCheck,ConnectorCheck,SystemNameCheck,EquipInSpaceCheck,SystemReferEquipCheck,ParameterIntegrityCheck");
+                factory.Check(doc);
+                var result = JsonConvert.SerializeObject(factory);
+                string fileName = DateTime.Now.ToString("yyyyMMddHHmmss");
+                string path = Path.Combine(@"D:\", $"DataCheck{fileName}.json");
+                File.WriteAllText(path, result);
+                //System.Diagnostics.Process.Start("notepad.exe", path);
+            }
+            catch (Exception e)
+            {
+            }
+        }
+    }
+   
+
+    #endregion
+}

+ 166 - 0
JBIM/ServiceDataCheck/Utils/DataCheckRule.cs

@@ -0,0 +1,166 @@
+/* ==============================================================================
+ * 功能描述:数据检查规范
+ * 创 建 者:Garrett
+ * 创建日期:2018/11/7 15:40:23
+ * ==============================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text.RegularExpressions;
+using SAGA.DotNetUtils;
+using SAGA.DotNetUtils.NPOI;
+using ServiceRevitLib.Common;
+
+namespace ServiceRevitLib.Utils
+{
+    /// <summary>
+    /// DataCheckRule
+    /// </summary>
+    class DataCheckRule
+    {
+        public static string MCRPath = Path.Combine(MBIConst.MBIResourcePath, @"DataCheck\模型检查结果输出格式-模版.xlsx");
+        /// <summary>
+        /// 获取设备编码检查Cateogry 列表
+        /// </summary>
+        /// <returns></returns>
+        public static List<DCR_CodeCheckCategory> GetCodeCheckCategories()
+        {
+            var list = NPOIHelper
+                .ConvertExcelSheetToModel<DCR_CodeCheckCategory>(MCRPath);
+            return list;
+        }
+
+        /// <summary>
+        /// 获取预定义的连接件类
+        /// </summary>
+        /// <returns></returns>
+        public static List<DCR_Connector> GetPreDefineConnectors()
+        {
+            var list = NPOIHelper
+                .ConvertExcelSheetToModel<DCR_Connector>(MCRPath);
+            return list;
+        }
+
+        /// <summary>
+        /// 获取可识别的管道系统名称
+        /// </summary>
+        /// <returns></returns>
+        public static List<DCR_MEPSystem> GetMepSystems()
+        {
+            var list = NPOIHelper
+                .ConvertExcelSheetToModel<DCR_MEPSystem>(MCRPath);
+            return list;
+        }
+        /// <summary>
+        /// 获取设备关联的系统类型
+        /// </summary>
+        /// <returns></returns>
+        public static List<DCR_EquipReferSystem> GetEquipReferSystems()
+        {
+            var list = NPOIHelper
+                .ConvertExcelSheetToModel<DCR_SystemReferEquip>(MCRPath);
+            List<Tuple<string, string>> tuples = new List<Tuple<string, string>>();
+            //将集合转化为:系统名称-设备名称
+            list.ForEach(t => t.Equips.ForEach(tt => tuples.Add(new Tuple<string, string>(t.SystemName, tt))));
+            //将集合转化为:设备名称-多个系统名称
+            var newList = tuples.GroupBy(t => t.Item2).Select(tt => new DCR_EquipReferSystem()
+            { EquipName = tt.Key, Systems = tt.Select(t => t.Item1).ToList() }).ToList();
+            return newList;
+        }
+    }
+    /// <summary>
+    /// 参考-可识别的系统名称
+    /// </summary>
+    [SheetInfo(SheetName = "参考-可识别的系统名称", RowStartIndex = 0)]
+    public class DCR_MEPSystem
+    {
+        [CellIndex(0)]
+        public string Name { get; set; }
+    }
+    /// <summary>
+    /// 参考-revit分类
+    /// </summary>
+    [SheetInfo(SheetName = "参考-revit分类", RowStartIndex = 0)]
+    public class DCR_CodeCheckCategory
+    {
+        [CellIndex(0)]
+        public string Name { get; set; }
+    }
+    /// <summary>
+    /// 设备类是否有连接件
+    /// </summary>
+    [SheetInfo(SheetName = "参考-连接件对照表", RowStartIndex = 1)]
+    public class DCR_Connector
+    {
+        [CellIndex(4)]
+        public string Name { get; set; }
+
+        [CellIndex(5)]
+        public string Code { get; set; }
+
+        [CellIndex(6)]
+        public string PName { get; set; }
+
+        [CellIndex(7)]
+        public string PCode { get; set; }
+
+        [CellIndex(8)]
+        public string HvacConnector { get; set; }
+
+        [CellIndex(9)]
+        public string PipeConnector { get; set; }
+    }
+    /// <summary>
+    /// 参考-管网与相关设备
+    /// </summary>
+    [SheetInfo(SheetName = "参考-管网及相关设备", RowStartIndex = 3)]
+    public class DCR_SystemReferEquip
+    {
+        [CellIndex(3)]
+        public string SystemName { get; set; }
+        [CellIndex(4)]
+        public string ReferEquipName { get; set; }
+
+        private List<string> m_Equips;
+
+        public List<string> Equips
+        {
+            get
+            {
+                if (m_Equips == null)
+                    m_Equips = ConverToList(ReferEquipName);
+                return m_Equips;
+            }
+        }
+
+        public List<string> ConverToList(string str)
+        {
+            var list = new List<string>();
+            if (str.IsNotNullEmpty())
+            {
+                Regex regex = new Regex(@"^[A-Z]{4}");
+                list = str.Split(new[] { ',', ',' })
+                    .Where(t => Regex.IsMatch(t, $"{RegexConstPattern.IsEquip}"))
+                    .Select(tt => regex.Match(tt).Value).ToList();
+            }
+
+            return list;
+        }
+    }
+    /// <summary>
+    /// 设备关联的系统
+    /// </summary>
+    public class DCR_EquipReferSystem
+    {
+        /// <summary>
+        /// 设备名称
+        /// </summary>
+        public string EquipName { get; set; }
+        /// <summary>
+        /// 系统名称
+        /// </summary>
+        public List<string> Systems { get; set; }
+    }
+}

+ 6 - 0
JBIM/ServiceDataCheck/packages.config

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="Newtonsoft.Json" version="10.0.2" targetFramework="net461" />
+  <package id="NPOI" version="2.2.1" targetFramework="net461" />
+  <package id="SharpZipLib" version="0.86.0" targetFramework="net461" />
+</packages>