Revit Macro: Generate sections and views of beams and columns
This macro creates sections and views of beams and columns.
Macro works with beams in plane and inclined beams.And also with usual and inclined columns.
In current example macro creates one side view to beam/column and 3 cross sections along beam/column. This sections can be used to show rebars in RC structures, for example:
Macro works with beams in plane and inclined beams.And also with usual and inclined columns.
In current example macro creates one side view to beam/column and 3 cross sections along beam/column. This sections can be used to show rebars in RC structures, for example:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Created by SharpDevelop. | |
* User: Nikolai.B | |
* Date: 02.10.2019 | |
* Time: 10:05 | |
* | |
* To change this template use Tools | Options | Coding | Edit Standard Headers. | |
*/ | |
using System; | |
using Autodesk.Revit.UI; | |
using Autodesk.Revit.DB; | |
using Autodesk.Revit.UI.Selection; | |
using System.Collections.Generic; | |
using System.Linq; | |
namespace BeamSections | |
{ | |
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)] | |
[Autodesk.Revit.DB.Macros.AddInId("51385248-3728-4704-B8CB-A3761C5E7AEC")] | |
public partial class ThisDocument | |
{ | |
//Rename it according to template: | |
string sectionViewTemplate = "70 - Sh - RC Section"; //Template for section | |
string detailViewTemplate = "70 - Sh - RC Detail"; //Template for detail | |
private void Module_Startup(object sender, EventArgs e) | |
{ | |
} | |
private void Module_Shutdown(object sender, EventArgs e) | |
{ | |
} | |
private void CreateBeamSection (Document doc, string sectionViewTemplate, FamilyInstance beam, double locat, bool parallel = false) | |
{ | |
ViewFamilyType vft = null; | |
FilteredElementCollector coll = new FilteredElementCollector(doc).OfClass(typeof(ViewFamilyType)); | |
foreach (Element element in coll) | |
{ | |
if (element.Name.Equals(sectionViewTemplate)) | |
{ | |
vft = element as ViewFamilyType; | |
} | |
} | |
if (vft == null) | |
{ | |
TaskDialog.Show("Error", "Template "+sectionViewTemplate+" not found"); | |
} | |
else | |
{ | |
LocationCurve beamline = beam.Location as LocationCurve; | |
Line line = beamline.Curve as Line; | |
XYZ p = line.GetEndPoint( 0 ); //начало балки | |
XYZ q = line.GetEndPoint( 1 ); //конец балки | |
XYZ v = q - p; | |
BoundingBoxXYZ bb = beam.get_BoundingBox( null ); | |
double minZ = bb.Min.Z; //верх балки | |
double maxZ = bb.Max.Z; //низ балки | |
double w = v.GetLength(); //длина балки | |
double h = maxZ - minZ; //высота балки | |
double offset = 0.1 * w; //отступ вида по краям балки | |
// min max для разреза вдоль балки | |
XYZ min = new XYZ( -offset, minZ - offset, -offset ); | |
XYZ max = new XYZ( offset, maxZ + offset, 0 ); | |
XYZ beamdir = v.Normalize(); | |
XYZ midpoint = (p + locat * v)+beamdir*offset; | |
XYZ upbasis = XYZ.BasisZ; | |
XYZ viewdir = -beamdir.CrossProduct( upbasis ); | |
XYZ up = beamdir.CrossProduct( viewdir ); | |
up=up.Normalize(); | |
viewdir=viewdir.Normalize(); | |
Transform t = Transform.Identity; | |
t.Origin = midpoint; | |
t.BasisX = viewdir; | |
t.BasisY = up; | |
t.BasisZ = beamdir; | |
if (parallel) //изменение параметров для разреза вдоль балки | |
{ | |
min = new XYZ( -w/2-offset, minZ - offset, -offset ); | |
max = new XYZ( w/2+offset, maxZ + offset, offset/2 ); | |
midpoint = (p + 0.5 * v); | |
t.Origin = midpoint; | |
XYZ newX=new XYZ(beamdir.X, beamdir.Y, 0).Normalize(); | |
t.BasisX = newX; | |
t.BasisY = XYZ.BasisZ; | |
t.BasisZ = newX.CrossProduct(XYZ.BasisZ).Normalize(); | |
} | |
BoundingBoxXYZ sectionBox = new BoundingBoxXYZ(); | |
sectionBox.Transform = t; | |
sectionBox.Min = min; | |
sectionBox.Max = max; | |
var section= ViewSection.CreateSection( doc, vft.Id, sectionBox ); | |
} | |
} | |
private void CreateColumnSection (Document doc, string detailViewTemplate, FamilyInstance column, double locat, bool parallel = false) | |
{ | |
ViewFamilyType vft = null; | |
FilteredElementCollector coll = new FilteredElementCollector(doc).OfClass(typeof(ViewFamilyType)); | |
foreach (Element element in coll) | |
{ | |
if (element.Name.Equals(detailViewTemplate)) | |
{ | |
vft = element as ViewFamilyType; | |
} | |
} | |
if (vft == null) | |
{ | |
TaskDialog.Show("Error", "Template "+detailViewTemplate+" not found"); | |
} | |
else | |
{ | |
try | |
{ | |
LocationPoint columnbase = column.Location as LocationPoint; | |
XYZ basePoint = columnbase.Point as XYZ; //Основание колонны | |
BoundingBoxXYZ bb = column.get_BoundingBox( null ); | |
double minZ = bb.Min.Z; | |
double maxZ = bb.Max.Z; | |
double minX = bb.Min.X; | |
double maxX = bb.Max.X; | |
double minY = bb.Min.Y; | |
double maxY = bb.Max.Y; | |
XYZ p= new XYZ(basePoint.X,basePoint.Y,minZ); //основание колонны | |
XYZ q= new XYZ(basePoint.X,basePoint.Y,maxZ); //верх колонны | |
XYZ v = q - p; //вектор колонны | |
double w = v.GetLength(); //длина балки | |
double h = maxZ - minZ; //высота балки | |
double offset = 0.1 * w; //отступ вида по краям балки | |
// min max для разреза вдоль балки | |
XYZ min = new XYZ( -(maxX-minX), -(maxY-minY), -offset ); | |
XYZ max = new XYZ( (maxX-minX), (maxY-minY), 0 ); | |
XYZ beamdir = v.Normalize(); | |
XYZ midpoint = (p + locat * v)-beamdir*offset; | |
XYZ up = XYZ.BasisZ; | |
//XYZ viewdir = beamdir.CrossProduct( up ); | |
XYZ toX = XYZ.BasisX; | |
XYZ toY = XYZ.BasisY; | |
Transform t = Transform.Identity; | |
t.Origin = midpoint; | |
t.BasisX = toX; | |
t.BasisY = -toY; | |
t.BasisZ = -up; | |
if (parallel) //изменение параметров для разреза вдоль балки | |
{ | |
min = new XYZ( -(maxX-minX),-w/2-offset,-(maxY-minY) ); | |
max = new XYZ( (maxX-minX), w/2+offset,(maxY-minY) ); | |
midpoint = (p + 0.5 * v); | |
t.Origin = midpoint; | |
t.BasisX = -toX; | |
t.BasisY = up; | |
t.BasisZ = toY; | |
} | |
BoundingBoxXYZ sectionBox = new BoundingBoxXYZ(); | |
sectionBox.Transform = t; | |
sectionBox.Min = min; | |
sectionBox.Max = max; | |
var section= ViewSection.CreateDetail( doc, vft.Id, sectionBox ); | |
} | |
catch(Exception e) | |
{ | |
TaskDialog.Show("Error", e.ToString()); | |
} | |
} | |
} | |
public void CreateSections() | |
{ | |
//var uidoc = this.ActiveUIDocument; //use this line if you are adding it to application | |
var uidoc = Application.ActiveUIDocument; //and for project | |
Document doc = uidoc.Document; | |
Selection sel = uidoc.Selection; | |
ICollection<ElementId> selectedIds = uidoc.Selection.GetElementIds(); | |
FamilyInstance beam=null; | |
FamilyInstance column=null; | |
// check user selection | |
if (selectedIds.Count < 1) | |
{ | |
TaskDialog.Show("Создать разрезы по балке/колонне", "Выберите балку или колонну для создания разрезов"); | |
return; | |
} | |
else | |
if (selectedIds.Count > 1) | |
{ | |
TaskDialog.Show("Создать разрезы по балке/колонне", "Выберите только 1 балку или колонну для создания разрезов"); | |
return; | |
} | |
else | |
{ | |
foreach (ElementId idd in selectedIds) | |
{ | |
Element elem = doc.GetElement(idd); | |
if (elem.Category.Name.Equals("Structural Framing")) | |
{ | |
beam = elem as FamilyInstance; | |
} | |
else | |
if(elem.Category.Name.Equals("Structural Columns")) | |
{ | |
//проверка на наклонную колонну, если колонна наклонная сечения строятся как для балки | |
var col=elem as FamilyInstance; | |
if(col.IsSlantedColumn) | |
{ | |
beam = elem as FamilyInstance; | |
} | |
else | |
column=elem as FamilyInstance; | |
} | |
else | |
TaskDialog.Show("error", "Балка или колонна не найдены"); | |
} | |
using (Transaction tt = new Transaction(doc, "Create Sections")) | |
{ | |
tt.Start(); | |
if(beam!=null) | |
{ | |
//параллельный разрез | |
CreateBeamSection (doc, sectionViewTemplate, beam, 0.5, true); | |
//перпендикулярные разрезы: | |
CreateBeamSection (doc, sectionViewTemplate, beam, 0.2); | |
CreateBeamSection (doc, sectionViewTemplate, beam, 0.5); | |
CreateBeamSection (doc, sectionViewTemplate, beam, 0.8); | |
} | |
else | |
if (column!=null) | |
{ | |
//параллельный разрез | |
CreateColumnSection (doc, detailViewTemplate, column, 0.5, true); | |
//перпендикулярные разрезы: | |
CreateColumnSection (doc, detailViewTemplate, column, 0.2); | |
CreateColumnSection (doc, detailViewTemplate, column, 0.5); | |
CreateColumnSection (doc, detailViewTemplate, column, 0.8); | |
} | |
tt.Commit(); | |
} | |
} | |
} | |
#region Revit Macros generated code | |
private void InternalStartup() | |
{ | |
this.Startup += new System.EventHandler(Module_Startup); | |
this.Shutdown += new System.EventHandler(Module_Shutdown); | |
} | |
#endregion | |
} | |
} |
Comments
Post a Comment