// // (C) Copyright 2003-2019 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 System.Text; using System.Collections.ObjectModel; using Autodesk.Revit; using Autodesk.Revit.DB; using Element = Autodesk.Revit.DB.Element; using GeometryElement = Autodesk.Revit.DB.GeometryElement; using GeometryOptions = Autodesk.Revit.DB.Options; namespace Revit.SDK.Samples.ObjectViewer.CS { /// /// The GeometryDatafactory object is used to transform Revit geometry data /// to appropriate format for GDI. /// public class GeometryData { // boundingBox of the geometry private BoundingBoxXYZ m_bbox; // curves can represent the wireframe of the geometry private List> m_curve3Ds = new List>(); /// /// 3D graphics data of the geometry /// public Graphics3DData Data3D { get { return new Graphics3DData(new List>(m_curve3Ds), m_bbox); } } /// /// create 3D and 2D data of given GeometryElement /// /// /// /// public GeometryData(Element elem, ViewDetailLevel detail, View currentView) { Options opt = Command.CommandData.Application.Application.Create.NewGeometryOptions(); opt.DetailLevel = detail; opt.ComputeReferences = false; GeometryElement geoElement = elem.get_Geometry(opt); Autodesk.Revit.DB.XYZ xyz = new Autodesk.Revit.DB.XYZ(0, 0, 0); Transform transform = Transform.CreateTranslation(xyz); AddGeoElement(geoElement, transform); m_bbox = elem.get_BoundingBox(currentView); } /// /// create 3D and 2D data of given GeometryElement /// /// of which geometry data be gotten /// current view of Revit public GeometryData(Element elem, View currentView) { Options opt = Command.CommandData.Application.Application.Create.NewGeometryOptions(); opt.View = currentView; opt.ComputeReferences = false; GeometryElement geoElement = elem.get_Geometry(opt); Autodesk.Revit.DB.XYZ xyz = new Autodesk.Revit.DB.XYZ(0, 0, 0); Transform transform = Transform.CreateTranslation(xyz); AddGeoElement(geoElement, transform); m_bbox = elem.get_BoundingBox(currentView); } /// /// get the solids in a Geometric primitive /// /// a geometry object of element /// private void AddGeoElement(GeometryObject obj, Transform transform) { GeometryElement geometry = obj as GeometryElement; if (null == geometry) { return; } //get all geometric primitives contained in the GeometryElement IEnumerator Objects = geometry.GetEnumerator(); AddGeometryObjects(Objects, transform); } /// /// iterate GeometryObject in GeometryObjectArray and generate data accordingly /// /// /// private void AddGeometryObjects(IEnumerator objects, Transform transform) { //foreach (GeometryObject o in objects) while (objects.MoveNext()) { GeometryObject o = objects.Current; //if the type of the geometric primitive is Solid string geoType = o.GetType().Name; switch (geoType) { case "Solid": AddSolid(o, transform); break; case "Face": AddFace(o, transform); break; case "Mesh": AddMesh(o, transform); break; case "Curve": case "Line": case "Arc": AddCurve(o, transform); break; case "Profile": AddProfile(o, transform); break; case "Element": AddGeoElement(o, transform); break; case "Instance": AddInstance(o, transform); break; case "Edge": AddEdge(o, transform); break; default: break; } } } /// /// generate data of a Solid /// /// /// private void AddSolid(GeometryObject obj, Transform transform) { Solid solid = obj as Solid; if (null == solid) { return; } //a solid has many faces FaceArray faces = solid.Faces; if (faces.Size == 0) { return; } foreach (Face face in faces) { AddFace(face, transform); } } /// /// generate data of a Face /// /// /// private void AddFace(GeometryObject obj, Transform transform) { Face face = obj as Face; if (null == face) { return; } Mesh mesh = face.Triangulate(); if (null == mesh) { return; } AddMesh(mesh, transform); } /// /// generate data of a Profile /// /// /// private void AddProfile(GeometryObject obj, Transform transform) { Profile profile = obj as Profile; if (null == profile) { return; } foreach (Curve curve in profile.Curves) { AddCurve(curve, transform); } } /// /// generate data of a Mesh /// /// /// private void AddMesh(GeometryObject obj, Transform transform) { Mesh mesh = obj as Mesh; if (null == mesh) { return; } //a face has a mesh, all meshes are made of triangles for (int i = 0; i < mesh.NumTriangles; i++) { MeshTriangle triangular = mesh.get_Triangle(i); List points = new List(); try { for (int n = 0; n < 3; n++) { Autodesk.Revit.DB.XYZ point = triangular.get_Vertex(n); Autodesk.Revit.DB.XYZ newPoint = MathUtil.GetBasis(point, transform); points.Add(newPoint); } Autodesk.Revit.DB.XYZ iniPoint = points[0]; points.Add(iniPoint); m_curve3Ds.Add(points); } catch { } } } /// /// generate data of a Curve /// /// /// private void AddCurve(GeometryObject obj, Transform transform) { Curve curve = obj as Curve; if (null == curve) { return; } if (curve.IsBound) { List points = curve.Tessellate() as List; List result = new List(); foreach (Autodesk.Revit.DB.XYZ point in points) { Autodesk.Revit.DB.XYZ newPoint = MathUtil.GetBasis(point, transform); result.Add(newPoint); } m_curve3Ds.Add(result); } } /// /// generate data of a Instance /// /// /// private void AddInstance(GeometryObject obj, Transform transform) { GeometryInstance instance = obj as GeometryInstance; if (null == instance) { return; } //get a transformation of the affine 3-space Transform allTransform = AddTransform(transform, instance.Transform); GeometryElement instanceGeometry = instance.SymbolGeometry; if (null == instanceGeometry) { return; } //get all geometric primitives contained in the GeometryElement //GeometryObjectArray instanceGeometries = instanceGeometry.Objects; IEnumerator Objects = instanceGeometry.GetEnumerator(); AddGeometryObjects(Objects, allTransform); } /// /// generate data of a Edge /// /// /// private void AddEdge(GeometryObject obj, Transform transform) { Edge edge = obj as Edge; if (null == edge) { return; } List points = edge.Tessellate() as List; List result = new List(); foreach (Autodesk.Revit.DB.XYZ point in points) { Autodesk.Revit.DB.XYZ newPoint = MathUtil.GetBasis(point, transform); result.Add(newPoint); } m_curve3Ds.Add(result); } /// /// Add 2 Transform Matrix /// /// /// /// private Transform AddTransform(Transform tran1, Transform tran2) { Autodesk.Revit.DB.XYZ xyz = new Autodesk.Revit.DB.XYZ(0, 0, 0); Transform result = Transform.CreateTranslation(xyz); result.Origin = MathUtil.AddXYZ(tran1.Origin, tran2.Origin); Autodesk.Revit.DB.XYZ[] left = new Autodesk.Revit.DB.XYZ[3]; Autodesk.Revit.DB.XYZ[] right = new Autodesk.Revit.DB.XYZ[3]; for (int i = 0; i < 3; i++) { left[i] = tran1.get_Basis(i); right[i] = tran2.get_Basis(i); } Autodesk.Revit.DB.XYZ[] temp = MathUtil.MultiCross(left, right); for (int i = 0; i < 3; i++) { result.set_Basis(i, temp[i]); } return result; } } }