339 lines
10 KiB
C#
339 lines
10 KiB
C#
|
|
using Autodesk.Revit;
|
|||
|
|
using Autodesk.Revit.ApplicationServices;
|
|||
|
|
using Autodesk.Revit.DB;
|
|||
|
|
using Autodesk.Revit.Utility;
|
|||
|
|
using Autodesk.RevitAddIns;
|
|||
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.IO;
|
|||
|
|
using System.Linq;
|
|||
|
|
using System.Reflection;
|
|||
|
|
using System.Text;
|
|||
|
|
using System.Threading.Tasks;
|
|||
|
|
|
|||
|
|
namespace DotNet.Revit.NET
|
|||
|
|
{
|
|||
|
|
public class Program
|
|||
|
|
{
|
|||
|
|
static readonly string WorkPath = Path.GetDirectoryName(typeof(Program).Assembly.Location);
|
|||
|
|
|
|||
|
|
static Program()
|
|||
|
|
{
|
|||
|
|
RevitCoreContext.Instance.Run();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Revit 内核必须加 STAThread 标签
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="args"></param>
|
|||
|
|
|
|||
|
|
[STAThread]
|
|||
|
|
static void Main(string[] args)
|
|||
|
|
{
|
|||
|
|
var app = RevitCoreContext.Instance.Application;
|
|||
|
|
|
|||
|
|
// Todo ...
|
|||
|
|
|
|||
|
|
var projectrTemplate = app.DefaultProjectTemplate;
|
|||
|
|
|
|||
|
|
if (!File.Exists(projectrTemplate))
|
|||
|
|
{
|
|||
|
|
throw new FileNotFoundException("默认项目路径不存在 , 请指定 !");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var document = app.NewProjectDocument(projectrTemplate);
|
|||
|
|
|
|||
|
|
if (document == null)
|
|||
|
|
{
|
|||
|
|
throw new InvalidOperationException();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// create wall demo ...
|
|||
|
|
|
|||
|
|
var p1 = XYZ.Zero;
|
|||
|
|
|
|||
|
|
var p2 = p1 + XYZ.BasisX * 10;
|
|||
|
|
|
|||
|
|
var p3 = p2 + XYZ.BasisY * 10;
|
|||
|
|
|
|||
|
|
var p4 = p1 + XYZ.BasisY * 10;
|
|||
|
|
|
|||
|
|
var points = new XYZ[] { p1, p2, p3, p4 };
|
|||
|
|
|
|||
|
|
document.Invoke(m =>
|
|||
|
|
{
|
|||
|
|
var level0 = document.QueryByType<Level>().OfType<Level>().FirstOrDefault(x => Math.Abs(x.Elevation - 0.0) <= 1e-7);
|
|||
|
|
|
|||
|
|
if (level0 == null)
|
|||
|
|
{
|
|||
|
|
level0 = Level.Create(document, 0);
|
|||
|
|
|
|||
|
|
document.Regenerate();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (int i = 0; i < points.Length; i++)
|
|||
|
|
{
|
|||
|
|
var a = points[i];
|
|||
|
|
|
|||
|
|
var b = i == points.Length - 1 ? points[0] : points[i + 1];
|
|||
|
|
|
|||
|
|
Wall.Create(document, Line.CreateBound(a, b), level0.Id, false);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
document.SaveAs(Path.Combine(WorkPath, "demowall.rvt"), new SaveAsOptions() { OverwriteExistingFile = true });
|
|||
|
|
|
|||
|
|
RevitCoreContext.Instance.Stop();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public class RevitCoreContext
|
|||
|
|
{
|
|||
|
|
// 此路径为动态反射搜索路径 、 此路径可为任意路径(只要路径下有RevitNET 所需依赖项即可,完整依赖项可在 Naviswork 2016 下面找到)
|
|||
|
|
|
|||
|
|
static readonly string[] Searchs = RevitProductUtility.GetAllInstalledRevitProducts().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))
|
|||
|
|
{
|
|||
|
|
return Assembly.LoadFile(file);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return args.RequestingAssembly;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
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));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|