integrate Revit 2025 SDK

This commit is contained in:
Jeremy Tammik
2024-04-11 13:47:20 +02:00
parent e786953544
commit f414362f2b
889 changed files with 26676 additions and 26865 deletions
@@ -0,0 +1,5 @@
{
"recommendations": [
"ms-dotnettools.csharp",
]
}
@@ -0,0 +1,15 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Attach to Revit",
"type": "coreclr",
"request": "attach",
"processName": "revit.exe",
"justMyCode": true
}
]
}
@@ -0,0 +1,14 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build"
],
"problemMatcher": "$msCompile"
},
]
}
@@ -0,0 +1,494 @@
//
// (C) Copyright 2003-2008 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.IO;
using System.Text.RegularExpressions;
using System.Reflection;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using MacroSamples_RFA;
namespace Revit.SDK.Samples.AutoParameter.CS
{
/// <summary>
/// add parameters(family parameters/shared parameters) to the opened family file
/// the parameters are recorded in txt file following certain formats
/// </summary>
class FamilyParameterAssigner
{
#region Memeber Fields
private Autodesk.Revit.ApplicationServices.Application m_app;
private ThisApplication? m_thisapp;
private FamilyManager? m_manager = null;
string addInPath = String.Empty;
// indicate whether the parameter files have been loaded. If yes, no need to load again.
bool m_paramLoaded;
// set the paramName as key of dictionary for exclusiveness (the names of parameters should be unique)
private Dictionary<string /*paramName*/, FamilyParam> m_familyParams;
private DefinitionFile? m_sharedFile;
private string m_familyFilePath = string.Empty;
private string m_sharedFilePath = string.Empty;
#endregion
/// <summary>
/// constructor
/// </summary>
/// <param name="app">
/// the active revit application
/// </param>
/// <param name="doc">
/// the family document which will have parameters added in
/// </param>
public FamilyParameterAssigner(ThisApplication thisApp)
{
m_thisapp = thisApp;
m_app = thisApp.Application;
m_manager = thisApp.ActiveUIDocument.Document.FamilyManager;
m_familyParams = new Dictionary<string, FamilyParam>();
addInPath = thisApp.AddinFolder;
m_paramLoaded = false;
}
/// <summary>
/// load the family parameter file (if exists) and shared parameter file (if exists)
/// only need to load once
/// </summary>
/// <returns>
/// if succeeded, return true; otherwise false
/// </returns>
public bool LoadParametersFromFile()
{
if (m_paramLoaded)
{
return true;
}
// load family parameter file
bool famParamFileExist;
bool succeeded = LoadFamilyParameterFromFile(out famParamFileExist);
if (!succeeded)
{
return false;
}
// load shared parameter file
bool sharedParamFileExist;
succeeded = LoadSharedParameterFromFile(out sharedParamFileExist);
if (!(famParamFileExist || sharedParamFileExist))
{
MessageManager.MessageBuff.AppendLine("Neither familyParameter.txt nor sharedParameter.txt exists in the assembly folder.");
return false;
}
if (!succeeded)
{
return false;
}
m_paramLoaded = true;
return true;
}
/// <summary>
/// load family parameters from the text file
/// </summary>
/// <returns>
/// return true if succeeded; otherwise false
/// </returns>
private bool LoadFamilyParameterFromFile(out bool exist)
{
exist = true;
if (m_thisapp == null)
return false;
// step 1: find the file "FamilyParameter.txt" and open it
string fileName = Directory.GetParent(m_thisapp.ActiveUIDocument.Document.PathName) + "\\FamilyParameter.txt";
if (!File.Exists(fileName))
{
exist = false;
return true;
}
FileStream? file = null;
StreamReader? reader = null;
try
{
file = new FileStream(fileName, FileMode.Open, FileAccess.Read);
reader = new StreamReader(file);
// step 2: read each line, if the line records the family parameter data, store it
// record the content of the current line
string? line;
// record the row number of the current line
int lineNumber = 0;
while (null != (line = reader.ReadLine()))
{
++lineNumber;
// step 2.1: verify the line
// check whether the line is blank line (contains only whitespaces)
Match match = Regex.Match(line, @"^\s*$");
if (true == match.Success)
{
continue;
}
// check whether the line starts from "#" or "*" (comment line)
match = Regex.Match(line, @"\s*['#''*'].*");
if (true == match.Success)
{
continue;
}
// step 2.2: get the parameter data
// it's a valid line (has the format of "paramName paramGroup paramType isInstance", separate by tab or by spaces)
// split the line to an array containing parameter items (format of string[] {"paramName", "paramGroup", "paramType", "isInstance"})
string[] lineData = Regex.Split(line, @"\s+");
// check whether the array has blank items (containing only spaces)
List<string> values = new List<string>();
foreach (string data in lineData)
{
match = Regex.Match(data, @"^\s*$");
if (true == match.Success)
{
continue;
}
values.Add(data);
}
// verify the parameter items (should have 4 items exactly: paramName, paramGroup, paramType and isInstance)
if (4 != values.Count)
{
MessageManager.MessageBuff.Append("Loading family parameter data from \"FamilyParam.txt\".");
MessageManager.MessageBuff.Append("Line [\"" + line + "]\"" + "doesn't follow the valid format.\n");
return false;
}
// get the paramName
string paramName = values[0];
// get the paramGroup
ForgeTypeId paramGroup = new ForgeTypeId(values[1]);
// get the paramType
ForgeTypeId paramType = new ForgeTypeId(values[2]);
// get data "isInstance"
string isInstanceString = values[3];
bool isInstance = Convert.ToBoolean(isInstanceString);
// step 2.3: store the parameter fetched, check for exclusiveness (as the names of parameters should keep unique)
FamilyParam param = new FamilyParam(paramName, paramGroup, paramType, isInstance, lineNumber);
// the family parameter with the same name has already been stored to the dictionary, raise an error
if (m_familyParams.ContainsKey(paramName))
{
FamilyParam duplicatedParam = m_familyParams[paramName];
string warning = "Line " + param.Line + "has a duplicate parameter name with Line " + duplicatedParam.Line + "\n";
MessageManager.MessageBuff.Append(warning);
continue;
}
m_familyParams.Add(paramName, param);
}
}
catch (System.Exception e)
{
MessageManager.MessageBuff.AppendLine(e.Message);
return false;
}
finally
{
if (null != reader)
{
reader.Close();
}
if (null != file)
{
file.Close();
}
}
return true;
}
/// <summary>
/// load family parameters from the text file
/// </summary>
/// <param name="exist">
/// indicate whether the shared parameter file exists
/// </param>
/// <returns>
/// return true if succeeded; otherwise false
/// </returns>
private bool LoadSharedParameterFromFile(out bool exist)
{
exist = true;
string filePath = addInPath + "\\SharedParameter.txt";
if (!File.Exists(filePath))
{
exist = false;
return true;
}
m_app.SharedParametersFilename = filePath;
try
{
m_sharedFile = m_app.OpenSharedParameterFile();
}
catch (System.Exception e)
{
MessageManager.MessageBuff.AppendLine(e.Message);
return false;
}
return true;
}
/// <summary>
/// add parameters to the family file
/// </summary>
/// <returns>
/// if succeeded, return true; otherwise false
/// </returns>
public bool AddParameters()
{
// add the loaded family parameters to the family
bool succeeded = AddFamilyParameter();
if (!succeeded)
{
return false;
}
// add the loaded shared parameters to the family
succeeded = AddSharedParameter();
if (!succeeded)
{
return false;
}
return true;
}
/// <summary>
/// add family parameter to the family
/// </summary>
/// <returns>
/// if succeeded, return true; otherwise false
/// </returns>
private bool AddFamilyParameter()
{
if (m_manager == null)
return false;
bool allParamValid = true;
if (File.Exists(m_familyFilePath) &&
0 == m_familyParams.Count)
{
MessageManager.MessageBuff.AppendLine("No family parameter available for adding.");
return false;
}
foreach (FamilyParameter param in m_manager.Parameters)
{
string name = param.Definition.Name;
if (m_familyParams.ContainsKey(name))
{
allParamValid = false;
FamilyParam famParam = m_familyParams[name];
MessageManager.MessageBuff.Append("Line " + famParam.Line + ": paramName \"" + famParam.Name + "\"already exists in the family document.\n");
}
}
// there're errors in the family parameter text file
if (!allParamValid)
{
return false;
}
foreach (FamilyParam param in m_familyParams.Values)
{
try
{
m_manager.AddParameter(param.Name, param.Group, param.Type, param.IsInstance);
}
catch (Exception e)
{
MessageManager.MessageBuff.AppendLine(e.Message);
return false;
}
}
return true;
}
/// <summary>
/// load shared parameters from shared parameter file and add them to family
/// </summary>
/// <returns>
/// if succeeded, return true; otherwise false
/// </returns>
private bool AddSharedParameter()
{
if (m_sharedFile == null)
return false;
if (File.Exists(m_sharedFilePath) &&
null == m_sharedFile)
{
MessageManager.MessageBuff.AppendLine("SharedParameter.txt has an invalid format.");
return false;
}
foreach (DefinitionGroup group in m_sharedFile.Groups)
{
foreach (ExternalDefinition def in group.Definitions)
{
// check whether the parameter already exists in the document
FamilyParameter? param = m_manager?.get_Parameter(def.Name);
if (null != param)
{
continue;
}
try
{
m_manager?.AddParameter(def, def.GetGroupTypeId(), true);
}
catch (System.Exception e)
{
MessageManager.MessageBuff.AppendLine(e.Message);
return false;
}
}
}
return true;
}
}// end of class "FamilyParameterAssigner"
/// <summary>
/// record the data of a parameter: its name, its group, etc
/// </summary>
class FamilyParam
{
string m_name = string.Empty;
/// <summary>
/// the caption of the parameter
/// </summary>
public string Name
{
get { return m_name; }
}
ForgeTypeId? m_group;
/// <summary>
/// the group of the parameter
/// </summary>
public ForgeTypeId? Group
{
get { return m_group; }
}
ForgeTypeId? m_type;
/// <summary>
/// the type of the parameter
/// </summary>
public ForgeTypeId? Type
{
get { return m_type; }
}
bool m_isInstance;
/// <summary>
/// indicate whether the parameter is an instance parameter or a type parameter
/// </summary>
public bool IsInstance
{
get { return m_isInstance; }
}
int m_line;
/// <summary>
/// record the location of this parameter in the family parameter file
/// </summary>
public int Line
{
get { return m_line; }
}
/// <summary>
/// default constructor, hide this by making it "private"
/// </summary>
private FamilyParam()
{
}
/// <summary>
/// constructor which exposes for invoking
/// </summary>
/// <param name="name">
/// parameter name
/// </param>
/// <param name="group">
/// indicate which group the parameter belongs to
/// </param>
/// <param name="type">
/// the type of the parameter
/// </param>
/// <param name="isInstance">
/// indicate whethe the parameter is an instance parameter
/// </param>
/// <param name="line">
/// record the location of this parameter in the family parameter file
/// </param>
public FamilyParam(string name, ForgeTypeId group, ForgeTypeId type, bool isInstance, int line)
{
m_name = name;
m_group = group;
m_type = type;
m_isInstance = isInstance;
m_line = line;
}
}
/// <summary>
/// store the warning/error messeges when executing the sample
/// </summary>
static class MessageManager
{
static StringBuilder m_messageBuff = new StringBuilder();
/// <summary>
/// store the warning/error messages
/// </summary>
public static StringBuilder MessageBuff
{
get
{
return m_messageBuff;
}
set
{
m_messageBuff = value;
}
}
}
}
@@ -0,0 +1,430 @@
//
// (C) Copyright 2003-2008 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.Diagnostics;
using System.IO;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using MacroSamples_RFA;
namespace Revit.SDK.Samples.GenericModelCreation.CS
{
/// <summary>
/// This class show how to create Generic Model Family by Revit API.
/// </summary>
public class GenericModelCreation
{
#region Class Memeber Variables
// Application of Revit
private Autodesk.Revit.ApplicationServices.Application? m_revit;
private ThisApplication? m_thisApp;
// the document to create generic model family
private Autodesk.Revit.DB.Document? m_familyDocument;
// FamilyItemFactory used to create family
private Autodesk.Revit.Creation.FamilyItemFactory? m_creationFamily = null;
// Count error numbers
private int m_errCount = 0;
// Error information
private string m_errorInfo = "";
#endregion
public GenericModelCreation(ThisApplication thisApp)
{
m_thisApp = thisApp;
m_revit = thisApp.ActiveUIDocument.Document.Application;
}
#region Class Interface 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 void Run()
{
try
{
if (m_thisApp == null)
return;
m_familyDocument = m_thisApp.ActiveUIDocument.Document;
if (!m_familyDocument.IsFamilyDocument)
{
System.Windows.Forms.MessageBox.Show("ActiveDocument is not family document.");
return;
}
m_creationFamily = m_familyDocument.FamilyCreate;
// create generic model family in the document
CreateGenericModel();
if (0 == m_errCount)
{
return;
}
else
{
System.Windows.Forms.MessageBox.Show(m_errorInfo);
return;
}
}
catch (Exception)
{
throw;
}
}
#endregion
#region Class Implementation
/// <summary>
/// Examples for form creation in generic model families.
/// Create extrusion, sweep, blend, swept blend
/// </summary>
public void CreateGenericModel()
{
// use transaction if the family document is not active document
CreateExtrusion();
CreateBlend();
CreateRevolution();
CreateSweep();
CreateSweptBlend();
return;
}
/// <summary>
/// Create one rectangular extrusion
/// </summary>
private void CreateExtrusion()
{
if (m_revit == null || m_creationFamily == null)
return;
try
{
#region Create rectangle profile
CurveArrArray curveArrArray = m_revit.Create.NewCurveArrArray();
CurveArray curveArray1 = m_revit.Create.NewCurveArray();
CurveArray curveArray2 = m_revit.Create.NewCurveArray();
CurveArray curveArray3 = m_revit.Create.NewCurveArray();
XYZ normal = XYZ.BasisZ;
SketchPlane sketchPlane = CreateSketchPlane(normal, XYZ.Zero);
// create one rectangular extrusion
XYZ p0 = XYZ.Zero;
XYZ p1 = m_revit.Create.NewXYZ(10, 0, 0);
XYZ p2 = m_revit.Create.NewXYZ(10, 10, 0);
XYZ p3 = m_revit.Create.NewXYZ(0, 10, 0);
Line line1 = Line.CreateBound(p0, p1);
Line line2 = Line.CreateBound(p1, p2);
Line line3 = Line.CreateBound(p2, p3);
Line line4 = Line.CreateBound(p3, p0);
curveArray1.Append(line1);
curveArray1.Append(line2);
curveArray1.Append(line3);
curveArray1.Append(line4);
curveArrArray.Append(curveArray1);
#endregion
// here create rectangular extrusion
Extrusion rectExtrusion = m_creationFamily.NewExtrusion(true, curveArrArray, sketchPlane, 10);
// move to proper place
XYZ transPoint1 = m_revit.Create.NewXYZ(-16, 0, 0);
ElementTransformUtils.MoveElement(m_familyDocument, rectExtrusion.Id, transPoint1);
}
catch (Exception e)
{
m_errCount++;
m_errorInfo += "Unexpected exceptions occur in CreateExtrusion: " + e.ToString() + "\r\n";
}
}
/// <summary>
/// Create one blend
/// </summary>
private void CreateBlend()
{
try
{
#region Create top and base profiles
if (m_revit == null)
return;
CurveArray topProfile = m_revit.Create.NewCurveArray();
CurveArray baseProfile = m_revit.Create.NewCurveArray();
XYZ normal = XYZ.BasisZ;
SketchPlane sketchPlane = CreateSketchPlane(normal, XYZ.Zero);
// create one blend
XYZ p00 = XYZ.Zero;
XYZ p01 = m_revit.Create.NewXYZ(10, 0, 0);
XYZ p02 = m_revit.Create.NewXYZ(10, 10, 0);
XYZ p03 = m_revit.Create.NewXYZ(0, 10, 0);
Line line01 = Line.CreateBound(p00, p01);
Line line02 = Line.CreateBound(p01, p02);
Line line03 = Line.CreateBound(p02, p03);
Line line04 = Line.CreateBound(p03, p00);
baseProfile.Append(line01);
baseProfile.Append(line02);
baseProfile.Append(line03);
baseProfile.Append(line04);
XYZ p10 = m_revit.Create.NewXYZ(5, 2, 10);
XYZ p11 = m_revit.Create.NewXYZ(8, 5, 10);
XYZ p12 = m_revit.Create.NewXYZ(5, 8, 10);
XYZ p13 = m_revit.Create.NewXYZ(2, 5, 10);
Line line11 = Line.CreateBound(p10, p11);
Line line12 = Line.CreateBound(p11, p12);
Line line13 = Line.CreateBound(p12, p13);
Line line14 = Line.CreateBound(p13, p10);
topProfile.Append(line11);
topProfile.Append(line12);
topProfile.Append(line13);
topProfile.Append(line14);
#endregion
// here create rectangular blend
if (m_creationFamily == null)
return;
Blend blend = m_creationFamily.NewBlend(true, topProfile, baseProfile, sketchPlane);
// move to proper place
XYZ transPoint1 = m_revit.Create.NewXYZ(0, 11, 0);
ElementTransformUtils.MoveElement(m_familyDocument, blend.Id, transPoint1);
}
catch (Exception e)
{
m_errCount++;
m_errorInfo += "Unexpected exceptions occur in CreateBlend: " + e.ToString() + "\r\n";
}
}
/// <summary>
/// Create one rectangular profile revolution
/// </summary>
private void CreateRevolution()
{
try
{
#region Create rectangular profile
if (m_revit == null)
return;
CurveArrArray curveArrArray = m_revit.Create.NewCurveArrArray();
CurveArray curveArray = m_revit.Create.NewCurveArray();
XYZ normal = XYZ.BasisZ;
SketchPlane sketchPlane = CreateSketchPlane(normal, XYZ.Zero);
// create one rectangular profile revolution
XYZ p0 = XYZ.Zero;
XYZ p1 = m_revit.Create.NewXYZ(10, 0, 0);
XYZ p2 = m_revit.Create.NewXYZ(10, 10, 0);
XYZ p3 = m_revit.Create.NewXYZ(0, 10, 0);
Line line1 = Line.CreateBound(p0, p1);
Line line2 = Line.CreateBound(p1, p2);
Line line3 = Line.CreateBound(p2, p3);
Line line4 = Line.CreateBound(p3, p0);
XYZ pp = m_revit.Create.NewXYZ(1, -1, 0);
Line axis1 = Line.CreateBound(XYZ.Zero, pp);
curveArray.Append(line1);
curveArray.Append(line2);
curveArray.Append(line3);
curveArray.Append(line4);
curveArrArray.Append(curveArray);
#endregion
// here create rectangular revolution
if (m_creationFamily == null)
return;
Revolution revolution1 = m_creationFamily.NewRevolution(true, curveArrArray, sketchPlane, axis1, -Math.PI, 0);
// move to proper place
XYZ transPoint1 = m_revit.Create.NewXYZ(0, 32, 0);
ElementTransformUtils.MoveElement(m_familyDocument, revolution1.Id, transPoint1);
}
catch (Exception e)
{
m_errCount++;
m_errorInfo += "Unexpected exceptions occur in CreateRevolution: " + e.ToString() + "\r\n";
}
}
/// <summary>
/// Create one sweep
/// </summary>
private void CreateSweep()
{
try
{
if (m_revit == null)
return;
#region Create rectangular profile and path curve
CurveArrArray arrarr = m_revit.Create.NewCurveArrArray();
CurveArray arr = m_revit.Create.NewCurveArray();
XYZ normal = XYZ.BasisZ;
SketchPlane sketchPlane = CreateSketchPlane(normal, XYZ.Zero);
XYZ pnt1 = m_revit.Create.NewXYZ(0, 0, 0);
XYZ pnt2 = m_revit.Create.NewXYZ(2, 0, 0);
XYZ pnt3 = m_revit.Create.NewXYZ(1, 1, 0);
arr.Append(Arc.Create(pnt2, 1.0d, 0.0d, 3.14d, XYZ.BasisX, XYZ.BasisY));
arr.Append(Arc.Create(pnt1, pnt3, pnt2));
arrarr.Append(arr);
SweepProfile profile = m_revit.Create.NewCurveLoopsProfile(arrarr);
XYZ pnt4 = m_revit.Create.NewXYZ(10, 0, 0);
XYZ pnt5 = m_revit.Create.NewXYZ(0, 10, 0);
Curve curve = Line.CreateBound(pnt4, pnt5);
CurveArray curves = m_revit.Create.NewCurveArray();
curves.Append(curve);
#endregion
// here create rectangular sweep
if (m_creationFamily == null)
return;
Sweep sweep1 = m_creationFamily.NewSweep(true, curves, sketchPlane, profile, 0, ProfilePlaneLocation.Start);
// move to proper place
XYZ transPoint1 = m_revit.Create.NewXYZ(11, 0, 0);
ElementTransformUtils.MoveElement(m_familyDocument, sweep1.Id, transPoint1);
}
catch (Exception e)
{
m_errCount++;
m_errorInfo += "Unexpected exceptions occur in CreateSweep: " + e.ToString() + "\r\n";
}
}
/// <summary>
/// Create one SweptBlend
/// </summary>
private void CreateSweptBlend()
{
try
{
if (m_revit == null)
return;
#region Create top and bottom profiles and path curve
XYZ pnt1 = m_revit.Create.NewXYZ(0, 0, 0);
XYZ pnt2 = m_revit.Create.NewXYZ(1, 0, 0);
XYZ pnt3 = m_revit.Create.NewXYZ(1, 1, 0);
XYZ pnt4 = m_revit.Create.NewXYZ(0, 1, 0);
XYZ pnt5 = m_revit.Create.NewXYZ(0, 0, 1);
CurveArrArray arrarr1 = m_revit.Create.NewCurveArrArray();
CurveArray arr1 = m_revit.Create.NewCurveArray();
arr1.Append(Line.CreateBound(pnt1, pnt2));
arr1.Append(Line.CreateBound(pnt2, pnt3));
arr1.Append(Line.CreateBound(pnt3, pnt4));
arr1.Append(Line.CreateBound(pnt4, pnt1));
arrarr1.Append(arr1);
XYZ pnt6 = m_revit.Create.NewXYZ(0.5, 0, 0);
XYZ pnt7 = m_revit.Create.NewXYZ(1, 0.5, 0);
XYZ pnt8 = m_revit.Create.NewXYZ(0.5, 1, 0);
XYZ pnt9 = m_revit.Create.NewXYZ(0, 0.5, 0);
CurveArrArray arrarr2 = m_revit.Create.NewCurveArrArray();
CurveArray arr2 = m_revit.Create.NewCurveArray();
arr2.Append(Line.CreateBound(pnt6, pnt7));
arr2.Append(Line.CreateBound(pnt7, pnt8));
arr2.Append(Line.CreateBound(pnt8, pnt9));
arr2.Append(Line.CreateBound(pnt9, pnt6));
arrarr2.Append(arr2);
SweepProfile bottomProfile = m_revit.Create.NewCurveLoopsProfile(arrarr1);
SweepProfile topProfile = m_revit.Create.NewCurveLoopsProfile(arrarr2);
XYZ pnt10 = m_revit.Create.NewXYZ(5, 0, 0);
XYZ pnt11 = m_revit.Create.NewXYZ(0, 20, 0);
Curve curve = Line.CreateBound(pnt10, pnt11);
XYZ normal = XYZ.BasisZ;
SketchPlane sketchPlane = CreateSketchPlane(normal, XYZ.Zero);
#endregion
// here create rectangular sweep blend
if (m_creationFamily == null)
return;
SweptBlend newSweptBlend1 = m_creationFamily.NewSweptBlend(true, curve, sketchPlane, bottomProfile, topProfile);
// move to proper place
XYZ transPoint1 = m_revit.Create.NewXYZ(11, 32, 0);
ElementTransformUtils.MoveElement(m_familyDocument, newSweptBlend1.Id, transPoint1);
}
catch (Exception e)
{
m_errCount++;
m_errorInfo += "Unexpected exceptions occur in CreateSweptBlend: " + e.ToString() + "\r\n";
}
}
/// <summary>
/// Get element by its id
/// </summary>
private T? GetElement<T>(Int64 eid) where T : Autodesk.Revit.DB.Element
{
ElementId elementId = new ElementId(eid);
return m_familyDocument?.GetElement(elementId) as T;
}
/// <summary>
/// Create sketch plane for generic model profile
/// </summary>
/// <param name="normal">plane normal</param>
/// <param name="origin">origin point</param>
/// <returns></returns>
internal SketchPlane CreateSketchPlane(XYZ normal, XYZ origin)
{
// First create a Geometry.Plane which need in NewSketchPlane() method
Plane geometryPlane = Plane.CreateByNormalAndOrigin(normal, origin);
if (null == geometryPlane) // assert the creation is successful
{
throw new Exception("Create the geometry plane failed.");
}
// Then create a sketch plane using the Geometry.Plane
SketchPlane plane = SketchPlane.Create(m_familyDocument, geometryPlane);
// throw exception if creation failed
if (null == plane)
{
throw new Exception("Create the sketch plane failed.");
}
return plane;
}
#endregion
}
}
@@ -0,0 +1,39 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
<PlatformTarget>x64</PlatformTarget>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<Optimize>False</Optimize>
<DebugSymbols>True</DebugSymbols>
<DebugType>Portable</DebugType>
<OutputPath>..\..\Addin\</OutputPath>
<AssemblyName>MacroSamples_RFA</AssemblyName>
<BaseInterMediateOutputPath>obj\</BaseInterMediateOutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<InterMediateOutputPath>obj\Debug</InterMediateOutputPath>
<Deterministic>false</Deterministic>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute>
</PropertyGroup>
<ItemGroup>
<Reference Include="..\..\..\..\..\RevitAPI.dll">
<Private>False</Private>
</Reference>
<Reference Include="..\..\..\..\..\RevitAPIUI.dll">
<Private>False</Private>
</Reference>
</ItemGroup>
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
<Exec Command="del $(OutputPath)\*.dll" />
</Target>
</Project>
@@ -0,0 +1,31 @@
#region Using directives
using System;
using System.Reflection;
using System.Runtime.InteropServices;
#endregion
// 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("NewModule")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("NewModule")]
[assembly: AssemblyCopyright("Copyright 2023")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// This sets the default COM visibility of types in the assembly to invisible.
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
[assembly: ComVisible(false)]
// The assembly version has following format :
//
// Major.Minor.Build.Revision
//
// You can specify all the values or you can use the default the Revision and
// Build Numbers by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.*")]
@@ -0,0 +1,54 @@
namespace MacroSamples_RFA
{
public sealed partial class ThisApplication : Autodesk.Revit.UI.Macros.ApplicationEntryPoint
{
public event System.EventHandler Startup;
public event System.EventHandler Shutdown;
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
private void OnStartup()
{
}
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
protected override void FinishInitialization()
{
base.FinishInitialization();
this.OnStartup();
this.InternalStartup();
if ((this.Startup != null))
{
this.Startup(this, System.EventArgs.Empty);
}
}
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
protected override void OnShutdown()
{
if ((this.Shutdown != null))
{
this.Shutdown(this, System.EventArgs.Empty);
}
base.OnShutdown();
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
protected override string PrimaryCookie
{
get
{
return "ThisApplication";
}
}
}
}
@@ -0,0 +1,165 @@
using System;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI.Selection;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using Revit.SDK.Samples.AutoParameter.CS;
using Revit.SDK.Samples.GenericModelCreation.CS;
using Revit.SDK.Samples.TypeRegeneration.CS;
using Revit.SDK.Samples.ValidateParameters.CS;
namespace MacroSamples_RFA
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.DB.Macros.AddInId("B0302F6B-64AC-438F-93CB-61F3C632FD57")]
public partial class ThisApplication
{
private void Module_Startup(object? sender, EventArgs e)
{
}
private void Module_Shutdown(object? sender, EventArgs e)
{
}
#region Revit Macros generated code
private void InternalStartup()
{
this.Startup += new System.EventHandler(Module_Startup);
this.Shutdown += new System.EventHandler(Module_Shutdown);
}
#endregion
/// <summary>
/// AutoJoin
/// </summary>
public void AutoJoin()
{
using (Transaction trans = new Transaction(this.ActiveUIDocument.Document, "AutoJoin"))
{
trans.Start();
CombinableElementArray solids = this.ActiveUIDocument.Document.Application.Create.NewCombinableElementArray();
foreach (Autodesk.Revit.DB.ElementId elementId in this.ActiveUIDocument.Selection.GetElementIds())
{
Element element = this.ActiveUIDocument.Document.GetElement(elementId);
System.Diagnostics.Trace.WriteLine(element.GetType().ToString());
GenericForm? gf = element as GenericForm;
if (null != gf && !gf.IsSolid)
{
continue;
}
CombinableElement? ce = element as CombinableElement;
if (null != ce)
{
solids.Append(ce);
}
}
if (solids.Size < 2)
{
MessageBox.Show("At least 2 combinable elements should be selected.");
return;
}
this.ActiveUIDocument.Document.CombineElements(solids);
trans.Commit();
}
}
/// <summary>
/// AutoParameter
/// </summary>
public void AutoParameter()
{
using (Transaction trans = new Transaction(this.ActiveUIDocument.Document, "AutoParameter"))
{
trans.Start();
MessageManager.MessageBuff = new StringBuilder();
bool succeeded = AddParameters();
if (!succeeded)
{
MessageBox.Show(MessageManager.MessageBuff.ToString());
}
trans.Commit();
}
}
/// <summary>
/// add parameters to the active document
/// </summary>
/// <returns>
/// if succeeded, return true; otherwise false
/// </returns>
private bool AddParameters()
{
Document doc = this.ActiveUIDocument.Document;
if (null == doc)
{
MessageManager.MessageBuff.Append("There's no available document. \n");
return false;
}
if (!doc.IsFamilyDocument)
{
MessageManager.MessageBuff.Append("The active document is not a family document. \n");
return false;
}
FamilyParameterAssigner assigner = new FamilyParameterAssigner(this);
// the parameters to be added are defined and recorded in a text file, read them from that file and load to memory
bool succeeded = assigner.LoadParametersFromFile();
if (!succeeded)
{
return false;
}
succeeded = assigner.AddParameters();
if (succeeded)
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// GenericModelCreation
/// </summary>
public void GenericModelCreation()
{
using (Transaction trans = new Transaction(this.ActiveUIDocument.Document, "GenericModelCreation"))
{
trans.Start();
GenericModelCreation sample = new GenericModelCreation(this);
sample.Run();
trans.Commit();
}
}
/// <summary>
/// TypeRegeneration
/// </summary>
public void TypeRegeneration()
{
TypeRegeneration sample = new TypeRegeneration(this);
sample.Run();
}
/// <summary>
/// ValidateParameters
/// </summary>
public void ValidateParameters()
{
ValidateParameters sample = new ValidateParameters(this);
sample.Run();
}
}
}
@@ -0,0 +1,90 @@
//
// (C) Copyright 2003-2008 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.TypeRegeneration.CS
{
partial class MessageForm
{
/// <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.messageRichTextBox = new System.Windows.Forms.RichTextBox();
this.SuspendLayout();
//
// messageRichTextBox
//
this.messageRichTextBox.BackColor = System.Drawing.SystemColors.Info;
this.messageRichTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.messageRichTextBox.EnableAutoDragDrop = true;
this.messageRichTextBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.messageRichTextBox.ForeColor = System.Drawing.SystemColors.InfoText;
this.messageRichTextBox.Location = new System.Drawing.Point(0, 0);
this.messageRichTextBox.Name = "messageRichTextBox";
this.messageRichTextBox.Size = new System.Drawing.Size(313, 186);
this.messageRichTextBox.TabIndex = 1;
this.messageRichTextBox.Text = "";
//
// MessageForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(313, 186);
this.Controls.Add(this.messageRichTextBox);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "MessageForm";
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "MessageForm";
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.RichTextBox messageRichTextBox;
}
}
@@ -0,0 +1,80 @@
//
// (C) Copyright 2003-2008 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 System.Threading;
using System.Runtime.InteropServices;
namespace Revit.SDK.Samples.TypeRegeneration.CS
{
/// <summary>
/// The form is used to show the result
/// </summary>
public partial class MessageForm : Form
{
/// <summary>
/// new a Timer,set the interval 2 seconds;
/// </summary>
System.Timers.Timer timer = new System.Timers.Timer(2000);
/// <summary>
/// construction of MessageForm
/// </summary>
public MessageForm()
{
InitializeComponent();
this.Text = "Type Regeneration Message Form";
//set the timer elapsed event
timer.Elapsed += new System.Timers.ElapsedEventHandler(onTimeOut);//Set the executed event when time is out;
timer.Enabled = false;
CheckForIllegalCrossThreadCalls = false;
}
/// <summary>
/// add text to the richtextbox and set time enable is true, then timer starts timing
/// </summary>
/// <param name="message">message from the regeneration</param>
/// <param name="enableTimer">enable or disable the timer elapsed event</param>
public void AddMessage(string message, bool enableTimer)
{
messageRichTextBox.AppendText(message);
timer.Enabled = enableTimer;
}
/// <summary>
/// the method is executed when time is out, and set the timer enabled false,then timer stop timing
/// </summary>
/// <param name="source"></param>
/// <param name="e">time elapsed event args</param>
private void onTimeOut(object? source, System.Timers.ElapsedEventArgs e)
{
timer.Enabled = false;
this.Close();
}
}
}
@@ -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,176 @@
//
// (C) Copyright 2003-2008 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.Windows.Forms;
using System.IO;
using System.Reflection;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using MacroSamples_RFA;
namespace Revit.SDK.Samples.TypeRegeneration.CS
{
/// <summary>
/// this class controls the class which subscribes handle events and the events' information UI.
/// like a bridge between them.
/// </summary>
public class TypeRegeneration
{
#region Class Memeber Variables
/// <summary>
/// store family manager
/// </summary>
private FamilyManager? m_familyManager;
private Autodesk.Revit.ApplicationServices.Application m_revit;
private ThisApplication? m_thisApp;
/// <summary>
/// store the log file name
/// </summary>
string m_logFileName = string.Empty;
#endregion
public TypeRegeneration(ThisApplication thisApp)
{
m_thisApp = thisApp;
m_revit = thisApp.ActiveUIDocument.Document.Application;
}
#region Class Interface Implementation
/// <summary>
/// Run
/// </summary>
public void Run()
{
if (m_thisApp == null)
return;
Document document = m_thisApp.ActiveUIDocument.Document;
String? docPath = String.Empty;
if (document.PathName != null)
{
docPath = System.IO.Path.GetDirectoryName(document.PathName);
}
m_logFileName = docPath + "\\RegenerationLog.txt";
//only a family document can retrieve family manager
if (document.IsFamilyDocument)
{
m_familyManager = document.FamilyManager;
//create regeneration log file
StreamWriter writer = File.CreateText(m_logFileName);
writer.WriteLine("Family Type Result");
writer.WriteLine("-------------------------");
writer.Close();
using (MessageForm msgForm = new MessageForm())
{
CheckTypeRegeneration(msgForm);
return;
}
}
else
{
System.Windows.Forms.MessageBox.Show("Current document is not family document.");
return;
}
}
#endregion
#region Class Implementation
/// <summary>
/// After setting CurrentType property, the CurrentType has changed to the new one,the Revit model will change along with the current type
/// </summary>
/// <param name="msgForm">the form is used to show the regeneration result</param>
private void CheckTypeRegeneration(MessageForm msgForm)
{
//the list to record the error messages
List<string> errorInfo = new List<string>();
try
{
if (m_familyManager == null)
return;
foreach (FamilyType type in m_familyManager.Types)
{
if (!(type.Name.ToString().Trim() == ""))
{
try
{
m_familyManager.CurrentType = type;
msgForm.AddMessage(type.Name + " Successful\n", true);
WriteLog(type.Name + " Successful");
}
catch
{
errorInfo.Add(type.Name);
msgForm.AddMessage(type.Name + " Failed \n", true);
WriteLog(type.Name + " Failed");
}
msgForm.ShowDialog();
}
}
//add a conclusion regeneration result
string resMsg;
if (errorInfo.Count > 0)
{
resMsg = "\nResult: " + errorInfo.Count + " family types regeneration failed!";
foreach (string error in errorInfo)
{
resMsg += "\n " + error;
}
}
else
{
resMsg = "\nResult: All types in the family can regenerate successfully.";
}
WriteLog(resMsg.ToString());
resMsg += "\nIf you want to know the detail regeneration result please get log file at " + m_logFileName;
msgForm.AddMessage(resMsg, false);
msgForm.ShowDialog();
}
catch (Exception ex)
{
WriteLog("There is some problem when regeneration:" + ex.ToString());
msgForm.AddMessage("There is some problem when regeneration:" + ex.ToString(), true);
msgForm.ShowDialog();
}
}
/// <summary>
/// The method to write line to log file
/// </summary>
/// <param name="logStr">the log string</param>
private void WriteLog(string logStr)
{
StreamWriter? writer = null;
writer = File.AppendText(m_logFileName);
writer.WriteLine(logStr);
writer.Close();
}
#endregion
}
}
@@ -0,0 +1,88 @@
//
// (C) Copyright 2003-2008 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.ValidateParameters.CS
{
partial class MessageForm
{
/// <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.messageRichTextBox = new System.Windows.Forms.RichTextBox();
this.SuspendLayout();
//
// messageRichTextBox
//
this.messageRichTextBox.BackColor = System.Drawing.SystemColors.Info;
this.messageRichTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.messageRichTextBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.messageRichTextBox.ForeColor = System.Drawing.SystemColors.InfoText;
this.messageRichTextBox.Location = new System.Drawing.Point(0, 0);
this.messageRichTextBox.Name = "messageRichTextBox";
this.messageRichTextBox.Size = new System.Drawing.Size(415, 216);
this.messageRichTextBox.TabIndex = 0;
this.messageRichTextBox.Text = "";
//
// MessageForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(415, 216);
this.Controls.Add(this.messageRichTextBox);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "MessageForm";
this.ShowInTaskbar = false;
this.Text = "MessageForm";
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.RichTextBox messageRichTextBox;
}
}
@@ -0,0 +1,108 @@
//
// (C) Copyright 2003-2008 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.Windows.Forms;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using MacroSamples_RFA;
namespace Revit.SDK.Samples.ValidateParameters.CS
{
/// <summary>
/// The form is used to show the result
/// </summary>
public partial class MessageForm : Form
{
/// <summary>
/// store the log file name
/// </summary>
string m_logFileName = string.Empty;
/// <summary>
/// construction of form
/// </summary>
public MessageForm(ThisApplication thisApp)
{
InitializeComponent();
//create regeneration log file
if (thisApp.ActiveUIDocument.Document.PathName != null)
{
m_logFileName = Path.GetDirectoryName(thisApp.ActiveUIDocument.Document.PathName) + "\\ValidateParametersLog.txt";
}
}
/// <summary>
/// construction method with parameter
/// </summary>
/// <param name="messages">messages</param>
public MessageForm(string[] messages, ThisApplication thisApp)
: this(thisApp)
{
string msgText = "";
//If the size of error messages is 0, means the validate parameters is successful
this.Text = "Validate Parameters Message Form";
StreamWriter writer = File.CreateText(m_logFileName);
writer.Close();
if (messages.Length == 0)
{
msgText = "All types and parameters passed the validation for API";
WriteLog(msgText);
messageRichTextBox.Text = msgText;
}
else
{
foreach (string row in messages)
{
if (row == null) continue;
else
{
WriteLog(row);
msgText += row + "\n";
}
}
}
msgText += "\n\nIf you want to know the validating parameters result, please get the log file at \n"+m_logFileName;
messageRichTextBox.Text = msgText;
this.StartPosition = FormStartPosition.CenterParent;
CheckForIllegalCrossThreadCalls = false;
}
/// <summary>
/// The method is used to write line to log file
/// </summary>
/// <param name="logStr">the log string</param>
private void WriteLog(string logStr)
{
StreamWriter? writer = null;
writer = File.AppendText(m_logFileName);
writer.WriteLine(logStr);
writer.Close();
}
}
}
@@ -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,148 @@
//
// (C) Copyright 2003-2008 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.Windows.Forms;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using MacroSamples_RFA;
namespace Revit.SDK.Samples.ValidateParameters.CS
{
/// <summary>
/// this class controls the class which subscribes handle events and the events' information UI.
/// like a bridge between them.
/// </summary>
public class ValidateParameters
{
#region Class Memeber Variables
/// <summary>
/// store the family manager
/// </summary>
private FamilyManager? m_familyManager;
private Autodesk.Revit.ApplicationServices.Application? m_revit = null;
private ThisApplication m_thisApp;
#endregion
public ValidateParameters(ThisApplication thisApp)
{
m_thisApp = thisApp;
m_revit = thisApp.ActiveUIDocument.Document.Application;
}
#region Class Interface Implementation
/// <summary>
/// Run
/// </summary>
public void Run()
{
Document document = m_thisApp.ActiveUIDocument.Document;
// only a family document can retrieve family manager
if (document.IsFamilyDocument)
{
m_familyManager = document.FamilyManager;
List<string> errorMessages = Validate(m_familyManager);
using (MessageForm msgForm = new MessageForm(errorMessages.ToArray(), m_thisApp))
{
msgForm.StartPosition = FormStartPosition.CenterParent;
msgForm.ShowDialog();
return;
}
}
else
{
System.Windows.Forms.MessageBox.Show("Current document is not family document.");
return;
}
}
#endregion
#region Class Implementation
/// <summary>
/// implementation of validate parameters, get all family types and parameters,
/// use the function FamilyType.HasValue() to make sure if the parameter needs to
/// validate. Then along to the storage type to validate the parameters.
/// </summary>
/// <returns>error information list</returns>
public static List<string> Validate(FamilyManager familyManager)
{
List<string> errorInfo = new List<string>();
// go though all parameters
foreach (FamilyType type in familyManager.Types)
{
bool right = true;
foreach (FamilyParameter para in familyManager.Parameters)
{
try
{
if (type.HasValue(para))
{
switch (para.StorageType)
{
case StorageType.Double:
if (!(type.AsDouble(para) is double))
right = false;
break;
case StorageType.ElementId:
try
{
ElementId elemId=type.AsElementId(para);
}
catch
{
right = false;
}
break;
case StorageType.Integer:
if (!(type.AsInteger(para) is int))
right = false;
break;
case StorageType.String:
if (!(type.AsString(para) is string))
right = false;
break;
default:
break;
}
}
}
// output the parameters which failed during validating.
catch
{
errorInfo.Add("Family Type:" + type.Name + " Family Parameter:"
+ para.Definition.Name + " validating failed!");
}
if (!right)
{
errorInfo.Add("Family Type:" + type.Name + " Family Parameter:"
+ para.Definition.Name + " validating failed!");
}
}
}
return errorInfo;
}
#endregion
}
}