using System.Diagnostics;
using System.IO;
using System.Text;
using System.Windows;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB.Visual;
using ShrlAlgoToolkit.RevitCore.Assists;
namespace ShrlAlgoToolkit.RevitCore.Extensions;
public static class DocumentExtensions
{
///
/// 轴网标注
///
///
///
///
///
///
public static Dimension CreateDimensionByExtremeGrids(
this Document doc,
Line chainDimensionLine,
ExtremeWallVariant extremeWallVariant,
List 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 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 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;
}
///
/// 获取所有可预览视图ID
///
///
///
///
///
public static ElementId FindPreviewId(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().First(v => setting.IsViewIdValidForPreview(v.Id));
return viewForPreview.Id;
}
///
/// 获取标高范围框
///
/// 最低标高除了包含以上部分,还包含以下部分,最高标高包含以上部分
///
///
public static Dictionary GetLevelRanges(this Document doc)
{
var levels = doc.OfClass().Cast().OrderBy(l => l.Elevation).ToList();
Dictionary 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 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 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 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 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 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;
}
///
/// 创建房间
///
///
///
///
public static void CreateRoom(this Document doc, Level level, Phase phase)
{
// 获取基于标高level的一个视图
var defaultView = new FilteredElementCollector(doc)
.OfClass(typeof(View))
.Cast()
.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);
}
}
}
}
///
/// 创建表格
///
///
///
///
///
///
///
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);
}
///
/// 创建表格
///
///
/// 图例视图
/// 行数
/// 列数
/// 单元格高度
/// 各列对应的宽度
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);
}
///
/// 创建表格
///
/// 图例视图
/// 行数(含标题行)
/// 列数
///
/// 单元格高度
/// 各单元格对应的宽度
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 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().ElementAt(0);
familyMgr.CurrentType = type;
}
}
}
///
/// 删除定位点重合的族实例
///
///
///
public static void DeleteOverlapInstance(this Document doc, List cardInstances)
{
List 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);
}
///
/// 复制图例
///
///
///
/// 比例
///
public static View DuplicateLegend(Document doc, string legendName, int viewScale)
{
var legends = doc.OfClass()
.OfCategory(BuiltInCategory.OST_Views)
.Cast()
.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;
}
///
/// 翻转工作平面
///
///
///
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;
}
///
/// 获取族中的元素
///
///
///
public static List GetFamilySolidForm(this Document famdoc)
{
var ids = new List();
if (famdoc.IsFamilyDocument)
{
var solids = new FilteredElementCollector(famdoc)
.OfClass(typeof(GenericForm))
.Cast()
.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;
}
///
/// 填充样式
///
///
///
///
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;
}
///
/// 获取已载入同名族,若无,则载入
///
///
///
///
public static Family GetOrLoadedFamily(this Document doc, string familyPath)
{
var family = new FilteredElementCollector(doc)
.OfClass(typeof(Family))
.Cast()
.FirstOrDefault(f => f.Name == Path.GetFileNameWithoutExtension(familyPath));
if (family == null && File.Exists(familyPath))
{
doc.LoadFamily(familyPath, new DefaultFamilyLoadOptions(), out family);
}
return family;
}
///
/// 获取或创建文字类型
///
///
/// 文字类型名称
///
///
///
///
public static TextNoteType GetOrNewTextNoteType(
this Document doc,
string textSymbolName,
string fontFamily,
string fontSize,
string widthScale
)
{
var textNoteType = new FilteredElementCollector(doc)
.OfClass(typeof(TextNoteType))
.OfType()
.FirstOrDefault(x => x.Name.Contains(textSymbolName));
if (textNoteType != null)
{
return textNoteType;
}
textNoteType =
new FilteredElementCollector(doc)
.OfClass(typeof(TextNoteType))
.Cast()
.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;
}
///
/// 射线法获取参照
///
///
///
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()
.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);
}
///
/// dwg图层隐藏
///
///
/// 选择的dwg引用,PointOnElement
///
///
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);
},
"隐藏图层"
);
}
}
///
/// 链接cad
///
///
///
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 _);
}
}
///
/// 链接Revit
///
///
///
///
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();
}
}
}
///
/// 有类型定义的DirectShape
///
///
/// 定义名称,即是族名称、类型名称(强制一致),创建多个实例时,如果相同,则会合并在一个族中
/// 族类别
/// 几何
///
public static DirectShape CreateDirectShapeInstance(this Document doc, string definitionId, BuiltInCategory category, List geos)
{
DirectShapeLibrary directShapeLibrary = DirectShapeLibrary.GetDirectShapeLibrary(doc);
ElementId directShapeTypeId = directShapeLibrary.FindDefinitionType(definitionId);
if (doc.GetElement(directShapeTypeId) == null)
{
var directShapeType = DirectShapeType.Create(doc, definitionId, new ElementId(category));
directShapeTypeId = directShapeType.Id;
directShapeLibrary.AddDefinitionType(definitionId, directShapeTypeId);
}
//else
//{
// directShapeLibrary.AddDefinition(definitionId, geos);
//}
var shape = DirectShape.CreateElementInstance(doc, directShapeTypeId, new ElementId(category), definitionId, Transform.Identity);
//shape.SetTypeId(directShapeTypeId);
//shape.SetName();实例名称
shape.SetShape(geos);
return shape;
}
///
/// 无名称定义的DirectShape
///
///
///
///
///
public static DirectShape CreateDirectShape(this Document doc, List geos, BuiltInCategory category)
{
var shape = DirectShape.CreateElement(doc, new ElementId(category));
shape.SetShape(geos);
return shape;
}
///
/// 删除Revit链接
///
///
///
///
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;
}
}
}
///
/// 设置中心文件
///
///
///
///
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);
}
///
/// 设置Revit链接集合
///
///
///
public static void SetLinkList(string centralPath, List 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);
}
///
/// 设置Revit链接
///
///
///
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().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;
}
}
///
/// 移除0长度标注
///
///
///
///
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;
}
}
///
/// 隐藏或者显示图层
///
///
///
/// tr是显示 false是隐藏
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);
}
}
}
///
/// 发光材质
///
///
public static void GetIllumMaterial(this Document doc)
{
var materials = doc.OfClass().Cast();
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);
}
}
}
}
///
/// 射线法查找所有的Element
///
/// Dcument
/// 例如:ElementClassFilter filter = new ElementClassFilter(typeof(CableTray))
/// 目标对象
/// 射源
/// 方向
/// 返回该射线
public static IList XRayFindAll(
this Document doc,
ElementFilter filter,
FindReferenceTarget targetRef,
XYZ center,
XYZ direction
)
{
var view3D = doc.OfClass().Cast().First(v3 => !v3.IsTemplate);
var refWithContexts = new ReferenceIntersector(filter, targetRef, view3D).Find(center, direction);
if (refWithContexts == null)
{
return null;
}
var resultElements = new List();
foreach (var rwc in refWithContexts)
{
var reference = rwc.GetReference();
var hitElement = doc.GetElement(reference);
if (hitElement != null)
{
resultElements.Add(hitElement);
}
}
return resultElements;
}
///
/// 射线法查找最近的Element
///
///
/// 例如:ElementClassFilter filter = new ElementClassFilter(typeof(CableTray))
/// 目标对象
/// 射源
/// 方向
/// 被击中的Element
/// 返回该射线
public static Line XRayFindNearest(
this Document doc,
ElementFilter filter,
FindReferenceTarget targetRef,
XYZ center,
XYZ direction,
ref Element hitElement
)
{
var view3D = doc
.OfClass()
.Cast()
.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
///
/// 修改测量点
///
///
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
}