应用程序:NewPathReinforcement
Revit平台:结构
Revit版本:2011.0
首次发布版本:2008.0
编程语言:C#
技能水平:中等
类别:结构、几何
类型:ExternalCommand
主题:创建PathReinforcement。
摘要:
本示例演示了如何使用API创建PathReinforcement。
类:
Autodesk.Revit.UI.IExternalCommand
Autodesk.Revit.DB.Structure.PathReinforcement
Autodesk.Revit.DB.Structure.PathReinforcementType
Autodesk.Revit.DB.Face
Autodesk.Revit.DB.Edge
Autodesk.Revit.DB.Solid
Autodesk.Revit.Creation.Document
项目文件:
Command.cs
该文件包含了实现IExternalCommand接口的命令类Command。它获取所选的墙壁或地板,并在其上创建PathReinforcement。
NewPathReinforcementForm.cs
该文件包含了一个继承自Form的NewPathReinforcementForm类,其功能是显示所选的墙壁或地板的剖面,并允许用户在其上绘制PathReinforcement的路径。
Profile.cs
该文件包含了一个由ProfileWall和ProfileFloor派生而来的抽象类Profile。Profile包括两种方法Draw2D()和CreatePathReinforcement(),Draw2D()用于在表单上绘制轮廓,CreatePathReinforcement()用于在所选的墙壁或地板上创建PathReinforcement。
LineTool.cs
该文件包含了一个名为LineTool的类,该类提供一些在表单上绘制线条并存储所绘线条数据的方法。
MathTools.cs
该文件包含了Verctor4和Matrix4两个类。这两个类用于在3D和2D之间转换点。
描述:
本示例展示了如何通过NewPathReinforcement(PathReinforcementType, Element, CurveArray, bool)方法创建PathReinforcement:
- 使用Document.Create.NewPathReinforcementType()方法来在当前文档中创建一个PathReinforcementType。
- 这里的Element代表PathReinforcement的宿主,即墙壁或地板。
- CurveArray存储PathReinforcement的路径。
- bool值指示PathReinforcement在路径的哪一侧。
操作说明:
1. 绘制结构墙壁或楼板(或打开NewPathReinforcement.rvt文件)并选择它。
2. 运行此命令。
3. 绘制您要创建的PathReinforcement路径,用户可以单击右键完成绘制。
4. 单击“预览”将预览将要创建的PathReinforcement。
5. 选择或取消选择“翻转”复选框,以在您绘制的路径左侧或右侧创建PathReinforcement。
6. 单击“创建”按钮,将在完成路径时创建PathReinforcement。
7. 用户可以单击“清除”按钮清除并重新绘制路径的草图。
源代码
完整的源代码请加入QQ群649037449,在群文件中下载RevitSDK.exe,解压后在文件夹中搜索本文中应用程序名称即可获得完整源码
NewPathReinforcementForm.cs
//
// (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.
//
namespace Revit.SDK.Samples.NewPathReinforcement.CS
{
partial class NewPathReinforcementForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.pictureBox = new System.Windows.Forms.PictureBox();
this.createButton = new System.Windows.Forms.Button();
this.cancelButton = new System.Windows.Forms.Button();
this.flipCheckBox = new System.Windows.Forms.CheckBox();
this.labelNote = new System.Windows.Forms.Label();
this.previewButton = new System.Windows.Forms.Button();
this.cleanButton = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.pictureBox)).BeginInit();
this.SuspendLayout();
//
// pictureBox
//
this.pictureBox.BackColor = System.Drawing.SystemColors.Window;
this.pictureBox.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.pictureBox.Location = new System.Drawing.Point(14, 12);
this.pictureBox.Name = "pictureBox";
this.pictureBox.Size = new System.Drawing.Size(446, 314);
this.pictureBox.TabIndex = 0;
this.pictureBox.TabStop = false;
this.pictureBox.MouseDown += new System.Windows.Forms.MouseEventHandler(this.PictureBox_MouseDown);
this.pictureBox.MouseMove += new System.Windows.Forms.MouseEventHandler(this.PictureBox_MouseMove);
this.pictureBox.Paint += new System.Windows.Forms.PaintEventHandler(this.PictureBox_Paint);
//
// createButton
//
this.createButton.Font = new System.Drawing.Font("Verdana", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.createButton.Location = new System.Drawing.Point(279, 403);
this.createButton.Name = "createButton";
this.createButton.Size = new System.Drawing.Size(87, 23);
this.createButton.TabIndex = 1;
this.createButton.Text = "C&reate";
this.createButton.UseVisualStyleBackColor = true;
this.createButton.Click += new System.EventHandler(this.CreateButton_Click);
//
// cancelButton
//
this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.cancelButton.Font = new System.Drawing.Font("Verdana", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.cancelButton.Location = new System.Drawing.Point(373, 403);
this.cancelButton.Name = "cancelButton";
this.cancelButton.Size = new System.Drawing.Size(87, 23);
this.cancelButton.TabIndex = 2;
this.cancelButton.Text = "&Cancel";
this.cancelButton.UseVisualStyleBackColor = true;
this.cancelButton.Click += new System.EventHandler(this.CancelButton_Click);
//
// flipCheckBox
//
this.flipCheckBox.AutoSize = true;
this.flipCheckBox.Font = new System.Drawing.Font("Verdana", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.flipCheckBox.Location = new System.Drawing.Point(415, 332);
this.flipCheckBox.Name = "flipCheckBox";
this.flipCheckBox.Size = new System.Drawing.Size(45, 17);
this.flipCheckBox.TabIndex = 3;
this.flipCheckBox.Text = "Flip";
this.flipCheckBox.UseVisualStyleBackColor = true;
this.flipCheckBox.CheckedChanged += new System.EventHandler(this.FlipCheckBox_CheckedChanged);
//
// labelNote
//
this.labelNote.Font = new System.Drawing.Font("Verdana", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelNote.Location = new System.Drawing.Point(11, 336);
this.labelNote.Name = "labelNote";
this.labelNote.Size = new System.Drawing.Size(245, 33);
this.labelNote.TabIndex = 4;
this.labelNote.Text = "Click mouse left button and drag to draw a curve. Right click to finish drawing.";
//
// previewButton
//
this.previewButton.Enabled = false;
this.previewButton.Location = new System.Drawing.Point(373, 364);
this.previewButton.Name = "previewButton";
this.previewButton.Size = new System.Drawing.Size(87, 23);
this.previewButton.TabIndex = 5;
this.previewButton.Text = "&Preview";
this.previewButton.UseVisualStyleBackColor = true;
this.previewButton.Click += new System.EventHandler(this.ButtonPreview_Click);
//
// cleanButton
//
this.cleanButton.Location = new System.Drawing.Point(279, 364);
this.cleanButton.Name = "cleanButton";
this.cleanButton.Size = new System.Drawing.Size(87, 23);
this.cleanButton.TabIndex = 6;
this.cleanButton.Text = "C&lean";
this.cleanButton.UseVisualStyleBackColor = true;
this.cleanButton.Click += new System.EventHandler(this.ButtonClean_Click);
//
// NewPathReinforcementForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(472, 438);
this.Controls.Add(this.cleanButton);
this.Controls.Add(this.previewButton);
this.Controls.Add(this.labelNote);
this.Controls.Add(this.flipCheckBox);
this.Controls.Add(this.cancelButton);
this.Controls.Add(this.createButton);
this.Controls.Add(this.pictureBox);
this.Font = new System.Drawing.Font("Verdana", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "NewPathReinforcementForm";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.Text = "New Path Reinforcement";
this.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.NewPathReinforcementForm_KeyPress);
((System.ComponentModel.ISupportInitialize)(this.pictureBox)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.PictureBox pictureBox;
private System.Windows.Forms.Button createButton;
private System.Windows.Forms.Button cancelButton;
private System.Windows.Forms.CheckBox flipCheckBox;
private System.Windows.Forms.Label labelNote;
private System.Windows.Forms.Button previewButton;
private System.Windows.Forms.Button cleanButton;
}
}
Profile.cs
//
// (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 Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit;
using System.Drawing;
using Point = System.Drawing.Point;
namespace Revit.SDK.Samples.NewPathReinforcement.CS
{
/// <summary>
/// base class of ProfileFloor and ProfileWall
/// contains the profile information and can make matrix to transform point to 2D plane
/// </summary>
public abstract class Profile
{
#region class member variables
/// <summary>
/// store all the points on the needed face
/// </summary>
protected List<List<XYZ>> m_points;
/// <summary>
/// object which contains reference to Revit Application
/// </summary>
protected Autodesk.Revit.UI.ExternalCommandData m_commandData;
/// <summary>
/// used to create new instances of utility objects.
/// </summary>
protected Autodesk.Revit.Creation.Application m_appCreator;
/// <summary>
/// Revit DB document
/// </summary>
protected Autodesk.Revit.DB.Document m_document;
/// <summary>
/// store the Matrix used to transform 3D points to 2D
/// </summary>
protected Matrix4 m_to2DMatrix = null;
#endregion
/// <summary>
/// CommandData property get object which contains reference to Revit Application
/// </summary>
public Autodesk.Revit.UI.ExternalCommandData CommandData
{
get
{
return m_commandData;
}
}
/// <summary>
/// To2DMatrix property to get Matrix used to transform 3D points to 2D
/// </summary>
public Matrix4 To2DMatrix
{
get
{
return m_to2DMatrix;
}
}
/// <summary>
/// constructor
/// </summary>
/// <param name="commandData">object which contains reference to Revit Application</param>
protected Profile(ExternalCommandData commandData)
{
m_commandData = commandData;
m_appCreator = m_commandData.Application.Application.Create;
m_document = m_commandData.Application.ActiveUIDocument.Document;
}
/// <summary>
/// abstract method to create PathReinforcement
/// </summary>
/// <returns>new created PathReinforcement</returns>
/// <param name="points">points used to create PathReinforcement</param>
/// <param name="flip">used to specify whether new PathReinforcement is Filp</param>
public abstract PathReinforcement CreatePathReinforcement(List<Vector4> points, bool flip);
/// <summary>
/// Get points in first face
/// </summary>
/// <param name="faces">edges in all faces</param>
/// <returns>points in first face</returns>
public abstract List<List<XYZ>> GetNeedPoints(List<List<Edge>> faces);
/// <summary>
/// Get a matrix which can transform points to 2D
/// </summary>
public abstract Matrix4 GetTo2DMatrix();
/// <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 void Draw2D(Graphics graphics, Pen pen, Matrix4 matrix4)
{
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>
/// Get edges of element's profile
/// </summary>
/// <param name="elem">selected element</param>
/// <returns>all the faces in the selected Element</returns>
public List<List<Edge>> GetFaces(Autodesk.Revit.DB.Element elem)
{
List<List<Edge>> faceEdges = new List<List<Edge>>();
Options options = m_appCreator.NewGeometryOptions();
options.DetailLevel = ViewDetailLevel.Medium;
options.ComputeReferences = true; //make sure references to geometric objects are computed.
Autodesk.Revit.DB.GeometryElement geoElem = elem.get_Geometry(options);
//GeometryObjectArray gObjects = geoElem.Objects;
IEnumerator<GeometryObject> Objects = geoElem.GetEnumerator();
//get all the edges in the Geometry object
//foreach (GeometryObject geo in gObjects)
while (Objects.MoveNext())
{
GeometryObject geo = Objects.Current;
Solid solid = geo as Solid;
if (solid != null)
{
FaceArray faces = solid.Faces;
foreach (Face face in faces)
{
EdgeArrayArray edgeArrarr = face.EdgeLoops;
foreach (EdgeArray edgeArr in edgeArrarr)
{
List<Edge> edgesList = new List<Edge>();
foreach (Edge edge in edgeArr)
{
edgesList.Add(edge);
}
faceEdges.Add(edgesList);
}
}
}
}
return faceEdges;
}
/// <summary>
/// Get normal of face
/// </summary>
/// <param name="face">edges in a face</param>
/// <returns>vector stands for normal of the face</returns>
public Vector4 GetFaceNormal(List<Edge> face)
{
Edge eg0 = face[0];
Edge eg1 = face[1];
//get two lines from the face
List<XYZ> points = eg0.Tessellate() as List<XYZ>;
Autodesk.Revit.DB.XYZ start = points[0];
Autodesk.Revit.DB.XYZ end = points[1];
Vector4 vStart = new Vector4((float)start.X, (float)start.Y, (float)start.Z);
Vector4 vEnd = new Vector4((float)end.X, (float)end.Y, (float)end.Z);
Vector4 vSub = vEnd - vStart;
points = eg1.Tessellate() as List<XYZ>;
start = points[0];
end = points[1];
vStart = new Vector4((float)start.X, (float)start.Y, (float)start.Z);
vEnd = new Vector4((float)end.X, (float)end.Y, (float)end.Z);
Vector4 vSub2 = vEnd - vStart;
//get the normal with two lines got from face
Vector4 result = vSub.CrossProduct(vSub2);
result.Normalize();
return result;
}
/// <summary>
/// Get a matrix which can move points to center
/// </summary>
/// <returns>matrix used to move point to center of graphics</returns>
public Matrix4 ToCenterMatrix()
{
//translate the origin to bound center
PointF[] bounds = GetFaceBounds();
PointF min = bounds[0];
PointF max = bounds[1];
PointF center = new PointF((min.X + max.X) / 2, (min.Y + max.Y) / 2);
return new Matrix4(new Vector4(center.X, center.Y, 0));
}
/// <summary>
/// Get the bound of a face
/// </summary>
/// <returns>points array store the bound of the face</returns>
public PointF[] GetFaceBounds()
{
Matrix4 matrix = m_to2DMatrix;
Matrix4 inverseMatrix = matrix.Inverse();
float minX = 0, maxX = 0, minY = 0, maxY = 0;
bool bFirstPoint = true;
//get the max and min point on the face
for (int i = 0; i < m_points.Count; i++)
{
List<XYZ> points = m_points[i];
foreach (Autodesk.Revit.DB.XYZ point in points)
{
Vector4 v = new Vector4(point);
Vector4 v1 = inverseMatrix.Transform(v);
if (bFirstPoint)
{
minX = maxX = v1.X;
minY = maxY = v1.Y;
bFirstPoint = false;
}
else
{
if (v1.X < minX)
{
minX = v1.X;
}
else if (v1.X > maxX)
{
maxX = v1.X;
}
if (v1.Y < minY)
{
minY = v1.Y;
}
else if (v1.Y > maxY)
{
maxY = v1.Y;
}
}
}
}
//return an array with max and min value of face
PointF[] resultPoints = new PointF[2] {
new PointF(minX, minY), new PointF(maxX, maxY) };
return resultPoints;
}
}
}
LineTool.cs
//
// (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.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Drawing;
namespace Revit.SDK.Samples.NewPathReinforcement.CS
{
/// <summary>
/// tool used to draw line
/// </summary>
public class LineTool
{
# region members
private List<Point> m_points = new List<Point>(); // Field used to store points of a line
private Pen m_backGroundPen; // background pen used to Erase the preview line
private Pen m_foreGroundPen; // foreground pen used to draw lines
private Point m_preMovePoint; // store the mouse position when mouse move in pictureBox
private bool m_finished; // indicate whether user have finished drawing
#endregion
/// <summary>
/// Finished property to define whether curve was finished
/// </summary>
public bool Finished
{
get
{
return m_finished;
}
set
{
m_finished = value;
}
}
/// <summary>
/// PointsNumber property to get the number of points stored
/// </summary>
public int PointsNumber
{
get
{
return m_points.Count;
}
}
/// <summary>
/// default constructor
/// </summary>
public LineTool()
{
m_backGroundPen = new Pen(System.Drawing.Color.White);
m_backGroundPen.Width *= 2;
m_foreGroundPen = new Pen(System.Drawing.Color.Black);
m_foreGroundPen.Width *= 2;
m_finished = false;
}
/// <summary>
/// get all lines drawn in pictureBox
/// </summary>
public List<Point> GetPoints()
{
return m_points;
}
/// <summary>
/// clear all the points in the tool
/// </summary>
public void Clear()
{
m_points.Clear();
}
/// <summary>
/// draw a line from end point of tool to the location where mouse move
/// </summary>
/// <param name="graphic">graphic object, used to draw geometry</param>
/// <param name="e">mouse event args</param>
public void OnMouseMove(System.Drawing.Graphics graphic, System.Windows.Forms.MouseEventArgs e)
{
if(m_points.Count != 0 && !m_finished)
{
graphic.DrawLine(m_backGroundPen, m_points[m_points.Count - 1], m_preMovePoint);
m_preMovePoint = e.Location;
graphic.DrawLine(m_foreGroundPen, m_points[m_points.Count - 1], e.Location);
}
}
/// <summary>
/// restore the location point where mouse click
/// </summary>
/// <param name="e">mouse event args</param>
public void OnMouseDown(System.Windows.Forms.MouseEventArgs e)
{
//when user click right button of mouse, then erase last line
if (MouseButtons.Right == e.Button && m_points.Count >= 2)
{
m_finished = true;
}
if (MouseButtons.Left == e.Button && !m_finished)
{
m_preMovePoint = e.Location;
m_points.Add(e.Location);
}
}
/// <summary>
/// draw lines stored in the tool
/// </summary>
/// <param name="graphic">Graphics object, use to draw geometry</param>
public void Draw(Graphics graphic)
{
for (int i = 0; i < m_points.Count - 1; i++)
{
graphic.DrawLine(m_foreGroundPen, m_points[i], m_points[i + 1]);
}
}
}
}
MathTools.cs
//
// (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 Autodesk.Revit.DB;
namespace Revit.SDK.Samples.NewPathReinforcement.CS
{
/// <summary>
/// Vector4 class use to store vector
/// and contain method to handle the vector
/// </summary>
public class Vector4
{
#region Class member variables and properties
private float m_x;
private float m_y;
private float m_z;
private float m_w = 1.0f;
/// <summary>
/// X property to get/set x value of Vector4
/// </summary>
public float X
{
get
{
return m_x;
}
set
{
m_x = value;
}
}
/// <summary>
/// Y property to get/set y value of Vector4
/// </summary>
public float Y
{
get
{
return m_y;
}
set
{
m_y = value;
}
}
/// <summary>
/// Z property to get/set z value of Vector4
/// </summary>
public float Z
{
get
{
return m_z;
}
set
{
m_z = value;
}
}
/// <summary>
/// W property to get/set fourth value of Vector4
/// </summary>
public float W
{
get
{
return m_w;
}
set
{
m_w = value;
}
}
#endregion
/// <summary>
/// constructor
/// </summary>
public Vector4(float x, float y, float z)
{
this.X = x; this.Y = y; this.Z = z;
}
/// <summary>
/// constructor, transfer Autodesk.Revit.DB.XYZ to vector
/// </summary>
/// <param name="v">Autodesk.Revit.DB.XYZ structure which need to be transferred</param>
public Vector4(Autodesk.Revit.DB.XYZ v)
{
this.X = (float)v.X; this.Y = (float)v.Y; this.Z = (float)v.Z;
}
/// <summary>
/// adds two vectors
/// </summary>
/// <param name="va">first vector</param>
/// <param name="vb">second vector</param>
public static Vector4 operator+ (Vector4 va, Vector4 vb)
{
return new Vector4(va.X + vb.X, va.Y + vb.Y, va.Z + vb.Z);
}
/// <summary>
/// subtracts two vectors
/// </summary>
/// <param name="va">first vector</param>
/// <param name="vb">second vector</param>
/// <returns>subtraction of two vector</returns>
public static Vector4 operator- (Vector4 va, Vector4 vb)
{
return new Vector4(va.X - vb.X, va.Y - vb.Y, va.Z - vb.Z);
}
/// <summary>
/// multiplies a vector by a floating type value
/// </summary>
/// <param name="v">vector</param>
/// <param name="factor">multiplier of floating type</param>
/// <returns> the result vector </returns>
public static Vector4 operator* (Vector4 v,float factor)
{
return new Vector4(v.X * factor, v.Y * factor, v.Z * factor);
}
/// <summary>
/// divides vector by an floating type value
/// </summary>
/// <param name="v">vector</param>
/// <param name="factor">floating type value</param>
/// <returns> vector divided by a floating type value </returns>
public static Vector4 operator /(Vector4 v, float factor)
{
return new Vector4(v.X / factor, v.Y / factor, v.Z / factor);
}
/// <summary>
/// dot multiply vector
/// </summary>
/// <param name="v"> the result vector </param>
public float DotProduct(Vector4 v)
{
return (this.X * v.X + this.Y * v.Y + this.Z * v.Z);
}
/// <summary>
/// get normal vector of two vectors
/// </summary>
/// <param name="v">second vector</param>
/// <returns> normal vector of two vectors</returns>
public Vector4 CrossProduct(Vector4 v)
{
return new Vector4(this.Y * v.Z - this.Z * v.Y,this.Z * v.X
- this.X * v.Z,this.X * v.Y - this.Y * v.X);
}
/// <summary>
/// dot multiply two vectors
/// </summary>
/// <param name="va">first vector</param>
/// <param name="vb">second vector</param>
public static float DotProduct(Vector4 va, Vector4 vb)
{
return (va.X * vb.X + va.Y * vb.Y + va.Z * vb.Z);
}
/// <summary>
/// get normal vector of two vectors
/// </summary>
/// <param name="va">first vector</param>
/// <param name="vb">second vector</param>
/// <returns> normal vector of two vectors </returns>
public static Vector4 CrossProduct(Vector4 va, Vector4 vb)
{
return new Vector4(va.Y * vb.Z - va.Z * vb.Y, va.Z * vb.X
- va.X * vb.Z, va.X * vb.Y - va.Y * vb.X);
}
/// <summary>
/// get unit vector
/// </summary>
public void Normalize()
{
float length = Length();
if(length == 0)
{
length = 1;
}
this.X /= length;
this.Y /= length;
this.Z /= length;
}
/// <summary>
/// calculate the length of vector
/// </summary>
public float Length()
{
return (float)Math.Sqrt(this.X * this.X + this.Y * this.Y + this.Z * this.Z);
}
};
/// <summary>
/// Matrix used to transform between ucs coordinate and world coordinate.
/// </summary>
public class Matrix4
{
#region MatrixType
/// <summary>
/// Matrix Type Enum use to define function of matrix
/// </summary>
public enum MatrixType
{
/// <summary>
/// matrix use to rotate
/// </summary>
Rotation,
/// <summary>
/// matrix used to Translation
/// </summary>
Translation,
/// <summary>
/// matrix used to Scale
/// </summary>
Scale,
/// <summary>
/// matrix used to Rotation and Translation
/// </summary>
RotationAndTranslation,
/// <summary>
/// normal matrix
/// </summary>
Normal
};
private float[,] m_matrix = new float[4,4];
private MatrixType m_type;
#endregion
/// <summary>
/// default ctor
/// </summary>
public Matrix4()
{
m_type = MatrixType.Normal;
Identity();
}
/// <summary>
/// ctor,rotation matrix,origin at (0,0,0)
/// </summary>
/// <param name="xAxis">identity of x axis</param>
/// <param name="yAxis">identity of y axis</param>
/// <param name="zAxis">identity of z axis</param>
public Matrix4(Vector4 xAxis,Vector4 yAxis, Vector4 zAxis)
{
m_type = MatrixType.Rotation;
Identity();
m_matrix[0, 0] = xAxis.X; m_matrix[0, 1] = xAxis.Y; m_matrix[0, 2] = xAxis.Z;
m_matrix[1, 0] = yAxis.X; m_matrix[1, 1] = yAxis.Y; m_matrix[1, 2] = yAxis.Z;
m_matrix[2, 0] = zAxis.X; m_matrix[2, 1] = zAxis.Y; m_matrix[2, 2] = zAxis.Z;
}
/// <summary>
/// ctor,translation matrix.
/// </summary>
/// <param name="origin">origin of ucs in world coordinate</param>
public Matrix4(Vector4 origin)
{
m_type = MatrixType.Translation;
Identity();
m_matrix[3, 0] = origin.X; m_matrix[3, 1] = origin.Y; m_matrix[3, 2] = origin.Z;
}
/// <summary>
/// rotation and translation matrix constructor
/// </summary>
/// <param name="xAxis">x Axis</param>
/// <param name="yAxis">y Axis</param>
/// <param name="zAxis">z Axis</param>
/// <param name="origin">origin</param>
public Matrix4(Vector4 xAxis, Vector4 yAxis, Vector4 zAxis, Vector4 origin)
{
m_type = MatrixType.RotationAndTranslation;
Identity();
m_matrix[0, 0] = xAxis.X; m_matrix[0, 1] = xAxis.Y; m_matrix[0, 2] = xAxis.Z;
m_matrix[1, 0] = yAxis.X; m_matrix[1, 1] = yAxis.Y; m_matrix[1, 2] = yAxis.Z;
m_matrix[2, 0] = zAxis.X; m_matrix[2, 1] = zAxis.Y; m_matrix[2, 2] = zAxis.Z;
m_matrix[3, 0] = origin.X; m_matrix[3, 1] = origin.Y; m_matrix[3, 2] = origin.Z;
}
/// <summary>
/// scale matrix constructor
/// </summary>
/// <param name="scale">scale factor</param>
public Matrix4(float scale)
{
m_type = MatrixType.Scale;
Identity();
m_matrix[0, 0] = m_matrix[1, 1] = m_matrix[2, 2] = scale;
}
/// <summary>
/// indexer of matrix
/// </summary>
/// <param name="row">row number</param>
/// <param name="column">column number</param>
/// <returns></returns>
public float this[int row, int column]
{
get
{
return this.m_matrix[row, column];
}
set
{
this.m_matrix[row, column] = value;
}
}
/// <summary>
/// Identity matrix
/// </summary>
public void Identity()
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
this.m_matrix[i, j] = 0.0f;
}
}
this.m_matrix[0, 0] = 1.0f;
this.m_matrix[1, 1] = 1.0f;
this.m_matrix[2, 2] = 1.0f;
this.m_matrix[3, 3] = 1.0f;
}
/// <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>
/// transform point use this matrix
/// </summary>
/// <param name="point">point needed to be transformed</param>
/// <returns>transform result</returns>
public Vector4 Transform(Vector4 point)
{
return new Vector4(point.X * this[0, 0] + point.Y * this[1, 0]
+ point.Z * this[2, 0]+ point.W * this[3, 0],
point.X * this[0, 1] + point.Y * this[1, 1]
+ point.Z * this[2, 1]+ point.W * this[3, 1],
point.X * this[0, 2] + point.Y * this[1, 2]
+ point.Z * this[2, 2]+ point.W * this[3, 2]);
}
/// <summary>
/// if m_matrix is a rotation matrix,this method can get the rotation inverse matrix.
/// </summary>
/// <returns>rotation inverse matrix</returns>
public Matrix4 RotationInverse()
{
return new Matrix4(new Vector4(this[0, 0], this[1, 0], this[2, 0]),
new Vector4(this[0, 1], this[1, 1], this[2, 1]),
new Vector4(this[0, 2], this[1, 2], this[2, 2]));
}
/// <summary>
/// if this m_matrix is a translation matrix,
/// this method can get the translation inverse matrix.
/// </summary>
/// <returns>translation inverse matrix</returns>
public Matrix4 TranslationInverse()
{
return new Matrix4(new Vector4(-this[3, 0], -this[3, 1], -this[3, 2]));
}
/// <summary>
/// get inverse matrix
/// </summary>
/// <returns>inverse matrix</returns>
public Matrix4 Inverse()
{
switch(m_type)
{
case MatrixType.Rotation:
return RotationInverse();
case MatrixType.Translation:
return TranslationInverse();
case MatrixType.RotationAndTranslation:
return Multiply(TranslationInverse(),RotationInverse());
case MatrixType.Scale:
return ScaleInverse();
case MatrixType.Normal:
return new Matrix4();
default: return null;
}
}
/// <summary>
/// if m_matrix is a scale matrix,this method can get the scale inverse matrix.
/// </summary>
/// <returns>scale inverse matrix</returns>
public Matrix4 ScaleInverse()
{
return new Matrix4(1 / m_matrix[0,0]);
}
};
}
版权所有 :无锡模信建筑科技有限公司 苏ICP备2021028830号-1 BIM建模|BIM技术应用|BIM软件开发
联系地址:江苏省无锡市新吴区龙山路4号B座705 手机:18761516598