// // (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.Drawing; using Autodesk.Revit; using Autodesk.Revit.DB; using Autodesk.Revit.UI; using System.Drawing.Drawing2D; namespace Revit.SDK.Samples.PathReinforcement.CS { /// /// This class stores the geometry information of path reinforcement. /// class Profile { /// /// field used to store path reinforcement. /// private Autodesk.Revit.DB.Structure.PathReinforcement m_pathRein; /// /// field used to store external command data. /// private Autodesk.Revit.UI.ExternalCommandData m_commandData; /// /// field used to store the geometry curves of path reinforcement. /// 3d data. /// private List> m_curves = new List>(); /// /// store path 3D. /// private List> m_path = new List>(); /// /// field used to store the bound of the curves of path reinforcement. /// 2d data. /// private BoundingBoxUV m_box = new BoundingBoxUV(); /// /// field used to store the geometry data of curves of path reinforcement. /// 2d data. /// private List> m_point2d = new List>(); /// /// store path 2D. /// private List> m_path2d = new List>(); /// /// Constructor /// /// selected path reinforcement element. /// External command data public Profile(Autodesk.Revit.DB.Structure.PathReinforcement pathRein, ExternalCommandData commandData) { m_pathRein = pathRein; m_commandData = commandData; Tessellate(); ComputeBound(); ComputePathTo2D(); } /// /// Draw the curves of path reinforcement. /// /// Gdi object, used to draw curves of path reinforcement. /// Bound to limit the size of the whole picture /// Gdi object,determine the color of the line. public void Draw(Graphics graphics, Size size, Pen pen) { Autodesk.Revit.DB.UV delta = m_box.Max - m_box.Min; float scaleX = size.Width / (float)delta.U; float scaleY = size.Width / (float)delta.V; float scale = scaleY > scaleX ? scaleX : scaleY; scale *= 0.90f; GraphicsContainer contain = graphics.BeginContainer(); { //set graphics coordinate system to picture center //and flip the yAxis. graphics.Transform = new Matrix(1, 0, 0, -1, size.Width / 2, size.Height / 2); //construct a matrix to transform the origin point to Bound center. Autodesk.Revit.DB.UV center = (m_box.Min + m_box.Max) / 2; Matrix toCenter = new Matrix(1, 0, 0, 1, -(float)center.U, -(float)center.V); bool isDrawFinished = false; List> point2d = m_point2d; Pen tmpPen = pen; while (!isDrawFinished) { foreach (List arr in point2d) { for (int i = 0; i < arr.Count - 1; i++) { //get the two connection points to draw a line between them. Autodesk.Revit.DB.UV uv1 = arr[i]; Autodesk.Revit.DB.UV uv2 = arr[i + 1]; PointF[] points = new PointF[] { new PointF((float)uv1.U, (float)uv1.V), new PointF((float)uv2.U, (float)uv2.V) }; //transform points to bound center. toCenter.TransformPoints(points); //Zoom(Scale) the points to fit the picture box. PointF pf1 = new PointF(points[0].X * scale, points[0].Y * scale); PointF pf2 = new PointF(points[1].X * scale, points[1].Y * scale); //draw a line between pf1 and pf2. graphics.DrawLine(tmpPen, pf1, pf2); } } if (point2d == m_path2d) { isDrawFinished = true; } point2d = m_path2d; tmpPen = Pens.Blue; } } graphics.EndContainer(contain); } /// /// Transform 3d path to 2d path. /// /// private void ComputePathTo2D() { Matrix4 transform = GetActiveViewMatrix().Inverse(); foreach (List arr in m_path) { List uvarr = new List(); foreach (Autodesk.Revit.DB.XYZ xyz in arr) { Vector4 tmpVector = transform.Transform(new Vector4(xyz)); Autodesk.Revit.DB.UV tmpUv = new Autodesk.Revit.DB.UV( tmpVector.X, tmpVector.Y); uvarr.Add(tmpUv); } m_path2d.Add(uvarr); } } /// /// Compute the bound of the curves of path reinforcement. /// private void ComputeBound() { //make the bound Autodesk.Revit.DB.UV min = m_box.get_Bounds(0); Autodesk.Revit.DB.UV max = m_box.get_Bounds(1); Matrix4 transform = GetActiveViewMatrix().Inverse(); bool isFirst = true; foreach (List arr in m_curves) { List uvarr = new List(); foreach (Autodesk.Revit.DB.XYZ xyz in arr) { Vector4 tmpVector = transform.Transform(new Vector4(xyz)); Autodesk.Revit.DB.UV tmpUv = new Autodesk.Revit.DB.UV( tmpVector.X, tmpVector.Y); uvarr.Add(tmpUv); if (isFirst) { isFirst = false; min = new UV(tmpUv.U, tmpUv.V); max = new UV(tmpUv.U, tmpUv.V); } if (tmpUv.U < min.U) { min = new UV(tmpUv.U, min.V); } else if (tmpUv.U > max.U) { max = new UV(tmpUv.U, max.V); } if (tmpUv.V < min.V) { min = new UV(min.U, tmpUv.V); } else if (tmpUv.V > max.V) { max = new UV(max.U, tmpUv.V); } } m_point2d.Add(uvarr); } m_box.Min = min; m_box.Max = max; } /// /// Tessellate the curves of path reinforcement. /// private void Tessellate() { Options option = new Options(); option.DetailLevel = ViewDetailLevel.Fine; Autodesk.Revit.DB.GeometryElement geoElem = m_pathRein.get_Geometry(option); //GeometryObjectArray geoArray = geoElem.Objects; IEnumerator Objects = geoElem.GetEnumerator(); //foreach (GeometryObject geo in geoArray) while (Objects.MoveNext()) { GeometryObject geo = Objects.Current; if (geo is Curve) { Curve curve = geo as Curve; m_curves.Add(curve.Tessellate() as List); } } IList curveIds = m_pathRein.GetCurveElementIds(); foreach (ElementId id in curveIds) { ModelCurve modelCurve = m_commandData.Application.ActiveUIDocument.Document.GetElement(id) as ModelCurve; m_path.Add(modelCurve.GeometryCurve.Tessellate() as List); } } /// /// Get view matrix from active view. /// /// view matrix private Matrix4 GetActiveViewMatrix() { View activeView = m_commandData.Application.ActiveUIDocument.Document.ActiveView; Autodesk.Revit.DB.XYZ vZAxis = activeView.ViewDirection; Autodesk.Revit.DB.XYZ vXAxis = activeView.RightDirection; Autodesk.Revit.DB.XYZ vYAxis = activeView.UpDirection; return new Matrix4(new Vector4(vXAxis), new Vector4(vYAxis), new Vector4(vZAxis)); } } }