Walls and Doors on Two Levels
Originally Published inHere is a little note to answer a question from Berria on creating walls and doors on two separate levels. This is a slightly edited version of the original query:
Question: I need to create a house with two floors. I create a level and then a new wall and a door. It draws the two objects on different levels. When I built the first level, all is OK. An error occurs when I build the second, because the level to define the component position is always zero.
Answer: I cannot tell you off-hand what the problem is in your situation, but I can provide you with a code example that achieves your goal. Look at the external command Lab2_0_CreateLittleHouse in the Revit API introduction labs. To demonstrate that the code can be easily adapted to work on several levels, here is a modified version which creates only the walls and doors, omitting the other elements, and repeats the process on two levels. In order to place the second door, I do indeed modify the Z coordinate of its insertion point by setting ‘midpoint.Z = levelMiddle.Elevation’. Before running this command, ensure that you have three levels in your model, and that the brain-dead code snippet which extracts them into the three variables really gets them in the right order:
WaitCursor waitCursor = new WaitCursor();
Application app = commandData.Application;
Document doc = app.ActiveDocument;
_createApp = app.Create;
_createDoc = doc.Create;
//
// determine the four corners of the rectangular house:
//
double width = 7 * LabConstants.MeterToFeet;
double depth = 4 * LabConstants.MeterToFeet;
List<XYZ> corners = new List<XYZ>( 4 );
corners.Add( new XYZ( 0, 0, 0 ) );
corners.Add( new XYZ( width, 0, 0 ) );
corners.Add( new XYZ( width, depth, 0 ) );
corners.Add( new XYZ( 0, depth, 0 ) );
Level levelBottom = null;
Level levelMiddle = null;
Level levelTop = null;
List<Element> levels = new List<Element>();
Filter filterType
= _createApp.Filter.NewTypeFilter(
typeof( Level ) );
doc.get_Elements( filterType, levels );
foreach( Element e in levels )
{
if( null == levelBottom )
{
levelBottom = e as Level;
}
else if( null == levelMiddle )
{
levelMiddle = e as Level;
}
else if( null == levelTop )
{
levelTop = e as Level;
}
else
{
break;
}
}
BuiltInParameter topLevelParam
= BuiltInParameter.WALL_HEIGHT_TYPE;
Line line;
Wall wall;
Parameter param;
ElementId topId = levelMiddle.Id;
List<Wall> walls = new List<Wall>( 8 );
for( int i = 0; i < 4; ++i )
{
line = _createApp.NewLineBound(
corners[i], corners[3 == i ? 0 : i + 1] );
wall = _createDoc.NewWall(
line, levelBottom, false );
param = wall.get_Parameter( topLevelParam );
param.Set( ref topId );
walls.Add( wall );
}
topId = levelTop.Id;
for( int i = 0; i < 4; ++i )
{
line = _createApp.NewLineBound(
corners[i], corners[3 == i ? 0 : i + 1] );
wall = _createDoc.NewWall(
line, levelMiddle, false );
param = wall.get_Parameter( topLevelParam );
param.Set( ref topId );
walls.Add( wall );
}
List<Element> doorSymbols
= LabUtils.GetAllFamilySymbols(
app, BuiltInCategory.OST_Doors );
Debug.Assert(
0 < doorSymbols.Count,
"expected at least one door symbol"
+ " to be loaded into project" );
FamilySymbol door
= doorSymbols[0] as FamilySymbol;
XYZ midpoint = LabUtils.Midpoint(
corners[0], corners[1] );
FamilyInstance inst0
= _createDoc.NewFamilyInstance(
midpoint, door, walls[0], levelBottom,
StructuralType.NonStructural );
midpoint.Z = levelMiddle.Elevation;
FamilyInstance inst1
= _createDoc.NewFamilyInstance(
midpoint, door, walls[4], levelMiddle,
StructuralType.NonStructural );
return CmdResult.Succeeded;
Here is the result of running the command:
I hope this helps resolve your problem.