Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.

Revit API Forum

Reply
Post 1 of 14
Accepted Solution

Help: Creating roof

377 Views, 13 Replies
09-22-2015 10:37 AM

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 isnt a way, for example: ceiling i know there isnt a way so i need to use a floor as a ceiling workaround. But for roof i dont have a workaround.

Hi onizukabr,

 

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 selcted 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.

 

http://help.autodesk.com/view/RVT/2016/ENU/?guid=GUID-33E6A6BD-96AA-4FAF-B660-1DD0C06CCD29

 

 

#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 :).

Post 2 of 14

Re: Help: Creating roof

09-22-2015 02:00 PM in reply to: onizukabr

Hi onizukabr,

 

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 selcted 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.

 

http://help.autodesk.com/view/RVT/2016/ENU/?guid=GUID-33E6A6BD-96AA-4FAF-B660-1DD0C06CCD29

 

 

#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 :).



Jaime Rosales D.
Sr. Developer Consultant
Twitter | AEC ADN DevBlog
Highlighted
Post 3 of 14

Re: Help: Creating roof

09-22-2015 06:11 PM in reply to: rosalesduquej

This worked on C#. The problem is i`m working with python ( Dynamo add ) and on python there isnt a way to pass a paramater by reference ( The case with 

out footPrintToModelCurveMapping ) so i cant make it work 

 

Post 4 of 14

Re: Help: Creating roof

09-23-2015 01:35 AM in reply to: onizukabr

Have you searched for a solution?

 

I see many suggestions.

 

Here is one of them:

 

http://stackoverflow.com/questions/10541343/ref-out-on-2d-array-with-ironpython

 

I searched for "ironpython out by reference", e.g., like this:

 

https://duckduckgo.com/?q=ironpython+out+by+reference

 

Good luck!



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Post 5 of 14

Re: Help: Creating roof

09-23-2015 05:46 PM in reply to: jeremytammik

Thanks it worked using:

footPrintToModelCurveMapping = clr.StrongBox[ModelCurveArray]()

 

it wasn`t a by Reference problem

Post 6 of 14

Re: Help: Creating roof

11-14-2016 09:36 AM in reply to: onizukabr
Hy, This method works fine for me with basic roof types. Although if i use it with sloped glazing roof type, the roof creation part works fine, but the slope defining iterator fails without any exception. Does anyone know how to create sloped sloped glazing? :D Regards, Gergő
Post 7 of 14

Re: Help: Creating roof

11-14-2016 09:53 AM in reply to: j.gergo89

Dear Gergő,

 

How do you achieve the desired result manually through the user interface?

 

Normally, programmatic approach is quite similar.

 

The procedure for you to explore this yourself is always the same:

 

Set up a simple minimal starting point situation manually through the user interface.

 

Explore the existing elements and their properties using RevitLookup, BipChecker, the element lister, and other, more intimate database exploration tools:

 

http://thebuildingcoder.typepad.com/blog/2013/11/intimate-revit-database-exploration-with-the-python...

 

Make the desired modification, in this case adding the sloped glazing.

 

Analyse what changed.

 

Now you know what you need to do to achieve the desired result.

 

I hope this helps.

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Post 8 of 14

Re: Help: Creating roof

11-15-2016 07:38 AM in reply to: jeremytammik

Dear Jeremy, as far as i managed to investigate, a BasicRoof and a SlopedGlazing are the same category, the same creation method should work for them. My code below works fine, if I specify a BasicRoof as the roof type and create the slope of the roof, with the iterator.

It also works fine, if I specify a SlopedGlazing as type, and don't specify slope for the footprint, so a flat sloped glazing is created.

But if I switch the type of the sloped roof from basic, to SlopedGlazing in code, the roof element disappears from the model, without any warning.

 

Any idea why that's happening?

 

Thanks, Gergő

 

public static IEnumerable<FootPrintRoof> RoofCreator(Document doc, IEnumerable<InputRoof> inputRoofs,
            IEnumerable<Level> levels,  IEnumerable<RoofType> roofTypes  )
        {
            var levelList = levels.ToList();
            var roofTypesList = roofTypes.ToList();
            const string roofTemplate = "RoofTemplate";
            foreach (var inputRoof in inputRoofs)
            {
                var level = levelList.Single(l => l.Name == inputRoof.LevelName);

                var roofTemp = roofTypesList.Single(r => r.Name == roofTemplate);

                var footPrintToModelCurveMapping = new ModelCurveArray();

                var roof = doc.Create.NewFootPrintRoof(inputRoof.RoofContour, level, roofTemp, out footPrintToModelCurveMapping);

                var iterator = footPrintToModelCurveMapping.ForwardIterator();
                iterator.Reset();

                var i = 1;
                while (iterator.MoveNext())
                {
                    i++;
                    var modelCurve = iterator.Current as ModelCurve;
                    if (i % 2 == 0)
                    {
                        roof.set_DefinesSlope(modelCurve, true);
                        roof.set_SlopeAngle(modelCurve, Converter.DegToRad(inputRoof.Slope));
                    }
                    else
                    {
                        roof.set_DefinesSlope(modelCurve, false);
                    }
                }
                var rType = roofTypesList.First(r => r.Name == inputRoof.RoofTypeName);
                roof.RoofType = rType;
                Log.Trace(roof.RoofType.Name);
                yield return roof;
            }
        }
Post 9 of 14

Re: Help: Creating roof

11-16-2016 06:04 AM in reply to: j.gergo89

What happens if you switch back and forth between basic and glazing manually in the user interface?



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Post 10 of 14

Re: Help: Creating roof

11-16-2016 07:09 AM in reply to: jeremytammik
It works back and forth without any problem.
Post 11 of 14

Re: Help: Creating roof

11-16-2016 07:55 AM in reply to: j.gergo89

Dear Gergő,

 

Thank you for your update.

 

Ok. In that case, I'll raise an issue with the development team. Please provide a full reproducible case for me to share with them so they can analyse in depth and verify any fixes that may be required:

http://thebuildingcoder.typepad.com/blog/about-the-author.html#1b

Thank you!

 

Best regards,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Post 12 of 14

Re: Help: Creating roof

11-17-2016 02:28 AM in reply to: jeremytammik
Dear Jeremy, I've created a file with an embeded macro in it, reproducing my issue with sloped glazing creation. You can dowload the file from here: https://we.tl/iueqHsIJV5 Thanks for all the help, hope there is a fix for this issue. Regards, Gergő
Post 13 of 14

Re: Help: Creating roof

11-17-2016 03:21 AM in reply to: j.gergo89

oh and btw sloped glazing creates the roof, but misplaces the glass panels.

 

Regards,

Gergő

Post 14 of 14

Re: Help: Creating roof

11-17-2016 04:11 PM in reply to: onizukabr

Dear Gergő,

 

Thank you for your reproducible case.

 

I logged the issue REVIT-103341 [API: roof creation fails for sloped glazing -- 12373437] with our development team for this on your behalf as it requires further exploration and possibly a modification to our software. Please make a note of this number for future reference.

 

You are welcome to request an update on the status of this issue or to provide additional information on it at any time quoting this change request number.

 

This issue is important to me. What can I do to help?

 

This issue needs to be assessed by our engineering team, and prioritised against all of the other outstanding change requests. Any information that you can provide to influence this assessment will help. Please provide the following where possible:

 

  • Impact on your application and/or your development.
  • The number of users affected.
  • The potential revenue impact to you.
  • The potential revenue impact to Autodesk.
  • Realistic timescale over which a fix would help you. 

 

This information is extremely important. Our engineering team have limited resources, and so must focus their efforts on the highest impact items. We do understand that this will cause you delays and affect your development planning, and we appreciate your cooperation and patience.

 

Best regards,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Post to the Community

Have questions about Autodesk products? Ask the community.

New Post

Revit Exchange Apps

Created by the community for the community, Autodesk Exchange Apps for Revit helps you achieve greater speed, accuracy, and automation from concept to manufacturing.