Пример #1
0
        /////////////////////////////////////////////////////////////////////////////////////////

        //////////////////   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);
        }
Пример #2
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);
        }
Пример #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);
        }
Пример #4
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);
        }
Пример #5
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);
        }
        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);
        }
Пример #7
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);
        }
Пример #8
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);
        }
Пример #9
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);
        }
Пример #10
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());
        }
        //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();
            }
        }
Пример #13
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();
            }
        }
Пример #14
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 }
            });
        }
Пример #15
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();
            }
        }
        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);
        }
Пример #18
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 }
            };
        }
        //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);
        }
Пример #20
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
        }
Пример #21
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);
        }
Пример #22
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);
        }
Пример #23
0
        //射线法找元素
        private List <FamilyInstance> ReferenceIntersectElement(Document doc, View3D view3d, XYZ origin, XYZ normal)
        {
            ElementClassFilter           filter      = new ElementClassFilter(typeof(FamilyInstance));
            ReferenceIntersector         refInter    = new ReferenceIntersector(filter, FindReferenceTarget.Element, view3d);
            IList <ReferenceWithContext> listContext = refInter.Find(origin, normal);

            List <FamilyInstance> instances = new List <FamilyInstance>();

            foreach (ReferenceWithContext reference in listContext)
            {
                Reference      refer    = reference.GetReference();
                ElementId      id       = refer.ElementId;
                FamilyInstance instance = doc.GetElement(id) as FamilyInstance;

                if (instance.Symbol.Family.Name.Contains("chordFamlily"))
                {
                    instances.Add(instance);
                }
            }

            return(instances);
        }
        List <Reference> 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);

            List <Reference> faceReferenceList
                = new List <Reference>(refs
                                       .Where <ReferenceWithContext>(r => IsSurface(
                                                                         r.GetReference()))
                                       .Where <ReferenceWithContext>(r => r.Proximity
                                                                     < wallLength + _offset + _offset)
                                       .Select <ReferenceWithContext, Reference>(r
                                                                                 => r.GetReference()));

            return(faceReferenceList);
        }
Пример #25
0
        public string FindDoorsInWallWithReferenceIntersector(Document doc, UIDocument uidoc)
        {
            Wall          wall     = doc.GetElement(uidoc.Selection.PickObject(ObjectType.Element)) as Wall;
            LocationCurve locCurve = wall.Location as LocationCurve;
            Curve         curve    = locCurve.Curve;

            XYZ curveTangent = curve.ComputeDerivatives(0.5, true).BasisX;
            XYZ wallEnd      = curve.GetEndPoint(0);

            ElementCategoryFilter filter      = new ElementCategoryFilter(BuiltInCategory.OST_Doors);
            ReferenceIntersector  intersector = new ReferenceIntersector(filter, FindReferenceTarget.Element, (View3D)doc.ActiveView);
            string doorDistanceInfo           = "";

            foreach (ReferenceWithContext refWithContext in intersector.Find(wallEnd, curveTangent))
            {
                double         proximity = refWithContext.Proximity;
                FamilyInstance door      = doc.GetElement(refWithContext.GetReference()) as FamilyInstance;

                doorDistanceInfo += String.Format("{0} - {1} = {2}\n", door.Symbol.Family.Name, door.Name, proximity);
            }

            return(doorDistanceInfo);
        }
        private bool CheckVisibilityByMaterial(ReferenceIntersector intersector, XYZ pointOrigin, List <XYZ> viewPoints)
        {
            bool visible = false;

            try
            {
                foreach (XYZ vPt in viewPoints)
                {
                    XYZ direction = vPt - pointOrigin;
                    IList <ReferenceWithContext> contexts = intersector.Find(pointOrigin, direction);

                    if (null != contexts)
                    {
                        var filteredContexts = from context in contexts where context.Proximity > epsilon select context;
                        filteredContexts = filteredContexts.OrderBy(x => x.Proximity).ToList();

                        if (filteredContexts.Count() > 0)
                        {
                            visible = true;
                            foreach (ReferenceWithContext context in filteredContexts)
                            {
                                Reference reference = context.GetReference();
                                Element   element   = null;
                                Transform transform = Transform.Identity;

                                if (reference.LinkedElementId != ElementId.InvalidElementId)
                                {
                                    //element from linked models
                                    if (linkedInstances.ContainsKey(reference.ElementId.IntegerValue))
                                    {
                                        LinkedInstanceData lid = linkedInstances[reference.ElementId.IntegerValue];
                                        element   = lid.LinkedDocument.GetElement(reference.LinkedElementId);
                                        transform = lid.TransformValue;
                                    }
                                }
                                else
                                {
                                    //element from host
                                    element = m_doc.GetElement(reference.ElementId);
                                }

                                if (null != element)
                                {
                                    int categoryId = element.Category.Id.IntegerValue;
                                    if (categoryId == (int)BuiltInCategory.OST_Walls)
                                    {
                                        Wall wall = element as Wall;
                                        if (null != wall)
                                        {
                                            if (wall.WallType.Kind != WallKind.Curtain)
                                            {
                                                visible = false; break;
                                            }
                                            else
                                            {
                                                var exteriorWalls = from exWall in exteriorElementIds
                                                                    where exWall.LinkInstanceId == reference.ElementId && (exWall.HostElementId == reference.LinkedElementId || exWall.LinkedElementId == reference.LinkedElementId)
                                                                    select exWall;
                                                if (exteriorWalls.Count() > 0)
                                                {
                                                    break; //exterior curtain walls
                                                }
                                            }
                                        }
                                        else
                                        {
                                            //family instance of wall
                                            visible = false; break;
                                        }
                                    }
                                    else if (categoryId == (int)BuiltInCategory.OST_StructuralColumns)
                                    {
                                        visible = false; break;
                                    }
                                    else if (categoryId == (int)BuiltInCategory.OST_Windows || categoryId == (int)BuiltInCategory.OST_Doors || categoryId == (int)BuiltInCategory.OST_CurtainWallPanels)
                                    {
                                        Face face = FindFaceByReference(element, reference, transform);
                                        if (null != face)
                                        {
                                            if (face.MaterialElementId != ElementId.InvalidElementId)
                                            {
                                                Material material = element.Document.GetElement(face.MaterialElementId) as Material;
                                                if (material.Transparency < minTransparency)
                                                {
                                                    visible = false; break;
                                                }
                                            }
                                        }

                                        FamilyInstance instance = element as FamilyInstance;
                                        if (null != instance)
                                        {
                                            if (null != instance.Host)
                                            {
                                                ElementId wallId        = instance.Host.Id;
                                                var       exteriorWalls = from exWall in exteriorElementIds
                                                                          where exWall.LinkInstanceId == reference.ElementId && (exWall.HostElementId == wallId || exWall.LinkedElementId == wallId)
                                                                          select exWall;
                                                if (exteriorWalls.Count() > 0)
                                                {
                                                    break; //exterior curtain walls
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            if (visible)
                            {
                                break; //at least one direction should be visible
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                string message = ex.Message;
            }
            return(visible);
        }
        private static double FindFloorHeight(Document doc, Room room, View3D view)
        {
            double floorHeight = 10;

            try
            {
                LocationPoint locationPoint = room.Location as LocationPoint;
                XYZ           roomPoint     = locationPoint.Point;

                List <ElementFilter> filters = new List <ElementFilter>();
                filters.Add(new ElementCategoryFilter(BuiltInCategory.OST_Roofs));
                filters.Add(new ElementCategoryFilter(BuiltInCategory.OST_Floors));
                filters.Add(new ElementCategoryFilter(BuiltInCategory.OST_RvtLinks));
                LogicalOrFilter orFilter = new LogicalOrFilter(filters);

                ReferenceIntersector intersector = new ReferenceIntersector(orFilter, FindReferenceTarget.Element, view);
                intersector.FindReferencesInRevitLinks = true;
                IList <ReferenceWithContext> contexts = intersector.Find(roomPoint, new XYZ(0, 0, 1));
                if (null != contexts)
                {
                    //floorHeight = 8.0;
                    foreach (ReferenceWithContext context in contexts)
                    {
                        if (context.Proximity > 0)
                        {
                            Reference reference = context.GetReference();
                            Element   element   = null;

                            if (reference.LinkedElementId != ElementId.InvalidElementId)
                            {
                                RevitLinkInstance instance = doc.GetElement(reference.ElementId) as RevitLinkInstance;
                                if (null != instance)
                                {
                                    Document linkedDoc = instance.GetLinkDocument();
                                    if (null != linkedDoc)
                                    {
                                        element = linkedDoc.GetElement(reference.LinkedElementId);
                                    }
                                }
                            }
                            else if (reference.ElementId != ElementId.InvalidElementId)
                            {
                                element = doc.GetElement(reference.ElementId);
                            }

                            if (null != element)
                            {
                                if (null != element.Category)
                                {
                                    if (element.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Floors || element.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Roofs)
                                    {
                                        floorHeight = context.Proximity; break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Failed to find the floor height.\n" + ex.Message, "Find Floor Height", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
            return(floorHeight);
        }
        /// <summary>
        /// Cast a ray in a direction and return all collisions
        /// </summary>
        public static RRay Cast(ModelInfo info, View3D view, List <BuiltInCategory> find_cats, XYZ origin_pt, XYZ ray_dir, double max_distance = -1, List <ElementId> ids_to_ignore = null)
        {
            RRay ray = new RRay
            {
                direction   = ray_dir,
                start_point = origin_pt
            };

            bool prune_lengths = max_distance >= 0;

            ReferenceIntersector ref_intersect = new ReferenceIntersector(
                new ElementMulticategoryFilter(find_cats), FindReferenceTarget.Element, view)
            {
                FindReferencesInRevitLinks = true
            };

            List <ReferenceWithContext> rwcs = new List <ReferenceWithContext>();

            rwcs = ref_intersect.Find(ray.start_point, ray.direction).ToList();

            if (prune_lengths)
            {
                foreach (var rwc in rwcs.ToArray())
                {
                    if (rwc.Proximity > max_distance)
                    {
                        rwcs.Remove(rwc);
                    }
                }
            }

            List <RRayCollision> temp_collisions_storage = new List <RRayCollision>();

            if (ids_to_ignore == null)
            {
                ids_to_ignore = new List <ElementId>();
            }

            foreach (var rwc in rwcs)
            {
                Reference r = rwc.GetReference();
                if (ids_to_ignore.Any(x => x.IntegerValue == r.ElementId.IntegerValue))
                {
                    continue;
                }

                Element collided_element = info.DOC.GetElement(r.ElementId);
                if (collided_element == null)
                {
                    continue;
                }

                RRayCollision ray_collision = new RRayCollision();
                if (max_distance == -1)
                {
                    ray_collision.distance = rwc.Proximity;
                    ray_collision.other_id = collided_element.Id;
                    ray_collision.point    = r.GlobalPoint;
                    temp_collisions_storage.Add(ray_collision);
                }
                else
                {
                    if (rwc.Proximity <= max_distance)
                    {
                        ray_collision.distance = rwc.Proximity;
                        ray_collision.other_id = collided_element.Id;
                        ray_collision.point    = r.GlobalPoint;
                        temp_collisions_storage.Add(ray_collision);
                    }
                }
            }

            ray.collisions = temp_collisions_storage.ToArray();
            return(ray);
        }
Пример #29
0
        /// <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.

            q = wallEndPoint + _offset * XYZ.BasisZ;

            bool wallHasFaceAtEnd = Util.IsEqual(
                pointList.Last(), q);

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

            int n = pointList.Count;

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

            var wallOpenings = new List <WallOpening2d>(
                n / 2);

            for (int i = 0; i < n; i += 2)
            {
                wallOpenings.Add(new WallOpening2d
                {
                    Start = pointList[i],
                    End   = pointList[i + 1]
                });
            }
            return(wallOpenings);
        }
Пример #30
0
        /// <summary> 射线法:找到与梁相交的所有墙对象 </summary>
        public Result FindSupporting()
        {
            Transaction trans = new Transaction(Doc, "ExComm");

            trans.Start();

            // 在界面中选择一个梁
            Selection      sel  = UIDoc.Selection;
            Reference      ref1 = sel.PickObject(ObjectType.Element, "Please pick a beam");
            FamilyInstance beam = Doc.GetElement(ref1) as FamilyInstance;

            //Read the beam's location line
            LocationCurve lc    = beam.Location as LocationCurve;
            Curve         curve = lc.Curve;

            // 将梁的起点和端点作为射线的原点与方向
            XYZ ptStart = curve.GetEndPoint(0);
            XYZ ptEnd   = curve.GetEndPoint(1);

            //move the two point a little bit lower, so the ray can go through the wall
            // 将这两个点向下移动一点点,来让引射线可以穿过墙
            XYZ offset = new XYZ(0, 0, 0.01);

            ptStart = ptStart - offset;
            ptEnd   = ptEnd - offset;

            // 将当前3D视图作为ReferenceIntersector的构造参数
            View3D view3d = null;

            view3d = Doc.ActiveView as View3D;
            if (view3d == null)
            {
                TaskDialog.Show("3D view", "current view should be 3D view");
                return(Result.Failed);
            }

            // 执行射线相交。注意此射线是无限延长的,如果没有指定ReferenceIntersector中的搜索范围,则会在整个项目中的所有Element中进行相交运算。
            double beamLen = Convert.ToDouble(curve.Length);
            ReferenceIntersector         ReferenceIntersector1 = new ReferenceIntersector(view3d);
            IList <ReferenceWithContext> references            = ReferenceIntersector1.Find(ptStart, ptEnd - ptStart);

            // 清除已经选择的对象
            sel.SetElementIds(new List <ElementId>());
            // 返回已经选择的对象
            ICollection <ElementId> Ge = sel.GetElementIds();

            // 找到所有相交对象中,与梁相交的墙对象
            double tolerate = 0.00001;

            foreach (ReferenceWithContext reference in references)
            {
                Reference ref2 = reference.GetReference();
                ElementId id   = ref2.ElementId;
                Element   elem = Doc.GetElement(id);
                //
                if (elem is Wall)
                {
                    // 如果与射线相交的对象到射线原点的距离比梁的长度小,说明,此对象是与梁相交的
                    // 如果相交面与梁的端面重合,则可以设置一个tolerate,这样的话,那个与之重合的面也可以被选中了。
                    if (reference.Proximity < beamLen + tolerate)
                    {
                        Ge.Add(elem.Id);
                    }
                }
            }
            // 整体选择所有与梁相交的墙
            sel.SetElementIds(Ge);
            trans.Commit();
            // Change
            return(Result.Succeeded);
        }
Пример #31
0
        /// <summary>
        /// OK button click event
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonOK_Click(object sender, EventArgs e)
        {
            DeleteLines();
            if (!UpdateData(false))
            {
                return;
            }
            m_outputInfo.Clear();
            m_stopWatch.Start();
            Transaction transaction = new Transaction(m_doc, "RayTraceBounce");

            transaction.Start();
            m_LineCount = 0;
            m_RayCount  = 0;
            // Start Find References By Direction
            Autodesk.Revit.DB.XYZ startpt = m_origin;
            m_outputInfo.Add("Start Find References By Direction: ");
            for (int ctr = 1; ctr <= rayLimit; ctr++)
            {
                ReferenceIntersector         referenceIntersector = new ReferenceIntersector(m_view);
                IList <ReferenceWithContext> references           = referenceIntersector.Find(startpt, m_direction);
                m_rClosest = null;
                FindClosestReference(references);
                if (m_rClosest == null)
                {
                    string info = "Ray " + ctr + " aborted. No closest face reference found. ";
                    m_outputInfo.Add(info);
                    if (ctr == 1)
                    {
                        TaskDialog.Show("Revit", info);
                    }
                    break;
                }
                else
                {
                    Reference             reference        = m_rClosest.GetReference();
                    Element               referenceElement = m_doc.GetElement(reference);
                    GeometryObject        referenceObject  = referenceElement.GetGeometryObjectFromReference(reference);
                    Autodesk.Revit.DB.XYZ endpt            = reference.GlobalPoint;
                    if (startpt.IsAlmostEqualTo(endpt))
                    {
                        m_outputInfo.Add("Start and end points are equal. Ray " + ctr + " aborted\n" + startpt.X + ", " + startpt.Y + ", " + startpt.Z);
                        break;
                    }
                    else
                    {
                        MakeLine(startpt, endpt, m_direction, "bounce");
                        m_RayCount = m_RayCount + 1;
                        string info = "Intersected Element Type: [" + referenceElement.GetType().ToString() + "] ElementId: [" + referenceElement.Id.IntegerValue.ToString();
                        m_face = referenceObject as Face;
                        if (m_face.MaterialElementId != ElementId.InvalidElementId)
                        {
                            Material materialElement = m_doc.GetElement(m_face.MaterialElementId) as Material;
                            info += "] Face MaterialElement Name: [" + materialElement.Name + "] Shininess: [" + materialElement.Shininess;
                        }
                        else
                        {
                            info += "] Face.MaterialElement is null [" + referenceElement.Category.Name;
                        }
                        info += "]";
                        m_outputInfo.Add(info);
                        Autodesk.Revit.DB.UV  endptUV    = reference.UVPoint;
                        Autodesk.Revit.DB.XYZ FaceNormal = m_face.ComputeDerivatives(endptUV).BasisZ;                                // face normal where ray hits
                        FaceNormal = m_rClosest.GetInstanceTransform().OfVector(FaceNormal);                                         // transformation to get it in terms of document coordinates instead of the parent symbol
                        Autodesk.Revit.DB.XYZ directionMirrored = m_direction - 2 * m_direction.DotProduct(FaceNormal) * FaceNormal; //http://www.fvastro.org/presentations/ray_tracing.htm
                        m_direction = directionMirrored;                                                                             // get ready to shoot the next ray
                        startpt     = endpt;
                    }
                }
            }
            transaction.Commit();
            m_stopWatch.Stop();
            TimeSpan ts          = m_stopWatch.Elapsed;
            string   elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);

            m_outputInfo.Add(elapsedTime + "\n" + "Lines = " + m_LineCount + "\n" + "Rays = " + m_RayCount);
            m_stopWatch.Reset();
            OutputInformation();
        }