// // (C) Copyright 2003-2009 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 Autodesk.Revit; using Autodesk.Revit.Elements; using Autodesk.Revit.Geometry; using Autodesk.Revit.Parameters; using Element = Autodesk.Revit.Element; using GElement = Autodesk.Revit.Geometry.Element; 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; foreach (GeometryObject geoObj in geoArr) { 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; foreach (GeometryObject geoObj in geoArr) { 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 (XYZ xyz in mesh.Vertices) { tempElevation = tempElevation + xyz.Y; } tempElevation = tempElevation / mesh.Vertices.Size; 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 (XYZ xyz in mesh.Vertices) { tempElevation = tempElevation + xyz.Y; } tempElevation = tempElevation / mesh.Vertices.Size; 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 XYZ startPoint, ref XYZ endPoint, ref XYZ thirdPnt) { int count = mesh.Vertices.Size; startPoint = mesh.Vertices.get_Item(0); endPoint = mesh.Vertices.get_Item((int)(count / 3)); thirdPnt = mesh.Vertices.get_Item((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) { XYZArray polyline = edge.Tessellate(); XYZ verticalVct = new XYZ(0, 0, 1); XYZ pointBuffer = polyline.get_Item(0); for (int i = 1; i < polyline.Size; i = i + 1) { XYZ temp = polyline.get_Item(i); 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 XYZ GetVector(XYZ startPoint, XYZ endPoint) { return new 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(XYZ vectorA, XYZ vectorB) { bool isNotEqual = (Precision < Math.Abs(vectorA.X - vectorB.X)) || (Precision < Math.Abs(vectorA.Y - vectorB.Y)); return isNotEqual ? false : true; } } }