Skip to content

Commit c10a9cf

Browse files
author
Jeremy Tammik
committed
insert fittings around rolling offset pipe segment
1 parent 67f1cf7 commit c10a9cf

File tree

3 files changed

+176
-39
lines changed

3 files changed

+176
-39
lines changed

BuildingCoder/BuildingCoder/CmdRollingOffset.cs

Lines changed: 172 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
using Autodesk.Revit.DB.Plumbing;
1818
using Autodesk.Revit.UI;
1919
using Autodesk.Revit.UI.Selection;
20+
using StructuralType = Autodesk.Revit.DB.Structure.StructuralType;
2021
#endregion // Namespaces
2122

2223
namespace BuildingCoder
@@ -32,6 +33,13 @@ class CmdRollingOffset : IExternalCommand
3233
/// </summary>
3334
static bool _place_model_line = false;
3435

36+
/// <summary>
37+
/// Place the two 45 degree fittings and connect
38+
/// them instead of explicitly placing the
39+
/// rolling offset pipe segment.
40+
/// </summary>
41+
static bool _place_fittings = true;
42+
3543
/// <summary>
3644
/// Switch between the new static Pipe.Create
3745
/// method and the obsolete
@@ -48,6 +56,10 @@ const string _prompt
4856
+ "this command, or post-select them when "
4957
+ "prompted.";
5058

59+
const BuiltInParameter bipDiameter
60+
= BuiltInParameter.RBS_PIPE_DIAMETER_PARAM;
61+
62+
5163
/// <summary>
5264
/// Allow selection of curve elements only.
5365
/// </summary>
@@ -203,8 +215,8 @@ public Result Execute(
203215
return Result.Failed;
204216
}
205217

206-
// Select the two pipe endpoints that are
207-
// farthest apart.
218+
// Select the two pipe endpoints
219+
// that are farthest apart.
208220

209221
XYZ p0 = p00.DistanceTo( p10 ) > p01.DistanceTo( p10 )
210222
? p00
@@ -224,7 +236,16 @@ public Result Execute(
224236
return Result.Failed;
225237
}
226238

239+
// Normal vector of the plane defined by the
240+
// two parallel and offset pipes, which is
241+
// the plane hosting the rolling offset
242+
227243
XYZ z = v.CrossProduct( v1 );
244+
245+
// Vector perpendicular to v0 and v0 and
246+
// z, i.e. vector pointing from the first pipe
247+
// to the second in the cross sectional view.
248+
228249
XYZ w = z.CrossProduct( v1 ).Normalize();
229250

230251
// Offset distance perpendicular to pipe direction
@@ -273,7 +294,30 @@ double remainingPipeLength
273294

274295
using( Transaction tx = new Transaction( doc ) )
275296
{
276-
Pipe pipe = null;
297+
// Determine pipe diameter for creating
298+
// matching pipes and fittings
299+
300+
Pipe pipe = pipes[0];
301+
302+
double diameter = pipe
303+
.get_Parameter( bipDiameter ) // "Diameter"
304+
.AsDouble();
305+
306+
// Pipe type for calls to doc.Create.NewPipe
307+
308+
PipeType pipe_type_standard
309+
= new FilteredElementCollector( doc )
310+
.OfClass( typeof( PipeType ) )
311+
.Cast<PipeType>()
312+
.Where<PipeType>( e
313+
=> e.Name.Equals( "Standard" ) )
314+
.FirstOrDefault<PipeType>();
315+
316+
Debug.Assert(
317+
pipe_type_standard.Id.IntegerValue.Equals(
318+
pipe.PipeType.Id.IntegerValue ),
319+
"expected all pipes in this simple "
320+
+ "model to use the same pipe type" );
277321

278322
tx.Start( "Rolling Offset" );
279323

@@ -294,11 +338,126 @@ double remainingPipeLength
294338
Line line = Line.CreateBound( q0, q1 );
295339

296340
creator.CreateModelCurve( line );
341+
342+
pipe = null;
297343
}
298-
else
344+
else if( _place_fittings )
299345
{
300-
pipe = pipes[0];
346+
// Set active work plane to the rolling
347+
// offset plane... removed again, since
348+
// this has no effect at all on the
349+
// fitting placement or rotation.
350+
//
351+
//Plane plane = new Plane( z, q0 );
352+
//
353+
//SketchPlane sp = SketchPlane.Create(
354+
// doc, plane );
355+
//
356+
//uidoc.ActiveView.SketchPlane = sp;
357+
//uidoc.ActiveView.ShowActiveWorkPlane();
358+
359+
FamilySymbol symbol
360+
= new FilteredElementCollector( doc )
361+
.OfClass( typeof( FamilySymbol ) )
362+
.OfCategory( BuiltInCategory.OST_PipeFitting )
363+
.Cast<FamilySymbol>()
364+
.Where<FamilySymbol>( e
365+
=> e.Family.Name.Contains( "Elbow - Generic" ) )
366+
.FirstOrDefault<FamilySymbol>();
367+
368+
// Set up first 45 degree elbow fitting
369+
370+
FamilyInstance fitting0 = doc.Create
371+
.NewFamilyInstance( q0, symbol,
372+
StructuralType.NonStructural );
373+
374+
fitting0.get_Parameter( "Angle" ).Set(
375+
45.0 * Math.PI / 180.0 );
376+
377+
//fitting0.get_Parameter( bipDiameter ) // does not exist
378+
// .Set( diameter );
379+
380+
fitting0.get_Parameter( "Nominal Radius" )
381+
.Set( 0.5 * diameter );
382+
383+
Line axis = Line.CreateBound( p0, q0 );
384+
angle = z.AngleTo( XYZ.BasisZ );
385+
386+
ElementTransformUtils.RotateElement(
387+
doc, fitting0.Id, axis, Math.PI - angle );
388+
389+
Connector con0 = Util.GetConnectorClosestTo(
390+
fitting0, p0 );
391+
392+
// Trim or extend existing pipe
393+
394+
( pipes[0].Location as LocationCurve ).Curve
395+
= Line.CreateBound( p0, con0.Origin );
396+
397+
// Connect pipe to fitting
398+
399+
Util.Connect( con0.Origin, pipe, fitting0 );
400+
401+
// Set up second 45 degree elbow fitting
402+
403+
FamilyInstance fitting1 = doc.Create
404+
.NewFamilyInstance( q1, symbol,
405+
StructuralType.NonStructural );
406+
407+
fitting1.get_Parameter( "Angle" ).Set(
408+
45.0 * Math.PI / 180.0 );
409+
410+
fitting1.get_Parameter( "Nominal Radius" )
411+
.Set( 0.5 * diameter );
412+
413+
axis = Line.CreateBound(
414+
q1, q1 + XYZ.BasisZ );
415+
416+
ElementTransformUtils.RotateElement(
417+
doc, fitting1.Id, axis, Math.PI );
301418

419+
axis = Line.CreateBound( q1, p1 );
420+
421+
ElementTransformUtils.RotateElement(
422+
doc, fitting1.Id, axis, Math.PI - angle );
423+
424+
Connector con1 = Util.GetConnectorClosestTo(
425+
fitting1, p1 );
426+
427+
( pipes[1].Location as LocationCurve ).Curve
428+
= Line.CreateBound( con1.Origin, p1 );
429+
430+
Util.Connect( con1.Origin, fitting1, pipes[1] );
431+
432+
con0 = Util.GetConnectorClosestTo(
433+
fitting0, pm );
434+
435+
con1 = Util.GetConnectorClosestTo(
436+
fitting1, pm );
437+
438+
// Connecting one fitting to the other does
439+
// not insert a pipe in between. If the
440+
// system is edited later, however, the two
441+
// fittings snap together.
442+
//
443+
//con0.ConnectTo( con1 );
444+
445+
// Create rolling offset pipe segment
446+
447+
pipe = doc.Create.NewPipe( con0.Origin,
448+
con1.Origin, pipe_type_standard );
449+
450+
pipe.get_Parameter( bipDiameter )
451+
.Set( diameter );
452+
453+
// Connect rolling offset pipe segment
454+
// with elbow fittings at each end
455+
456+
Util.Connect( con0.Origin, fitting0, pipe );
457+
Util.Connect( con1.Origin, pipe, fitting1 );
458+
}
459+
else
460+
{
302461
if( _use_static_pipe_create )
303462
{
304463
ElementId idSystem = pipe.MEPSystem.Id; // invalid
@@ -321,42 +480,20 @@ double remainingPipeLength
321480
}
322481
else
323482
{
324-
BuiltInParameter bip
325-
= BuiltInParameter.RBS_PIPE_DIAMETER_PARAM;
326-
327-
double diameter = pipe
328-
.get_Parameter( bip ) // "Diameter"
329-
.AsDouble();
330-
331-
PipeType pipe_type_standard
332-
= new FilteredElementCollector( doc )
333-
.OfClass( typeof( PipeType ) )
334-
.Cast<PipeType>()
335-
.Where<PipeType>( e
336-
=> e.Name.Equals( "Standard" ) )
337-
.FirstOrDefault<PipeType>();
338-
339-
Debug.Assert(
340-
pipe_type_standard.Id.IntegerValue.Equals(
341-
pipe.PipeType.Id.IntegerValue ),
342-
"expected all pipes in this simple "
343-
+ "model to use the same pipe type" );
344-
345483
pipe = doc.Create.NewPipe( q0, q1,
346484
pipe_type_standard );
347485

348-
pipe.get_Parameter( bip )
486+
pipe.get_Parameter( bipDiameter )
349487
.Set( diameter );
350488
}
351-
}
352-
353-
if( null != pipe )
354-
{
355-
// Connect rolling offset pipe segment
356-
// with its neighbours
489+
if( null != pipe )
490+
{
491+
// Connect rolling offset pipe segment
492+
// with its neighbours
357493

358-
Util.Connect( q0, pipes[0], pipe );
359-
Util.Connect( q1, pipe, pipes[1] );
494+
Util.Connect( q0, pipes[0], pipe );
495+
Util.Connect( q1, pipe, pipes[1] );
496+
}
360497
}
361498

362499
tx.Commit();

BuildingCoder/BuildingCoder/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,5 @@
3131
//
3232
// You can specify all the values or you can default the Revision and Build Numbers
3333
// by using the '*' as shown below:
34-
[assembly: AssemblyVersion( "2014.0.106.3" )]
35-
[assembly: AssemblyFileVersion( "2014.0.106.3" )]
34+
[assembly: AssemblyVersion( "2014.0.106.4" )]
35+
[assembly: AssemblyFileVersion( "2014.0.106.4" )]

BuildingCoder/BuildingCoder/Util.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -980,7 +980,7 @@ static Connector GetConnectorAt(
980980
}
981981

982982
/// <summary>
983-
/// Return the connector in the set
983+
/// Return the connector set element
984984
/// closest to the given point.
985985
/// </summary>
986986
static Connector GetConnectorClosestTo(
@@ -1007,7 +1007,7 @@ static Connector GetConnectorClosestTo(
10071007
/// Return the connector on the element
10081008
/// closest to the given point.
10091009
/// </summary>
1010-
static Connector GetConnectorClosestTo(
1010+
public static Connector GetConnectorClosestTo(
10111011
Element e,
10121012
XYZ p )
10131013
{

0 commit comments

Comments
 (0)