added Revit 2022 SDK minus except *rvt and *rfa

This commit is contained in:
Jeremy Tammik
2021-04-20 11:36:21 +02:00
parent 1133a82dc5
commit 7e327986e8
3034 changed files with 1245318 additions and 0 deletions
+173
View File
@@ -0,0 +1,173 @@
//
// (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;
using System.Drawing;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB.Structure;
namespace Revit.SDK.Samples.ShaftHolePuncher.CS
{
/// <summary>
/// The entrance of this example, implements the Execute method of IExternalCommand
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
[Autodesk.Revit.Attributes.Journaling(Autodesk.Revit.Attributes.JournalingMode.NoCommandData)]
public class Command : IExternalCommand
{
#region IExternalCommand Members Implementation
///<summary>
/// Implement this method as an external command for Revit.
/// </summary>
/// <param name="commandData">An object that is passed to the external application
/// which contains data related to the command,
/// such as the application object and active view.</param>
/// <param name="message">A message that can be set by the external application
/// which will be displayed if a failure or cancellation is returned by
/// the external command.</param>
/// <param name="elements">A set of elements to which the external application
/// can add elements that are to be highlighted in case of failure or cancellation.</param>
/// <returns>Return the status of the external command.
/// A result of Succeeded means that the API external method functioned as expected.
/// Cancelled can be used to signify that the user cancelled the external operation
/// at some point. Failure should be returned if the application is unable to proceed with
/// the operation.</returns>
public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData,
ref string message, Autodesk.Revit.DB.ElementSet elements)
{
Transaction trans = new Transaction(commandData.Application.ActiveUIDocument.Document, "Revit.SDK.Samples.ShaftHolePuncher");
trans.Start();
try
{
Wall wall = null;
Floor floor = null;
FamilyInstance familyInstance = null;
ElementSet elems = new ElementSet();
foreach (ElementId elementId in commandData.Application.ActiveUIDocument.Selection.GetElementIds())
{
elems.Insert(commandData.Application.ActiveUIDocument.Document.GetElement(elementId));
}
#region selection handle -- select one floor, wall, beam or nothing
//if user had some wrong selection, give user an Error message
string errorMessage =
"Please select one Floor (Beam or Wall) to create opening or select nothing to create Shaft Opening";
if (elems.Size > 1)
{
message = errorMessage;
trans.RollBack();
return Autodesk.Revit.UI.Result.Cancelled;
}
Autodesk.Revit.DB.Element selectElem = null;
if (1 == elems.Size)
{
IEnumerator iter = elems.GetEnumerator();
iter.Reset();
if (iter.MoveNext())
{
selectElem = (Autodesk.Revit.DB.Element)iter.Current;
}
if (selectElem is Wall)
{
wall = selectElem as Wall;
}
else if (selectElem is Floor)
{
floor = selectElem as Floor;
}
else if (selectElem is FamilyInstance)
{
familyInstance = selectElem as FamilyInstance;
if (familyInstance.StructuralType !=
Autodesk.Revit.DB.Structure.StructuralType.Beam)
{
message = errorMessage;
trans.RollBack();
return Autodesk.Revit.UI.Result.Cancelled;
}
}
else
{
message = errorMessage;
trans.RollBack();
return Autodesk.Revit.UI.Result.Cancelled;
}
}
#endregion
try
{
if (null != wall)
{
ProfileWall profileWall = new ProfileWall(wall, commandData);
ShaftHolePuncherForm shaftHolePuncherForm =
new ShaftHolePuncherForm(profileWall);
shaftHolePuncherForm.ShowDialog();
}
else if (null != floor)
{
ProfileFloor profileFloor = new ProfileFloor(floor, commandData);
ShaftHolePuncherForm shaftHolePuncherForm =
new ShaftHolePuncherForm(profileFloor);
shaftHolePuncherForm.ShowDialog();
}
else if (null != familyInstance)
{
ProfileBeam profileBeam = new ProfileBeam(familyInstance, commandData);
ShaftHolePuncherForm shaftHolePuncherForm =
new ShaftHolePuncherForm(profileBeam);
shaftHolePuncherForm.ShowDialog();
}
else
{
ProfileNull profileNull = new ProfileNull(commandData);
ShaftHolePuncherForm shaftHolePuncherForm =
new ShaftHolePuncherForm(profileNull);
shaftHolePuncherForm.ShowDialog();
}
}
catch (Exception ex)
{
message = ex.Message;
trans.RollBack();
return Autodesk.Revit.UI.Result.Cancelled;
}
trans.Commit();
return Autodesk.Revit.UI.Result.Succeeded;
}
catch (Exception e)
{
message = e.Message;
trans.RollBack();
return Autodesk.Revit.UI.Result.Failed;
}
}
#endregion
}
}
+124
View File
@@ -0,0 +1,124 @@
//
// (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.ShaftHolePuncher.CS
{
/// <summary>
/// Abstract class used as a base class of all drawing tool class
/// </summary>
public abstract class ITool
{
# region members
protected List<Point> m_points = new List<Point>(); // Field used to store points of a line
protected Pen m_backGroundPen; // background pen used to Erase the preview line
protected Pen m_foreGroundPen; // foreground pen used to draw lines
protected Point m_preMovePoint; // store the mouse position when mouse move in pictureBox
protected Point m_preDownPoint; // store the mouse position when right mouse button clicked in pictureBox
protected bool m_finished; // indicate whether user have finished drawing
#endregion
/// <summary>
/// Finished property to define whether curve was finished
/// </summary>
public virtual bool Finished
{
get
{
return m_finished;
}
set
{
m_finished = value;
}
}
/// <summary>
/// get all lines drawn in pictureBox
/// </summary>
public virtual List<Point> Points
{
get
{
return m_points;
}
}
/// <summary>
/// default constructor
/// </summary>
public ITool()
{
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>
/// calculate the distance between two points
/// </summary>
/// <param name="p1">first point</param>
/// <param name="p2">second point</param>
/// <returns>distance between two points</returns>
public double GetDistance(Point p1, Point p2)
{
double distance = Math.Sqrt(
(p2.X - p1.X) * (p2.X - p1.X) + (p2.Y - p1.Y) * (p2.Y - p1.Y));
return distance;
}
/// <summary>
/// clear all the points in the tool
/// </summary>
public virtual void Clear()
{
m_points.Clear();
}
/// <summary>
/// draw a line from end point to the location where mouse moved
/// </summary>
/// <param name="graphic">Graphics object,used to draw geometry</param>
/// <param name="e">mouse event args</param>
public virtual void OnMouseMove(System.Drawing.Graphics graphic,
System.Windows.Forms.MouseEventArgs e) { }
/// <summary>
/// record the location point where mouse clicked
/// </summary>
/// <param name="e">mouse event args</param>
public virtual void OnMouseDown(System.Windows.Forms.MouseEventArgs e) { }
/// <summary>
/// draw the stored lines
/// </summary>
/// <param name="graphic">Graphics object, used to draw geometry</param>
public virtual void Draw(Graphics graphic) { }
}
}
@@ -0,0 +1,91 @@
//
// (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.ShaftHolePuncher.CS
{
/// <summary>
/// tool used to draw line
/// </summary>
public class LineTool : ITool
{
/// <summary>
/// draw a line from end point of tool to the location where mouse moved
/// </summary>
/// <param name="graphic">graphic object,used to draw geometry</param>
/// <param name="e">mouse event args</param>
public override 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>
/// record the location point where mouse clicked
/// </summary>
/// <param name="e">mouse event args</param>
public override void OnMouseDown(System.Windows.Forms.MouseEventArgs e)
{
//when user click right button of mouse,
//finish the curve if the number of points is more than 2
if (MouseButtons.Right == e.Button && m_points.Count > 2)
{
m_finished = true;
}
if (MouseButtons.Left == e.Button && !m_finished
&& GetDistance(m_preDownPoint, e.Location) > 2)
{
m_preDownPoint = e.Location;
m_points.Add(e.Location);
}
}
/// <summary>
/// draw lines recorded in the tool
/// </summary>
/// <param name="graphic">Graphics object, use to draw geometry</param>
public override 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]);
}
//if user finished draw (clicked the right button), then close the curve
if (m_finished)
{
graphic.DrawLine(m_foreGroundPen, m_points[0], m_points[m_points.Count - 1]);
}
}
}
}
@@ -0,0 +1,462 @@
//
// (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.ShaftHolePuncher.CS
{
/// <summary>
/// Vector4 class used 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 needs 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 vectors</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] = scale;
m_matrix[1, 1] = scale;
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 using this matrix
/// </summary>
/// <param name="point">point 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]);
}
};
}
+347
View File
@@ -0,0 +1,347 @@
//
// (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.ShaftHolePuncher.CS
{
/// <summary>
/// base class of ProfileFloor, ProfileWall and ProfileNull.
/// contains the profile information and can calculate matrix to transform point to 2D plane
/// </summary>
public abstract class Profile
{
#region class member variables
// store all the points on the needed face
protected List<List<XYZ>> m_points;
// object which contains reference to Revit Application
protected Autodesk.Revit.UI.ExternalCommandData m_commandData;
// used to create new instances of utility objects.
protected Autodesk.Revit.Creation.Application m_appCreator;
// used to create new instances of elements
protected Autodesk.Revit.Creation.Document m_docCreator;
// store the Matrix used to transform 3D points to 2D
protected Matrix4 m_to2DMatrix = null;
// store the Matrix used to move points to center
protected Matrix4 m_moveToCenterMatrix = null;
// store the Matrix used to scale profile fit to pictureBox
protected Matrix4 m_scaleMatrix = null;
// store the Matrix used to transform Revit coordinate to window UI
protected Matrix4 m_transformMatrix = null;
// store the Matrix used to transform window UI coordinate to Revit
protected Matrix4 m_restoreMatrix = null;
// store the size of pictureBox in UI
protected Size m_sizePictureBox;
#endregion
/// <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_docCreator = m_commandData.Application.ActiveUIDocument.Document.Create;
}
/// <summary>
/// abstract method to create Opening
/// </summary>
/// <returns>newly created Opening</returns>
/// <param name="points">points used to create Opening</param>
public abstract Opening CreateOpening(List<Vector4> points);
/// <summary>
/// Get points in first face
/// </summary>
/// <param name="faces">edges in all faces</param>
/// <returns>points in first face</returns>
public virtual List<List<XYZ>> GetNeedPoints(List<List<Edge>> faces)
{
return null;
}
/// <summary>
/// Get a matrix which can transform points to 2D
/// </summary>
public virtual Matrix4 GetTo2DMatrix()
{
return null;
}
/// <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>
/// Get edges of element's profile
/// </summary>
/// <param name="elem">selected element</param>
/// <returns>all the faces in the selected Element</returns>
public virtual 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;
//make sure references to geometric objects are computed.
options.ComputeReferences = true;
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 stores the bound of the face</returns>
public virtual 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;
}
/// <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>
/// transform the point on Form to 3d world coordinate of revit
/// </summary>
/// <param name="ps">contain the points to be transformed</param>
/// <returns>Vector list contains points being transformed</returns>
public virtual List<Vector4> Transform2DTo3D(Point[] ps)
{
List<Vector4> result = new List<Vector4>();
TransformPoints(ps);
Matrix4 transformMatrix = Matrix4.Multiply(
m_scaleMatrix.Inverse(), m_moveToCenterMatrix);
transformMatrix = Matrix4.Multiply(transformMatrix, m_to2DMatrix);
foreach (Point point in ps)
{
Vector4 v = new Vector4(point.X, point.Y, 0);
v = transformMatrix.Transform(v);
result.Add(v);
}
return result;
}
/// <summary>
/// use matrix to transform point
/// </summary>
/// <param name="pts">contain the points to be transformed</param>
private void TransformPoints(Point[] pts)
{
System.Drawing.Drawing2D.Matrix matrix = new System.Drawing.Drawing2D.Matrix(
1, 0, 0, 1, m_sizePictureBox.Width / 2, m_sizePictureBox.Height / 2);
matrix.Invert();
matrix.TransformPoints(pts);
}
}
}
@@ -0,0 +1,316 @@
//
// (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;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace Revit.SDK.Samples.ShaftHolePuncher.CS
{
/// <summary>
/// ProfileBeam class contains the information about profile of beam,
/// and contains method used to create opening on a beam.
/// </summary>
public class ProfileBeam : Profile
{
private FamilyInstance m_data = null; //beam
//store the transform used to change points in beam coordinate system to Revit coordinate system
Transform m_beamTransform = null;
bool m_isZaxis = true; //decide whether to create opening on Zaxis of beam or Yaixs of beam
//if m_haveOpening is true means beam has already had opening on it
//then the points get from get_Geometry(Option) do not need to be transformed
//by the Transform get from Instance object anymore.
bool m_haveOpening = false;
Matrix4 m_MatrixZaxis = null; //transform points to plane whose normal is Zaxis of beam
Matrix4 m_MatrixYaxis = null; //transform points to plane whose normal is Yaxis of beam
/// <summary>
/// constructor
/// </summary>
/// <param name="beam">beam to create opening on</param>
/// <param name="commandData">object which contains reference to Revit Application</param>
public ProfileBeam(FamilyInstance beam, ExternalCommandData commandData)
: base(commandData)
{
m_data = beam;
List<List<Edge>> faces = GetFaces(m_data);
m_points = GetNeedPoints(faces);
m_to2DMatrix = GetTo2DMatrix();
m_moveToCenterMatrix = ToCenterMatrix();
}
/// <summary>
/// Get points of the first face
/// </summary>
/// <param name="faces">edges in all faces</param>
/// <returns>points of first face</returns>
public override List<List<XYZ>> GetNeedPoints(List<List<Edge>> faces)
{
List<List<XYZ>> needPoints = new List<List<XYZ>>();
for (int i = 0; i < faces.Count; i++)
{
foreach (Edge edge in faces[i])
{
List<XYZ> edgexyzs = edge.Tessellate() as List<XYZ>;
if (false == m_haveOpening)
{
List<XYZ> transformedPoints = new List<XYZ>();
for (int j = 0; j < edgexyzs.Count; j++)
{
Autodesk.Revit.DB.XYZ xyz = edgexyzs[j];
Autodesk.Revit.DB.XYZ transformedXYZ = m_beamTransform.OfPoint(xyz);
transformedPoints.Add(transformedXYZ);
}
edgexyzs = transformedPoints;
}
needPoints.Add(edgexyzs);
}
}
return needPoints;
}
/// <summary>
/// Get the bound of a face
/// </summary>
/// <returns>points array stores the bound of the face</returns>
public override 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;
}
/// <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;
}
/// <summary>
/// Get edges of element's profile
/// </summary>
/// <param name="elem">selected element</param>
/// <returns>all the faces in the selected Element</returns>
public override 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;
//make sure references to geometric objects are computed.
options.ComputeReferences = true;
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;
//if beam doesn't contain opening on it, then we can get edges from instance
//and the points we get should be transformed by instance.Tranceform
if (geo is Autodesk.Revit.DB.GeometryInstance)
{
Autodesk.Revit.DB.GeometryInstance instance = geo as Autodesk.Revit.DB.GeometryInstance;
m_beamTransform = instance.Transform;
Autodesk.Revit.DB.GeometryElement elemGeo = instance.SymbolGeometry;
//GeometryObjectArray objectsGeo = elemGeo.Objects;
IEnumerator<GeometryObject> Objects1 = elemGeo.GetEnumerator();
//foreach (GeometryObject objGeo in objectsGeo)
while (Objects1.MoveNext())
{
GeometryObject objGeo = Objects1.Current;
Solid solid = objGeo as Solid;
if (null != solid)
{
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);
}
}
}
}
}
//if beam contains opening on it, then we can get edges from solid
//and the points we get do not need transform anymore
else if (geo is Autodesk.Revit.DB.Solid)
{
m_haveOpening = true;
Solid solid = geo as Solid;
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>
/// Create Opening on beam
/// </summary>
/// <param name="points">points used to create Opening</param>
/// <returns>newly created Opening</returns>
public override Opening CreateOpening(List<Vector4> points)
{
Autodesk.Revit.DB.XYZ p1, p2; Line curve;
CurveArray curves = m_appCreator.NewCurveArray();
for (int i = 0; i < points.Count - 1; i++)
{
p1 = new Autodesk.Revit.DB.XYZ(points[i].X, points[i].Y, points[i].Z);
p2 = new Autodesk.Revit.DB.XYZ(points[i + 1].X, points[i + 1].Y, points[i + 1].Z);
curve = Line.CreateBound(p1, p2);
curves.Append(curve);
}
//close the curve
p1 = new Autodesk.Revit.DB.XYZ(points[0].X, points[0].Y, points[0].Z);
p2 = new Autodesk.Revit.DB.XYZ(points[points.Count - 1].X, points[points.Count - 1].Y, points[points.Count - 1].Z);
curve = Line.CreateBound(p1, p2);
curves.Append(curve);
if (false == m_isZaxis)
{
return m_docCreator.NewOpening(m_data, curves, Autodesk.Revit.Creation.eRefFace.CenterY);
}
else
{
return m_docCreator.NewOpening(m_data, curves, Autodesk.Revit.Creation.eRefFace.CenterZ);
}
}
/// <summary>
/// Change transform matrix used to transform points to 2d.
/// </summary>
/// <param name="isZaxis">transform points to which plane.
/// true means transform points to plane whose normal is Zaxis of beam.
/// false means transform points to plane whose normal is Yaxis of beam
/// </param>
public void ChangeTransformMatrix(bool isZaxis)
{
m_isZaxis = isZaxis;
if (isZaxis)
{
m_to2DMatrix = m_MatrixZaxis;
}
else
{
m_to2DMatrix = m_MatrixYaxis;
}
//re-calculate matrix used to move points to center
m_moveToCenterMatrix = ToCenterMatrix();
}
}
}
@@ -0,0 +1,129 @@
//
// (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.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace Revit.SDK.Samples.ShaftHolePuncher.CS
{
/// <summary>
/// ProfileFloor class contains the information about profile of floor,
/// and contains method used to create Opening on floor
/// </summary>
public class ProfileFloor : Profile
{
private Floor m_data = null;
/// <summary>
/// constructor
/// </summary>
/// <param name="floor">floor to create Opening on</param>
/// <param name="commandData">object which contains reference of Revit Application</param>
public ProfileFloor(Floor floor, ExternalCommandData commandData)
: base(commandData)
{
m_data = floor;
List<List<Edge>> faces = GetFaces(m_data);
m_points = GetNeedPoints(faces);
m_to2DMatrix = GetTo2DMatrix();
m_moveToCenterMatrix = ToCenterMatrix();
}
/// <summary>
/// Get points of the first face
/// </summary>
/// <param name="faces">edges in all faces</param>
/// <returns>points of first face</returns>
public override List<List<XYZ>> GetNeedPoints(List<List<Edge>> faces)
{
List<List<XYZ>> needPoints = new List<List<XYZ>>();
foreach (Edge edge in faces[0])
{
List<XYZ> edgexyzs = edge.Tessellate() as List<XYZ>;
needPoints.Add(edgexyzs);
}
return needPoints;
}
/// <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.Name
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>
/// Create Opening on floor
/// </summary>
/// <param name="points">points used to create Opening</param>
/// <returns>newly created Opening</returns>
public override Opening CreateOpening(List<Vector4> points)
{
Autodesk.Revit.DB.XYZ p1, p2; Line curve;
CurveArray curves = m_appCreator.NewCurveArray();
for (int i = 0; i < points.Count - 1; i++)
{
p1 = new Autodesk.Revit.DB.XYZ(points[i].X, points[i].Y, points[i].Z);
p2 = new Autodesk.Revit.DB.XYZ(points[i + 1].X, points[i + 1].Y, points[i + 1].Z);
curve = Line.CreateBound(p1, p2);
curves.Append(curve);
}
//close the curve
p1 = new Autodesk.Revit.DB.XYZ(points[0].X, points[0].Y, points[0].Z);
p2 = new Autodesk.Revit.DB.XYZ(points[points.Count - 1].X,
points[points.Count - 1].Y, points[points.Count - 1].Z);
curve = Line.CreateBound(p1, p2);
curves.Append(curve);
return m_docCreator.NewOpening(m_data, curves, true);
}
}
}
@@ -0,0 +1,202 @@
//
// (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.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit;
using System.Drawing;
using System.Drawing.Drawing2D;
using Point = System.Drawing.Point;
namespace Revit.SDK.Samples.ShaftHolePuncher.CS
{
/// <summary>
/// ProfileNull class contains method to draw a coordinate system,
/// and contains method used to create Shaft Opening
/// </summary>
public class ProfileNull : Profile
{
Level level1 = null; //level 1 used to create Shaft Opening
Level level2 = null; //level 2 used to create Shaft Opening
float m_scale = 1; //scale of shaft opening
/// <summary>
/// Scale property to get/set scale of shaft opening
/// </summary>
public float Scale
{
get
{
return m_scale;
}
set
{
m_scale = value;
}
}
/// <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 level1 and level2 used to create shaft opening
/// </summary>
private void GetLevels()
{
IList<Element> levelList = (new FilteredElementCollector(m_commandData.Application.ActiveUIDocument.Document)).OfClass(typeof(Level)).ToElements();
IEnumerable<Level> levels = from elem in levelList
let level = elem as Level
where level != null && "Level 1" == level.Name
select level;
if (levels.Count() > 0)
{
level1 = levels.First();
}
levels = from elem in levelList
let level = elem as Level
where level != null && "Level 2" == level.Name
select level;
if (levels.Count() > 0)
{
level2 = levels.First();
}
}
/// <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>
/// 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>
/// move the points to the center and scale as user selected.
/// profile of shaft opening in Revit is 2d too, so don't need transform points to 2d
/// </summary>
/// <param name="ps">contain the points to be transformed</param>
/// <returns>Vector list contains points have been transformed</returns>
public override List<Vector4> Transform2DTo3D(Point[] ps)
{
List<Vector4> result = new List<Vector4>();
foreach (Point point in ps)
{
//because our coordinate system is different with window UI
//so we should change what we got from UI coordinate
Vector4 v = new Vector4((point.X - 20), -(point.Y - 280), 0);
v = m_scaleMatrix.Transform(v);
result.Add(v);
}
return result;
}
/// <summary>
/// Create Shaft Opening
/// </summary>
/// <param name="points">points used to create Opening</param>
/// <returns>newly created Opening</returns>
public override Opening CreateOpening(List<Vector4> points)
{
Autodesk.Revit.DB.XYZ p1, p2; Line curve;
CurveArray curves = m_appCreator.NewCurveArray();
for (int i = 0; i < points.Count - 1; i++)
{
p1 = new Autodesk.Revit.DB.XYZ(points[i].X, points[i].Y, points[i].Z);
p2 = new Autodesk.Revit.DB.XYZ(points[i + 1].X, points[i + 1].Y, points[i + 1].Z);
curve = Line.CreateBound(p1, p2);
curves.Append(curve);
}
//close the curve
p1 = new Autodesk.Revit.DB.XYZ(points[0].X, points[0].Y, points[0].Z);
p2 = new Autodesk.Revit.DB.XYZ(points[points.Count - 1].X,
points[points.Count - 1].Y, points[points.Count - 1].Z);
curve = Line.CreateBound(p1, p2);
curves.Append(curve);
return m_docCreator.NewOpening(level1, level2, curves);
}
}
}
@@ -0,0 +1,159 @@
//
// (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;
using System.Drawing;
using System.Windows.Forms;
namespace Revit.SDK.Samples.ShaftHolePuncher.CS
{
/// <summary>
/// ProfileWall class contains the information about profile of a wall,
/// and contains method to create Opening on a wall
/// </summary>
public class ProfileWall : Profile
{
private Wall m_data;
/// <summary>
/// constructor
/// </summary>
/// <param name="wall">wall to create Opening on</param>
/// <param name="commandData">object which contains reference of Revit Application</param>
public ProfileWall(Wall wall, ExternalCommandData commandData)
: base(commandData)
{
m_data = wall;
List<List<Edge>> faces = GetFaces(m_data);
m_points = GetNeedPoints(faces);
m_to2DMatrix = GetTo2DMatrix();
m_moveToCenterMatrix = ToCenterMatrix();
}
/// <summary>
/// Get points of first face
/// </summary>
/// <param name="faces">edges in all faces</param>
/// <returns>points of first face</returns>
public override List<List<XYZ>> GetNeedPoints(List<List<Edge>> faces)
{
List<Edge> needFace = new List<Edge>();
List<List<XYZ>> needPoints = new List<List<XYZ>>();
LocationCurve location = m_data.Location as LocationCurve;
Curve curve = location.Curve;
List<XYZ> xyzs = curve.Tessellate() as List<XYZ>;
Vector4 zAxis = new Vector4(0, 0, 1);
//if Location curve of wall is line, then return first face
if (xyzs.Count == 2)
{
needFace = faces[0];
}
//else we return the face whose normal is Z axis
foreach (List<Edge> face in faces)
{
foreach (Edge edge in face)
{
List<XYZ> edgexyzs = edge.Tessellate() as List<XYZ>;
if (xyzs.Count == edgexyzs.Count)
{
//get the normal of face
Vector4 normal = GetFaceNormal(face);
Vector4 cross = Vector4.CrossProduct(zAxis, normal);
cross.Normalize();
if (cross.Length() == 1)
{
needFace = face;
}
}
}
}
needFace = faces[0];
//get points array in edges
foreach (Edge edge in needFace)
{
List<XYZ> edgexyzs = edge.Tessellate() as List<XYZ>;
needPoints.Add(edgexyzs);
}
return needPoints;
}
/// <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 the location curve
LocationCurve location = m_data.Location as LocationCurve;
Vector4 xAxis = new Vector4(1, 0, 0);
Vector4 yAxis = new Vector4(0, 1, 0);
Vector4 zAxis = new Vector4(0, 0, 1);
Vector4 origin = new Vector4(0, 0, 0);
if (location != null)
{
Curve curve = location.Curve;
if (!(curve is Autodesk.Revit.DB.Line))
{
throw new Exception("Opening cannot build on this Wall");
}
Autodesk.Revit.DB.XYZ start = curve.GetEndPoint(0);
Autodesk.Revit.DB.XYZ end = curve.GetEndPoint(1);
xAxis = new Vector4((float)(end.X - start.X),
(float)(end.Y - start.Y), (float)(end.Z - start.Z));
xAxis.Normalize();
//because in the windows UI, Y axis is downward
yAxis = new Vector4(0, 0, -1);
zAxis = Vector4.CrossProduct(xAxis, yAxis);
zAxis.Normalize();
origin = new Vector4((float)(end.X + start.X) / 2,
(float)(end.Y + start.Y) / 2, (float)(end.Z + start.Z) / 2);
}
return new Matrix4(xAxis, yAxis, zAxis, origin);
}
/// <summary>
/// create Opening on wall
/// </summary>
/// <param name="points">points used to create Opening</param>
/// <returns>newly created Opening</returns>
public override Opening CreateOpening(List<Vector4> points)
{
//create Opening on wall
Autodesk.Revit.DB.XYZ p1 = new Autodesk.Revit.DB.XYZ (points[0].X, points[0].Y, points[0].Z);
Autodesk.Revit.DB.XYZ p2 = new Autodesk.Revit.DB.XYZ (points[1].X, points[1].Y, points[1].Z);
return m_docCreator.NewOpening(m_data, p1, p2);
}
}
}
@@ -0,0 +1,56 @@
//
// (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.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ShaftHolePuncher")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ShaftHolePuncher")]
[assembly: AssemblyCopyright("Copyright © Autodesk, Inc. 2009")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("03213aff-4e9d-486a-9e73-f269445eaea1")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
@@ -0,0 +1,96 @@
//
// (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.ShaftHolePuncher.CS
{
/// <summary>
/// tool used to draw line
/// </summary>
public class RectangleTool : ITool
{
/// <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 override void OnMouseMove(System.Drawing.Graphics graphic,
System.Windows.Forms.MouseEventArgs e)
{
if (1 == m_points.Count)
{
DrawRect(graphic, m_backGroundPen, m_points[0], m_preMovePoint);
m_preMovePoint = e.Location;
DrawRect(graphic, m_foreGroundPen, m_points[0], m_preMovePoint);
}
}
/// <summary>
/// record the location point where mouse clicked
/// </summary>
/// <param name="e">mouse event args</param>
public override void OnMouseDown(System.Windows.Forms.MouseEventArgs e)
{
if (MouseButtons.Left == e.Button && !m_finished
&& GetDistance(m_preDownPoint, e.Location) > 2)
{
m_preDownPoint = e.Location;
m_points.Add(e.Location);
if (2 == m_points.Count)
{
m_finished = true;
}
}
}
/// <summary>
/// draw a rectangle
/// </summary>
/// <param name="graphic">Graphics object, use to draw geometry</param>
public override void Draw(Graphics graphic)
{
if (2 == m_points.Count)
{
DrawRect(graphic, m_foreGroundPen, m_points[0], m_points[1]);
}
}
/// <summary>
/// draw rectangle use the given two points p1 and p2
/// </summary>
/// <param name="graphic">Graphics object,used to draw geometry</param>
/// <param name="pen">Pen used to set color</param>
/// <param name="p1">rectangle one corner</param>
/// <param name="p2">opposite corner of p1</param>
private void DrawRect(Graphics graphic, Pen pen, Point p1, Point p2)
{
Point[] points = new Point[5] { p1, new Point(p1.X, p2.Y),
p2, new Point(p2.X, p1.Y), p1 };
graphic.DrawLines(pen, points);
}
}
}
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<RevitAddIns>
<AddIn Type="Command">
<Assembly>ShaftHolePuncher.dll</Assembly>
<ClientId>9708919a-94fc-429a-986e-556c65286694</ClientId>
<FullClassName>Revit.SDK.Samples.ShaftHolePuncher.CS.Command</FullClassName>
<Text>Shaft Hole Puncher</Text>
<Description>Create shaft opening or create opening on wall, floor or beam.</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<VendorId>ADSK</VendorId>
<VendorDescription>Autodesk, www.autodesk.com</VendorDescription>
</AddIn>
</RevitAddIns>
@@ -0,0 +1,106 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{F505433F-AF41-4A23-AC0F-F38FFA99EC5D}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ShaftHolePuncher</RootNamespace>
<AssemblyName>ShaftHolePuncher</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup>
<RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Command.cs" />
<Compile Include="ITool.cs" />
<Compile Include="LineTool.cs" />
<Compile Include="MathTools.cs" />
<Compile Include="Profile.cs" />
<Compile Include="ProfileBeam.cs" />
<Compile Include="ProfileFloor.cs" />
<Compile Include="ProfileNull.cs" />
<Compile Include="ProfileWall.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RectangleTool.cs" />
<Compile Include="ShaftHolePuncherForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="ShaftHolePuncherForm.Designer.cs">
<DependentUpon>ShaftHolePuncherForm.cs</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="ShaftHolePuncherForm.resx">
<SubType>Designer</SubType>
<DependentUpon>ShaftHolePuncherForm.cs</DependentUpon>
</EmbeddedResource>
</ItemGroup>
<Import Project="$(SolutionDir)VSProps\SDKSamples.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<PropertyGroup>
<PostBuildEvent>set FILEFORSAMPLEREG="$(SolutionDir)..\..\..\..\Regression\API\SDKSamples\UpdateSampleDllForRegression.pl"
if exist %25FILEFORSAMPLEREG%25 perl %25FILEFORSAMPLEREG%25 $(ProjectExt) "$(ProjectPath)" "$(TargetPath)" "$(SolutionDir)"</PostBuildEvent>
</PropertyGroup>
<PropertyGroup>
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
</PropertyGroup>
</Project>
@@ -0,0 +1,231 @@
//
// (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.ShaftHolePuncher.CS
{
/// <summary>
/// window form contains one picture box to show the
/// profile of wall (or floor), and three command buttons.
/// User can draw curves of opening in picture box.
/// </summary>
partial class ShaftHolePuncherForm
{
/// <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.labelNote = new System.Windows.Forms.Label();
this.cleanButton = new System.Windows.Forms.Button();
this.ScaleComboBox = new System.Windows.Forms.ComboBox();
this.scaleLabel = new System.Windows.Forms.Label();
this.DirectionLabel = new System.Windows.Forms.Label();
this.DirectionComboBox = new System.Windows.Forms.ComboBox();
this.DirectionPanel = new System.Windows.Forms.Panel();
((System.ComponentModel.ISupportInitialize)(this.pictureBox)).BeginInit();
this.DirectionPanel.SuspendLayout();
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(10, 12);
this.pictureBox.Name = "pictureBox";
this.pictureBox.Size = new System.Drawing.Size(450, 300);
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(275, 395);
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(369, 395);
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);
//
// 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(7, 328);
this.labelNote.Name = "labelNote";
this.labelNote.Size = new System.Drawing.Size(233, 33);
this.labelNote.TabIndex = 4;
this.labelNote.Text = "Click and drag to create a curve. Right click to close the curve.";
//
// cleanButton
//
this.cleanButton.Location = new System.Drawing.Point(369, 357);
this.cleanButton.Name = "cleanButton";
this.cleanButton.Size = new System.Drawing.Size(87, 23);
this.cleanButton.TabIndex = 3;
this.cleanButton.Text = "C&lean";
this.cleanButton.UseVisualStyleBackColor = true;
this.cleanButton.Click += new System.EventHandler(this.ButtonClean_Click);
//
// ScaleComboBox
//
this.ScaleComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.ScaleComboBox.FormattingEnabled = true;
this.ScaleComboBox.Items.AddRange(new object[] {
"1",
"0.1",
"0.3",
"0.5",
"0.8",
"2",
"3"});
this.ScaleComboBox.Location = new System.Drawing.Point(369, 325);
this.ScaleComboBox.Name = "ScaleComboBox";
this.ScaleComboBox.Size = new System.Drawing.Size(85, 21);
this.ScaleComboBox.TabIndex = 4;
this.ScaleComboBox.Visible = false;
this.ScaleComboBox.SelectedIndexChanged += new System.EventHandler(this.ScaleComboBox_SelectedIndexChanged);
//
// scaleLabel
//
this.scaleLabel.AutoSize = true;
this.scaleLabel.Location = new System.Drawing.Point(316, 328);
this.scaleLabel.Name = "scaleLabel";
this.scaleLabel.Size = new System.Drawing.Size(47, 13);
this.scaleLabel.TabIndex = 8;
this.scaleLabel.Text = "Scale :";
this.scaleLabel.Visible = false;
//
// DirectionLabel
//
this.DirectionLabel.AutoSize = true;
this.DirectionLabel.Location = new System.Drawing.Point(3, 6);
this.DirectionLabel.Name = "DirectionLabel";
this.DirectionLabel.Size = new System.Drawing.Size(67, 13);
this.DirectionLabel.TabIndex = 9;
this.DirectionLabel.Text = "Direction :";
//
// DirectionComboBox
//
this.DirectionComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.DirectionComboBox.FormattingEnabled = true;
this.DirectionComboBox.Items.AddRange(new object[] {
"Z-axis",
"Y-axis"});
this.DirectionComboBox.Location = new System.Drawing.Point(76, 3);
this.DirectionComboBox.Name = "DirectionComboBox";
this.DirectionComboBox.Size = new System.Drawing.Size(85, 21);
this.DirectionComboBox.TabIndex = 10;
this.DirectionComboBox.SelectedIndexChanged += new System.EventHandler(this.DirectionComboBox_SelectedIndexChanged);
//
// DirectionPanel
//
this.DirectionPanel.Controls.Add(this.DirectionLabel);
this.DirectionPanel.Controls.Add(this.DirectionComboBox);
this.DirectionPanel.Location = new System.Drawing.Point(291, 323);
this.DirectionPanel.Name = "DirectionPanel";
this.DirectionPanel.Size = new System.Drawing.Size(169, 28);
this.DirectionPanel.TabIndex = 11;
this.DirectionPanel.Visible = false;
//
// ShaftHolePuncherForm
//
this.AcceptButton = this.createButton;
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.cancelButton;
this.ClientSize = new System.Drawing.Size(470, 429);
this.Controls.Add(this.DirectionPanel);
this.Controls.Add(this.scaleLabel);
this.Controls.Add(this.ScaleComboBox);
this.Controls.Add(this.cleanButton);
this.Controls.Add(this.labelNote);
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 = "ShaftHolePuncherForm";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.Text = "Shaft Hole Puncher";
((System.ComponentModel.ISupportInitialize)(this.pictureBox)).EndInit();
this.DirectionPanel.ResumeLayout(false);
this.DirectionPanel.PerformLayout();
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.Label labelNote;
private System.Windows.Forms.Button cleanButton;
private System.Windows.Forms.ComboBox ScaleComboBox;
private System.Windows.Forms.Label scaleLabel;
private System.Windows.Forms.Label DirectionLabel;
private System.Windows.Forms.ComboBox DirectionComboBox;
private System.Windows.Forms.Panel DirectionPanel;
}
}
@@ -0,0 +1,213 @@
//
// (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.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Point = System.Drawing.Point;
namespace Revit.SDK.Samples.ShaftHolePuncher.CS
{
/// <summary>
/// window form contains one picture box to show the
/// profile of a wall or floor, and three command buttons.
/// User can draw curves of opening in picture box.
/// </summary>
public partial class ShaftHolePuncherForm : System.Windows.Forms.Form
{
#region class members
private Profile m_profile; //save the profile data
private ITool m_tool = null; //current using tool
Size m_sizePictureBox; //size of picture box
#endregion
/// <summary>
/// constructor
/// </summary>
public ShaftHolePuncherForm()
{
InitializeComponent();
}
/// <summary>
/// constructor
/// </summary>
/// <param name="profile">ProfileWall, ProfileFloor or ProfileNull</param>
public ShaftHolePuncherForm(Profile profile)
: this()
{
m_profile = profile;
m_sizePictureBox = this.pictureBox.Size;
if (profile is ProfileWall)
{
m_tool = new RectangleTool();
}
else
{
m_tool = new LineTool();
}
if (profile is ProfileNull)
{
this.ScaleComboBox.Visible = true;
this.ScaleComboBox.SelectedIndex = 0;
this.scaleLabel.Visible = true;
}
else if (profile is ProfileBeam)
{
this.DirectionPanel.Visible = true;
this.DirectionComboBox.SelectedIndex = 0;
}
}
/// <summary>
/// store mouse location when mouse down
/// </summary>
/// <param name="sender">object who sent this event</param>
/// <param name="e">event args</param>
private void PictureBox_MouseDown(object sender, MouseEventArgs e)
{
Graphics graphics = this.pictureBox.CreateGraphics();
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
m_tool.OnMouseDown(e);
this.pictureBox.Refresh();
}
/// <summary>
/// draw the line to where mouse moved
/// </summary>
/// <param name="sender">object who sent this event</param>
/// <param name="e">event args</param>
private void PictureBox_MouseMove(object sender, MouseEventArgs e)
{
this.pictureBox.Refresh();
Graphics graphics = this.pictureBox.CreateGraphics();
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
m_tool.OnMouseMove(graphics, e);
}
/// <summary>
/// draw the curve of floor (or wall) and curves of Opening
/// </summary>
/// <param name="sender">object who sent this event</param>
/// <param name="e">event args</param>
private void PictureBox_Paint(object sender, PaintEventArgs e)
{
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//Draw the pictures in the m_tools
m_tool.Draw(e.Graphics);
//get transform matrix
m_profile.ComputeScaleMatrix(m_sizePictureBox);
Matrix4 trans = m_profile.Compute3DTo2DMatrix();
//draw profile
m_profile.Draw2D(e.Graphics, Pens.Blue, trans);
}
/// <summary>
/// clear all the curves of the Opening
/// </summary>
/// <param name="sender">object who sent this event</param>
/// <param name="e">event args</param>
private void ButtonClean_Click(object sender, EventArgs e)
{
m_tool.Clear();
m_tool.Finished = false;
this.pictureBox.Refresh();
}
/// <summary>
/// create Shaft Opening in Revit
/// </summary>
/// <param name="sender">object who sent this event</param>
/// <param name="e">event args</param>
private void CreateButton_Click(object sender, EventArgs e)
{
List<Point> points = m_tool.Points;
if (!m_tool.Finished)
{
TaskDialog.Show("Revit", "Please finish the curve of Opening first!");
return;
}
List<Vector4> ps3D = m_profile.Transform2DTo3D(points.ToArray());
try
{
m_profile.CreateOpening(ps3D);
this.Close();
}
catch (Exception ex)
{
TaskDialog.Show("Revit", ex.Message);
ButtonClean_Click(null, null);
}
}
/// <summary>
/// close the form
/// </summary>
/// <param name="sender">object who sent this event</param>
/// <param name="e">event args</param>
private void CancelButton_Click(object sender, EventArgs e)
{
this.Close();
}
/// <summary>
/// set the scale of profile when create Shaft Opening
/// </summary>
/// <param name="sender">object who sent this event</param>
/// <param name="e">event args</param>
private void ScaleComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
ProfileNull profile = m_profile as ProfileNull;
profile.Scale = (float)Convert.ToDouble(this.ScaleComboBox.Text);
m_profile.ComputeScaleMatrix(m_sizePictureBox);
}
private void DirectionComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
m_tool.Clear();
m_tool.Finished = false;
ProfileBeam profile = m_profile as ProfileBeam;
if (0 == this.DirectionComboBox.SelectedIndex)
{
profile.ChangeTransformMatrix(true);
}
else if (1 == this.DirectionComboBox.SelectedIndex)
{
profile.ChangeTransformMatrix(false);
}
this.pictureBox.Refresh();
}
}
}
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>