Files
Shrlalgo.RvKits/ShrlAlgoToolkit.Revit/Extensions/FamilyExtensions.cs

148 lines
6.3 KiB
C#
Raw Normal View History

2024-09-22 11:05:41 +08:00
using Autodesk.Revit.DB;
2025-04-24 20:56:44 +08:00
using ShrlAlgoToolkit.Revit.Assists;
namespace ShrlAlgoToolkit.Revit.Extensions
2024-09-22 11:05:41 +08:00
{
2025-04-24 20:56:44 +08:00
public static class FamilyExtensions
2024-09-22 11:05:41 +08:00
{
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);
}
}
}