中文链接
By Aaron Lu
A customer has a headache to create family instance on wall, he tried several combinations of Document.Create.NewFamilyInstance but got nothing.
Here is what he wants, place a light fixture on wall:
I found when we place them by manual, it is always on a face of the wall, so we can get rid of other overloads, but focus only on the following:
NewFamilyInstance(Reference, Line position, FamilySymbol)
NewFamilyInstance(Reference, XYZ location, XYZ referenceDirection, FamilySymbol)
NewFamilyInstance(Face, Line position, FamilySymbol)
NewFamilyInstance(Face, XYZ location, XYZ referenceDirection, FamilySymbol)
And since it is placed by point, so I decided to use this method:
NewFamilyInstance(Reference, XYZ location, XYZ referenceDirection, FamilySymbol)
As you can see, the first argument Reference should be the reference of a face on the wall, the second is the location, the third referenceDirection is the rotation of the instance, and last one FamilySymbol is the symbol.
But how to get face reference?
Fortunately, there is a class named HostObjectUtils, which has several convinient methods to get faces of host objects, for example, GetSideFaces is used to get side faces of Wall:
var reference = HostObjectUtils.GetSideFaces(wall,
ShellLayerType.Interior).First();
ShellLayerType is to designate whethere it is exterior face or interior face. Call .First() is to get the first face, I believe there is only one face in one side :).
Now it is simple, whole code looks like this:
FamilySymbol familySymbol = GetFamilySymbol("Switch board");
ElementId elementId = new ElementId(308696);
Wall wall = RevitDoc.GetElement(elementId) as Wall;
var reference = HostObjectUtils.GetSideFaces(wall,
ShellLayerType.Interior).First();
if (wall != null)
{
var instance = RevitDoc.Create.NewFamilyInstance(reference,
new XYZ(13.3997604933275,-1.35161192601243,9.0571329707487),
new XYZ(0,0,0),
familySymbol);
if (instance == null)
TaskDialog.Show("ERROR", "Instance is null!");
}
We don't want to rotate the instance, so referenceDirection is set to (0,0,0).
But new problem comes out, we found difference between the one created by API and the one by manual
Here is the one by manual:
And here is the one by API:
You should find that the elevation parameter is disabled in the second image but not in the first one.
So how to solve it?
Inspecting again, I found there is another difference, the "Schedule Level", the one created manually has a "Schedule Level" by default, but API created one has nothing set.
So now, we've got a solution: change the parameter "Schedule Level" to a real level after the instance is created. Cheers!
Parameter parameter = instance.get_Parameter(
BuiltInParameter.INSTANCE_SCHEDULE_ONLY_LEVEL_PARAM);
if (parameter != null)
{
parameter.Set(new ElementId(311));
}