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

咨询适配带角度墙体的NewFamilyInstance重载方法

Fixing FamilyInstance Orientation on Angled Walls in Revit API

It looks like the issue you're facing comes down to how the NewFamilyInstance overload you're using handles orientation. The two overloads you're calling associate the family with the wall as a host, but they don't explicitly set the instance's rotation to match the wall's angle—so it defaults to the world coordinate system's horizontal axis, which works for straight horizontal walls but fails on angled ones.

Here's how to fix this, with two reliable approaches:


Approach 1: Use the Overload with referenceDirection Parameter

The most straightforward fix is to switch to a NewFamilyInstance overload that lets you define the instance's orientation explicitly. This overload takes a referenceDirection vector, which you can set to match the wall's lengthwise direction:

public FamilyInstance NewFamilyInstance(
    XYZ location,
    FamilySymbol symbol,
    Element host,
    XYZ referenceDirection,
    StructuralType structuralType
)

Modified Code Example

Replace your existing instance creation line with this, using your normalizeVectorAlongTheWall as the reference direction (since this is already the wall's lengthwise vector):

foreach (double layerOffsett in layerOffsets ) {
    int counter = 0;
    XYZ oldStartPoint = p0 + layerOffsett * vectoPerpendicularTothewall;
    // Use the overload with referenceDirection to match wall orientation
    FamilyInstance instance2 = document.Create.NewFamilyInstance(
        oldStartPoint, 
        symbol, 
        wall, 
        normalizeVectorAlongTheWall, // This sets the instance's orientation
        StructuralType.NonStructural
    );
    for (int j = 1; j < n2 - 1; j++) {
        XYZ newStartPoint = oldStartPoint + 4 * normalizeVectorAlongTheWall;
        instance2 = document.Create.NewFamilyInstance(
            newStartPoint, 
            symbol, 
            wall, 
            normalizeVectorAlongTheWall,
            StructuralType.NonStructural
        );
        oldStartPoint = newStartPoint;
    }
    counter++;
}

This ensures each family instance aligns its orientation with the wall's direction, no matter the wall's angle.


Approach 2: Attach to the Wall's Finish Layer Face (More Reliable for Layer Alignment)

If you want the family to not just rotate with the wall but also strictly adhere to the Finish[1]/Finish[2] layer's plane (useful if the wall has complex geometry or non-standard layers), use the face-based NewFamilyInstance overload. This directly places the instance on the specified wall layer's face, which automatically handles orientation.

Step 1: Get the Finish Layer's Face

First, retrieve the face corresponding to your target Finish layer:

// Get the wall's layer structure
WallLayerStructure layerStructure = wall.WallType.GetWallLayers();
Face targetFinishFace = null;

// Locate the Finish[1] layer (adjust to Finish[2] if needed)
foreach (WallLayer layer in layerStructure)
{
    if (layer.Function == WallFunction.Finish1)
    {
        // Get the exterior or interior face based on which side the Finish layer is on
        IList<Reference> faceRefs = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Exterior);
        if (faceRefs.Count > 0)
        {
            targetFinishFace = wall.Document.GetElement(faceRefs[0]).GetGeometryObjectFromReference(faceRefs[0]) as Face;
        }
        break;
    }
}

Step 2: Create Instances on the Face

Use the face-based overload to place your family instances:

if (targetFinishFace != null)
{
    foreach (double layerOffsett in layerOffsets ) {
        int counter = 0;
        XYZ oldStartPoint = p0 + layerOffsett * vectoPerpendicularTothewall;
        // Create instance directly on the Finish layer face
        FamilyInstance instance2 = document.Create.NewFamilyInstance(
            targetFinishFace, 
            oldStartPoint, 
            normalizeVectorAlongTheWall, // Orientation along the wall
            symbol
        );
        for (int j = 1; j < n2 - 1; j++) {
            XYZ newStartPoint = oldStartPoint + 4 * normalizeVectorAlongTheWall;
            instance2 = document.Create.NewFamilyInstance(
                targetFinishFace, 
                newStartPoint, 
                normalizeVectorAlongTheWall,
                symbol
            );
            oldStartPoint = newStartPoint;
        }
        counter++;
    }
}

Key Notes

  • Check Family Symbol Settings: Ensure your family symbol allows rotation—some families have locked orientations, so you may need to adjust the family's properties in the Revit editor first.
  • Avoid Post-Creation Rotation: While you could rotate instances after creation using instance.get_Parameter(BuiltInParameter.INSTANCE_ROTATION_PARAM) or Transform, it's cleaner and more reliable to set the orientation during creation.

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

火山引擎 最新活动