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}"; } } /// /// 朝着向量方向左侧偏移并调整角度对齐直线 /// /// /// /// 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); } /// /// 调整族实例位置 /// /// 需要偏移的族实例 /// 用于调整偏移和角度的参考线 /// 偏移量 public static void AdjustByLine(this List 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); } } /// /// 族参数关联 /// /// 几何体 /// 几何体内建参数 /// 用户创建的族参数 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); } /// /// 自适应族放置 /// /// 自适应的族类型 /// public static FamilyInstance CreateAdaptiveComponent(this FamilySymbol familySymbol, List 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); } } }