创建一个平面与模型线最终创建自适应族的案例。
这是一个我在Autodeks论坛回复的问题,这里整理一下发表在CSDN。
二开时,如何解决自适应族,移动自适应点,自适应族发生翻转,如何解决

如果直接使用轮廓族,读取轮廓族的线段再继续创建,会出现路径发生偏转之后形状镜像显示的问题,这种情况出现的原因是因为refernce的附着面变化导致自适应族在路径偏移重新生成形状的时候发生的法向量的变化导致。
如果需要将轮廓族与路径位置锁定,只需要直接获取轮廓族的refernce这样会和手动创建一样,随着路径的偏移自动创建新的正确形状。
new Reference(familyInstances[i])

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
UIApplication uIApplication = commandData.Application;
Autodesk.Revit.ApplicationServices.Application application = uIApplication.Application;

UIDocument uidoc = commandData.Application.ActiveUIDocument;
Document familydoc1 = uidoc.Document;
ReferencePointArray referencePointArray = new ReferencePointArray();
string filepath = @"D:\梁板截面.rfa";
CurveByPoints curveByPoints = null;//使用自适应点创建模型线
Curve curve = null;//存储模型线转换的几何线
using (Transaction ts1 = new Transaction(familydoc1))
{
ts1.Start("创建自适点");
for (int i = 0; i < 3; i++)
{
ReferencePoint referencePoint = familydoc1.FamilyCreate.NewReferencePoint(new XYZ(i, 0, 0));
AdaptiveComponentFamilyUtils.MakeAdaptivePoint(familydoc1, referencePoint.Id, AdaptivePointType.PlacementPoint);
AdaptiveComponentFamilyUtils.SetPlacementNumber(familydoc1, referencePoint.Id, i + 1);
referencePointArray.Append(referencePoint);
}

curveByPoints = familydoc1.FamilyCreate.NewCurveByPoints(referencePointArray);
curve = curveByPoints.GeometryCurve;
ts1.Commit();
}
ReferenceArray pathReference = new ReferenceArray();
pathReference.Append(curve.Reference);
IList<XYZ> qiexian = (curve as HermiteSpline).Tangents;//模型线自适应点位置切线集合
//载入CAD图实例

ReferenceArrayArray referenceArrayArray = new ReferenceArrayArray();
FilteredElementCollector collector1 = new FilteredElementCollector(familydoc1);
FamilySymbol familySymbol = collector1.OfClass(typeof(FamilySymbol)).ToElements().FirstOrDefault(x => x.Name == "梁板") as FamilySymbol;
using (Transaction ts = new Transaction(familydoc1))
{
ts.Start("载入CAD实例");
for (int i = 0; i < 3; i++)
{
if (i == 1)
{
continue;
}
FamilyInstance instance = AdaptiveComponentInstanceUtils.CreateAdaptiveComponentInstance(familydoc1, familySymbol);
IList<ElementId> placePointIds = AdaptiveComponentInstanceUtils.GetInstancePlacementPointElementRefIds(instance);
ReferencePoint point = familydoc1.GetElement(placePointIds[0]) as ReferencePoint;
//载入实例与模型线绑定
if (i == 0)
{

point.Position = curve.GetEndPoint(i);
PointLocationOnCurve pointLocationOnCurve = new PointLocationOnCurve(PointOnCurveMeasurementType.NormalizedCurveParameter, 0, PointOnCurveMeasureFrom.Beginning);
PointOnEdge pointOnEdge = application.Create.NewPointOnEdge(curve.Reference, pointLocationOnCurve);
point.SetPointElementReference(pointOnEdge as PointElementReference);
}
else
{
point.Position = curve.GetEndPoint(i - 1);
PointLocationOnCurve pointLocationOnCurve = new PointLocationOnCurve(PointOnCurveMeasurementType.NormalizedCurveParameter, 1, PointOnCurveMeasureFrom.Beginning);
PointOnEdge pointOnEdge = application.Create.NewPointOnEdge(curve.Reference, pointLocationOnCurve);
point.SetPointElementReference(pointOnEdge as PointElementReference);
}
}
//使载入的cad图实例与模型线相切
FilteredElementCollector collector2 = new FilteredElementCollector(familydoc1);
List<Element> elements1 = collector2.OfClass(typeof(FamilyInstance)).ToList();
for (int i = 0; i < 3; i++)
{
if (i == 2)
{
continue;
}
if (elements1[i] is FamilyInstance familyInstance)
{
XYZ location = (familyInstance.Location as LocationPoint).Point;
Transform transform = familyInstance.GetTotalTransform();
Line line = Line.CreateBound(location, new XYZ(location.X + 1, location.Y, location.Z));
double angle = qiexian[i].AngleTo(transform.BasisX);
bool flag = qiexian[i].CrossProduct(transform.BasisX).Z < 0;
if (flag)
{

familyInstance.Location.Rotate(line, angle);
}
else
{
familyInstance.Location.Rotate(line, -angle);
}
}
}
FilteredElementCollector elements2 = new FilteredElementCollector(familydoc1);
List<FamilyInstance> familyInstances = elements2.OfClass(typeof(FamilyInstance)).Cast<FamilyInstance>().ToList();
TaskDialog.Show("Revit",familyInstances.Count.ToString());
for (int i = 0; i < 2; i++)
{
ReferenceArray referenceArray = new ReferenceArray();
GeometryElement geometryElement = familyInstances[i].get_Geometry(new Options());
//if (i == 1)
//{
// i++;
//}
//double u1 = curve.Project(new XYZ(i, 0, 0)).Parameter;
//Transform transform1 = curve.ComputeDerivatives(u1, false);
//XYZ normal =XYZ.BasisY;
//Plane plane = Plane.CreateByNormalAndOrigin(normal, new XYZ(i, 0, 0));
//SketchPlane sketchPlane = SketchPlane.Create(familydoc1, plane);
//foreach (var item in geometryElement)
//{
// if (item is GeometryInstance geometryInstance)
// {
// GeometryElement geometryElement1 = geometryInstance.GetInstanceGeometry();
// foreach (var item1 in geometryElement1)
// {
// if (item1 is Curve curve1)
// {
// ModelCurve modelCurve = familydoc1.FamilyCreate.NewModelCurve(curve1, sketchPlane);
// Reference referenceInstnce = modelCurve.GeometryCurve.Reference;
// referenceArray.Append(referenceInstnce);
// }
// }
// }
//}
referenceArray.Append(new Reference(familyInstances[i]));
referenceArrayArray.Append(referenceArray);
}

ts.Commit();


}

using (Transaction tran = new Transaction(familydoc1))
{
tran.Start("Create");
Form form = familydoc1.FamilyCreate.NewSweptBlendForm(true, pathReference, referenceArrayArray);

tran.Commit();
}
![Snipaste_2026-01-04_15-22-40.png](https://cdn.bimath.com/blog/pg/Snipaste_2026-01-04_15-22-40.png)
![Snipaste_2026-01-04_15-22-45.png](https://cdn.bimath.com/blog/pg/Snipaste_2026-01-04_15-22-45.png)