Creating Face Wall and Mass Floor

I went on my first ski tour this season, on and around the Hochgescheid, in the Black Forest, for a change:

Hochgescheid

On the Revit API side of things, besides lots of interesting issues in the Revit API discussion forum, a Japanese ADN case came up on programmatically generating a mass floor, enabling us to mention yet another hitherto unmentioned Revit API usility class, MassInstanceUtils:

Question: マス床をAPIで生成する方法があれば教えてください。 – Please tell me if a method exists to generate a mass floor using the API.

Answer: First of all, here is the description on creating a floor from a mass floor in the user interface.

Please be aware that the Revit API does not support the creation of in-place mass elements.

As suggested by the Revit API discussion forum thread on creating components in mode 'Model In-Place', the alternative is to create a direct shape instead. Unfortunately, you will still not end up with a mass.

However, if you have already created a mass element by some other means, you can use it to generate face walls and mass floors programmatically.

This really old thread asking the same question on creating mass floors and or scope boxes still remains open today. I'll add this answer to that as soon as I complete publishing it on The Building Coder.

Nowadays, the answer to this question is provided by the MassInstanceUtils.AddMassLevelDataToMassInstance method.

It generates floors defined by levels based on a given mass geometry.

Its use is demonstrated and very clearly explained by Harry Mattison of Boost your BIM in his post on automating the Building Maker workflow.

It uses the FaceWall Create and MassInstanceUtils AddMassLevelDataToMassInstance methods to generate walls and floors based on a selected mass element's geometry, faces and levels.

He demonstrates the add-in running live in his three-and-a-half-minute video on Face Wall and Mass Floor creation with the Revit API:

The API calls are driven by Harry's C# .NET Revit API macro CreateFaceWallsAndMassFloors.

Here is the code copied from Harry's post and added to The Building Coder samples in lines 414-473 of CmdFaceWall.cs:

#region CreateFaceWallsAndMassFloors
// By Harry Mattison, Boost Your BIM,
// Automating the Building Maker workflow
// https://boostyourbim.wordpress.com/2014/02/11/automating-the-building-maker-workflow/
// Face Wall and Mass Floor creation with the Revit API
// https://youtu.be/nHWen2_lN6U

/// <summary>
/// Create face walls and mass floors on and in selected mass element
/// </summary>
public void CreateFaceWallsAndMassFloors( UIDocument uidoc )
{
  Document doc = uidoc.Document;

  FamilyInstance fi = doc.GetElement(
    uidoc.Selection.PickObject(
      ObjectType.Element ) )
        as FamilyInstance;

  WallType wType = new FilteredElementCollector( doc )
    .OfClass( typeofWallType ) )
    .Cast<WallType>().FirstOrDefault( q
      => q.Name == "Generic - 6\" Masonry" );

  Options opt = new Options();
  opt.ComputeReferences = true;

  usingTransaction t = new Transaction( doc ) )
  {
    t.Start( "Create Face Walls & Mass Floors" );

    foreachSolid solid in fi.get_Geometry( opt )
      .Where( q => q is Solid ).Cast<Solid>() )
    {
      foreachFace f in solid.Faces )
      {
        ifFaceWall.IsValidFaceReferenceForFaceWall(
          doc, f.Reference ) )
        {
          FaceWall.Create( doc, wType.Id,
            WallLocationLine.CoreExterior,
            f.Reference );
        }
      }
    }

    FilteredElementCollector levels
      = new FilteredElementCollector( doc )
        .OfClass( typeofLevel ) );

    foreachLevel level in levels )
    {
      MassInstanceUtils.AddMassLevelDataToMassInstance(
        doc, fi.Id, level.Id );
    }

    t.Commit();
  }
}
#endregion // CreateFaceWallsAndMassFloors

Many thanks to Harry for documenting and implementing this!