[TransactionAttribute(Autodesk.Revit.Attributes.TransactionMode.Manual)] public class cmdCreateSolid : IExternalCommand { // 创建封闭曲线 CurveArrArray createProfileLShape(Application _rvtApp) { // // define a simple L-shape profile // // 5 tw 4 // +-+ // | | 3 h = height // d | +---+ 2 // +-----+ td // 0 1 // 6 w // // sizes (hard coded for simplicity) // note: these need to match reference plane. otherwise, alignment won't work. // as an exercise, try changing those values and see how it behaves. // double w = Util.mmToFeet( 600.0); // those are hard coded for simplicity here. in practice, you may want to find out from the references) double d = Util.mmToFeet( 600.0); double tw = Util.mmToFeet( 150.0); // thickness added for Lab2 double td = Util.mmToFeet( 150.0); // define vertices // const int nVerts = 6; // the number of vertices XYZ[] pts = new XYZ[] { new XYZ(-w / 2.0, -d / 2.0, 0.0), new XYZ(w / 2.0, -d / 2.0, 0.0), new XYZ(w / 2.0, (-d / 2.0) + td, 0.0), new XYZ((-w / 2.0) + tw, (-d / 2.0) + td, 0.0), new XYZ((-w / 2.0) + tw, d / 2.0, 0.0), new XYZ(-w / 2.0, d / 2.0, 0.0), new XYZ(-w / 2.0, -d / 2.0, 0.0) }; // the last one is to make the loop simple // define a loop. define individual edges and put them in a curveArray // CurveArray pLoop = _rvtApp.Create.NewCurveArray(); for ( int i = 0; i < nVerts; ++i) { Line line = _rvtApp.Create.NewLineBound(pts[i], pts[i + 1]); pLoop.Append(line); } // then, put the loop in the curveArrArray as a profile // CurveArrArray pProfile = _rvtApp.Create.NewCurveArrArray(); pProfile.Append(pLoop); // if we come here, we have a profile now. return pProfile; } Extrusion CreateSolid(Application app, Document doc) { CurveArrArray pProfile = createProfileLShape(app); // 这个参考平面模板中没有,可以切换到Front立面,自己画一个。 ReferencePlane pRefPlane = Util.findElement(doc, typeof(ReferencePlane), " Reference Plane ") as ReferencePlane; SketchPlane pSketchPlane = doc.FamilyCreate.NewSketchPlane(pRefPlane.Plane); double dHeight = Util.mmToFeet( 4000); bool bIsSolid = true; Extrusion pSolid = doc.FamilyCreate.NewExtrusion(bIsSolid, pProfile, pSketchPlane, dHeight); return pSolid; } public Result Execute(ExternalCommandData commandData, ref string messages, ElementSet elements) { UIApplication app = commandData.Application; Document doc = app.ActiveUIDocument.Document; Transaction ts = new Transaction(doc, " AddType "); ts.Start(); // FamilyManager m_familyMgr = doc.FamilyManager; CreateSolid(app.Application, doc); ts.Commit(); return Result.Succeeded; } } public class Util { // Revit内部单位feet转化为mm即毫米 public static double mmToFeet( double val) { return val / 304.8; } public static double feetToMm( double val) { return val * 304.8; } // 通过类型与名称找Element public static Element findElement(Document _rvtDoc, Type targetType, string targetName) { // get the elements of the given type // FilteredElementCollector collector = new FilteredElementCollector(_rvtDoc); collector.WherePasses( new ElementClassFilter(targetType)); // parse the collection for the given name // using LINQ query here. // var targetElems = from element in collector where element.Name.Equals(targetName) select element; List<Element> elems = targetElems.ToList<Element>(); if (elems.Count > 0) { // we should have only one with the given name. return elems[ 0]; } // cannot find it. return null; } #region Formatting and message handlers public const string Caption = " Revit Family API Labs "; /// <summary> /// MessageBox wrapper for informational message. /// </summary> public static void InfoMsg( string msg) { System.Diagnostics.Debug.WriteLine(msg); WinForm.MessageBox.Show(msg, Caption, WinForm.MessageBoxButtons.OK, WinForm.MessageBoxIcon.Information); } /// <summary> /// MessageBox wrapper for error message. /// </summary> public static void ErrorMsg( string msg) { WinForm.MessageBox.Show(msg, Caption, WinForm.MessageBoxButtons.OK, WinForm.MessageBoxIcon.Error); } #endregion // Formatting and message handlers }