123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using Autodesk.Revit;
- using Autodesk.Revit.DB;
- using Autodesk.Revit.UI;
- using Autodesk.Revit.DB.Mechanical;
- using System.Windows;
- using System.Windows.Shapes;
- using System.Windows.Media;
- using System.Windows.Controls;
- namespace SpacePlugin
- {
- [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
- [Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
- [Autodesk.Revit.Attributes.Journaling(Autodesk.Revit.Attributes.JournalingMode.NoCommandData)]
- public class GetEdgesCmd : IExternalCommand
- {
- /// <summary>
- /// Implement this method as an external command for Revit.
- /// </summary>
- /// <param name="commandData">An object that is passed to the external application
- /// which contains data related to the command,
- /// such as the application object and active view.</param>
- /// <param name="message">A message that can be set by the external application
- /// which will be displayed if a failure or cancellation is returned by
- /// the external command.</param>
- /// <param name="elements">A set of elements to which the external application
- /// can add elements that are to be highlighted in case of failure or cancellation.</param>
- /// <returns>Return the status of the external command.
- /// A result of Succeeded means that the API external method functioned as expected.
- /// Cancelled can be used to signify that the user cancelled the external operation
- /// at some point. Failure should be returned if the application is unable to proceed with
- /// the operation.</returns>
- public Result Execute(ExternalCommandData commandData,
- ref string message,
- ElementSet elements)
- {
- try
- {
- Transaction docTrans = new Transaction(commandData.Application.ActiveUIDocument.Document, "Document");
- docTrans.Start();
- UIApplication uiApp = commandData.Application;
- UIDocument uiDoc = commandData.Application.ActiveUIDocument;
- Document doc = uiDoc.Document;
- ElementClassFilter familyInstanceFilter = new ElementClassFilter(typeof(FamilyInstance));
- var lstCategoryFilter = new List<ElementFilter>
- {
- new ElementCategoryFilter(BuiltInCategory.OST_Doors),
- new ElementCategoryFilter(BuiltInCategory.OST_Windows),
- new ElementCategoryFilter(BuiltInCategory.OST_StructuralColumns)
- };
- LogicalOrFilter orCategoryFilter = new LogicalOrFilter(lstCategoryFilter);
- LogicalAndFilter andFilter = new LogicalAndFilter(familyInstanceFilter, orCategoryFilter);
- ElementClassFilter wallFilter = new ElementClassFilter(typeof(Wall));
- LogicalOrFilter filter = new LogicalOrFilter(andFilter, wallFilter);
- FilteredElementCollector collector = new FilteredElementCollector(doc);
- var lstEle = collector.WherePasses(filter).ToList();
- if (lstEle.Count == 0)
- {
- MessageBox.Show("没发现可生成空间的元素");
- docTrans.RollBack();
- return Result.Failed;
- }
- WinSpaceBottom win = new WinSpaceBottom();
- foreach (var ele in lstEle)
- {
- var brush = (ele is Wall) ? green : red;
- var curve = ele.Location as LocationCurve;
- if (curve == null)
- {
- this.DrawBottomFace(ele, win.canvas);
- }
- else
- {
- this.DrawCurve(curve.Curve, win.canvas, brush);
- }
- }
- var width = (maxX - minX) * 1.2;
- var height = (maxY - minY) * 1.2;
- foreach (UIElement ele in win.canvas.Children)
- {
- Canvas.SetLeft(ele, -minX + width * 0.1);
- Canvas.SetTop(ele, -minY + height * 0.1);
- }
- win.canvas.Width = width;
- win.canvas.Height = height;
- win.Show();
- docTrans.Commit();
- return Result.Succeeded;
- }
- catch (Exception exp)
- {
- message = exp.Message;
- return Result.Failed;
- }
- }
- SolidColorBrush green = new SolidColorBrush(Colors.Green);
- SolidColorBrush red = new SolidColorBrush(Colors.Red);
- double minX = double.MaxValue;
- double maxX = 0.0;
- double minY = double.MaxValue;
- double maxY = 0.0;
- const double Scale = 50.0;
- void DrawBottomFace(Element ele, Canvas canvas)
- {
- Options opt = new Options();
- opt.ComputeReferences = true;
- opt.DetailLevel = ViewDetailLevel.Medium;
- GeometryElement e = ele.get_Geometry(opt);
- foreach (GeometryObject obj in e)
- {
- if (obj is Solid)
- {
- Solid solid = obj as Solid;
- if (solid != null && solid.Faces.Size > 0) this.DrawSolid(solid, canvas, green);
- }
- else if (obj is GeometryInstance)
- {
- var sube = (obj as GeometryInstance).GetInstanceGeometry();
- foreach (GeometryObject subobj in sube)
- {
- Solid subsolid = subobj as Solid;
- if (subsolid != null && subsolid.Faces.Size > 0) this.DrawSolid(subsolid, canvas, red);
- }
- }
- }
- }
- void DrawSolid(Solid solid, Canvas canvas, Brush brush)
- {
- var pf = FindBottomFace(solid);
- if (pf == null) return;
- foreach (EdgeArray edgeArr in pf.EdgeLoops)
- {
- var pl = this.CreateDefaultPolyLine(brush);
- foreach (Edge edge in edgeArr)
- {
- var lstPt = edge.Tessellate().ToList();
- this.AddPoints(lstPt, pl);
- }
- canvas.Children.Add(pl);
- }
- }
- PlanarFace FindBottomFace(Solid solid)
- {
- PlanarFace pf = null;
- foreach (Face face in solid.Faces)
- {
- pf = face as PlanarFace;//转化为立面平面
- if (pf == null) continue;
- var normal = pf.FaceNormal;
- if (Math.Abs(normal.X) < 0.01 && Math.Abs(normal.Y) < 0.01 && normal.Z < 0)
- break;
- }
- return pf;
- }
- void DrawCurve(Curve curve, Canvas canvas, Brush brush)
- {
- var lstPt = curve.Tessellate();
- if (lstPt == null || lstPt.Count < 2) return;
-
-
- var pl = this.CreateDefaultPolyLine(brush);
- this.AddPoints(lstPt, pl);
- canvas.Children.Add(pl);
- }
- void AddPoints(IEnumerable<XYZ> lstPt, Polyline pl)
- {
- foreach (var pt in lstPt)
- {
- var x = pt.X * Scale;
- //由于winform,y轴与revit Y轴方向相反。Winform Y向下
- var y = pt.Y * Scale*(-1);
- if (x < minX) minX = x;
- if (x > maxX) maxX = x;
- if (y < minY) minY = y;
- if (y > maxY) maxY = y;
- pl.Points.Add(new System.Windows.Point(x, y));
- }
- }
- Polyline CreateDefaultPolyLine(Brush brush)
- {
- var pl = new Polyline();
- pl.Stroke = brush;
- pl.StrokeThickness = 2;
- pl.StrokeStartLineCap = PenLineCap.Flat;
- pl.StrokeEndLineCap = PenLineCap.Flat;
- pl.StrokeLineJoin = PenLineJoin.Round;
- return pl;
- }
- }
- }
|