BuildingCoder.CmdDimensionWallsFindRefs.Execute C# (CSharp) Метод

Execute() публичный Метод

public Execute ( ExternalCommandData commandData, string &message, ElementSet elements ) : System.Result
commandData ExternalCommandData
message string
elements ElementSet
Результат System.Result
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
              UIDocument uidoc = uiapp.ActiveUIDocument;
              Application app = uiapp.Application;
              Document doc = uidoc.Document;

              // Select two walls and the dimension line point:

              Selection sel = uidoc.Selection;
              ReferenceArray refs = new ReferenceArray();

              try
              {
            ISelectionFilter f
              = new JtElementsOfClassSelectionFilter<Wall>();

            refs.Append( sel.PickObject(
              ObjectType.Element, f,
              "Please select first wall" ) );

            refs.Append( sel.PickObject(
              ObjectType.Element, f,
              "Please pick dimension line "
              + "point on second wall" ) );

            //rFace = sel.PickObject( ObjectType.Face,
            //  "Please select face on second wall at dimension line point" );
            //
            //rPoint = sel.PickObject( ObjectType.PointOnElement,
            //  "Please select point on first wall" );
              }
              catch( Autodesk.Revit.Exceptions.OperationCanceledException )
              {
            message = "No two walls selected";
            return Result.Failed;
              }

              // Ensure the two selected walls are straight and
              // parallel; determine their mutual normal vector
              // and a point on each wall for distance
              // calculations:

              Wall[] walls = new Wall[2];
              List<int> ids = new List<int>( 2 );
              XYZ[] pts = new XYZ[2];
              Line[] lines = new Line[2];
              IntersectionResult ir;
              XYZ normal = null;
              int i = 0;

              foreach( Reference r in refs )
              {
            // 'Autodesk.Revit.DB.Reference.Element' is
            // obsolete: Property will be removed. Use
            // Document.GetElement(Reference) instead.
            //Wall wall = r.Element as Wall; // 2011

            Wall wall = doc.GetElement( r ) as Wall; // 2012

            walls[i] = wall;
            ids.Add( wall.Id.IntegerValue );

            // Obtain location curve and
            // check that it is straight:

            LocationCurve lc = wall.Location
              as LocationCurve;

            Curve curve = lc.Curve;
            lines[i] = curve as Line;

            if( null == lines[i] )
            {
              message = _prompt;
              return Result.Failed;
            }

            // Obtain normal vectors
            // and ensure that they are equal,
            // i.e. walls are parallel:

            if( null == normal )
            {
              normal = Util.Normal( lines[i] );
            }
            else
            {
              if( !Util.IsParallel( normal,
            Util.Normal( lines[i] ) ) )
              {
            message = _prompt;
            return Result.Failed;
              }
            }

            // Obtain pick points and project
            // onto wall location lines:

            XYZ p = r.GlobalPoint;
            ir = lines[i].Project( p );

            if( null == ir )
            {
              message = string.Format(
            "Unable to project pick point {0} "
            + "onto wall location line.",
            i );

              return Result.Failed;
            }

            pts[i] = ir.XYZPoint;

            Debug.Print(
              "Wall {0} id {1} at {2}, {3} --> point {4}",
              i, wall.Id.IntegerValue,
              Util.PointString( lines[i].GetEndPoint( 0 ) ),
              Util.PointString( lines[i].GetEndPoint( 1 ) ),
              Util.PointString( pts[i] ) );

            if( 0 < i )
            {
              // Project dimension point selected on second wall
              // back onto first wall, and ensure that normal
              // points from second wall to first:

              ir = lines[0].Project( pts[1] );
              if( null == ir )
              {
            message = string.Format(
              "Unable to project selected dimension "
              + "line point {0} on second wall onto "
              + "first wall's location line.",
              Util.PointString( pts[1] ) );

            return Result.Failed;
              }
              pts[0] = ir.XYZPoint;
            }

            ++i;
              }

              XYZ v = pts[0] - pts[1];
              if( 0 > v.DotProduct( normal ) )
              {
            normal = -normal;
              }

              // Shoot a ray back from the second
              // picked wall towards first:

              Debug.Print(
            "Shooting ray from {0} in direction {1}",
            Util.PointString( pts[1] ),
            Util.PointString( normal ) );

              View3D view = Get3DView( doc );

              if( null == view )
              {
            message = "No 3D view named '{3D}' found; "
              + "run the View > 3D View command once "
              + "to generate it.";

            return Result.Failed;
              }

              //refs = doc.FindReferencesByDirection(
              //  pts[1], normal, view ); // 2011

              //IList<ReferenceWithContext> refs2
              //  = doc.FindReferencesWithContextByDirection(
              //    pts[1], normal, view ); // 2012

              // In the Revit 2014 API, the call to
              // FindReferencesWithContextByDirection causes a
              // warning saying:
              // "FindReferencesWithContextByDirection is obsolete:
              // This method is deprecated in Revit 2014.
              // Use the ReferenceIntersector class instead."

              ReferenceIntersector ri
            = new ReferenceIntersector(
              walls[0].Id, FindReferenceTarget.Element, view );

              ReferenceWithContext ref2
            = ri.FindNearest( pts[1], normal );

              if( null == ref2 )
              {
            message = "ReferenceIntersector.FindNearest"
              + " returned null!";

            return Result.Failed;
              }

              #region Obsolete code to determine the closest reference
            #if NEED_TO_DETERMINE_CLOSEST_REFERENCE
              // Store the references to the wall surfaces:

              Reference[] surfrefs = new Reference[2] {
            null, null };

              // Find the two closest intersection
              // points on each of the two walls:

              double[] minDistance = new double[2] {
            double.MaxValue,
            double.MaxValue };

              //foreach( Reference r in refs )
              foreach( ReferenceWithContext rc in refs2 )
              {
            // 'Autodesk.Revit.DB.Reference.Element' is
            // obsolete: Property will be removed. Use
            // Document.GetElement(Reference) instead.
            //Element e = r.Element; // 2011

            Reference r = rc.GetReference();
            Element e = doc.GetElement( r ); // 2012

            if( e is Wall )
            {
              i = ids.IndexOf( e.Id.IntegerValue );

              if( -1 < i
            && ElementReferenceType.REFERENCE_TYPE_SURFACE
              == r.ElementReferenceType )
              {
            //GeometryObject g = r.GeometryObject; // 2011
            GeometryObject g = e.GetGeometryObjectFromReference( r ); // 2012

            if( g is PlanarFace )
            {
              PlanarFace face = g as PlanarFace;

              Line line = ( e.Location as LocationCurve )
            .Curve as Line;

              Debug.Print(
            "Wall {0} at {1}, {2} surface {3} "
            + "normal {4} proximity {5}",
            e.Id.IntegerValue,
            Util.PointString( line.GetEndPoint( 0 ) ),
            Util.PointString( line.GetEndPoint( 1 ) ),
            Util.PointString( face.Origin ),
            Util.PointString( face.Normal ),
            rc.Proximity );

              // First reference: assert it is a face on this wall
              // and the distance is half the wall thickness.
              // Second reference: the first reference on the other
              // wall; assert the distance between the two references
              // equals the distance between the wall location lines
              // minus half of the sum of the two wall thicknesses.

              if( rc.Proximity < minDistance[i] )
              {
            surfrefs[i] = r;
            minDistance[i] = rc.Proximity;
              }
            }
              }
            }
              }

              if( null == surfrefs[0] )
              {
            message = "No suitable face intersection "
              + "points found on first wall.";

            return Result.Failed;
              }

              if( null == surfrefs[1] )
              {
            message = "No suitable face intersection "
              + "points found on second wall.";

            return Result.Failed;
              }

              CmdDimensionWallsIterateFaces
            .CreateDimensionElement( doc.ActiveView,
            pts[0], surfrefs[0], pts[1], surfrefs[1] );
            #endif // NEED_TO_DETERMINE_CLOSEST_REFERENCE
              #endregion // Obsolete code to determine the closest reference

              CmdDimensionWallsIterateFaces
            .CreateDimensionElement( doc.ActiveView,
            pts[0], ref2.GetReference(), pts[1], refs.get_Item( 1 ) );

              return Result.Succeeded;
        }
CmdDimensionWallsFindRefs