// Rveit API .NET Sample // // Copyright (c) 2005-2006 by Autodesk, Inc. // // Permission to use, copy, modify, and distribute this software // 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 System.Windows.Forms; using Autodesk; using Autodesk.Revit; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Structure; namespace RevitLookup.Test.SDKSamples.StructuralSample { /// /// .Net sample: StructSample. /// /// This command places a set of coulmns in the selected wall. /// /// Note that Revit uses Feet as an internal length unit. /// /// (1) Draw some walls, and constrain their top and bottom to the levels in the properties dialog. /// (2) Run the test. /// It will place columns along each wall with the interval of 5 feet. (The interval is also hard coded.) /// /// public class StructSample { Autodesk.Revit.UI.UIApplication m_app = null; Autodesk.Revit.DB.ElementSet m_ss = null; public StructSample(Autodesk.Revit.UI.UIApplication app, ElementSet ss) { m_app = app; m_ss = ss; } /// /// /// /// public Boolean ExecuteStructSample() { Document rvtDoc = m_app.ActiveUIDocument.Document; FamilySymbol colType = null; List walls = new List(); // iterate through a selection set, and collect walls which are constrained at the top and the bottom. // foreach (Element elem in m_ss) { if (elem.GetType() == typeof(Autodesk.Revit.DB.Wall)) { if (elem.get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE) != null && elem.get_Parameter(BuiltInParameter.WALL_BASE_CONSTRAINT) != null) { walls.Add(elem as Wall); } } } // how many did we get? MessageBox.Show("Number of constrained walls in the selection set is " + walls.Count); if (walls.Count == 0) { DialogResult dlgRes = MessageBox.Show("You must select some walls that are constrained top or bottom", "Structural Sample", MessageBoxButtons.OK, MessageBoxIcon.Information); if (dlgRes == System.Windows.Forms.DialogResult.OK) { return false; } } // we have some # of walls now. // Load the required family FilteredElementCollector collect = new FilteredElementCollector(rvtDoc); ElementClassFilter familyAreWanted = new ElementClassFilter(typeof(Family)); collect.WherePasses(familyAreWanted); List elements = collect.ToElements() as List; foreach (Element e in elements) { Family fam = e as Family; if (fam != null) { if (fam.Name == "M_Wood Timber Column") { colType = Utils.FamilyUtil.GetFamilySymbol(fam, "191 x 292mm"); } } } String fileName = "../Data/Platform/Metric/Library/Architectural/Columns/M_Wood Timber Column.rfa"; Family columnFamily; if (colType == null) { m_app.ActiveUIDocument.Document.LoadFamily(fileName, out columnFamily); colType = Utils.FamilyUtil.GetFamilySymbol(columnFamily, "191 x 292mm"); } if (colType == null) { MessageBox.Show("Please load the M_Wood Timber Column : 191 x 292mm family"); Utils.UserInput.LoadFamily(null, m_app.ActiveUIDocument.Document); } // // place columns. // double spacing = 5; // Spacing in feet hard coded. Note: Revit's internal length unit is feet. foreach (Autodesk.Revit.DB.Wall wall in walls) { FrameWall(m_app.Application, wall, spacing, colType); } return true; } /// /// Frame a wall. /// /// /// /// /// private void FrameWall(Autodesk.Revit.ApplicationServices.Application rvtApp, Autodesk.Revit.DB.Wall wall, double spacing, FamilySymbol columnType) { Document rvtDoc = wall.Document; LocationCurve loc = (LocationCurve)wall.Location; XYZ startPt = loc.Curve.get_EndPoint(0); XYZ endPt = loc.Curve.get_EndPoint(1); UV wallVec = new UV(endPt.X - startPt.X, endPt.Y - startPt.Y); UV axis = new UV(1.0, 0.0); ElementId baseLevelId = wall.get_Parameter(BuiltInParameter.WALL_BASE_CONSTRAINT).AsElementId(); ElementId topLevelId = wall.get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE).AsElementId(); double wallLength = VecLength(wallVec); wallVec = VecNormalise(wallVec); int nmax = (int)(wallLength / spacing); MessageBox.Show("Wall Length = " + wallLength + "\nSpacing = " + spacing + "\nMax Number = " + nmax, "Structural Sample", MessageBoxButtons.OK, MessageBoxIcon.Information); double angle = VecAngle(wallVec, axis); XYZ loc2 = startPt; double dx = wallVec.U * spacing; double dy = wallVec.V * spacing; for (int i = 0; i < nmax; i++) { PlaceColumn(rvtApp, rvtDoc, loc2, angle, columnType, baseLevelId, topLevelId); loc2 = new XYZ(startPt.X + dx, startPt.Y + dy, startPt.Z); } PlaceColumn(rvtApp, rvtDoc, endPt, angle, columnType, baseLevelId, topLevelId); } /// /// Create a column instance and place it on the wall line. /// /// /// /// /// /// /// /// private void PlaceColumn(Autodesk.Revit.ApplicationServices.Application rvtApp, Document rvtDoc, Autodesk.Revit.DB.XYZ point2, double angle, FamilySymbol columnType, ElementId baseLevelId, ElementId topLevelId) { Autodesk.Revit.DB.XYZ point = point2; // Note: Must use level-hosted NewFamilyInstance! Level instLevel = (Level)rvtDoc.get_Element(baseLevelId); Autodesk.Revit.DB.FamilyInstance column = rvtDoc.Create.NewFamilyInstance(point, columnType, instLevel, StructuralType.Column); if (column == null) { MessageBox.Show("failed to create an instance of a column."); return; } Autodesk.Revit.DB.XYZ zVec = new Autodesk.Revit.DB.XYZ(0, 0, 1); Autodesk.Revit.DB.Line axis = rvtApp.Create.NewLineUnbound(point, zVec); column.Location.Rotate(axis, angle); // Set the level Ids Parameter baseLevelParameter = column.get_Parameter(Autodesk.Revit.DB.BuiltInParameter.FAMILY_BASE_LEVEL_PARAM); Parameter topLevelParameter = column.get_Parameter(Autodesk.Revit.DB.BuiltInParameter.FAMILY_TOP_LEVEL_PARAM); ; baseLevelParameter.Set(baseLevelId); topLevelParameter.Set(topLevelId); } // // helper functions. // /// /// /// /// /// private double VecLength(UV v) { double len = v.U * v.U + v.V * v.V; len = Math.Sqrt(len); return (len); } /// /// /// /// /// private UV VecNormalise(UV v) { double len = VecLength(v); UV newV = new UV(v.U / len, v.V / len); return (newV); } /// /// /// /// /// /// private double VecDot(UV va, UV vb) { return ((va.U * vb.U) + (va.V * vb.V)); } /// /// /// /// /// private double ACos(double d) { // we probably need to consider tolerance here. if (Math.Abs(d) != 1.0) { return (1.5707963267949 - Math.Atan(d / Math.Sqrt(1.0 - d * d))); } if (d == -1.0) { return 3.14159265358979; } return 0.0; } /// /// /// /// /// /// private double VecAngle(UV va, UV vb) { UV vecA = VecNormalise(va); UV vecB = VecNormalise(vb); return (ACos(VecDot(vecA, vecB))); } } }