// // (C) Copyright 2003-2023 by Autodesk, Inc. // // Permission to use, copy, modify, and distribute this software in // object code form 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 Autodesk.Revit; using Autodesk.Revit.DB; using Element = Autodesk.Revit.DB.Element; using GElement = Autodesk.Revit.DB.GeometryElement; namespace Revit.SDK.Samples.WindowWizard.CS { /// /// A object to help locating with geometry data. /// public class GeoHelper { /// /// store the const precision /// private const double Precision = 0.0001; /// /// The method is used to get the wall face along the specified parameters /// /// the wall /// the options view /// if true indicate that get exterior wall face, else false get the interior wall face /// the face static public Face GetWallFace(Wall wall, View view, bool ExtOrInt) { FaceArray faces = null; Face face = null; Options options = new Options(); options.ComputeReferences = true; options.View = view; if (wall != null) { //GeometryObjectArray geoArr = wall.get_Geometry(options).Objects; IEnumerator Objects = wall.get_Geometry(options).GetEnumerator(); //foreach (GeometryObject geoObj in geoArr) while (Objects.MoveNext()) { GeometryObject geoObj = Objects.Current; if (geoObj is Solid) { Solid s = geoObj as Solid; faces = s.Faces; } } } if (ExtOrInt) face = GetExteriorFace(faces); else face = GetInteriorFace(faces); return face; } /// /// The method is used to get extrusion's face along to the specified parameters /// /// the extrusion /// options view /// If true indicate getting exterior extrusion face, else getting interior extrusion face /// the face static public Face GetExtrusionFace(Extrusion extrusion, View view, bool ExtOrInt) { Face face = null; FaceArray faces = null; if (extrusion.IsSolid) { Options options = new Options(); options.ComputeReferences = true; options.View = view; //GeometryObjectArray geoArr = extrusion.get_Geometry(options).Objects; IEnumerator Objects = extrusion.get_Geometry(options).GetEnumerator(); //foreach (GeometryObject geoObj in geoArr) while (Objects.MoveNext()) { GeometryObject geoObj = Objects.Current; if (geoObj is Solid) { Solid s = geoObj as Solid; faces = s.Faces; } } if (ExtOrInt) face = GetExteriorFace(faces); else face = GetInteriorFace(faces); } return face; } /// /// The assistant method is used for getting wall face and getting extrusion face /// /// faces array /// the face static private Face GetExteriorFace(FaceArray faces) { double elevation = 0; double tempElevation = 0; Mesh mesh = null; Face face = null; foreach (Face f in faces) { tempElevation = 0; mesh = f.Triangulate(); foreach (Autodesk.Revit.DB.XYZ xyz in mesh.Vertices) { tempElevation = tempElevation + xyz.Y; } tempElevation = tempElevation / mesh.Vertices.Count; if (elevation < tempElevation || null == face) { face = f; elevation = tempElevation; } } return face; } /// /// The assistant method is used for getting wall face and getting extrusion face /// /// faces array /// the face static private Face GetInteriorFace(FaceArray faces) { double elevation = 0; double tempElevation = 0; Mesh mesh = null; Face face = null; foreach (Face f in faces) { tempElevation = 0; mesh = f.Triangulate(); foreach (Autodesk.Revit.DB.XYZ xyz in mesh.Vertices) { tempElevation = tempElevation + xyz.Y; } tempElevation = tempElevation / mesh.Vertices.Count; if (elevation > tempElevation || null == face) { face = f; elevation = tempElevation; } } return face; } /// /// Find out the three points which made of a plane. /// /// A mesh contains many points. /// Create a new instance of ReferencePlane. /// The free end apply to reference plane. /// A third point needed to define the reference plane. static public void Distribute(Mesh mesh, ref Autodesk.Revit.DB.XYZ startPoint, ref Autodesk.Revit.DB.XYZ endPoint, ref Autodesk.Revit.DB.XYZ thirdPnt) { int count = mesh.Vertices.Count; startPoint = mesh.Vertices[0]; endPoint = mesh.Vertices[(int)(count / 3)]; thirdPnt = mesh.Vertices[(int)(count / 3 * 2)]; } /// /// Determines whether a edge is vertical. /// /// The edge to be determined. /// Return true if this edge is vertical, or else return false. static public bool IsVerticalEdge(Edge edge) { List polyline = edge.Tessellate() as List; Autodesk.Revit.DB.XYZ verticalVct = new Autodesk.Revit.DB.XYZ(0, 0, 1); Autodesk.Revit.DB.XYZ pointBuffer = polyline[0]; for (int i = 1; i < polyline.Count; i = i + 1) { Autodesk.Revit.DB.XYZ temp = polyline[i]; Autodesk.Revit.DB.XYZ vector = GetVector(pointBuffer, temp); if (Equal(vector, verticalVct)) { return true; } else { continue; } } return false; } /// /// Get the vector between two points. /// /// The start point. /// The end point. /// The vector between two points. static public Autodesk.Revit.DB.XYZ GetVector(Autodesk.Revit.DB.XYZ startPoint, Autodesk.Revit.DB.XYZ endPoint) { return new Autodesk.Revit.DB.XYZ(endPoint.X - startPoint.X, endPoint.Y - startPoint.Y, endPoint.Z - startPoint.Z); } /// /// Determines whether two vector are equal in x and y axis. /// /// The vector A. /// The vector B. /// Return true if two vector are equals, or else return false. static public bool Equal(Autodesk.Revit.DB.XYZ vectorA, Autodesk.Revit.DB.XYZ vectorB) { bool isNotEqual = (Precision < Math.Abs(vectorA.X - vectorB.X)) || (Precision < Math.Abs(vectorA.Y - vectorB.Y)); return isNotEqual ? false : true; } } }