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,145 @@
//
// (C) Copyright 2003-2019 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB.Fabrication;
using Autodesk.Revit.UI.Selection;
namespace Revit.SDK.Samples.FabricationPartLayout.CS
{
/// <summary>
/// Implements the Revit add-in interface IExternalCommand
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class Ancillaries : 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 virtual Result Execute(ExternalCommandData commandData
, ref string message, ElementSet elements)
{
Document doc = commandData.Application.ActiveUIDocument.Document;
UIDocument uidoc = commandData.Application.ActiveUIDocument;
FabricationPart fabPart = null;
FabricationConfiguration config = null;
try
{
// check for a load fabrication config
config = FabricationConfiguration.GetFabricationConfiguration(doc);
if (config == null)
{
message = "No fabrication configuration loaded.";
return Result.Failed;
}
// pick a fabrication part
Reference refObj = uidoc.Selection.PickObject(ObjectType.Element, "Pick a fabrication part to start.");
fabPart = doc.GetElement(refObj) as FabricationPart;
}
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
{
return Result.Cancelled;
}
if (fabPart == null)
{
message = "The selected element is not a fabrication part.";
return Result.Failed;
}
else
{
// get ancillary data from selected part and report to user
IList<FabricationAncillaryUsage> ancillaries = fabPart.GetPartAncillaryUsage();
List<string> ancillaryDescriptions = new List<string>();
// create list of ancillary descriptions using the Ancillary UseageType and Name
foreach (var ancillaryUsage in ancillaries)
{
FabricationAncillaryType ancilType = ancillaryUsage.Type;
FabricationAncillaryUsageType usageType = ancillaryUsage.UsageType;
ancillaryDescriptions.Add($"{ancilType.ToString()}: {usageType.ToString()} - "
+ $"{config.GetAncillaryName(ancillaryUsage.AncillaryId)}");
}
string results = string.Empty;
// group and quantify
if (ancillaryDescriptions.Count > 0)
{
ancillaryDescriptions.Sort();
StringBuilder resultsBuilder = new StringBuilder();
string currentAncillary = string.Empty;
foreach (var ancillaryName in ancillaryDescriptions)
{
if (ancillaryName != currentAncillary)
{
resultsBuilder.AppendLine($"{ancillaryName} x {ancillaryDescriptions.Count(x => x == ancillaryName)}");
currentAncillary = ancillaryName;
}
}
results = resultsBuilder.ToString();
}
TaskDialog td = new TaskDialog("Ancillaries")
{
MainIcon = TaskDialogIcon.TaskDialogIconInformation,
TitleAutoPrefix = false,
MainInstruction = ancillaryDescriptions.Count > 0 ?
$"{ancillaryDescriptions.Count} ancillaries found on selected part"
: $"No ancillaries found on selected part",
MainContent = results
};
td.Show();
}
return Result.Succeeded;
}
}
}
@@ -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.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB.Fabrication;
namespace Revit.SDK.Samples.FabricationPartLayout.CS
{
/// <summary>
/// Implements the Revit add-in interface IExternalCommand
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class ButtonPaletteExclusions : 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 virtual Result Execute(ExternalCommandData commandData
, ref string message, ElementSet elements)
{
try
{
Document doc = commandData.Application.ActiveUIDocument.Document;
using (Transaction tr = new Transaction(doc, "Set button and palette exclusions"))
{
tr.Start();
FabricationConfiguration config = FabricationConfiguration.GetFabricationConfiguration(doc);
if (config == null)
{
message = "No fabrication configuration loaded.";
return Result.Failed;
}
// get all loaded fabrication services
IList<FabricationService> allLoadedServices = config.GetAllLoadedServices();
// get the "ADSK - HVAC:Supply Air" service
string serviceName = "ADSK - HVAC: Supply Air";
FabricationService selectedService = allLoadedServices.FirstOrDefault(x => x.Name == serviceName);
if (selectedService == null)
{
message = $"Could not find fabrication service {serviceName}";
return Result.Failed;
}
string rectangularPaletteName = "Rectangular";
string roundPaletteName = "Round Bought Out";
string excludeButtonName = "Square Bend";
int rectangularPaletteIndex = -1;
int roundPaletteIndex = -1;
// find Rectangular and Round palettes in service
for (int i = 0; i < selectedService.PaletteCount; i++)
{
if (selectedService.GetPaletteName(i) == rectangularPaletteName)
{
rectangularPaletteIndex = i;
}
if (selectedService.GetPaletteName(i) == roundPaletteName)
{
roundPaletteIndex = i;
}
if (rectangularPaletteIndex > -1 && roundPaletteIndex > -1)
{
break;
}
}
if (rectangularPaletteIndex > -1)
{
// exclude square bend in Rectangular palette
for (int i = 0; i < selectedService.GetButtonCount(rectangularPaletteIndex); i++)
{
if (selectedService.GetButton(rectangularPaletteIndex, i).Name == excludeButtonName)
{
selectedService.OverrideServiceButtonExclusion(rectangularPaletteIndex, i, true);
break;
}
}
}
else
{
message = $"Unable to locate {excludeButtonName} button to exclude.";
return Result.Failed;
}
// exclude entire Round Bought Out service palette
if (roundPaletteIndex > -1)
{
selectedService.SetServicePaletteExclusions(new List<int>() { roundPaletteIndex });
}
else
{
message = $"Unable to locate {roundPaletteName} service palette to exclude.";
return Result.Failed;
}
tr.Commit();
TaskDialog td = new TaskDialog("Button and Palette Exclsuions")
{
MainIcon = TaskDialogIcon.TaskDialogIconInformation,
TitleAutoPrefix = false,
MainInstruction = "Operation Successful",
MainContent = $"Excluded {excludeButtonName} button from {serviceName} {rectangularPaletteName} Palette {Environment.NewLine}"
+ $"Excluded {roundPaletteName} Palette from {serviceName}"
};
td.Show();
}
return Result.Succeeded;
}
catch (Exception ex)
{
message = ex.Message;
return Result.Failed;
}
}
}
}
@@ -0,0 +1,348 @@
//
// (C) Copyright 2003-2011 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.Linq;
using System.Text;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB.Fabrication;
namespace Revit.SDK.Samples.FabricationPartLayout.CS
{
/// <summary>
/// Implements the Revit add-in interface IExternalCommand
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class ChangeService : 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 virtual Result Execute(ExternalCommandData commandData
, ref string message, ElementSet elements)
{
try
{
Document doc = commandData.Application.ActiveUIDocument.Document;
// get the user selection
UIDocument uidoc = commandData.Application.ActiveUIDocument;
ICollection<ElementId> collection = uidoc.Selection.GetElementIds();
if (collection.Count > 0)
{
// FabricationNetworkChangeService needs an ISet<ElementId>
ISet<ElementId> selIds = new HashSet<ElementId>();
foreach (ElementId id in collection)
{
selIds.Add(id);
}
using (Transaction tr = new Transaction(doc, "Change Service of Fabrication Parts"))
{
tr.Start();
FabricationConfiguration config = FabricationConfiguration.GetFabricationConfiguration(doc);
// Get all loaded fabrication services
IList<FabricationService> allLoadedServices = config.GetAllLoadedServices();
FabricationNetworkChangeService changeservice = new FabricationNetworkChangeService(doc);
// Change the fabrication parts to the first loaded service and palette
FabricationNetworkChangeServiceResult result = changeservice.ChangeService(selIds, allLoadedServices[0].ServiceId, 0);
if (result != FabricationNetworkChangeServiceResult.Success)
{
message = "There was a problem with the change service.";
return Result.Failed;
}
doc.Regenerate();
tr.Commit();
}
return Result.Succeeded;
}
else
{
// inform user they need to select at least one element
message = "Please select at least one element.";
}
return Result.Failed;
}
catch (Exception ex)
{
message = ex.Message;
return Result.Failed;
}
}
}
/// <summary>
/// Implements the Revit add-in interface IExternalCommand
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class ChangeSize : 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 virtual Result Execute(ExternalCommandData commandData
, ref string message, ElementSet elements)
{
try
{
Document doc = commandData.Application.ActiveUIDocument.Document;
// get the user selection
UIDocument uidoc = commandData.Application.ActiveUIDocument;
ICollection<ElementId> collection = uidoc.Selection.GetElementIds();
if (collection.Count > 0)
{
// FabricationNetworkChangeService needs an ISet<ElementId>
ISet<ElementId> selIds = new HashSet<ElementId>();
foreach (ElementId id in collection)
{
selIds.Add(id);
}
using (Transaction tr = new Transaction(doc, "Change Size of Fabrication Parts"))
{
tr.Start();
FabricationConfiguration config = FabricationConfiguration.GetFabricationConfiguration(doc);
// Get all loaded fabrication services
IList<FabricationService> allLoadedServices = config.GetAllLoadedServices();
// Create a map of sizes to swap the current sizes to a new size
var sizeMappings = new HashSet<Autodesk.Revit.DB.Fabrication.FabricationPartSizeMap>();
var mapping = new Autodesk.Revit.DB.Fabrication.FabricationPartSizeMap("12x12", 1.0, 1.0, false, ConnectorProfileType.Rectangular, allLoadedServices[0].ServiceId, 0 );
mapping.MappedWidthDiameter = 1.5;
mapping.MappedDepth = 1.5;
sizeMappings.Add( mapping );
var mapping1 = new Autodesk.Revit.DB.Fabrication.FabricationPartSizeMap("18x18", 1.5, 1.5, false, ConnectorProfileType.Rectangular, allLoadedServices[0].ServiceId, 0 );
mapping1.MappedWidthDiameter = 2.0;
mapping1.MappedDepth = 2.0;
sizeMappings.Add( mapping1 );
FabricationNetworkChangeService changesize = new FabricationNetworkChangeService(doc);
// Change the size of the fabrication parts in the selection to the new sizes
FabricationNetworkChangeServiceResult result = changesize.ChangeSize(selIds, sizeMappings );
if (result != FabricationNetworkChangeServiceResult.Success)
{
// Get the collection of element identifiers for parts that had errors posted against them
ICollection<ElementId> errorIds = changesize.GetElementsThatFailed();
if ( errorIds.Count > 0 )
{
message = "There was a problem with the change size.";
return Result.Failed;
}
}
doc.Regenerate();
tr.Commit();
}
return Result.Succeeded;
}
else
{
// inform user they need to select at least one element
message = "Please select at least one element.";
}
return Result.Failed;
}
catch (Exception ex)
{
message = ex.Message;
return Result.Failed;
}
}
}
/// <summary>
/// Implements the Revit add-in interface IExternalCommand
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class ApplyChange : 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 virtual Result Execute(ExternalCommandData commandData
, ref string message, ElementSet elements)
{
try
{
Document doc = commandData.Application.ActiveUIDocument.Document;
// get the user selection
UIDocument uidoc = commandData.Application.ActiveUIDocument;
ICollection<ElementId> collection = uidoc.Selection.GetElementIds();
if (collection.Count > 0)
{
// FabricationNetworkChangeService needs an ISet<ElementId>
ISet<ElementId> selIds = new HashSet<ElementId>();
foreach (ElementId id in collection)
{
selIds.Add(id);
}
using (Transaction tr = new Transaction(doc, "Appply Change Service and Size of Fabrication Parts"))
{
tr.Start();
FabricationConfiguration config = FabricationConfiguration.GetFabricationConfiguration(doc);
// Get all loaded fabrication services
IList<FabricationService> allLoadedServices = config.GetAllLoadedServices();
FabricationNetworkChangeService applychange = new FabricationNetworkChangeService(doc);
// Set the selection of element identifiers to be changed
applychange.SetSelection( selIds );
// Set the service to the second service in the list (ductwork exhaust service)
applychange.SetServiceId( allLoadedServices[1].ServiceId );
// Set the palette to the second in the list (round)
applychange.SetPaletteId( 1 );
// Get the sizes of all the straights that was in the selection of elements that was added to FabricationNetworkChangeService
ISet<Autodesk.Revit.DB.Fabrication.FabricationPartSizeMap> sizeMappings = applychange.GetMapOfAllSizesForStraights();
foreach (Autodesk.Revit.DB.Fabrication.FabricationPartSizeMap sizemapping in sizeMappings)
{
if (sizemapping != null)
{
// Testing round so ignoring the depth and adding 6" to the current size so all straights will be updated to a new size
var widthDia = sizemapping.WidthDiameter + 0.5;
sizemapping.MappedWidthDiameter = widthDia;
}
}
applychange.SetMapOfSizesForStraights( sizeMappings );
// Get the in-line element type identiers
var inlineRevIds = new HashSet<Autodesk.Revit.DB.ElementId>();
ISet<Autodesk.Revit.DB.ElementId> inlineIds = applychange.GetInLinePartTypes();
for ( var ii = inlineIds.Count() - 1; ii > -1; ii-- )
{
var elemId = inlineIds.ElementAt( ii );
if (elemId != null)
inlineRevIds.Add(elemId);
}
// Set the in-line element type identiers by swapping them out by reversing the order to keep it simple but still exercise the code
IDictionary<ElementId, ElementId> swapinlineIds = new Dictionary<ElementId, ElementId>();
for ( var ii = inlineIds.Count() - 1; ii > -1; ii-- )
{
var elemId = inlineIds.ElementAt( ii );
var elemIdother = inlineRevIds.ElementAt( ii );
if ((elemId != null) && (elemId != null))
swapinlineIds.Add(elemId, elemIdother);
}
applychange.SetMapOfInLinePartTypes( swapinlineIds );
// Apply the changes
FabricationNetworkChangeServiceResult result = applychange.ApplyChange();
if (result != FabricationNetworkChangeServiceResult.Success)
{
message = "There was a problem with the apply change.";
return Result.Failed;
}
doc.Regenerate();
tr.Commit();
}
return Result.Succeeded;
}
else
{
// inform user they need to select at least one element
message = "Please select at least one element.";
}
return Result.Failed;
}
catch (Exception ex)
{
message = ex.Message;
return Result.Failed;
}
}
}
}
@@ -0,0 +1,198 @@
//
// (C) Copyright 2003-2011 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.Linq;
using System.Text;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB.Fabrication;
namespace Revit.SDK.Samples.FabricationPartLayout.CS
{
/// <summary>
/// Implements the Revit add-in interface IExternalCommand
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class ConvertToFabrication : 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 virtual Result Execute(ExternalCommandData commandData
, ref string message, ElementSet elements)
{
try
{
Document doc = commandData.Application.ActiveUIDocument.Document;
// get the user selection
UIDocument uidoc = commandData.Application.ActiveUIDocument;
ICollection<ElementId> collection = uidoc.Selection.GetElementIds();
if (collection.Count > 0)
{
// DesignToFabrication needs an ISet<ElementId>
ISet<ElementId> selIds = new HashSet<ElementId>();
foreach (ElementId id in collection)
{
selIds.Add(id);
}
// Set the in-line element type identiers to be swapped during the conversion replacing the family with a similar fabrication part
IDictionary<ElementId, ElementId> convertInLineIds = new Dictionary<ElementId, ElementId>();
// Get all family symbols
FilteredElementCollector familyFinder = new FilteredElementCollector(doc);
var families = familyFinder.OfClass(typeof(FamilySymbol)).ToElements().ToList();
// Get the family symbol for the damper we are going to convert
String fsName = "Fire Damper - Rectangular - Simple";
// The found family symbol
FamilySymbol fsDamper = null;
foreach (FamilySymbol family in families)
{
if (family.FamilyName == fsName)
{
fsDamper = family;
break;
}
}
// If the damper was found try to find the matching fabrication part type
if (fsDamper != null)
{
// Get the element type identifier for the family symbol
var elemFamSymId = fsDamper.Id;
// Get all fabrication part types
FilteredElementCollector fabPartTypeFinder = new FilteredElementCollector(doc);
var fabPartTypes = fabPartTypeFinder.OfClass(typeof(FabricationPartType)).ToElements().ToList();
// Get the fabrication part type for the damper we are going to convert to
String fptName = "Rect FD - Flange";
// The found fabrication part type
FabricationPartType fptDamper = null;
foreach (FabricationPartType partType in fabPartTypes)
{
if (partType.FamilyName == fptName)
{
fptDamper = partType;
break;
}
}
// The damper was found create the mapping in between the family symbol and the matching fabrication part type
if (fptDamper != null)
{
// Get the element type identifier for the fabricaion part type
var elemFabPartTypeId = fptDamper.Id;
// Create the mapping for the family to the fabrication part
convertInLineIds.Add(elemFamSymId, elemFabPartTypeId);
}
}
using (Transaction tr = new Transaction(doc, "Convert To Fabrication Parts"))
{
tr.Start();
FabricationConfiguration config = FabricationConfiguration.GetFabricationConfiguration(doc);
// get all loaded fabrication services and attempt to convert the design elements
// to the first loaded service
IList<FabricationService> allLoadedServices = config.GetAllLoadedServices();
DesignToFabricationConverter converter = new DesignToFabricationConverter(doc);
// If there is a mapping defined attempt to add it to the converter
if (convertInLineIds.Count() > 0)
{
// Set the mappings
DesignToFabricationMappingResult mappingResult = converter.SetMapForFamilySymbolToFabricationPartType(convertInLineIds);
if (mappingResult != DesignToFabricationMappingResult.Success)
{
if (mappingResult != DesignToFabricationMappingResult.Undefined)
message = "There was a problem with the conversion. The map contained no entries.";
else if (mappingResult != DesignToFabricationMappingResult.InvalidFamilySymbol)
message = "There was a problem with the conversion. There was an invalid Family symbol identifier or an identifier that did not exist in the mappings.";
else if (mappingResult != DesignToFabricationMappingResult.InvalidFabricationPartType)
message = "There was a problem with the conversion. There was an invalid Fabrication part type identifier or an identifier that did not exist in the mappings.";
else if (mappingResult != DesignToFabricationMappingResult.UnsupportedFamilySymbol)
message = "There was a problem with the conversion. Unsupported Family symbol it is expected to be either valve, strainer, damper, smoke detector, end cap, or other in line component.";
else if (mappingResult != DesignToFabricationMappingResult.UnsupportedFabricationPartType)
message = "There was a problem with the conversion. Unsupported Fabrication part type. It is expected to be either valve, strainer, damper, smoke detector, end cap, or other in line component.";
return Result.Failed;
}
}
DesignToFabricationConverterResult result = converter.Convert(selIds, allLoadedServices[0].ServiceId);
if (result != DesignToFabricationConverterResult.Success)
{
message = "There was a problem with the conversion.";
return Result.Failed;
}
doc.Regenerate();
tr.Commit();
}
return Result.Succeeded;
}
else
{
// inform user they need to select at least one element
message = "Please select at least one element.";
}
return Result.Failed;
}
catch (Exception ex)
{
message = ex.Message;
return Result.Failed;
}
}
}
}
@@ -0,0 +1,258 @@
//
// (C) Copyright 2003-2019 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB.Fabrication;
using Autodesk.Revit.UI.Selection;
namespace Revit.SDK.Samples.FabricationPartLayout.CS
{
/// <summary>
/// Helper class to report custom data from fabrication part selection.
/// </summary>
public class CustomDataHelper
{
/// <summary>
/// Report the custom data.
/// </summary>
/// <param name="doc"></param>
/// <param name="uiDoc"></param>
/// <param name="setNewValues"></param>
/// <param name="message"></param>
/// <returns></returns>
public static Result ReportCustomData(Document doc, UIDocument uiDoc, bool setNewValues, ref string message)
{
FabricationPart fabPart = null;
FabricationConfiguration config = null;
try
{
// check for a load fabrication config
config = FabricationConfiguration.GetFabricationConfiguration(doc);
if (config == null)
{
message = "No fabrication configuration loaded.";
return Result.Failed;
}
// pick a fabrication part
Reference refObj = uiDoc.Selection.PickObject(ObjectType.Element, "Pick a fabrication part to start.");
fabPart = doc.GetElement(refObj) as FabricationPart;
}
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
{
return Result.Cancelled;
}
if (fabPart == null)
{
message = "The selected element is not a fabrication part.";
return Result.Failed;
}
else
{
// get custom data from loaded fabrication config
IList<int> customDataIds = config.GetAllPartCustomData();
int customDataCount = customDataIds.Count;
string results = string.Empty;
// report custom data info
if (customDataCount > 0)
{
StringBuilder resultsBuilder = new StringBuilder();
resultsBuilder.AppendLine($"Fabrication config contains {customDataCount} custom data entries {Environment.NewLine}");
foreach (var customDataId in customDataIds)
{
FabricationCustomDataType customDataType = config.GetPartCustomDataType(customDataId);
string customDataName = config.GetPartCustomDataName(customDataId);
resultsBuilder.AppendLine($"Type: {customDataType.ToString()} Name: {customDataName}");
// check custom data exists on selected part
if (fabPart.HasCustomData(customDataId))
{
string fabPartCurrentValue = string.Empty;
string fabPartNewValue = string.Empty;
switch (customDataType)
{
case FabricationCustomDataType.Text:
fabPartCurrentValue = $"\"{fabPart.GetPartCustomDataText(customDataId)}\"";
if (setNewValues)
{
string installDateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm");
fabPart.SetPartCustomDataText(customDataId, installDateTime);
fabPartNewValue = installDateTime;
}
break;
case FabricationCustomDataType.Integer:
fabPartCurrentValue = fabPart.GetPartCustomDataInteger(customDataId).ToString();
if (setNewValues)
{
int installHours = new Random().Next(1, 10);
fabPart.SetPartCustomDataInteger(customDataId, installHours);
fabPartNewValue = installHours.ToString();
}
break;
case FabricationCustomDataType.Real:
fabPartCurrentValue = $"{fabPart.GetPartCustomDataReal(customDataId):0.##}";
if (setNewValues)
{
double installCost = new Random().NextDouble() * new Random().Next(100, 1000);
fabPart.SetPartCustomDataReal(customDataId, installCost);
fabPartNewValue = $"{installCost:0.##}";
}
break;
}
resultsBuilder.AppendLine("Current custom data entry value = "
+ $"{fabPartCurrentValue} {Environment.NewLine}");
if (setNewValues)
{
resultsBuilder.AppendLine("New custom data entry value = "
+ $"{fabPartNewValue} {Environment.NewLine}");
}
}
else
{
resultsBuilder.AppendLine($"Custom data entry is not set on the part {Environment.NewLine}");
}
}
results = resultsBuilder.ToString();
}
TaskDialog td = new TaskDialog("Custom Data")
{
MainIcon = TaskDialogIcon.TaskDialogIconInformation,
TitleAutoPrefix = false,
MainInstruction = $"{customDataCount} custom data entries found in the loaded fabrication config",
MainContent = results
};
td.Show();
}
return Result.Succeeded;
}
}
/// <summary>
/// Implements the Revit add-in interface IExternalCommand
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class GetCustomData : 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 virtual Result Execute(ExternalCommandData commandData
, ref string message, ElementSet elements)
{
Document doc = commandData.Application.ActiveUIDocument.Document;
UIDocument uidoc = commandData.Application.ActiveUIDocument;
return CustomDataHelper.ReportCustomData(doc, uidoc, false, ref message);
}
}
/// <summary>
/// Implements the Revit add-in interface IExternalCommand
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class SetCustomData : 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 virtual Result Execute(ExternalCommandData commandData
, ref string message, ElementSet elements)
{
Document doc = commandData.Application.ActiveUIDocument.Document;
UIDocument uidoc = commandData.Application.ActiveUIDocument;
Result result;
using (Transaction tr = new Transaction(doc, "Setting Custom Data"))
{
tr.Start();
result = CustomDataHelper.ReportCustomData(doc, uidoc, true, ref message);
if (result == Result.Succeeded)
{
tr.Commit();
}
else
{
tr.RollBack();
}
}
return result;
}
}
}
@@ -0,0 +1,124 @@
//
// (C) Copyright 2003-2019 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB.Fabrication;
using System.IO;
using System.Reflection;
namespace Revit.SDK.Samples.FabricationPartLayout.CS
{
/// <summary>
/// Implements the Revit add-in interface IExternalCommand
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class ExportToMAJ : 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 virtual Result Execute(ExternalCommandData commandData
, ref string message, ElementSet elements)
{
try
{
// check user selection
var uidoc = commandData.Application.ActiveUIDocument;
var doc = uidoc.Document;
var elementIds = new HashSet<ElementId>();
uidoc.Selection.GetElementIds().ToList().ForEach( x => elementIds.Add(x) );
var hasFabricationParts = false;
foreach (var elementId in elementIds)
{
var part = doc.GetElement(elementId) as FabricationPart;
if (part != null)
{
hasFabricationParts = true;
break;
}
}
if (hasFabricationParts == false)
{
message = "Select at least one fabrication part";
return Result.Failed;
}
var callingFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var saveAsDlg = new FileSaveDialog("MAJ Files (*.maj)|*.maj");
saveAsDlg.InitialFileName = callingFolder + "\\majExport";
saveAsDlg.Title = "Export To MAJ";
var result = saveAsDlg.Show();
if (result == ItemSelectionDialogResult.Canceled)
return Result.Cancelled;
string filename = ModelPathUtils.ConvertModelPathToUserVisiblePath(saveAsDlg.GetSelectedModelPath());
ISet<ElementId> exported = FabricationPart.SaveAsFabricationJob(doc, elementIds, filename, new FabricationSaveJobOptions(true));
if (exported.Count > 0)
{
TaskDialog td = new TaskDialog("Export to MAJ")
{
MainIcon = TaskDialogIcon.TaskDialogIconInformation,
TitleAutoPrefix = false,
MainInstruction = string.Concat("Export to MAJ was successful - ", exported.Count.ToString(), " Parts written"),
MainContent = filename,
AllowCancellation = false,
CommonButtons = TaskDialogCommonButtons.Ok
};
td.Show();
}
return Result.Succeeded;
}
catch (Exception ex)
{
message = ex.Message;
return Result.Failed;
}
}
}
}
@@ -0,0 +1,133 @@
//
// (C) Copyright 2003-2019 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB.Fabrication;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
namespace Revit.SDK.Samples.FabricationPartLayout.CS
{
/// <summary>
/// Implements the Revit add-in interface IExternalCommand
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class ExportToPCF : 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 virtual Result Execute(ExternalCommandData commandData
, ref string message, ElementSet elements)
{
try
{
// check user selection
var uidoc = commandData.Application.ActiveUIDocument;
var doc = uidoc.Document;
var collection = uidoc.Selection.GetElementIds();
var hasFabricationPart = false;
using (var trans = new Transaction(doc, "Change Spool Name"))
{
trans.Start();
foreach (var elementId in collection)
{
var part = doc.GetElement(elementId) as FabricationPart;
if (part != null)
{
hasFabricationPart = true;
part.SpoolName = "My Spool";
}
}
trans.Commit();
}
if (hasFabricationPart == false)
{
message = "Select at least one fabrication part";
return Result.Failed;
}
var callingFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var saveAsDlg = new FileSaveDialog("PCF Files (*.pcf)|*.pcf");
saveAsDlg.InitialFileName = callingFolder + "\\pcfExport";
saveAsDlg.Title = "Export To PCF";
var result = saveAsDlg.Show();
if (result == ItemSelectionDialogResult.Canceled)
return Result.Cancelled;
var fabParts = collection.ToList();
string filename = ModelPathUtils.ConvertModelPathToUserVisiblePath(saveAsDlg.GetSelectedModelPath());
FabricationUtils.ExportToPCF(doc, fabParts, filename);
TaskDialog td = new TaskDialog("Export to PCF")
{
MainIcon = TaskDialogIcon.TaskDialogIconInformation,
TitleAutoPrefix = false,
MainInstruction = "Export to PCF was successful",
MainContent = filename,
AllowCancellation = false,
CommonButtons = TaskDialogCommonButtons.Ok
};
td.Show();
return Result.Succeeded;
}
catch (Exception ex)
{
message = ex.Message;
return Result.Failed;
}
}
}
}
@@ -0,0 +1,219 @@
//
// (C) Copyright 2003-2019 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB.Fabrication;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
namespace Revit.SDK.Samples.FabricationPartLayout.CS
{
/// <summary>
/// Implements the Revit add-in interface IExternalCommand
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class FabPartGeometry : IExternalCommand
{
private IList<Mesh> getMeshes(GeometryElement ge)
{
IList<Mesh> rv = new List<Mesh>();
if (ge != null)
{
foreach (GeometryObject g in ge)
{
GeometryInstance i = g as GeometryInstance;
if (i != null)
{
GeometryElement ge2 = i.GetInstanceGeometry();
if (ge2 != null)
rv = rv.Concat(getMeshes(ge2)).ToList();
}
else
{
Mesh mesh = g as Mesh;
if (mesh != null && mesh.Vertices.Count > 0)
rv.Add(mesh);
}
}
}
return rv;
}
private bool exportMesh(String filename, Mesh mesh)
{
bool bSaved = false;
try
{
StreamWriter sout = new StreamWriter(filename, false);
sout.WriteLine("P1X, P1Y, P1Z, P2X, P2Y, P2Z, P3X, P3Y, P3Z");
for (int tlp = 0; tlp < mesh.NumTriangles; tlp++)
{
MeshTriangle tri = mesh.get_Triangle(tlp);
XYZ p1 = mesh.Vertices[(int)tri.get_Index(0)];
XYZ p2 = mesh.Vertices[(int)tri.get_Index(1)];
XYZ p3 = mesh.Vertices[(int)tri.get_Index(2)];
String tstr = String.Format("{0:0.000}, {1:0.000}, {2:0.000}, {3:0.000}, {4:0.000}, {5:0.000}, {6:0.000}, {7:0.000}, {8:0.000}", new object[] { p1.X, p1.Y, p1.Z, p2.X, p2.Y, p2.Z, p3.X, p3.Y, p3.Z });
sout.WriteLine(tstr);
}
sout.Close();
bSaved = true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Unable to write file", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
return bSaved;
}
/// <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 virtual Result Execute(ExternalCommandData commandData
, ref string message, ElementSet elements)
{
try
{
// check user selection
var uidoc = commandData.Application.ActiveUIDocument;
var doc = uidoc.Document;
ISet<ElementId> parts = null;
using (Transaction tr = new Transaction(doc, "Optimise Preselection"))
{
tr.Start();
ICollection<ElementId> selElems = uidoc.Selection.GetElementIds();
if (selElems.Count > 0)
{
parts = new HashSet<ElementId>(selElems);
}
tr.Commit();
}
if (parts == null)
{
MessageBox.Show("Select parts to export.");
return Result.Failed;
}
var callingFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var saveAsDlg = new FileSaveDialog("CSV Files (*.csv)|*.csv");
saveAsDlg.InitialFileName = callingFolder + "\\geomExport";
saveAsDlg.Title = "Save Part Geometry As";
var result = saveAsDlg.Show();
if (result == ItemSelectionDialogResult.Canceled)
return Result.Cancelled;
string filename = ModelPathUtils.ConvertModelPathToUserVisiblePath(saveAsDlg.GetSelectedModelPath());
string ext = Path.GetExtension(filename);
filename = Path.GetFileNameWithoutExtension(filename);
int partcount = 1, exported = 0;
foreach (ElementId eid in parts)
{
            // get all rods and kist with rods
            FabricationPart part = doc.GetElement(eid) as FabricationPart;
if (part != null)
{
Options options = new Options();
options.DetailLevel = ViewDetailLevel.Coarse;
IList<Mesh> main = getMeshes(part.get_Geometry(options));
IList<Mesh> ins = getMeshes(part.GetInsulationLiningGeometry());
int mlp = 0;
foreach (Mesh mesh in main)
{
String file = String.Concat( filename, partcount.ToString(), "-main-", (++mlp).ToString(), ext);
if (exportMesh(file, mesh))
exported++;
}
int ilp = 0;
foreach (Mesh mesh in ins)
{
String file = String.Concat(filename, partcount.ToString(), "-ins-", (++ilp).ToString(), ext);
if (exportMesh(file, mesh))
exported++;
}
}
partcount++;
}
String res = (exported > 0) ? "Export was successful" : "Nothing was exported";
String manywritten = String.Format("{0} Parts were exported", exported);
TaskDialog td = new TaskDialog("Export Part Mesh Geometry")
{
MainIcon = TaskDialogIcon.TaskDialogIconInformation,
TitleAutoPrefix = false,
MainInstruction = res,
MainContent = manywritten,
AllowCancellation = false,
CommonButtons = TaskDialogCommonButtons.Ok
};
td.Show();
return Result.Succeeded;
}
catch (Exception ex)
{
message = ex.Message;
return Result.Failed;
}
}
}
}
@@ -0,0 +1,267 @@
<?xml version="1.0" encoding="utf-8"?>
<RevitAddIns>
<AddIn Type="Command">
<Assembly>FabricationPartLayout.dll</Assembly>
<AddInId>399fe985-0175-42c0-98a2-ce1469d2a592</AddInId>
<FullClassName>Revit.SDK.Samples.FabricationPartLayout.CS.FabricationPartLayout</FullClassName>
<VendorId>ADSK</VendorId>
<Text>Fabrication Part Layout</Text>
<Description>Fabrication Part Layout Sample</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Discipline>Any</Discipline>
<LanguageType>Unknown</LanguageType>
</AddIn>
<AddIn Type="Command">
<Assembly>FabricationPartLayout.dll</Assembly>
<AddInId>dece0d9a-51eb-48cd-b260-dd7e4373ffee</AddInId>
<FullClassName>Revit.SDK.Samples.FabricationPartLayout.CS.OptimizeStraights</FullClassName>
<VendorId>ADSK</VendorId>
<Text>Optimize Straights</Text>
<Description>Optimize Straights</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Discipline>Any</Discipline>
<LanguageType>Unknown</LanguageType>
</AddIn>
<AddIn Type="Command">
<Assembly>FabricationPartLayout.dll</Assembly>
<AddInId>21ec0e70-7a8a-4852-853a-d1163f4fe256</AddInId>
<FullClassName>Revit.SDK.Samples.FabricationPartLayout.CS.StretchAndFit</FullClassName>
<VendorId>ADSK</VendorId>
<Text>Stretch and Fit</Text>
<Description>Stretch and fit</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Discipline>Any</Discipline>
<LanguageType>Unknown</LanguageType>
</AddIn>
<AddIn Type="Command">
<Assembly>FabricationPartLayout.dll</Assembly>
<AddInId>78e2660c-497e-4b5b-9e69-e094f1620bc0</AddInId>
<FullClassName>Revit.SDK.Samples.FabricationPartLayout.CS.ConvertToFabrication</FullClassName>
<VendorId>ADSK</VendorId>
<Text>Convert To Fabrication</Text>
<Description>Convert Design Elements To Fabrication Parts</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Discipline>Any</Discipline>
<LanguageType>Unknown</LanguageType>
</AddIn>
<AddIn Type="Command">
<Assembly>FabricationPartLayout.dll</Assembly>
<AddInId>01710049-182d-442a-a5f3-6bc88142a69c</AddInId>
<FullClassName>Revit.SDK.Samples.FabricationPartLayout.CS.ButtonPaletteExclusions</FullClassName>
<VendorId>ADSK</VendorId>
<Text>Buttons and Palette Exclusions</Text>
<Description>Exclude Fabrication Service Buttons and Palettes for Routing Operations</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Discipline>Any</Discipline>
<LanguageType>Unknown</LanguageType>
</AddIn>
<AddIn Type="Command">
<Assembly>FabricationPartLayout.dll</Assembly>
<AddInId>b083fe9b-dd69-43f9-b4ba-71d83e783825</AddInId>
<FullClassName>Revit.SDK.Samples.FabricationPartLayout.CS.Ancillaries</FullClassName>
<VendorId>ADSK</VendorId>
<Text>Ancillaries</Text>
<Description>Discover the Ancillaries Associated with a Fabrication Part</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Discipline>Any</Discipline>
<LanguageType>Unknown</LanguageType>
</AddIn>
<AddIn Type="Command">
<Assembly>FabricationPartLayout.dll</Assembly>
<AddInId>c7ed9947-fd8a-4902-b4ab-70a8768f7994</AddInId>
<FullClassName>Revit.SDK.Samples.FabricationPartLayout.CS.GetCustomData</FullClassName>
<VendorId>ADSK</VendorId>
<Text>Get Custom Data</Text>
<Description>Discover the Custom data Associated with a Fabrication Config and Part</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Discipline>Any</Discipline>
<LanguageType>Unknown</LanguageType>
</AddIn>
<AddIn Type="Command">
<Assembly>FabricationPartLayout.dll</Assembly>
<AddInId>fd062a9b-b1f6-4238-8099-072b75168565</AddInId>
<FullClassName>Revit.SDK.Samples.FabricationPartLayout.CS.SetCustomData</FullClassName>
<VendorId>ADSK</VendorId>
<Text>Set Custom Data</Text>
<Description>Set Custom data Associated with a Fabrication Config to a Selected Part</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Discipline>Any</Discipline>
<LanguageType>Unknown</LanguageType>
</AddIn>
<AddIn Type="Command">
<Assembly>FabricationPartLayout.dll</Assembly>
<AddInId>4FED7AA3-1934-492F-B65C-F1E07D1717F0</AddInId>
<FullClassName>Revit.SDK.Samples.FabricationPartLayout.CS.ExportToPCF</FullClassName>
<VendorId>ADSK</VendorId>
<Text>Export to PCF</Text>
<Description>Exports fabrication parts to a PCF file</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Discipline>Any</Discipline>
<LanguageType>Unknown</LanguageType>
</AddIn>
<AddIn Type="Command">
<Assembly>FabricationPartLayout.dll</Assembly>
<AddInId>B38DDFE1-4218-4B4B-9D88-FB89AE69B5AE</AddInId>
<FullClassName>Revit.SDK.Samples.FabricationPartLayout.CS.FabPartGeometry</FullClassName>
<VendorId>ADSK</VendorId>
<Text>Export Part Geometry</Text>
<Description>Exports fabrication part geometry to a CSV file</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Discipline>Any</Discipline>
<LanguageType>Unknown</LanguageType>
</AddIn>
<AddIn Type="Command">
<Assembly>FabricationPartLayout.dll</Assembly>
<AddInId>D10B0B0E-5CB1-47A2-96C0-0007F4B8A610</AddInId>
<FullClassName>Revit.SDK.Samples.FabricationPartLayout.CS.PartInfo</FullClassName>
<VendorId>ADSK</VendorId>
<Text>Display Part Info</Text>
<Description>Displays fabrication part information</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Discipline>Any</Discipline>
<LanguageType>Unknown</LanguageType>
</AddIn>
<AddIn Type="Command">
<Assembly>FabricationPartLayout.dll</Assembly>
<AddInId>857F26D5-AA39-4DC1-8ED7-35886D082DA9</AddInId>
<FullClassName>Revit.SDK.Samples.FabricationPartLayout.CS.DetachRods</FullClassName>
<VendorId>ADSK</VendorId>
<Text>Detach Hanger Rods</Text>
<Description>Detaches hanger rods from their structural host</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Discipline>Any</Discipline>
<LanguageType>Unknown</LanguageType>
</AddIn>
<AddIn Type="Command">
<Assembly>FabricationPartLayout.dll</Assembly>
<AddInId>7478836E-55CD-4870-81EF-31A6BBA56B1C</AddInId>
<FullClassName>Revit.SDK.Samples.FabricationPartLayout.CS.DoubleRodLength</FullClassName>
<VendorId>ADSK</VendorId>
<Text>Double Rod Lengths</Text>
<Description>Doubles the length of the picked hanger rods</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Discipline>Any</Discipline>
<LanguageType>Unknown</LanguageType>
</AddIn>
<AddIn Type="Command">
<Assembly>FabricationPartLayout.dll</Assembly>
<AddInId>19850600-D546-4B3B-90FF-7A8C8D263A7E</AddInId>
<FullClassName>Revit.SDK.Samples.FabricationPartLayout.CS.HalveRodLength</FullClassName>
<VendorId>ADSK</VendorId>
<Text>Halve Rod Lengths</Text>
<Description>Halves the length of the picked hanger rods</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Discipline>Any</Discipline>
<LanguageType>Unknown</LanguageType>
</AddIn>
<AddIn Type="Command">
<Assembly>FabricationPartLayout.dll</Assembly>
<AddInId>C74A04FD-8767-4AA7-9176-52732134D5BB</AddInId>
<FullClassName>Revit.SDK.Samples.FabricationPartLayout.CS.IncreaseRodStructureExtension</FullClassName>
<VendorId>ADSK</VendorId>
<Text>Increase Rod Structure Extension</Text>
<Description>Increase the length of the rod as an extension from its hosted structure (by 1ft)</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Discipline>Any</Discipline>
<LanguageType>Unknown</LanguageType>
</AddIn>
<AddIn Type="Command">
<Assembly>FabricationPartLayout.dll</Assembly>
<AddInId>7404BDC0-98AE-4E77-B85C-0EB3E4CE8E7B</AddInId>
<FullClassName>Revit.SDK.Samples.FabricationPartLayout.CS.DecreaseRodStructureExtension</FullClassName>
<VendorId>ADSK</VendorId>
<Text>Decrease Rod Structure Extension</Text>
<Description>Decrease the length of the rod as an extension from its hosted structure (by 1ft)</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Discipline>Any</Discipline>
<LanguageType>Unknown</LanguageType>
</AddIn>
<AddIn Type="Command">
<Assembly>FabricationPartLayout.dll</Assembly>
<AddInId>44F05E94-6646-45C3-A855-26B0BB0A34D1</AddInId>
<FullClassName>Revit.SDK.Samples.FabricationPartLayout.CS.PartRenumber</FullClassName>
<VendorId>ADSK</VendorId>
<Text>Part Renumber</Text>
<Description>Renumbers a selection of fabrication parts</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Discipline>Any</Discipline>
<LanguageType>Unknown</LanguageType>
</AddIn>
<AddIn Type="Command">
<Assembly>FabricationPartLayout.dll</Assembly>
<AddInId>5444859C-A7C2-45D1-A527-AFE269EB2275</AddInId>
<FullClassName>Revit.SDK.Samples.FabricationPartLayout.CS.SplitStraight</FullClassName>
<VendorId>ADSK</VendorId>
<Text>Split Straight</Text>
<Description>Splits a fabrication part straight into two equal pieces</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Discipline>Any</Discipline>
<LanguageType>Unknown</LanguageType>
</AddIn>
<AddIn Type="Command">
<Assembly>FabricationPartLayout.dll</Assembly>
<AddInId>328E8863-D396-44F0-A429-3862D222C287</AddInId>
<FullClassName>Revit.SDK.Samples.FabricationPartLayout.CS.LoadAndPlaceNextItemFile</FullClassName>
<VendorId>ADSK</VendorId>
<Text>Load and Place Next Item File</Text>
<Description>Reloads the fabrication configuration and then iterates the item folders and finds the next unloaded item file and lets a user place it in the model</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Discipline>Any</Discipline>
<LanguageType>Unknown</LanguageType>
</AddIn>
<AddIn Type="Command">
<Assembly>FabricationPartLayout.dll</Assembly>
<AddInId>6FC9FEB1-EA83-4C5B-B663-EDBCCC58D427</AddInId>
<FullClassName>Revit.SDK.Samples.FabricationPartLayout.CS.UnloadUnusedItemFiles</FullClassName>
<VendorId>ADSK</VendorId>
<Text>Unload Unused Item Files</Text>
<Description>Unloads item files that are loaded but are not used in the model</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Discipline>Any</Discipline>
<LanguageType>Unknown</LanguageType>
</AddIn>
<AddIn Type="Command">
<Assembly>FabricationPartLayout.dll</Assembly>
<AddInId>970D8022-3085-4CC8-9C47-262C33652AB3</AddInId>
<FullClassName>Revit.SDK.Samples.FabricationPartLayout.CS.ExportToMAJ</FullClassName>
<VendorId>ADSK</VendorId>
<Text>Export to MAJ</Text>
<Description>Export Fabrication Parts to a fabrication job (MAJ) file</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Discipline>Any</Discipline>
<LanguageType>Unknown</LanguageType>
</AddIn>
<AddIn Type="Command">
<Assembly>FabricationPartLayout.dll</Assembly>
<AddInId>6A812363-55D1-4E6E-9D92-31293032D0EA</AddInId>
<FullClassName>Revit.SDK.Samples.FabricationPartLayout.CS.ChangeService</FullClassName>
<VendorId>ADSK</VendorId>
<Text>Change Service</Text>
<Description>Change the service of a selection of Fabrication Parts</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Discipline>Any</Discipline>
<LanguageType>Unknown</LanguageType>
</AddIn>
<AddIn Type="Command">
<Assembly>FabricationPartLayout.dll</Assembly>
<AddInId>103490FA-DE09-407D-90E6-255BF4C320B5</AddInId>
<FullClassName>Revit.SDK.Samples.FabricationPartLayout.CS.ChangeSize</FullClassName>
<VendorId>ADSK</VendorId>
<Text>Change Size</Text>
<Description>Change the size of a selection of Fabrication Parts</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Discipline>Any</Discipline>
<LanguageType>Unknown</LanguageType>
</AddIn>
<AddIn Type="Command">
<Assembly>FabricationPartLayout.dll</Assembly>
<AddInId>9F159E47-EDD6-4727-B9EE-5992F05057CB</AddInId>
<FullClassName>Revit.SDK.Samples.FabricationPartLayout.CS.ApplyChange</FullClassName>
<VendorId>ADSK</VendorId>
<Text>Apply Change</Text>
<Description>Apply change to the service and the size of a selection of Fabrication Parts</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Discipline>Any</Discipline>
<LanguageType>Unknown</LanguageType>
</AddIn>
</RevitAddIns>
@@ -0,0 +1,995 @@
//
// (C) Copyright 2003-2019 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//
using System;
using System.Windows.Forms;
using System.Collections;
using System.Collections.Generic;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB.Fabrication;
using System.Linq;
namespace Revit.SDK.Samples.FabricationPartLayout.CS
{
/// <summary>
/// Implements the Revit add-in interface IExternalCommand
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class FabricationPartLayout : IExternalCommand
{
Document m_doc { get; set; }
IList<FabricationService> m_services { get; set; }
// kept in sync
IList<int> m_materialIds { get; set; }
IList<string> m_materialGroups { get; set; }
IList<string> m_materialNames { get; set; }
// kept in sync
IList<int> m_specIds { get; set; }
IList<string> m_specGroups { get; set; }
IList<string> m_specNames { get; set; }
// kept in sync
IList<int> m_insSpecIds { get; set; }
IList<string> m_insSpecGroups { get; set; }
IList<string> m_insSpecNames { get; set; }
// kept in sync
IList<int> m_connIds { get; set; }
IList<string> m_connGroups { get; set; }
IList<string> m_connNames { get; set; }
/// <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 virtual Result Execute(ExternalCommandData commandData
, ref string message, ElementSet elements)
{
try
{
m_doc = commandData.Application.ActiveUIDocument.Document;
FilteredElementCollector cl = new FilteredElementCollector(m_doc);
cl.OfClass(typeof(Level));
IList<Element> levels = cl.ToElements();
Level levelOne = null;
foreach (Level level in levels)
{
if (level != null && level.Name.Equals("Level 1"))
{
levelOne = level;
break;
}
}
if (levelOne == null)
return Result.Failed;
// locate the AHU in the model - should only be one instance in the model.
FilteredElementCollector c2 = new FilteredElementCollector(m_doc);
c2.OfClass(typeof(FamilyInstance));
IList<Element> families = c2.ToElements();
if (families.Count != 1)
return Result.Failed;
FamilyInstance fam_ahu = families[0] as FamilyInstance;
if (fam_ahu == null)
return Result.Failed;
// locate the proper connector - rectangular 40"x40" outlet
Connector conn_ahu = null;
ConnectorSet conns_ahu = fam_ahu.MEPModel.ConnectorManager.UnusedConnectors;
double lengthInFeet = 40.0 / 12.0;
foreach (Connector conn in conns_ahu)
{
// Revit units measured in feet, so dividing the width and height by 12
if (conn.Shape == ConnectorProfileType.Rectangular && conn.Width == lengthInFeet && conn.Height == lengthInFeet)
conn_ahu = conn;
}
if (conn_ahu == null)
return Result.Failed;
// get the current fabrication configuration
FabricationConfiguration config = FabricationConfiguration.GetFabricationConfiguration(m_doc);
if (config == null)
return Result.Failed;
// create materials look-up tables
GetMaterials(config);
// create specs look-up tables
GetSpecs(config);
// create insulation specs look-up tables
GetInsulationSpecs(config);
// create fabrication configuration look-up tables
GetFabricationConnectors(config);
// get all the loaded services
m_services = config.GetAllLoadedServices();
if (m_services.Count == 0)
return Result.Failed;
FabricationService havcService = m_services.FirstOrDefault(x => x.Name.Contains("HVAC"));
FabricationService pipeService = m_services.FirstOrDefault(x => x.Name.Contains("Plumbing"));
FabricationServiceButton bt_transition = locateButton(havcService, 0, "Transition");
FabricationServiceButton bt_sqBend = locateButton(havcService, 0, "Square Bend");
FabricationServiceButton bt_tap = locateButton(havcService, 0, "Tap");
FabricationServiceButton bt_rectStraight = locateButton(havcService, 0, "Straight");
FabricationServiceButton bt_radBend = locateButton(havcService, 0, "Radius Bend");
FabricationServiceButton bt_flatShoe = locateButton(havcService, 1, "Flat Shoe");
FabricationServiceButton bt_tube = locateButton(havcService, 1, "Tube");
FabricationServiceButton bt_90bend = locateButton(havcService, 1, "Bend - 90");
FabricationServiceButton bt_45bend = locateButton(havcService, 1, "Bend - 45");
FabricationServiceButton bt_rectTee = locateButton(havcService, 0, "Tee");
FabricationServiceButton bt_sqToRound = locateButton(havcService, 0, "Square to Round");
FabricationServiceButton bt_reducer = locateButton(havcService, 1, "Reducer - C");
FabricationServiceButton bt_curvedBoot = locateButton(havcService, 1, "Curved Boot");
FabricationServiceButton bt_hangerBearer = locateButton(havcService, 4, "Rectangular Bearer");
FabricationServiceButton bt_hangerRound = locateButton(havcService, 4, "Round Duct Hanger");
FabricationServiceButton bt_valve = locateButton(pipeService, 2, "Globe Valve");
FabricationServiceButton bt_groovedPipe = locateButton(pipeService, 1, "Type L Hard Copper");
FabricationServiceButton bt_90elbow = locateButton(pipeService, 1, "No610 - 90 Elbow");
using (Transaction tr = new Transaction(m_doc, "Create Layout"))
{
tr.Start();
// connect a square bend to the ahu
FabricationPart pt_sqBend1 = FabricationPart.Create(m_doc, bt_sqBend, 0, levelOne.Id);
Connector conn1_sqBend1 = GetPrimaryConnector(pt_sqBend1.ConnectorManager);
Connector conn2_sqBend1 = GetSecondaryConnector(pt_sqBend1.ConnectorManager);
SizeAlignCoupleConnect(conn1_sqBend1, conn_ahu, 3.0 * Math.PI / 2.0);
// add a 15' straight to the square bend
FabricationPart pt_rectStraight1 = CreateStraightPart(bt_rectStraight, 0, levelOne.Id, 15.0);
Connector conn1_straight1 = GetPrimaryConnector(pt_rectStraight1.ConnectorManager);
Connector conn2_straight1 = GetSecondaryConnector(pt_rectStraight1.ConnectorManager);
SizeAlignCoupleConnect(conn1_straight1, conn2_sqBend1, 0);
// add two Rectangular Bearer hangers at 5' to each end of the 15' straight
FabricationPart.CreateHanger(m_doc, bt_hangerBearer, pt_rectStraight1.Id, conn1_straight1, 5.0, true);
FabricationPart.CreateHanger(m_doc, bt_hangerBearer, pt_rectStraight1.Id, conn2_straight1, 5.0, true);
// connect a tap to the straight half way along
FabricationPart pt_tap1 = FabricationPart.Create(m_doc, bt_tap, 0, levelOne.Id);
Connector conn1_tap1 = GetPrimaryConnector(pt_tap1.ConnectorManager);
Connector conn2_tap1 = GetSecondaryConnector(pt_tap1.ConnectorManager);
FabricationPart.PlaceAsTap(m_doc, conn1_tap1, conn1_straight1, 7.5, 3.0 * Math.PI / 2.0, 0);
// connect a square to round to the tap, with an outlet of 10"
FabricationPart pt_sqToRound1 = FabricationPart.Create(m_doc, bt_sqToRound, 0, levelOne.Id);
Connector conn1_sqToRound1 = GetPrimaryConnector(pt_sqToRound1.ConnectorManager);
Connector conn2_sqToRound1 = GetSecondaryConnector(pt_sqToRound1.ConnectorManager);
conn2_sqToRound1.Radius = 5.0 / 12.0; // convert to feet
SizeAlignCoupleConnect(conn1_sqToRound1, conn2_tap1, 0);
// connect a bend 90, based on the condition (converting 10" into feet)
FabricationPart pt_90bend1 = FabricationPart.Create(m_doc, bt_90bend, 10.0 / 12.0, 10.0 / 12.0, levelOne.Id);
Connector conn1_90bend1 = GetPrimaryConnector(pt_90bend1.ConnectorManager);
Connector conn2_90bend1 = GetSecondaryConnector(pt_90bend1.ConnectorManager);
SizeAlignCoupleConnect(conn1_90bend1, conn2_sqToRound1, 0);
FabricationPart pt_90bend2 = FabricationPart.Create(m_doc, bt_90bend, 0, levelOne.Id);
Connector conn1_90bend2 = GetPrimaryConnector(pt_90bend2.ConnectorManager);
Connector conn2_90bend2 = GetSecondaryConnector(pt_90bend2.ConnectorManager);
SizeAlignCoupleConnect(conn1_90bend2, conn2_90bend1, 0);
// now let's add a tube in
FabricationPart pt_tube1 = CreateStraightPart(bt_tube, 0, levelOne.Id, 5.0);
Connector conn1_tube1 = GetPrimaryConnector(pt_tube1.ConnectorManager);
Connector conn2_tube1 = GetSecondaryConnector(pt_tube1.ConnectorManager);
SizeAlignCoupleConnect(conn1_tube1, conn2_90bend2, 0);
// and now add a square to round, connecting by round end
// change the spec to undefined, change material, add insulation, change a connector
FabricationPart pt_sqToRound2 = FabricationPart.Create(m_doc, bt_sqToRound, 0, levelOne.Id);
Connector conn1_sqToRound2 = GetPrimaryConnector(pt_sqToRound2.ConnectorManager);
Connector conn2_sqToRound2 = GetSecondaryConnector(pt_sqToRound2.ConnectorManager); // round end
SizeAlignCoupleConnect(conn2_sqToRound2, conn2_tube1, 0);
// set the spec to none
pt_sqToRound2.Specification = 0; // none
// now locate specific material, insulation spec and fabrication connector
//int specId = config.LocateSpecification("Ductwork", "+6 WG");
int materialId = config.LocateMaterial("Ductwork", "Mild Steel");
int insSpecId = config.LocateInsulationSpecification("Ductwork", "Acoustic Liner 1''");
int connId = config.LocateFabricationConnector("Duct - S&D", "S&D", ConnectorDomainType.Undefined, ConnectorProfileType.Rectangular);
// now set the material, insulation spec and one of the connectors
if (materialId >= 0)
pt_sqToRound2.Material = materialId;
if (insSpecId >= 0)
pt_sqToRound2.InsulationSpecification = insSpecId;
if (connId >= 0)
conn1_sqToRound2.GetFabricationConnectorInfo().BodyConnectorId = connId;
// connect a 2' 6" transition to the square bend
FabricationPart pt_transition1 = FabricationPart.Create(m_doc, bt_transition, 0, levelOne.Id);
SetDimValue(pt_transition1, "Length", 2.5); // set length of transition to 2' 6"
Connector conn1_transition1 = GetPrimaryConnector(pt_transition1.ConnectorManager);
Connector conn2_transition1 = GetSecondaryConnector(pt_transition1.ConnectorManager);
conn2_transition1.Width = 2.0;
conn2_transition1.Height = 2.0;
SizeAlignCoupleConnect(conn1_transition1, conn2_straight1, 0);
// connect a rising square bend to the transition
FabricationPart pt_sqBend2 = FabricationPart.Create(m_doc, bt_sqBend, 0, levelOne.Id);
Connector conn1_sqBend2 = GetPrimaryConnector(pt_sqBend2.ConnectorManager);
Connector conn2_sqBend2 = GetSecondaryConnector(pt_sqBend2.ConnectorManager);
SizeAlignCoupleConnect(conn1_sqBend2, conn2_transition1, 0);
// connect a 4' 5" straight to the square bend
FabricationPart pt_rectStraight2 = CreateStraightPart(bt_rectStraight, 0, levelOne.Id, (4.0 + (5.0 / 12.0)));
Connector conn1_straight2 = GetPrimaryConnector(pt_rectStraight2.ConnectorManager);
Connector conn2_straight2 = GetSecondaryConnector(pt_rectStraight2.ConnectorManager);
SizeAlignCoupleConnect(conn1_straight2, conn2_sqBend2, 0);
// connect a square bend to the straight
FabricationPart pt_sqBend3 = FabricationPart.Create(m_doc, bt_sqBend, 0, levelOne.Id);
Connector conn1_sqBend3 = GetPrimaryConnector(pt_sqBend3.ConnectorManager);
Connector conn2_sqBend3 = GetSecondaryConnector(pt_sqBend3.ConnectorManager);
SizeAlignCoupleConnect(conn1_sqBend3, conn2_straight2, Math.PI);
// add a 5' straight
FabricationPart pt_rectStraight3 = CreateStraightPart(bt_rectStraight, 0, levelOne.Id, 5.0);
Connector conn1_straight3 = GetPrimaryConnector(pt_rectStraight3.ConnectorManager);
Connector conn2_straight3 = GetSecondaryConnector(pt_rectStraight3.ConnectorManager);
SizeAlignCoupleConnect(conn1_straight3, conn2_sqBend3, 0);
//add a Bearer hanger in middle of straight3
FabricationPart.CreateHanger(m_doc, bt_hangerBearer, pt_rectStraight3.Id, conn1_straight3, 2.5, true);
// add a 45 degree radius bend
FabricationPart pt_radBend1 = FabricationPart.Create(m_doc, bt_radBend, 0, levelOne.Id);
Connector conn1_radBend1 = GetPrimaryConnector(pt_radBend1.ConnectorManager);
Connector conn2_radBend1 = GetSecondaryConnector(pt_radBend1.ConnectorManager);
SizeAlignCoupleConnect(conn1_radBend1, conn2_straight3, 3.0 * Math.PI / 2.0);
SetDimValue(pt_radBend1, "Angle", Math.PI / 4.0);
// add a 1' 8" straight
FabricationPart pt_rectStraight4 = CreateStraightPart(bt_rectStraight, 0, levelOne.Id, 1.0 + (8.0 / 12.0));
Connector conn1_straight4 = GetPrimaryConnector(pt_rectStraight4.ConnectorManager);
Connector conn2_straight4 = GetSecondaryConnector(pt_rectStraight4.ConnectorManager);
SizeAlignCoupleConnect(conn1_straight4, conn2_radBend1, 0);
// add a 45 degree radius bend
FabricationPart pt_radBend2 = FabricationPart.Create(m_doc, bt_radBend, 0, levelOne.Id);
Connector conn1_radBend2 = GetPrimaryConnector(pt_radBend2.ConnectorManager);
Connector conn2_radBend2 = GetSecondaryConnector(pt_radBend2.ConnectorManager);
SizeAlignCoupleConnect(conn1_radBend2, conn2_straight4, Math.PI);
SetDimValue(pt_radBend2, "Angle", Math.PI / 4.0);
// add a 5' straight
FabricationPart pt_rectStraight5 = CreateStraightPart(bt_rectStraight, 0, levelOne.Id, 5.0);
Connector conn1_straight5 = GetPrimaryConnector(pt_rectStraight5.ConnectorManager);
Connector conn2_straight5 = GetSecondaryConnector(pt_rectStraight5.ConnectorManager);
SizeAlignCoupleConnect(conn1_straight5, conn2_radBend2, 0);
//add a Bearer hanger in middle of straight5
FabricationPart.CreateHanger(m_doc, bt_hangerBearer, pt_rectStraight5.Id, conn1_straight5, 2.5, true);
// add a 2' 6" straight
FabricationPart pt_rectStraight6 = CreateStraightPart(bt_rectStraight, 0, levelOne.Id, 2.5);
Connector conn1_straight6 = GetPrimaryConnector(pt_rectStraight6.ConnectorManager);
Connector conn2_straight6 = GetSecondaryConnector(pt_rectStraight6.ConnectorManager);
SizeAlignCoupleConnect(conn1_straight6, conn2_straight5, 0);
// add an 8" tap to the last straight - half way along the straight - using parameter to set the product entry
// could also set the radius directly.
FabricationPart pt_flatShoe1 = FabricationPart.Create(m_doc, bt_flatShoe, 0, levelOne.Id);
Parameter prodEntry_flatShoe1 = pt_flatShoe1.get_Parameter(BuiltInParameter.FABRICATION_PRODUCT_ENTRY);
prodEntry_flatShoe1.Set("8''");
Connector conn1_flatShoe1 = GetPrimaryConnector(pt_flatShoe1.ConnectorManager);
Connector conn2_flatShoe1 = GetSecondaryConnector(pt_flatShoe1.ConnectorManager);
FabricationPart.PlaceAsTap(m_doc, conn1_flatShoe1, conn1_straight6, 1.25, Math.PI, 0);
// add a 16' 8 long tube
double length_tube2 = 16.0 + (8.0 / 12.0);
FabricationPart pt_tube2 = CreateStraightPart(bt_tube, 0, levelOne.Id, length_tube2);
Connector conn1_tube2 = GetPrimaryConnector(pt_tube2.ConnectorManager);
Connector conn2_tube2 = GetSecondaryConnector(pt_tube2.ConnectorManager);
SizeAlignCoupleConnect(conn1_tube2, conn2_flatShoe1, 0);
//add 3 hangers for tube2 , with specified button condition
for (int i = 0; i < 3; i++)
{
FabricationPart.CreateHanger(m_doc, bt_hangerRound, 1, pt_tube2.Id, conn1_tube2, (i + 1) * length_tube2 / 4, true);
}
// add a 90 degree bend
FabricationPart pt_90bend3 = FabricationPart.Create(m_doc, bt_90bend, 0, levelOne.Id);
Connector conn1_90bend3 = GetPrimaryConnector(pt_90bend3.ConnectorManager);
Connector conn2_90bend3 = GetSecondaryConnector(pt_90bend3.ConnectorManager);
SizeAlignCoupleConnect(conn1_90bend3, conn2_tube2, Math.PI);
// add a 10' long tube
FabricationPart pt_tube3 = CreateStraightPart(bt_tube, 0, levelOne.Id, 10.0);
Connector conn1_tube3 = GetPrimaryConnector(pt_tube3.ConnectorManager);
Connector conn2_tube3 = GetSecondaryConnector(pt_tube3.ConnectorManager);
SizeAlignCoupleConnect(conn1_tube3, conn2_90bend3, 0);
//add one hangers in middle of tube3, by default button condition
FabricationPart.CreateHanger(m_doc, bt_hangerRound, pt_tube3.Id, conn1_tube3, 5.0, true);
// add a 45 degree bend
FabricationPart pt_45Bend1 = FabricationPart.Create(m_doc, bt_45bend, 0, levelOne.Id);
Connector conn1_45Bend1 = GetPrimaryConnector(pt_45Bend1.ConnectorManager);
Connector conn2_45Bend1 = GetSecondaryConnector(pt_45Bend1.ConnectorManager);
SizeAlignCoupleConnect(conn1_45Bend1, conn2_tube3, Math.PI);
// add a 2' long tube
FabricationPart pt_tube4 = CreateStraightPart(bt_tube, 0, levelOne.Id, 2.0);
Connector conn1_tube4 = GetPrimaryConnector(pt_tube4.ConnectorManager);
Connector conn2_tube4 = GetSecondaryConnector(pt_tube4.ConnectorManager);
SizeAlignCoupleConnect(conn1_tube4, conn2_45Bend1, 0);
// add a 45 degree bend
FabricationPart pt_45Bend2 = FabricationPart.Create(m_doc, bt_45bend, 0, levelOne.Id);
Connector conn1_45Bend2 = GetPrimaryConnector(pt_45Bend2.ConnectorManager);
Connector conn2_45Bend2 = GetSecondaryConnector(pt_45Bend2.ConnectorManager);
SizeAlignCoupleConnect(conn1_45Bend2, conn2_tube4, Math.PI);
// add a 10' long tube
FabricationPart pt_tube5 = CreateStraightPart(bt_tube, 0, levelOne.Id, 10.0);
Connector conn1_tube5 = GetPrimaryConnector(pt_tube5.ConnectorManager);
Connector conn2_tube5 = GetSecondaryConnector(pt_tube5.ConnectorManager);
SizeAlignCoupleConnect(conn1_tube5, conn2_45Bend2, 0);
//add one hangers in middle of tube5, by default button condition
FabricationPart.CreateHanger(m_doc, bt_hangerRound, pt_tube5.Id, conn1_tube5, 5.0, true);
// now go back to the straight (pt_rectStraight5) with the tap and add a square bend
FabricationPart pt_sqBend4 = FabricationPart.Create(m_doc, bt_sqBend, 0, levelOne.Id);
Connector conn1_sqBend4 = GetPrimaryConnector(pt_sqBend4.ConnectorManager);
Connector conn2_sqBend4 = GetSecondaryConnector(pt_sqBend4.ConnectorManager);
SizeAlignCoupleConnect(conn1_sqBend4, conn2_straight6, Math.PI);
// add a 5' straight
FabricationPart pt_rectStraight7 = CreateStraightPart(bt_rectStraight, 0, levelOne.Id, 5.0);
Connector conn1_straight7 = GetPrimaryConnector(pt_rectStraight7.ConnectorManager);
Connector conn2_straight7 = GetSecondaryConnector(pt_rectStraight7.ConnectorManager);
SizeAlignCoupleConnect(conn1_straight7, conn2_sqBend4, 0);
//add a Bearer hanger in middle of straight7, by default condition
FabricationPart.CreateHanger(m_doc, bt_hangerBearer, pt_rectStraight7.Id, conn1_straight7, 2.5, true);
// add a modified tee
FabricationPart pt_rectTee1 = FabricationPart.Create(m_doc, bt_rectTee, 0, levelOne.Id);
// Set the size prior to connecting the part. Template parts with more than 2 connectors will disable editing of sizes once one of the connectors is connected to something.
SetDimValue(pt_rectTee1, "Right Width", 16.0 / 12.0); // set right width dimension to 16" (converted to feet)
SetDimValue(pt_rectTee1, "Btm Width", 20.0 / 12.0); // set bottom width dimension to 20" (converted to feet)
Connector conn1_rectTee1 = GetPrimaryConnector(pt_rectTee1.ConnectorManager);
Connector conn2_rectTee1 = GetSecondaryConnector(pt_rectTee1.ConnectorManager);
Connector conn3_rectTee1 = GetFirstNonPrimaryOrSecondaryConnector(pt_rectTee1.ConnectorManager);
SizeAlignCoupleConnect(conn3_rectTee1, conn2_straight7, Math.PI);
// add a square to round to the tee (conn2)
FabricationPart pt_sqToRound3 = FabricationPart.Create(m_doc, bt_sqToRound, 0, levelOne.Id);
Connector conn1_sqToRound3 = GetPrimaryConnector(pt_sqToRound3.ConnectorManager);
Connector conn2_sqToRound3 = GetSecondaryConnector(pt_sqToRound3.ConnectorManager);
SizeAlignCoupleConnect(conn1_sqToRound3, conn2_rectTee1, 0);
SetDimValue(pt_sqToRound3, "Length", 1.0 + (8.5 / 12.0)); // set length dimension to 1' 8 1/2" (converted to feet)
SetDimValue(pt_sqToRound3, "Diameter", 1.0); // set diameter dimension to 1'
// add a 22' 4" long tube
double length_tube6 = 22.0 + (4.0 / 12.0);
FabricationPart pt_tube6 = CreateStraightPart(bt_tube, 0, levelOne.Id, length_tube6);
Connector conn1_tube6 = GetPrimaryConnector(pt_tube6.ConnectorManager);
Connector conn2_tube6 = GetSecondaryConnector(pt_tube6.ConnectorManager);
SizeAlignCoupleConnect(conn1_tube6, conn2_sqToRound3, 0);
//add 3 hangers for tube6, by default condition
for (int i = 0; i < 3; i++)
{
FabricationPart.CreateHanger(m_doc, bt_hangerRound, 1, pt_tube6.Id, conn1_tube6, (i + 1) * length_tube6 / 4, true);
}
// add a reducer, reducing to 8"
FabricationPart pt_reducer1 = FabricationPart.Create(m_doc, bt_reducer, 0, levelOne.Id);
Connector conn1_reducer1 = GetPrimaryConnector(pt_reducer1.ConnectorManager);
Connector conn2_reducer1 = GetSecondaryConnector(pt_reducer1.ConnectorManager);
SizeAlignCoupleConnect(conn1_reducer1, conn2_tube6, 0);
Parameter prodEntry_reducer1 = pt_reducer1.get_Parameter(BuiltInParameter.FABRICATION_PRODUCT_ENTRY);
prodEntry_reducer1.Set("12''x8''");
// add a 10' long tube
FabricationPart pt_tube7 = CreateStraightPart(bt_tube, 0, levelOne.Id, 10.0);
Connector conn1_tube7 = GetPrimaryConnector(pt_tube7.ConnectorManager);
Connector conn2_tube7 = GetSecondaryConnector(pt_tube7.ConnectorManager);
SizeAlignCoupleConnect(conn1_tube7, conn2_reducer1, 0);
//add one hangers in middle of tube7, by default button condition
FabricationPart.CreateHanger(m_doc, bt_hangerRound, pt_tube7.Id, conn1_tube7, 5.0, true);
// add a curved boot tap to the 22' 4" tube (pt_tube6) 1' 2" from the end, reducing to 8"
FabricationPart pt_curvedBoot1 = FabricationPart.Create(m_doc, bt_curvedBoot, 0, levelOne.Id);
Parameter prodEntry_curvedBoot1 = pt_curvedBoot1.get_Parameter(BuiltInParameter.FABRICATION_PRODUCT_ENTRY);
prodEntry_curvedBoot1.Set("12''x8''");
Connector conn1_curvedBoot1 = GetPrimaryConnector(pt_curvedBoot1.ConnectorManager);
Connector conn2_curvedBoot1 = GetSecondaryConnector(pt_curvedBoot1.ConnectorManager);
FabricationPart.PlaceAsTap(m_doc, conn1_curvedBoot1, conn2_tube6, 1.0 + (2.0 / 12.0), Math.PI, Math.PI);
// add a 16' 8" long tube to the curved boot
double length_tube8 = 16.0 + (8.0 / 12.0);
FabricationPart pt_tube8 = CreateStraightPart(bt_tube, 0, levelOne.Id, length_tube8);
Connector conn1_tube8 = GetPrimaryConnector(pt_tube8.ConnectorManager);
Connector conn2_tube8 = GetSecondaryConnector(pt_tube8.ConnectorManager);
SizeAlignCoupleConnect(conn1_tube8, conn2_curvedBoot1, 0);
//add 3 hangers for tube8, with specified condition
for (int i = 0; i < 3; i++)
{
FabricationPart.CreateHanger(m_doc, bt_hangerRound, 0, pt_tube8.Id, conn1_tube8, (i + 1) * length_tube8 / 4, true);
}
// going back to the modified tee
// add a square to round to the tee (conn2)
FabricationPart pt_sqToRound4 = FabricationPart.Create(m_doc, bt_sqToRound, 0, levelOne.Id);
Connector conn1_sqToRound4 = GetPrimaryConnector(pt_sqToRound4.ConnectorManager);
Connector conn2_sqToRound4 = GetSecondaryConnector(pt_sqToRound4.ConnectorManager);
SizeAlignCoupleConnect(conn1_sqToRound4, conn1_rectTee1, 0);
SetDimValue(pt_sqToRound4, "Length", 1.0 + (8.5 / 12.0)); // set length dimension to 1' 8 1/2" (converted to feet)
SetDimValue(pt_sqToRound4, "Diameter", 1.0); // set diameter dimension to 1'
// add a 10' long tube
FabricationPart pt_tube9 = CreateStraightPart(bt_tube, 0, levelOne.Id, 10.0);
Connector conn1_tube9 = GetPrimaryConnector(pt_tube9.ConnectorManager);
Connector conn2_tube9 = GetSecondaryConnector(pt_tube9.ConnectorManager);
SizeAlignCoupleConnect(conn1_tube9, conn2_sqToRound4, 0);
//add one hangers in middle of tube9, by default button condition
FabricationPart.CreateHanger(m_doc, bt_hangerRound, pt_tube9.Id, conn1_tube9, 5.0, true);
// add a curved boot to the tube 3/4 way along, reducing to 10"
FabricationPart pt_curvedBoot2 = FabricationPart.Create(m_doc, bt_curvedBoot, 0, levelOne.Id);
Parameter prodEntry_curvedBoot2 = pt_curvedBoot2.get_Parameter(BuiltInParameter.FABRICATION_PRODUCT_ENTRY);
prodEntry_curvedBoot2.Set("12''x8''");
Connector conn1_curvedBoot2 = GetPrimaryConnector(pt_curvedBoot2.ConnectorManager);
Connector conn2_curvedBoot2 = GetSecondaryConnector(pt_curvedBoot2.ConnectorManager);
FabricationPart.PlaceAsTap(m_doc, conn1_curvedBoot2, conn1_tube9, 7.5, Math.PI, 0);
// add 8' 1" long tube to the curved boot
double length_tube10 = 8.0 + (1.0 / 12.0);
FabricationPart pt_tube10 = CreateStraightPart(bt_tube, 0, levelOne.Id, length_tube10);
Connector conn1_tube10 = GetPrimaryConnector(pt_tube10.ConnectorManager);
Connector conn2_tube10 = GetSecondaryConnector(pt_tube10.ConnectorManager);
SizeAlignCoupleConnect(conn1_tube10, conn2_curvedBoot2, 0);
//add one hangers in middle of tube10, by default button condition
FabricationPart.CreateHanger(m_doc, bt_hangerRound, pt_tube10.Id, conn1_tube10, length_tube10 / 2, true);
// add a 45 degree bend
FabricationPart pt_45Bend3 = FabricationPart.Create(m_doc, bt_45bend, 0, levelOne.Id);
Connector conn1_45Bend3 = GetPrimaryConnector(pt_45Bend3.ConnectorManager);
Connector conn2_45Bend3 = GetSecondaryConnector(pt_45Bend3.ConnectorManager);
SizeAlignCoupleConnect(conn1_45Bend3, conn2_tube10, 0);
// add 20' long tube
FabricationPart pt_tube11 = CreateStraightPart(bt_tube, 0, levelOne.Id, 20.0);
Connector conn1_tube11 = GetPrimaryConnector(pt_tube11.ConnectorManager);
Connector conn2_tube11 = GetSecondaryConnector(pt_tube11.ConnectorManager);
SizeAlignCoupleConnect(conn1_tube11, conn2_45Bend3, 0);
// add a 45 degree bend
FabricationPart pt_45Bend4 = FabricationPart.Create(m_doc, bt_45bend, 0, levelOne.Id);
Connector conn1_45Bend4 = GetPrimaryConnector(pt_45Bend4.ConnectorManager);
Connector conn2_45Bend4 = GetSecondaryConnector(pt_45Bend4.ConnectorManager);
SizeAlignCoupleConnect(conn1_45Bend4, conn2_tube11, 0);
// add 1' 8" long tube
FabricationPart pt_tube12 = CreateStraightPart(bt_tube, 0, levelOne.Id, 1.0 + (8.0 / 12.0));
Connector conn1_tube12 = GetPrimaryConnector(pt_tube12.ConnectorManager);
Connector conn2_tube12 = GetSecondaryConnector(pt_tube12.ConnectorManager);
SizeAlignCoupleConnect(conn1_tube12, conn2_45Bend4, 0);
// add a reducer (to 10") on the tube with the curved boot (pt_tube12)
FabricationPart pt_reducer2 = FabricationPart.Create(m_doc, bt_reducer, 0, levelOne.Id);
Connector conn1_reducer2 = GetPrimaryConnector(pt_reducer2.ConnectorManager);
Connector conn2_reducer2 = GetSecondaryConnector(pt_reducer2.ConnectorManager);
SizeAlignCoupleConnect(conn1_reducer2, conn2_tube9, 0);
Parameter prodEntry_reducer2 = pt_reducer2.get_Parameter(BuiltInParameter.FABRICATION_PRODUCT_ENTRY);
prodEntry_reducer2.Set("12''x10''");
// add a 10' long tube
FabricationPart pt_tube13 = CreateStraightPart(bt_tube, 0, levelOne.Id, 10.0);
Connector conn1_tube13 = GetPrimaryConnector(pt_tube13.ConnectorManager);
Connector conn2_tube13 = GetSecondaryConnector(pt_tube13.ConnectorManager);
SizeAlignCoupleConnect(conn1_tube13, conn2_reducer2, 0);
//add one hangers for tube13, by default button condition
FabricationPart.CreateHanger(m_doc, bt_hangerRound, pt_tube13.Id, conn1_tube13, 5.0, true);
// add a 90 bend, going 45 degrees down
FabricationPart pt_90bend4 = FabricationPart.Create(m_doc, bt_90bend, 0, levelOne.Id);
Connector conn1_90bend4 = GetPrimaryConnector(pt_90bend4.ConnectorManager);
Connector conn2_90bend4 = GetSecondaryConnector(pt_90bend4.ConnectorManager);
SizeAlignCoupleConnect(conn1_90bend4, conn2_tube13, 3.0 * Math.PI / 4.0);
// add a 1' 2.5" long tube
FabricationPart pt_tube14 = CreateStraightPart(bt_tube, 0, levelOne.Id, 1.0 + (2.5 / 12.0));
Connector conn1_tube14 = GetPrimaryConnector(pt_tube14.ConnectorManager);
Connector conn2_tube14 = GetSecondaryConnector(pt_tube14.ConnectorManager);
SizeAlignCoupleConnect(conn1_tube14, conn2_90bend4, 0);
// add a 45 bend
FabricationPart pt_45bend5 = FabricationPart.Create(m_doc, bt_45bend, 0, levelOne.Id);
Connector conn1_45bend5 = GetPrimaryConnector(pt_45bend5.ConnectorManager);
Connector conn2_45bend5 = GetSecondaryConnector(pt_45bend5.ConnectorManager);
SizeAlignCoupleConnect(conn1_45bend5, conn2_tube14, Math.PI / 2.0);
// add a 20' long tube
FabricationPart pt_tube15 = CreateStraightPart(bt_tube, 0, levelOne.Id, 20.0);
Connector conn1_tube15 = GetPrimaryConnector(pt_tube15.ConnectorManager);
Connector conn2_tube15 = GetSecondaryConnector(pt_tube15.ConnectorManager);
SizeAlignCoupleConnect(conn1_tube15, conn2_45bend5, 0);
//add 4 hangers for tube15, by default button condition
for (int i = 0; i < 4; i++)
{
FabricationPart.CreateHanger(m_doc, bt_hangerRound, pt_tube15.Id, conn1_tube15, (i + 1) * (20.0 / 5), true);
}
// now let's place a 6" valve by its insertion point in free space
FabricationPart pt_valve1 = FabricationPart.Create(m_doc, bt_valve, 1, levelOne.Id);
Parameter prodEntry_pt_valve1 = pt_valve1.get_Parameter(BuiltInParameter.FABRICATION_PRODUCT_ENTRY);
prodEntry_pt_valve1.Set("6''");
FabricationPart.AlignPartByInsertionPoint(m_doc, pt_valve1.Id, new XYZ(16, -10, 0), 0, 0, 0, FabricationPartJustification.Middle, null);
m_doc.Regenerate();
Connector conn2_valve1 = GetSecondaryConnector(pt_valve1.ConnectorManager);
// add 10' copper pipe to the valve
FabricationPart pt_pipe1 = CreateStraightPart(bt_groovedPipe, 0, levelOne.Id, 10.0);
Connector conn1_pipe1 = GetPrimaryConnector(pt_pipe1.ConnectorManager);
Connector conn2_pipe1 = GetSecondaryConnector(pt_pipe1.ConnectorManager);
SizeAlignSlopeJustifyCoupleConnect(conn1_pipe1, conn2_valve1, 0, 0, FabricationPartJustification.Middle);
// insert a valve into the middle of the copper pipe - it will size automatically
XYZ pipe1_pos = (conn1_pipe1.Origin + conn2_pipe1.Origin) / 2.0;
FabricationPart pt_valve2 = FabricationPart.Create(m_doc, bt_valve, 1, levelOne.Id);
FabricationPart.AlignPartByInsertionPointAndCutInToStraight(m_doc, pt_pipe1.Id, pt_valve2.Id, pipe1_pos, Math.PI / 2.0, 0, false);
m_doc.Regenerate();
// add a 90 elbow and slope it
FabricationPart pt_90elbow1 = FabricationPart.Create(m_doc, bt_90elbow, 0, levelOne.Id);
Connector conn1_90elbow1 = GetPrimaryConnector(pt_90elbow1.ConnectorManager);
Connector conn2_90elbow1 = GetSecondaryConnector(pt_90elbow1.ConnectorManager);
SizeAlignSlopeJustifyCoupleConnect(conn1_90elbow1, conn2_pipe1, Math.PI, 0.02, FabricationPartJustification.Middle);
// add a copper pipe
FabricationPart pt_pipe2 = CreateStraightPart(bt_groovedPipe, 0, levelOne.Id, 10.0);
Connector conn1_pipe2 = GetPrimaryConnector(pt_pipe2.ConnectorManager);
Connector conn2_pipe2 = GetSecondaryConnector(pt_pipe2.ConnectorManager);
SizeAlignSlopeJustifyCoupleConnect(conn1_pipe2, conn2_90elbow1, 0, 0, FabricationPartJustification.Middle);
tr.Commit();
}
}
catch (Exception ex)
{
message = ex.Message;
return Result.Failed;
}
return Result.Succeeded;
}
/// <summary>
/// Convenience method to get fabrication part's dimension value, specified by the dimension name.
/// </summary>
/// <param name="part">
/// The fabrication part to be queried.
/// </param>
/// <param name="dimName">
/// The name of the fabrication dimension.
/// </param>
/// <returns>
/// Returns the fabrication dimension value for the fabrication part, as specified by the dimension name.
/// </returns>
double GetDimValue(FabricationPart part, string dimName)
{
double value = 0;
if (part != null)
{
IList<FabricationDimensionDefinition> dims = part.GetDimensions();
foreach (FabricationDimensionDefinition def in dims)
{
if (def.Name.Equals(dimName))
{
value = part.GetDimensionValue(def);
break;
}
}
}
return value;
}
/// <summary>
/// Convenience method to set fabrication part's dimension value, specified by the dimension name.
/// </summary>
/// <param name="part">
/// The fabrication part.
/// </param>
/// <param name="dimName">
/// The name of the fabrication dimension.
/// </param>
/// <param name="dimValue">
/// The value of the fabrication dimension to set to.
/// </param>
/// <returns>
/// Returns the fabrication dimension value for the fabrication part, as specified by the dimension name.
/// </returns>
bool SetDimValue(FabricationPart part, string dimName, double dimValue)
{
IList<FabricationDimensionDefinition> dims = part.GetDimensions();
FabricationDimensionDefinition dim = null;
foreach (FabricationDimensionDefinition def in dims)
{
if (def.Name.Equals(dimName))
{
dim = def;
break;
}
}
if (dim == null)
return false;
part.SetDimensionValue(dim, dimValue);
m_doc.Regenerate();
return true;
}
/// <summary>
/// Convenience method to automatically size, align, couple (if needed) and connect two fabrication part
/// by the specified connectors.
/// </summary>
/// <param name="conn_from">
/// The connector to align by of the fabrication part to move.
/// </param>
/// <param name="conn_to">
/// The connector to align to.
/// </param>
/// <param name="rotation">
/// Rotation around the direction of connection - angle between width vectors in radians.
/// </param>
/// <returns>
/// Returns the fabrication dimension value for the fabrication part, as specified by the dimension name.
/// </returns>
void SizeAlignCoupleConnect(Connector conn_from, Connector conn_to, double rotation)
{
if (conn_from.Shape == ConnectorProfileType.Rectangular || conn_from.Shape == ConnectorProfileType.Oval)
{
conn_from.Height = conn_to.Height;
conn_from.Width = conn_to.Width;
}
else
{
conn_from.Radius = conn_to.Radius;
}
m_doc.Regenerate();
FabricationPart.AlignPartByConnectors(m_doc, conn_from, conn_to, rotation);
m_doc.Regenerate();
FabricationPart.ConnectAndCouple(m_doc, conn_from, conn_to);
m_doc.Regenerate();
}
/// <summary>
/// Convenience method to automatically size, align, slope, justification couple (if needed) and connect two fabrication parts
/// by the specified connectors.
/// </summary>
/// <param name="conn_from">
/// The connector to align by of the fabrication part to move.
/// </param>
/// <param name="conn_to">
/// The connector to align to.
/// </param>
/// <param name="rotation">
/// Rotation around the direction of connection - angle between width vectors in radians.
/// </param>
/// <param name="slope">
/// The slope value to flex to match if possible in fractional units (eg.1/50). Positive values are up, negative are down. Slopes can only be applied
/// to fittings, whilst straights will inherit the slope from the piece it is connecting to.
/// </param>
/// <param name="justification">
/// The justification to align eccentric parts.
/// </param>
/// <returns>
/// Returns the fabrication dimension value for the fabrication part, as specified by the dimension name.
/// </returns>
void SizeAlignSlopeJustifyCoupleConnect(Connector conn_from, Connector conn_to, double rotation, double slope, FabricationPartJustification justification)
{
if (conn_from.Shape == ConnectorProfileType.Rectangular || conn_from.Shape == ConnectorProfileType.Oval)
{
conn_from.Height = conn_to.Height;
conn_from.Width = conn_to.Width;
}
else
{
conn_from.Radius = conn_to.Radius;
}
m_doc.Regenerate();
FabricationPart.AlignPartByConnectorToConnector(m_doc, conn_from, conn_to, rotation, slope, justification);
m_doc.Regenerate();
FabricationPart.ConnectAndCouple(m_doc, conn_from, conn_to);
m_doc.Regenerate();
}
/// <summary>
/// Convenience method to locate a fabrication service button specified by palette and name.
/// </summary>
/// <param name="service">
/// The fabrication service.
/// </param>
/// <param name="palette">
/// The fabrication service palette index.
/// </param>
/// <param name="name">
/// The fabrication service button name.
/// </param>
/// <returns>
/// Returns the fabrication service button as specified by the fabrication service, palette and name.
/// </returns>
FabricationServiceButton locateButton(FabricationService service, int palette, string name)
{
FabricationServiceButton button = null;
if (service != null && palette >= 0 && palette < service.PaletteCount)
{
int buttonCount = service.GetButtonCount(palette);
for (int i = 0; button == null && i < buttonCount; i++)
{
FabricationServiceButton bt = service.GetButton(palette, i);
if (bt != null && bt.Name.Equals(name))
button = bt;
}
}
return button;
}
/// <summary>
/// Convenience method to create a straight fabrication part.
/// </summary>
/// <param name="fsb">
/// The FabricationServiceButton used to create the fabrication part from.
/// </param>
/// <param name="condition">
/// The condition index of the fabrication service button.
/// </param>
/// <param name="levelId">
/// The element identifier belonging to the level on which to create this fabrication part.
/// </param>
/// <param name="length">
/// The length, in feet, of the fabrication part to be created.
/// </param>
/// <returns>
/// Returns a straight fabrication part, as specified by the fabrication service button, condition, level id and length.
/// </returns>
FabricationPart CreateStraightPart(FabricationServiceButton fsb, int condition, ElementId levelId, double length)
{
FabricationPart straight = FabricationPart.Create(m_doc, fsb, condition, levelId);
Parameter length_option = straight.LookupParameter("Length Option");
length_option.Set("Value");
Parameter lengthParam = straight.LookupParameter("Length");
lengthParam.Set(length);
m_doc.Regenerate();
return straight;
}
/// <summary>
/// Convenience method to get the primary connector from the specified connector manager.
/// </summary>
/// <param name="cm">
/// The connector manager.
/// </param>
/// <returns>
/// Returns the primary connector from the connector manager.
/// </returns>
Connector GetPrimaryConnector(ConnectorManager cm)
{
foreach (Connector cn in cm.Connectors)
{
MEPConnectorInfo info = cn.GetMEPConnectorInfo();
if (info.IsPrimary)
return cn;
}
return null;
}
/// <summary>
/// Convenience method to get the secondary connector from the specified connector manager.
/// </summary>
/// <param name="cm">
/// The connector manager.
/// </param>
/// <returns>
/// Returns the secondary connector from the connector manager.
/// </returns>
Connector GetSecondaryConnector(ConnectorManager cm)
{
foreach (Connector cn in cm.Connectors)
{
MEPConnectorInfo info = cn.GetMEPConnectorInfo();
if (info.IsSecondary)
return cn;
}
return null;
}
/// <summary>
/// Convenience method to get the first non-primary and non-secondary connector from the specified connector manager.
/// </summary>
/// <param name="cm">
/// The connector manager.
/// </param>
/// <returns>
/// Returns the first non-primary and non-secondary connector from the connector manager.
/// </returns>
Connector GetFirstNonPrimaryOrSecondaryConnector(ConnectorManager cm)
{
foreach (Connector cn in cm.Connectors)
{
MEPConnectorInfo info = cn.GetMEPConnectorInfo();
if (!info.IsPrimary && !info.IsSecondary)
return cn;
}
return null;
}
/// <summary>
/// Convenience method to get all fabrication material identifiers from the
/// specified fabrication configuration.
/// </summary>
/// <param name="config">
/// The fabrication configuration.
/// </param>
/// <returns>
/// Returns a list of all the fabrication material identifiers for this
/// fabrication configuration.
/// </returns>
void GetMaterials(FabricationConfiguration config)
{
m_materialIds = config.GetAllMaterials(null);
m_materialGroups = new List<string>();
m_materialNames = new List<string>();
for (int i = 0; i < m_materialIds.Count; i++)
{
m_materialGroups.Add(config.GetMaterialGroup(m_materialIds[i]));
m_materialNames.Add(config.GetMaterialName(m_materialIds[i]));
}
}
/// <summary>
/// Convenience method to get all fabrication specification identifiers from the
/// specified fabrication configuration.
/// </summary>
/// <param name="config">
/// The fabrication configuration.
/// </param>
/// <returns>
/// Returns a list of all the fabrication specification identifiers for this
/// fabrication configuration.
/// </returns>
void GetSpecs(FabricationConfiguration config)
{
m_specIds = config.GetAllSpecifications(null);
m_specGroups = new List<string>();
m_specNames = new List<string>();
for (int i = 0; i < m_specIds.Count; i++)
{
m_specGroups.Add(config.GetSpecificationGroup(m_specIds[i]));
m_specNames.Add(config.GetSpecificationName(m_specIds[i]));
}
}
/// <summary>
/// Convenience method to get all fabrication insulation specification identifiers from the
/// specified fabrication configuration.
/// </summary>
/// <param name="config">
/// The fabrication configuration.
/// </param>
/// <returns>
/// Returns a list of all the fabrication insulation specification identifiers for this
/// fabrication configuration.
/// </returns>
void GetInsulationSpecs(FabricationConfiguration config)
{
m_insSpecIds = config.GetAllInsulationSpecifications(null);
m_insSpecGroups = new List<string>();
m_insSpecNames = new List<string>();
for (int i = 0; i < m_insSpecIds.Count; i++)
{
m_insSpecGroups.Add(config.GetInsulationSpecificationGroup(m_insSpecIds[i]));
m_insSpecNames.Add(config.GetInsulationSpecificationName(m_insSpecIds[i]));
}
}
/// <summary>
/// Convenience method to get all fabrication connector identifiers from the
/// specified fabrication configuration.
/// </summary>
/// <param name="config">
/// The fabrication configuration.
/// </param>
/// <returns>
/// Returns a list of all the fabrication connector identifiers for this
/// fabrication configuration.
/// </returns>
void GetFabricationConnectors(FabricationConfiguration config)
{
m_connIds = config.GetAllFabricationConnectorDefinitions(ConnectorDomainType.Undefined, ConnectorProfileType.Invalid);
m_connGroups = new List<string>();
m_connNames = new List<string>();
for (int i = 0; i < m_connIds.Count; i++)
{
m_connGroups.Add(config.GetFabricationConnectorGroup(m_connIds[i]));
m_connNames.Add(config.GetFabricationConnectorName(m_connIds[i]));
}
}
}
}
@@ -0,0 +1,108 @@
<?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>{806D4F74-F72D-40C2-BA7F-4DF99980D601}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Revit.SDK.Samples.FabricationPartLayout.CS</RootNamespace>
<AssemblyName>FabricationPartLayout</AssemblyName>
<StartupObject>
</StartupObject>
<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>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<DocumentationFile>bin\Debug\FabricationPartLayout.XML</DocumentationFile>
<PlatformTarget>x64</PlatformTarget>
</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>
<DocumentationFile>bin\Release\FabricationPartLayout.XML</DocumentationFile>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DocumentationFile>bin\x64\Debug\FabricationPartLayout.XML</DocumentationFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<DocumentationFile>bin\x64\Release\FabricationPartLayout.XML</DocumentationFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup>
<RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<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="ChangeService.cs" />
<Compile Include="ExportToMAJ.cs" />
<Compile Include="FabPartGeometry.cs" />
<Compile Include="ItemFile.cs" />
<Compile Include="SplitStraight.cs" />
<Compile Include="PartRenumber.cs" />
<Compile Include="HangerRods.cs" />
<Compile Include="PartInfo.cs" />
<Compile Include="ExportToPCF.cs" />
<Compile Include="CustomData.cs" />
<Compile Include="Ancillaries.cs" />
<Compile Include="ButtonPaletteExclusions.cs" />
<Compile Include="ConvertToFabrication.cs" />
<Compile Include="FabricationPartLayout.cs" />
<Compile Include="OptimizeStraights.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="StretchAndFit.cs" />
</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>
</Project>
@@ -0,0 +1,387 @@
//
// (C) Copyright 2003-2019 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB.Fabrication;
using System.Windows.Forms;
using Autodesk.Revit.UI.Selection;
namespace Revit.SDK.Samples.FabricationPartLayout.CS
{
#region Detach Rods
/// <summary>
/// Implements the Revit add-in interface IExternalCommand
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class DetachRods : 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 virtual Result Execute(ExternalCommandData commandData
, ref string message, ElementSet elements)
{
try
{
// check user selection
var uiDoc = commandData.Application.ActiveUIDocument;
var doc = uiDoc.Document;
Reference refObj = uiDoc.Selection.PickObject(ObjectType.Element, "Pick a fabrication part hanger to start.");
var part = doc.GetElement(refObj) as FabricationPart;
if (part == null || part.IsAHanger() == false)
{
message = "The selected element is not a fabrication part hanger.";
return Result.Failed;
}
var rodInfo = part.GetRodInfo();
using (var trans = new Transaction(doc, "Detach Rods"))
{
trans.Start();
rodInfo.CanRodsBeHosted = false;
trans.Commit();
}
message = "Detach successful";
return Result.Succeeded;
}
catch (Exception ex)
{
message = ex.Message;
return Result.Failed;
}
}
}
#endregion
#region Increase Rod Length (x2)
/// <summary>
/// Implements the Revit add-in interface IExternalCommand
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class DoubleRodLength : 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 virtual Result Execute(ExternalCommandData commandData
, ref string message, ElementSet elements)
{
try
{
// check user selection
var uiDoc = commandData.Application.ActiveUIDocument;
var doc = uiDoc.Document;
Reference refObj = uiDoc.Selection.PickObject(ObjectType.Element, "Pick a fabrication part hanger to start.");
var part = doc.GetElement(refObj) as FabricationPart;
if (part == null || part.IsAHanger() == false)
{
message = "The selected element is not a fabrication part hanger.";
return Result.Failed;
}
var rodInfo = part.GetRodInfo();
if (rodInfo.IsAttachedToStructure == true)
{
message = "The hanger rods must be detached from their host first";
return Result.Failed;
}
using (var trans = new Transaction(doc, "Double Rod Length"))
{
trans.Start();
for (int i = 0; i < rodInfo.RodCount; i++)
{
var originalLength = rodInfo.GetRodLength(i);
rodInfo.SetRodLength(i, originalLength * 2.0);
}
trans.Commit();
}
return Result.Succeeded;
}
catch (Exception ex)
{
message = ex.Message;
return Result.Failed;
}
}
}
#endregion
#region Decrease Rod Length (x2)
/// <summary>
/// Implements the Revit add-in interface IExternalCommand
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class HalveRodLength : 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 virtual Result Execute(ExternalCommandData commandData
, ref string message, ElementSet elements)
{
try
{
// check user selection
var uiDoc = commandData.Application.ActiveUIDocument;
var doc = uiDoc.Document;
Reference refObj = uiDoc.Selection.PickObject(ObjectType.Element, "Pick a fabrication part hanger to start.");
var part = doc.GetElement(refObj) as FabricationPart;
if (part == null || part.IsAHanger() == false)
{
message = "The selected element is not a fabrication part hanger.";
return Result.Failed;
}
var rodInfo = part.GetRodInfo();
if (rodInfo.IsAttachedToStructure == true)
{
message = "The hanger rods must be detached from their host first";
return Result.Failed;
}
using (var trans = new Transaction(doc, "Halve Rod Length"))
{
trans.Start();
for (int i = 0; i < rodInfo.RodCount; i++)
{
var originalLength = rodInfo.GetRodLength(i);
rodInfo.SetRodLength(i, originalLength / 2.0);
}
trans.Commit();
}
return Result.Succeeded;
}
catch (Exception ex)
{
message = ex.Message;
return Result.Failed;
}
}
}
#endregion
#region Increase Rod Strcuture Extension (by 1ft)
/// <summary>
/// Implements the Revit add-in interface IExternalCommand
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class IncreaseRodStructureExtension : 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 virtual Result Execute(ExternalCommandData commandData
, ref string message, ElementSet elements)
{
try
{
// check user selection
var uiDoc = commandData.Application.ActiveUIDocument;
var doc = uiDoc.Document;
Reference refObj = uiDoc.Selection.PickObject(ObjectType.Element, "Pick a fabrication part hanger to start.");
var part = doc.GetElement(refObj) as FabricationPart;
if (part == null || part.IsAHanger() == false)
{
message = "The selected element is not a fabrication part hanger.";
return Result.Failed;
}
var rodInfo = part.GetRodInfo();
if (rodInfo.IsAttachedToStructure == false)
{
message = "The hanger rods must be attached to structure.";
return Result.Failed;
}
using (var trans = new Transaction(doc, "Increase Rod Structure Extension"))
{
trans.Start();
for (int i = 0; i < rodInfo.RodCount; i++)
{
var originalExtension = rodInfo.GetRodStructureExtension(i);
rodInfo.SetRodStructureExtension(i, originalExtension + 1.0);
}
trans.Commit();
}
return Result.Succeeded;
}
catch (Exception ex)
{
message = ex.Message;
return Result.Failed;
}
}
}
#endregion
#region Decrease Rod Strcuture Extension (by 1ft)
/// <summary>
/// Implements the Revit add-in interface IExternalCommand
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class DecreaseRodStructureExtension : 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 virtual Result Execute(ExternalCommandData commandData
, ref string message, ElementSet elements)
{
try
{
// check user selection
var uiDoc = commandData.Application.ActiveUIDocument;
var doc = uiDoc.Document;
Reference refObj = uiDoc.Selection.PickObject(ObjectType.Element, "Pick a fabrication part hanger to start.");
var part = doc.GetElement(refObj) as FabricationPart;
if (part == null || part.IsAHanger() == false)
{
message = "The selected element is not a fabrication part hanger.";
return Result.Failed;
}
var rodInfo = part.GetRodInfo();
if (rodInfo.IsAttachedToStructure == false)
{
message = "The hanger rods must be attached to structure.";
return Result.Failed;
}
using (var trans = new Transaction(doc, "Increase Rod Structure Extension"))
{
trans.Start();
for (int i = 0; i < rodInfo.RodCount; i++)
{
var originalExtension = rodInfo.GetRodStructureExtension(i);
rodInfo.SetRodStructureExtension(i, originalExtension - 1.0);
}
trans.Commit();
}
return Result.Succeeded;
}
catch (Exception ex)
{
message = ex.Message;
return Result.Failed;
}
}
}
#endregion
}
@@ -0,0 +1,265 @@
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Revit.SDK.Samples.FabricationPartLayout.CS
{
/// <summary>
/// Implements the Revit add-in interface IExternalCommand
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class LoadAndPlaceNextItemFile : 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 virtual Result Execute(ExternalCommandData commandData
, ref string message, ElementSet elements)
{
try
{
var uiDoc = commandData.Application.ActiveUIDocument;
var doc = uiDoc.Document;
FilteredElementCollector cl = new FilteredElementCollector(doc);
cl.OfClass(typeof(Level));
IList<Element> levels = cl.ToElements();
Level levelOne = null;
foreach (Level level in levels)
{
if (level != null && level.Name.Equals("Level 1"))
{
levelOne = level;
break;
}
}
if (levelOne == null)
return Result.Failed;
using (var config = FabricationConfiguration.GetFabricationConfiguration(doc))
{
if (config == null)
{
message = "No fabrication configuration in use";
return Result.Failed;
}
using (var configInfo = config.GetFabricationConfigurationInfo())
{
using (var source = FabricationConfigurationInfo.FindSourceFabricationConfiguration(configInfo))
{
if (source == null)
{
message = "Source fabrication configuration not found";
return Result.Failed;
}
using (var trans = new Autodesk.Revit.DB.Transaction(doc, "Load And Place Next Item File"))
{
trans.Start();
// reload the configuration
config.ReloadConfiguration();
// get the item folders
var itemFolders = config.GetItemFolders();
// get the next unloaded item file from the item folders structure
var nextFile = GetNextUnloadedItemFile(itemFolders);
if (nextFile == null)
{
message = "Could not locate the next unloaded item file";
return Result.Failed;
}
var itemFilesToLoad = new List<FabricationItemFile>();
itemFilesToLoad.Add(nextFile);
// load the item file into the config
var failedItems = config.LoadItemFiles(itemFilesToLoad);
if (failedItems != null && failedItems.Count > 0)
{
message = "Could not load the item file: " + nextFile.Identifier;
return Result.Failed;
}
// create a part from the item file
using (var part = FabricationPart.Create(doc, nextFile, levelOne.Id))
{
doc.Regenerate();
var selectedElements = new List<ElementId>() { part.Id };
uiDoc.Selection.SetElementIds(selectedElements);
uiDoc.ShowElements(selectedElements);
trans.Commit();
}
}
}
}
}
return Result.Succeeded;
}
catch (Exception ex)
{
message = ex.Message;
return Result.Failed;
}
}
private FabricationItemFile GetNextUnloadedItemFile(IList<FabricationItemFolder> itemFolders)
{
if (itemFolders == null)
return null;
foreach (var folder in itemFolders)
{
var file = GetNextUnloadedItemFileRecursive(folder);
if (file != null)
return file;
}
return null;
}
private FabricationItemFile GetNextUnloadedItemFileRecursive(FabricationItemFolder folder)
{
if (folder == null)
return null;
var files = folder.GetItemFiles();
if (files != null && files.Count > 0)
{
foreach (var file in files)
{
if (file != null && file.IsLoaded() == false && file.IsValid() == true)
return file;
}
}
var subFolders = folder.GetSubFolders();
if (subFolders != null && subFolders.Count > 0)
{
foreach (var subFolder in subFolders)
{
var file = GetNextUnloadedItemFileRecursive(subFolder);
if (file != null)
return file;
}
}
return null;
}
}
/// <summary>
/// Implements the Revit add-in interface IExternalCommand
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class UnloadUnusedItemFiles : 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 virtual Result Execute(ExternalCommandData commandData
, ref string message, ElementSet elements)
{
try
{
var uiDoc = commandData.Application.ActiveUIDocument;
var doc = uiDoc.Document;
using (var config = FabricationConfiguration.GetFabricationConfiguration(doc))
{
if (config == null)
{
message = "No fabrication configuration in use";
return Result.Failed;
}
using (var trans = new Transaction(doc, "Unload unused item files"))
{
trans.Start();
config.ReloadConfiguration();
var loadedFiles = config.GetAllLoadedItemFiles();
var unusedFiles = loadedFiles.Where(x => x.IsUsed == false).ToList();
if (unusedFiles.Count == 0)
{
message = "No unuseed item files found";
return Result.Failed;
}
if (config.CanUnloadItemFiles(unusedFiles) == false)
{
message = "Cannot unload item files";
return Result.Failed;
}
config.UnloadItemFiles(unusedFiles);
trans.Commit();
var builder = new StringBuilder();
unusedFiles.ForEach(x => builder.AppendLine(System.IO.Path.GetFileNameWithoutExtension(x.Identifier)));
TaskDialog td = new TaskDialog("Unload Unused Item Files")
{
MainIcon = TaskDialogIcon.TaskDialogIconInformation,
TitleAutoPrefix = false,
MainInstruction = "The following item files were unloaded:",
MainContent = builder.ToString()
};
td.Show();
}
}
return Result.Succeeded;
}
catch (Exception ex)
{
message = ex.Message;
return Result.Failed;
}
}
}
}
@@ -0,0 +1,108 @@
//
// (C) Copyright 2003-2011 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.Linq;
using System.Text;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
namespace Revit.SDK.Samples.FabricationPartLayout.CS
{
/// <summary>
/// Implements the Revit add-in interface IExternalCommand
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class OptimizeStraights : 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 virtual Result Execute(ExternalCommandData commandData
, ref string message, ElementSet elements)
{
try
{
Document doc = commandData.Application.ActiveUIDocument.Document;
// check user selection
UIDocument uidoc = commandData.Application.ActiveUIDocument;
ICollection<ElementId> collection = uidoc.Selection.GetElementIds();
if (collection.Count > 0)
{
ISet<ElementId> selIds = new HashSet<ElementId>();
foreach (ElementId id in collection)
selIds.Add(id);
using (Transaction tr = new Transaction(doc, "Optimize Straights"))
{
tr.Start();
// optimize lengths method will take a set of elements and any fabrication straight parts
// within this set that have been optimized will be returned.
ISet<ElementId> affectedPartIds = FabricationPart.OptimizeLengths(doc, selIds);
if (affectedPartIds.Count == 0)
{
message = "No fabrication straight parts were optimized.";
return Result.Cancelled;
}
doc.Regenerate();
tr.Commit();
}
return Result.Succeeded;
}
else
{
// inform user they need to select at least one element
message = "Please select at least one element.";
}
return Result.Failed;
}
catch (Exception ex)
{
message = ex.Message;
return Result.Failed;
}
}
}
}
@@ -0,0 +1,160 @@
//
// (C) Copyright 2003-2019 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB.Fabrication;
using System.Windows.Forms;
using Autodesk.Revit.UI.Selection;
namespace Revit.SDK.Samples.FabricationPartLayout.CS
{
/// <summary>
/// Implements the Revit add-in interface IExternalCommand
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class PartInfo : 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 virtual Result Execute(ExternalCommandData commandData
, ref string message, ElementSet elements)
{
try
{
// check user selection
var uiDoc = commandData.Application.ActiveUIDocument;
var doc = uiDoc.Document;
Reference refObj = uiDoc.Selection.PickObject(ObjectType.Element, "Pick a fabrication part to start.");
var part = doc.GetElement(refObj) as FabricationPart;
if (part == null)
{
message = "The selected element is not a fabrication part.";
return Result.Failed;
}
var config = FabricationConfiguration.GetFabricationConfiguration(doc);
if (config == null)
{
message = "no valid fabrication configuration";
return Result.Failed;
}
var builder = new StringBuilder();
// alias
builder.AppendLine("Alias: " + part.Alias);
// cid
builder.AppendLine("CID: " + part.ItemCustomId.ToString());
// domain type
builder.AppendLine("Domain Type: " + part.DomainType.ToString());
// hanger rod kit
if (part.IsAHanger())
{
string rodKitName = "None";
var rodKit = part.HangerRodKit;
if (rodKit > 0)
rodKitName = config.GetAncillaryGroupName(part.HangerRodKit) + ": " + config.GetAncillaryName(part.HangerRodKit);
builder.AppendLine("Hanger Rod Kit: " + rodKitName);
}
// insulation specification
var insSpec = config.GetInsulationSpecificationGroup(part.InsulationSpecification)
+ ": " + config.GetInsulationSpecificationName(part.InsulationSpecification);
builder.AppendLine("Insulation Specification: " + insSpec);
// has no connections
builder.AppendLine("Has No Connections: " + part.HasNoConnections().ToString());
// item number
builder.AppendLine("Item Number: " + part.ItemNumber);
// material
var material = config.GetMaterialGroup(part.Material) + ": " + config.GetMaterialName(part.Material);
builder.AppendLine("Material: " + material);
// part guid
builder.AppendLine("Part Guid: " + part.PartGuid.ToString());
// part status
builder.AppendLine("Part Status: " + config.GetPartStatusDescription(part.PartStatus));
// product code
builder.AppendLine("Product Code: " + part.ProductCode);
// service
builder.AppendLine("Service Name: " + part.ServiceName);
// get the service type name
builder.AppendLine("Service Type: " + config.GetServiceTypeName(part.ServiceType));
// specification
var spec = config.GetSpecificationGroup(part.Specification) + ": " + config.GetSpecificationName(part.Specification);
builder.AppendLine("Specification: " + spec);
// centerline length
builder.AppendLine("Centerline Length: " + GetStringFromNumber(doc, part.CenterlineLength, SpecTypeId.Length));
TaskDialog.Show("Fabrication Part [" + part.Id.IntegerValue + "]", builder.ToString());
return Result.Succeeded;
}
catch (Exception ex)
{
message = ex.Message;
return Result.Failed;
}
}
private string GetStringFromNumber(Document doc, double number, ForgeTypeId specTypeId)
{
return UnitFormatUtils.Format(doc.GetUnits(), specTypeId, number, false);
}
}
}
@@ -0,0 +1,214 @@
//
// (C) Copyright 2003-2019 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB.Fabrication;
using System.Windows.Forms;
namespace Revit.SDK.Samples.FabricationPartLayout.CS
{
/// <summary>
/// Implements the Revit add-in interface IExternalCommand
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class PartRenumber : IExternalCommand
{
#region region Member Variables
private int m_ductNum = 1;
private int m_ductCouplingNum = 1;
private int m_pipeNum = 1;
private int m_pipeCouplingNum = 1;
private int m_hangerNum = 1;
private int m_otherNum = 1;
#endregion
/// <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 virtual Result Execute(ExternalCommandData commandData
, ref string message, ElementSet elements)
{
try
{
// check user selection
var uidoc = commandData.Application.ActiveUIDocument;
var doc = uidoc.Document;
var collection = uidoc.Selection.GetElementIds();
using (var trans = new Transaction(doc, "Part Renumber"))
{
trans.Start();
var fabParts = new List<FabricationPart>();
foreach (var elementId in collection)
{
var part = doc.GetElement(elementId) as FabricationPart;
if (part != null)
{
part.ItemNumber = string.Empty; // wipe the item number
fabParts.Add(part);
}
}
if (fabParts.Count == 0)
{
message = "Select at least one fabrication part";
return Result.Failed;
}
// ignore certain fields
var ignoreFields = new List<FabricationPartCompareType>();
ignoreFields.Add(FabricationPartCompareType.Notes);
ignoreFields.Add(FabricationPartCompareType.OrderNo);
ignoreFields.Add(FabricationPartCompareType.Service);
for (int i = 0; i < fabParts.Count; i++)
{
var part1 = fabParts[i];
if (string.IsNullOrWhiteSpace(part1.ItemNumber))
{
// part has not already been checked
if (IsADuct(part1))
{
if (IsACoupling(part1))
part1.ItemNumber = "DUCT COUPLING: " + m_ductCouplingNum++;
else
part1.ItemNumber = "DUCT: " + m_ductNum++;
}
else if (IsAPipe(part1))
{
if (IsACoupling(part1))
part1.ItemNumber = "PIPE COUPLING: " + m_pipeCouplingNum++;
else
part1.ItemNumber = "PIPE: " + m_pipeNum++;
}
else if (part1.IsAHanger())
part1.ItemNumber = "HANGER: " + m_hangerNum++;
else
part1.ItemNumber = "MISC: " + m_otherNum++;
}
for (int j = i + 1; j < fabParts.Count; j++)
{
var part2 = fabParts[j];
if (string.IsNullOrWhiteSpace(part2.ItemNumber))
{
// part2 has not been checked
if (part1.IsSameAs(part2, ignoreFields))
{
// items are the same, so give them the same item number
part2.ItemNumber = part1.ItemNumber;
}
}
}
}
trans.Commit();
}
TaskDialog td = new TaskDialog("Fabrication Part Renumber")
{
MainIcon = TaskDialogIcon.TaskDialogIconInformation,
TitleAutoPrefix = false,
MainInstruction = "Renumber was successful",
AllowCancellation = false,
CommonButtons = TaskDialogCommonButtons.Ok
};
td.Show();
return Result.Succeeded;
}
catch (Exception ex)
{
message = ex.Message;
return Result.Failed;
}
}
/// <summary>
/// Checks if the given part is fabrication ductwork.
/// </summary>
/// <param name="fabPart">The part to check.</param>
/// <returns>True if the part is fabrication ductwork.</returns>
private bool IsADuct(FabricationPart fabPart)
{
return (fabPart != null && (fabPart.Category.Id.IntegerValue == (int)BuiltInCategory.OST_FabricationDuctwork));
}
/// <summary>
/// Checks if the part is fabrication pipework.
/// </summary>
/// <param name="fabPart">The part to check.</param>
/// <returns>True if the part is fabrication pipework.</returns>
private bool IsAPipe(FabricationPart fabPart)
{
return (fabPart != null && (fabPart.Category.Id.IntegerValue == (int)BuiltInCategory.OST_FabricationPipework));
}
/// <summary>
/// Checks if the part is a coupling.
/// The CID's (the fabrication part item customer Id) that are recognized internally as couplings are:
/// CID 522, 1112 - Round Ductwork
/// CID 1522 - Oval Ductwork
/// CID 4522 - Rectangular Ductwork
/// CID 2522 - Pipe Work
/// CID 3522 - Electrical
/// </summary>
/// <param name="fabPart">The part to check.</param>
/// <returns>True if the part is a coupling.</returns>
private bool IsACoupling(FabricationPart fabPart)
{
if (fabPart != null)
{
int CID = fabPart.ItemCustomId;
if (CID == 522 || CID == 1522 || CID == 2522 || CID == 3522 || CID == 1112)
{
return true;
}
}
return false;
}
}
}
@@ -0,0 +1,55 @@
//
// (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("FabricationPartLayout")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Autodesk, Inc.")]
[assembly: AssemblyProduct("FabricationPartLayout")]
[assembly: AssemblyCopyright("Copyright © Autodesk, Inc. 2014")]
[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("2b22e4f2-1d70-4b55-b92f-46e3d84cf7f4")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
@@ -0,0 +1,336 @@
{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang2057\deflangfe2057{\fonttbl{\f0\fswiss\fprq2\fcharset0 Arial;}{\f1\froman\fprq2\fcharset0 Times New Roman;}{\f2\fnil\fcharset2 Symbol;}}
{\colortbl ;\red0\green0\blue255;}
{\*\generator Riched20 10.0.14393}{\*\mmathPr\mnaryLim0\mdispDef1\mwrapIndent1440 }\viewkind4\uc1
\pard\nowidctlpar\b\f0\fs20 Application:\b0 FabricationPartLayout\line\b Revit Platform:\b0 MEP\line\b Revit Version:\b0 2017.0\line\b First Released For:\b0 2016.0\line\b Programming Language:\b0 C#\line\b Skill Level:\b0 Medium\line\b Category:\b0 MEP\line\b Type:\b0 ExternalCommand\line\line\b Subject:\b0 Fabrication Part\line\b Summary:\b0 \line\kerning2 This sample shows how to use the Fabrication Part API to create a sample layout and make modifications to fabrication data in the model. This includes:\par
\pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\nowidctlpar\fi-360\li720 rectangular and round ductwork\par
{\pntext\f2\'B7\tab}tap placement\par
{\pntext\f2\'B7\tab}rotations\par
{\pntext\f2\'B7\tab}straight optimizations\par
{\pntext\f2\'B7\tab}connections to a generic Revit family instance\par
{\pntext\f2\'B7\tab}stretch fabrication part fitting to a target element\par
{\pntext\f2\'B7\tab}converting design elements into fabrication parts\par
{\pntext\f2\'B7\tab}renumbering the straight/coupling fabrication parts\par
{\pntext\f2\'B7\tab}loading and unloading of item files\par
{\pntext\f2\'B7\tab}exporting fabrication parts to PCF and MAJ\par
{\pntext\f2\'B7\tab}accessing fabrication part mesh geometry.\par
\pard\nowidctlpar\kerning0\f1\par
\b\f0 Classes:\b0 \par
\pard\nowidctlpar\fi180\li180 Autodesk.Revit.DB.Connector\par
Autodesk.Revit.DB.ConnectorSet\par
Autodesk.Revit.DB.Document\par
Autodesk.Revit.DB.ElementId\par
Autodesk.Revit.DB.FabricationAncillaryUsage\par
Autodesk.Revit.DB.FabricationConfiguration\par
Autodesk.Revit.DB.FabricationDimensionDefinition\par
Autodesk.Revit.DB.FabricationItemFile\par
Autodesk.Revit.DB.FabricationItemFolder\par
Autodesk.Revit.DB.FabricationRodInfo\par
Autodesk.Revit.DB.FabricationPart\par
Autodesk.Revit.DB.FabricationService\par
Autodesk.Revit.DB.FabricationServiceButton\par
Autodesk.Revit.DB.FamilyInstance\par
Autodesk.Revit.DB.Level\par
Autodesk.Revit.DB.MEPConnectorInfo\par
Autodesk.Revit.DB.Parameter\par
Autodesk.Revit.DB.Fabrication.CustomDataType\par
Autodesk.Revit.DB.Fabrication.DesignToFabricationConverter\par
Autodesk.Revit.DB.Fabrication.DesignToFabricationConverterResult\par
Autodesk.Revit.DB.Fabrication.FabricationAncillaryType\par
Autodesk.Revit.DB.Fabrication.FabricationAncillaryUsageType\par
Autodesk.Revit.DB.Fabrication.FabricationPartCompareType\par
Autodesk.Revit.DB.Fabrication.FabricationPartFitResult\par
Autodesk.Revit.DB.Fabrication.FabricationPartRouteEnd\par
Autodesk.Revit.DB.Fabrication.FabricationUtils\par
Autodesk.Revit.UI.IExternalCommand\line\par
\par
\cf1\par
\cf0\f1\lang1036\par
\pard\nowidctlpar\b\f0\lang1033 Project Files:\b0 \i\par
\i0 FabricationPartLayout.cs\par
\pard\nowidctlpar\li360 It contains the class FabricationPartLayout which inherits from interface IExternalCommand and implements the Execute method. This class shows the user how to create a sample layout containing fabrication parts.\par
\pard\nowidctlpar\par
OptimizeStraights.cs\par
\pard\nowidctlpar\li360 It contains the class OptimizeStraights which inherits from interface IExternalCommand and implements the Execute method. This class shows the user how to use the Optimize Lengths method based on a user selection.\par
\pard\nowidctlpar\par
StretchAndFit.cs\par
\pard\nowidctlpar\li360 It contains the class StretchAndFit which inherits from interface IExternalCommand and implements the Execute method. This class shows the user how to use the StretchAndFit method based on a user selection.\par
\par
\pard\nowidctlpar ConvertToFabrication.cs\par
\pard\nowidctlpar\li360 It contains the class ConvertToFabrication which inherits from interface IExternalCommand and implements the Execute method. This class shows the user how to use the DesignToFabrication method based on a user selection.\par
\par
\pard\nowidctlpar PartRenumber.cs\par
\pard\nowidctlpar\li360 It contains the class PartRenumber which inherits from interface IExternalCommand and implements the Execute method. This class shows the user how to use the FabricationPart.ItemNumber and renumber a selection of parts, and using the Fabrication.IsSameAs method.\par
\par
\pard\nowidctlpar ButtonPaletteExclusions.cs\par
\pard\nowidctlpar\li360 It contains the class ButtonPaletteExclusions which inherits from interface IExternalCommand and implements the Execute method. This class shows the user how to override the default fabrication service palette and button exclusions for routing operations.\par
\par
\pard\nowidctlpar Ancillaries.cs\par
\pard\nowidctlpar\li360 It contains the class Ancillaries which inherits from interface IExternalCommand and implements the Execute method. This class shows the user how to obtain the ancillary information for a selected fabrication part.\par
\par
\pard\nowidctlpar CustomData.cs\par
\pard\nowidctlpar\li360 It contains the classes GetCustomData and SetCustomData which inherit from the interface IExternalCommand and implements the Execute method. This class shows the user how to obtain the ancillary information for a selected fabrication part. The GetCustomData class shows a user how to obtain fabrication custom data on a fabrication part, whilst the SetCustomData class shows a user how to set fabrication custom data.\par
\par
\pard\nowidctlpar ExportToPCF.cs\par
\pard\nowidctlpar\li360 It contains the class ExportToPCF which inherits from interface IExternalCommand and implements the Execute method. This class shows the user how to export a selection of fabrication parts to a PCF file.\par
\par
\pard\nowidctlpar FabPartGeometry.cs\par
\pard\nowidctlpar\li360 It contains the class FabPartGeometry which inherits from interface IExternalCommand and implements the Execute method. This class shows the user how to access fabrication part mesh geometry.\par
\par
\pard\nowidctlpar PartInfo.cs\par
\pard\nowidctlpar\li360 It contains the class PartInfo which inherits from interface IExternalCommand and implements the Execute method. This class shows the user how to get a variety of fabrication part properties.\par
\par
\pard\nowidctlpar HangerRods.cs\par
\pard\nowidctlpar\li360 It contains the classes DetachRods, DoubleRodLength, HalveRodLength, IncreaseRodStructureExtension and DecreaseRodStructureExtension which inherit from the interface IExternalCommand and implements the Execute method. These classes show a user how to detach hanger rods from their hosted structure, how to change the size of the rod lengths and also the size of the rod structure extensions.\par
\par
\pard\nowidctlpar SplitStraight.cs\par
\pard\nowidctlpar\li360 It contains the class SplitStraight which inherits from interface IExternalCommand and implements the Execute method. This class shows the user how to split a straight into two segments.\par
\par
\pard\nowidctlpar ItemFile.cs\par
It contains the classes LoadAndPlaceNextItemFile and UnloadUnusedItemFiles which inherit from the interface IExternalCommand and implements the Execute command. These classes show a user how to load and unload fabrication item files from within the configuration\rquote s item folders structure.\par
\par
SaveAsFabricationJob.cs\par
It contains the class ExportToMAJ which inherits from interface IExternalCommand and implements the Execute method. This class shows the user how to export a selection of fabrication parts to a MAJ file.\par
\par
\pard\nowidctlpar\li360\par
\pard\nowidctlpar\b Description:\b0 \par
This sample provides the following functionalities.\par
\pard\nowidctlpar\fi-360\li360\tx360 -\tab Creates a sample layout from fabrication parts\par
-\tab Access fabrication configuration information\par
-\tab Connects fabrication taps to fabrication straight parts\par
-\tab Rotates fabrication parts about its connected end\par
-\tab Modify specification\par
-\tab Modify insulation specification\par
- \tab Modify fabrication material\par
-\tab Modify fabrication connector\par
-\tab Place fabrication taps on fabrication straight parts\par
- \tab Place fabrication hangers on fabrication straight parts\par
-\tab Optimize the lengths of fabrication straight parts based on user selection\par
-\tab Stretch and fit a fabrication part to a target connector.\par
-\tab Convert design elements into fabrication parts\par
-\tab Renumber a selection of fabrication parts\par
-\tab View ancillary data\par
-\tab Set service palette and button exclusions\par
-\tab View and set part custom data\par
-\tab Export a selection of fabrication parts to a PCF file\par
-\tab View fabrication part data\par
-\tab Adjust hanger rod lengths, structural extensions and detach from their structural hosts\par
-\tab Split straights into two equal segments\par
-\tab Load and place additional parts\par
-\tab Unload unused additional parts\par
-\tab Export a selection of fabrication parts to a MAJ file\par
-\tab Access fabrication part mesh geometry.\line\par
\pard\nowidctlpar\b Instructions:\cf1\b0 \f1\par
\cf0\f0 Open Revit application.\par
\pard\nowidctlpar\fi-360\li360\tx360 1.\tab Fabrication Part Layout\par
\pard\nowidctlpar\li765 a. Load FabricationPartLayout.rvt\par
b. Execute the command.\par
Expected result: Draws a sample layout containing fabrication parts connected to the existing Revit AHU instance.\par
\par
\pard\nowidctlpar\fi-360\li360\tx360 2.\tab Optimize Straights\par
\pard\nowidctlpar\fi-360\li1080\tx1080 a.\tab Load FabricationPartLayout.rvt or add some fabrication part straights.\par
\pard\nowidctlpar\fi-360\li1080 b.\tab Make a selection of the fabrication parts, making sure to select some of the longer fabrication part straights.\par
c.\tab Execute the command\par
\par
\pard\nowidctlpar\li720 Expected result: Fabrication part lengths longer than the standard length will be optimized into smaller straight parts.\par
\pard\nowidctlpar\li765\par
\par
\pard\nowidctlpar\fi-360\li360\tx360 3.\tab Stretch and Fit\par
\pard\nowidctlpar\fi-360\li1080\tx1080 a.\tab Load StretchAndFit.rvt.\par
\pard\nowidctlpar\fi-360\li1080 b.\tab Select the two radius bends in the model.\par
c.\tab Execute the command\par
\par
\pard\nowidctlpar\li720 Expected result: The radius bend should stretch and fit and connect to the selected straight.\par
\pard\nowidctlpar\par
\pard\nowidctlpar\fi-360\li360\tx360 4. \tab Convert To Fabrication\par
\pard\nowidctlpar\fi-360\li1080\tx1080 a.\tab ConvertToFabrication.rvt.\par
\pard\nowidctlpar\fi-360\li1080 b.\tab Select the duct layout\par
c.\tab Execute the command\par
\par
\pard\nowidctlpar\li720 Expected result: The duct layout should convert to fabrication parts.\par
\pard\nowidctlpar\par
\par
5. Part Renumber\par
\tab a. Make a selection of fabrication parts\par
\tab b. Execute the command\par
\tab\par
\pard\nowidctlpar\li720 Expected result: The fabrication parts Item Number property should be filled in and all parts that are the same have the same number. The fields ignored are based on ignoring the part\rquote s notes, order number and service.\par
\pard\nowidctlpar\par
6. Button and Palette Exclusions\par
\tab a. Load ButtonPaletteExclusions.rvt\par
\tab b. Execute the command\par
\par
\pard\nowidctlpar\li720 Expected result: The Square Bend button is excluded and the Round Bought Out service palette is excluded.\par
\pard\nowidctlpar\par
7. Ancillaries\par
\tab a. Execute the command\par
\tab b. Select a fabrication part\par
\par
\pard\nowidctlpar\li720 Expected result: A dialog should be presented with the ancillary information for the selected fabrication part.\par
\pard\nowidctlpar\par
8. Get Custom Data\par
\tab a. Load CustomData.rvt\par
\tab b. Execute the command\par
\tab c. Select a fabrication part\par
\par
\pard\nowidctlpar\li720 Expected result: A dialog should be presented with the custom data information for the selected fabrication part.\par
\pard\nowidctlpar\par
9. Set Custom Data\par
\tab a. Load CustomData.rvt\par
\tab b. Execute the command\par
\tab c. Select a fabrication part\par
\par
\pard\nowidctlpar\li720 Expected result: A dialog should be presented with the custom data information for the selected fabrication part, detailing the before and after values.\par
\pard\nowidctlpar\par
\par
10. Export to PCF\par
\tab a. Select some fabrication parts\par
\tab b. Execute the command\par
\par
\tab Expected result: A PCF file will be created at the specified location.\par
\par
11. Display Part Info\par
\tab a. Execute the command\par
\tab b. Select a fabrication part\par
\par
\tab Expected result: A dialog should be presented with fabrication part information.\par
\par
12. Detach Hanger Rods\par
\tab a. Load HangerRods.rvt\par
\tab b. Execute the command\par
\tab c. Select a fabrication part hanger\par
\par
\tab Expected result: The hanger rods should no longer be hosted by their structural host.\par
\par
13. Double Rod Lengths\par
\tab a. Load HangerRods.rvt\par
\tab b. Execute the command\par
\pard\nowidctlpar\li720 c. Select a fabrication part hanger that is not attached to structure. Use the Detach Hanger Rods command first, if necessary\par
\pard\nowidctlpar\par
\tab Expected result: The hanger rod lengths should double in size.\par
\par
14. Halve Rod Lengths\par
\tab a. Load HangerRods.rvt\par
\pard\nowidctlpar\fi720 b. Execute the command\par
\pard\nowidctlpar\li720 c. Select a fabrication part hanger that is not attached to structure. Use the Detach Hanger Rods command first, if necessary\par
\par
Expected result: The hanger rod lengths should halve in size.\par
\pard\nowidctlpar\par
15. Increase Rod Structure Extension\par
\tab a. Load HangerRods.rvt\par
\tab b. Execute the command\par
\tab c. Select a fabrication part hanger that is attached to structure. \par
\par
\pard\nowidctlpar\li720 Expected result: The hanger rod lengths will increase by 1 foot in length and are still attached to structure.\par
\pard\nowidctlpar\par
16. Decrease Rod Structure Extension\par
\tab a. Load HangerRods.rvt\par
\tab b. Execute the command\par
\tab c. Select a fabrication part hanger that is attached to structure. \par
\par
\pard\nowidctlpar\li720 Expected result: The hanger rod lengths will decrease by 1 foot in length and are still attached to structure.\par
\pard\nowidctlpar\par
17. Split Straight\par
\tab a. Execute the command\par
\tab b. Select a fabrication part straight segment\par
\par
\tab Expected result: The straight will split into two equal segments. \par
18. Load and Place Next Item File\par
\tab a. Load a project with a valid fabrication configuration that you have access to the source.\par
\tab b. Execute the command.\par
\par
\pard\nowidctlpar\li720 Expected result: The first item file that has not been previously loaded will be loaded into the configuration. A new fabrication part will be created from the loaded item file, placed and selected into the model.\par
\pard\nowidctlpar\par
19. Unload Unused Item Files\par
\pard\nowidctlpar\li720 a. Load a project that has item files that have been loaded into the configuration but have not been used.\par
b. Execute the command.\par
\par
Expected result: The unused loaded item files will be unloaded from the configuration.\par
\pard\nowidctlpar\par
20. Export to MAJ\par
\tab a. Make a selection of fabrication parts.\par
\tab b. Execute the command\par
\par
\tab Expected result: A MAJ file will be created at the specified location. \par
\par
21. Access Fabrication Part Geometry\par
\tab a. Select some fabrication parts\par
\tab b. Execute the command\par
\par
\tab Expected result: Mesh triangle face geometry will be exported to CSV files.\par
\par
}
@@ -0,0 +1,125 @@
//
// (C) Copyright 2003-2019 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB.Fabrication;
using System.Windows.Forms;
using Autodesk.Revit.UI.Selection;
namespace Revit.SDK.Samples.FabricationPartLayout.CS
{
/// <summary>
/// Implements the Revit add-in interface IExternalCommand
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class SplitStraight : 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 virtual Result Execute(ExternalCommandData commandData
, ref string message, ElementSet elements)
{
try
{
// check user selection
var uiDoc = commandData.Application.ActiveUIDocument;
var doc = uiDoc.Document;
Reference refObj = uiDoc.Selection.PickObject(ObjectType.Element, "Pick a fabrication part straight to start.");
var part = doc.GetElement(refObj) as FabricationPart;
if (part == null || part.IsAStraight() == false)
{
message = "The selected element is not a fabrication part straight.";
return Result.Failed;
}
// get the 2 end connectors
var connectors = new List<Connector>();
foreach (Connector c in part.ConnectorManager.Connectors)
{
if (c.ConnectorType == ConnectorType.End)
connectors.Add(c);
}
if (connectors.Count != 2)
{
message = "There are not 2 end connectors on this straight.";
return Result.Failed;
}
var conn1 = connectors[0];
var conn2 = connectors[1];
var x = (conn1.Origin.X + conn2.Origin.X) / 2.0;
var y = (conn1.Origin.Y + conn2.Origin.Y) / 2.0;
var z = (conn1.Origin.Z + conn2.Origin.Z) / 2.0;
var midpoint = new XYZ(x, y, z);
if (part.CanSplitStraight(midpoint) == false)
{
message = "straight cannot be split at its mid-point";
return Result.Failed;
}
using (var trans = new Transaction(doc, "split straight"))
{
trans.Start();
part.SplitStraight(midpoint);
trans.Commit();
}
return Result.Succeeded;
}
catch (Exception ex)
{
message = ex.Message;
return Result.Failed;
}
}
}
}
@@ -0,0 +1,172 @@
//
// (C) Copyright 2003-2011 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.Linq;
using System.Text;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB.Fabrication;
namespace Revit.SDK.Samples.FabricationPartLayout.CS
{
/// <summary>
/// Implements the Revit add-in interface IExternalCommand
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class StretchAndFit : 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 virtual Result Execute(ExternalCommandData commandData
, ref string message, ElementSet elements)
{
try
{
Document doc = commandData.Application.ActiveUIDocument.Document;
// check user selection
UIDocument uidoc = commandData.Application.ActiveUIDocument;
ICollection<ElementId> collection = uidoc.Selection.GetElementIds();
if (collection.Count > 0)
{
List<ElementId> selIds = new List<ElementId>();
foreach (ElementId id in collection)
selIds.Add(id);
if (selIds.Count != 2)
{
message = "Select a fabrication part to stretch and fit from and an element to connect to.";
return Result.Cancelled;
}
Connector connFrom = GetValidConnectorToStretchAndFitFrom(doc, selIds.ElementAt(0));
Connector connTo = GetValidConnectorToStretchAndFitTo(doc, selIds.ElementAt(1));
FabricationPartRouteEnd toEnd = FabricationPartRouteEnd.CreateFromConnector(connTo);
if (connFrom == null || connTo == null)
{
message = "Invalid fabrication parts to stretch and fit";
return Result.Cancelled;
}
using (Transaction tr = new Transaction(doc, "Stretch and Fit"))
{
tr.Start();
ISet<ElementId> newPartIds;
FabricationPartFitResult result = FabricationPart.StretchAndFit(doc, connFrom, toEnd, out newPartIds);
if (result != FabricationPartFitResult.Success)
{
message = result.ToString();
return Result.Failed;
}
doc.Regenerate();
tr.Commit();
}
return Result.Succeeded;
}
else
{
// inform user they need to select at least one element
message = "Select a fabrication part to stretch and fit from and an element to connect to.";
}
return Result.Failed;
}
catch (Exception ex)
{
message = ex.Message;
return Result.Failed;
}
}
private Connector GetValidConnectorToStretchAndFitFrom(Document doc, ElementId elementId)
{
// must be a fabrication part
FabricationPart part = doc.GetElement(elementId) as FabricationPart;
if (part == null)
return null;
// must not be a straight, hanger or tap
if (part.IsAStraight() || part.IsATap() || part.IsAHanger())
return null;
// part must be connected at one end and have one unoccupied connector
int numUnused = part.ConnectorManager.UnusedConnectors.Size;
int numConns = part.ConnectorManager.Connectors.Size;
if (numConns - numUnused != 1)
return null;
foreach (Connector conn in part.ConnectorManager.UnusedConnectors)
{
// return the first unoccupied connector
return conn;
}
return null;
}
private Connector GetValidConnectorToStretchAndFitTo(Document doc, ElementId elementId)
{
// connect to another fabrication part - will work also with families.
FabricationPart part = doc.GetElement(elementId) as FabricationPart;
if (part == null)
return null;
// must not be a fabrication part hanger
if (part.IsAHanger())
return null;
foreach (Connector conn in part.ConnectorManager.UnusedConnectors)
{
// return the first unoccupied connector
return conn;
}
return null;
}
}
}