public Result Execute(
ExternalCommandData commandData,
ref string message,
ElementSet elements)
{
UIApplication app = commandData.Application;
UIDocument uidoc = app.ActiveUIDocument;
Document doc = uidoc.Document;
// Retrieve selected floors, or all floors, if nothing is selected:
List<Element> floors = new List<Element>();
if( !Util.GetSelectedElementsOrAll(
floors, uidoc, typeof( Floor ) ) )
{
Selection sel = uidoc.Selection;
message = ( 0 < sel.GetElementIds().Count )
? "Please select some floor elements."
: "No floor elements found.";
return Result.Failed;
}
// Determine top face of each selected floor:
int nNullFaces = 0;
List<Face> topFaces = new List<Face>();
Options opt = app.Application.Create.NewGeometryOptions();
foreach( Floor floor in floors )
{
GeometryElement geo = floor.get_Geometry( opt );
//GeometryObjectArray objects = geo.Objects; // 2012
foreach( GeometryObject obj in geo )
{
Solid solid = obj as Solid;
if( solid != null )
{
PlanarFace f = GetTopFace( solid );
if( null == f )
{
Debug.WriteLine(
Util.ElementDescription( floor )
+ " has no top face." );
++nNullFaces;
}
topFaces.Add( f );
}
}
}
using ( Transaction t = new Transaction( doc ) )
{
t.Start( "Create Model Lines and Floor" );
// Create new floors from the top faces found.
// Before creating the new floor, we would obviously
// apply whatever modifications are required to the
// new floor profile:
Autodesk.Revit.Creation.Application creApp = app.Application.Create;
Autodesk.Revit.Creation.Document creDoc = doc.Create;
int i = 0;
int n = topFaces.Count - nNullFaces;
Debug.Print(
"{0} top face{1} found.",
n, Util.PluralSuffix( n ) );
foreach ( Face f in topFaces )
{
Floor floor = floors[i++] as Floor;
if ( null != f )
{
EdgeArrayArray eaa = f.EdgeLoops;
CurveArray profile;
#region Attempt to include inner loops
#if ATTEMPT_TO_INCLUDE_INNER_LOOPS
bool use_original_loops = true;
if( use_original_loops )
{
profile = Convert( eaa );
}
else
#endif // ATTEMPT_TO_INCLUDE_INNER_LOOPS
#endregion // Attempt to include inner loops
{
profile = new CurveArray();
// Only use first edge array,
// the outer boundary loop,
// skip the further items
// representing holes:
EdgeArray ea = eaa.get_Item( 0 );
foreach ( Edge e in ea )
{
IList<XYZ> pts = e.Tessellate();
int m = pts.Count;
XYZ p = pts[0];
XYZ q = pts[m - 1];
Line line = Line.CreateBound( p, q );
profile.Append( line );
}
}
//Level level = floor.Level; // 2013
Level level = doc.GetElement( floor.LevelId )
as Level; // 2014
// In this case we have a valid floor type given.
// In general, not that NewFloor will only accept
// floor types whose IsFoundationSlab predicate
// is false.
floor = creDoc.NewFloor( profile,
floor.FloorType, level, true );
XYZ v = new XYZ( 5, 5, 0 );
//doc.Move( floor, v ); // 2011
ElementTransformUtils.MoveElement( doc, floor.Id, v ); // 2012
}
}
t.Commit();
}
return Result.Succeeded;
}