Autodesk Answer Days – Revit, October 7, 2015
Do you have any Revit® or Revit LT® questions that you’ve always wanted to ask?
If yes, then join the latest installment of Ask Autodesk Anything events on October 7, 2015. This event is dedicated to answering your questions about Revit and Revit LT. We’ll have some DevTech engineers attending the event to answer your API questions. The event runs from 6 am to 6 pm Pacific Time and will take place in Autodesk Community. Come spend a minute, an hour, or the whole day in the Autodesk Community to interact directly with the folks who bring this award-winning building information modeling software!
Click here for more information.
This week I have a chance to help a developer looking for a way on how to create a roof through the API. Interesting question since I don’t think I never tried that before so it was a fun piece to work on. Here is the question from our Forum community.
Question: I'm having trouble to create a roof via code. I know how to create a stairs for example : I start a StairsEditScope and use CreateSketchedLanding with all the right parameters to create my stairs and just commit the StairsEditScope, but for a roof i cant find a clue on how to create it from scratch, any leads?
And if there isn't a way, for example: ceiling i know there isn't a way so i need to use a floor as a ceiling workaround. But for roof I don't have a workaround.
Answer:Here is a command to create a roof, Just make sure you have some walls to hold it and also one of your levels is named "Roof".
I created a simple 4 walls rectangle and the selected them and ran the command that I'm providing.
You can read more about this sample in the Revit Help file, here is the link.
#region Namespaces
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using System.Linq;
#endregion
namespace CreateRoof
{
[Transaction(TransactionMode.Automatic)]
public class Command : IExternalCommand
{
public Result Execute(
ExternalCommandData commandData,
ref string message,
ElementSet elements)
{
UIApplication uiapp = commandData.Application;
UIDocument uidoc = uiapp.ActiveUIDocument;
Application app = uiapp.Application;
Document doc = uidoc.Document;
// Before invoking this sample, select some walls to add a roof over.
// Make sure there is a level named "Roof" in the document.
// find the Roof level
FilteredElementCollector collector = new FilteredElementCollector(doc);
collector.OfClass(typeof(Level));
var elem = from element in collector where element.Name== "Roof" select element;
Level level = elem.Cast<Level>().ElementAt<Level>(0);
collector = new FilteredElementCollector(doc);
collector.OfClass(typeof(RoofType));
RoofType roofType = collector.FirstElement() as RoofType;
// Get the handle of the application
Autodesk.Revit.ApplicationServices.Application application = doc.Application;
// Define the footprint for the roof based on user selection
CurveArray footprint = application.Create.NewCurveArray();
ICollection<ElementId> selectedIds = uidoc.Selection.GetElementIds();
if (selectedIds.Count != 0)
{
foreach (ElementId id in selectedIds)
{
Element element = doc.GetElement(id);
Wall wall = element as Wall;
if (wall != null)
{
LocationCurve wallCurve = wall.Location as LocationCurve;
footprint.Append(wallCurve.Curve);
continue;
}
ModelCurve modelCurve = element as ModelCurve;
if (modelCurve != null)
{
footprint.Append(modelCurve.GeometryCurve);
}
}
}
else
{
throw new Exception ("You should select a curve loop,or a wall loop, or loops combination\nof walls and curves to create a footprint roof.");
}
ModelCurveArray footPrintToModelCurveMapping = new ModelCurveArray();
FootPrintRoof footprintRoof = doc.Create.NewFootPrintRoof(footprint, level, roofType,out footPrintToModelCurveMapping);
ModelCurveArrayIterator iterator =footPrintToModelCurveMapping.ForwardIterator();
iterator.Reset();
while (iterator.MoveNext())
{
ModelCurve modelCurve = iterator.Current as ModelCurve;
footprintRoof.set_DefinesSlope(modelCurve, true);
footprintRoof.set_SlopeAngle(modelCurve, 0.5);
}
return Result.Succeeded;
}
}
}
Let me know how it goes.
Also the same question, or at least that is how it looks like, got asked in Stack Overflow. The answer this time came by our API Guru Jeremy Tammik. It is nice to see how we are covering same questions across different support forums for Revit API, I call that a great collaboration across forums. You are best of continuing your questions in the Revit API forum, but we are also looking out for those questions that get posted in other places, like Stack Overflow for example.
Here is the response that Jeremy wrote in Stack Overflow.
Answer: Revit provides different kinds of roofs. It is best to understand the various types from an end user point of view before starting to drive them programmatically. The simplest one is defined by a horizontal outline. You can create a roof from such an outline using the Document.NewFootPrintRoof method. Such a roof can be flat, or you can specify a slope for each edge of the outline profile. The Building Coder Xtra labs provide a working sample in the external command Lab2_0_CreateLittleHouse in Labs2.cs:
https://github.com/jeremytammik/AdnRevitApiLabsXtra/blob/master/XtraCs/Labs2.cs
Here are some other roof-related posts on The Building Coder:
I hope this helps.
Thanks for reading and until next time.