Skip to content

Commit

Permalink
integrated CmdProjectParameterGuids by CoderBoy and cleaned up CmdWal…
Browse files Browse the repository at this point in the history
…lOpenings
  • Loading branch information
Jeremy Tammik committed Dec 17, 2015
1 parent b8bf811 commit aa108e6
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 133 deletions.
262 changes: 131 additions & 131 deletions BuildingCoder/BuildingCoder/CmdWallOpenings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace BuildingCoder
/// A simple class with two coordinates
/// and some other basic info.
/// </summary>
class WallOpening2D
class WallOpening2d
{
//public ElementId Id { get; set; }
public XYZ Start { get; set; }
Expand Down Expand Up @@ -66,11 +66,11 @@ static bool IsSurface( Reference r )
== r.ElementReferenceType;
}

class XyzProximityComparer : IComparer<XYZ>
class XyzProximityComparerNotUsed : IComparer<XYZ>
{
XYZ _p;

public XyzProximityComparer( XYZ p )
public XyzProximityComparerNotUsed( XYZ p )
{
_p = p;
}
Expand Down Expand Up @@ -98,151 +98,151 @@ public int GetHashCode( XYZ a )
}
}

/// <summary>
/// Retrieve all wall openings,
/// including at start and end of wall.
/// </summary>
List<WallOpening2D> GetWallOpenings(
Wall wall,
View3D view )
{
Document doc = wall.Document;
Level level = doc.GetElement( wall.LevelId ) as Level;
double elevation = level.Elevation;
Curve c = ( wall.Location as LocationCurve ).Curve;
XYZ wallOrigin = c.GetEndPoint( 0 );
XYZ wallEndPoint = c.GetEndPoint( 1 );
XYZ wallDirection = wallEndPoint - wallOrigin;
double wallLength = wallDirection.GetLength();
wallDirection = wallDirection.Normalize();
UV offsetOut = _offset * new UV( wallDirection.X, wallDirection.Y );

XYZ rayStart = new XYZ( wallOrigin.X - offsetOut.U,
wallOrigin.Y - offsetOut.V, elevation + _offset );

ReferenceIntersector intersector
= new ReferenceIntersector( wall.Id,
FindReferenceTarget.Face, view );

IList<ReferenceWithContext> refs
= intersector.Find( rayStart, wallDirection );

// Extract the intersection points:
// - only surfaces
// - within wall length plus offset at each end
// - sorted by proximity
// - eliminating duplicates

List<XYZ> pointList = new List<XYZ>( refs
.Where<ReferenceWithContext>( r => IsSurface(
r.GetReference() ) )
.Where<ReferenceWithContext>( r => r.Proximity
< wallLength + _offset + _offset )
.OrderBy<ReferenceWithContext, double>(
r => r.Proximity )
.Select<ReferenceWithContext, XYZ>( r
=> r.GetReference().GlobalPoint )
.Distinct<XYZ>( new XyzEqualityComparer() ) );

// Check if first point is at the wall start.
// If so, the wall does not begin with an opening,
// so that point can be removed. Else, add it.

XYZ q = wallOrigin + _offset * XYZ.BasisZ;

bool wallHasFaceAtStart = Util.IsEqual(
pointList[0], q );

if( wallHasFaceAtStart )
{
pointList.RemoveAll( p
//=> _eps > p.DistanceTo( q ) );
=> Util.IsEqual( p, q ) );
}
else
{
pointList.Insert( 0, wallOrigin );
}

// Check if last point is at the wall end.
// If so, the wall does not end with an opening,
// so that point can be removed. Else, add it.
/// <summary>
/// Retrieve all wall openings,
/// including at start and end of wall.
/// </summary>
List<WallOpening2d> GetWallOpenings(
Wall wall,
View3D view )
{
Document doc = wall.Document;
Level level = doc.GetElement( wall.LevelId ) as Level;
double elevation = level.Elevation;
Curve c = ( wall.Location as LocationCurve ).Curve;
XYZ wallOrigin = c.GetEndPoint( 0 );
XYZ wallEndPoint = c.GetEndPoint( 1 );
XYZ wallDirection = wallEndPoint - wallOrigin;
double wallLength = wallDirection.GetLength();
wallDirection = wallDirection.Normalize();
UV offsetOut = _offset * new UV( wallDirection.X, wallDirection.Y );

XYZ rayStart = new XYZ( wallOrigin.X - offsetOut.U,
wallOrigin.Y - offsetOut.V, elevation + _offset );

ReferenceIntersector intersector
= new ReferenceIntersector( wall.Id,
FindReferenceTarget.Face, view );

IList<ReferenceWithContext> refs
= intersector.Find( rayStart, wallDirection );

// Extract the intersection points:
// - only surfaces
// - within wall length plus offset at each end
// - sorted by proximity
// - eliminating duplicates

List<XYZ> pointList = new List<XYZ>( refs
.Where<ReferenceWithContext>( r => IsSurface(
r.GetReference() ) )
.Where<ReferenceWithContext>( r => r.Proximity
< wallLength + _offset + _offset )
.OrderBy<ReferenceWithContext, double>(
r => r.Proximity )
.Select<ReferenceWithContext, XYZ>( r
=> r.GetReference().GlobalPoint )
.Distinct<XYZ>( new XyzEqualityComparer() ) );

// Check if first point is at the wall start.
// If so, the wall does not begin with an opening,
// so that point can be removed. Else, add it.

XYZ q = wallOrigin + _offset * XYZ.BasisZ;

bool wallHasFaceAtStart = Util.IsEqual(
pointList[0], q );

if( wallHasFaceAtStart )
{
pointList.RemoveAll( p
//=> _eps > p.DistanceTo( q ) );
=> Util.IsEqual( p, q ) );
}
else
{
pointList.Insert( 0, wallOrigin );
}

q = wallEndPoint + _offset * XYZ.BasisZ;
// Check if last point is at the wall end.
// If so, the wall does not end with an opening,
// so that point can be removed. Else, add it.

bool wallHasFaceAtEnd = Util.IsEqual(
pointList.Last(), q );
q = wallEndPoint + _offset * XYZ.BasisZ;

if( wallHasFaceAtEnd )
{
pointList.RemoveAll( p
//=> _eps > p.DistanceTo( q ) );
=> Util.IsEqual( p, q ) );
}
else
{
pointList.Add( wallEndPoint );
}
bool wallHasFaceAtEnd = Util.IsEqual(
pointList.Last(), q );

int n = pointList.Count;
if( wallHasFaceAtEnd )
{
pointList.RemoveAll( p
//=> _eps > p.DistanceTo( q ) );
=> Util.IsEqual( p, q ) );
}
else
{
pointList.Add( wallEndPoint );
}

Debug.Assert( IsEven( n ),
"expected an even number of opening sides" );
int n = pointList.Count;

var wallOpenings = new List<WallOpening2D>(
n / 2 );
Debug.Assert( IsEven( n ),
"expected an even number of opening sides" );

for( int i = 0; i < n; i += 2 )
{
wallOpenings.Add( new WallOpening2D
{
Start = pointList[i],
End = pointList[i + 1]
} );
}
return wallOpenings;
}
var wallOpenings = new List<WallOpening2d>(
n / 2 );

public Result Execute(
ExternalCommandData commandData,
ref string message,
ElementSet elements )
for( int i = 0; i < n; i += 2 )
{
wallOpenings.Add( new WallOpening2d
{
UIApplication uiapp = commandData.Application;
UIDocument uidoc = uiapp.ActiveUIDocument;
Document doc = uidoc.Document;
Start = pointList[i],
End = pointList[i + 1]
} );
}
return wallOpenings;
}

if( null == doc )
{
message = "Please run this command in a valid document.";
return Result.Failed;
}
public Result Execute(
ExternalCommandData commandData,
ref string message,
ElementSet elements )
{
UIApplication uiapp = commandData.Application;
UIDocument uidoc = uiapp.ActiveUIDocument;
Document doc = uidoc.Document;

View3D view = doc.ActiveView as View3D;
if( null == doc )
{
message = "Please run this command in a valid document.";
return Result.Failed;
}

if( null == view )
{
message = "Please run this command in a 3D view.";
return Result.Failed;
}
View3D view = doc.ActiveView as View3D;

Element e = Util.SelectSingleElementOfType(
uidoc, typeof( Wall ), "wall", true );
if( null == view )
{
message = "Please run this command in a 3D view.";
return Result.Failed;
}

List<WallOpening2D> openings = GetWallOpenings(
e as Wall, view );
Element e = Util.SelectSingleElementOfType(
uidoc, typeof( Wall ), "wall", true );

int n = openings.Count;
List<WallOpening2d> openings = GetWallOpenings(
e as Wall, view );

string msg = string.Format(
"{0} opening{1} found{2}",
n, Util.PluralSuffix( n ),
Util.DotOrColon( n ) );
int n = openings.Count;

Util.InfoMsg2( msg, string.Join(
"\r\n", openings ) );
string msg = string.Format(
"{0} opening{1} found{2}",
n, Util.PluralSuffix( n ),
Util.DotOrColon( n ) );

return Result.Succeeded;
}
Util.InfoMsg2( msg, string.Join(
"\r\n", openings ) );

return Result.Succeeded;
}
}
}
5 changes: 3 additions & 2 deletions BuildingCoder/BuildingCoder/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
// 2015-11-30 2016.0.123.2 YbExporteContext
// 2015-12-16 2016.0.124.0 implemented CmdWallOpenings
// 2015-12-17 2016.0.125.0 integrated CmdProjectParameterGuids by CoderBoy
// 2015-12-17 2016.0.125.1 cleaned up CmdWallOpenings
//
[assembly: AssemblyVersion( "2016.0.125.0" )]
[assembly: AssemblyFileVersion( "2016.0.125.0" )]
[assembly: AssemblyVersion( "2016.0.125.1" )]
[assembly: AssemblyFileVersion( "2016.0.125.1" )]

0 comments on commit aa108e6

Please sign in to comment.