Revit二次开发之梁随板
这个demo实现了梁随斜板的功能:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.UI;
using Autodesk.Revit.Attributes;
namespace 梁随板
{
[Autodesk.Revit.Attributes.Transaction(TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(RegenerationOption.Manual)]
[Autodesk.Revit.Attributes.Journaling(JournalingMode.UsingCommandData)]
public class Command:IExternalCommand
{
public Result Execute(ExternalCommandData commandData,ref string message,ElementSet elementSet)
{
UIDocument uidoc = commandData.Application.ActiveUIDocument;
Document doc = uidoc.Document;
Selection selection = uidoc.Selection;
//楼板
Reference refFloor = selection.PickObject(ObjectType.Element, new FloorFilter(), "请选择楼板");
Floor floor = doc.GetElement(refFloor) as Floor;
//梁
IList<Reference> references = selection.PickObjects(ObjectType.Element,new BeamFilter(), "请选择需要的梁");
List<ElementId> ids = new List<ElementId>();
foreach(Reference reff in references)
{
ElementId id = doc.GetElement(reff).Id;
ids.Add(id);
}
FilteredElementCollector Beams = new FilteredElementCollector(doc, ids);
IList<Element> beams = Beams.OfCategory(BuiltInCategory.OST_StructuralFraming).ToList();
ids.Clear();
foreach(Element elem in beams)
{
ids.Add(elem.Id);
}
//分开楼板和梁
for(int i=0;i<ids.Count;i++)
{
Floor fl = doc.GetElement(ids[i]) as Floor;
if(fl!=null)
{
floor = fl;
ids.RemoveAt(i);
break;
}
}
// TaskDialog.Show("beam", ids.Count.ToString());
using (Transaction ts = new Transaction(doc))
{
ts.Start("梁随板");
BeamALignToFloor(doc, floor, ids);
ts.Commit();
}
return Result.Succeeded;
}
/// <summary>
/// 主函数
/// </summary>
/// <param name="doc"></param>
/// <param name="floor"></param>
/// <param name="beamIds"></param>
public static void BeamALignToFloor(Document doc,Floor floor,List<ElementId> beamIds)
{
foreach(ElementId id in beamIds)
{
Element beam = doc.GetElement(id);
LocationCurve lc = beam.Location as LocationCurve;
//获取楼板的下面的面
Reference bottomFaceref = HostObjectUtils.GetBottomFaces(floor).First();
Face bottomFace = floor.GetGeometryObjectFromReference(bottomFaceref) as Face;
PlanarFace planarFace = bottomFace as PlanarFace;
//面的信息
XYZ planarNormal = planarFace.FaceNormal;
XYZ planeOrigin = planarFace.Origin;
Plane plane = new Plane(planarNormal, planeOrigin);
//设置Transform信息
Transform trans = Transform.Identity;
trans.Origin = planeOrigin;
trans.BasisX = planarFace.XVector;
trans.BasisY = planarFace.YVector;
trans.BasisZ = planarNormal;
Line locationLine = lc.Curve as Line;
XYZ start_pt = locationLine.GetEndPoint(0);
XYZ end_pt = locationLine.GetEndPoint(1);
XYZ startpo_intrans = trans.Inverse.OfPoint(start_pt);
XYZ endpo_intrans = trans.Inverse.OfPoint(end_pt);
XYZ startPoint_Project = new XYZ(startpo_intrans.X, startpo_intrans.Y, 0);
XYZ endPoint_Project = new XYZ(endpo_intrans.X, endpo_intrans.Y, 0);
startPoint_Project = trans.OfPoint(startPoint_Project);
endPoint_Project = trans.OfPoint(endPoint_Project);
lc.Curve = Line.CreateBound(startPoint_Project, endPoint_Project);
}
}
}
/// <summary>
/// 过滤族实例
/// </summary>
public class BeamFilter:ISelectionFilter
{
public bool AllowElement(Element elem)
{
FamilyInstance fm = elem as FamilyInstance;
if (fm!= null )
{
return true;
}
else return false;
}
public bool AllowReference(Reference reference, XYZ position)
{
return true;
}
}
public class FloorFilter : ISelectionFilter
{
public bool AllowElement(Element elem)
{
return (elem is Floor);
}
public bool AllowReference(Reference reference, XYZ position)
{
return true;
}
}
}
效果如下:
参考资料:
来源:CSDN
作者:yasenRK
链接:https://blog.csdn.net/yasenRK/article/details/103642285