/// <summary> /// Create a room on a given level. /// </summary> void CreateRoom( Document doc, Level level) { Application app = doc.Application; Autodesk.Revit.Creation.Application appCreation = app.Create; Autodesk.Revit.Creation.Document docCreation = doc.Create; XYZ pt1 = new XYZ(0, -5, 0); XYZ pt2 = new XYZ(0, 5, 0); XYZ pt3 = new XYZ(8, 5, 0); XYZ pt4 = new XYZ(8, -5, 0); Line line1 = Line.CreateBound(pt1, pt2); Line line2 = Line.CreateBound(pt2, pt3); Line line3 = Line.CreateBound(pt3, pt4); Line line4 = Line.CreateBound(pt4, pt1); CurveArray curveArr = new CurveArray(); curveArr.Append(line1); curveArr.Append(line2); curveArr.Append(line3); curveArr.Append(line4); docCreation.NewRoomBoundaryLines( doc.ActiveView.SketchPlane, curveArr, doc.ActiveView); // Create a new room UV tagPoint = new UV(4, 0); Room room = docCreation.NewRoom( level, tagPoint); if (null == room) { throw new Exception( "Create a new room failed."); } room.Number = "42"; room.Name = "Lobby"; // Creation.Document.NewRoomTag( Room, UV, View) is obsolete. // Use the NewRoomTag(LinkElementId, UV, ElementId) overload instead. //RoomTag tag = docCreation.NewRoomTag( room, tagPoint, doc.ActiveView ); // 2013 RoomTag tag = docCreation.NewRoomTag( new LinkElementId(room.Id), tagPoint, doc.ActiveView.Id); // 2014 }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { try { WaitCursor waitCursor = new WaitCursor(); UIApplication app = commandData.Application; Document doc = app.ActiveUIDocument.Document; Autodesk.Revit.Creation.Application createApp = app.Application.Create; Autodesk.Revit.Creation.Document createDoc = doc.Create; using (Transaction t = new Transaction(doc)) { t.Start("Create Little House"); // Determine the four corners of the rectangular house: double width = 7 * LabConstants.MeterToFeet; double depth = 4 * LabConstants.MeterToFeet; List <XYZ> corners = new List <XYZ>(4); corners.Add(XYZ.Zero); corners.Add(new XYZ(width, 0, 0)); corners.Add(new XYZ(width, depth, 0)); corners.Add(new XYZ(0, depth, 0)); #region Test creating two levels #if CREATE_TWO_LEVELS Level levelBottom = null; Level levelMiddle = null; Level levelTop = null; List <Element> levels = new List <Element>(); Filter filterType = createApp.Filter.NewTypeFilter( typeof(Level)); doc.get_Elements(filterType, levels); foreach (Element e in levels) { if (null == levelBottom) { levelBottom = e as Level; } else if (null == levelMiddle) { levelMiddle = e as Level; } else if (null == levelTop) { levelTop = e as Level; } else { break; } } BuiltInParameter topLevelParam = BuiltInParameter.WALL_HEIGHT_TYPE; Line line; Wall wall; Parameter param; ElementId topId = levelMiddle.Id; List <Wall> walls = new List <Wall>(8); for (int i = 0; i < 4; ++i) { line = createApp.NewLineBound( corners[i], corners[3 == i ? 0 : i + 1]); wall = createDoc.NewWall( line, levelBottom, false); param = wall.get_Parameter(topLevelParam); param.Set(ref topId); walls.Add(wall); } topId = levelTop.Id; for (int i = 0; i < 4; ++i) { line = createApp.NewLineBound( corners[i], corners[3 == i ? 0 : i + 1]); wall = createDoc.NewWall( line, levelMiddle, false); param = wall.get_Parameter(topLevelParam); param.Set(ref topId); walls.Add(wall); } List <Element> doorSymbols = LabUtils.GetAllFamilySymbols( app, BuiltInCategory.OST_Doors); Debug.Assert( 0 < doorSymbols.Count, "expected at least one door symbol" + " to be loaded into project"); FamilySymbol door = doorSymbols[0] as FamilySymbol; XYZ midpoint = LabUtils.Midpoint( corners[0], corners[1]); FamilyInstance inst0 = createDoc.NewFamilyInstance( midpoint, door, walls[0], levelBottom, StructuralType.NonStructural); midpoint.Z = levelMiddle.Elevation; FamilyInstance inst1 = createDoc.NewFamilyInstance( midpoint, door, walls[4], levelMiddle, StructuralType.NonStructural); #endif // CREATE_TWO_LEVELS #endregion // Test creating two levels // Determine the levels where the walls will be located: Level levelBottom = null; Level levelTop = null; if (!LabUtils.GetBottomAndTopLevels(doc, ref levelBottom, ref levelTop)) { message = "Unable to determine wall bottom and top levels"; return(Result.Failed); } Debug.Print(string.Format("Drawing walls on '{0}' up to '{1}'", levelBottom.Name, levelTop.Name)); // Create the walls: BuiltInParameter topLevelParam = BuiltInParameter.WALL_HEIGHT_TYPE; ElementId levelBottomId = levelBottom.Id; ElementId topLevelId = levelTop.Id; List <Wall> walls = new List <Wall>(4); for (int i = 0; i < 4; ++i) { Line line = Line.CreateBound(corners[i], corners[3 == i ? 0 : i + 1]); //Wall wall = createDoc.NewWall( line, levelBottom, false ); // 2012 Wall wall = Wall.Create(doc, line, levelBottomId, false); // 2013 Parameter param = wall.get_Parameter(topLevelParam); param.Set(topLevelId); walls.Add(wall); } // Determine wall thickness for tag offset and profile growth: //double wallThickness = walls[0].WallType.CompoundStructure.Layers.get_Item( 0 ).Thickness; // 2011 //double wallThickness = walls[0].WallType.GetCompoundStructure().GetLayers()[0].Width; // 2012 double wallThickness = walls[0].WallType.Width; // simpler and more direct property available in 2012 // Add door and windows to the first wall; // note that the NewFamilyInstance() api method does not automatically add door // and window tags, like the ui command does. we add tags here by making additional calls // to NewTag(): FamilySymbol door = LabUtils.GetFirstFamilySymbol(doc, BuiltInCategory.OST_Doors); if (null == door) { LabUtils.InfoMsg("No door symbol found."); return(Result.Failed); } FamilySymbol window = LabUtils.GetFirstFamilySymbol( doc, BuiltInCategory.OST_Windows); if (null == window) { LabUtils.InfoMsg("No window symbol found."); return(Result.Failed); } XYZ midpoint = LabUtils.Midpoint(corners[0], corners[1]); XYZ p = LabUtils.Midpoint(corners[0], midpoint); XYZ q = LabUtils.Midpoint(midpoint, corners[1]); double tagOffset = 3 * wallThickness; //double windowHeight = 1 * LabConstants.MeterToFeet; double windowHeight = levelBottom.Elevation + 0.3 * ( levelTop.Elevation - levelBottom.Elevation); p = new XYZ(p.X, p.Y, windowHeight); q = new XYZ(q.X, q.Y, windowHeight); View view = doc.ActiveView; door.Activate(); // 2016 FamilyInstance inst = createDoc.NewFamilyInstance( midpoint, door, walls[0], levelBottom, StructuralType.NonStructural); midpoint += tagOffset * XYZ.BasisY; //IndependentTag tag = createDoc.NewTag( // view, inst, false, TagMode.TM_ADDBY_CATEGORY, // TagOrientation.Horizontal, midpoint ); // 2017 IndependentTag tag = IndependentTag.Create( doc, view.Id, new Reference(inst), false, TagMode.TM_ADDBY_CATEGORY, TagOrientation.Horizontal, midpoint); // 2018 IList <FamilyPointPlacementReference> fpprefs = inst.GetFamilyPointPlacementReferences(); IList <Reference> refs = inst.GetReferences(FamilyInstanceReferenceType.CenterLeftRight); //IndependentTag tag = IndependentTag.Create( doc, // view.Id, refs[0], false, TagMode.TM_ADDBY_CATEGORY, // TagOrientation.Horizontal, midpoint ); // 2018 window.Activate(); // 2016 inst = createDoc.NewFamilyInstance(p, window, walls[0], levelBottom, StructuralType.NonStructural); p += tagOffset * XYZ.BasisY; //tag = createDoc.NewTag( view, inst, // false, TagMode.TM_ADDBY_CATEGORY, // TagOrientation.Horizontal, p ); // 2017 tag = IndependentTag.Create( doc, view.Id, new Reference(inst), false, TagMode.TM_ADDBY_CATEGORY, TagOrientation.Horizontal, p); // 2018 inst = createDoc.NewFamilyInstance(q, window, walls[0], levelBottom, StructuralType.NonStructural); q += tagOffset * XYZ.BasisY; //tag = createDoc.NewTag( view, inst, // false, TagMode.TM_ADDBY_CATEGORY, // TagOrientation.TAG_HORIZONTAL, q ); // 2011 //tag = createDoc.NewTag( view, inst, // false, TagMode.TM_ADDBY_CATEGORY, // TagOrientation.Horizontal, q ); // 2012 tag = IndependentTag.Create( doc, view.Id, new Reference(inst), false, TagMode.TM_ADDBY_CATEGORY, TagOrientation.Horizontal, p); // 2018 // Grow the profile out by half the wall thickness, // so the floor and roof do not stop halfway through the wall: double w = 0.5 * wallThickness; corners[0] -= w * (XYZ.BasisX + XYZ.BasisY); corners[1] += w * (XYZ.BasisX - XYZ.BasisY); corners[2] += w * (XYZ.BasisX + XYZ.BasisY); corners[3] -= w * (XYZ.BasisX - XYZ.BasisY); CurveArray profile = new CurveArray(); for (int i = 0; i < 4; ++i) { //Line line = createApp.NewLineBound( // 2013 Line line = Line.CreateBound( // 2014 corners[i], corners[3 == i ? 0 : i + 1]); profile.Append(line); } // Add a floor, a roof and the roof slope: bool structural = false; Floor floor = createDoc.NewFloor( profile, structural); List <Element> roofTypes = new List <Element>( LabUtils.GetElementsOfType( doc, typeof(RoofType), BuiltInCategory.OST_Roofs)); Debug.Assert(0 < roofTypes.Count, "expected at least one roof type" + " to be loaded into project"); // Ensure that we get a valid roof type. // In Revit 2013, the first one encountered // is sloped glazing with zero entries in // its compound layers; actually, the entire // compound structure is null: //RoofType roofType = null; //foreach( RoofType rt in roofTypes ) //{ // CompoundStructure cs = rt.GetCompoundStructure(); // if( null != cs // && 0 < cs.GetLayers().Count ) // { // roofType = rt; // break; // } //} RoofType roofType = roofTypes .Cast <RoofType>() .FirstOrDefault <RoofType>(typ => null != typ.GetCompoundStructure()); ModelCurveArray modelCurves = new ModelCurveArray(); FootPrintRoof roof = createDoc.NewFootPrintRoof(profile, levelTop, roofType, out modelCurves); // Regenerate the model after roof creation, // otherwise the calls to set_DefinesSlope and // set_SlopeAngle throw the exception "Unable // to access curves from the roof sketch." doc.Regenerate(); // The argument to set_SlopeAngle is NOT an // angle, it is really a slope, i.e. relation // of height to distance, e.g. 0.5 = 6" / 12", // 0.75 = 9" / 12", etc. double slope = 0.3; foreach (ModelCurve curve in modelCurves) { roof.set_DefinesSlope(curve, true); roof.set_SlopeAngle(curve, slope); } // Add a room and a room tag: Room room = createDoc.NewRoom(levelBottom, new UV(0.5 * width, 0.5 * depth)); //RoomTag roomTag = createDoc.NewRoomTag( // room, new UV( 0.5 * width, 0.7 * depth ), // null ); // 2014 RoomTag roomTag = createDoc.NewRoomTag( new LinkElementId(room.Id), new UV(0.5 * width, 0.7 * depth), null); // 2015 //doc.AutoJoinElements(); // todo: remove this, the transaction should perform this automatically //LabUtils.InfoMsg( "Little house was created successfully." ); //#region Test setting BaseOffset and LimitOffset //// 11334196 [Failed to set Room.BaseOffset and Room.LimitOffset properties] //double h = 0.123; //room.BaseOffset = -h; //room.LimitOffset = h + h; //#endregion // Test setting BaseOffset and LimitOffset t.Commit(); return(Result.Succeeded); } } catch (Exception ex) { message = ex.Message; return(Result.Failed); } }