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
@@ -0,0 +1,72 @@
//
// (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.CreateBeamSystem.CS
{
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using Autodesk.Revit;
using Autodesk.Revit.DB;
/// <summary>
/// is used to create new instances of beam system
/// </summary>
public class BeamSystemBuilder
{
/// <summary>
/// the data used to create beam system
/// </summary>
private BeamSystemData m_data;
/// <summary>
/// constructor
/// </summary>
/// <param name="data">the data used to create beam system</param>
public BeamSystemBuilder(BeamSystemData data)
{
m_data = data;
}
/// <summary>
/// create beam system according to given profile and property
/// </summary>
public void CreateBeamSystem()
{
Document document = m_data.CommandData.Application.ActiveUIDocument.Document;
// create curve array and insert Lines in order
IList<Curve> curves = new List<Curve>();
foreach (Line line in m_data.Lines)
{
curves.Add(line);
}
// create beam system takes closed profile consist of lines
BeamSystem aBeamSystem = BeamSystem.Create(document, curves, document.ActiveView.SketchPlane, 0);
// set created beam system's layout rule and beam type property
aBeamSystem.LayoutRule = m_data.Param.Layout;
aBeamSystem.BeamType = m_data.Param.BeamType;
}
}
}
@@ -0,0 +1,279 @@
//
// (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.CreateBeamSystem.CS
{
using System;
using System.Text;
using System.Collections.Generic;
using System.Collections;
using System.Diagnostics;
using System.Collections.ObjectModel;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB.Structure;
/// <summary>
/// mixed data class save the data to show in UI
/// and the data used to create beam system
/// </summary>
public class BeamSystemData
{
/// <summary>
/// all beam types loaded in current Revit project
/// it is declared as static only because of PropertyGrid
/// </summary>
private static Dictionary<string, FamilySymbol> m_beamTypes = new Dictionary<string, FamilySymbol>();
/// <summary>
/// properties of beam system
/// </summary>
private BeamSystemParam m_param;
/// <summary>
/// buffer of ExternalCommandData
/// </summary>
private ExternalCommandData m_commandData;
/// <summary>
/// the lines compose the profile of beam system
/// </summary>
private List<Line> m_lines = new List<Line>();
/// <summary>
/// a number of beams that intersect end to end
/// so that form a profile used as beam system's profile
/// </summary>
private List<FamilyInstance> m_beams = new List<FamilyInstance>();
/// <summary>
/// properties of beam system
/// </summary>
public BeamSystemParam Param
{
get
{
return m_param;
}
}
/// <summary>
/// lines form the profile of beam system
/// </summary>
public ReadOnlyCollection<Line> Lines
{
get
{
return new ReadOnlyCollection<Line>(m_lines);
}
}
/// <summary>
/// buffer of ExternalCommandData
/// </summary>
public ExternalCommandData CommandData
{
get
{
return m_commandData;
}
}
/// <summary>
/// the data used to show in UI is updated
/// </summary>
public event EventHandler ParamsUpdated;
/// <summary>
/// constructor
/// if precondition in current Revit project isn't enough,
/// ErrorMessageException will be throw out
/// </summary>
/// <param name="commandData">data from Revit</param>
public BeamSystemData(ExternalCommandData commandData)
{
// initialize members
m_commandData = commandData;
PrepareData();
InitializeProfile(m_beams);
m_param = BeamSystemParam.CreateInstance(LayoutMethod.ClearSpacing);
List<FamilySymbol> beamTypes = new List<FamilySymbol>(m_beamTypes.Values);
m_param.BeamType = beamTypes[0];
m_param.LayoutRuleChanged += new LayoutRuleChangedHandler(LayoutRuleChanged);
}
/// <summary>
/// change the direction to the next line in the profile
/// </summary>
public void ChangeProfileDirection()
{
Line tmp = m_lines[0];
m_lines.RemoveAt(0);
m_lines.Add(tmp);
}
/// <summary>
/// all beam types loaded in current Revit project
/// it is declared as static only because of PropertyGrid
/// </summary>
/// <returns></returns>
public static Dictionary<string, FamilySymbol> GetBeamTypes()
{
Dictionary<string, FamilySymbol> beamTypes = new Dictionary<string, FamilySymbol>(m_beamTypes);
return beamTypes;
}
/// <summary>
/// initialize members using data from current Revit project
/// </summary>
private void PrepareData()
{
UIDocument doc = m_commandData.Application.ActiveUIDocument;
m_beamTypes.Clear();
// iterate all selected beams
foreach (ElementId elementId in doc.Selection.GetElementIds())
{
object obj = doc.Document.GetElement(elementId);
FamilyInstance beam = obj as FamilyInstance;
if (null == beam)
{
continue;
}
// add beam to lists according to category name
string categoryName = beam.Category.Name;
if ("Structural Framing" == categoryName
&& beam.StructuralType == StructuralType.Beam)
{
m_beams.Add(beam);
}
}
//iterate all beam types
FilteredElementIterator itor = new FilteredElementCollector(doc.Document).OfClass(typeof(Family)).GetElementIterator();
itor.Reset();
while (itor.MoveNext())
{
// get Family to get FamilySymbols
Family aFamily = itor.Current as Family;
if (null == aFamily)
{
continue;
}
foreach (ElementId symbolId in aFamily.GetFamilySymbolIds())
{
FamilySymbol symbol = doc.Document.GetElement(symbolId) as FamilySymbol;
if (null == symbol.Category)
{
continue;
}
// add symbols to lists according to category name
string categoryName = symbol.Category.Name;
if ("Structural Framing" == categoryName)
{
m_beamTypes.Add(symbol.Family.Name + ":" + symbol.Name, symbol);
}
}
}
if (m_beams.Count == 0)
{
throw new ErrorMessageException("Please select beams.");
}
if (m_beamTypes.Count == 0)
{
throw new ErrorMessageException("There is no Beam families loaded in current project.");
}
}
/// <summary>
/// retrieve the profiles using the selected beams
/// ErrorMessageException will be thrown out if beams can't make a closed profile
/// </summary>
/// <param name="beams">beams which may form a closed profile</param>
private void InitializeProfile(List<FamilyInstance> beams)
{
// retrieve collection of lines in beams
List<Line> lines = new List<Line>();
foreach (FamilyInstance beam in beams)
{
LocationCurve locationLine = beam.Location as LocationCurve;
Line line = locationLine.Curve as Line;
if (null == line)
{
throw new ErrorMessageException("Please don't select any arc beam.");
}
lines.Add(line);
}
// lines should in the same horizontal plane
if (!GeometryUtil.InSameHorizontalPlane(lines))
{
throw new ErrorMessageException("The selected beams can't form a horizontal profile.");
}
// sorted lines so that all lines are intersect end to end
m_lines = GeometryUtil.SortLines(lines);
// lines can't make a closed profile
if (null == m_lines)
{
throw new ErrorMessageException("The selected beams can't form a closed profile.");
}
}
/// <summary>
/// layout rule of beam system has changed
/// </summary>
/// <param name="layoutMethod">changed method</param>
private void LayoutRuleChanged(ref LayoutMethod layoutMethod)
{
// create BeamSystemParams instance according to changed LayoutMethod
m_param = m_param.CloneInstance(layoutMethod);
// raise DataUpdated event
OnParamsUpdated(new EventArgs());
// rebind delegate
m_param.LayoutRuleChanged += new LayoutRuleChangedHandler(LayoutRuleChanged);
}
/// <summary>
/// the data used to show in UI is updated
/// </summary>
/// <param name="e"></param>
protected virtual void OnParamsUpdated(EventArgs e)
{
if (null != ParamsUpdated)
{
ParamsUpdated(this, e);
}
}
}
}
+142
View File
@@ -0,0 +1,142 @@
//
// (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.CreateBeamSystem.CS
{
partial class BeamSystemForm
{
/// <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.previewPictureBox = new System.Windows.Forms.PictureBox();
this.beamSystemPropertyGrid = new System.Windows.Forms.PropertyGrid();
this.OKButton = new System.Windows.Forms.Button();
this.cancelButton = new System.Windows.Forms.Button();
this.changeDirectionButton = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.previewPictureBox)).BeginInit();
this.SuspendLayout();
//
// previewPictureBox
//
this.previewPictureBox.BackColor = System.Drawing.SystemColors.ButtonHighlight;
this.previewPictureBox.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.previewPictureBox.Location = new System.Drawing.Point(12, 12);
this.previewPictureBox.Name = "previewPictureBox";
this.previewPictureBox.Size = new System.Drawing.Size(426, 326);
this.previewPictureBox.TabIndex = 0;
this.previewPictureBox.TabStop = false;
//
// beamSystemPropertyGrid
//
this.beamSystemPropertyGrid.Location = new System.Drawing.Point(444, 12);
this.beamSystemPropertyGrid.Name = "beamSystemPropertyGrid";
this.beamSystemPropertyGrid.Size = new System.Drawing.Size(318, 297);
this.beamSystemPropertyGrid.TabIndex = 1;
//
// OKButton
//
this.OKButton.Location = new System.Drawing.Point(606, 315);
this.OKButton.Name = "OKButton";
this.OKButton.Size = new System.Drawing.Size(75, 23);
this.OKButton.TabIndex = 3;
this.OKButton.Text = "&OK";
this.OKButton.UseVisualStyleBackColor = true;
this.OKButton.Click += new System.EventHandler(this.OKButton_Click);
//
// cancelButton
//
this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.cancelButton.Location = new System.Drawing.Point(687, 315);
this.cancelButton.Name = "cancelButton";
this.cancelButton.Size = new System.Drawing.Size(75, 23);
this.cancelButton.TabIndex = 4;
this.cancelButton.Text = "&Cancel";
this.cancelButton.UseVisualStyleBackColor = true;
this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click);
//
// changeDirectionButton
//
this.changeDirectionButton.Location = new System.Drawing.Point(444, 315);
this.changeDirectionButton.Name = "changeDirectionButton";
this.changeDirectionButton.Size = new System.Drawing.Size(156, 23);
this.changeDirectionButton.TabIndex = 2;
this.changeDirectionButton.Text = "Change &Direction";
this.changeDirectionButton.UseVisualStyleBackColor = true;
this.changeDirectionButton.Click += new System.EventHandler(this.changeDirectionButton_Click);
//
// BeamSystemForm
//
this.AcceptButton = this.OKButton;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.cancelButton;
this.ClientSize = new System.Drawing.Size(774, 350);
this.Controls.Add(this.changeDirectionButton);
this.Controls.Add(this.cancelButton);
this.Controls.Add(this.OKButton);
this.Controls.Add(this.beamSystemPropertyGrid);
this.Controls.Add(this.previewPictureBox);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "BeamSystemForm";
this.ShowInTaskbar = false;
this.Text = "Create Beam System";
this.Load += new System.EventHandler(this.BeamSystemForm_Load);
((System.ComponentModel.ISupportInitialize)(this.previewPictureBox)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.PictureBox previewPictureBox;
private System.Windows.Forms.PropertyGrid beamSystemPropertyGrid;
private System.Windows.Forms.Button OKButton;
private System.Windows.Forms.Button cancelButton;
private System.Windows.Forms.Button changeDirectionButton;
}
}
@@ -0,0 +1,119 @@
//
// (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.CreateBeamSystem.CS
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
/// <summary>
/// display beam system to be created and allow user to set its properties
/// </summary>
public partial class BeamSystemForm : System.Windows.Forms.Form
{
/// <summary>
/// buffer of data related to UI
/// </summary>
private BeamSystemData m_data;
/// <summary>
/// class to draw profile of beam system in PictureBox
/// </summary>
private BeamSystemSketch m_sketch;
/// <summary>
/// constructor
/// </summary>
/// <param name="data">data related to UI</param>
public BeamSystemForm(BeamSystemData data)
{
InitializeComponent();
m_data = data;
// bound PictureBox to display the profile
m_sketch = new BeamSystemSketch(previewPictureBox);
}
/// <summary>
/// update PropertyGrid when BeamSystemParams bound to beam system updated
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ParamsUpdated(object sender, EventArgs e)
{
beamSystemPropertyGrid.SelectedObject = null;
beamSystemPropertyGrid.SelectedObject = m_data.Param;
}
/// <summary>
/// form is loaded
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BeamSystemForm_Load(object sender, EventArgs e)
{
// bound PropertyGrid to show beam system's properties
beamSystemPropertyGrid.SelectedObject = m_data.Param;
m_data.ParamsUpdated += new EventHandler(ParamsUpdated);
// draw the profile
m_sketch.DrawProfile(m_data.Lines);
}
/// <summary>
/// to create beam system
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OKButton_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
Close();
}
/// <summary>
/// cancel all command
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void cancelButton_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
/// <summary>
/// change the direction of beam system to the next line in the profile
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void changeDirectionButton_Click(object sender, EventArgs e)
{
m_data.ChangeProfileDirection();
m_sketch.DrawProfile(m_data.Lines);
}
}
}
@@ -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>
@@ -0,0 +1,470 @@
//
// (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.CreateBeamSystem.CS
{
using System;
using System.Text;
using System.Collections.Generic;
using System.Diagnostics;
using System.ComponentModel;
using Autodesk.Revit;
using Autodesk.Revit.DB;
/// <summary>
/// describes the type of beam layout method in beam system
/// </summary>
public enum LayoutMethod
{
/// <summary>
/// the beam's layout method in beam System is clear the spacing among beams
/// </summary>
ClearSpacing,
/// <summary>
/// maximum the space among beams
/// </summary>
MaximumSpacing,
/// <summary>
/// has fixed beams number and user appoint the number
/// </summary>
FixedNumber,
/// <summary>
/// has fixed distance among beams and user appoint this distance
/// </summary>
FixedDistance
}
/// <summary>
/// declares a delegate for a method that takes in a LayoutMethod
/// </summary>
/// <param name="layoutMethod"></param>
public delegate void LayoutRuleChangedHandler(ref LayoutMethod layoutMethod);
/// <summary>
/// the properties of beam system;
/// can be displayed in PropertyGrid
/// </summary>
public abstract class BeamSystemParam
{
/// <summary>
/// layout method
/// </summary>
protected LayoutMethod m_layoutType;
/// <summary>
/// space between beams; buffer for subclass
/// </summary>
protected double m_fixedSpacing;
/// <summary>
/// justify type; buffer for subclass
/// </summary>
protected BeamSystemJustifyType m_justifyType;
/// <summary>
/// number of beams
/// </summary>
protected int m_numberOfLines;
private LayoutRuleChangedHandler m_layoutRuleChanged;
private FamilySymbol m_beamType; // beam type of beam system
/// <summary>
/// layout method of beam system is changed
/// </summary>
[Browsable(false)]
public LayoutRuleChangedHandler LayoutRuleChanged
{
get
{
return m_layoutRuleChanged;
}
set
{
m_layoutRuleChanged = value;
}
}
/// <summary>
/// kind of layout rule
/// </summary>
[Category("Pattern"),
Description("Specify the layout rule")]
public LayoutMethod LayoutRuleMethod
{
get
{
return m_layoutType;
}
set
{
if (m_layoutType != value)
{
// invokes the delegate
LayoutRuleChanged(ref value);
}
}
}
/// <summary>
/// type of beam used to create beam system
/// </summary>
[Category("Pattern"), TypeConverter(typeof(BeamTypeItem)),
Description("Select a value for the Beam Type used in the beam system")]
public FamilySymbol BeamType
{
get
{
return m_beamType;
}
set
{
m_beamType = value;
}
}
/// <summary>
/// initial general members for its subclass
/// </summary>
protected BeamSystemParam()
{
m_fixedSpacing = 2000.0;
m_justifyType = BeamSystemJustifyType.Center;
m_numberOfLines = 6;
}
/// <summary>
/// create BeamSystemParam's subclass according to LayoutMethod
/// </summary>
/// <param name="layoutType">LayoutMethod</param>
/// <returns>created BeamSystemParam's subclass</returns>
public static BeamSystemParam CreateInstance(LayoutMethod layoutType)
{
BeamSystemParam param = null;
switch (layoutType)
{
case LayoutMethod.ClearSpacing:
param = new ClearSpacingParam();
break;
case LayoutMethod.FixedDistance:
param = new FixedDistanceParam();
break;
case LayoutMethod.FixedNumber:
param = new FixedNumberParam();
break;
case LayoutMethod.MaximumSpacing:
param = new MaximumSpacingParam();
break;
default:
break;
}
// it is absolutely impossible unless layoutType is wrong
Debug.Assert(null != param);
return param;
}
/// <summary>
/// clone BeamSystemParam to one of its subclass according to LayoutMethod
/// </summary>
/// <param name="layoutType">LayoutMethod</param>
/// <returns>cloned BeamSystemParam's subclass</returns>
public BeamSystemParam CloneInstance(LayoutMethod layoutType)
{
// create a BeamSystemParam instance and set its properties
BeamSystemParam param = CreateInstance(layoutType);
param.m_fixedSpacing = m_fixedSpacing;
param.m_justifyType = m_justifyType;
param.m_numberOfLines = m_numberOfLines;
param.m_beamType = m_beamType;
return param;
}
/// <summary>
/// subclass of LayoutRule
/// </summary>
[Browsable(false)]
public abstract LayoutRule Layout
{
get;
}
/// <summary>
/// properties related to LayoutRule when it's clear spacing
/// only visible for class BeamSystemParam
/// </summary>
class ClearSpacingParam : BeamSystemParam
{
protected LayoutRuleClearSpacing m_layout;
/// <summary>
/// wrapped LayoutRuleClearSpacing object
/// </summary>
public override LayoutRule Layout
{
get
{
return m_layout;
}
}
/// <summary>
/// FixedSpacing value of beam system
/// </summary>
[Category("Pattern"),
Description("representing the distance between each beam")]
public double ClearSpacing
{
get
{
return m_fixedSpacing;
}
set
{
try
{
m_layout.Spacing = value;
m_fixedSpacing = value;
}
catch
{
}
}
}
/// <summary>
/// JustifyType value of beam system
/// </summary>
[Category("Pattern"),
Description("This value determines the placement of the first beam"
+ " and each subsequent beam is spaced a fixed distance from it.")]
public BeamSystemJustifyType JustifyType
{
get
{
return m_justifyType;
}
set
{
m_layout.JustifyType = value;
m_justifyType = value;
}
}
/// <summary>
/// constructor
/// </summary>
public ClearSpacingParam()
: base()
{
m_layout = new LayoutRuleClearSpacing(m_fixedSpacing, m_justifyType);
m_layoutType = LayoutMethod.ClearSpacing;
}
}
/// <summary>
/// properties related to LayoutRule when it's fixed distance
/// only visible for class BeamSystemParam
/// </summary>
class FixedDistanceParam : BeamSystemParam
{
protected LayoutRuleFixedDistance m_layout;
/// <summary>
/// wrapped LayoutRuleFixedDistance object
/// </summary>
public override LayoutRule Layout
{
get
{
return m_layout;
}
}
/// <summary>
/// constructor
/// </summary>
public FixedDistanceParam()
: base()
{
m_layout = new LayoutRuleFixedDistance(m_fixedSpacing, m_justifyType);
m_layoutType = LayoutMethod.FixedDistance;
}
/// <summary>
/// FixedSpacing value of beam system
/// </summary>
[Category("Pattern"),
Description("allows you to specify the distance between beams"
+ " based on the justification you specify.")]
public double FixedSpacing
{
get
{
return m_fixedSpacing;
}
set
{
try
{
m_layout.Spacing = value;
m_fixedSpacing = value;
}
catch
{
}
}
}
/// <summary>
/// JustifyType value of beam system
/// </summary>
[Category("Pattern"),
Description("determines the placement of the first beam in the system"
+ " and each subsequent beam is spaced a fixed distance from that point.")]
public BeamSystemJustifyType JustifyType
{
get
{
return m_justifyType;
}
set
{
m_layout.JustifyType = value;
m_justifyType = value;
}
}
}
/// <summary>
/// properties related to LayoutRule when it's fixed number
/// only visible for class BeamSystemParam
/// </summary>
class FixedNumberParam : BeamSystemParam
{
protected LayoutRuleFixedNumber m_layout;
/// <summary>
/// NumberOfLines value of beam system
/// </summary>
[Category("Pattern"),
Description("allows you to specify the number of beams within the beam system.")]
public int NumberOfLines
{
get
{
return m_numberOfLines;
}
set
{
try
{
m_layout.NumberOfLines = value;
m_numberOfLines = value;
}
catch
{
}
}
}
/// <summary>
/// wrapped LayoutRuleFixedNumber object
/// </summary>
public override LayoutRule Layout
{
get
{
return m_layout;
}
}
/// <summary>
/// constructor
/// </summary>
public FixedNumberParam()
: base()
{
m_layout = new LayoutRuleFixedNumber(m_numberOfLines);
m_layoutType = LayoutMethod.FixedNumber;
}
}
/// <summary>
/// properties related to LayoutRule when it's maximum spacing
/// only visible for class BeamSystemParam
/// </summary>
class MaximumSpacingParam : BeamSystemParam
{
protected LayoutRuleMaximumSpacing m_layout;
/// <summary>
/// FixedSpacing value of beam system
/// </summary>
[Category("Pattern"),
Description("allows you to specify the maximum distance between beams.")]
public double MaximumSpacing
{
get
{
return m_fixedSpacing;
}
set
{
try
{
m_layout.Spacing = value;
m_fixedSpacing = value;
}
catch
{
}
}
}
/// <summary>
/// wrapped LayoutRuleMaximumSpacing object
/// </summary>
public override LayoutRule Layout
{
get
{
return m_layout;
}
}
/// <summary>
/// constructor
/// </summary>
public MaximumSpacingParam()
: base()
{
m_layout = new LayoutRuleMaximumSpacing(m_fixedSpacing);
m_layoutType = LayoutMethod.MaximumSpacing;
}
}
}
}
@@ -0,0 +1,189 @@
//
// (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.CreateBeamSystem.CS
{
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using Autodesk.Revit.DB;
/// <summary>
/// Sketch the profile of beam system on canvas
/// Code here have nothing with Revit API
/// </summary>
public class BeamSystemSketch : ObjectSketch
{
/// <summary>
/// ratio of margin to canvas width
/// </summary>
private const float MarginRatio = 0.1f;
/// <summary>
/// the control to draw beam system
/// </summary>
private System.Windows.Forms.Control m_canvas;
/// <summary>
/// defines a local geometric inverse transform
/// </summary>
private Matrix m_inverse;
/// <summary>
/// constructor
/// </summary>
/// <param name="canvas">the control to draw beam system</param>
public BeamSystemSketch(System.Windows.Forms.Control canvas)
{
m_canvas = canvas;
}
/// <summary>
/// draw the profile in the canvas
/// </summary>
/// <param name="profile">the profile of the beam system</param>
public void DrawProfile(IList<Line> profile)
{
Initialize(profile);
CalculateTransform();
m_canvas.Paint += new PaintEventHandler(this.Paint);
m_canvas.Refresh();
}
/// <summary>
/// draw beam system
/// </summary>
/// <param name="g">encapsulates a GDI+ drawing surface</param>
/// <param name="translate">translation matrix to canvas coordinates</param>
public override void Draw(Graphics g, Matrix translate)
{
foreach (LineSketch sketch in m_objects)
{
sketch.Draw(g, m_transform);
}
}
/// <summary>
/// draw beam system on canvas control
/// </summary>
/// <param name="sender">canvas control</param>
/// <param name="e">data for the Paint event</param>
protected void Paint(Object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.Clear(System.Drawing.Color.White);
Draw(g, m_transform);
}
/// <summary>
/// generate a Line2D instance using a Line's data
/// </summary>
/// <param name="line">where new Line2D get data</param>
/// <returns>new Line2D</returns>
private static Line2D GetLine2D(Line line)
{
Line2D result = new Line2D();
result.StartPnt = new PointF((float)line.GetEndPoint(0).X, (float)line.GetEndPoint(0).Y);
result.EndPnt = new PointF((float)line.GetEndPoint(1).X, (float)line.GetEndPoint(1).Y);
return result;
}
/// <summary>
/// calculate the transform between canvas and geometry objects
/// </summary>
private void CalculateTransform()
{
PointF[] plgpts = CalculateCanvasRegion();
m_transform = new Matrix(BoundingBox, plgpts);
m_inverse = m_transform.Clone();
if (m_inverse.IsInvertible)
{
m_inverse.Invert();
}
}
/// <summary>
/// initialize geometry objects and bounding box
/// </summary>
/// <param name="profile">the profile of the beam system</param>
private void Initialize(IList<Line> profile)
{
// deal with first line in profile
m_objects.Clear();
LineSketch firstSketch = new LineSketch(GetLine2D(profile[0]));
m_boundingBox = firstSketch.BoundingBox;
firstSketch.IsDirection = true;
m_objects.Add(firstSketch);
// all other lines
for (int i = 1; i < profile.Count; i++)
{
LineSketch sketch = new LineSketch(GetLine2D(profile[i]));
m_boundingBox = RectangleF.Union(BoundingBox, sketch.BoundingBox);
m_objects.Add(sketch);
}
}
/// <summary>
/// get the display region, adjust the proportion and location
/// </summary>
/// <returns>upper-left, upper-right, and lower-left corners of the rectangle </returns>
private PointF[] CalculateCanvasRegion()
{
// get the area without margin
float realWidth = m_canvas.Width * (1 - 2 * MarginRatio);
float realHeight = m_canvas.Height * (1 - 2 * MarginRatio);
float minX = m_canvas.Width * MarginRatio;
float minY = m_canvas.Height * MarginRatio;
// ratio of width to height
float originRate = m_boundingBox.Width / m_boundingBox.Height;
float displayRate = realWidth / realHeight;
if (originRate > displayRate)
{
// display area in canvas need move to center in height
float goalHeight = realWidth / originRate;
minY = minY + (realHeight - goalHeight) / 2;
realHeight = goalHeight;
}
else
{
// display area in canvas need move to center in width
float goalWidth = realHeight * originRate;
minX = minX + (realWidth - goalWidth) / 2;
realWidth = goalWidth;
}
PointF[] plgpts = new PointF[3];
plgpts[0] = new PointF(minX, realHeight + minY); // upper-left point
plgpts[1] = new PointF(realWidth + minX, realHeight + minY); // upper-right point
plgpts[2] = new PointF(minX, minY); // lower-left point
return plgpts;
}
}
}
@@ -0,0 +1,168 @@
//
// (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.CreateBeamSystem.CS
{
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.ComponentModel;
using System.Globalization;
using Autodesk.Revit;
using Autodesk.Revit.DB;
/// <summary>
/// base class of converting types of FamilySymbol to string
/// Code here have nothing with Revit API
/// it's only for PropertyGrid and its SelectedObject
/// </summary>
public abstract class ParameterConverter : TypeConverter
{
/// <summary>
/// hashtable of FamilySymbol and its Name
/// </summary>
protected Dictionary<string, FamilySymbol> m_hash;
/// <summary>
/// subclass must implement to initialize m_hash
/// </summary>
public abstract void GetConvertHash();
/// <summary>
/// returns whether this object supports a standard set of values that can be picked from a list
/// </summary>
/// <param name="context">provides a format context</param>
/// <returns>true if GetStandardValues should be called to find a common set of values the object supports;
/// otherwise, false</returns>
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
return true;
}
/// <summary>
/// returns a collection of FamilySymbol
/// </summary>
/// <param name="context">provides a format context</param>
/// <returns>collection of FamilySymbol</returns>
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
{
return new StandardValuesCollection(m_hash.Values);
}
/// <summary>
/// whether this converter can convert an object of the given type to string
/// </summary>
/// <param name="context">provides a format context</param>
/// <param name="sourceType">a Type that represents the type you want to convert from</param>
/// <returns></returns>
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
/// <summary>
/// converts the Name to corresponding FamilySymbol
/// </summary>
/// <param name="context">provides a format context</param>
/// <param name="culture">the CultureInfo to use as the current culture</param>
/// <param name="value">the Object to convert</param>
/// <returns>an FamilySymbol object</returns>
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
return m_hash[value.ToString()];
}
/// <summary>
/// converts the given FamilySymbol to the Name, using the specified context and culture information
/// </summary>
/// <param name="context">provides a format context</param>
/// <param name="culture">the CultureInfo to use as the current culture</param>
/// <param name="v">the Object to convert</param>
/// <param name="destinationType">should be string</param>
/// <returns></returns>
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object v, Type destinationType)
{
if (destinationType == typeof(string))
{
FamilySymbol symbol = v as FamilySymbol;
if (null == symbol)
{
return "";
}
foreach (KeyValuePair<string, FamilySymbol> kvp in m_hash)
{
if (kvp.Value.Id.IntegerValue == symbol.Id.IntegerValue)
{
return kvp.Key;
}
}
return "";
}
return base.ConvertTo(context, culture, v, destinationType);
}
/// <summary>
/// whether the collection of standard values returned
/// from GetStandardValues is an exclusive list of possible values
/// </summary>
/// <param name="context">provides a format context</param>
/// <returns></returns>
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
{
return false;
}
/// <summary>
/// constructor initialize m_hash
/// </summary>
protected ParameterConverter()
{
GetConvertHash();
}
}
/// <summary>
/// converting types of FamilySymbol to string
/// Code here have nothing with Revit API
/// it's only for PropertyGrid and its SelectedObject
/// </summary>
public class BeamTypeItem : ParameterConverter
{
/// <summary>
/// override the base type's GetConvertHash method
/// </summary>
public override void GetConvertHash()
{
m_hash = BeamSystemData.GetBeamTypes();
}
}
}
+106
View File
@@ -0,0 +1,106 @@
//
// (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.CreateBeamSystem.CS
{
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using Autodesk.Revit;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
/// <summary>
/// external applications' only entry point class that supports the IExternalCommand interface
/// </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
{
/// <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 tran = new Transaction(commandData.Application.ActiveUIDocument.Document, "CreateBeamSystem");
tran.Start();
try
{
GeometryUtil.CreApp = commandData.Application.Application.Create;
// initialize precondition data of the program
BeamSystemData data = new BeamSystemData(commandData);
// display form to collect user's setting for beam system
using (BeamSystemForm form = new BeamSystemForm(data))
{
if (form.ShowDialog() != DialogResult.OK)
{
tran.RollBack();
return Autodesk.Revit.UI.Result.Cancelled;
}
}
// create beam system using the parameters saved in BeamSystemData
BeamSystemBuilder builder = new BeamSystemBuilder(data);
builder.CreateBeamSystem();
}
catch (ErrorMessageException errorEx)
{
// checked exception need to show in error messagebox
message = errorEx.Message;
tran.RollBack();
return Autodesk.Revit.UI.Result.Failed;
}
catch(Exception ex)
{
// unchecked exception cause command failed
message = "Command is failed for unexpected reason.";
Trace.WriteLine(ex.ToString());
tran.RollBack();
return Autodesk.Revit.UI.Result.Failed;
}
tran.Commit();
return Autodesk.Revit.UI.Result.Succeeded;
}
}
}
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<RevitAddIns>
<AddIn Type="Command">
<Assembly>CreateBeamSystem.dll</Assembly>
<ClientId>058c25ff-22bc-4203-8e12-3a09639c21c4</ClientId>
<FullClassName>Revit.SDK.Samples.CreateBeamSystem.CS.Command</FullClassName>
<Text>Create Beam System</Text>
<Description>Create beam system according to the profile made of selected beams.</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<VendorId>ADSK</VendorId>
<VendorDescription>Autodesk, www.autodesk.com</VendorDescription>
</AddIn>
</RevitAddIns>
@@ -0,0 +1,119 @@
<?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>{205E158D-9960-489D-A391-4804D9D3F8DC}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Revit.SDK.Samples.CreateBeamSystem.CS</RootNamespace>
<AssemblyName>CreateBeamSystem</AssemblyName>
<StartupObject>
</StartupObject>
<SccProjectName>
</SccProjectName>
<SccLocalPath>
</SccLocalPath>
<SccAuxPath>
</SccAuxPath>
<SccProvider>
</SccProvider>
<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>
<RunCodeAnalysis>false</RunCodeAnalysis>
<CodeAnalysisRules>-Microsoft.Globalization#CA1301;-Microsoft.Globalization#CA1302;-Microsoft.Globalization#CA1303;-Microsoft.Globalization#CA1306;-Microsoft.Globalization#CA1304;-Microsoft.Globalization#CA1305;-Microsoft.Globalization#CA1300;-Microsoft.Interoperability#CA1403;-Microsoft.Interoperability#CA1406;-Microsoft.Interoperability#CA1413;-Microsoft.Interoperability#CA1402;-Microsoft.Interoperability#CA1407;-Microsoft.Interoperability#CA1404;-Microsoft.Interoperability#CA1410;-Microsoft.Interoperability#CA1411;-Microsoft.Interoperability#CA1405;-Microsoft.Interoperability#CA1409;-Microsoft.Interoperability#CA1415;-Microsoft.Interoperability#CA1408;-Microsoft.Interoperability#CA1414;-Microsoft.Interoperability#CA1412;-Microsoft.Interoperability#CA1400;-Microsoft.Interoperability#CA1401;-Microsoft.Mobility#CA1600;-Microsoft.Mobility#CA1601;-Microsoft.Portability#CA1901;-Microsoft.Portability#CA1900</CodeAnalysisRules>
</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>
<CodeAnalysisRules>-Microsoft.Globalization#CA1301;-Microsoft.Globalization#CA1302;-Microsoft.Globalization#CA1303;-Microsoft.Globalization#CA1306;-Microsoft.Globalization#CA1304;-Microsoft.Globalization#CA1305;-Microsoft.Globalization#CA1300;-Microsoft.Interoperability#CA1403;-Microsoft.Interoperability#CA1406;-Microsoft.Interoperability#CA1413;-Microsoft.Interoperability#CA1402;-Microsoft.Interoperability#CA1407;-Microsoft.Interoperability#CA1404;-Microsoft.Interoperability#CA1410;-Microsoft.Interoperability#CA1411;-Microsoft.Interoperability#CA1405;-Microsoft.Interoperability#CA1409;-Microsoft.Interoperability#CA1415;-Microsoft.Interoperability#CA1408;-Microsoft.Interoperability#CA1414;-Microsoft.Interoperability#CA1412;-Microsoft.Interoperability#CA1400;-Microsoft.Interoperability#CA1401;-Microsoft.Mobility#CA1600;-Microsoft.Mobility#CA1601;-Microsoft.Portability#CA1901;-Microsoft.Portability#CA1900</CodeAnalysisRules>
<ErrorReport>prompt</ErrorReport>
</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="BeamSystemBuilder.cs" />
<Compile Include="BeamSystemData.cs" />
<Compile Include="BeamSystemForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="BeamSystemForm.Designer.cs">
<DependentUpon>BeamSystemForm.cs</DependentUpon>
</Compile>
<Compile Include="BeamSystemParams.cs" />
<Compile Include="BeamSystemSketch.cs" />
<Compile Include="BeamTypeConverter.cs" />
<Compile Include="Command.cs" />
<Compile Include="ErrorMessageException.cs" />
<Compile Include="Line2D.cs" />
<Compile Include="GeometryUtil.cs" />
<Compile Include="LineSketch.cs" />
<Compile Include="ObjectSketch.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="BeamSystemForm.resx">
<SubType>Designer</SubType>
<DependentUpon>BeamSystemForm.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,52 @@
//
// (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.CreateBeamSystem.CS
{
using System;
using System.Collections.Generic;
using System.Text;
/// <summary>
/// pass error message to UI or back to internal error messagebox by Execute method in IExternalCommand
/// </summary>
public class ErrorMessageException : ApplicationException
{
/// <summary>
/// constructor entirely using baseclass'
/// </summary>
public ErrorMessageException()
: base()
{
}
/// <summary>
/// constructor entirely using baseclass'
/// </summary>
/// <param name="message">error message</param>
public ErrorMessageException(String message)
: base(message)
{
}
}
}
@@ -0,0 +1,351 @@
//
// (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.CreateBeamSystem.CS
{
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using Autodesk.Revit.DB;
/// <summary>
/// utility class contains some methods deal with 3D arithmetic
/// </summary>
public class GeometryUtil
{
/// <summary>
/// The Application Creation object is used to create new instances of utility objects.
/// </summary>
public static Autodesk.Revit.Creation.Application CreApp;
/// <summary>
/// judge whether two XYZs are equal
/// </summary>
/// <param name="pnt1">first XYZ</param>
/// <param name="pnt2">second XYZ</param>
/// <returns>is equal</returns>
public static bool CompareXYZ(Autodesk.Revit.DB.XYZ pnt1, Autodesk.Revit.DB.XYZ pnt2)
{
return (MathUtil.CompareDouble(pnt1.X, pnt2.X) &&
MathUtil.CompareDouble(pnt1.Y, pnt2.Y) &&
MathUtil.CompareDouble(pnt1.Z, pnt2.Z));
}
/// <summary>
/// sorted lines end to end to make a closed loop profile
/// if input lines can't make a profile, null will return
/// </summary>
/// <param name="originLines">lines to be sorted</param>
/// <returns>sorted lines which can make a closed loop profile</returns>
public static List<Line> SortLines(List<Line> originLines)
{
// at least 3 lines to form the profile
if (originLines.Count < 3)
{
return null;
}
List<Line> lines = new List<Line>(originLines);
List<Line> result = new List<Line>();
// sorted line end to end in order
result.Add(lines[0]);
Autodesk.Revit.DB.XYZ intersectPnt = lines[0].GetEndPoint(1);
lines[0] = null;
for (int i = 0; i < lines.Count; i++)
{
for (int j = 1; j < lines.Count; j++)
{
if (null == lines[j])
{
continue;
}
if (CompareXYZ(lines[j].GetEndPoint(0), intersectPnt))
{
result.Add(lines[j]);
intersectPnt = lines[j].GetEndPoint(1);
lines[j] = null;
break;
}
else if (CompareXYZ(lines[j].GetEndPoint(1), intersectPnt))
{
Autodesk.Revit.DB.XYZ startPnt = lines[j].GetEndPoint(1);
Autodesk.Revit.DB.XYZ endPnt = lines[j].GetEndPoint(0);
lines[j] = null;
Line inversedLine = Line.CreateBound(startPnt, endPnt);
result.Add(inversedLine);
intersectPnt = inversedLine.GetEndPoint(1);
break;
}
}
}
// there is line doesn't included in the closed loop
if (result.Count != lines.Count)
{
return null;
}
// the last point in the sorted loop is same to the firs point
if (!CompareXYZ(intersectPnt, result[0].GetEndPoint(0)))
{
return null;
}
// make sure there is only one closed region enclosed by the closed loop
for (int i = 0; i < result.Count - 2; i++)
{
for (int j = i + 2; j < result.Count; j++)
{
if (i == 0 && j == (result.Count - 1))
{
continue;
}
Line2D line1 = ConvertTo2DLine(result[i]);
Line2D line2 = ConvertTo2DLine(result[j]);
int count = Line2D.FindIntersection(line1, line2);
// line shouldn't intersect with lines which not adjoin to it
if (count > 0)
{
return null;
}
}
}
return result;
}
/// <summary>
/// judge whether the lines are in the same horizontal plane
/// </summary>
/// <param name="lines">lines to be judged</param>
/// <returns>is in the same horizontal plane</returns>
public static bool InSameHorizontalPlane(List<Line> lines)
{
// all the Z coordinate of lines' start point and end point should be equal
Autodesk.Revit.DB.XYZ firstPnt = lines[0].GetEndPoint(0);
for (int i = 0; i < lines.Count; i++)
{
if (!MathUtil.CompareDouble(lines[i].GetEndPoint(0).Z, firstPnt.Z) ||
!MathUtil.CompareDouble(lines[i].GetEndPoint(1).Z, firstPnt.Z))
{
return false;
}
}
return true;
}
/// <summary>
/// use the X and Y coordinate of 3D Line to new a Line2D instance
/// </summary>
/// <param name="line">3D Line</param>
/// <returns>2D Line</returns>
private static Line2D ConvertTo2DLine(Line line)
{
PointF pnt1 = new PointF((float)line.GetEndPoint(0).X, (float)line.GetEndPoint(0).Y);
PointF pnt2 = new PointF((float)line.GetEndPoint(1).X, (float)line.GetEndPoint(1).Y);
return new Line2D(pnt1, pnt2);
}
}
/// <summary>
/// utility class contains some methods deal with some general arithmetic
/// </summary>
public class MathUtil
{
/// <summary>
/// the minimum double used to compare
/// </summary>
public const double Double_Epsilon = 0.00001;
/// <summary>
/// the minimum positive float used to compare to as zero
/// </summary>
public const float Float_Epsilon = 0.00001f;
/// <summary>
/// forbidden default constructor
/// </summary>
private MathUtil()
{
}
/// <summary>
/// compare whether 2 double is equal using internal precision
/// </summary>
/// <param name="d1">first value</param>
/// <param name="d2">second value</param>
/// <returns>is Equal</returns>
public static bool CompareDouble(double d1, double d2)
{
return Math.Abs(d1 - d2) < Double_Epsilon;
}
/// <summary>
/// dot multiply two vector
/// </summary>
/// <param name="pnt1">first vector</param>
/// <param name="pnt2">second vector</param>
/// <returns>result</returns>
public static float Dot(PointF pnt1, PointF pnt2)
{
return pnt1.X * pnt2.X + pnt1.Y * pnt2.Y;
}
/// <summary>
/// multiply a float with a vector
/// </summary>
/// <param name="f">float value</param>
/// <param name="pnt">vector</param>
/// <returns>result</returns>
public static PointF Multiply(float f, PointF pnt)
{
return new PointF(f * pnt.X, f * pnt.Y);
}
/// <summary>
/// add 2 vector
/// </summary>
/// <param name="f1">first vector</param>
/// <param name="f2">second vector</param>
/// <returns>result</returns>
public static PointF Add(PointF f1, PointF f2)
{
return new PointF(f1.X + f2.X, f1.Y + f2.Y);
}
/// <summary>
/// subtract 2 vector
/// </summary>
/// <param name="f1">first vector</param>
/// <param name="f2">second vector</param>
/// <returns>result</returns>
public static PointF Subtract(PointF f1, PointF f2)
{
return new PointF(f1.X - f2.X, f1.Y - f2.Y);
}
/// <summary>
/// find and calculate the intersection of two interval [u0, u1] and [v0, v1]
/// </summary>
/// <param name="u0">first interval</param>
/// <param name="u1">first interval</param>
/// <param name="v0">second interval</param>
/// <param name="v1">second interval</param>
/// <param name="w">2 intersections</param>
/// <returns>number of intersection</returns>
public static int FindIntersection(float u0, float u1, float v0, float v1, ref float[] w)
{
if (u1 < v0 || u0 > v1)
{
return 0;
}
if (u1 == v0)
{
w[0] = u1;
return 1;
}
if (u0 == v1)
{
w[0] = u0;
return 1;
}
if (u1 > v0)
{
if (u0 < v1)
{
if (u0 < v0)
{
w[0] = v0;
}
else
{
w[0] = u0;
}
if (u1 > v1)
{
w[1] = v1;
}
else
{
w[1] = u1;
}
return 2;
}
else
{
w[0] = u0;
return 1;
}
}
else
{
w[0] = u1;
return 1;
}
}
/// <summary>
/// get the minimum value of 2 float
/// </summary>
/// <param name="f1">first float</param>
/// <param name="f2">second float</param>
/// <returns>minimum float</returns>
public static float GetMin(float f1, float f2)
{
if (f1 < f2)
{
return f1;
}
return f2;
}
/// <summary>
/// get the maximum value of 2 float
/// </summary>
/// <param name="f1">first float</param>
/// <param name="f2">second float</param>
/// <returns>maximum float</returns>
public static float GetMax(float f1, float f2)
{
if (f1 > f2)
{
return f1;
}
return f2;
}
}
}
+366
View File
@@ -0,0 +1,366 @@
//
// (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.CreateBeamSystem.CS
{
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using Autodesk.Revit.DB;
/// <summary>
/// represent a geometry segment line
/// </summary>
public class Line2D
{
private PointF m_startPnt = new PointF(); // start point
private PointF m_endPnt = new PointF(); // end point
private float m_length; // length of the line
private PointF m_normal = new PointF(); // normal of the line; start point to end point
private RectangleF m_boundingBox = new RectangleF();// rectangle box contains the line
/// <summary>
/// rectangle box contains the line
/// </summary>
public RectangleF BoundingBox
{
get
{
return m_boundingBox;
}
}
/// <summary>
/// start point of the line; if it is set to new value,
/// EndPoint is changeless; Length, Normal and BoundingBox will updated
/// </summary>
public PointF StartPnt
{
get
{
return m_startPnt;
}
set
{
if (m_startPnt == value)
{
return;
}
m_startPnt = value;
CalculateDirection();
CalculateBoundingBox();
}
}
/// <summary>
/// end point of the line; if it is set to new value,
/// StartPoint is changeless; Length, Normal and BoundingBox will updated
/// </summary>
public PointF EndPnt
{
get
{
return m_endPnt;
}
set
{
if (m_endPnt == value)
{
return;
}
m_endPnt = value;
CalculateDirection();
CalculateBoundingBox();
}
}
/// <summary>
/// Length of the line; if it is set to new value,
/// StartPoint and Normal is changeless; EndPoint and BoundingBox will updated
/// </summary>
public float Length
{
get
{
return m_length;
}
set
{
if (m_length == value)
{
return;
}
m_length = value;
CalculateEndPoint();
CalculateBoundingBox();
}
}
/// <summary>
/// Normal of the line; if it is set to new value,
/// StartPoint is changeless; EndPoint and BoundingBox will updated
/// </summary>
public PointF Normal
{
get
{
return m_normal;
}
set
{
if (m_normal == value)
{
return;
}
m_normal = value;
CalculateEndPoint();
CalculateBoundingBox();
}
}
/// <summary>
/// constructor
/// default StartPoint = (0.0, 0.0), EndPoint = (1.0, 0.0)
/// </summary>
public Line2D()
{
m_startPnt.X = 0.0f;
m_startPnt.Y = 0.0f;
m_endPnt.X = 1.0f;
m_endPnt.Y = 0.0f;
CalculateDirection();
CalculateBoundingBox();
}
/// <summary>
/// constructor
/// </summary>
/// <param name="startPnt">StartPoint</param>
/// <param name="endPnt">EndPoint</param>
public Line2D(PointF startPnt, PointF endPnt)
{
m_startPnt = startPnt;
m_endPnt = endPnt;
CalculateDirection();
CalculateBoundingBox();
}
/// <summary>
/// get an interval point on the line of the segment
/// </summary>
/// <param name="rate">rate of length from interval to StartPoint
/// to length from EndPoint to interval</param>
/// <returns>interval point</returns>
public PointF GetIntervalPoint(float rate)
{
PointF result = new PointF();
result.X = m_startPnt.X + (m_endPnt.X - m_startPnt.X) * rate;
result.Y = m_startPnt.Y + (m_endPnt.Y - m_startPnt.Y) * rate;
return result;
}
/// <summary>
/// scale the segment according to the center of the segment
/// </summary>
/// <param name="rate">rate to scale</param>
public void Scale(float rate)
{
PointF startPnt = GetIntervalPoint((1.0f - rate) / 2.0f);
PointF endPnt = GetIntervalPoint((1.0f + rate) / 2.0f);
m_startPnt = startPnt;
m_endPnt = endPnt;
CalculateLength();
}
/// <summary>
/// parallelly shift the line
/// </summary>
/// <param name="distance">distance</param>
public void Shift(float distance)
{
SizeF moveSize = new SizeF(-distance * m_normal.Y, distance * m_normal.X);
m_startPnt = m_startPnt + moveSize;
m_endPnt = m_endPnt + moveSize;
}
/// <summary>
/// creates an instance of the GeometryLine class that is identical to the current GeometryLine
/// </summary>
/// <returns>created GeometryLine</returns>
public Line2D Clone()
{
Line2D cloned = new Line2D(m_startPnt, m_endPnt);
return cloned;
}
/// <summary>
/// find the number of intersection points for two segments
/// </summary>
/// <param name="line0">first line</param>
/// <param name="line1">second line</param>
/// <returns>number of intersection points; 0, 1, or 2</returns>
public static int FindIntersection(Line2D line0, Line2D line1)
{
PointF[] intersectPnt = new PointF[2];
return FindIntersection(line0, line1, ref intersectPnt);
}
/// <summary>
/// find the intersection points of two segments
/// </summary>
/// <param name="line0">first line</param>
/// <param name="line1">second line</param>
/// <param name="intersectPnt">0, 1 or 2 intersection points</param>
/// <returns>number of intersection points; 0, 1, or 2</returns>
public static int FindIntersection(Line2D line0, Line2D line1, ref PointF[] intersectPnt)
{
// segments p0 + s * d0 for s in [0, 0], p1 + t * d1 for t in [0, 1]
PointF p0 = line0.StartPnt;
PointF d0 = MathUtil.Multiply(line0.Length, line0.Normal);
PointF p1 = line1.StartPnt;
PointF d1 = MathUtil.Multiply(line1.Length, line1.Normal);
PointF E = MathUtil.Subtract(p1, p0);
float kross = d0.X * d1.Y - d0.Y * d1.X;
float sqrKross = kross * kross;
float sqrLen0 = d0.X * d0.X + d0.Y * d0.Y;
float sqrLen1 = d1.X * d1.X + d1.Y * d1.Y;
// lines of the segments are not parallel
if (sqrKross > MathUtil.Float_Epsilon * sqrLen0 * sqrLen1)
{
float s = (E.X * d1.Y - E.Y * d1.X) / kross;
if (s < 0 || s > 1)
{
// intersection of lines is not point on segment p0 + s * d0
return 0;
}
float t = (E.X * d0.Y - E.Y * d0.X) / kross;
if (t < 0 || t > 1)
{
// intersection of lines is not a point on segment p1 + t * d1
return 0;
}
// intersection of lines is a point on each segment
intersectPnt[0] = MathUtil.Add(p0, MathUtil.Multiply(s, d0));
return 1;
}
// lines of the segments are paralled
float sqrLenE = E.X * E.X + E.Y * E.Y;
float kross2 = E.X * d0.Y - E.Y * d0.X;
float sqrKross2 = kross2 * kross2;
if (sqrKross2 > MathUtil.Float_Epsilon * sqrLen0 * sqrLenE)
{
// lines of the segments are different
return 0;
}
// lines of the segments are the same. need to test for overlap of segments
float s0 = MathUtil.Dot(d0, E) / sqrLen0;
float s1 = s0 + MathUtil.Dot(d0, d1) / sqrLen0;
float smin = MathUtil.GetMin(s0, s1);
float smax = MathUtil.GetMax(s0, s1);
float[] w = new float[2];
int imax = MathUtil.FindIntersection(0.0f, 1.0f, smin, smax, ref w);
for (int i = 0; i < imax; i++)
{
intersectPnt[i] = MathUtil.Add(p0, MathUtil.Multiply(w[i], d0));
}
return imax;
}
/// <summary>
/// calculate BoundingBox according to StartPoint and EndPoint
/// </summary>
private void CalculateBoundingBox()
{
float x1 = m_endPnt.X;
float x2 = m_startPnt.X;
float y1 = m_endPnt.Y;
float y2 = m_startPnt.Y;
float width = Math.Abs(x1 - x2);
float height = Math.Abs(y1 - y2);
if (x1 > x2)
{
x1 = x2;
}
if (y1 > y2)
{
y1 = y2;
}
m_boundingBox = new RectangleF(x1, y1, width, height);
}
/// <summary>
/// calculate length by StartPoint and EndPoint
/// </summary>
private void CalculateLength()
{
m_length =
(float)Math.Sqrt(Math.Pow((m_startPnt.X - m_endPnt.X), 2) + Math.Pow((m_startPnt.Y - m_endPnt.Y), 2));
}
/// <summary>
/// calculate Direction by StartPoint and EndPoint
/// </summary>
private void CalculateDirection()
{
CalculateLength();
m_normal.X = (m_endPnt.X - m_startPnt.X) / m_length;
m_normal.Y = (m_endPnt.Y - m_startPnt.Y) / m_length;
}
/// <summary>
/// calculate EndPoint by StartPoint, Length and Direction
/// </summary>
private void CalculateEndPoint()
{
m_endPnt.X = m_startPnt.X + m_length * m_normal.X;
m_endPnt.Y = m_startPnt.Y + m_length * m_normal.Y;
}
/// <summary>
/// calculate StartPoint by EndPoint, Length and Direction
/// </summary>
private void CalculateStartPoint()
{
m_startPnt.X = m_endPnt.X - m_length * m_normal.X;
m_startPnt.Y = m_endPnt.Y - m_length * m_normal.Y;
}
}
}
@@ -0,0 +1,116 @@
//
// (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.CreateBeamSystem.CS
{
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using Autodesk.Revit.DB;
/// <summary>
/// sketch line and any tag on it
/// </summary>
public class LineSketch : ObjectSketch
{
/// <summary>
/// the rate of direction tag's distance to the line
/// </summary>
private const float DirectionTag_Distance_Ratio = 0.02f;
/// <summary>
/// the rate of direction tag's length to the line
/// </summary>
private const float DirectionTag_Length_Ratio = 0.1f;
private Line2D m_line = new Line2D(); // geometry line to draw
private bool m_isDirection; // whether has direction tag
/// <summary>
/// whether has direction tag
/// </summary>
public bool IsDirection
{
get
{
return m_isDirection;
}
set
{
m_isDirection = value;
}
}
/// <summary>
/// constructor
/// </summary>
/// <param name="line"></param>
public LineSketch(Line2D line)
{
m_line = line;
m_boundingBox = line.BoundingBox;
m_pen.Color = System.Drawing.Color.DarkGreen;
m_pen.Width = 1f;
}
/// <summary>
/// draw the line
/// </summary>
/// <param name="g">drawing object</param>
/// <param name="translate">translation between drawn sketch and geometry object</param>
public override void Draw(Graphics g, Matrix translate)
{
GraphicsPath path = new GraphicsPath();
path.AddLine(m_line.StartPnt, m_line.EndPnt);
if (m_isDirection)
{
DrawDirectionTag(path);
}
path.Transform(translate);
g.DrawPath(m_pen, path);
}
/// <summary>
/// draw 2 shorter parallel lines on each side of the line
/// </summary>
/// <param name="path"></param>
private void DrawDirectionTag(GraphicsPath path)
{
Line2D leftLine = m_line.Clone();
Line2D rightLine = m_line.Clone();
leftLine.Scale(DirectionTag_Length_Ratio);
leftLine.Shift(DirectionTag_Distance_Ratio * m_line.Length);
rightLine.Scale(DirectionTag_Length_Ratio);
rightLine.Shift(-DirectionTag_Distance_Ratio * m_line.Length);
GraphicsPath leftPath = new GraphicsPath();
leftPath.AddLine(leftLine.StartPnt, leftLine.EndPnt);
GraphicsPath rightPath = new GraphicsPath();
rightPath.AddLine(rightLine.StartPnt, rightLine.EndPnt);
path.AddPath(leftPath, false);
path.AddPath(rightPath, false);
}
}
}
@@ -0,0 +1,75 @@
//
// (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.CreateBeamSystem.CS
{
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
/// <summary>
/// base class of sketch object to draw 2D geometry object
/// </summary>
public abstract class ObjectSketch
{
/// <summary>
/// bounding box of the geometry object
/// </summary>
protected RectangleF m_boundingBox = new RectangleF();
/// <summary>
/// bounding box of the geometry object
/// </summary>
public RectangleF BoundingBox
{
get
{
return m_boundingBox;
}
}
/// <summary>
/// pen to draw the object
/// </summary>
protected Pen m_pen = new Pen(System.Drawing.Color.DarkGreen);
/// <summary>
/// defines a local geometric transform
/// </summary>
protected Matrix m_transform;
/// <summary>
/// reserve lines that form the profile
/// </summary>
protected List<ObjectSketch> m_objects = new List<ObjectSketch>();
/// <summary>
/// geometric object draw itself
/// </summary>
/// <param name="g"></param>
/// <param name="translate"></param>
public abstract void Draw(Graphics g, Matrix translate);
}
}
@@ -0,0 +1,58 @@
//
// (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("CreateBeamSystem")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CreateBeamSystem")]
[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("e3c8fcc0-9ee9-4f5a-909f-3dea372446a5")]
// 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")]