You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Revit API技术问询:如何从Solid Form获取生成它的FamilyInstance

获取Solid Form对应的原始FamilyInstance

嘿,这个问题我之前也碰到过!当你通过Revit UI的「创建形状→实心形状」生成Solid Form后,直接用GetGeneratingElementIds()确实拿不到原始的FamilyInstance——因为这个API方法更多是针对通过API直接创建的Form对象,而非UI操作生成的衍生形状。下面给你几个可行的解决思路:

1. 解析轮廓引用的原始元素ID

你提到form.get_CurveLoopReferencesOnProfile()返回了ReferenceArray,这里面的Reference对象很可能包含了原始FamilyInstance的ID!因为生成的实心形状的轮廓曲线其实是引用了原始FamilyInstance的几何边界,所以可以遍历这些Reference来提取对应的元素:

var form = ele as Autodesk.Revit.DB.Form;
Document doc = form.Document;

// 遍历所有轮廓和曲线环
for (int profileIdx = 0; profileIdx < form.ProfileCount; profileIdx++)
{
    int loopCount = form.GetCurveLoopCountOnProfile(profileIdx);
    for (int loopIdx = 0; loopIdx < loopCount; loopIdx++)
    {
        ReferenceArray refs = form.get_CurveLoopReferencesOnProfile(profileIdx, loopIdx);
        foreach (Reference r in refs)
        {
            if (r.ElementId != ElementId.InvalidElementId)
            {
                Element elem = doc.GetElement(r.ElementId);
                if (elem is FamilyInstance originalInstance)
                {
                    // 找到对应的原始FamilyInstance
                    // 这里可以添加你的处理逻辑,比如记录ID或操作实例
                    TaskDialog.Show("找到原始实例", $"ID: {originalInstance.Id}, 类型: {originalInstance.Name}");
                }
            }
        }
    }
}

这个方法应该是最直接的,因为UI生成的形状本质是基于原始实例的几何轮廓创建的,引用关系会保留在轮廓的Reference里。

2. 通过依赖关系追踪原始元素

Revit的DependencyUtils类可以用来追踪元素之间的依赖关系,你可以尝试获取Form的所有依赖源元素,从中筛选FamilyInstance:

var form = ele as Autodesk.Revit.DB.Form;
Document doc = form.Document;

// 获取Form的所有依赖源元素
ICollection<ElementId> sourceIds = DependencyUtils.GetDependencySources(doc, form.Id, DependencyType.Any);

foreach (ElementId id in sourceIds)
{
    Element elem = doc.GetElement(id);
    if (elem is FamilyInstance originalInstance)
    {
        // 找到目标FamilyInstance
        // 处理逻辑
        break;
    }
}

注意:DependencyUtils是Revit 2021及以上版本才有的API,如果你的项目需要兼容旧版本,这个方法可能不适用。

3. 自定义参数存储关联(适合插件触发创建的场景)

如果这个Form是你自己的插件触发创建的,那可以提前记录原始FamilyInstance的ID,并将其存储到Form的自定义共享参数中:

步骤1:提前创建共享参数

先在Revit中创建一个名为OriginalFamilyInstanceId的共享参数,绑定到Form类别。

步骤2:创建Form时存储关联ID

// 假设你已经选中了要转换的FamilyInstance列表
foreach (FamilyInstance fi in selectedFamilyInstances)
{
    // 执行创建实心形状的操作(这里需要根据你的插件逻辑实现Form创建)
    Form newForm = CreateSolidFormFromInstance(doc, fi);
    
    // 给Form设置自定义参数,存储原始实例ID
    Parameter originalIdParam = newForm.LookupParameter("OriginalFamilyInstanceId");
    if (originalIdParam != null && !originalIdParam.IsReadOnly)
    {
        originalIdParam.Set(fi.Id);
    }
}

步骤3:后续读取关联ID

var form = ele as Autodesk.Revit.DB.Form;
Parameter originalIdParam = form.LookupParameter("OriginalFamilyInstanceId");
if (originalIdParam != null && originalIdParam.StorageType == StorageType.ElementId)
{
    ElementId originalId = originalIdParam.AsElementId();
    FamilyInstance originalInstance = form.Document.GetElement(originalId) as FamilyInstance;
    // 处理逻辑
}

这个方法的优势是关联关系非常明确,不会受Revit内部API变化的影响。


内容的提问来源于stack exchange,提问作者KungPhoo

火山引擎 最新活动