2024-09-22 11:05:41 +08:00
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
using System.Windows;
|
|
|
|
|
|
using Autodesk.Revit.DB;
|
|
|
|
|
|
using Autodesk.Revit.DB.Visual;
|
|
|
|
|
|
using Autodesk.Revit.UI;
|
2025-02-10 20:53:40 +08:00
|
|
|
|
using ShrlAlgo.Toolkit.Revit.Helpers;
|
2024-09-22 11:05:41 +08:00
|
|
|
|
|
2025-02-10 20:53:40 +08:00
|
|
|
|
namespace ShrlAlgo.Toolkit.Revit.Assist;
|
2024-09-22 11:05:41 +08:00
|
|
|
|
|
|
|
|
|
|
public static class DocumentAssist
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 轴网标注
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="doc"></param>
|
|
|
|
|
|
/// <param name="chainDimensionLine"></param>
|
|
|
|
|
|
/// <param name="extremeWallVariant"></param>
|
|
|
|
|
|
/// <param name="grids"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static Dimension CreateDimensionByExtremeGrids(
|
|
|
|
|
|
this Document doc,
|
|
|
|
|
|
Line chainDimensionLine,
|
|
|
|
|
|
ExtremeWallVariant extremeWallVariant,
|
|
|
|
|
|
List<Grid> grids
|
|
|
|
|
|
)
|
|
|
|
|
|
{
|
|
|
|
|
|
Dimension result;
|
|
|
|
|
|
if (!grids.Any())
|
|
|
|
|
|
{
|
|
|
|
|
|
result = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Dimension dimension = null;
|
|
|
|
|
|
ReferenceArray referenceArray = new();
|
|
|
|
|
|
if (extremeWallVariant is ExtremeWallVariant.Left or ExtremeWallVariant.Right)
|
|
|
|
|
|
{
|
|
|
|
|
|
var list = (
|
|
|
|
|
|
from g in grids
|
|
|
|
|
|
where ((Line)g.Curve).Direction.DotProduct(XYZ.BasisY) < 0.0001
|
|
|
|
|
|
select g
|
|
|
|
|
|
).ToList();
|
|
|
|
|
|
if (list.Any())
|
|
|
|
|
|
{
|
|
|
|
|
|
list.Sort((g1, g2) => g1.Curve.GetEndPoint(0).Y.CompareTo(g2.Curve.GetEndPoint(0).Y));
|
|
|
|
|
|
List<Grid> list2 = [list.First(), list.Last()];
|
|
|
|
|
|
foreach (var grid in list2)
|
|
|
|
|
|
{
|
|
|
|
|
|
referenceArray.Append(new Reference(grid));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
var list3 = (
|
|
|
|
|
|
from g in grids
|
|
|
|
|
|
where ((Line)g.Curve).Direction.DotProduct(XYZ.BasisX) < 0.0001
|
|
|
|
|
|
select g
|
|
|
|
|
|
).ToList();
|
|
|
|
|
|
if (list3.Any())
|
|
|
|
|
|
{
|
|
|
|
|
|
list3.Sort((g1, g2) => g1.Curve.GetEndPoint(0).X.CompareTo(g2.Curve.GetEndPoint(0).X));
|
|
|
|
|
|
List<Grid> list4 = [list3.First(), list3.Last()];
|
|
|
|
|
|
foreach (var grid2 in list4)
|
|
|
|
|
|
{
|
|
|
|
|
|
referenceArray.Append(new Reference(grid2));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!referenceArray.IsEmpty && referenceArray.Size > 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
dimension = doc.Create.NewDimension(doc.ActiveView, chainDimensionLine, referenceArray);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
result = dimension;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取所有可预览视图ID
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <typeparam name="T"></typeparam>
|
|
|
|
|
|
/// <param name="doc"></param>
|
|
|
|
|
|
/// <param name="setting"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static ElementId FindPreviewId<T>(this Document doc, DocumentPreviewSettings setting) where T : View
|
|
|
|
|
|
{
|
|
|
|
|
|
var collector = new FilteredElementCollector(doc).OfClass(typeof(T));
|
|
|
|
|
|
if (!collector.Any())
|
|
|
|
|
|
{
|
|
|
|
|
|
return new FilteredElementCollector(doc).OfClass(typeof(ViewPlan)).FirstElementId();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var viewForPreview = collector.OfType<T>().First(v => setting.IsViewIdValidForPreview(v.Id));
|
|
|
|
|
|
return viewForPreview.Id;
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取标高范围框
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <remarks>最低标高除了包含以上部分,还包含以下部分,最高标高包含以上部分</remarks>
|
|
|
|
|
|
/// <param name="doc"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static Dictionary<Level, Outline> GetLevelRanges(this Document doc)
|
|
|
|
|
|
{
|
|
|
|
|
|
var levels = doc.OfClass<Level>().Cast<Level>().OrderBy(l => l.Elevation).ToList();
|
|
|
|
|
|
Dictionary<Level, Outline> levelOutlines = [];
|
|
|
|
|
|
//获取标高范围
|
|
|
|
|
|
for (var i = 0; i < levels.Count; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
var baseLevel = levels[i];
|
|
|
|
|
|
XYZ min = new(double.MinValue, double.MinValue, baseLevel.Elevation);
|
|
|
|
|
|
XYZ max;
|
|
|
|
|
|
Outline outline;
|
|
|
|
|
|
if (i == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
min = new XYZ(double.MinValue, double.MinValue, double.MinValue);
|
|
|
|
|
|
var topLevel = levels[i + 1];
|
|
|
|
|
|
max = new XYZ(double.MaxValue, double.MaxValue, topLevel.Elevation);
|
|
|
|
|
|
outline = new Outline(min, max);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (i < levels.Count - 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
var topLevel = levels[i + 1];
|
|
|
|
|
|
max = new XYZ(double.MaxValue, double.MaxValue, topLevel.Elevation);
|
|
|
|
|
|
outline = new Outline(min, max);
|
|
|
|
|
|
}
|
|
|
|
|
|
else//最后一个标高以上
|
|
|
|
|
|
{
|
|
|
|
|
|
max = new XYZ(double.MaxValue, double.MaxValue, double.MaxValue);
|
|
|
|
|
|
outline = new Outline(min, max);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
levelOutlines.Add(baseLevel, outline);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return levelOutlines;
|
|
|
|
|
|
}
|
|
|
|
|
|
public static Dimension CreateDimensionByOverallWalls(
|
|
|
|
|
|
this Document doc,
|
|
|
|
|
|
Line chainDimensionLine,
|
|
|
|
|
|
IReadOnlyCollection<Wall> sideWalls,
|
|
|
|
|
|
ExtremeWallVariant extremeWallVariant
|
|
|
|
|
|
)
|
|
|
|
|
|
{
|
|
|
|
|
|
Dimension dimension = null;
|
|
|
|
|
|
var list = sideWalls.Where(w => w.Orientation.DotProduct(XYZ.BasisX) < 0.0001).ToList();
|
|
|
|
|
|
var list2 = sideWalls.Where(w => w.Orientation.DotProduct(XYZ.BasisY) < 0.0001).ToList();
|
|
|
|
|
|
|
|
|
|
|
|
Dimension result;
|
|
|
|
|
|
if (!list.Any() && !list2.Any())
|
|
|
|
|
|
{
|
|
|
|
|
|
result = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
ReferenceArray referenceArray = new();
|
|
|
|
|
|
if (extremeWallVariant is ExtremeWallVariant.Right or ExtremeWallVariant.Left)
|
|
|
|
|
|
{
|
|
|
|
|
|
List<PlanarFace> list3 = [];
|
|
|
|
|
|
foreach (var wall in list)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var planarFace in wall.GetFaces())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (planarFace.IsHorizontal())
|
|
|
|
|
|
{
|
|
|
|
|
|
list3.Add(planarFace);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var elementArray = ((LocationCurve)wall.Location).get_ElementsAtJoin(0);
|
|
|
|
|
|
var elementArray2 = ((LocationCurve)wall.Location).get_ElementsAtJoin(1);
|
|
|
|
|
|
List<Wall> list4 = [];
|
|
|
|
|
|
foreach (Element element in elementArray)
|
|
|
|
|
|
{
|
|
|
|
|
|
var wallFromListById = (from w in list where w.Id == element.Id select w).First();
|
|
|
|
|
|
if (wallFromListById != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
list4.Add(wallFromListById);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (Element element2 in elementArray2)
|
|
|
|
|
|
{
|
|
|
|
|
|
var wallFromListById2 = (from w in list where w.Id == element2.Id select w).First();
|
|
|
|
|
|
if (wallFromListById2 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
list4.Add(wallFromListById2);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var wall2 in list4)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var planarFace2 in wall2.GetFaces())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (planarFace2.IsHorizontal())
|
|
|
|
|
|
{
|
|
|
|
|
|
list3.Add(planarFace2);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
list3.Sort((f1, f2) => f1.GetMinY().CompareTo(f2.GetMinY()));
|
|
|
|
|
|
referenceArray.Append(list3.First().Reference);
|
|
|
|
|
|
referenceArray.Append(list3.Last().Reference);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (extremeWallVariant is ExtremeWallVariant.Top or ExtremeWallVariant.Bottom)
|
|
|
|
|
|
{
|
|
|
|
|
|
List<PlanarFace> list5 = [];
|
|
|
|
|
|
foreach (var wall3 in list2)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var planarFace3 in wall3.GetFaces())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (planarFace3.IsVertical())
|
|
|
|
|
|
{
|
|
|
|
|
|
list5.Add(planarFace3);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var elementArray3 = ((LocationCurve)wall3.Location).get_ElementsAtJoin(0);
|
|
|
|
|
|
var elementArray4 = ((LocationCurve)wall3.Location).get_ElementsAtJoin(1);
|
|
|
|
|
|
List<Wall> list6 = [];
|
|
|
|
|
|
foreach (Element element3 in elementArray3)
|
|
|
|
|
|
{
|
|
|
|
|
|
var wallFromListById3 = (from w in list where w.Id == element3.Id select w).First();
|
|
|
|
|
|
if (wallFromListById3 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
list6.Add(wallFromListById3);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (Element element4 in elementArray4)
|
|
|
|
|
|
{
|
|
|
|
|
|
var wallFromListById4 = (from w in list where w.Id == element4.Id select w).First();
|
|
|
|
|
|
if (wallFromListById4 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
list6.Add(wallFromListById4);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var wall4 in list6)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var planarFace4 in wall4.GetFaces())
|
|
|
|
|
|
{
|
|
|
|
|
|
var isVertical2 = planarFace4.IsVertical();
|
|
|
|
|
|
if (isVertical2)
|
|
|
|
|
|
{
|
|
|
|
|
|
list5.Add(planarFace4);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
list5.Sort((f1, f2) => f1.GetMinX().CompareTo(f2.GetMinX()));
|
|
|
|
|
|
referenceArray.Append(list5[0].Reference);
|
|
|
|
|
|
referenceArray.Append(list5.Last().Reference);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!referenceArray.IsEmpty)
|
|
|
|
|
|
{
|
|
|
|
|
|
doc.Invoke(_ =>
|
|
|
|
|
|
{
|
|
|
|
|
|
dimension = doc.Create.NewDimension(doc.ActiveView, chainDimensionLine, referenceArray);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
result = dimension;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 创建房间
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="doc"></param>
|
|
|
|
|
|
/// <param name="level"></param>
|
|
|
|
|
|
/// <param name="phase"></param>
|
|
|
|
|
|
public static void CreateRoom(this Document doc, Level level, Phase phase)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 获取基于标高level的一个视图
|
|
|
|
|
|
var defaultView = new FilteredElementCollector(doc)
|
|
|
|
|
|
.OfClass(typeof(View))
|
|
|
|
|
|
.Cast<View>()
|
|
|
|
|
|
.FirstOrDefault(v => v.GenLevel != null && v.GenLevel.Id == level.Id);
|
|
|
|
|
|
// 确保视图不为空
|
|
|
|
|
|
if (defaultView != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var defaultPhase = defaultView.get_Parameter(BuiltInParameter.VIEW_PHASE);
|
|
|
|
|
|
if (defaultPhase != null && defaultPhase.AsElementId() == phase.Id)
|
|
|
|
|
|
{
|
|
|
|
|
|
var circuits = doc.get_PlanTopology(level, phase).Circuits;
|
|
|
|
|
|
foreach (PlanCircuit planCircuit in circuits)
|
|
|
|
|
|
{
|
|
|
|
|
|
doc.Create.NewRoom(null, planCircuit);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 创建表格
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="doc"></param>
|
|
|
|
|
|
/// <param name="legend"></param>
|
|
|
|
|
|
/// <param name="rowCount"></param>
|
|
|
|
|
|
/// <param name="columnCount"></param>
|
|
|
|
|
|
/// <param name="gridWidth"></param>
|
|
|
|
|
|
/// <param name="gridHeight"></param>
|
|
|
|
|
|
public static void CreateTable(
|
|
|
|
|
|
this Document doc,
|
|
|
|
|
|
View legend,
|
|
|
|
|
|
int rowCount,
|
|
|
|
|
|
int columnCount,
|
|
|
|
|
|
double gridWidth,
|
|
|
|
|
|
double gridHeight
|
|
|
|
|
|
)
|
|
|
|
|
|
{
|
|
|
|
|
|
CurveArray curveArray = new();
|
|
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i <= rowCount; i++) //水平网格
|
|
|
|
|
|
{
|
|
|
|
|
|
var l = Line.CreateBound(XYZ.Zero, XYZ.BasisX * gridWidth * columnCount)
|
|
|
|
|
|
.CreateOffset(gridHeight * i, -XYZ.BasisZ);
|
|
|
|
|
|
curveArray.Append(l);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Curve line = Line.CreateBound(XYZ.Zero, XYZ.BasisY * rowCount * gridHeight);
|
|
|
|
|
|
curveArray.Append(line);
|
|
|
|
|
|
for (var i = 0; i <= columnCount; i++) //垂直网格
|
|
|
|
|
|
{
|
|
|
|
|
|
line = line.CreateOffset(gridWidth, XYZ.BasisZ);
|
|
|
|
|
|
curveArray.Append(line);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
doc.Create.NewDetailCurveArray(legend, curveArray);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 创建表格
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="doc"></param>
|
|
|
|
|
|
/// <param name="legend">图例视图</param>
|
|
|
|
|
|
/// <param name="rowCount">行数</param>
|
|
|
|
|
|
/// <param name="columnCount">列数</param>
|
|
|
|
|
|
/// <param name="gridHeight">单元格高度</param>
|
|
|
|
|
|
/// <param name="gridWidths">各列对应的宽度</param>
|
|
|
|
|
|
public static void CreateTable(
|
|
|
|
|
|
this Document doc,
|
|
|
|
|
|
View legend,
|
|
|
|
|
|
int rowCount,
|
|
|
|
|
|
int columnCount,
|
|
|
|
|
|
double gridHeight,
|
|
|
|
|
|
params double[] gridWidths
|
|
|
|
|
|
)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (columnCount != gridWidths.Length)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CurveArray curveArray = new();
|
|
|
|
|
|
var totalWidth = 0.0;
|
|
|
|
|
|
foreach (var w in gridWidths)
|
|
|
|
|
|
{
|
|
|
|
|
|
totalWidth += w;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i <= rowCount; i++) //水平网格
|
|
|
|
|
|
{
|
|
|
|
|
|
var c = Line.CreateBound(XYZ.Zero, XYZ.BasisX * totalWidth).CreateOffset(gridHeight * i, -XYZ.BasisZ);
|
|
|
|
|
|
curveArray.Append(c);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Curve line = Line.CreateBound(XYZ.Zero, XYZ.BasisY * rowCount * gridHeight);
|
|
|
|
|
|
curveArray.Append(line);
|
|
|
|
|
|
for (var i = 0; i < columnCount; i++) //垂直网格
|
|
|
|
|
|
{
|
|
|
|
|
|
line = line.CreateOffset(gridWidths[i], XYZ.BasisZ);
|
|
|
|
|
|
curveArray.Append(line);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
doc.Create.NewDetailCurveArray(legend, curveArray);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 创建表格
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="legend">图例视图</param>
|
|
|
|
|
|
/// <param name="rowCount">行数(含标题行)</param>
|
|
|
|
|
|
/// <param name="columnCount">列数</param>
|
|
|
|
|
|
/// <param name="headHeight"></param>
|
|
|
|
|
|
/// <param name="gridHeight">单元格高度</param>
|
|
|
|
|
|
/// <param name="gridWidths">各单元格对应的宽度</param>
|
|
|
|
|
|
public static void CreateTable(
|
|
|
|
|
|
View legend,
|
|
|
|
|
|
int rowCount,
|
|
|
|
|
|
int columnCount,
|
|
|
|
|
|
double headHeight,
|
|
|
|
|
|
double gridHeight,
|
|
|
|
|
|
params double[] gridWidths
|
|
|
|
|
|
)
|
|
|
|
|
|
{
|
|
|
|
|
|
var doc = legend.Document;
|
|
|
|
|
|
if (columnCount != gridWidths.Length)
|
|
|
|
|
|
{
|
|
|
|
|
|
MessageBox.Show("列数和提供的列宽数量不一致。", "提示");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CurveArray curveArray = new();
|
|
|
|
|
|
var totalWidth = 0.0;
|
|
|
|
|
|
foreach (var w in gridWidths)
|
|
|
|
|
|
{
|
|
|
|
|
|
totalWidth += w;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i <= rowCount - 1; i++) //水平网格
|
|
|
|
|
|
{
|
|
|
|
|
|
var c = Line.CreateBound(XYZ.Zero, XYZ.BasisX * totalWidth).CreateOffset(gridHeight * i, -XYZ.BasisZ);
|
|
|
|
|
|
curveArray.Append(c);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//标题行
|
|
|
|
|
|
var line = Line.CreateBound(XYZ.Zero, XYZ.BasisX * totalWidth)
|
|
|
|
|
|
.CreateOffset((gridHeight * (rowCount - 1)) + headHeight, -XYZ.BasisZ);
|
|
|
|
|
|
curveArray.Append(line);
|
|
|
|
|
|
//列
|
|
|
|
|
|
line = Line.CreateBound(XYZ.Zero, XYZ.BasisY * (((rowCount - 1) * gridHeight) + headHeight));
|
|
|
|
|
|
curveArray.Append(line);
|
|
|
|
|
|
for (var i = 0; i < columnCount; i++) //垂直网格
|
|
|
|
|
|
{
|
|
|
|
|
|
line = line.CreateOffset(gridWidths[i], XYZ.BasisZ);
|
|
|
|
|
|
curveArray.Append(line);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
doc.Create.NewDetailCurveArray(legend, curveArray);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static void CreateTag(this Document doc, List<Reference> references, TagMode tagMode, bool hasLeader)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var refer in references)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
IndependentTag.Create(
|
|
|
|
|
|
doc,
|
|
|
|
|
|
doc.ActiveView.Id,
|
|
|
|
|
|
refer,
|
|
|
|
|
|
hasLeader,
|
|
|
|
|
|
tagMode,
|
|
|
|
|
|
TagOrientation.Horizontal,
|
|
|
|
|
|
new XYZ(0, 0, 0)
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch
|
|
|
|
|
|
{
|
|
|
|
|
|
// ignored
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static void DeleteFamilyType(this Document famdoc)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 得到FamilyManager
|
|
|
|
|
|
var familyMgr = famdoc.FamilyManager;
|
|
|
|
|
|
if (familyMgr.CurrentType != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 只有当前族类型存在,我们才能调用下面的删除方法
|
|
|
|
|
|
familyMgr.DeleteCurrentType();
|
|
|
|
|
|
// 一般来说,当删除结束后,第一个族类型会成为当前类型,
|
|
|
|
|
|
// 但是为了确保安全, 建议你显式设置成你需要的类型
|
|
|
|
|
|
if (familyMgr.Types.Size != 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
var type = familyMgr.Types.Cast<FamilyType>().ElementAt(0);
|
|
|
|
|
|
familyMgr.CurrentType = type;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 删除定位点重合的族实例
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="doc"></param>
|
|
|
|
|
|
/// <param name="cardInstances"></param>
|
|
|
|
|
|
public static void DeleteOverlapInstance(this Document doc, List<FamilyInstance> cardInstances)
|
|
|
|
|
|
{
|
|
|
|
|
|
List<ElementId> idsToDelete = [];
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var ins in cardInstances)
|
|
|
|
|
|
{
|
|
|
|
|
|
var lp = ins.GetLocXYZ();
|
|
|
|
|
|
foreach (var card in cardInstances)
|
|
|
|
|
|
{
|
|
|
|
|
|
var lpt = card.GetLocXYZ();
|
|
|
|
|
|
if (!card.Id.Equals(ins.Id) && lp.IsAlmostEqualTo(lpt))
|
|
|
|
|
|
{
|
|
|
|
|
|
idsToDelete.Add(ins.Id);
|
|
|
|
|
|
idsToDelete.Add(card.Id);
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
doc.Delete(idsToDelete);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 复制图例
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="doc"></param>
|
|
|
|
|
|
/// <param name="legendName"></param>
|
|
|
|
|
|
/// <param name="viewScale">比例</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static View DuplicateLegend(Document doc, string legendName, int viewScale)
|
|
|
|
|
|
{
|
|
|
|
|
|
var legends = doc.OfClass<View>()
|
|
|
|
|
|
.OfCategory(BuiltInCategory.OST_Views)
|
|
|
|
|
|
.Cast<View>()
|
|
|
|
|
|
.Where(v => v.ViewType == ViewType.Legend)
|
|
|
|
|
|
.ToList();
|
|
|
|
|
|
|
|
|
|
|
|
if (!legends.Any())
|
|
|
|
|
|
{
|
|
|
|
|
|
MessageBox.Show("当前项目中没有图例", "温馨提示");
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var legendToCopy = legends.FirstOrDefault();
|
|
|
|
|
|
|
|
|
|
|
|
var newLegendId = legendToCopy?.Duplicate(ViewDuplicateOption.Duplicate);
|
|
|
|
|
|
var newLegend = doc.GetElement(newLegendId) as View;
|
|
|
|
|
|
for (var i = 0; i < 100; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
newLegend!.Name = $"{legendName} {i}";
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Autodesk.Revit.Exceptions.ArgumentException) { }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
newLegend!.Scale = viewScale;
|
|
|
|
|
|
return newLegend;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 翻转工作平面
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="doc"></param>
|
|
|
|
|
|
/// <param name="id"></param>
|
|
|
|
|
|
public static void FlipWorkPlane(this Document doc, ElementId id)
|
|
|
|
|
|
{
|
|
|
|
|
|
var fi = (FamilyInstance)doc.GetElement(id);
|
|
|
|
|
|
if (fi != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
fi.IsWorkPlaneFlipped = !fi.IsWorkPlaneFlipped;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static FamilySymbol GetAndActiveDefaultFamilySymbol(this Document doc, string rfaFile)
|
|
|
|
|
|
{
|
|
|
|
|
|
var family = GetOrLoadedFamily(doc, rfaFile);
|
|
|
|
|
|
FamilySymbol symbol = null;
|
|
|
|
|
|
if (family != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var symbolId = family.GetFamilySymbolIds().FirstOrDefault();
|
|
|
|
|
|
symbol = doc.GetElement(symbolId) as FamilySymbol;
|
|
|
|
|
|
Debug.Assert(symbol != null, nameof(symbol) + " != null");
|
|
|
|
|
|
if (!symbol.IsActive)
|
|
|
|
|
|
{
|
|
|
|
|
|
symbol.Activate();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return symbol;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取族中的元素
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="famdoc"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static List<ElementId> GetFamilySolidForm(this Document famdoc)
|
|
|
|
|
|
{
|
|
|
|
|
|
var ids = new List<ElementId>();
|
|
|
|
|
|
if (famdoc.IsFamilyDocument)
|
|
|
|
|
|
{
|
|
|
|
|
|
var solids = new FilteredElementCollector(famdoc)
|
|
|
|
|
|
.OfClass(typeof(GenericForm))
|
|
|
|
|
|
.Cast<GenericForm>()
|
|
|
|
|
|
.Where(x => x.IsSolid)
|
|
|
|
|
|
.Select(y => y.Id);
|
|
|
|
|
|
|
|
|
|
|
|
var fiids = new FilteredElementCollector(famdoc).OfClass(typeof(FamilyInstance)).Select(y => y.Id);
|
|
|
|
|
|
ids.AddRange(solids);
|
|
|
|
|
|
ids.AddRange(fiids);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return ids;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 填充样式
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="doc"></param>
|
|
|
|
|
|
/// <param name="patternName"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static ElementId GetFillPatternElemId(this Document doc, string patternName)
|
|
|
|
|
|
{
|
|
|
|
|
|
var fillPatternElemId = ElementId.InvalidElementId;
|
|
|
|
|
|
var fecOfFpe = new FilteredElementCollector(doc).OfClass(typeof(FillPatternElement));
|
|
|
|
|
|
foreach (var element in fecOfFpe.ToElements())
|
|
|
|
|
|
{
|
|
|
|
|
|
var fpe = element as FillPatternElement;
|
|
|
|
|
|
var fp = fpe.GetFillPattern();
|
|
|
|
|
|
if (null != fp && fp.Name == patternName)
|
|
|
|
|
|
{
|
|
|
|
|
|
fillPatternElemId = fpe.Id;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return fillPatternElemId;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取已载入同名族,若无,则载入
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="doc"></param>
|
|
|
|
|
|
/// <param name="familyPath"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static Family GetOrLoadedFamily(this Document doc, string familyPath)
|
|
|
|
|
|
{
|
|
|
|
|
|
var family = new FilteredElementCollector(doc)
|
|
|
|
|
|
.OfClass(typeof(Family))
|
|
|
|
|
|
.Cast<Family>()
|
|
|
|
|
|
.FirstOrDefault(f => f.Name == Path.GetFileNameWithoutExtension(familyPath));
|
|
|
|
|
|
if (family == null && File.Exists(familyPath))
|
|
|
|
|
|
{
|
|
|
|
|
|
doc.LoadFamily(familyPath, new LoadFamilyOptions(), out family);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return family;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取或创建文字类型
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="doc"></param>
|
|
|
|
|
|
/// <param name="textSymbolName">文字类型名称</param>
|
|
|
|
|
|
/// <param name="fontFamily"></param>
|
|
|
|
|
|
/// <param name="fontSize"></param>
|
|
|
|
|
|
/// <param name="widthScale"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static TextNoteType GetOrNewTextNoteType(
|
|
|
|
|
|
this Document doc,
|
|
|
|
|
|
string textSymbolName,
|
|
|
|
|
|
string fontFamily,
|
|
|
|
|
|
string fontSize,
|
|
|
|
|
|
string widthScale
|
|
|
|
|
|
)
|
|
|
|
|
|
{
|
|
|
|
|
|
var textNoteType = new FilteredElementCollector(doc)
|
|
|
|
|
|
.OfClass(typeof(TextNoteType))
|
|
|
|
|
|
.OfType<TextNoteType>()
|
|
|
|
|
|
.FirstOrDefault(x => x.Name.Contains(textSymbolName));
|
|
|
|
|
|
if (textNoteType != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return textNoteType;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
textNoteType =
|
|
|
|
|
|
new FilteredElementCollector(doc)
|
|
|
|
|
|
.OfClass(typeof(TextNoteType))
|
|
|
|
|
|
.Cast<TextNoteType>()
|
|
|
|
|
|
.FirstOrDefault()
|
|
|
|
|
|
?.Duplicate(textSymbolName) as TextNoteType;
|
|
|
|
|
|
if (textNoteType != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
textNoteType.get_Parameter(BuiltInParameter.TEXT_FONT).SetValueString(fontFamily);
|
|
|
|
|
|
textNoteType.get_Parameter(BuiltInParameter.TEXT_SIZE).SetValueString(fontSize);
|
|
|
|
|
|
textNoteType.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).SetValueString(widthScale);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return textNoteType;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 射线法获取参照
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="doc"></param>
|
|
|
|
|
|
/// <param name="vector"></param>
|
|
|
|
|
|
public static Reference GetSpotDimensionReference(this Document doc, XYZ vector)
|
|
|
|
|
|
{
|
|
|
|
|
|
Reference reference = null;
|
|
|
|
|
|
if (doc.ActiveView is ViewPlan view)
|
|
|
|
|
|
{
|
|
|
|
|
|
//可能存在贯穿标高的构件,需修改射线贯穿距离
|
|
|
|
|
|
#region 视图范围
|
|
|
|
|
|
|
|
|
|
|
|
var range = view.GetViewRange();
|
|
|
|
|
|
var bottomLevel = doc.GetElement(range.GetLevelId(PlanViewPlane.BottomClipPlane)) as Level;
|
|
|
|
|
|
var b = range.GetOffset(PlanViewPlane.BottomClipPlane);
|
|
|
|
|
|
var topLevel = doc.GetElement(range.GetLevelId(PlanViewPlane.TopClipPlane)) as Level;
|
|
|
|
|
|
var t = range.GetOffset(PlanViewPlane.TopClipPlane);
|
|
|
|
|
|
var bot = bottomLevel.Elevation + b;
|
|
|
|
|
|
var tt = topLevel.Elevation + t;
|
|
|
|
|
|
var p1 = new XYZ(vector.X, vector.Y, bot);
|
|
|
|
|
|
var p2 = new XYZ(vector.X, vector.Y, tt);
|
|
|
|
|
|
|
|
|
|
|
|
#endregion 视图范围
|
|
|
|
|
|
|
|
|
|
|
|
var v3d = new FilteredElementCollector(doc)
|
|
|
|
|
|
.OfClass(typeof(View3D))
|
|
|
|
|
|
.Cast<View3D>()
|
|
|
|
|
|
.FirstOrDefault(v => !v.IsTemplate);
|
|
|
|
|
|
|
|
|
|
|
|
//射线法找到相交的元素
|
|
|
|
|
|
ReferenceIntersector intersector = new(v3d);
|
|
|
|
|
|
var refer = intersector.FindNearest(p1, XYZ.BasisZ)?.GetReference();
|
|
|
|
|
|
var refer1 = intersector.FindNearest(p2, -XYZ.BasisZ)?.GetReference();
|
|
|
|
|
|
|
|
|
|
|
|
if (refer != null && refer1 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
reference = refer.GlobalPoint.Z > refer1.GlobalPoint.Z ? refer : refer1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return reference;
|
|
|
|
|
|
//Line l2 = Line.CreateUnbound(vector, XYZ.BasisZ);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// dwg图层隐藏
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="doc"></param>
|
|
|
|
|
|
/// <param name="reference">选择的dwg引用,PointOnElement</param>
|
|
|
|
|
|
/// <param name="graphicStyleId"></param>
|
|
|
|
|
|
/// <param name="geoElem"></param>
|
|
|
|
|
|
public static void HideDwgLayer(
|
|
|
|
|
|
this Document doc,
|
|
|
|
|
|
Reference reference,
|
|
|
|
|
|
out ElementId graphicStyleId,
|
|
|
|
|
|
out GeometryElement geoElem
|
|
|
|
|
|
)
|
|
|
|
|
|
{
|
|
|
|
|
|
var dwg = doc.GetElement(reference) as ImportInstance;
|
|
|
|
|
|
graphicStyleId = null;
|
|
|
|
|
|
Options opts =
|
|
|
|
|
|
new()
|
|
|
|
|
|
{
|
|
|
|
|
|
ComputeReferences = true,
|
|
|
|
|
|
IncludeNonVisibleObjects = true,
|
|
|
|
|
|
DetailLevel = 0
|
|
|
|
|
|
};
|
|
|
|
|
|
geoElem = dwg?.get_Geometry(opts);
|
|
|
|
|
|
var geoObj = dwg?.GetGeometryObjectFromReference(reference);
|
|
|
|
|
|
if (
|
|
|
|
|
|
geoObj != null
|
|
|
|
|
|
&& geoObj.GraphicsStyleId != ElementId.InvalidElementId
|
|
|
|
|
|
&& doc.GetElement(geoObj.GraphicsStyleId) is GraphicsStyle gsSelected
|
|
|
|
|
|
)
|
|
|
|
|
|
{
|
|
|
|
|
|
//图层Id
|
|
|
|
|
|
graphicStyleId = gsSelected.GraphicsStyleCategory.Id;
|
|
|
|
|
|
|
|
|
|
|
|
doc.Invoke(
|
|
|
|
|
|
_ =>
|
|
|
|
|
|
{
|
|
|
|
|
|
doc.ActiveView.SetCategoryHidden(gsSelected.GraphicsStyleCategory.Id, true);
|
|
|
|
|
|
},
|
|
|
|
|
|
"隐藏图层"
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 链接cad
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="doc"></param>
|
|
|
|
|
|
/// <param name="linkPaths"></param>
|
|
|
|
|
|
public static void LinkDwgByPaths(this Document doc, params string[] linkPaths)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (doc is null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentNullException(nameof(doc));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (linkPaths is null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentNullException(nameof(linkPaths));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var options = new DWGImportOptions { OrientToView = true };
|
|
|
|
|
|
//var li = linkPaths.ToList();
|
|
|
|
|
|
//li.ForEach(famdoc.Link(linkPath, options, famdoc.ActiveView, out _));
|
|
|
|
|
|
foreach (var linkPath in linkPaths)
|
|
|
|
|
|
{
|
|
|
|
|
|
doc.Link(linkPath, options, doc.ActiveView, out _);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 链接Revit
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="doc"></param>
|
|
|
|
|
|
/// <param name="linkPaths"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static void LinkRvt(this Document doc, params string[] linkPaths)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (doc is null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentNullException(nameof(doc));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (linkPaths is null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentNullException(nameof(linkPaths));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var linkPath in linkPaths)
|
|
|
|
|
|
{
|
|
|
|
|
|
var filePath = new FilePath(linkPath);
|
|
|
|
|
|
var linkOption = new RevitLinkOptions(false);
|
|
|
|
|
|
var result = RevitLinkType.Create(doc, filePath, linkOption);
|
|
|
|
|
|
|
|
|
|
|
|
var instance = RevitLinkInstance.Create(doc, result.ElementId);
|
|
|
|
|
|
|
|
|
|
|
|
if (doc.GetElement(instance.GetTypeId()) is not RevitLinkType type)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type.AttachmentType = AttachmentType.Attachment;
|
|
|
|
|
|
|
|
|
|
|
|
type.PathType = PathType.Relative;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static void ReadImporterFile(
|
|
|
|
|
|
this Document revitDoc,
|
|
|
|
|
|
ShapeImporterSourceFormat sourceFormat,
|
|
|
|
|
|
BuiltInCategory builtInCategory
|
|
|
|
|
|
)
|
|
|
|
|
|
{
|
|
|
|
|
|
//ofd.Filter = "SAT Files (.sat)|.sat";
|
|
|
|
|
|
FileOpenDialog ofd = new("*");
|
|
|
|
|
|
|
|
|
|
|
|
if (ofd.Show() == ItemSelectionDialogResult.Confirmed)
|
|
|
|
|
|
{
|
|
|
|
|
|
ShapeImporter shapeImporter = new() { InputFormat = sourceFormat };
|
|
|
|
|
|
var mp = ofd.GetSelectedModelPath();
|
|
|
|
|
|
var fileName = ModelPathUtils.ConvertModelPathToUserVisiblePath(mp);
|
|
|
|
|
|
var shapes = shapeImporter.Convert(revitDoc, fileName);
|
|
|
|
|
|
|
|
|
|
|
|
if (shapes.Count != 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
using Transaction tr = new(revitDoc, "创建内建模型");
|
|
|
|
|
|
tr.Start();
|
|
|
|
|
|
var dsImportedSat = DirectShape.CreateElement(revitDoc, new ElementId(builtInCategory));
|
|
|
|
|
|
dsImportedSat.SetShape(shapes);
|
|
|
|
|
|
|
|
|
|
|
|
tr.Commit();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 删除Revit链接
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="doc"></param>
|
|
|
|
|
|
/// <param name="linkPaths"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static void RemoveLinks(this Document doc, params string[] linkPaths)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (doc is null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentNullException(nameof(doc));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (linkPaths is null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentNullException(nameof(linkPaths));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var linkPath in linkPaths)
|
|
|
|
|
|
{
|
|
|
|
|
|
var links = new FilteredElementCollector(doc).OfClass(typeof(RevitLinkInstance));
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var link in links)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (link.Name.Split(':').Length != 3)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (link is not RevitLinkInstance instance)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (link.Name == Path.GetFileName(linkPath))
|
|
|
|
|
|
{
|
|
|
|
|
|
var type = doc.GetElement(instance.GetTypeId()) as RevitLinkType;
|
|
|
|
|
|
|
|
|
|
|
|
type?.Unload(null);
|
|
|
|
|
|
|
|
|
|
|
|
doc.Invoke(_ =>
|
|
|
|
|
|
{
|
|
|
|
|
|
doc.Delete(instance.Id);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static void RenameFamilyType(this Document famdoc, string oldTypeName, string newTypeName)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (famdoc.IsFamilyDocument)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 得到FamilyManager
|
|
|
|
|
|
var familyMgr = famdoc.FamilyManager;
|
|
|
|
|
|
// 族类型的名字,保证在所有族类型中唯一
|
|
|
|
|
|
var isExist = false;
|
|
|
|
|
|
foreach (FamilyType t in familyMgr.Types)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (t.Name == oldTypeName)
|
|
|
|
|
|
{
|
|
|
|
|
|
familyMgr.CurrentType = t;
|
|
|
|
|
|
familyMgr.RenameCurrentType(newTypeName);
|
|
|
|
|
|
isExist = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!isExist)
|
|
|
|
|
|
{
|
|
|
|
|
|
familyMgr.NewType(newTypeName);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
var familySymbol = new FilteredElementCollector(famdoc)
|
|
|
|
|
|
.WhereElementIsElementType()
|
|
|
|
|
|
.FirstOrDefault(t => t.Name == oldTypeName);
|
|
|
|
|
|
if (familySymbol != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
familySymbol.Name = newTypeName;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 设置中心文件
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="doc"></param>
|
|
|
|
|
|
/// <param name="centralPath"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static void SetCentralFile(this Document doc, string centralPath)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (doc is null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentNullException(nameof(doc));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (centralPath is null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentNullException(nameof(centralPath));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var saveOption = new SaveAsOptions { OverwriteExistingFile = true };
|
|
|
|
|
|
|
|
|
|
|
|
var sharingOption = new WorksharingSaveAsOptions
|
|
|
|
|
|
{
|
|
|
|
|
|
SaveAsCentral = true,
|
|
|
|
|
|
OpenWorksetsDefault = SimpleWorksetConfiguration.LastViewed
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
saveOption.SetWorksharingOptions(sharingOption);
|
|
|
|
|
|
|
|
|
|
|
|
doc.SaveAs(centralPath, saveOption);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 设置Revit链接集合
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="centralPath"></param>
|
|
|
|
|
|
/// <param name="linkPaths"></param>
|
|
|
|
|
|
public static void SetLinkList(string centralPath, List<string> linkPaths)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (centralPath is null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentNullException(nameof(centralPath));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (linkPaths is null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentNullException(nameof(linkPaths));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var transData = TransmissionData.ReadTransmissionData(new FilePath(centralPath));
|
|
|
|
|
|
|
|
|
|
|
|
if (transData is null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// If found not the link, don't submit, otherwise throw file writing exception.
|
|
|
|
|
|
var flag = false;
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var referId in transData.GetAllExternalFileReferenceIds())
|
|
|
|
|
|
{
|
|
|
|
|
|
var extRef = transData.GetLastSavedReferenceData(referId);
|
|
|
|
|
|
|
|
|
|
|
|
if (extRef.ExternalFileReferenceType != ExternalFileReferenceType.RevitLink)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var userPath = ModelPathUtils.ConvertModelPathToUserVisiblePath(extRef.GetPath());
|
|
|
|
|
|
|
|
|
|
|
|
var linkPath = linkPaths.FirstOrDefault(w => w != null && userPath.Contains(Path.GetFileName(w)));
|
|
|
|
|
|
|
|
|
|
|
|
if (linkPath is null)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var elmId = extRef.GetReferencingId();
|
|
|
|
|
|
|
|
|
|
|
|
transData.SetDesiredReferenceData(elmId, new FilePath(linkPath), PathType.Relative, true);
|
|
|
|
|
|
|
|
|
|
|
|
flag = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!flag)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
transData.IsTransmitted = true;
|
|
|
|
|
|
|
|
|
|
|
|
TransmissionData.WriteTransmissionData(new FilePath(centralPath), transData);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 设置Revit链接
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="doc"></param>
|
|
|
|
|
|
/// <param name="filePaths"></param>
|
|
|
|
|
|
public static void SetLinks(this Document doc, params string[] filePaths)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (doc is null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentNullException(nameof(doc));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (filePaths is null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentNullException(nameof(filePaths));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var filePath in filePaths)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!File.Exists(filePath))
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new FileNotFoundException(filePath);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// main elementFunc modifies repeatedly, so the performance is poor.
|
|
|
|
|
|
var linkTypes = doc.OfClass<RevitLinkType>().Where(w => filePath.Contains(w.Name));
|
|
|
|
|
|
|
|
|
|
|
|
if (linkTypes.FirstOrDefault(f => f.Name.Split('-').Length == 5) is not RevitLinkType type)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type.LoadFrom(new FilePath(filePath), new WorksetConfiguration(WorksetConfigurationOption.OpenLastViewed));
|
|
|
|
|
|
|
|
|
|
|
|
type.PathType = PathType.Relative;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 移除0长度标注
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="dimension"></param>
|
|
|
|
|
|
/// <param name="referenceArray"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static bool TryRemoveZeroes(this Dimension dimension, out ReferenceArray referenceArray)
|
|
|
|
|
|
{
|
|
|
|
|
|
referenceArray = new ReferenceArray();
|
|
|
|
|
|
var document = dimension.Document;
|
|
|
|
|
|
var isEmpty = dimension.Segments.IsEmpty;
|
|
|
|
|
|
if (isEmpty)
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
for (var i = 0; i < dimension.NumberOfSegments; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
var dimensionSegment = dimension.Segments.get_Item(i);
|
|
|
|
|
|
|
|
|
|
|
|
var value = dimensionSegment.Value;
|
|
|
|
|
|
if (!(value != null && Math.Abs(value.Value) < 0.0001))
|
|
|
|
|
|
{
|
|
|
|
|
|
var isEmpty2 = referenceArray.IsEmpty;
|
|
|
|
|
|
if (isEmpty2)
|
|
|
|
|
|
{
|
|
|
|
|
|
var refer = dimension.References.get_Item(i);
|
|
|
|
|
|
var element = document.GetElement(refer);
|
|
|
|
|
|
if (element is Grid or Level)
|
|
|
|
|
|
{
|
|
|
|
|
|
refer = new Reference(element);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
referenceArray.Append(refer);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var refer1 = dimension.References.get_Item(i + 1);
|
|
|
|
|
|
var element1 = document.GetElement(refer1);
|
|
|
|
|
|
if (element1 is Grid or Level)
|
|
|
|
|
|
{
|
|
|
|
|
|
refer1 = new Reference(element1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
referenceArray.Append(refer1);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return referenceArray.Size < dimension.References.Size;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 隐藏或者显示图层
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="doc"></param>
|
|
|
|
|
|
/// <param name="reference"></param>
|
|
|
|
|
|
/// <param name="bl">tr是显示 false是隐藏</param>
|
|
|
|
|
|
public static void VisLayer(this Document doc, Reference reference, bool bl)
|
|
|
|
|
|
{
|
|
|
|
|
|
var element = doc.GetElement(reference);
|
|
|
|
|
|
//GeometryElement geoElem = elementFunc.get_Geometry(new Options()); //几何图元
|
|
|
|
|
|
var geoObj = element.GetGeometryObjectFromReference(reference); //几何对象
|
|
|
|
|
|
if (geoObj.GraphicsStyleId != ElementId.InvalidElementId)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (doc.GetElement(geoObj.GraphicsStyleId) is GraphicsStyle gs)
|
|
|
|
|
|
{
|
|
|
|
|
|
var targetCategory = gs.GraphicsStyleCategory;
|
|
|
|
|
|
doc.ActiveView.SetCategoryHidden(targetCategory.Id, bl);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 发光材质
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="doc"></param>
|
|
|
|
|
|
public static void GetIllumMaterial(this Document doc)
|
|
|
|
|
|
{
|
|
|
|
|
|
var materials = doc.OfClass<Material>().Cast<Material>();
|
|
|
|
|
|
StringBuilder sb = new();
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var material in materials)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (doc.GetElement(material.AppearanceAssetId) is AppearanceAssetElement assetElem)
|
|
|
|
|
|
{
|
|
|
|
|
|
var asset = assetElem.GetRenderingAsset();
|
|
|
|
|
|
var prop = asset.FindByName("generic_self_illum_luminance");
|
|
|
|
|
|
|
|
|
|
|
|
var d = prop as AssetPropertyDouble;
|
|
|
|
|
|
if (d?.Value > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
sb.AppendLine(material.Name);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 射线法查找所有的Element
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="doc">Dcument</param>
|
|
|
|
|
|
/// <param name="filter">例如:ElementClassFilter filter = new ElementClassFilter(typeof(CableTray))</param>
|
|
|
|
|
|
/// <param name="targetRef">目标对象</param>
|
|
|
|
|
|
/// <param name="center">射源</param>
|
|
|
|
|
|
/// <param name="direction">方向</param>
|
|
|
|
|
|
/// <returns>返回该射线</returns>
|
|
|
|
|
|
public static IList<Element> XRayFindAll(
|
|
|
|
|
|
this Document doc,
|
|
|
|
|
|
ElementFilter filter,
|
|
|
|
|
|
FindReferenceTarget targetRef,
|
|
|
|
|
|
XYZ center,
|
|
|
|
|
|
XYZ direction
|
|
|
|
|
|
)
|
|
|
|
|
|
{
|
|
|
|
|
|
var view3D = doc.OfClass<View3D>().Cast<View3D>().First(v3 => !v3.IsTemplate);
|
|
|
|
|
|
var refWithContexts = new ReferenceIntersector(filter, targetRef, view3D).Find(center, direction);
|
|
|
|
|
|
if (refWithContexts == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var resultElements = new List<Element>();
|
|
|
|
|
|
foreach (var rwc in refWithContexts)
|
|
|
|
|
|
{
|
|
|
|
|
|
var reference = rwc.GetReference();
|
|
|
|
|
|
var hitElement = doc.GetElement(reference);
|
|
|
|
|
|
if (hitElement != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
resultElements.Add(hitElement);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return resultElements;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 射线法查找最近的Element
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="doc"></param>
|
|
|
|
|
|
/// <param name="filter">例如:ElementClassFilter filter = new ElementClassFilter(typeof(CableTray))</param>
|
|
|
|
|
|
/// <param name="targetRef">目标对象</param>
|
|
|
|
|
|
/// <param name="center">射源</param>
|
|
|
|
|
|
/// <param name="direction">方向</param>
|
|
|
|
|
|
/// <param name="hitElement">被击中的Element</param>
|
|
|
|
|
|
/// <returns>返回该射线</returns>
|
|
|
|
|
|
public static Line XRayFindNearest(
|
|
|
|
|
|
this Document doc,
|
|
|
|
|
|
ElementFilter filter,
|
|
|
|
|
|
FindReferenceTarget targetRef,
|
|
|
|
|
|
XYZ center,
|
|
|
|
|
|
XYZ direction,
|
|
|
|
|
|
ref Element hitElement
|
|
|
|
|
|
)
|
|
|
|
|
|
{
|
|
|
|
|
|
var view3D = doc
|
|
|
|
|
|
.OfClass<View3D>()
|
|
|
|
|
|
.Cast<View3D>()
|
|
|
|
|
|
.First(v3 => !v3.IsTemplate);
|
|
|
|
|
|
ReferenceIntersector refIntersector = new(filter, targetRef, view3D);
|
|
|
|
|
|
var rwc = refIntersector.FindNearest(center, direction);
|
|
|
|
|
|
if (rwc == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var reference = rwc.GetReference();
|
|
|
|
|
|
var intersection = reference.GlobalPoint;
|
|
|
|
|
|
hitElement = doc.GetElement(reference);
|
|
|
|
|
|
Line result = null;
|
|
|
|
|
|
if (!center.IsAlmostEqualTo(intersection))
|
|
|
|
|
|
{
|
|
|
|
|
|
result = Line.CreateBound(center, intersection);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
hitElement = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#if REVIT2021
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 修改测量点
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="doc"></param>
|
|
|
|
|
|
public static void ResetBasePoint(this Document doc)
|
|
|
|
|
|
{
|
|
|
|
|
|
var surveyPoint = BasePoint.GetSurveyPoint(doc);
|
|
|
|
|
|
var pos = surveyPoint.Position;
|
|
|
|
|
|
var sharedPos = surveyPoint.SharedPosition;
|
|
|
|
|
|
//surveyPoint.Position.Subtract(pos);
|
|
|
|
|
|
|
|
|
|
|
|
var projectBasePoint = BasePoint.GetProjectBasePoint(doc);
|
|
|
|
|
|
var pos1 = projectBasePoint.Position;
|
|
|
|
|
|
var sharePos1 = projectBasePoint.SharedPosition;
|
|
|
|
|
|
using (Transaction trans = new(doc, "移动测量点"))
|
|
|
|
|
|
{
|
|
|
|
|
|
trans.Start();
|
|
|
|
|
|
|
|
|
|
|
|
ElementTransformUtils.MoveElement(doc, surveyPoint.Id, sharedPos.Negate());
|
|
|
|
|
|
doc.Regenerate();
|
|
|
|
|
|
ElementTransformUtils.MoveElement(doc, surveyPoint.Id, pos.Negate());
|
|
|
|
|
|
|
|
|
|
|
|
ElementTransformUtils.MoveElement(doc, projectBasePoint.Id, pos1.Negate());
|
|
|
|
|
|
projectBasePoint.get_Parameter(BuiltInParameter.BASEPOINT_ANGLETON_PARAM).Set(0);
|
|
|
|
|
|
trans.Commit();
|
|
|
|
|
|
}
|
|
|
|
|
|
if (
|
|
|
|
|
|
!(
|
|
|
|
|
|
surveyPoint.SharedPosition.IsAlmostEqualTo(XYZ.Zero)
|
|
|
|
|
|
&& projectBasePoint.SharedPosition.IsAlmostEqualTo(XYZ.Zero)
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
|
|
|
|
|
{
|
|
|
|
|
|
MessageBox.Show("请修改测量点的裁剪状态", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|