//
// (C) Copyright 2003-2010 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//
using System;
using System.Collections.Generic;
using Autodesk.Revit;
using Autodesk.Revit.Creation;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
namespace Revit.SDK.Samples.CreateAirHandler.CS
{
///
/// Create one air handler and add connectors.
///
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
[Autodesk.Revit.Attributes.Journaling(Autodesk.Revit.Attributes.JournalingMode.NoCommandData)]
public class Command : IExternalCommand
{
///
/// The revit application
///
private static Autodesk.Revit.ApplicationServices.Application m_application;
///
/// The current document of the application
///
private static Autodesk.Revit.DB.Document m_document;
///
/// the factory to creaate extrusions and connectors
///
private FamilyItemFactory f;
///
/// the extrusion array
///
private Extrusion[] extrusions;
///
/// The list of all the elements to be combined in the air handler system
///
private CombinableElementArray m_combineElements;
#region Data used to create extrusions and connectors
///
/// Data to create extrusions and connectors
///
private Autodesk.Revit.DB.XYZ [,] profileData = new Autodesk.Revit.DB.XYZ [5, 4]
{
// In Array 0 to 2, the data is the points that defines the edges of the profile
{
new Autodesk.Revit.DB.XYZ (-17.28, -0.53, 0.9),
new Autodesk.Revit.DB.XYZ (-17.28, 11, 0.9),
new Autodesk.Revit.DB.XYZ (-0.57, 11, 0.9),
new Autodesk.Revit.DB.XYZ (-0.57, -0.53, 0.9)
},
{
new Autodesk.Revit.DB.XYZ (-0.57, 7, 6.58),
new Autodesk.Revit.DB.XYZ (-0.57, 7, 3),
new Autodesk.Revit.DB.XYZ (-0.57, 3.6, 3),
new Autodesk.Revit.DB.XYZ (-0.57, 3.6, 6.58)
},
{
new Autodesk.Revit.DB.XYZ (-17.28, -0.073, 7.17),
new Autodesk.Revit.DB.XYZ (-17.28, 10.76, 7.17),
new Autodesk.Revit.DB.XYZ (-17.28, 10.76, 3.58),
new Autodesk.Revit.DB.XYZ (-17.28, -0.073, 3.58)
},
// In Array 3 and 4, the data is the normal and origin of the plane of the arc profile
{
new Autodesk.Revit.DB.XYZ (0, -1, 0),
new Autodesk.Revit.DB.XYZ (-9, 0.53, 7.17),
null,
null
},
{
new Autodesk.Revit.DB.XYZ (0, -1, 0),
new Autodesk.Revit.DB.XYZ (-8.24, 0.53, 0.67),
null,
null
}
};
///
/// the normal and origin of the sketch plane
///
private Autodesk.Revit.DB.XYZ [,] sketchPlaneData = new Autodesk.Revit.DB.XYZ [5, 2]
{
{new Autodesk.Revit.DB.XYZ (0, 0, 1), new Autodesk.Revit.DB.XYZ (0, 0, 0.9)},
{new Autodesk.Revit.DB.XYZ (1, 0, 0), new Autodesk.Revit.DB.XYZ (-0.57, 0, 0)},
{new Autodesk.Revit.DB.XYZ (-1, 0, 0), new Autodesk.Revit.DB.XYZ (-17.28, 0, 0)},
{new Autodesk.Revit.DB.XYZ (0, -1, 0), new Autodesk.Revit.DB.XYZ (0, 0.53, 0)},
{new Autodesk.Revit.DB.XYZ (0, -1, 0), new Autodesk.Revit.DB.XYZ (0, 0.53, 0)}
};
///
/// the start and end offsets of the extrusion
///
private double[,] extrusionOffsets = new double[5, 2]
{
{-0.9, 6.77},
{0, -0.18},
{0, -0.08},
{1, 1.15},
{1, 1.15}
};
///
/// whether the extrusion is solid
///
private bool[] isSolid = new bool[5] { true, false, false, true, true };
///
/// the radius of the arc profile
///
private double arcRadius = 0.17;
///
/// the height and width of the connector
///
private double[,] connectorDimensions = new double[2, 2]
{
{3.58, 3.4},
{3.59, 10.833}
};
///
/// the flow of the connector
///
private double flow = 547;
///
/// Transaction of ExternalCommand
///
private Transaction m_transaction;
#endregion
#region IExternalCommand Members
///
/// Implement this method as an external command for Revit.
///
/// An object that is passed to the external application
/// which contains data related to the command,
/// such as the application object and active view.
/// A message that can be set by the external application
/// which will be displayed if a failure or cancellation is returned by
/// the external command.
/// A set of elements to which the external application
/// can add elements that are to be highlighted in case of failure or cancellation.
/// Return the status of the external command.
/// A result of Succeeded means that the API external method functioned as expected.
/// Cancelled can be used to signify that the user cancelled the external operation
/// at some point. Failure should be returned if the application is unable to proceed with
/// the operation.
public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, ref string message,
ElementSet elements)
{
// set out default result to failure.
Autodesk.Revit.UI.Result retRes = Autodesk.Revit.UI.Result.Failed;
m_application = commandData.Application.Application;
m_document = commandData.Application.ActiveUIDocument.Document;
f = m_document.FamilyCreate;
extrusions = new Extrusion[5];
m_combineElements = new CombinableElementArray();
m_transaction = new Transaction(m_document, "External Tool");
m_transaction.Start();
if (m_document.OwnerFamily.FamilyCategory.Name != "Mechanical Equipment")
{
message = "Please make sure you opened a template of Mechanical Equipment.";
return retRes;
}
try
{
CreateExtrusions();
m_document.Regenerate();
CreateConnectors();
m_document.Regenerate();
m_document.CombineElements(m_combineElements);
m_document.Regenerate();
}
catch(Exception x)
{
m_transaction.RollBack();
message = x.Message;
return retRes;
}
m_transaction.Commit();
retRes = Autodesk.Revit.UI.Result.Succeeded;
return retRes;
}
#endregion
///
/// get all planar faces of an extrusion
///
/// the extrusion to read
/// a list of all planar faces of the extrusion
public List GetPlanarFaces(Extrusion extrusion)
{
// the option to get geometry elements
Options m_geoOptions = m_application.Create.NewGeometryOptions();
m_geoOptions.View = m_document.ActiveView;
m_geoOptions.ComputeReferences = true;
// get the planar faces
List m_planarFaces = new List();
Autodesk.Revit.DB.GeometryElement geoElement = extrusion.get_Geometry(m_geoOptions);
foreach (GeometryObject geoObject in geoElement.Objects)
{
Solid geoSolid = geoObject as Solid;
if (null == geoSolid)
{
continue;
}
foreach (Face geoFace in geoSolid.Faces)
{
if (geoFace is PlanarFace)
{
m_planarFaces.Add(geoFace as PlanarFace);
}
}
}
return m_planarFaces;
}
///
/// create the extrusions of the air handler system
///
private void CreateExtrusions()
{
Autodesk.Revit.Creation.Application app = m_application.Create;
CurveArray curves = null;
CurveArrArray profile = null;
Plane plane = null;
SketchPlane sketchPlane = null;
#region Create the cuboid extrusions
for (int i = 0; i <= 2; ++i)
{
// create the profile
curves = app.NewCurveArray();
curves.Append(app.NewLine(profileData[i, 0], profileData[i, 1], true));
curves.Append(app.NewLine(profileData[i, 1], profileData[i, 2], true));
curves.Append(app.NewLine(profileData[i, 2], profileData[i, 3], true));
curves.Append(app.NewLine(profileData[i, 3], profileData[i, 0], true));
profile = app.NewCurveArrArray();
profile.Append(curves);
// create the sketch plane
plane = app.NewPlane(sketchPlaneData[i, 0], sketchPlaneData[i, 1]);
sketchPlane = f.NewSketchPlane(plane);
// create the extrusion
extrusions[i] = f.NewExtrusion(isSolid[i], profile, sketchPlane,
extrusionOffsets[i, 1]);
extrusions[i].StartOffset = extrusionOffsets[i, 0];
m_combineElements.Append(extrusions[i]);
}
#endregion
#region Create the round extrusions
for (int i = 3; i <= 4; ++i)
{
// create the profile
profile = app.NewCurveArrArray();
curves = app.NewCurveArray();
plane = new Plane(profileData[i, 0], profileData[i, 1]);
curves.Append(app.NewArc(plane, arcRadius, 0, Math.PI * 2));
profile.Append(curves);
// create the sketch plane
plane = app.NewPlane(sketchPlaneData[i, 0], sketchPlaneData[i, 1]);
sketchPlane = f.NewSketchPlane(plane);
// create the extrusion
extrusions[i] = f.NewExtrusion(isSolid[i], profile, sketchPlane,
extrusionOffsets[i, 1]);
extrusions[i].StartOffset = extrusionOffsets[i, 0];
m_combineElements.Append(extrusions[i]);
}
#endregion
}
///
/// create the connectors on the extrusions
///
private void CreateConnectors()
{
List m_planarFaces = null;
Parameter param = null;
#region Create the Supply Air duct connector
// get the planar faces of extrusion1
m_planarFaces = GetPlanarFaces(extrusions[1]);
// create the Supply Air duct connector
DuctConnector connSupplyAir = f.NewDuctConnector(m_planarFaces[0].Reference,
DuctSystemType.SupplyAir);
param = connSupplyAir.get_Parameter(BuiltInParameter.CONNECTOR_HEIGHT);
param.Set(connectorDimensions[0, 0]);
param = connSupplyAir.get_Parameter(BuiltInParameter.CONNECTOR_WIDTH);
param.Set(connectorDimensions[0, 1]);
param = connSupplyAir.get_Parameter(BuiltInParameter.RBS_DUCT_FLOW_DIRECTION_PARAM);
param.Set(2);
param = connSupplyAir.get_Parameter(BuiltInParameter.RBS_DUCT_FLOW_CONFIGURATION_PARAM);
param.Set(1);
param = connSupplyAir.get_Parameter(BuiltInParameter.RBS_DUCT_FLOW_PARAM);
param.Set(flow);
#endregion
#region Create the Return Air duct connector
// get the planar faces of extrusion2
m_planarFaces = GetPlanarFaces(extrusions[2]);
// create the Return Air duct connector
DuctConnector connReturnAir = f.NewDuctConnector(m_planarFaces[0].Reference,
DuctSystemType.ReturnAir);
param = connReturnAir.get_Parameter(BuiltInParameter.CONNECTOR_HEIGHT);
param.Set(connectorDimensions[1, 0]);
param = connReturnAir.get_Parameter(BuiltInParameter.CONNECTOR_WIDTH);
param.Set(connectorDimensions[1, 1]);
param = connReturnAir.get_Parameter(BuiltInParameter.RBS_DUCT_FLOW_DIRECTION_PARAM);
param.Set(1);
param =
connReturnAir.get_Parameter(BuiltInParameter.RBS_DUCT_FLOW_CONFIGURATION_PARAM);
param.Set(1);
param = connReturnAir.get_Parameter(BuiltInParameter.RBS_DUCT_FLOW_PARAM);
param.Set(flow);
#endregion
#region Create the Supply Hydronic pipe connector
// get the planar faces of extrusion3
m_planarFaces = GetPlanarFaces(extrusions[3]);
// create the Hydronic Supply pipe connector
PipeConnector connSupplyHydronic = f.NewPipeConnector(m_planarFaces[0].Reference,
PipeSystemType.SupplyHydronic);
param = connSupplyHydronic.get_Parameter(BuiltInParameter.CONNECTOR_RADIUS);
param.Set(arcRadius);
param =
connSupplyHydronic.get_Parameter(BuiltInParameter.RBS_PIPE_FLOW_DIRECTION_PARAM);
param.Set(2);
#endregion
#region Create the Return Hydronic pipe connector
// get the planar faces of extrusion4
m_planarFaces = GetPlanarFaces(extrusions[4]);
// create the Hydronic Return pipe connector
PipeConnector connReturnHydronic = f.NewPipeConnector(m_planarFaces[0].Reference,
PipeSystemType.ReturnHydronic);
param = connReturnHydronic.get_Parameter(BuiltInParameter.CONNECTOR_RADIUS);
param.Set(arcRadius);
param =
connReturnHydronic.get_Parameter(BuiltInParameter.RBS_PIPE_FLOW_DIRECTION_PARAM);
param.Set(1);
#endregion
}
}
}