Example #1
0
        /// <summary>
        /// 寻找给定线段上的障碍物,并按距离排序
        /// 超出线段长度会被忽略
        /// </summary>
        /// <param name="boundLine"></param>
        /// <returns></returns>
        public List <ReferenceWithContext> Obstructions(Line boundLine)
        {
            List <ReferenceWithContext> result = new List <ReferenceWithContext>();
            XYZ start    = boundLine.GetEndPoint(0);
            XYZ end      = boundLine.GetEndPoint(1);
            XYZ direcion = (end - start).Normalize();

            ReferenceIntersector referenceIntersector = new ReferenceIntersector(view3d);

            referenceIntersector.TargetType = FindReferenceTarget.Face;
            IList <ReferenceWithContext> obstructionsOnUnboundLine = referenceIntersector.Find(start, direcion);

            foreach (ReferenceWithContext gRefWithContext in obstructionsOnUnboundLine)
            {
                Reference gRef = gRefWithContext.GetReference();
                //如果点到线段的距离 为0,说明点在直线上
                if (boundLine.Distance(gRef.GlobalPoint) < 1e-9)
                {
                    if (!InArray(result, gRefWithContext))
                    {
                        result.Add(gRefWithContext);
                    }
                }
            }
            result.Sort(CompareReferencesWithContext);

            return(result);
        }
        public List <XYZ> GetWallOpenings(Element wall, double eyeLevel, View3D view)
        {
            List <XYZ> somePoints = new List <XYZ>();


            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     offset       = new UV(wallDirection.X, wallDirection.Y);
            double step_outside = offset.GetLength();

            XYZ rayStart = new XYZ(wallOrigin.X - offset.U, wallOrigin.Y - offset.V, eyeLevel);

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

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

            List <XYZ> pointList = new List <XYZ>(refs.Select <ReferenceWithContext, XYZ>(r => r.GetReference().GlobalPoint));

            //TaskDialog.Show("title", pointList.Count.ToString());

            if (pointList.Count() >= 4)
            {
                pointList.RemoveAt(0);
                pointList.RemoveAt(0);
                somePoints.AddRange(pointList);
            }


            return(somePoints);
        }
Example #3
0
        /// <summary>
        /// Finds columns by projecting rays along a given direction.
        /// </summary>
        /// <param name="rayStart">The origin of the ray.</param>
        /// <param name="rayDirection">The direction of the ray.</param>
        /// <param name="within">The maximum distance away that columns may be found.</param>
        /// <param name="wall">The wall that this search is associated with.</param>
        private void FindColumnsByDirection(XYZ rayStart, XYZ rayDirection, double within, Wall wall)
        {
            ReferenceIntersector         referenceIntersector  = new ReferenceIntersector(m_view3D);
            IList <ReferenceWithContext> intersectedReferences = referenceIntersector.Find(rayStart, rayDirection);

            FindColumnsWithin(intersectedReferences, within, wall);
        }
Example #4
0
        public static double Gethsfs(Document doc, Room piece, ElementCategoryFilter filtresol)
        {
            double hsfs = 0.00;

            // on verifie si sol au dessus de piece
            try
            {
                LocationPoint locpiece = piece.Location as LocationPoint;
                XYZ           ptpiece  = locpiece.Point;
                ptpiece = new XYZ(ptpiece.X, ptpiece.Y, ptpiece.Z + 0.05);
                XYZ vecteurpiece               = new XYZ(0, 0, 1);
                ReferenceIntersector refi      = new ReferenceIntersector(filtresol, FindReferenceTarget.Face, (View3D)doc.ActiveView);
                ReferenceWithContext refc      = refi.FindNearest(ptpiece, vecteurpiece);
                Reference            reference = refc.GetReference();
                XYZ intpoint = reference.GlobalPoint;
                hsfs = ptpiece.DistanceTo(intpoint);
                hsfs = UnitUtils.ConvertFromInternalUnits(hsfs, DisplayUnitType.DUT_METERS);
                hsfs = Math.Round(hsfs, 2);
                //MessageBox.Show(string.Format("hauteur sous dalle : {0}", hsfs));
            }
            catch (Exception)
            {
                //MessageBox.Show("pas de sol au dessus de la piece","erreur");
                hsfs = 0.00;
            }
            return(hsfs);
        }
Example #5
0
        /// <summary>
        /// Determines the line segment that connects the skylight to the already obtained floor.
        /// </summary>
        /// <returns>The line segment.</returns>
        private Line CalculateLineAboveFloor()
        {
            // Use the center of the skylight bounding box as the start point.
            BoundingBoxXYZ box    = m_skylight.get_BoundingBox(m_view3D);
            XYZ            center = box.Min.Add(box.Max).Multiply(0.5);

            // Project in the negative Z direction down to the floor.
            XYZ rayDirection = new XYZ(0, 0, -1);

            // Look for references to faces where the element is the floor element id.
            ReferenceIntersector         referenceIntersector = new ReferenceIntersector(m_floor.Id, FindReferenceTarget.Face, m_view3D);
            IList <ReferenceWithContext> references           = referenceIntersector.Find(center, rayDirection);

            double distance     = Double.PositiveInfinity;
            XYZ    intersection = null;

            foreach (ReferenceWithContext referenceWithContext in references)
            {
                Reference reference = referenceWithContext.GetReference();
                // Keep the closest matching reference (using the proximity parameter to determine closeness).
                double proximity = referenceWithContext.Proximity;
                if (proximity < distance)
                {
                    distance     = proximity;
                    intersection = reference.GlobalPoint;
                }
            }

            // Create line segment from the start point and intersection point.
            Line result = Line.CreateBound(center, intersection);

            return(result);
        }
        /////////////////////////////////////////////////////////////////////////////////////////

        //////////////////   Fire a reference intersector with filters   ////////////////////////
        public IList <ElementId> Fire(Document doc, LocationPoint pXYZ)
        {
            IList <ElementId> returnId = new List <ElementId>();

            //limit depth of ray cast
            double limit = 10;

            //setup parameters for raycast
            View3D view      = Get3DView(doc);
            XYZ    direction = new XYZ(0, 0, -1);
            XYZ    origin    = pXYZ.Point;

            ElementCategoryFilter roofFilter  = new ElementCategoryFilter(BuiltInCategory.OST_Roofs);
            ElementCategoryFilter floorFilter = new ElementCategoryFilter(BuiltInCategory.OST_Floors);
            LogicalOrFilter       orFilter    = new LogicalOrFilter(roofFilter, floorFilter);

            //cast ray, found elements are stored in array as References with proximity data attached
            ReferenceIntersector         refIntersector       = new ReferenceIntersector(orFilter, FindReferenceTarget.Element, view);
            IList <ReferenceWithContext> referenceWithContext = refIntersector.Find(origin, direction).Where(w => w.Proximity < limit).OrderBy(o => o.Proximity).ToList();

            //iterate through array, store Elements with proximity < limit to ElementId array
            foreach (ReferenceWithContext rC in referenceWithContext)
            {
                returnId.Add(doc.GetElement(rC.GetReference()).GetTypeId());
            }
            if (returnId.Count < 1)
            {
                return(null);
            }
            return(returnId);
        }
Example #7
0
        // http://thebuildingcoder.typepad.com/blog/2010/01/findreferencesbydirection.html#comment-4055509541
        /// <summary>
        /// Return reference to ceiling face to place
        /// lighting fixture above a given point.
        /// </summary>
        Reference GetCeilingReferenceAbove(
            View3D view,
            XYZ p)
        {
            ElementClassFilter filter = new ElementClassFilter(
                typeof(Ceiling));

            ReferenceIntersector refIntersector
                = new ReferenceIntersector(filter,
                                           FindReferenceTarget.Face, view);

            refIntersector.FindReferencesInRevitLinks = true;

            ReferenceWithContext rwc = refIntersector.FindNearest(
                p, XYZ.BasisZ);

            Reference r = (null == rwc)
        ? null
        : rwc.GetReference();

            if (null == r)
            {
                System.Windows.MessageBox.Show("no intersecting geometry");
            }
            return(r);
        }
Example #8
0
        private List <double> GetDistancesToFloors(Document doc, View3D view3D, Room room)
        {
            LocationPoint point  = room.Location as LocationPoint;
            XYZ           origin = point.Point;
            XYZ           center = new XYZ(point.Point.X, point.Point.Y, point.Point.Z + 0.01);
            // Project in the positive Z direction up to the floor.
            XYZ rayDirection = new XYZ(0, 0, 1);

            ElementClassFilter filter = new ElementClassFilter(typeof(Floor));

            ReferenceIntersector refIntersector = new ReferenceIntersector(filter, FindReferenceTarget.Face, view3D);

            refIntersector.FindReferencesInRevitLinks = true;
            IList <ReferenceWithContext> referencesWithContext = refIntersector.Find(center, rayDirection);

            IList <Reference>           intersectRefs            = new List <Reference>();
            Dictionary <Reference, XYZ> dictProvisionForVoidRefs = new Dictionary <Reference, XYZ>();
            List <double> result = new List <double>();

            foreach (ReferenceWithContext r in referencesWithContext)
            {
                XYZ  intersection = r.GetReference().GlobalPoint;
                Line line         = Line.CreateBound(origin, intersection);
                result.Add(line.Length);
            }
            result.Sort();
            return(result);
        }
Example #9
0
        /// <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);
        }
Example #10
0
        private void CreateInstancesAndSetLocations(List <XYZ> locations, Room room)
        {
            FilteredElementCollector collector     = new FilteredElementCollector(Doc);
            Func <View3D, bool>      isNotTemplate = v3 => !(v3.IsTemplate);
            View3D view3D = collector.OfClass(typeof(View3D)).Cast <View3D>().First <View3D>(isNotTemplate);

            BoundingBoxXYZ box    = room.get_BoundingBox(view3D);
            XYZ            center = box.Min.Add(box.Max).Multiply(0.5);

            // Project in the negative Z direction down to the floor.
            XYZ rayDirection = new XYZ(0, 0, 1);

            ElementClassFilter filter = new ElementClassFilter(typeof(Floor));

            ReferenceIntersector refIntersector       = new ReferenceIntersector(filter, FindReferenceTarget.Face, view3D);
            ReferenceWithContext referenceWithContext = refIntersector.FindNearest(center, rayDirection);

            Reference reference = referenceWithContext.GetReference();

            var el     = Doc.GetElement(reference);
            var ids    = string.Empty;
            var vector = new XYZ(1, 0, 0);

            for (int i = 0; i < locations.Count; i++)
            {
                var fi = App.ActiveUIDocument.Document.Create.NewFamilyInstance(reference, locations[i], vector, this.symbol);
                ids += fi.Id.IntegerValue.ToString() + ";";
            }
        }
Example #11
0
        private double CenterToBorder(XYZ targetDirection, FamilyInstance targetFamilyInstance)
        {
            ReferenceIntersector rayCaster = new ReferenceIntersector(targetFamilyInstance.Id, FindReferenceTarget.Face, doc.ActiveView as View3D);
            BoundingBoxXYZ       familyBB  = targetFamilyInstance.get_BoundingBox(null);

            Location familyLocation = targetFamilyInstance.Location;
            XYZ      objectCenter   = Utils.GetPoint.getMidPoint(familyBB.Min, familyBB.Max);

            if (familyLocation is LocationPoint)
            {
                LocationPoint familyPoint = targetFamilyInstance.Location as LocationPoint;
                objectCenter = new XYZ(familyPoint.Point.X, familyPoint.Point.Y, objectCenter.Z);
            }
            else
            {
                LocationCurve familyCurve = targetFamilyInstance.Location as LocationCurve;
                XYZ           midPoint    = Utils.GetPoint.getMidPoint(familyCurve.Curve.GetEndPoint(1), familyCurve.Curve.GetEndPoint(0));
                Line          line        = (familyCurve.Curve as Line);
                if (line == null)
                {
                    return(0);
                }
                XYZ    direct          = line.Direction;
                XYZ    cross           = XYZ.BasisZ.CrossProduct(direct);
                double offset          = targetFamilyInstance.get_Parameter(BuiltInParameter.Y_OFFSET_VALUE).AsDouble();
                XYZ    offsetFromMidle = cross.Multiply(offset);
                objectCenter = midPoint.Add(offsetFromMidle);
            }


            IList <ReferenceWithContext> hitFaces = rayCaster.Find(objectCenter, targetDirection);
            ReferenceWithContext         refFace  = null;

            if (hitFaces != null)
            {
                if (hitFaces.Count > 0)
                {
                    refFace = hitFaces.LastOrDefault();
                }
            }

            if (refFace != null)
            {
                //FamilySymbol pSafe = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_GenericModel)
                //    .WhereElementIsElementType().Where(t => t.Name == "DebugPointSafe").FirstOrDefault() as FamilySymbol;

                //using (Transaction ta = new Transaction(doc, "hey"))
                //{
                //    ta.Start();
                //    doc.Create.NewFamilyInstance(refFace.GetReference().GlobalPoint, pSafe, Autodesk.Revit.DB.Structure.StructuralType.NonStructural);
                //    doc.Create.NewFamilyInstance(objectCenter, pSafe, Autodesk.Revit.DB.Structure.StructuralType.NonStructural);

                //    ta.Commit();
                //}
                return(refFace.GetReference().GlobalPoint.DistanceTo(objectCenter));
            }

            return(0);
        }
Example #12
0
        public override void Evaluate(FSharpList <FScheme.Value> args, Dictionary <PortData, FScheme.Value> outPuts)
        {
            var origin    = (XYZ)((FScheme.Value.Container)args[0]).Item;
            var direction = (XYZ)((FScheme.Value.Container)args[1]).Item;
            var rayLimit  = ((FScheme.Value.Number)args[2]).Item;
            var view      = (View3D)((FScheme.Value.Container)args[3]).Item;

            XYZ startpt  = origin;
            int rayCount = 0;

            var bouncePts      = FSharpList <FScheme.Value> .Empty;
            var bounceElements = FSharpList <FScheme.Value> .Empty;

            bouncePts = FSharpList <FScheme.Value> .Cons(FScheme.Value.NewContainer(origin), bouncePts);

            for (int ctr = 1; ctr <= rayLimit; ctr++)
            {
                var referenceIntersector = new ReferenceIntersector(view);
                IList <ReferenceWithContext> references = referenceIntersector.Find(startpt, direction);
                ReferenceWithContext         rClosest   = null;
                rClosest = FindClosestReference(references);
                if (rClosest == null)
                {
                    break;
                }
                else
                {
                    var reference        = rClosest.GetReference();
                    var referenceElement = dynRevitSettings.Doc.Document.GetElement(reference);
                    bounceElements = FSharpList <FScheme.Value> .Cons(FScheme.Value.NewContainer(referenceElement), bounceElements);

                    var referenceObject = referenceElement.GetGeometryObjectFromReference(reference);
                    var endpt           = reference.GlobalPoint;
                    if (startpt.IsAlmostEqualTo(endpt))
                    {
                        break;
                    }
                    else
                    {
                        rayCount = rayCount + 1;
                        currFace = referenceObject as Face;
                        var endptUV    = reference.UVPoint;
                        var FaceNormal = currFace.ComputeDerivatives(endptUV).BasisZ;                          // face normal where ray hits
                        FaceNormal = rClosest.GetInstanceTransform().OfVector(FaceNormal);                     // transformation to get it in terms of document coordinates instead of the parent symbol
                        var directionMirrored = direction - 2 * direction.DotProduct(FaceNormal) * FaceNormal; //http://www.fvastro.org/presentations/ray_tracing.htm
                        direction = directionMirrored;                                                         // get ready to shoot the next ray
                        startpt   = endpt;

                        bouncePts = FSharpList <FScheme.Value> .Cons(FScheme.Value.NewContainer(endpt), bouncePts);
                    }
                }
            }
            bouncePts.Reverse();
            bounceElements.Reverse();

            outPuts[intersections] = FScheme.Value.NewList(bouncePts);
            outPuts[elements]      = FScheme.Value.NewList(bounceElements);
        }
Example #13
0
        /// <summary>
        ///     Gets the nearest planar face by ray that room cener point to element center point.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="elm"></param>
        /// <param name="room"></param>
        /// <param name="doc"></param>
        /// <param name="view"></param>
        /// <returns></returns>
        public static PlanarFace GetNearestPlanarFace <T>(this T elm, SpatialElement room, Document doc, View3D view) where T : Element
        {
            if (elm is null)
            {
                throw new ArgumentNullException(nameof(elm));
            }

            if (room is null)
            {
                throw new ArgumentNullException(nameof(room));
            }

            if (doc is null)
            {
                throw new ArgumentNullException(nameof(doc));
            }

            if (view is null)
            {
                throw new ArgumentNullException(nameof(view));
            }

            var elmCenter = elm.GetBoundingBox(doc).GetBoxCenter();

            var roomCenter = room.GetBoundingBox(doc).GetBoxCenter();

            var direction = (elmCenter - roomCenter).Normalize();

            var elmFilter = new ElementClassFilter(elm.GetType());

            var intersector = new ReferenceIntersector(elmFilter, FindReferenceTarget.Face, view);

            var context = intersector.FindNearest(roomCenter, direction);

            doc.AutoTransaction(() =>
            {
                doc.CreateModelCurve(Line.CreateBound(roomCenter, elmCenter), out _);
            });

            if (context == null)
            {
                return(null);
            }

            var reference = context.GetReference();

            var refElm = doc.GetElement(reference.ElementId);

            var face = refElm.GetGeometryObjectFromReference(reference) as Face;

            if (face is PlanarFace planarFace)
            {
                return(planarFace);
            }

            return(null);
        }
Example #14
0
        public override void Evaluate(FSharpList<FScheme.Value> args, Dictionary<PortData, FScheme.Value> outPuts)
        {
            var origin = (XYZ)((FScheme.Value.Container)args[0]).Item;
            var direction = (XYZ)((FScheme.Value.Container)args[1]).Item;
            var rayLimit = ((FScheme.Value.Number)args[2]).Item;
            var view = (View3D)((FScheme.Value.Container)args[3]).Item;

            XYZ startpt = origin;
            int rayCount = 0;

            var bouncePts = FSharpList<FScheme.Value>.Empty;
            var bounceElements = FSharpList<FScheme.Value>.Empty;
            bouncePts = FSharpList<FScheme.Value>.Cons(FScheme.Value.NewContainer(origin), bouncePts);

            for (int ctr = 1; ctr <= rayLimit; ctr++)
            {
                var referenceIntersector = new ReferenceIntersector(view);
                IList<ReferenceWithContext> references = referenceIntersector.Find(startpt, direction);
                ReferenceWithContext rClosest = null;
                rClosest = FindClosestReference(references);
                if (rClosest == null)
                {
                    break;
                }
                else
                {
                    var reference = rClosest.GetReference();
                    var referenceElement = dynRevitSettings.Doc.Document.GetElement(reference);
                    bounceElements = FSharpList<FScheme.Value>.Cons(FScheme.Value.NewContainer(referenceElement), bounceElements);
                    var referenceObject = referenceElement.GetGeometryObjectFromReference(reference);
                    var endpt = reference.GlobalPoint;
                    if (startpt.IsAlmostEqualTo(endpt))
                    {
                        break;
                    }
                    else
                    {
                        rayCount = rayCount + 1;
                        currFace = referenceObject as Face;
                        var endptUV = reference.UVPoint;
                        var FaceNormal = currFace.ComputeDerivatives(endptUV).BasisZ;  // face normal where ray hits
                        FaceNormal = rClosest.GetInstanceTransform().OfVector(FaceNormal); // transformation to get it in terms of document coordinates instead of the parent symbol
                        var directionMirrored = direction - 2 * direction.DotProduct(FaceNormal) * FaceNormal; //http://www.fvastro.org/presentations/ray_tracing.htm
                        direction = directionMirrored; // get ready to shoot the next ray
                        startpt = endpt;

                        bouncePts = FSharpList<FScheme.Value>.Cons(FScheme.Value.NewContainer(endpt), bouncePts);
                    }
                }
            }
            bouncePts.Reverse();
            bounceElements.Reverse();

            outPuts[intersections] = FScheme.Value.NewList(bouncePts);
            outPuts[elements] = FScheme.Value.NewList(bounceElements);
        }
        /// <summary>
        /// Determine walls in linked file intersecting pipe
        /// </summary>
        public void GetWalls(UIDocument uidoc)
        {
            Document doc = uidoc.Document;

            Reference pipeRef = uidoc.Selection.PickObject(
                ObjectType.Element);

            Element pipeElem = doc.GetElement(pipeRef);

            LocationCurve lc    = pipeElem.Location as LocationCurve;
            Curve         curve = lc.Curve;

            ReferenceComparer reference1 = new ReferenceComparer();

            ElementFilter filter = new ElementCategoryFilter(
                BuiltInCategory.OST_Walls);

            FilteredElementCollector collector
                = new FilteredElementCollector(doc);

            Func <View3D, bool> isNotTemplate = v3 => !(v3.IsTemplate);
            View3D view3D = collector
                            .OfClass(typeof(View3D))
                            .Cast <View3D>()
                            .First <View3D>(isNotTemplate);

            ReferenceIntersector refIntersector
                = new ReferenceIntersector(
                      filter, FindReferenceTarget.Element, view3D);

            refIntersector.FindReferencesInRevitLinks = true;
            IList <ReferenceWithContext> referenceWithContext
                = refIntersector.Find(
                      curve.GetEndPoint(0),
                      (curve as Line).Direction);

            IList <Reference> references
                = referenceWithContext
                  .Select(p => p.GetReference())
                  .Distinct(reference1)
                  .Where(p => p.GlobalPoint.DistanceTo(
                             curve.GetEndPoint(0)) < curve.Length)
                  .ToList();

            IList <Element> walls = new List <Element>();

            foreach (Reference reference in references)
            {
                RevitLinkInstance instance = doc.GetElement(reference)
                                             as RevitLinkInstance;
                Document linkDoc = instance.GetLinkDocument();
                Element  element = linkDoc.GetElement(reference.LinkedElementId);
                walls.Add(element);
            }
            TaskDialog.Show("Count of wall", walls.Count.ToString());
        }
Example #16
0
        public static Dictionary <string, object> ByOriginDirection(Point origin, Vector direction, int maxBounces, Elements.Views.View3D view)
        {
            var startpt  = origin.ToXyz();
            var rayCount = 0;

            var bouncePts = new List <Point> {
                origin
            };
            var bounceElements = new List <Elements.Element>();

            for (int ctr = 1; ctr <= maxBounces; ctr++)
            {
                var referenceIntersector = new ReferenceIntersector((View3D)view.InternalElement);
                IList <ReferenceWithContext> references = referenceIntersector.Find(startpt, direction.ToXyz());
                ReferenceWithContext         rClosest   = null;
                rClosest = FindClosestReference(references);
                if (rClosest == null)
                {
                    break;
                }
                else
                {
                    var reference        = rClosest.GetReference();
                    var referenceElement = DocumentManager.Instance.CurrentDBDocument.GetElement(reference);
                    var referenceObject  = referenceElement.GetGeometryObjectFromReference(reference);
                    bounceElements.Add(referenceElement.ToDSType(true));
                    var endpt = reference.GlobalPoint;
                    if (startpt.IsAlmostEqualTo(endpt))
                    {
                        break;
                    }
                    else
                    {
                        rayCount = rayCount + 1;
                        var currFace   = referenceObject as Face;
                        var endptUV    = reference.UVPoint;
                        var FaceNormal = currFace.ComputeDerivatives(endptUV).BasisZ;                                          // face normal where ray hits
                        FaceNormal = rClosest.GetInstanceTransform().OfVector(FaceNormal);                                     // transformation to get it in terms of document coordinates instead of the parent symbol
                        var directionMirrored = direction.ToXyz() - 2 * direction.ToXyz().DotProduct(FaceNormal) * FaceNormal; //http://www.fvastro.org/presentations/ray_tracing.htm
                        direction = directionMirrored.ToVector();                                                              // get ready to shoot the next ray
                        startpt   = endpt;
                        bouncePts.Add(endpt.ToPoint());
                    }
                }
            }

            return(new Dictionary <string, object>
            {
                { "points", bouncePts },
                { "elements", bounceElements }
            });
        }
Example #17
0
        /// <summary>
        ///     Gets planar face list by ray that room cener point to element center point.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="elm"></param>
        /// <param name="room"></param>
        /// <param name="doc"></param>
        /// <param name="view"></param>
        /// <returns></returns>
        public static List <PlanarFace> GetPlanarFaceList <T>(this T elm, SpatialElement room, Document doc, View3D view) where T : Element
        {
            if (elm is null)
            {
                throw new ArgumentNullException(nameof(elm));
            }

            if (room is null)
            {
                throw new ArgumentNullException(nameof(room));
            }

            if (doc is null)
            {
                throw new ArgumentNullException(nameof(doc));
            }

            if (view is null)
            {
                throw new ArgumentNullException(nameof(view));
            }

            var elmCenter = elm.GetBoundingBox(doc).GetBoxCenter();

            var roomCenter = room.GetBoundingBox(doc).GetBoxCenter();

            var direction = (elmCenter - roomCenter).Normalize();

            var elmFilter = new ElementClassFilter(elm.GetType());

            var intersector = new ReferenceIntersector(elmFilter, FindReferenceTarget.Face, view);

            var contexts = intersector.Find(roomCenter, direction);

            var results = new List <PlanarFace>();

            foreach (var context in contexts)
            {
                var reference = context.GetReference();

                var refElm = doc.GetElement(reference.ElementId);

                var face = refElm.GetGeometryObjectFromReference(reference) as Face;

                if (face is PlanarFace planarFace)
                {
                    results.Add(planarFace);
                }
            }

            return(results);
        }
        //method to extend the rod height to structure above
        public static double StructureHeight(XYZ point, Document m_document)
        {
            try
            {
                double leastProximity = 0;

                //create an instance of the refernce intersector and make it to intersect in Elements and revit links
                ReferenceIntersector intersector = new ReferenceIntersector(view3D);
                intersector.TargetType = FindReferenceTarget.Element;
                intersector.FindReferencesInRevitLinks = true;

                //find the points of intersection
                IList <ReferenceWithContext> referenceWithContext = intersector.Find(point, XYZ.BasisZ);

                //remove the intersection on the element inside which the point lies
                for (int i = 0; i < referenceWithContext.Count; i++)
                {
                    if (m_document.GetElement(referenceWithContext[i].GetReference()).GetType().Name != "RevitLinkInstance")
                    {
                        referenceWithContext.RemoveAt(i);
                        i--;
                    }
                }

                if (referenceWithContext.Count != 0)
                {
                    //find the least proximity
                    leastProximity = referenceWithContext.First().Proximity;

                    for (int i = 0; i < referenceWithContext.Count; i++)
                    {
                        if (leastProximity > referenceWithContext[i].Proximity)
                        {
                            leastProximity = referenceWithContext[i].Proximity;
                        }
                    }
                }
                if (leastProximity <= 10)
                {
                    return(leastProximity);
                }
                else
                {
                    return(0);
                }
            }
            catch
            {
                throw new Exception();
            }
        }
Example #19
0
        private XYZ ProjectPoint(Document doc, Reference refFace, XYZ point, XYZ rayDirection)
        {
            View3D active3D = doc.ActiveView as View3D;

            ReferenceIntersector refIntersector = new ReferenceIntersector(refFace.ElementId, FindReferenceTarget.Face, active3D);

            ReferenceWithContext referenceWithContext = refIntersector.FindNearest(point, rayDirection);

            Reference reference = referenceWithContext.GetReference();

            XYZ intersection = reference.GlobalPoint;

            return(intersection);
        }
        public static IEnumerable <XYZ> GetPointProjectedVertically(View3D view, ElementId targetId, XYZ pointOfInterest)
        {
            //Move the point WAY down so that it is guaranteed (well almost) to be below target element
            //Everest is 29000ft so if we use 50000ft should be within typical working range :).
            var projectionBasePoint = pointOfInterest.Subtract(new XYZ(0, 0, 50000));


            //find all points of intersection between the target element and a vertical ray
            var intersector = new ReferenceIntersector(targetId, FindReferenceTarget.Element, view);
            var rwcList     = intersector.Find(projectionBasePoint, XYZ.BasisZ);

            return(from r in rwcList
                   select r.GetReference().GlobalPoint);
        }
Example #21
0
        public static Dictionary<string,object> ByOriginDirection(Point origin, Vector direction, int maxBounces, Elements.Views.View3D view)
        {
            var startpt = origin.ToXyz();
            var rayCount = 0;

            var bouncePts = new List<Point> {origin};
            var bounceElements = new List<Elements.Element>();

            for (int ctr = 1; ctr <= maxBounces; ctr++)
            {
                var referenceIntersector = new ReferenceIntersector((View3D)view.InternalElement);
                IList<ReferenceWithContext> references = referenceIntersector.Find(startpt, direction.ToXyz());
                ReferenceWithContext rClosest = null;
                rClosest = FindClosestReference(references);
                if (rClosest == null)
                {
                    break;
                }
                else
                {
                    var reference = rClosest.GetReference();
                    var referenceElement = DocumentManager.Instance.CurrentDBDocument.GetElement(reference);
                    var referenceObject = referenceElement.GetGeometryObjectFromReference(reference);
                    bounceElements.Add(referenceElement.ToDSType(true));
                    var endpt = reference.GlobalPoint;
                    if (startpt.IsAlmostEqualTo(endpt))
                    {
                        break;
                    }
                    else
                    {
                        rayCount = rayCount + 1;
                        var currFace = referenceObject as Face;
                        var endptUV = reference.UVPoint;
                        var FaceNormal = currFace.ComputeDerivatives(endptUV).BasisZ;  // face normal where ray hits
                        FaceNormal = rClosest.GetInstanceTransform().OfVector(FaceNormal); // transformation to get it in terms of document coordinates instead of the parent symbol
                        var directionMirrored = direction.ToXyz() - 2 * direction.ToXyz().DotProduct(FaceNormal) * FaceNormal; //http://www.fvastro.org/presentations/ray_tracing.htm
                        direction = directionMirrored.ToVector(); // get ready to shoot the next ray
                        startpt = endpt;
                        bouncePts.Add(endpt.ToPoint());
                    }
                }
            }

            return new Dictionary<string, object>
            {
                { "points", bouncePts },
                { "elements", bounceElements }
            };
        }
Example #22
0
        public Result OLET(ElementSymbol elementSymbol)
        {
            try
            {
                //Get all pipe connectors
                var allConnectors = ch.GetALLConnectors(pif._doc);

                //Determine the branch1point of the olet which is the connection to the olet pipe
                XYZ bp1 = elementSymbol.Branch1Point.Xyz;
                XYZ cp  = elementSymbol.CentrePoint.Xyz;

                Pipe pipe1 = null;
                //Pipe pipe2 = null;

                pipe1 = ch.CreateDummyPipe(bp1, elementSymbol.CentrePoint.Xyz, elementSymbol.Branch1Point, elementSymbol);
                var c1 = ch.MatchConnector(bp1, pipe1);

                ////Determine the corresponding pipe connector to bp1
                //var c1 = (from Connector c in allConnectors where Util.IsEqual(bp1, c.Origin) select c).FirstOrDefault();
                ////Get the owner of the connector
                //var owner = c1.Owner;

                //Find the target pipe
                var filter               = new ElementClassFilter(typeof(Pipe));
                var view3D               = ch.Get3DView(pif._doc);
                var refIntersect         = new ReferenceIntersector(filter, FindReferenceTarget.Element, view3D);
                ReferenceWithContext rwc = refIntersect.FindNearest(c1.Origin, c1.CoordinateSystem.BasisZ);
                var refId             = rwc.GetReference().ElementId;
                var pipeToConnectInto = (MEPCurve)pif._doc.GetElement(refId);

                if (c1 != null)
                {
                    Element element = PCFImport.doc.Create.NewTakeoffFitting(c1, pipeToConnectInto);
                    if (pipe1 != null)
                    {
                        PCFImport.doc.Delete(pipe1.Id);
                    }
                    //if (pipe2 != null) PCFImport.doc.Delete(pipe2.Id);
                    elementSymbol.CreatedElement = element;
                    PCFImport.doc.Regenerate();
                    return(Result.Succeeded);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
            //If this point is reached, something has failed
            return(Result.Failed);
        }
        //method to extend the rod height to structure above
        public static double ExtendRod(XYZ point, Document m_document, View3D view3D)
        {
            double leastProximity = -1.0;

            try
            {
                //create an instance of the refernce intersector and make it to intersect in Elements and revit links
                ReferenceIntersector intersector = new ReferenceIntersector(view3D);
                intersector.TargetType = FindReferenceTarget.Element;
                intersector.FindReferencesInRevitLinks = true;

                //find the points of intersection
                IList <ReferenceWithContext> referenceWithContext = intersector.Find(point, XYZ.BasisZ);

                //remove the intersection on the pipe inside which the point lies
                for (int i = 0; i < referenceWithContext.Count; i++)
                {
                    if (m_document.GetElement(referenceWithContext[i].GetReference()).GetType().Name != "RevitLinkInstance")
                    {
                        referenceWithContext.RemoveAt(i);
                        i--;
                    }
                }

                //if the referncewithcontext is empty return to the calling method
                if (referenceWithContext.Count == 0)
                {
                    return(-1);
                }

                //find the least proximity
                leastProximity = referenceWithContext.First().Proximity;

                for (int i = 0; i < referenceWithContext.Count; i++)
                {
                    if (leastProximity > referenceWithContext[i].Proximity)
                    {
                        leastProximity = referenceWithContext[i].Proximity;
                    }
                }
            }
            catch
            {
                return(-1);
            }
            //return least proximity found above
            return(leastProximity);
        }
Example #24
0
        /// <summary>
        /// 寻找与光线相交的柱子
        /// </summary>
        /// <param name="rayStart"></param>
        /// <param name="rayDirection"></param>
        /// <param name="proximity"></param>
        /// <param name="wall"></param>
        private void FindColumnsByDirection(XYZ rayStart, XYZ rayDirection, double proximity, Wall wall)
        {
            ReferenceIntersector         referenceIntersector  = new ReferenceIntersector(m_view3D);
            IList <ReferenceWithContext> intersectedReferences = referenceIntersector.Find(rayStart, rayDirection);

            //处理找到的柱子,加入集合中
            foreach (ReferenceWithContext reference in intersectedReferences)
            {
                // Exclude items too far from the start point.
                if (reference.Proximity < proximity)
                {
                    Element referenceElement = wall.Document.GetElement(reference.GetReference());
                    if (referenceElement is FamilyInstance)
                    {
                        FamilyInstance familyInstance   = (FamilyInstance)referenceElement;
                        ElementId      familyInstanceId = familyInstance.Id;
                        ElementId      wallId           = wall.Id;
                        int            categoryIdValue  = referenceElement.Category.Id.IntegerValue;
                        if (categoryIdValue == (int)BuiltInCategory.OST_Columns || categoryIdValue == (int)BuiltInCategory.OST_StructuralColumns)
                        {
                            // Add the column to the map of wall->columns
                            if (m_columnsOnWall.ContainsKey(wallId))
                            {
                                List <ElementId> columnsOnWall = m_columnsOnWall[wallId];
                                if (!columnsOnWall.Contains(familyInstanceId))
                                {
                                    columnsOnWall.Add(familyInstanceId);
                                }
                            }
                            else
                            {
                                List <ElementId> columnsOnWall = new List <ElementId>();
                                columnsOnWall.Add(familyInstanceId);
                                m_columnsOnWall.Add(wallId, columnsOnWall);
                            }
                            // Add the column to the complete list of all embedded columns
                            if (!m_allColumnsOnWalls.Contains(familyInstanceId))
                            {
                                m_allColumnsOnWalls.Add(familyInstanceId);
                            }
                        } //end if is column
                    }     //end if is instance
                }         //end if is in wallLength
            }             //end foreach
        }
Example #25
0
        //TODO: Write a test to ensure this actually intersects itself
        private bool IntersectsWithOwner(Connector c)
        {
            ReferenceWithContext intersectedReference =
                new ReferenceIntersector(                           // shoots a ray from the connector's face
                    c.Owner.Id,                                     // element it looks for intersection with
                    FindReferenceTarget.All,                        // look for all intersections because this should hit it's owner first anyway if they intersect
                    CurrentDocument.Create3DView()).                // newly created 3DView
                FindNearest(c.Origin, c.CoordinateSystem.BasisZ);   // gives the normal from the connector's face

            // if the object returned is not null AND is the element itself, the connector intersects with it
            if (null != intersectedReference.GetReference() &&
                intersectedReference.GetReference() == new Reference(c.Owner))
            {
                return(true);
            }

            return(false);
        }
        //method to find parallel trays/ducts from the list
        public static List <Element> ParallelElements(XYZ point, Document m_document, ICollection <ElementId> parallels)
        {
            try
            {
                List <Element> intersected = new List <Element>();

                //create an instance of the refernce intersector and make it to intersect in Elements in list
                ReferenceIntersector intersector = new ReferenceIntersector(parallels, FindReferenceTarget.Element, view3D);
                intersector.FindReferencesInRevitLinks = false;

                //find the points of intersection in upward direction
                IList <ReferenceWithContext> referContUp = intersector.Find(point, XYZ.BasisZ);

                //find the points of intersection in downward direction
                IList <ReferenceWithContext> referContDown = intersector.Find(point, -XYZ.BasisZ);

                for (int i = 0; i < referContUp.Count; i++)
                {
                    if ((m_document.GetElement(referContUp[i].GetReference()) is CableTray) ||
                        (m_document.GetElement(referContUp[i].GetReference()) is Duct))
                    {
                        intersected.Add(m_document.GetElement(referContUp[i].GetReference()));
                    }
                }

                for (int i = 0; i < referContDown.Count; i++)
                {
                    if ((m_document.GetElement(referContDown[i].GetReference()) is CableTray) ||
                        (m_document.GetElement(referContDown[i].GetReference()) is Duct))
                    {
                        intersected.Add(m_document.GetElement(referContDown[i].GetReference()));
                    }
                }

                intersected = intersected.Distinct().ToList();

                return(intersected);
            }
            catch
            {
                throw new Exception();
            }
        }
Example #27
0
        /// <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);
        }
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            var uiApp = commandData.Application;
            var uiDoc = uiApp.ActiveUIDocument;
            var app   = uiApp.Application;
            var doc   = uiDoc.Document;

            // Start code here

            // Lay nhung doi tuong dang chon
            try
            {
                var refObject = uiDoc.Selection.PickObject(ObjectType.Element);
                var elementId = refObject.ElementId;
                var element   = doc.GetElement(elementId);

                //Bộ lọc các đối tượng cần tính toán giao điểm
                var filter = new ElementCategoryFilter(BuiltInCategory.OST_Floors);
                // là đối tượng hướng dẫn để tìm giao điểm
                var refInter = new ReferenceIntersector(filter, FindReferenceTarget.Face, (View3D)doc.ActiveView);

                // điểm cơ sở của vector bạn cần tính toán giao điểm.
                var basePoint = ((LocationPoint)element.Location).Point;
                // điểm chỉ hướng của vector bạn cần tính toán
                var ray = new XYZ(0, 0, 1);

                // trong trường hợp tia chỉ hướng là ngược hướng
                // với hướng mà lẽ ra theo hướng đó, vector mới cắt với mặt phẳng thì sẽ không trả về kế quả nào.
                var refContext = refInter.FindNearest(basePoint, ray);
                var intersectP = refContext.GetReference().GlobalPoint;

                var distacne = UnitUtils.ConvertFromInternalUnits(basePoint.DistanceTo(intersectP), DisplayUnitType.DUT_MILLIMETERS);
                // Lưu ý element location point không nhất thiết là điểm thấp nhất mà là điểm cơ sở của đối tượng
                TaskDialog.Show("Tinh Khoang cach", "Khoỏng cách từ chân cột đến mái là " + distacne);
            }
            catch (Exception e)
            {
                message = e.Message;
                return(Result.Failed);
            }
            return(Result.Succeeded);
        }
Example #29
0
        internal IList <XYZ> ProjectSupportPointsOnRoof(XYZ currentPointOnRidge)
        {
            IList <XYZ> supportPoints = GetEavePointsOnSupports(currentPointOnRidge);

            //if (supportPoints.Count < 1 || supportPoints.Count > 2)
            //    throw new Exception("Invalid number of support points for the truss");

            IList <XYZ> resultingPoints = new List <XYZ>();

            ReferenceIntersector roofIntersector = new ReferenceIntersector(CurrentRoof.Id, FindReferenceTarget.Element, CurrentRoof.Document.ActiveView as View3D);

            foreach (XYZ currentSupportPoint in supportPoints)
            {
                XYZ originPoint = new XYZ(currentSupportPoint.X, currentSupportPoint.Y, GetCurrentRoofHeight() - 1);
                ReferenceWithContext roofIntersContext = roofIntersector.FindNearest(originPoint, XYZ.BasisZ);

                if (roofIntersContext == null)
                {
                    continue;
                }

                XYZ currentHitPoint = roofIntersContext.GetReference().GlobalPoint;
                resultingPoints.Add(currentHitPoint);
            }

            if (resultingPoints.Count == 1)
            {
                if (RoofLineType == RoofLineType.Ridge)
                {
                    if (Support.HasSameSlopes(CurrentRoof))
                    {
                        XYZ  ridgePointFlaten = new XYZ(currentPointOnRidge.X, currentPointOnRidge.Y, resultingPoints[0].Z);
                        Line CrossedRidgeLine = Line.CreateBound(resultingPoints[0], ridgePointFlaten);
                        XYZ  crossedDirection = CrossedRidgeLine.Direction;
                        XYZ  mirroredPoint    = resultingPoints[0].Add(crossedDirection.Multiply(CrossedRidgeLine.ApproximateLength * 2));
                        resultingPoints.Add(mirroredPoint);
                    }
                }
            }

            return(resultingPoints);
        }
Example #30
0
        //method to find parallel trays/ducts from the list
        public static List <Element> ParallelElements(XYZ point, Document m_document, ICollection <ElementId> parallels, XYZ normal)
        {
            try
            {
                List <Element> intersected = new List <Element>();

                //create an instance of the refernce intersector and make it to intersect in Elements in list
                ReferenceIntersector intersector = new ReferenceIntersector(parallels, FindReferenceTarget.Element, view3D);
                intersector.FindReferencesInRevitLinks = false;

                //find the points of intersection in upward direction
                IList <ReferenceWithContext> referContLeft = intersector.Find(point, normal);

                //find the points of intersection in downward direction
                IList <ReferenceWithContext> referContRight = intersector.Find(point, -normal);

                for (int i = 0; i < referContLeft.Count; i++)
                {
                    if ((m_document.GetElement(referContLeft[i].GetReference()) is Pipe) && (referContLeft[i].Proximity < 10))
                    {
                        intersected.Add(m_document.GetElement(referContLeft[i].GetReference()));
                    }
                }

                for (int i = 0; i < referContRight.Count; i++)
                {
                    if ((m_document.GetElement(referContRight[i].GetReference()) is Pipe) && (referContLeft[i].Proximity < 10))
                    {
                        intersected.Add(m_document.GetElement(referContRight[i].GetReference()));
                    }
                }

                intersected = intersected.Distinct().ToList();

                return(intersected);
            }
            catch
            {
                throw new Exception();
            }
        }
Example #31
0
        /// <summary>
        /// Find Elements Intersect By Ray
        /// </summary>
        /// <param name="element"></param>
        /// <param name="categories"></param>
        /// <param name="direction"></param>
        /// <returns></returns>
        public static Autodesk.Revit.DB.XYZ RayIntersect(this Autodesk.Revit.DB.Element element, List <string> categories, XYZ direction)
        {
            // Find a 3D view to use for the ReferenceIntersector constructor

            FilteredElementCollector collector     = new FilteredElementCollector(element.Document);
            Func <View3D, bool>      isNotTemplate = v3 => !(v3.IsTemplate);
            View3D view3D = collector.OfClass(typeof(View3D)).Cast <View3D>().First <View3D>(isNotTemplate);

            // Use the center of the skylight bounding box as the start point.
            BoundingBoxXYZ box    = element.get_BoundingBox(view3D);
            XYZ            center = box.Min.Add(box.Max).Multiply(0.5);
            // Project in the negative Z direction down to the ceiling.
            ElementFilter        elementFilter  = element.Document.FiltersElementByCategory(categories);
            ReferenceIntersector refIntersector = new ReferenceIntersector(elementFilter, FindReferenceTarget.Face, view3D);

            refIntersector.FindReferencesInRevitLinks = true;
            ReferenceWithContext referenceWithContext = refIntersector.FindNearest(center, direction);
            Reference            reference            = referenceWithContext?.GetReference();

            return(reference?.GlobalPoint);
        }
Example #32
0
        /// <summary>
        /// Return the number of walls encountered
        /// between the two given points.
        /// </summary>
        int GetWallCount(XYZ psource, XYZ ptarget)
        {
            double d = ptarget.DistanceTo(psource);

            ReferenceIntersector intersector
                = new ReferenceIntersector(_wallFilter,
                                           FindReferenceTarget.Face, _view3d);

            intersector.FindReferencesInRevitLinks = true;

            IList <ReferenceWithContext> referencesWithContext
                = intersector.Find(psource, ptarget - psource);

            List <ElementId> wallIds = new List <ElementId>();

            foreach (ReferenceWithContext rc in
                     referencesWithContext)
            {
                if (rc.Proximity <= d)
                {
                    Reference r = rc.GetReference();
                    Element   e = _doc.GetElement(r.ElementId);
                    Debug.Assert(e is Wall, "expected only walls");
                    Debug.Print(string.Format("wall {0} at {1}",
                                              e.Id, d));

                    if (!wallIds.Contains(e.Id))
                    {
                        wallIds.Add(e.Id);
                    }
                }
            }
            Debug.Print(
                string.Format("{0} -> {1}: {2} walls",
                              Util.PointString(psource),
                              Util.PointString(ptarget),
                              wallIds.Count));

            return(wallIds.Count);
        }
        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;
        }