Create Gable Wall

I discussed

creating a wall with a sloped profile
using
Revit 2009.
Now Saikat Bhattacharya created a similar command to answer a similar question in Revit 2012:

Question: Using the Revit user interface, I can create walls that consist of more then four edges, i.e. non-rectangular.
Usually they would represent some sort of gable wall in a building.
How can I achieve this using the API, please?

Answer: To answer your question, I wrote some quick code which creates a gable wall with seven faces, instead of the usual six faces of a rectangular wall.
It creates the following wall:

Gable wall

Jeremy adds: Many thanks to Saikat for setting this up!

I created a new Building Coder sample command CmdCreateGableWall based on Saikat’s code.
It is similar to the existing external command

CmdSlopedWall
,
updated to use new Revit API functionality to use manual transaction mode and filtered element collectors and LINQ to determine a suitable wall type and level:


[Transaction( TransactionMode.Manual )]
class CmdCreateGableWall : 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;
 
    // Build a wall profile for the wall creation 
 
    XYZ [] pts = new XYZ[] {
      XYZ.Zero,
      new XYZ( 20, 0, 0 ),
      new XYZ( 20, 0, 15 ),
      new XYZ( 10, 0, 30 ),
      new XYZ( 0, 0, 15 )
    };
 
    // Get application creation object 
 
    Autodesk.Revit.Creation.Application appCreation
      = app.Create;
 
    // Create wall profile
 
    CurveArray profile = new CurveArray();
 
    XYZ q = pts[ pts.Length - 1 ];
 
    foreach( XYZ p in pts )
    {
      profile.Append( appCreation.NewLineBound(
        q, p ) );
 
      q = p;
    }
 
    XYZ normal = XYZ.BasisY;
 
    WallType wallType
      = new FilteredElementCollector( doc )
        .OfClass( typeof( WallType ) )
        .First<Element>()
          as WallType;
 
    Level level
      = new FilteredElementCollector( doc )
        .OfClass( typeof( Level ) )
        .First<Element>( e
          => e.Name.Equals( "Level 1" ) )
        as Level;
 
    Transaction trans = new Transaction( doc );
 
    trans.Start( "Create Gable Wall" );
 
    Wall wall = doc.Create.NewWall(
      profile, wallType, level, true, normal );
 
    trans.Commit();
 
    return Result.Succeeded;
  }
}

Here is
version 2012.0.88.0 of
The Building Coder samples including the new command CmdCreateGableWall as well as the existing simpler CmdSlopedWall one.


Comments

8 responses to “Create Gable Wall”

  1. Arnaud Avatar
    Arnaud

    Hi Jeremy,
    I have a question please,
    I created an ExternalCommand, Is it possible to call the command from an external application?

  2. Dear Arnaud,
    Exactly that is actually the main purpose of many external applications. For a pretty minimal example of doing so, please refer to the zero document state sample, for instance:
    http://thebuildingcoder.typepad.com/blog/2011/02/enable-ribbon-items-in-zero-document-state.html
    Cheers, Jeremy.

  3. Arnaud Avatar
    Arnaud

    Hi Jeremy,
    Thank you very much for your reponse, but my question is false.
    T would like to know if it’s possible to call a EXTERNALCOMMAND or an EXTERNALPPLICATION from another application(not from revit)
    (Example: I Have a button in Add-ins that displays an TaskDIalog(HelloWorld), and I have another programme PROG.EXE that he must call REVIT and then Call the Button HelloWorld)
    How Can i do that?
    (Excuse me, my english is bad)

  4. Arnaud Avatar
    Arnaud

    Hi Jeremy,
    Thank you very much for your reponse, but my question is false.
    T would like to know if it’s possible to call a EXTERNALCOMMAND or an EXTERNALPPLICATION from another application(not from revit)
    (Example: I Have a button in Add-ins that displays an TaskDIalog(HelloWorld), and I have another programme PROG.EXE that he must call REVIT and then Call the Button HelloWorld)
    How Can i do that?
    (Excuse me, my english is bad)

  5. Dear Arnaud,
    I always thought that only answers could be false, not questions. Congratulations on proving me wrong :-)
    Nope, what you are asking for is not possible. There are workarounds to get around this, and they are convoluted. There are lots of posts discussing this issue. For instance, look at all the posts involving ‘driving Revit from outside’, ‘launching a command’, the Idling event, and
    http://thebuildingcoder.typepad.com/blog/2010/04/asynchronous-api-calls-and-idling.html
    Cheers, Jeremy.

  6. Dear Arnaud,
    I always thought that only answers could be false, not questions. Congratulations on proving me wrong :-)
    Nope, what you are asking for is not possible. There are workarounds to get around this, and they are convoluted. There are lots of posts discussing this issue. For instance, look at all the posts involving ‘driving Revit from outside’, ‘launching a command’, the Idling event, and
    http://thebuildingcoder.typepad.com/blog/2010/04/asynchronous-api-calls-and-idling.html
    Cheers, Jeremy.

  7. Arnaud Avatar
    Arnaud

    Thank you very much Jeremy.

  8. Ahmed Avatar
    Ahmed

    How you are able to create using newwall !!, i am suffering when i am trying this using revit macro ,
    look for example i am trying to create walls from reference planes.
    imagine the errors comes from newwall
    also i need to compute where the planes intersect to find the start and end points of the walls which i do not know how to perform any help Jeremy ?
    using System;
    using Autodesk.Revit.UI;
    using Autodesk.Revit.DB;
    using Autodesk.Revit.UI.Selection;
    using System.Collections.Generic;
    using System.Linq;
    namespace refplanes2walls
    {
    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    [Autodesk.Revit.DB.Macros.AddInId(“B4947BF5-8424-46D1-92EC-D300EFDC6699”)]
    public partial class ThisApplication
    {
    private void Module_Startup(object sender, EventArgs e)
    {
    }
    private void Module_Shutdown(object sender, EventArgs e)
    {
    }
    #region Revit Macros generated code
    private void InternalStartup()
    {
    this.Startup += new System.EventHandler(Module_Startup);
    this.Shutdown += new System.EventHandler(Module_Shutdown);
    }
    #endregion
    public void Replanes2walls()
    {
    Document doc = this.ActiveUIDocument.Document;
    UIDocument uidoc = new UIDocument(doc);
    // Get “Level 1”
    Level level = (from l in new FilteredElementCollector(doc).OfClass(typeof(Level)) where l.Name == “Level 1” select l).First() as Level;
    // Selection will be restricted to lines only. Attempts to click on other objects will be ignored
    ISelectionFilter referenceplanefilter = new refplaneSelectionFilter();
    IList refr = uidoc.Selection.PickObjects(ObjectType.Element, referenceplanefilter, “Pick lines”);
    using (Transaction t = new Transaction(doc,”Create Walls From Lines”))
    {
    // Get application creation object
    Autodesk.Revit.Creation.Application appCreation
    = this.Application.Create;
    t.Start();
    foreach (Reference reference in refr)
    {
    ReferencePlane refplane = doc.GetElement(reference) as ReferencePlane;
    Wall wall= doc.Create.newwall(refplane.Direction, level, false); // false indicates that the wall’s Structural property is false
    }
    t.Commit();
    }
    }
    public class refplaneSelectionFilter : ISelectionFilter
    {
    // determine if the element should be accepted by the filter
    public bool AllowElement(Element element)
    {
    // Convert the element to a ModelLine
    ReferencePlane refplane = element as ReferencePlane;
    // line is null if the element is not a model line
    if (refplane == null)
    {
    return false;
    }
    // return true if the line is a model line
    return true;
    }
    // references will never be accepeted by this filter, so always return false
    public bool AllowReference(Reference refer, XYZ point)
    {return false;}
    }
    }
    }

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading