mirror of
https://github.com/jeremytammik/RevitSdkSamples.git
synced 2026-08-30 08:32:50 +00:00
added Revit 2022 SDK minus except *rvt and *rfa
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RevitAddIns>
|
||||
<AddIn Type="Command">
|
||||
<Assembly>AvoidObstruction.dll</Assembly>
|
||||
<ClientId>e2d9f6bb-12cd-49fd-a9de-883f86c785d8</ClientId>
|
||||
<FullClassName>Revit.SDK.Samples.AvoidObstruction.CS.Command</FullClassName>
|
||||
<Text>AvoidObstruction</Text>
|
||||
<Description>Resolve the obstructions of pipe with pipe, pipe with beam and pipe with duct.</Description>
|
||||
<VisibilityMode>AlwaysVisible</VisibilityMode>
|
||||
<VendorId>ADSK</VendorId>
|
||||
<VendorDescription>Autodesk, www.autodesk.com</VendorDescription>
|
||||
</AddIn>
|
||||
</RevitAddIns>
|
||||
@@ -0,0 +1,75 @@
|
||||
<?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>
|
||||
<ProjectGuid>{07E03997-2E23-4CA5-9EF1-1EE7887FFA24}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<NoStandardLibraries>false</NoStandardLibraries>
|
||||
<AssemblyName>AvoidObstruction</AssemblyName>
|
||||
<RootNamespace>AvoidObstruction</RootNamespace>
|
||||
<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>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Command.cs" />
|
||||
<Compile Include="Detector.cs" />
|
||||
<Compile Include="Resolver.cs" />
|
||||
<Compile Include="Section.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="ReadMe_AvoidObstruction.rtf" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(SolutionDir)VSProps\SDKSamples.targets" />
|
||||
<ProjectExtensions>
|
||||
<VisualStudio AllowExistingFolder="true" />
|
||||
</ProjectExtensions>
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>set FILEFORSAMPLEREG="$(SolutionDir)..\..\..\..\Regression\API\SDKSamples\UpdateSampleDllForRegression.pl"
|
||||
if exist %25FILEFORSAMPLEREG%25 perl %25FILEFORSAMPLEREG%25 $(ProjectExt) "$(ProjectPath)" "$(TargetPath)" "$(SolutionDir)"</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// (C) Copyright 2003-2019 by Autodesk, Inc.
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software in
|
||||
// object code form for any purpose and without fee is hereby granted,
|
||||
// provided that the above copyright notice appears in all copies and
|
||||
// that both that copyright notice and the limited warranty and
|
||||
// restricted rights notice below appear in all supporting
|
||||
// documentation.
|
||||
//
|
||||
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
|
||||
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
|
||||
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
|
||||
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
|
||||
// UNINTERRUPTED OR ERROR FREE.
|
||||
//
|
||||
// Use, duplication, or disclosure by the U.S. Government is subject to
|
||||
// restrictions set forth in FAR 52.227-19 (Commercial Computer
|
||||
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
|
||||
// (Rights in Technical Data and Computer Software), as applicable.
|
||||
//
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Autodesk.Revit;
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.UI;
|
||||
|
||||
namespace Revit.SDK.Samples.AvoidObstruction.CS
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements interface IExternalCommand of Revit API.
|
||||
/// </summary>
|
||||
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
|
||||
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
|
||||
[Autodesk.Revit.Attributes.Journaling(Autodesk.Revit.Attributes.JournalingMode.NoCommandData)]
|
||||
public class Command : IExternalCommand
|
||||
{
|
||||
#region IExternalCommand Members
|
||||
|
||||
/// <summary>
|
||||
/// Implement this method as an external command for Revit.
|
||||
/// </summary>
|
||||
/// <param name="commandData">An object that is passed to the external application
|
||||
/// which contains data related to the command,
|
||||
/// such as the application object and active view.</param>
|
||||
/// <param name="message">A message that can be set by the external application
|
||||
/// which will be displayed if a failure or cancellation is returned by
|
||||
/// the external command.</param>
|
||||
/// <param name="elements">A set of elements to which the external application
|
||||
/// can add elements that are to be highlighted in case of failure or cancellation.</param>
|
||||
/// <returns>Return the status of the external command.
|
||||
/// A result of Succeeded means that the API external method functioned as expected.
|
||||
/// Cancelled can be used to signify that the user cancelled the external operation
|
||||
/// at some point. Failure should be returned if the application is unable to proceed with
|
||||
/// the operation.</returns>
|
||||
public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, ref string message, Autodesk.Revit.DB.ElementSet elements)
|
||||
{
|
||||
Transaction transaction = new Transaction(commandData.Application.ActiveUIDocument.Document, "External Tool");
|
||||
try
|
||||
{
|
||||
transaction.Start();
|
||||
|
||||
Resolver resolver = new Resolver(commandData);
|
||||
resolver.Resolve();
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
transaction.RollBack();
|
||||
message += e.ToString();
|
||||
return Autodesk.Revit.UI.Result.Failed;
|
||||
}
|
||||
finally
|
||||
{
|
||||
transaction.Commit();
|
||||
}
|
||||
return Autodesk.Revit.UI.Result.Succeeded;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
//
|
||||
// (C) Copyright 2003-2019 by Autodesk, Inc.
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software in
|
||||
// object code form for any purpose and without fee is hereby granted,
|
||||
// provided that the above copyright notice appears in all copies and
|
||||
// that both that copyright notice and the limited warranty and
|
||||
// restricted rights notice below appear in all supporting
|
||||
// documentation.
|
||||
//
|
||||
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
|
||||
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
|
||||
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
|
||||
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
|
||||
// UNINTERRUPTED OR ERROR FREE.
|
||||
//
|
||||
// Use, duplication, or disclosure by the U.S. Government is subject to
|
||||
// restrictions set forth in FAR 52.227-19 (Commercial Computer
|
||||
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
|
||||
// (Rights in Technical Data and Computer Software), as applicable.
|
||||
//
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit;
|
||||
using Element = Autodesk.Revit.DB.Element;
|
||||
|
||||
namespace Revit.SDK.Samples.AvoidObstruction.CS
|
||||
{
|
||||
/// <summary>
|
||||
/// This class is used to detect the obstructions of a Line or a ray.
|
||||
/// </summary>
|
||||
class Detector
|
||||
{
|
||||
/// <summary>
|
||||
/// Revit Document.
|
||||
/// </summary>
|
||||
private Document m_rvtDoc;
|
||||
|
||||
/// <summary>
|
||||
/// Revit 3D view.
|
||||
/// </summary>
|
||||
private View3D m_view3d;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor, initialize all the fields.
|
||||
/// </summary>
|
||||
/// <param name="rvtDoc">Revit Document</param>
|
||||
public Detector(Document rvtDoc)
|
||||
{
|
||||
m_rvtDoc = rvtDoc;
|
||||
FilteredElementCollector collector = new FilteredElementCollector(m_rvtDoc);
|
||||
FilteredElementIterator iter = collector.OfClass(typeof(View3D)).GetElementIterator();
|
||||
iter.Reset();
|
||||
while (iter.MoveNext())
|
||||
{
|
||||
m_view3d = iter.Current as View3D;
|
||||
if (null != m_view3d && !m_view3d.IsTemplate)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return all the obstructions which intersect with a ray given by an origin and a direction.
|
||||
/// </summary>
|
||||
/// <param name="origin">Ray's origin</param>
|
||||
/// <param name="dir">Ray's direction</param>
|
||||
/// <returns>Obstructions intersected with the given ray</returns>
|
||||
public List<ReferenceWithContext> Obstructions(Autodesk.Revit.DB.XYZ origin, Autodesk.Revit.DB.XYZ dir)
|
||||
{
|
||||
List<ReferenceWithContext> result = new List<ReferenceWithContext>();
|
||||
ReferenceIntersector referenceIntersector = new ReferenceIntersector(m_view3d);
|
||||
referenceIntersector.TargetType = FindReferenceTarget.Face;
|
||||
IList<ReferenceWithContext> obstructionsOnUnboundLine = referenceIntersector.Find(origin, dir);
|
||||
foreach (ReferenceWithContext gRef in obstructionsOnUnboundLine)
|
||||
{
|
||||
if (!InArray(result, gRef))
|
||||
{
|
||||
result.Add(gRef);
|
||||
}
|
||||
}
|
||||
|
||||
result.Sort(CompareReferencesWithContext);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return all the obstructions which intersect with a bound line.
|
||||
/// </summary>
|
||||
/// <param name="boundLine">Bound line</param>
|
||||
/// <returns>Obstructions intersected with the bound line</returns>
|
||||
public List<ReferenceWithContext> Obstructions(Line boundLine)
|
||||
{
|
||||
List<ReferenceWithContext> result = new List<ReferenceWithContext>();
|
||||
Autodesk.Revit.DB.XYZ startPt = boundLine.GetEndPoint(0);
|
||||
Autodesk.Revit.DB.XYZ endPt = boundLine.GetEndPoint(1);
|
||||
Autodesk.Revit.DB.XYZ dir = (endPt - startPt).Normalize();
|
||||
ReferenceIntersector referenceIntersector = new ReferenceIntersector(m_view3d);
|
||||
referenceIntersector.TargetType = FindReferenceTarget.Face;
|
||||
IList<ReferenceWithContext> obstructionsOnUnboundLine = referenceIntersector.Find(startPt, dir);
|
||||
foreach (ReferenceWithContext gRefWithContext in obstructionsOnUnboundLine)
|
||||
{
|
||||
Reference gRef = gRefWithContext.GetReference();
|
||||
// Judge whether the point is in the bound line or not, if the distance between the point and line
|
||||
// is Zero, then the point is in the bound line.
|
||||
if (boundLine.Distance(gRef.GlobalPoint) < 1e-9)
|
||||
{
|
||||
if (!InArray(result, gRefWithContext))
|
||||
{
|
||||
result.Add(gRefWithContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result.Sort(CompareReferencesWithContext);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Judge whether a given Reference is in a Reference list.
|
||||
/// Give two References, if their Proximity and Element Id is equal,
|
||||
/// we say the two reference is equal.
|
||||
/// </summary>
|
||||
/// <param name="arr">Reference Array</param>
|
||||
/// <param name="entry">Reference</param>
|
||||
/// <returns>True of false</returns>
|
||||
private bool InArray(List<ReferenceWithContext> arr, ReferenceWithContext entry)
|
||||
{
|
||||
foreach (ReferenceWithContext tmp in arr)
|
||||
{
|
||||
if (Math.Abs(tmp.Proximity - entry.Proximity) < 1e-9 &&
|
||||
tmp.GetReference().ElementId == entry.GetReference().ElementId)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to compare two references, just compare their ProximityParameter.
|
||||
/// </summary>
|
||||
/// <param name="a">First Reference to compare</param>
|
||||
/// <param name="b">Second Reference to compare</param>
|
||||
/// <returns>-1, 0, or 1</returns>
|
||||
private int CompareReferencesWithContext(ReferenceWithContext a, ReferenceWithContext b)
|
||||
{
|
||||
if (a.Proximity > b.Proximity)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (a.Proximity < b.Proximity)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,534 @@
|
||||
//
|
||||
// (C) Copyright 2003-2019 by Autodesk, Inc.
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software in
|
||||
// object code form for any purpose and without fee is hereby granted,
|
||||
// provided that the above copyright notice appears in all copies and
|
||||
// that both that copyright notice and the limited warranty and
|
||||
// restricted rights notice below appear in all supporting
|
||||
// documentation.
|
||||
//
|
||||
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
|
||||
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
|
||||
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
|
||||
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
|
||||
// UNINTERRUPTED OR ERROR FREE.
|
||||
//
|
||||
// Use, duplication, or disclosure by the U.S. Government is subject to
|
||||
// restrictions set forth in FAR 52.227-19 (Commercial Computer
|
||||
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
|
||||
// (Rights in Technical Data and Computer Software), as applicable.
|
||||
//
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.UI;
|
||||
using Autodesk.Revit;
|
||||
using Autodesk.Revit.ApplicationServices;
|
||||
using Autodesk.Revit.DB.Plumbing;
|
||||
using Autodesk.Revit.DB.Mechanical;
|
||||
using System.Diagnostics;
|
||||
using Element = Autodesk.Revit.DB.Element;
|
||||
using System.Collections;
|
||||
|
||||
namespace Revit.SDK.Samples.AvoidObstruction.CS
|
||||
{
|
||||
/// <summary>
|
||||
/// This class implement the algorithm to detect the obstruction and resolve it.
|
||||
/// </summary>
|
||||
class Resolver
|
||||
{
|
||||
/// <summary>
|
||||
/// Revit Document.
|
||||
/// </summary>
|
||||
private Document m_rvtDoc;
|
||||
|
||||
/// <summary>
|
||||
/// Revit Application.
|
||||
/// </summary>
|
||||
private Application m_rvtApp;
|
||||
|
||||
/// <summary>
|
||||
/// Detector to detect the obstructions.
|
||||
/// </summary>
|
||||
private Detector m_detector;
|
||||
|
||||
|
||||
PipingSystemType m_pipingSystemType;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor, initialize all the fields of this class.
|
||||
/// </summary>
|
||||
/// <param name="data">Revit ExternalCommandData from external command entrance</param>
|
||||
public Resolver(ExternalCommandData data)
|
||||
{
|
||||
m_rvtDoc = data.Application.ActiveUIDocument.Document;
|
||||
m_rvtApp = data.Application.Application;
|
||||
m_detector = new Detector(m_rvtDoc);
|
||||
|
||||
FilteredElementCollector collector = new FilteredElementCollector(m_rvtDoc);
|
||||
var pipingSystemTypes = collector.OfClass(typeof(PipingSystemType)).ToElements();
|
||||
foreach (PipingSystemType pipingSystemType in pipingSystemTypes)
|
||||
{
|
||||
if (pipingSystemType.SystemClassification == MEPSystemClassification.SupplyHydronic ||
|
||||
pipingSystemType.SystemClassification == MEPSystemClassification.ReturnHydronic)
|
||||
{
|
||||
m_pipingSystemType = pipingSystemType;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Detect and resolve the obstructions of all Pipes.
|
||||
/// </summary>
|
||||
public void Resolve()
|
||||
{
|
||||
List<Autodesk.Revit.DB.Element> pipes = new List<Autodesk.Revit.DB.Element>();
|
||||
FilteredElementCollector collector = new FilteredElementCollector(m_rvtDoc);
|
||||
pipes.AddRange(collector.OfClass(typeof(Pipe)).ToElements());
|
||||
foreach (Element pipe in pipes)
|
||||
{
|
||||
Resolve(pipe as Pipe);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the uniform perpendicular directions with inputting direction "dir".
|
||||
/// </summary>
|
||||
/// <param name="dir">Direction to calculate</param>
|
||||
/// <param name="count">How many perpendicular directions will be calculated</param>
|
||||
/// <returns>The calculated perpendicular directions with dir</returns>
|
||||
private List<Autodesk.Revit.DB.XYZ> PerpendicularDirs(Autodesk.Revit.DB.XYZ dir, int count)
|
||||
{
|
||||
List<Autodesk.Revit.DB.XYZ> dirs = new List<Autodesk.Revit.DB.XYZ>();
|
||||
Plane plane = Plane.CreateByNormalAndOrigin(dir, Autodesk.Revit.DB.XYZ.Zero);
|
||||
Arc arc = Arc.Create(plane, 1.0, 0, 6.28);
|
||||
|
||||
double delta = 1.0 / (double)count;
|
||||
for (int i = 1; i <= count; i++)
|
||||
{
|
||||
Autodesk.Revit.DB.XYZ pt = arc.Evaluate(delta * i, true);
|
||||
dirs.Add(pt);
|
||||
}
|
||||
|
||||
return dirs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Detect the obstructions of pipe and resolve them.
|
||||
/// </summary>
|
||||
/// <param name="pipe">Pipe to resolve</param>
|
||||
private void Resolve(Pipe pipe)
|
||||
{
|
||||
var parameter = pipe.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM);
|
||||
var levelId = parameter.AsElementId();
|
||||
var systemTypeId = m_pipingSystemType.Id;
|
||||
// Get the centerline of pipe.
|
||||
Line pipeLine = (pipe.Location as LocationCurve).Curve as Line;
|
||||
|
||||
// Calculate the intersection references with pipe's centerline.
|
||||
List<ReferenceWithContext> obstructionRefArr = m_detector.Obstructions(pipeLine);
|
||||
|
||||
// Filter out the references, just allow Pipe, Beam, and Duct.
|
||||
Filter(pipe, obstructionRefArr);
|
||||
|
||||
if (obstructionRefArr.Count == 0)
|
||||
{
|
||||
// There are no intersection found.
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate the direction of pipe's centerline.
|
||||
Autodesk.Revit.DB.XYZ dir = pipeLine.GetEndPoint(1) - pipeLine.GetEndPoint(0);
|
||||
|
||||
// Build the sections from the intersection references.
|
||||
List<Section> sections = Section.BuildSections(obstructionRefArr, dir.Normalize());
|
||||
|
||||
// Merge the neighbor sections if the distance of them is too close.
|
||||
for (int i = sections.Count - 2; i >= 0; i--)
|
||||
{
|
||||
Autodesk.Revit.DB.XYZ detal = sections[i].End - sections[i + 1].Start;
|
||||
if (detal.GetLength() < pipe.Diameter * 3)
|
||||
{
|
||||
sections[i].Refs.AddRange(sections[i + 1].Refs);
|
||||
sections.RemoveAt(i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve the obstructions one by one.
|
||||
foreach (Section sec in sections)
|
||||
{
|
||||
Resolve(pipe, sec);
|
||||
}
|
||||
|
||||
// Connect the neighbor sections with pipe and elbow fittings.
|
||||
//
|
||||
for (int i = 1; i < sections.Count; i++)
|
||||
{
|
||||
// Get the end point from the previous section.
|
||||
Autodesk.Revit.DB.XYZ start = sections[i - 1].End;
|
||||
|
||||
// Get the start point from the current section.
|
||||
Autodesk.Revit.DB.XYZ end = sections[i].Start;
|
||||
|
||||
// Create a pipe between two neighbor section.
|
||||
Pipe tmpPipe = Pipe.Create(m_rvtDoc, systemTypeId, pipe.PipeType.Id, levelId, start, end);
|
||||
|
||||
// Copy pipe's parameters values to tmpPipe.
|
||||
CopyParameters(pipe, tmpPipe);
|
||||
|
||||
// Create elbow fitting to connect previous section with tmpPipe.
|
||||
Connector conn1 = FindConnector(sections[i - 1].Pipes[2], start);
|
||||
Connector conn2 = FindConnector(tmpPipe, start);
|
||||
FamilyInstance fi = m_rvtDoc.Create.NewElbowFitting(conn1, conn2);
|
||||
|
||||
// Create elbow fitting to connect current section with tmpPipe.
|
||||
Connector conn3 = FindConnector(sections[i].Pipes[0], end);
|
||||
Connector conn4 = FindConnector(tmpPipe, end);
|
||||
FamilyInstance f2 = m_rvtDoc.Create.NewElbowFitting(conn3, conn4);
|
||||
}
|
||||
|
||||
// Find two connectors which pipe's two ends connector connected to.
|
||||
Connector startConn = FindConnectedTo(pipe, pipeLine.GetEndPoint(0));
|
||||
Connector endConn = FindConnectedTo(pipe, pipeLine.GetEndPoint(1));
|
||||
|
||||
Pipe startPipe = null;
|
||||
if (null != startConn)
|
||||
{
|
||||
// Create a pipe between pipe's start connector and pipe's start section.
|
||||
startPipe = Pipe.Create(m_rvtDoc, pipe.PipeType.Id, levelId, startConn, sections[0].Start);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a pipe between pipe's start point and pipe's start section.
|
||||
startPipe = Pipe.Create(m_rvtDoc, systemTypeId, pipe.PipeType.Id, levelId, sections[0].Start, pipeLine.GetEndPoint(0));
|
||||
}
|
||||
|
||||
// Copy parameters from pipe to startPipe.
|
||||
CopyParameters(pipe, startPipe);
|
||||
|
||||
// Connect the startPipe and first section with elbow fitting.
|
||||
Connector connStart1 = FindConnector(startPipe, sections[0].Start);
|
||||
Connector connStart2 = FindConnector(sections[0].Pipes[0], sections[0].Start);
|
||||
FamilyInstance fii = m_rvtDoc.Create.NewElbowFitting(connStart1, connStart2);
|
||||
|
||||
Pipe endPipe = null;
|
||||
int count = sections.Count;
|
||||
if (null != endConn)
|
||||
{
|
||||
// Create a pipe between pipe's end connector and pipe's end section.
|
||||
endPipe = Pipe.Create(m_rvtDoc, pipe.PipeType.Id, levelId, endConn, sections[count - 1].End);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a pipe between pipe's end point and pipe's end section.
|
||||
endPipe = Pipe.Create(m_rvtDoc, systemTypeId, pipe.PipeType.Id, levelId, sections[count - 1].End, pipeLine.GetEndPoint(1));
|
||||
}
|
||||
|
||||
// Copy parameters from pipe to endPipe.
|
||||
CopyParameters(pipe, endPipe);
|
||||
|
||||
// Connect the endPipe and last section with elbow fitting.
|
||||
Connector connEnd1 = FindConnector(endPipe, sections[count - 1].End);
|
||||
Connector connEnd2 = FindConnector(sections[count - 1].Pipes[2], sections[count - 1].End);
|
||||
FamilyInstance fiii = m_rvtDoc.Create.NewElbowFitting(connEnd1, connEnd2);
|
||||
|
||||
// Delete the pipe after resolved.
|
||||
m_rvtDoc.Delete(pipe.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filter the inputting References, just allow Pipe, Duct and Beam References.
|
||||
/// </summary>
|
||||
/// <param name="pipe">Pipe</param>
|
||||
/// <param name="refs">References to filter</param>
|
||||
private void Filter(Pipe pipe, List<ReferenceWithContext> refs)
|
||||
{
|
||||
for (int i = refs.Count - 1; i >= 0; i--)
|
||||
{
|
||||
Reference cur = refs[i].GetReference();
|
||||
Element curElem = m_rvtDoc.GetElement(cur);
|
||||
if (curElem.Id == pipe.Id ||
|
||||
(!(curElem is Pipe) && !(curElem is Duct) &&
|
||||
curElem.Category.Id.IntegerValue != (int)BuiltInCategory.OST_StructuralFraming))
|
||||
{
|
||||
refs.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method will find out a route to avoid the obstruction.
|
||||
/// </summary>
|
||||
/// <param name="pipe">Pipe to resolve</param>
|
||||
/// <param name="section">Pipe's one obstruction</param>
|
||||
/// <returns>A route which can avoid the obstruction</returns>
|
||||
private Line FindRoute(Pipe pipe, Section section)
|
||||
{
|
||||
// Perpendicular direction minimal length.
|
||||
double minLength = pipe.Diameter * 2;
|
||||
|
||||
// Parallel direction jump step.
|
||||
double jumpStep = pipe.Diameter;
|
||||
|
||||
// Calculate the directions in which to find the solution.
|
||||
List<Autodesk.Revit.DB.XYZ> dirs = new List<Autodesk.Revit.DB.XYZ>();
|
||||
Autodesk.Revit.DB.XYZ crossDir = null;
|
||||
foreach (ReferenceWithContext gref in section.Refs)
|
||||
{
|
||||
Element elem = m_rvtDoc.GetElement(gref.GetReference());
|
||||
Line locationLine = (elem.Location as LocationCurve).Curve as Line;
|
||||
Autodesk.Revit.DB.XYZ refDir = locationLine.GetEndPoint(1) - locationLine.GetEndPoint(0);
|
||||
refDir = refDir.Normalize();
|
||||
if (refDir.IsAlmostEqualTo(section.PipeCenterLineDirection) || refDir.IsAlmostEqualTo(-section.PipeCenterLineDirection))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
crossDir = refDir.CrossProduct(section.PipeCenterLineDirection);
|
||||
dirs.Add(crossDir.Normalize());
|
||||
break;
|
||||
}
|
||||
|
||||
// When all the obstruction are parallel with the centerline of the pipe,
|
||||
// We can't calculate the direction from the vector.Cross method.
|
||||
if (dirs.Count == 0)
|
||||
{
|
||||
// Calculate perpendicular directions with dir in four directions.
|
||||
List<Autodesk.Revit.DB.XYZ> perDirs = PerpendicularDirs(section.PipeCenterLineDirection, 4);
|
||||
dirs.Add(perDirs[0]);
|
||||
dirs.Add(perDirs[1]);
|
||||
}
|
||||
|
||||
Line foundLine = null;
|
||||
while (null == foundLine)
|
||||
{
|
||||
// Extend the section interval by jumpStep.
|
||||
section.Inflate(0, jumpStep);
|
||||
section.Inflate(1, jumpStep);
|
||||
|
||||
// Find solution in the given directions.
|
||||
for (int i = 0; null == foundLine && i < dirs.Count; i++)
|
||||
{
|
||||
// Calculate the intersections.
|
||||
List<ReferenceWithContext> obs1 = m_detector.Obstructions(section.Start, dirs[i]);
|
||||
List<ReferenceWithContext> obs2 = m_detector.Obstructions(section.End, dirs[i]);
|
||||
|
||||
// Filter out the intersection result.
|
||||
Filter(pipe, obs1);
|
||||
Filter(pipe, obs2);
|
||||
|
||||
// Find out the minimal intersections in two opposite direction.
|
||||
ReferenceWithContext[] mins1 = GetClosestSectionsToOrigin(obs1);
|
||||
ReferenceWithContext[] mins2 = GetClosestSectionsToOrigin(obs2);
|
||||
|
||||
// Find solution in the given direction and its opposite direction.
|
||||
for (int j = 0; null == foundLine && j < 2; j++)
|
||||
{
|
||||
if (mins1[j] != null && Math.Abs(mins1[j].Proximity) < minLength ||
|
||||
mins2[j] != null && Math.Abs(mins2[j].Proximity) < minLength)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Calculate the maximal height that the parallel line can be reached.
|
||||
double maxHight = 1000 * pipe.Diameter;
|
||||
if (mins1[j] != null && mins2[j] != null)
|
||||
{
|
||||
maxHight = Math.Min(Math.Abs(mins1[j].Proximity), Math.Abs(mins2[j].Proximity));
|
||||
}
|
||||
else if (mins1[j] != null)
|
||||
{
|
||||
maxHight = Math.Abs(mins1[j].Proximity);
|
||||
}
|
||||
else if (mins2[j] != null)
|
||||
{
|
||||
maxHight = Math.Abs(mins2[j].Proximity);
|
||||
}
|
||||
|
||||
Autodesk.Revit.DB.XYZ dir = (j == 1) ? dirs[i] : -dirs[i];
|
||||
|
||||
// Calculate the parallel line which can avoid obstructions.
|
||||
foundLine = FindParallelLine(pipe, section, dir, maxHight);
|
||||
}
|
||||
}
|
||||
}
|
||||
return foundLine;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find a line Parallel to pipe's centerline to avoid the obstruction.
|
||||
/// </summary>
|
||||
/// <param name="pipe">Pipe who has obstructions</param>
|
||||
/// <param name="section">Pipe's one obstruction</param>
|
||||
/// <param name="dir">Offset Direction of the parallel line</param>
|
||||
/// <param name="maxLength">Maximum offset distance</param>
|
||||
/// <returns>Parallel line which can avoid the obstruction</returns>
|
||||
private Line FindParallelLine(Pipe pipe, Section section, Autodesk.Revit.DB.XYZ dir, double maxLength)
|
||||
{
|
||||
double step = pipe.Diameter;
|
||||
double hight = 2 * pipe.Diameter;
|
||||
while (hight <= maxLength)
|
||||
{
|
||||
Autodesk.Revit.DB.XYZ detal = dir * hight;
|
||||
Line line = Line.CreateBound(section.Start + detal, section.End + detal);
|
||||
List<ReferenceWithContext> refs = m_detector.Obstructions(line);
|
||||
Filter(pipe, refs);
|
||||
|
||||
if (refs.Count == 0)
|
||||
{
|
||||
return line;
|
||||
}
|
||||
hight += step;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find out two References, whose ProximityParameter is negative or positive,
|
||||
/// And Get the minimal value from all positive reference, and get the maximal value
|
||||
/// from the negative reference. if there are no such reference, using null instead.
|
||||
/// </summary>
|
||||
/// <param name="refs">References</param>
|
||||
/// <returns>Reference array</returns>
|
||||
private ReferenceWithContext[] GetClosestSectionsToOrigin(List<ReferenceWithContext> refs)
|
||||
{
|
||||
ReferenceWithContext[] mins = new ReferenceWithContext[2];
|
||||
if (refs.Count == 0)
|
||||
{
|
||||
return mins;
|
||||
}
|
||||
|
||||
if (refs[0].Proximity > 0)
|
||||
{
|
||||
mins[1] = refs[0];
|
||||
return mins;
|
||||
}
|
||||
|
||||
for (int i = 0; i < refs.Count - 1; i++)
|
||||
{
|
||||
if (refs[i].Proximity < 0 && refs[i + 1].Proximity > 0)
|
||||
{
|
||||
mins[0] = refs[i];
|
||||
mins[1] = refs[i + 1];
|
||||
return mins;
|
||||
}
|
||||
}
|
||||
|
||||
mins[0] = refs[refs.Count - 1];
|
||||
|
||||
return mins;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Resolve one obstruction of Pipe.
|
||||
/// </summary>
|
||||
/// <param name="pipe">Pipe to resolve</param>
|
||||
/// <param name="section">One pipe's obstruction</param>
|
||||
private void Resolve(Pipe pipe, Section section)
|
||||
{
|
||||
// Find out a parallel line of pipe centerline, which can avoid the obstruction.
|
||||
Line offset = FindRoute(pipe, section);
|
||||
|
||||
// Construct a section line according to the given section.
|
||||
Line sectionLine = Line.CreateBound(section.Start, section.End);
|
||||
|
||||
// Construct two side lines, which can avoid the obstruction too.
|
||||
Line side1 = Line.CreateBound(sectionLine.GetEndPoint(0), offset.GetEndPoint(0));
|
||||
Line side2 = Line.CreateBound(offset.GetEndPoint(1), sectionLine.GetEndPoint(1));
|
||||
|
||||
//
|
||||
// Create an "U" shape, which connected with three pipes and two elbows, to round the obstruction.
|
||||
//
|
||||
PipeType pipeType = pipe.PipeType;
|
||||
Autodesk.Revit.DB.XYZ start = side1.GetEndPoint(0);
|
||||
Autodesk.Revit.DB.XYZ startOffset = offset.GetEndPoint(0);
|
||||
Autodesk.Revit.DB.XYZ endOffset = offset.GetEndPoint(1);
|
||||
Autodesk.Revit.DB.XYZ end = side2.GetEndPoint(1);
|
||||
|
||||
var parameter = pipe.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM);
|
||||
var levelId = parameter.AsElementId();
|
||||
// Create three side pipes of "U" shape.
|
||||
var systemTypeId = m_pipingSystemType.Id;
|
||||
Pipe pipe1 = Pipe.Create(m_rvtDoc, systemTypeId, pipeType.Id, levelId, start, startOffset);
|
||||
Pipe pipe2 = Pipe.Create(m_rvtDoc, systemTypeId, pipeType.Id, levelId, startOffset, endOffset);
|
||||
Pipe pipe3 = Pipe.Create(m_rvtDoc, systemTypeId, pipeType.Id, levelId, endOffset, end);
|
||||
|
||||
// Copy parameters from pipe to other three created pipes.
|
||||
CopyParameters(pipe, pipe1);
|
||||
CopyParameters(pipe, pipe2);
|
||||
CopyParameters(pipe, pipe3);
|
||||
|
||||
// Add the created three pipes to current section.
|
||||
section.Pipes.Add(pipe1);
|
||||
section.Pipes.Add(pipe2);
|
||||
section.Pipes.Add(pipe3);
|
||||
|
||||
// Create the first elbow to connect two neighbor pipes of "U" shape.
|
||||
Connector conn1 = FindConnector(pipe1, startOffset);
|
||||
Connector conn2 = FindConnector(pipe2, startOffset);
|
||||
m_rvtDoc.Create.NewElbowFitting(conn1, conn2);
|
||||
|
||||
// Create the second elbow to connect another two neighbor pipes of "U" shape.
|
||||
Connector conn3 = FindConnector(pipe2, endOffset);
|
||||
Connector conn4 = FindConnector(pipe3, endOffset);
|
||||
m_rvtDoc.Create.NewElbowFitting(conn3, conn4);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy parameters from source pipe to target pipe.
|
||||
/// </summary>
|
||||
/// <param name="source">Coping source</param>
|
||||
/// <param name="target">Coping target</param>
|
||||
private void CopyParameters(Pipe source, Pipe target)
|
||||
{
|
||||
double diameter = source.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM).AsDouble();
|
||||
target.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM).Set(diameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find out a connector from pipe with a specified point.
|
||||
/// </summary>
|
||||
/// <param name="pipe">Pipe to find the connector</param>
|
||||
/// <param name="conXYZ">Specified point</param>
|
||||
/// <returns>Connector whose origin is conXYZ</returns>
|
||||
private Connector FindConnector(Pipe pipe, Autodesk.Revit.DB.XYZ conXYZ)
|
||||
{
|
||||
ConnectorSet conns = pipe.ConnectorManager.Connectors;
|
||||
foreach (Connector conn in conns)
|
||||
{
|
||||
if (conn.Origin.IsAlmostEqualTo(conXYZ))
|
||||
{
|
||||
return conn;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find out the connector which the pipe's specified connector connected to.
|
||||
/// The pipe's specified connector is given by point conxyz.
|
||||
/// </summary>
|
||||
/// <param name="pipe">Pipe to find the connector</param>
|
||||
/// <param name="conXYZ">Specified point</param>
|
||||
/// <returns>Connector whose origin is conXYZ</returns>
|
||||
private Connector FindConnectedTo(Pipe pipe, Autodesk.Revit.DB.XYZ conXYZ)
|
||||
{
|
||||
Connector connItself = FindConnector(pipe, conXYZ);
|
||||
ConnectorSet connSet = connItself.AllRefs;
|
||||
foreach (Connector conn in connSet)
|
||||
{
|
||||
if (conn.Owner.Id.IntegerValue != pipe.Id.IntegerValue &&
|
||||
conn.ConnectorType == ConnectorType.End)
|
||||
{
|
||||
return conn;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
//
|
||||
// (C) Copyright 2003-2019 by Autodesk, Inc.
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software in
|
||||
// object code form for any purpose and without fee is hereby granted,
|
||||
// provided that the above copyright notice appears in all copies and
|
||||
// that both that copyright notice and the limited warranty and
|
||||
// restricted rights notice below appear in all supporting
|
||||
// documentation.
|
||||
//
|
||||
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
|
||||
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
|
||||
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
|
||||
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
|
||||
// UNINTERRUPTED OR ERROR FREE.
|
||||
//
|
||||
// Use, duplication, or disclosure by the U.S. Government is subject to
|
||||
// restrictions set forth in FAR 52.227-19 (Commercial Computer
|
||||
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
|
||||
// (Rights in Technical Data and Computer Software), as applicable.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.DB.Plumbing;
|
||||
|
||||
namespace Revit.SDK.Samples.AvoidObstruction.CS
|
||||
{
|
||||
/// <summary>
|
||||
/// This class presents an obstruction of a Pipe.
|
||||
/// </summary>
|
||||
class Section
|
||||
{
|
||||
/// <summary>
|
||||
/// Pipe centerline's direction.
|
||||
/// </summary>
|
||||
private Autodesk.Revit.DB.XYZ m_dir;
|
||||
|
||||
/// <summary>
|
||||
/// Extend factor in negative direction.
|
||||
/// </summary>
|
||||
private double m_startFactor;
|
||||
|
||||
/// <summary>
|
||||
/// Extend factor in positive direction.
|
||||
/// </summary>
|
||||
private double m_endFactor;
|
||||
|
||||
/// <summary>
|
||||
/// References contained in this obstruction.
|
||||
/// </summary>
|
||||
private List<ReferenceWithContext> m_refs;
|
||||
|
||||
/// <summary>
|
||||
/// Pipes to avoid this obstruction, it is assigned when resolving this obstruction.
|
||||
/// Its count will be three if resolved, the three pipe constructs a "U" shape to round the obstruction.
|
||||
/// </summary>
|
||||
private List<Pipe> m_pipes;
|
||||
|
||||
/// <summary>
|
||||
/// Private constructor, just be called in static factory method BuildSections.
|
||||
/// </summary>
|
||||
/// <param name="dir">Pipe's direction</param>
|
||||
private Section(Autodesk.Revit.DB.XYZ dir)
|
||||
{
|
||||
m_dir = dir;
|
||||
m_startFactor = 0;
|
||||
m_endFactor = 0;
|
||||
m_refs = new List<ReferenceWithContext>();
|
||||
m_pipes = new List<Pipe>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pipe centerline's direction.
|
||||
/// </summary>
|
||||
public Autodesk.Revit.DB.XYZ PipeCenterLineDirection
|
||||
{
|
||||
get { return m_dir; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pipes to avoid this obstruction, it is assigned when resolving this obstruction.
|
||||
/// Its count will be three if resolved, the three pipe constructs a "U" shape to round the obstruction.
|
||||
/// </summary>
|
||||
public List<Pipe> Pipes
|
||||
{
|
||||
get { return m_pipes; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start point of this obstruction.
|
||||
/// </summary>
|
||||
public Autodesk.Revit.DB.XYZ Start
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_refs[0].GetReference().GlobalPoint + m_dir * m_startFactor;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// End point of this obstruction.
|
||||
/// </summary>
|
||||
public Autodesk.Revit.DB.XYZ End
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_refs[m_refs.Count - 1].GetReference().GlobalPoint + m_dir * m_endFactor;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// References contained in this obstruction.
|
||||
/// </summary>
|
||||
public List<ReferenceWithContext> Refs
|
||||
{
|
||||
get { return m_refs; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extend this obstruction's interval in one direction.
|
||||
/// </summary>
|
||||
/// <param name="index">index of direction, 0 => start, 1 => end</param>
|
||||
public void Inflate(int index, double value)
|
||||
{
|
||||
if (index == 0)
|
||||
{
|
||||
m_startFactor -= value;
|
||||
}
|
||||
else if(index == 1)
|
||||
{
|
||||
m_endFactor += value;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("Index should be 0 or 1.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build sections for References, it's a factory method to build sections.
|
||||
/// A section contains several points through which the ray passes the obstruction(s).
|
||||
/// for example, a section may contain 2 points when the obstruction is stand alone,
|
||||
/// or contain 4 points if 2 obstructions are intersects with each other in the direction of the ray.
|
||||
/// </summary>
|
||||
/// <param name="allrefs">References</param>
|
||||
/// <param name="dir">Pipe's direction</param>
|
||||
/// <returns>List of Section</returns>
|
||||
public static List<Section> BuildSections(List<ReferenceWithContext> allrefs, Autodesk.Revit.DB.XYZ dir)
|
||||
{
|
||||
List<ReferenceWithContext> buildStack = new List<ReferenceWithContext>();
|
||||
List<Section> sections = new List<Section>();
|
||||
Section current = null;
|
||||
foreach (ReferenceWithContext geoRef in allrefs)
|
||||
{
|
||||
if (buildStack.Count == 0)
|
||||
{
|
||||
current = new Section(dir);
|
||||
sections.Add(current);
|
||||
}
|
||||
|
||||
current.Refs.Add(geoRef);
|
||||
|
||||
ReferenceWithContext tmp = Find(buildStack, geoRef);
|
||||
if (tmp != null)
|
||||
{
|
||||
buildStack.Remove(tmp);
|
||||
}
|
||||
else
|
||||
buildStack.Add(geoRef);
|
||||
}
|
||||
|
||||
return sections;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Judge whether a Reference is already in the list of Reference, return the founded value.
|
||||
/// </summary>
|
||||
/// <param name="arr">List of Reference</param>
|
||||
/// <param name="entry">Reference to test</param>
|
||||
/// <returns>One Reference has the same element's Id with entry</returns>
|
||||
private static ReferenceWithContext Find(List<ReferenceWithContext> arr, ReferenceWithContext entry)
|
||||
{
|
||||
foreach (ReferenceWithContext tmp in arr)
|
||||
{
|
||||
if (tmp.GetReference().ElementId == entry.GetReference().ElementId)
|
||||
{
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user