/// <summary> /// Add a roof over the rectangular profile of the walls we created earlier. /// </summary> public void AddRoof(List <Wall> walls) { // Hard coding the roof type we will use. // E.g., "Basic Roof: Generic - 400mm" const string roofFamilyName = "Basic Roof"; const string roofTypeName = Util.Constant.RoofTypeName; // Util.Constant.RoofTypeName const string roofFamilyAndTypeName = roofFamilyName + ": " + roofTypeName; // Find the roof type RoofType roofType = (RoofType)ElementFiltering.FindFamilyType(_doc, typeof(RoofType), roofFamilyName, roofTypeName, null); if (roofType == null) { TaskDialog.Show( "Add roof", "Cannot find (" + roofFamilyAndTypeName + "). Maybe you use a different template? Try with DefaultMetric.rte."); } // Wall thickness to adjust the footprint of the walls // to the outer most lines. // Note: this may not be the best way, // but we will live with this for this exercise. //double wallThickness = walls[0].WallType.CompoundStructure.Layers.get_Item(0).Thickness; // 2011 double wallThickness = walls[0].Width; double dt = wallThickness / 2.0; List <XYZ> dts = new List <XYZ>(5); dts.Add(new XYZ(-dt, -dt, 0.0)); dts.Add(new XYZ(dt, -dt, 0.0)); dts.Add(new XYZ(dt, dt, 0.0)); dts.Add(new XYZ(-dt, dt, 0.0)); dts.Add(dts[0]); // Set the profile from four walls CurveArray footPrint = new CurveArray(); for (int i = 0; i <= 3; i++) { LocationCurve locCurve = (LocationCurve)walls[i].Location; XYZ pt1 = locCurve.Curve.GetEndPoint(0) + dts[i]; XYZ pt2 = locCurve.Curve.GetEndPoint(1) + dts[i + 1]; Line line = Line.CreateBound(pt1, pt2); footPrint.Append(line); } // Get the level2 from the wall ElementId idLevel2 = walls[0].get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE).AsElementId(); //Level level2 = (Level)_doc.get_Element(idLevel2); // 2012 Level level2 = (Level)_doc.GetElement(idLevel2); // since 2013 // Footprint to morel curve mapping ModelCurveArray mapping = new ModelCurveArray(); // Create a roof. FootPrintRoof aRoof = _doc.Create.NewFootPrintRoof(footPrint, level2, roofType, out mapping); foreach (ModelCurve modelCurve in mapping) { aRoof.set_DefinesSlope(modelCurve, true); aRoof.set_SlopeAngle(modelCurve, 0.5); } }
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); } }
/// <summary> /// Add a roof over the rectangular profile of the walls we created earlier. /// </summary> public static void AddRoof(Document rvtDoc, List <Wall> walls) { // Hard coding the roof type we will use. // e.g., "Basic Roof: Generic - 400mm" const string roofFamilyName = "Basic Roof"; const string roofTypeName = Util.Constant.RoofTypeName; const string roofFamilyAndTypeName = roofFamilyName + ": " + roofTypeName; // Find the roof type RoofType roofType = ElementFiltering.FindFamilyType( rvtDoc, typeof(RoofType), roofFamilyName, roofTypeName, null ) as RoofType; if (roofType == null) { TaskDialog.Show( "Add roof", "Cannot find (" + roofFamilyAndTypeName + "). Maybe you use a different template? Try with DefaultMetric.rte."); } // Wall thickness to adjust the footprint of the walls // to the outer most lines. // Note: this may not be the best way. // but we will live with this for this exercise. //Dim wallThickness As Double = _ //walls(0).WallType.CompoundStructure.Layers.Item(0).Thickness() ' 2011 double wallThickness = walls[0].WallType.GetCompoundStructure().GetLayers()[0].Width; // 2012 double dt = wallThickness / 2.0; List <XYZ> dts = new List <XYZ>(5); dts.Add(new XYZ(-dt, -dt, 0.0)); dts.Add(new XYZ(dt, -dt, 0.0)); dts.Add(new XYZ(dt, dt, 0.0)); dts.Add(new XYZ(-dt, dt, 0.0)); dts.Add(dts[0]); // Set the profile from four walls CurveArray footPrint = new CurveArray(); for (int i = 0; i <= 3; i++) { LocationCurve locCurve = (LocationCurve)walls[i].Location; XYZ pt1 = locCurve.Curve.GetEndPoint(0) + dts[i]; XYZ pt2 = locCurve.Curve.GetEndPoint(1) + dts[i + 1]; Line line = Line.CreateBound(pt1, pt2); footPrint.Append(line); } // Get the level2 from the wall. ElementId idLevel2 = walls[0].get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE).AsElementId(); //Level level2 = (Level)_doc.get_Element(idLevel2); // 2012 Level level2 = rvtDoc.GetElement(idLevel2) as Level; // since 2013 // Footprint to model curve mapping. ModelCurveArray mapping = new ModelCurveArray(); // Create a roof. FootPrintRoof aRoof = rvtDoc.Create.NewFootPrintRoof( footPrint, level2, roofType, out mapping); // Set the slope. ///////////////////////////////////////////////// ///new mapping ///////////////////////////////////////////////// LocationCurve wallCurv1 = (LocationCurve)walls[1].Location; // set the gable roof slope ModelCurveArray mappingNew = new ModelCurveArray(); ModelCurve gableCurve1 = mapping.get_Item(1); ModelCurve gableCurve2 = mapping.get_Item(3); double a = wallCurv1.Curve.Length / 2.00; double b = 4.00; //double angleB = Math.Truncate( Math.Acos((c * c + a * a - b * b)/(2 * c * a)) * 100 ) / 100; // Math.PI * 180; /* The value is a 'slope' measurement. For example, 0.5 is one unit of rise for each 2 units of run. * this creates a slope of 26.57 degrees * (the arctangent of 0.5) * double angleBDegrees = angleBRadians * 180 / Math.PI; * double c = Math.Truncate(Math.Sqrt(a * a + b * b) * 100) / 100; * double c = Math.Sqrt(a * a + b * b); * double a = Math.Truncate(gableCurve1.GeometryCurve.Length /2.00 * 100) / 100; * //double a = gableCurve1.GeometryCurve.Length / 2.00; * //double n = wallCurv2.Curve.Length; * //// * * //double c = Math.Sqrt(a * a + b * b); * //double angleB = Math.Acos(c); * //find double slope A use pythagorum theroum * // set lines a and b, find c * * //double b = 4.00; // height should be 4' from center * ////// <<<hey hey hey hey hey hey herrrreeeeeeeeee <<<<<<<<<< * /////LocationCurve wallCurv2 = (LocationCurve)walls[3].Location; * */ double angleBRadians = Math.Atan(b / a); double angleB = Math.Tan(angleBRadians); TaskDialog.Show("Test Values", "lenght a: " + a + " length b: " + b + " radians: " + angleBRadians + " angle B: " + angleB); aRoof.set_DefinesSlope(gableCurve1, true); aRoof.set_SlopeAngle(gableCurve1, angleB); aRoof.set_DefinesSlope(gableCurve2, true); aRoof.set_SlopeAngle(gableCurve2, angleB); #region note text and abandoned code //foreach (ModelCurve modelCurve in mapping) //{ // aRoof.set_DefinesSlope(modelCurve, true); // aRoof.set_SlopeAngle(modelCurve, 0.5); //} // Performed automatically by transaction commit. //rvtDoc.Regenerate(); //rvtDoc.AutoJoinElements(); #endregion }
void f(Document doc) { // Before invoking this sample, select some walls // to add a roof over. Make sure there is a level // named "Roof" in the document. Level level = new FilteredElementCollector(doc) .OfClass(typeof(Level)) .Where <Element>(e => !string.IsNullOrEmpty(e.Name) && e.Name.Equals("Roof")) .FirstOrDefault <Element>() as Level; RoofType roofType = new FilteredElementCollector(doc) .OfClass(typeof(RoofType)) .FirstOrDefault <Element>() as RoofType; // Get the handle of the application Application application = doc.Application; // Define the footprint for the roof based on user selection CurveArray footprint = application.Create .NewCurveArray(); UIDocument uidoc = new UIDocument(doc); ICollection <ElementId> selectedIds = uidoc.Selection.GetElementIds(); if (selectedIds.Count != 0) { foreach (ElementId id in selectedIds) { Element element = doc.GetElement(id); Wall wall = element as Wall; if (wall != null) { LocationCurve wallCurve = wall.Location as LocationCurve; footprint.Append(wallCurve.Curve); continue; } ModelCurve modelCurve = element as ModelCurve; if (modelCurve != null) { footprint.Append(modelCurve.GeometryCurve); } } } else { throw new Exception( "Please select a curve loop, wall loop or " + "combination of walls and curves to " + "create a footprint roof."); } ModelCurveArray footPrintToModelCurveMapping = new ModelCurveArray(); FootPrintRoof footprintRoof = doc.Create.NewFootPrintRoof( footprint, level, roofType, out footPrintToModelCurveMapping); ModelCurveArrayIterator iterator = footPrintToModelCurveMapping.ForwardIterator(); iterator.Reset(); while (iterator.MoveNext()) { ModelCurve modelCurve = iterator.Current as ModelCurve; footprintRoof.set_DefinesSlope(modelCurve, true); footprintRoof.set_SlopeAngle(modelCurve, 0.5); } }
public void AddRoof(Document rvtDoc, List <Wall> walls) { // Hardcoding the roof type we will use. // e.g., "Basic Roof: Generic - 400mm" const string roofFamilyName = "Basic Roof"; const string roofTypeName = "Generic - 9\""; const string roofFamilyAndTypeName = roofFamilyName + ": " + roofTypeName; // Find the roof type RoofType roofType = (RoofType)ElementFiltering.FindFamilyType( rvtDoc, typeof(RoofType), roofFamilyName, roofTypeName, null); if (roofType == null) { TaskDialog.Show( "Add roof", "Cannot find (" + roofFamilyAndTypeName + "). Maybe you use a different template? Try with DefaultMetric.rte."); } /* * Wall thickness to adjust the footprint of the walls * to the outer most lines. * Note: This may not be the best way, * but we will live with this excercise. * DIM wallThickness as Double */ double wallThickness = walls[0].WallType.GetCompoundStructure().GetLayers()[0].Width; double dt = wallThickness / 2.0; List <XYZ> dts = new List <XYZ>(5); dts.Add(new XYZ(-dt, -dt, 0.0)); dts.Add(new XYZ(dt, -dt, 0.0)); dts.Add(new XYZ(dt, dt, 0.0)); dts.Add(new XYZ(-dt, dt, 0.0)); dts.Add(dts[0]); // set the profile from four wals CurveArray footPrint = new CurveArray(); for (int i = 0; i <= 3; i++) { LocationCurve locCurve = (LocationCurve)walls[i].Location; XYZ pt1 = locCurve.Curve.GetEndPoint(0) + dts[i]; XYZ pt2 = locCurve.Curve.GetEndPoint(1) + dts[i + 1]; Line line = Line.CreateBound(pt1, pt2); footPrint.Append(line); } ///////////////////////////////////////////////// ///new mapping ///////////////////////////////////////////////// Curve getCurveOne = footPrint.get_Item(1); Curve getCurveTwo = footPrint.get_Item(3); CurveArray gabledFootprint = new CurveArray(); gabledFootprint.Append(getCurveOne); gabledFootprint.Append(getCurveTwo); // get the lvl2 from wall ElementId idlvl2 = walls[0].get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE).AsElementId(); Level lvl2 = rvtDoc.GetElement(idlvl2) as Level; ModelCurveArray mapping = new ModelCurveArray(); // footprint to model curve mapping FootPrintRoof aRoof = rvtDoc.Create.NewFootPrintRoof(footPrint, lvl2, roofType, out mapping); //double offsetValue = 10; foreach /*set the slope */ (ModelCurve modelCurve in mapping) { aRoof.set_DefinesSlope(modelCurve, true); aRoof.set_SlopeAngle(modelCurve, 0.5); //aRoof.set_Offset(modelCurve, offsetValue); } /* performed automatically by transaction commit. * rvtDoc.Regenerate(); * rvtDoc.AutoJoinElement(); */ }