float m_scale = 1; //scale of shaft opening #endregion Fields #region Constructors /// <summary> /// constructor /// </summary> /// <param name="commandData">object which contains reference of Revit Application</param> public ProfileNull(ExternalCommandData commandData) : base(commandData) { GetLevels(); m_to2DMatrix = new Matrix4(); m_moveToCenterMatrix = new Matrix4(); }
/// <summary> /// Get a matrix which can transform points to 2D /// </summary> /// <returns>matrix which can transform points to 2D</returns> public override Matrix4 GetTo2DMatrix() { View viewLevel2 = null; // get view which named "Level 2". // Skip view templates because they're behind-the-scene and invisible in project browser; also invalid for API. IEnumerable<View> views = from elem in (new FilteredElementCollector(m_commandData.Application.ActiveUIDocument.Document)).OfClass(typeof(ViewPlan)).ToElements() let view=elem as View where view!=null && !view.IsTemplate && "Level 2" == view.ViewName select view; if (views.Count()>0) { viewLevel2 = views.First(); } Vector4 xAxis = new Vector4(viewLevel2.RightDirection); //Because Y axis in windows UI is downward, so we should Multiply(-1) here Vector4 yAxis = new Vector4(viewLevel2.UpDirection.Multiply(-1)); Vector4 zAxis = new Vector4(viewLevel2.ViewDirection); Matrix4 result = new Matrix4(xAxis, yAxis, zAxis); return result; }
/// <summary> /// draw profile of wall or floor in 2D /// </summary> /// <param name="graphics">form graphic</param> /// <param name="pen">pen used to draw line in pictureBox</param> /// <param name="matrix4">Matrix used to transform 3d to 2d /// and make picture in right scale </param> public virtual void Draw2D(Graphics graphics, Pen pen, Matrix4 matrix4) { //move the gdi origin to the picture center graphics.Transform = new System.Drawing.Drawing2D.Matrix( 1, 0, 0, 1, m_sizePictureBox.Width / 2, m_sizePictureBox.Height / 2); //draw profile for (int i = 0; i < m_points.Count; i++) { List<XYZ> points = m_points[i]; for (int j = 0; j < points.Count - 1; j++) { Autodesk.Revit.DB.XYZ point1 = points[j]; Autodesk.Revit.DB.XYZ point2 = points[j + 1]; Vector4 v1 = new Vector4(point1); Vector4 v2 = new Vector4(point2); v1 = matrix4.Transform(v1); v2 = matrix4.Transform(v2); graphics.DrawLine(pen, new Point((int)v1.X, (int)v1.Y), new Point((int)v2.X, (int)v2.Y)); } } }
/// <summary> /// calculate the matrix use to scale /// </summary> /// <param name="size">pictureBox size</param> /// <returns>maxtrix is use to scale the profile</returns> public virtual Matrix4 ComputeScaleMatrix(Size size) { m_sizePictureBox = size; PointF[] boundPoints = GetFaceBounds(); float width = ((float)size.Width) / (boundPoints[1].X - boundPoints[0].X); float hight = ((float)size.Height) / (boundPoints[1].Y - boundPoints[0].Y); float factor = width <= hight ? width : hight; //leave some margin, so multiply factor by 0.85 m_scaleMatrix = new Matrix4((float)(factor * 0.85)); return m_scaleMatrix; }
/// <summary> /// calculate the matrix used to transform 3D to 2D /// </summary> /// <returns>maxtrix is use to transform 3d points to 2d</returns> public virtual Matrix4 Compute3DTo2DMatrix() { Matrix4 result = Matrix4.Multiply( m_to2DMatrix.Inverse(), m_moveToCenterMatrix.Inverse()); m_transformMatrix = Matrix4.Multiply(result, m_scaleMatrix); return m_transformMatrix; }
/// <summary> /// multiply matrix left and right /// </summary> /// <param name="left">left matrix</param> /// <param name="right">right matrix</param> /// <returns></returns> public static Matrix4 Multiply(Matrix4 left, Matrix4 right) { Matrix4 result = new Matrix4(); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { result[i, j] = left[i, 0] * right[0, j] + left[i, 1] * right[1, j] + left[i, 2] * right[2, j] + left[i, 3] * right[3, j]; } } return result; }
/// <summary> /// calculate the matrix used to transform 3D to 2D. /// because profile of shaft opening in Revit is 2d too, /// so we need do nothing but new a matrix /// </summary> /// <returns>maxtrix is use to transform 3d points to 2d</returns> public override Matrix4 Compute3DTo2DMatrix() { m_transformMatrix = new Matrix4(); return m_transformMatrix; }
/// <summary> /// draw the coordinate system /// </summary> /// <param name="graphics">form graphic</param> /// <param name="pen">pen used to draw line in pictureBox</param> /// <param name="matrix4">Matrix used to transform 3d to 2d /// and make picture in right scale </param> public override void Draw2D(Graphics graphics, Pen pen, Matrix4 matrix4) { graphics.Transform = new System.Drawing.Drawing2D.Matrix( 1, 0, 0, 1, 0, 0); //draw X axis graphics.DrawLine(pen, new Point(20, 280), new Point(400, 280)); graphics.DrawPie(pen, 400, 265, 30, 30, 165, 30); //draw Y axis graphics.DrawLine(pen, new Point(20, 280), new Point(20, 50)); graphics.DrawPie(pen, 5, 20, 30, 30, 75, 30); //draw scale graphics.DrawLine(pen, new Point(120, 275), new Point(120, 285)); graphics.DrawLine(pen, new Point(220, 275), new Point(220, 285)); graphics.DrawLine(pen, new Point(320, 275), new Point(320, 285)); graphics.DrawLine(pen, new Point(15, 80), new Point(25, 80)); graphics.DrawLine(pen, new Point(15, 180), new Point(25, 180)); //dimension Font font = new Font("Verdana", 10, FontStyle.Regular); graphics.DrawString("100'", font, Brushes.Blue, new PointF(122, 266)); graphics.DrawString("200'", font, Brushes.Blue, new PointF(222, 266)); graphics.DrawString("300'", font, Brushes.Blue, new PointF(322, 266)); graphics.DrawString("100'", font, Brushes.Blue, new PointF(22, 181)); graphics.DrawString("200'", font, Brushes.Blue, new PointF(22, 81)); graphics.DrawString("(0,0)", font, Brushes.Blue, new PointF(10, 280)); }
/// <summary> /// calculate the matrix for scale /// </summary> /// <param name="size">pictureBox size</param> /// <returns>maxtrix to scale the opening curve</returns> public override Matrix4 ComputeScaleMatrix(Size size) { m_scaleMatrix = new Matrix4(m_scale); return m_scaleMatrix; }
/// <summary> /// calculate the matrix used to transform 3D to 2D. /// because profile of shaft opening in Revit is 2d too, /// so we need do nothing but new a matrix /// </summary> /// <returns>maxtrix is use to transform 3d points to 2d</returns> public override Matrix4 Compute3DTo2DMatrix() { m_transformMatrix = new Matrix4(); return(m_transformMatrix); }
/// <summary> /// calculate the matrix for scale /// </summary> /// <param name="size">pictureBox size</param> /// <returns>maxtrix to scale the opening curve</returns> public override Matrix4 ComputeScaleMatrix(Size size) { m_scaleMatrix = new Matrix4(m_scale); return(m_scaleMatrix); }
/// <summary> /// Get a matrix which can transform points to 2D /// </summary> /// <returns>matrix which can transform points to 2D</returns> public override Matrix4 GetTo2DMatrix() { //get transform used to transform points to plane whose normal is Zaxis of beam Vector4 xAxis = new Vector4(m_data.HandOrientation); xAxis.Normalize(); //Because Y axis in windows UI is downward, so we should Multiply(-1) here Vector4 yAxis = new Vector4(m_data.FacingOrientation.Multiply(-1)); yAxis.Normalize(); Vector4 zAxis = yAxis.CrossProduct(xAxis); zAxis.Normalize(); Vector4 vOrigin = new Vector4(m_points[0][0]); Matrix4 result = new Matrix4(xAxis, yAxis, zAxis, vOrigin); m_MatrixZaxis = result; //get transform used to transform points to plane whose normal is Yaxis of beam xAxis = new Vector4(m_data.HandOrientation); xAxis.Normalize(); zAxis = new Vector4(m_data.FacingOrientation); zAxis.Normalize(); yAxis = (xAxis.CrossProduct(zAxis)) * (-1); yAxis.Normalize(); result = new Matrix4(xAxis, yAxis, zAxis, vOrigin); m_MatrixYaxis = result; return m_MatrixZaxis; }