Files
ShrlAlgoToolkit/ShrlAlgoToolkit.Revit/Extensions/FamilyExtensions.cs
2025-04-24 20:56:44 +08:00

148 lines
6.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Autodesk.Revit.DB;
using ShrlAlgoToolkit.Revit.Assists;
namespace ShrlAlgoToolkit.Revit.Extensions
{
public static class FamilyExtensions
{
public static void Rename(this FamilySymbol symbol, string newString)
{
var n = 0;
bool isExistName;
while (true)
{
try
{
symbol.Name = newString;
}
catch (Autodesk.Revit.Exceptions.ArgumentException)
{
isExistName = true;
n += 1;
break;
}
}
if (isExistName)
{
symbol.Name = $"{newString} {n}";
}
}
/// <summary>
/// 朝着向量方向左侧偏移并调整角度对齐直线
/// </summary>
/// <param name="fi"></param>
/// <param name="referLine"></param>
/// <param name="offset"></param>
public static void AdjustByLine(this FamilyInstance fi, Line referLine, double offset)
{
var doc = fi.Document;
//朝着向量方向左侧偏移
var zdir = XYZ.BasisZ;
//通过第三点垂直于直线的单位向量(无论左右侧)*偏移距离(一半的闸机长度)
var offsetVector = zdir.CrossProduct(referLine.Direction).Normalize() * offset;
//旋转角度
var radian = XYZ.BasisY.AngleTo(offsetVector);
//判断相对于Y轴是正向角度逆时针还是逆向角度顺时针
var z = offsetVector.CrossProduct(XYZ.BasisY).Normalize();
if (z.IsAlmostEqualTo(XYZ.BasisZ))
{
//逆向旋转,角度取负值
radian = -radian;
}
var p = fi.GetLocXYZ();
var l = Line.CreateUnbound(p, XYZ.BasisZ);
//旋转,移动
ElementTransformUtils.RotateElement(doc, fi.Id, l, radian + Math.PI);
ElementTransformUtils.MoveElement(doc, fi.Id, offsetVector);
}
/// <summary>
/// 调整族实例位置
/// </summary>
/// <param name="instances">需要偏移的族实例</param>
/// <param name="referLine">用于调整偏移和角度的参考线</param>
/// <param name="offset">偏移量</param>
public static void AdjustByLine(this List<FamilyInstance> instances, Line referLine, double offset = 0.0)
{
var doc = instances.FirstOrDefault().Document;
var zdir = XYZ.BasisZ;
//通过第三点垂直于直线的单位向量(无论左右侧)*偏移距离(一半的闸机长度)
var offsetVector = zdir.CrossProduct(referLine.Direction).Normalize();
//旋转角度
var angle = XYZ.BasisY.AngleTo(offsetVector);
//判断相对于Y轴是正向角度逆时针还是逆向角度顺时针
var z = offsetVector.CrossProduct(XYZ.BasisY).Normalize();
if (z.IsAlmostEqualTo(XYZ.BasisZ))
{
//逆向旋转,角度取负值
angle = -angle;
//var ml = doc.Create.NewModelCurve(Line.CreateBound(XYZ.Zero, re), SketchPlane.Create(doc, Plane.CreateByNormalAndOrigin(XYZ.BasisZ, new XYZ())));
}
offsetVector *= offset;
foreach (var instance in instances)
{
var p = instance.GetLocXYZ();
var l = Line.CreateUnbound(p, XYZ.BasisZ);
//旋转,移动
ElementTransformUtils.RotateElement(doc, instance.Id, l, angle);
ElementTransformUtils.MoveElement(doc, instance.Id, offsetVector);
}
}
/// <summary>
/// 族参数关联
/// </summary>
/// <param name="form">几何体</param>
/// <param name="formBuiltInParameter">几何体内建参数</param>
/// <param name="familyParameter">用户创建的族参数</param>
public static void AssociateParameter(this GenericForm form, BuiltInParameter formBuiltInParameter, BuiltInParameter familyParameter)
{
var famdoc = form.Document;
var p = form.get_Parameter(formBuiltInParameter);
var fm = famdoc.FamilyManager;
//var currentType = fm.CurrentType;
//if (currentType != null & !currentType.HasValue(p))
//{
//}
//var fp = fm.AddParamsToFiles("结构材质", BuiltInParameterGroup.PG_MATERIALS, ParameterType.Material, false);
var fp = fm.get_Parameter(familyParameter);
fm.Set(fp, p.AsElementId());
fm.AssociateElementParameterToFamilyParameter(p, fp);
}
/// <summary>
/// 自适应族放置
/// </summary>
/// <param name="familySymbol">自适应的族类型</param>
/// <param name="points"></param>
public static FamilyInstance CreateAdaptiveComponent(this FamilySymbol familySymbol, List<XYZ> points)
{
var doc = familySymbol.Document;
//创建实例,并获取其自适应点列表
var familyInstance = AdaptiveComponentInstanceUtils.CreateAdaptiveComponentInstance(doc, familySymbol);
var adaptivePoints = AdaptiveComponentInstanceUtils.GetInstancePlacementPointElementRefIds(familyInstance);
for (var i = 0; i < points.Count; i++)
{
if (points.Count != adaptivePoints.Count)
{
continue;
}
//Task.Delay(5_00);
//设置参照点坐标
if (doc.GetElement(adaptivePoints[i]) is ReferencePoint referencePoint)
{
referencePoint.Position = points[i];
}
}
return familyInstance;
//PointOnEdge pointOnEdge = commandData.Application.Application.Create.NewPointOnEdge(, locationOnCurve);
//point.SetPointElementReference(pointOnEdge as PointElementReference);
//PointLocationOnCurve locationOnCurve = new PointLocationOnCurve(PointOnCurveMeasurementType.NormalizedCurveParameter, 0, PointOnCurveMeasureFrom.Beginning);
}
}
}