Ejemplo n.º 1
0
        /// <summary>
        /// Find out two References, whose ProximityParameter is negative or positive,
        /// And Get the minimal value from all positive reference, and get the maximal value
        /// from the negative reference. if there are no such reference, using null instead.
        /// </summary>
        /// <param name="refs">References</param>
        /// <returns>Reference array</returns>
        private ReferenceWithContext[] GetClosestSectionsToOrigin(List <ReferenceWithContext> refs)
        {
            ReferenceWithContext[] mins = new ReferenceWithContext[2];
            if (refs.Count == 0)
            {
                return(mins);
            }

            if (refs[0].Proximity > 0)
            {
                mins[1] = refs[0];
                return(mins);
            }

            for (int i = 0; i < refs.Count - 1; i++)
            {
                if (refs[i].Proximity < 0 && refs[i + 1].Proximity > 0)
                {
                    mins[0] = refs[i];
                    mins[1] = refs[i + 1];
                    return(mins);
                }
            }

            mins[0] = refs[refs.Count - 1];

            return(mins);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 构造断面
        /// 两个 ReferenceWithContext 一进一出 正好对应一个 障碍物
        /// </summary>
        /// <param name="allrefs">与管线碰撞的所有障碍物</param>
        /// <param name="dir">管线方向</param>
        /// <returns></returns>
        public static List <Section> BuildSections(List <ReferenceWithContext> allrefs, XYZ dir)
        {
            List <ReferenceWithContext> buildStack = new List <ReferenceWithContext>();
            List <Section> sections = new List <Section>();
            Section        current  = null;

            foreach (ReferenceWithContext geoRef in allrefs)
            {
                if (buildStack.Count == 0)
                {
                    current = new Section(dir);
                    sections.Add(current);
                }

                current.Refs.Add(geoRef);

                //这里为什么要用一个栈呢?
                //因为之前找和当前管道碰撞的 ReferenceWithContext 的时候,找的是 face
                //两个 face 对应一个元素,所以当一个 ReferenceWithContext 进去后再出来,正好对应这一个障碍物
                ReferenceWithContext tmp = Find(buildStack, geoRef);
                if (tmp != null)
                {
                    buildStack.Remove(tmp);
                }
                else
                {
                    buildStack.Add(geoRef);
                }
            }

            return(sections);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Build sections for References, it's a factory method to build sections.
        /// A section contains several points through which the ray passes the obstruction(s).
        /// for example, a section may contain 2 points when the obstruction is stand alone,
        /// or contain 4 points if 2 obstructions are intersects with each other in the direction of the ray.
        /// </summary>
        /// <param name="allrefs">References</param>
        /// <param name="dir">Pipe's direction</param>
        /// <returns>List of Section</returns>
        public static List <Section> BuildSections(List <ReferenceWithContext> allrefs, Autodesk.Revit.DB.XYZ dir)
        {
            List <ReferenceWithContext> buildStack = new List <ReferenceWithContext>();
            List <Section> sections = new List <Section>();
            Section        current  = null;

            foreach (ReferenceWithContext geoRef in allrefs)
            {
                if (buildStack.Count == 0)
                {
                    current = new Section(dir);
                    sections.Add(current);
                }

                current.Refs.Add(geoRef);

                ReferenceWithContext tmp = Find(buildStack, geoRef);
                if (tmp != null)
                {
                    buildStack.Remove(tmp);
                }
                else
                {
                    buildStack.Add(geoRef);
                }
            }

            return(sections);
        }
Ejemplo n.º 4
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);
        }
Ejemplo n.º 5
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);
        }
Ejemplo n.º 6
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() + ";";
            }
        }
Ejemplo n.º 7
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);
        }
Ejemplo n.º 8
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);
        }
Ejemplo n.º 9
0
 /// <summary>
 /// Judge whether a Reference is already in the list of Reference, return the founded value.
 /// </summary>
 /// <param name="arr">List of Reference</param>
 /// <param name="entry">Reference to test</param>
 /// <returns>One Reference has the same element's Id with entry</returns>
 private static ReferenceWithContext Find(List <ReferenceWithContext> arr, ReferenceWithContext entry)
 {
     foreach (ReferenceWithContext tmp in arr)
     {
         if (tmp.GetReference().ElementId == entry.GetReference().ElementId)
         {
             return(tmp);
         }
     }
     return(null);
 }
Ejemplo n.º 10
0
 /// <summary>
 /// Judge whether a given Reference is in a Reference list.
 /// Give two References, if their Proximity and Element Id is equal,
 /// we say the two reference is equal.
 /// </summary>
 /// <param name="arr">Reference Array</param>
 /// <param name="entry">Reference</param>
 /// <returns>True of false</returns>
 private bool InArray(List <ReferenceWithContext> arr, ReferenceWithContext entry)
 {
     foreach (ReferenceWithContext tmp in arr)
     {
         if (Math.Abs(tmp.Proximity - entry.Proximity) < 1e-9 &&
             tmp.GetReference().ElementId == entry.GetReference().ElementId)
         {
             return(true);
         }
     }
     return(false);
 }
Ejemplo n.º 11
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 }
            });
        }
Ejemplo n.º 12
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);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Used to compare two references, just compare their ProximityParameter.
        /// </summary>
        /// <param name="a">First Reference to compare</param>
        /// <param name="b">Second Reference to compare</param>
        /// <returns>-1, 0, or 1</returns>
        private int CompareReferencesWithContext(ReferenceWithContext a, ReferenceWithContext b)
        {
            if (a.Proximity > b.Proximity)
            {
                return(1);
            }

            if (a.Proximity < b.Proximity)
            {
                return(-1);
            }

            return(0);
        }
Ejemplo n.º 14
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);
        }
Ejemplo n.º 15
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);
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Find the first intersection with a face
        /// </summary>
        /// <param name="references"></param>
        /// <returns></returns>
        private static ReferenceWithContext FindClosestReference(IEnumerable <ReferenceWithContext> references)
        {
            ReferenceWithContext rClosest = null;

            var face_prox = Double.PositiveInfinity;
            var edge_prox = Double.PositiveInfinity;

            foreach (ReferenceWithContext r in references)
            {
                var  reference               = r.GetReference();
                var  referenceElement        = DocumentManager.Instance.CurrentDBDocument.GetElement(reference);
                var  referenceGeometryObject = referenceElement.GetGeometryObjectFromReference(reference);
                Face currFace = null;
                currFace = referenceGeometryObject as Autodesk.Revit.DB.Face;
                Autodesk.Revit.DB.Edge edge = null;
                edge = referenceGeometryObject as Autodesk.Revit.DB.Edge;
                if (currFace != null)
                {
                    if ((r.Proximity < face_prox) && (r.Proximity > Double.Epsilon))
                    {
                        rClosest  = r;
                        face_prox = Math.Abs(r.Proximity);
                    }
                }
                else if (edge != null)
                {
                    if ((r.Proximity < edge_prox) && (r.Proximity > Double.Epsilon))
                    {
                        edge_prox = Math.Abs(r.Proximity);
                    }
                }
            }
            if (edge_prox <= face_prox)
            {
                // stop bouncing if there is an edge at least as close as the nearest face - there is no single angle of reflection for a ray striking a line
                //m_outputInfo.Add("there is an edge at least as close as the nearest face - there is no single angle of reflection for a ray striking a line");
                rClosest = null;
            }

            return(rClosest);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// 通过查找到的ReferenceWithContext 获取对象
        /// </summary>
        /// <param name="referenceWithContext"></param>
        /// <param name="currDoc">当前稳点 Document</param>
        /// <returns></returns>
        public static Element GetElementByReferenceWithContext(this ReferenceWithContext referenceWithContext, Document currDoc)
        {
            if (referenceWithContext == null)
            {
                return(null);
            }

            Reference reference = referenceWithContext.GetReference();
            Element   element   = null;

            if (reference.ElementId != ElementId.InvalidElementId)
            {//LinkedElement的ElementId是RevitLinkInstance
                element = currDoc.GetElement(reference.ElementId);
            }
            if (reference.LinkedElementId != ElementId.InvalidElementId)
            {
                element = LinkedElementUtils.GetLinkedDocumnet(currDoc, reference).GetElement(reference.LinkedElementId);
            }

            return(element);
        }
Ejemplo n.º 18
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);
        }
Ejemplo n.º 19
0
        public void RoomCeilingHeight()
        {
            Document   doc   = this.ActiveUIDocument.Document;
            UIDocument uidoc = new UIDocument(doc);
//			RevitCommandId commandId = RevitCommandId.LookupPostableCommandId(PostableCommand.Default3DView);
            //            if (this.CanPostCommand(commandId))
            //              this.PostCommand(commandId);

            // Prompt user to select a room
            Room          room      = doc.GetElement(uidoc.Selection.PickObject(ObjectType.Element)) as Room;
            LocationPoint roomPoint = room.Location as LocationPoint;

            //GeometryElement roomGeoElem = room.get_Geometry(new Options());
            //XYZ roomCent = roomGeoElem.Select(geo => geo as Solid).FirstOrDefault(sld => null != sld).ComputeCentroid();
            var view = new FilteredElementCollector(doc)
                       .OfClass(typeof(View3D)).OfType <View3D>()
                       .FirstOrDefault((View3D v) => v.Name.Contains("{3d"));
            var bic = BuiltInCategory.OST_Floors;


            ReferenceIntersector intersector = new ReferenceIntersector(
                new ElementCategoryFilter(bic),
                FindReferenceTarget.Element, view);

            // XYZ.BasisZ shoots the ray "up"
            ReferenceWithContext rwC = intersector.FindNearest(roomPoint.Point, XYZ.BasisZ * -1);

            // Report the data to the user. This information could also be used to set a "Ceiling Height" instance parameter
            if (rwC == null)
            {
                TaskDialog.Show(string.Format("{0}", view.Name), "no Floors found");
            }
            else
            {
                var rwD   = "View used to Project the Ray " + doc.GetElement(intersector.ViewId).Name;
                var rwPro = "Height is " + UnitUtils.ConvertFromInternalUnits(rwC.Proximity, DisplayUnitType.DUT_MILLIMETERS).ToString() + " mm";
                var rwEle = bic.ToString() + " id: " + rwC.GetReference().ElementId.ToString();
                TaskDialog.Show("Element ID", rwEle + "\n" + rwPro + "\n" + rwD);
            }
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Find the first intersection with a face
        /// </summary>
        /// <param name="references"></param>
        /// <returns></returns>
        public Autodesk.Revit.DB.ReferenceWithContext FindClosestReference(IList <ReferenceWithContext> references)
        {
            ReferenceWithContext rClosest = null;

            double face_prox = System.Double.PositiveInfinity;
            double edge_prox = System.Double.PositiveInfinity;

            foreach (ReferenceWithContext r in references)
            {
                Reference      reference               = r.GetReference();
                Element        referenceElement        = dynRevitSettings.Doc.Document.GetElement(reference);
                GeometryObject referenceGeometryObject = referenceElement.GetGeometryObjectFromReference(reference);
                currFace = null;
                currFace = referenceGeometryObject as Face;
                Edge edge = null;
                edge = referenceGeometryObject as Edge;
                if (currFace != null)
                {
                    if ((r.Proximity < face_prox) && (r.Proximity > System.Double.Epsilon))
                    {
                        rClosest  = r;
                        face_prox = Math.Abs(r.Proximity);
                    }
                }
                else if (edge != null)
                {
                    if ((r.Proximity < edge_prox) && (r.Proximity > System.Double.Epsilon))
                    {
                        edge_prox = Math.Abs(r.Proximity);
                    }
                }
            }
            if (edge_prox <= face_prox)
            {
                // stop bouncing if there is an edge at least as close as the nearest face - there is no single angle of reflection for a ray striking a line
                //m_outputInfo.Add("there is an edge at least as close as the nearest face - there is no single angle of reflection for a ray striking a line");
                rClosest = null;
            }
            return(rClosest);
        }
        // finding building elevation
        public double FindBuildingElevation(ProcessPolygon polygon)
        {
            List <XYZ>           heights        = new List <XYZ>();
            ReferenceIntersector refIntersector = new ReferenceIntersector(this.TopographyID, FindReferenceTarget.Mesh, this.RayTracerView);
            int    counter = 0;
            double h       = 0;

            foreach (XYZ item in polygon.ProcessedPolygon)
            {
                ReferenceWithContext referenceWithContext = refIntersector.FindNearest(item, XYZ.BasisZ);
                if (referenceWithContext != null)
                {
                    counter++;
                    h += referenceWithContext.Proximity;
                }
                else
                {
                    return(-1);
                }
            }
            return(h / counter);
        }
Ejemplo n.º 22
0
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document   doc   = uidoc.Document;

            try
            {
                // pick object
                Reference pickedObj = uidoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element);
                if (pickedObj != null)
                {
                    //Retrieve Element
                    ElementId eleId = pickedObj.ElementId;
                    Element   ele   = doc.GetElement(eleId);

                    //Project Ray
                    LocationPoint locp = ele.Location as LocationPoint;
                    XYZ           p1   = locp.Point;

                    // Ray
                    XYZ rayd = new XYZ(0, 0, 1);
                    ElementCategoryFilter filter    = new ElementCategoryFilter(BuiltInCategory.OST_Roofs);
                    ReferenceIntersector  refi      = new ReferenceIntersector(filter, FindReferenceTarget.Face, (View3D)doc.ActiveView);
                    ReferenceWithContext  refc      = refi.FindNearest(p1, rayd);
                    Reference             reference = refc.GetReference();
                    XYZ    intpoing = reference.GlobalPoint;
                    Double dist     = p1.DistanceTo(intpoing);

                    TaskDialog.Show("Ray", string.Format("Distance to roof {0}", dist));
                }
                return(Result.Succeeded);
            }
            catch (Exception e)
            {
                message = e.Message;
                return(Result.Failed);
            }
        }
Ejemplo n.º 23
0
        //this method checks to see if a rectangular region has valid projection on the ground.
        private bool CanSubregionBeValid(BoundingBoxUV boundingBox)
        {
            List <XYZ> corners = new List <XYZ>();
            XYZ        Min     = new XYZ(boundingBox.Min.U, boundingBox.Min.V, 0);
            XYZ        Max     = new XYZ(boundingBox.Max.U, boundingBox.Max.V, 0);
            XYZ        p0      = new XYZ(boundingBox.Min.U, boundingBox.Max.V, 0);
            XYZ        p1      = new XYZ(boundingBox.Max.U, boundingBox.Min.V, 0);

            corners.Add(Min);
            corners.Add(Max);
            corners.Add(p0);
            corners.Add(p1);
            ReferenceIntersector refIntersector = new ReferenceIntersector(this.TopographySurfaceId, FindReferenceTarget.Mesh, this.RayTracerView);

            foreach (XYZ item in corners)
            {
                ReferenceWithContext referenceWithContext = refIntersector.FindNearest(item, XYZ.BasisZ);
                if (referenceWithContext == null)
                {
                    return(false);
                }
            }
            return(true);
        }
Ejemplo n.º 24
0
        internal XYZ GetTrussTopPoint(XYZ currentPointOnRidge)
        {
            if (RoofLineType == RoofLineType.Ridge)
            {
                return(currentPointOnRidge);
            }

            //If the is not a Ridge this MUST be a SinglePanelRidge
            if (RoofLineType == RoofLineType.RidgeSinglePanel)
            {
                return(currentPointOnRidge);
            }

            Line currentRidgeLine = Curve.Clone() as Line;

            if (currentRidgeLine == null)
            {
                throw new Exception("The ridge is not a straight line!");
            }

            ModelCurveArrArray sketchModels = CurrentRoof.GetProfiles();
            double             minDist      = double.MaxValue;
            ModelCurve         targetEave   = null;
            XYZ projectedPoint = null;

            double currentRoofTotalHeight = GetCurrentRoofHeight();

            foreach (ModelCurveArray currentCurveArr in sketchModels)
            {
                foreach (ModelCurve currentCurve in currentCurveArr)
                {
                    Curve targetGeoCurve = currentCurve.GeometryCurve;
                    Line  targetGeoLine  = targetGeoCurve as Line;

                    if (targetGeoLine == null)
                    {
                        throw new Exception("Eave is not a straight line");
                    }

                    targetGeoLine = targetGeoLine.Flatten(currentRoofTotalHeight);

                    double currentDist = targetGeoLine.Project(currentPointOnRidge).Distance;
                    if (currentDist < minDist)
                    {
                        minDist        = currentDist;
                        targetEave     = currentCurve;
                        projectedPoint = targetGeoLine.Project(currentPointOnRidge).XYZPoint;
                    }
                }
            }

            double overHang = 0;

            try { overHang = CurrentRoof.get_Overhang(targetEave); }
            catch { }

            XYZ ridgePointFlatten = new XYZ(currentPointOnRidge.X, currentPointOnRidge.Y, currentRoofTotalHeight);

            //We just need to get the side that the eave is to move the point to that direction
            //so we dont need to get a specific eave, lets just project the first one with infinite bounds to get the direction
            if (RelatedRidgeEaves == null || RelatedRidgeEaves.Count == 0)
            {
                RelatedRidgeEaves = GetRelatedEaves();
            }

            if (RelatedRidgeEaves == null || RelatedRidgeEaves.Count == 0)
            {
                throw new Exception("Related eave or eaves to current singleRidge was not found");
            }


            Curve eaveCurve = RelatedRidgeEaves[0].AsCurve();

            if (eaveCurve as Line == null)
            {
                throw new Exception("Related eave is not a straight line!");
            }

            Line eaveLine = eaveCurve as Line;

            XYZ lineIntersectionPoint = GeometrySupport.GetRoofIntersectionFlattenLines(currentRidgeLine, ridgePointFlatten, eaveLine, currentRoofTotalHeight);

            if (lineIntersectionPoint == null)
            {
                throw new Exception("No Intersection between eave could be estabilished!");
            }

            XYZ overHangdirection = Line.CreateBound(projectedPoint, lineIntersectionPoint).Direction.Normalize();
            XYZ pointOnOverhang   = projectedPoint.Add(overHangdirection.Multiply(overHang));

            //We will get the point on the overhang because if we are working with a single panel ridge it may have overhangs
            XYZ pointOnSupport = GetSupportPoint(pointOnOverhang, currentRidgeLine.Direction.Normalize());

            //Now we will shoot the point up on the Roof
            XYZ startingPoint = new XYZ(pointOnSupport.X, pointOnSupport.Y, pointOnSupport.Z - 1);
            ReferenceIntersector currentRefIntersect = new ReferenceIntersector(CurrentRoof.Id, FindReferenceTarget.Element, CurrentRoof.Document.ActiveView as View3D);
            ReferenceWithContext currenRefContext    = currentRefIntersect.FindNearest(startingPoint, XYZ.BasisZ);

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

            XYZ projectedPointOnRoof = currenRefContext.GetReference().GlobalPoint;

            return(projectedPointOnRoof);
        }
Ejemplo n.º 25
0
        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);
        }
Ejemplo n.º 26
0
 /// <summary>
 /// Judge whether a Reference is already in the list of Reference, return the founded value.
 /// </summary>
 /// <param name="arr">List of Reference</param>
 /// <param name="entry">Reference to test</param>
 /// <returns>One Reference has the same element's Id with entry</returns>
 private static ReferenceWithContext Find(List<ReferenceWithContext> arr, ReferenceWithContext entry)
 {
     foreach (ReferenceWithContext tmp in arr)
     {
         if (tmp.GetReference().ElementId == entry.GetReference().ElementId)
         {
             return tmp;
         }
     }
     return null;
 }
Ejemplo n.º 27
0
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
            UIDocument    uidoc = commandData.Application.ActiveUIDocument;
            Document      doc   = uidoc.Document;
            Selection     sel   = uidoc.Selection;

            //选择一个点
            Reference refPoint = sel.PickObject(ObjectType.PointOnElement);
            XYZ       point1   = refPoint.GlobalPoint; //The position on which the reference is hit.???

            //射线方向及工作平面法向量
            XYZ rayDirection = XYZ.BasisZ;
            XYZ skVector     = XYZ.BasisX; //???????????

            //当选择的主体为平面时,射线根据选择的点与此面的法线方向进行放射
            if (refPoint.ElementReferenceType == ElementReferenceType.REFERENCE_TYPE_SURFACE)
            {
                PlanarFace pFace = null;
                //主体是链接的图元时,获取平面的方法
                if (refPoint.LinkedElementId.IntegerValue != -1)
                {
                    RevitLinkInstance linkIIns = doc.GetElement(refPoint) as RevitLinkInstance;
                    Document          linkDoc  = linkIIns.GetLinkDocument();
                    Element           linkElem = linkDoc.GetElement(refPoint.LinkedElementId);
                    Options           opt      = new Options();
                    opt.DetailLevel = ViewDetailLevel.Fine;
                    GeometryElement geoElem = linkElem.get_Geometry(opt);
                    pFace = getTarFace(geoElem, point1); //point1是原始点.
                }
                else
                {
                    //判断是否FamilyInstance类型的族,采用不同的获取方法
                    Element elem = doc.GetElement(refPoint);
                    if (elem is FamilyInstance)
                    {
                        Options opt = new Options();
                        opt.DetailLevel = ViewDetailLevel.Fine;
                        GeometryElement ge = elem.get_Geometry(opt);
                        pFace = getTarFace(ge, point1);
                    }
                    else
                    {
                        pFace = elem.GetGeometryObjectFromReference(refPoint) as PlanarFace;
                    }
                }

                //修正射线方向及工作平面法向量
                if (pFace != null)
                {
                    rayDirection = pFace.FaceNormal;
                    skVector     = pFace.XVector;
                }
            }

            //获得视图
            View3D view3D = doc.ActiveView as View3D;

            //创建射线测量出第二点
            ExclusionFilter filter =
                new ExclusionFilter(new List <ElementId>()
            {
                refPoint.ElementId, refPoint.LinkedElementId
            });

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

            refIntersector.FindReferencesInRevitLinks = true;
            ReferenceWithContext rwc = refIntersector.FindNearest(point1, rayDirection);

            if (rwc != null)
            {
                XYZ point2 = rwc.GetReference().GlobalPoint;
                //创建模型线
                Line line = Line.CreateBound(point1, point2);
                TaskDialog.Show("距离", line.Length.FeetToMm().ToString("0.00"));
                using (Transaction ts = new Transaction(doc, "尺寸"))
                {
                    ts.Start();
                    SketchPlane sk         = SketchPlane.Create(doc, Plane.CreateByNormalAndOrigin(skVector, point1));
                    ModelCurve  modelCurve = doc.Create.NewModelCurve(line, sk);
                    sel.SetElementIds(new List <ElementId>()
                    {
                        modelCurve.Id
                    });
                    ts.Commit();
                }
            }
            else
            {
                TaskDialog.Show("返回结果", "未检测到图元");
            }

            return(Result.Succeeded);
        }
Ejemplo n.º 28
0
        /// <summary>
        /// Find out two References, whose ProximityParameter is negative or positive,
        /// And Get the minimal value from all positive reference, and get the maximal value 
        /// from the negative reference. if there are no such reference, using null instead.
        /// </summary>
        /// <param name="refs">References</param>
        /// <returns>Reference array</returns>
        private ReferenceWithContext[] GetClosestSectionsToOrigin(List<ReferenceWithContext> refs)
        {
            ReferenceWithContext[] mins = new ReferenceWithContext[2];
            if (refs.Count == 0)
            {
                return mins;
            }

            if (refs[0].Proximity > 0)
            {
                mins[1] = refs[0];
                return mins;
            }

            for (int i = 0; i < refs.Count - 1; i++)
            {
                if (refs[i].Proximity < 0 && refs[i + 1].Proximity > 0)
                {
                    mins[0] = refs[i];
                    mins[1] = refs[i + 1];
                    return mins;
                }
            }

            mins[0] = refs[refs.Count - 1];

            return mins;
        }
Ejemplo n.º 29
0
        static internal EdgeInfo GetCurveInformation(Element targetRoof, Curve targetCurve, IList <PlanarFace> targetPlanarFaceList)
        {
            if (targetPlanarFaceList != null && targetRoof != null && (targetRoof as FootPrintRoof) != null)
            {
                FootPrintRoof currentRoof = targetRoof as FootPrintRoof;
                foreach (PlanarFace currentPlanarFace in targetPlanarFaceList)
                {
                    EdgeArrayArray EdgeLoops = currentPlanarFace.EdgeLoops;
                    foreach (EdgeArray currentEdgeArray in EdgeLoops)
                    {
                        foreach (Edge currentEdge in currentEdgeArray)
                        {
                            if (currentEdge != null)
                            {
                                IList <Edge> currentEdges = new List <Edge>();
                                currentEdges.Add(currentEdge);
                                EdgeInfo currentEdgeInfo = new EdgeInfo();
                                Curve    edgeCurve       = currentEdge.AsCurve();

                                if (edgeCurve.IsAlmostEqualTo(targetCurve))
                                {
                                    if (edgeCurve.GetEndPoint(0).Z.IsAlmostEqualTo(currentPlanarFace.Origin.Z) && edgeCurve.GetEndPoint(1).Z.IsAlmostEqualTo(currentPlanarFace.Origin.Z))
                                    {
                                        currentEdgeInfo = new EdgeInfo {
                                            Edges = currentEdges, Curve = edgeCurve, RoofLineType = RoofLineType.Eave, CurrentRoof = currentRoof
                                        };
                                        currentEdgeInfo.RelatedPanelFaces = GetEdgeRelatedPanels(currentEdge, targetPlanarFaceList);
                                        return(currentEdgeInfo);
                                    }
                                    else if (edgeCurve.GetEndPoint(0).Z.IsAlmostEqualTo(currentPlanarFace.Origin.Z) || edgeCurve.GetEndPoint(1).Z.IsAlmostEqualTo(currentPlanarFace.Origin.Z))
                                    {
                                        PlanarFace firstFace  = currentEdge.GetFace(0) as PlanarFace;
                                        PlanarFace secondFace = currentEdge.GetFace(1) as PlanarFace;

                                        if (!targetPlanarFaceList.Contains(firstFace) || !targetPlanarFaceList.Contains(secondFace))
                                        {
                                            currentEdgeInfo = new EdgeInfo {
                                                Edges = currentEdges, Curve = edgeCurve, RoofLineType = RoofLineType.Gable, CurrentRoof = currentRoof
                                            };
                                            currentEdgeInfo.RelatedPanelFaces = GetEdgeRelatedPanels(currentEdge, targetPlanarFaceList);
                                            return(currentEdgeInfo);
                                        }
                                        else
                                        {
                                            if (GetOuterCurveLoop(firstFace).Count() == 3 || GetOuterCurveLoop(secondFace).Count() == 3)
                                            {
                                                currentEdgeInfo = new EdgeInfo {
                                                    Edges = currentEdges, Curve = edgeCurve, RoofLineType = RoofLineType.Hip, CurrentRoof = currentRoof
                                                };
                                                currentEdgeInfo.RelatedPanelFaces = GetEdgeRelatedPanels(currentEdge, targetPlanarFaceList);
                                                return(currentEdgeInfo);
                                            }
                                            else
                                            {
                                                XYZ startingPoint = targetCurve.GetEndPoint(0).Z < targetCurve.GetEndPoint(1).Z ? targetCurve.GetEndPoint(0) : targetCurve.GetEndPoint(1);

                                                XYZ extendedPoint = GetExtendedPoint(startingPoint, firstFace);
                                                XYZ rayTracePoint = new XYZ(extendedPoint.X, extendedPoint.Y, extendedPoint.Z + 999);

                                                ReferenceIntersector ReferenceIntersect = new ReferenceIntersector(targetRoof.Id, FindReferenceTarget.Element, (targetRoof.Document.ActiveView as View3D));
                                                ReferenceWithContext RefContext         = ReferenceIntersect.FindNearest(rayTracePoint, XYZ.BasisZ.Negate());

                                                if (RefContext == null)
                                                {
                                                    currentEdgeInfo = new EdgeInfo {
                                                        Edges = currentEdges, Curve = edgeCurve, RoofLineType = RoofLineType.Hip, CurrentRoof = currentRoof
                                                    };
                                                    currentEdgeInfo.RelatedPanelFaces = GetEdgeRelatedPanels(currentEdge, targetPlanarFaceList);
                                                    return(currentEdgeInfo);
                                                }

                                                currentEdgeInfo = new EdgeInfo {
                                                    Edges = currentEdges, Curve = edgeCurve, RoofLineType = RoofLineType.Valley, CurrentRoof = currentRoof
                                                };
                                                currentEdgeInfo.RelatedPanelFaces = GetEdgeRelatedPanels(currentEdge, targetPlanarFaceList);
                                                return(currentEdgeInfo);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        if (edgeCurve.GetEndPoint(0).Z.IsAlmostEqualTo(edgeCurve.GetEndPoint(1).Z))
                                        {
                                            if (targetPlanarFaceList.Contains(currentEdge.GetFace(0)) && targetPlanarFaceList.Contains(currentEdge.GetFace(1)))
                                            {
                                                currentEdgeInfo = new EdgeInfo {
                                                    Edges = currentEdges, Curve = edgeCurve, RoofLineType = RoofLineType.Ridge, CurrentRoof = currentRoof
                                                };
                                                currentEdgeInfo.RelatedPanelFaces = GetEdgeRelatedPanels(currentEdge, targetPlanarFaceList);
                                                return(currentEdgeInfo);
                                            }
                                            else
                                            {
                                                PlanarFace firstFace  = currentEdge.GetFace(0) as PlanarFace;
                                                PlanarFace secondFace = currentEdge.GetFace(1) as PlanarFace;

                                                XYZ startingPoint      = edgeCurve.Evaluate(0.5, true);
                                                XYZ crossedDirection   = Line.CreateBound(edgeCurve.GetEndPoint(0), edgeCurve.GetEndPoint(1)).Direction.CrossProduct(XYZ.BasisZ);
                                                XYZ crossedPointStart  = startingPoint.Add(crossedDirection.Multiply(0.02));
                                                XYZ crossedPointEnd    = startingPoint.Add(crossedDirection.Multiply(0.1));
                                                XYZ rayTracePointStart = new XYZ(crossedPointStart.X, crossedPointStart.Y, crossedPointStart.Z + 999);
                                                XYZ rayTracePointEnd   = new XYZ(crossedPointEnd.X, crossedPointEnd.Y, crossedPointEnd.Z + 999);

                                                ReferenceIntersector ReferenceIntersect = new ReferenceIntersector(targetRoof.Id, FindReferenceTarget.Element, (targetRoof.Document.ActiveView as View3D));
                                                ReferenceWithContext refStart           = ReferenceIntersect.FindNearest(rayTracePointStart, XYZ.BasisZ.Negate());
                                                ReferenceWithContext refEnd             = ReferenceIntersect.FindNearest(rayTracePointEnd, XYZ.BasisZ.Negate());

                                                bool isEave = true;
                                                if (refEnd != null)
                                                {
                                                    if (refStart != null)
                                                    {
                                                        //Document doc = currentRoof.Document;
                                                        //double refPointHeight = refEnd.GetReference().GlobalPoint.Z;
                                                        //double starPHeight = refStart.GetReference().GlobalPoint.Z;
                                                        //FamilySymbol fs = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_GenericModel).WhereElementIsElementType().Where(type => type.Name.Contains("DebugPoint2")).FirstOrDefault() as FamilySymbol;
                                                        //doc.Create.NewFamilyInstance(refEnd.GetReference().GlobalPoint, fs, Autodesk.Revit.DB.Structure.StructuralType.NonStructural);
                                                        //doc.Create.NewFamilyInstance(refStart.GetReference().GlobalPoint, fs, Autodesk.Revit.DB.Structure.StructuralType.NonStructural);
                                                        if (refEnd.GetReference().GlobalPoint.Z < refStart.GetReference().GlobalPoint.Z)
                                                        {
                                                            isEave = false;
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    crossedPointStart  = startingPoint.Add(crossedDirection.Multiply(-0.02));
                                                    crossedPointEnd    = startingPoint.Add(crossedDirection.Multiply(-0.1));
                                                    rayTracePointStart = new XYZ(crossedPointStart.X, crossedPointStart.Y, crossedPointStart.Z + 999);
                                                    rayTracePointEnd   = new XYZ(crossedPointEnd.X, crossedPointEnd.Y, crossedPointEnd.Z + 999);

                                                    refStart = ReferenceIntersect.FindNearest(rayTracePointStart, XYZ.BasisZ.Negate());
                                                    refEnd   = ReferenceIntersect.FindNearest(rayTracePointEnd, XYZ.BasisZ.Negate());

                                                    if (refEnd != null)
                                                    {
                                                        if (refStart != null)
                                                        {
                                                            //Document doc = currentRoof.Document;
                                                            //double refPointHeight = refEnd.GetReference().GlobalPoint.Z;
                                                            //double starPHeight = refStart.GetReference().GlobalPoint.Z;
                                                            //FamilySymbol fs = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_GenericModel).WhereElementIsElementType().Where(type => type.Name.Contains("DebugPoint2")).FirstOrDefault() as FamilySymbol;
                                                            //doc.Create.NewFamilyInstance(refEnd.GetReference().GlobalPoint, fs, Autodesk.Revit.DB.Structure.StructuralType.NonStructural);
                                                            //doc.Create.NewFamilyInstance(refStart.GetReference().GlobalPoint, fs, Autodesk.Revit.DB.Structure.StructuralType.NonStructural);
                                                            if (refEnd.GetReference().GlobalPoint.Z < refStart.GetReference().GlobalPoint.Z)
                                                            {
                                                                isEave = false;
                                                            }
                                                        }
                                                    }
                                                }

                                                if (isEave)
                                                {
                                                    currentEdgeInfo = new EdgeInfo {
                                                        Edges = currentEdges, Curve = edgeCurve, RoofLineType = RoofLineType.Eave, CurrentRoof = currentRoof
                                                    };
                                                    currentEdgeInfo.RelatedPanelFaces = GetEdgeRelatedPanels(currentEdge, targetPlanarFaceList);
                                                    return(currentEdgeInfo);
                                                }
                                                else
                                                {
                                                    currentEdgeInfo = new EdgeInfo {
                                                        Edges = currentEdges, Curve = edgeCurve, RoofLineType = RoofLineType.RidgeSinglePanel, CurrentRoof = currentRoof
                                                    };
                                                    currentEdgeInfo.RelatedPanelFaces = GetEdgeRelatedPanels(currentEdge, targetPlanarFaceList);
                                                    return(currentEdgeInfo);
                                                }
                                            }
                                        }
                                        else
                                        {
                                            if (targetPlanarFaceList.Contains(currentEdge.GetFace(0)) && targetPlanarFaceList.Contains(currentEdge.GetFace(1)))
                                            {
                                                currentEdgeInfo = new EdgeInfo {
                                                    Edges = currentEdges, Curve = edgeCurve, RoofLineType = RoofLineType.Hip, CurrentRoof = currentRoof
                                                };
                                                currentEdgeInfo.RelatedPanelFaces = GetEdgeRelatedPanels(currentEdge, targetPlanarFaceList);
                                                return(currentEdgeInfo);
                                            }
                                            else
                                            {
                                                currentEdgeInfo = new EdgeInfo {
                                                    Edges = currentEdges, Curve = edgeCurve, RoofLineType = RoofLineType.Gable, CurrentRoof = currentRoof
                                                };
                                                currentEdgeInfo.RelatedPanelFaces = GetEdgeRelatedPanels(currentEdge, targetPlanarFaceList);
                                                return(currentEdgeInfo);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return(new EdgeInfo {
                Edges = new List <Edge>(), Curve = targetCurve, RoofLineType = RoofLineType.Undefined, CurrentRoof = null
            });
        }
Ejemplo n.º 30
0
        private Result SlopeSelectedBuildingPad(UIDocument targetUIdoc, ref string message, double maxPointDistInFeet, double targetAngleInRadians)
        {
            Document  doc = targetUIdoc.Document;
            Selection sel = targetUIdoc.Selection;

            View3D current3dView = doc.ActiveView as View3D;

            if (current3dView == null)
            {
                message = Properties.Messages.SlopeGradingFromPads_Not3DView;
                return(Result.Failed);
            }

            BuildingPad selectedBuildingPad = doc.GetElement(sel.PickObject(ObjectType.Element, new PadSelectionFilter(), Properties.Messages.SlopeGradingFromPads_SelectPad)) as BuildingPad;

            //Check if the Pad is associate with a Surface (never seen one doesnt, but anyways)
            ElementId topoElementID = selectedBuildingPad.HostId;

            if (topoElementID.Equals(ElementId.InvalidElementId))
            {
                message = Properties.Messages.SlopeGradingFromPads_NoTopoAssociate;
                return(Result.Failed);
            }

            TopographySurface currentTopo = doc.GetElement(topoElementID) as TopographySurface;

            if (currentTopo == null)
            {
                message = Properties.Messages.SlopeGradingFromPads_NoTopoAssociate;;
                return(Result.Failed);
            }

            IList <CurveLoop> PadBoundaryLoops = new List <CurveLoop>();
            CurveLoop         outerLoop        = null;

            IList <Reference> TopFacesReferences = HostObjectUtils.GetTopFaces(selectedBuildingPad);

            if (TopFacesReferences.Count > 1)
            {
                message = Properties.Messages.SlopeGradingFromPads_PadsWithMoreThanOneUpperFace;
                return(Result.Failed);
            }

            XYZ plannarDirection = XYZ.BasisZ;
            XYZ plannarOrigin    = XYZ.Zero;

            // interate on the only face
            foreach (Reference currentFaceRef in TopFacesReferences)
            {
                GeometryObject currentFaceObj = selectedBuildingPad.GetGeometryObjectFromReference(currentFaceRef);
                if (currentFaceObj is PlanarFace)
                {
                    PlanarFace currentPlanarFace = currentFaceObj as PlanarFace;
                    plannarDirection = currentPlanarFace.FaceNormal;
                    plannarOrigin    = currentPlanarFace.Origin;
                    PadBoundaryLoops = currentPlanarFace.GetEdgesAsCurveLoops();
                }
                else
                {
                    message = Properties.Messages.SlopeGradingFromPads_UpperFaceNotPlanar;
                    return(Result.Failed);
                }
            }

            //Sort the curves so the outer loop comes first
            IList <IList <CurveLoop> > curveLoopLoop = ExporterIFCUtils.SortCurveLoops(PadBoundaryLoops);

            if (curveLoopLoop.Count > 0)
            {
                IList <CurveLoop> firstList = curveLoopLoop.First();
                if (firstList.Count > 0)
                {
                    outerLoop = firstList.First();
                }
            }

            if (outerLoop == null)
            {
                message = Properties.Messages.SlopeGradingFromPads_OuterLoopIssue;
                return(Result.Failed);
            }

            //This will be the list of elements that the ReferenceIntersector will shoot the rays
            //If we try to shoot the rays only in the toposurface and the it has subregions, the reference
            //intersection will not recognize these regions, so its necessary to shoot rays to the surface and its subregions
            IList <ElementId> currentSubRegionsAndSurface = currentTopo.GetHostedSubRegionIds();

            currentSubRegionsAndSurface.Add(topoElementID);

            //Search for the max distance from the Pad to the topography
            //Doesnt matter if it is upwards or downwards, but we will check that, since the ray has to go to one direction
            //This is to estabilish what the distance will be using to create the slope to the right amount
            ReferenceIntersector topoRefIntersec = new ReferenceIntersector(currentSubRegionsAndSurface, FindReferenceTarget.Mesh, current3dView);

            double maxDist = double.NegativeInfinity;

            foreach (Curve currentCurve in outerLoop)
            {
                int    numberOfInteractions = 0;
                double increaseAmount       = 0;
                double currentParameter     = 0;
                EstabilishInteractionPoints(currentCurve, maxPointDistInFeet, out numberOfInteractions, out increaseAmount);

                for (int i = 0; i < numberOfInteractions; i++)
                {
                    if (i == 0)
                    {
                        currentParameter = 0;
                    }
                    else
                    {
                        currentParameter += increaseAmount;
                    }

                    XYZ currentPointToEvaluate = currentCurve.Evaluate(currentParameter, true);

                    ReferenceWithContext currentRefContext = topoRefIntersec.FindNearest(currentPointToEvaluate, XYZ.BasisZ);
                    if (currentRefContext == null)
                    {
                        currentRefContext = topoRefIntersec.FindNearest(currentPointToEvaluate, XYZ.BasisZ.Negate());
                    }

                    if (currentRefContext == null)
                    {
                        continue;
                    }

                    double currentDist = currentRefContext.Proximity;
                    if (currentDist > maxDist)
                    {
                        maxDist = currentDist;
                    }
                }
            }

            // if we haven't changed the maxdist yet, something went wrong
            if (maxDist == double.NegativeInfinity)
            {
                message = Properties.Messages.SlopeGradingFromPads_NoTopoAssociate;
                return(Result.Failed);
            }

            //Estabilish the offset from the pad
            double offsetDist = maxDist / Math.Tan(targetAngleInRadians);

            using (TopographyEditScope topoEditGroup = new TopographyEditScope(doc, Properties.Messages.SlopeGradingFromPads_Transaction))
            {
                topoEditGroup.Start(topoElementID);
                using (Transaction t = new Transaction(doc, Properties.Messages.SlopeGradingFromPads_Transaction))
                {
                    t.Start();

                    CurveLoop offsetLoop = null;

                    try
                    {
                        offsetLoop = CurveLoop.CreateViaOffset(outerLoop, offsetDist, plannarDirection);
                    }
                    catch
                    {
                        message += Properties.Messages.SlopeGradingFromPads_OuterOffsetLoopIssue;
                        return(Result.Failed);
                    }

                    #region DebugCurve Loop

                    //Plane p = new Plane(plannarDirection, plannarOrigin);
                    //SketchPlane sktP = SketchPlane.Create(doc, p);
                    //foreach (Curve currentOffsetCurve in offsetLoop)
                    //{
                    //    doc.Create.NewModelCurve(currentOffsetCurve, sktP);
                    //}

                    #endregion


                    foreach (Curve currentOffsetCurve in offsetLoop)
                    {
                        int    numberOfInteractions = 0;
                        double increaseAmount       = 0;
                        double currentParameter     = 0;

                        EstabilishInteractionPoints(currentOffsetCurve, maxPointDistInFeet, out numberOfInteractions, out increaseAmount);

                        for (int i = 0; i < numberOfInteractions; i++)
                        {
                            if (i == 0)
                            {
                                currentParameter = 0;
                            }
                            else
                            {
                                currentParameter += increaseAmount;
                            }

                            XYZ currentPointOffset = currentOffsetCurve.Evaluate(currentParameter, true);

                            ReferenceWithContext currentRefContext = topoRefIntersec.FindNearest(currentPointOffset, XYZ.BasisZ);
                            if (currentRefContext == null)
                            {
                                currentRefContext = topoRefIntersec.FindNearest(currentPointOffset, XYZ.BasisZ.Negate());
                            }
                            //if we couldn't find points upwards and downwards, the topo is near the border, so we cant add points
                            if (currentRefContext == null)
                            {
                                continue;
                            }

                            Reference currentReference  = currentRefContext.GetReference();
                            XYZ       currentPointToAdd = currentReference.GlobalPoint;

                            if (currentTopo.ContainsPoint(currentPointToAdd))
                            {
                                continue;
                            }

                            IList <XYZ> ListPointToAdd = new List <XYZ>();
                            ListPointToAdd.Add(currentPointToAdd);

                            currentTopo.AddPoints(ListPointToAdd);
                        }
                    }

                    foreach (Curve currentCurve in outerLoop)
                    {
                        int    numberOfInteractions = 0;
                        double increaseAmount       = 0;
                        double currentParameter     = 0;
                        EstabilishInteractionPoints(currentCurve, maxPointDistInFeet, out numberOfInteractions, out increaseAmount);

                        for (int i = 0; i < numberOfInteractions; i++)
                        {
                            if (i == 0)
                            {
                                currentParameter = 0;
                            }
                            else
                            {
                                currentParameter += increaseAmount;
                            }

                            XYZ currentPointToAdd = currentCurve.Evaluate(currentParameter, true);

                            if (currentTopo.ContainsPoint(currentPointToAdd))
                            {
                                continue;
                            }

                            IList <XYZ> ListPointToAdd = new List <XYZ>();
                            ListPointToAdd.Add(currentPointToAdd);

                            currentTopo.AddPoints(ListPointToAdd);
                        }
                    }
                    t.Commit();
                }
                topoEditGroup.Commit(new TopographyFailurePreprocessor());

                return(Result.Succeeded);
            }
        }
Ejemplo n.º 31
0
 /// <summary>
 /// Judge whether a given Reference is in a Reference list.
 /// Give two References, if their Proximity and Element Id is equal, 
 /// we say the two reference is equal.
 /// </summary>
 /// <param name="arr">Reference Array</param>
 /// <param name="entry">Reference</param>
 /// <returns>True of false</returns>
 private bool InArray(List<ReferenceWithContext> arr, ReferenceWithContext entry)
 {
     foreach (ReferenceWithContext tmp in arr)
     {
         if (Math.Abs(tmp.Proximity - entry.Proximity) < 1e-9 &&
             tmp.GetReference().ElementId == entry.GetReference().ElementId)
         {
             return true;
         }
     }
     return false;
 }
        /// <summary>
        /// Return the neighbouring BIM element generating
        /// the given room boundary curve c, assuming it
        /// is oriented counter-clockwise around the room
        /// if part of an interior loop, and vice versa.
        /// </summary>
        public Element GetElementByRay(
            UIApplication app,
            Document doc,
            View3D view3d,
            Curve c)
        {
            Element boundaryElement = null;

            // Tolerances

            const double minTolerance = 0.00000001;
            const double maxTolerance = 0.01;

            // Height of ray above room level:
            // ray starts from one foot above room level

            const double elevation = 1;

            // Ray starts not directly from the room border
            // but from a point offset slightly into it.

            const double stepInRoom = 0.1;

            // We could use Line.Direction if Curve c is a
            // Line, but since c also might be an Arc, we
            // calculate direction like this:

            XYZ lineDirection
                = (c.GetEndPoint(1) - c.GetEndPoint(0))
                  .Normalize();

            XYZ upDir = elevation * XYZ.BasisZ;

            // Assume that the room is on the left side of
            // the room boundary curve and wall on the right.
            // This is valid for both outer and inner room
            // boundaries (outer are counter-clockwise, inner
            // are clockwise). Start point is slightly inside
            // the room, one foot above room level.

            XYZ toRoomVec = stepInRoom * GetLeftDirection(
                lineDirection);

            XYZ pointBottomInRoom = c.Evaluate(0.5, true)
                                    + toRoomVec;

            XYZ startPoint = pointBottomInRoom + upDir;

            // We are searching for walls only

            ElementFilter wallFilter
                = new ElementCategoryFilter(
                      BuiltInCategory.OST_Walls);

            ReferenceIntersector intersector
                = new ReferenceIntersector(wallFilter,
                                           FindReferenceTarget.Element, view3d);

            // We don't want to find elements in linked files

            intersector.FindReferencesInRevitLinks = false;

            XYZ toWallDir = GetRightDirection(
                lineDirection);

            ReferenceWithContext context = intersector
                                           .FindNearest(startPoint, toWallDir);

            Reference closestReference = null;

            if (context != null)
            {
                if ((context.Proximity > minTolerance) &&
                    (context.Proximity < maxTolerance
                     + stepInRoom))
                {
                    closestReference = context.GetReference();

                    if (closestReference != null)
                    {
                        boundaryElement = doc.GetElement(
                            closestReference);
                    }
                }
            }
            return(boundaryElement);
        }
        /// <summary>
        /// Return a reference to the topmost face of the given element.
        /// </summary>
        private Reference FindTopMostReference(Element e)
        {
            Reference ret = null;
            Document  doc = e.Document;

            #region Revit 2012
#if _2012
            using (SubTransaction t = new SubTransaction(doc))
            {
                t.Start();

                // Create temporary 3D view

                //View3D view3D = doc.Create.NewView3D( // 2012
                //  viewDirection ); // 2012

                ViewFamilyType vft
                    = new FilteredElementCollector(doc)
                      .OfClass(typeof(ViewFamilyType))
                      .Cast <ViewFamilyType>()
                      .FirstOrDefault <ViewFamilyType>(x =>
                                                       ViewFamily.ThreeDimensional == x.ViewFamily);

                Debug.Assert(null != vft,
                             "expected to find a valid 3D view family type");

                View3D view = View3D.CreateIsometric(doc, vft.Id); // 2013

                XYZ eyePosition      = XYZ.BasisZ;
                XYZ upDirection      = XYZ.BasisY;
                XYZ forwardDirection = -XYZ.BasisZ;

                view.SetOrientation(new ViewOrientation3D(
                                        eyePosition, upDirection, forwardDirection));

                XYZ viewDirection = -XYZ.BasisZ;

                BoundingBoxXYZ bb = e.get_BoundingBox(view);

                XYZ max = bb.Max;

                XYZ minAtMaxElevation = Create.NewXYZ(
                    bb.Min.X, bb.Min.Y, max.Z);

                XYZ centerOfTopOfBox = 0.5
                                       * (minAtMaxElevation + max);

                centerOfTopOfBox += 10 * XYZ.BasisZ;

                // Cast a ray through the model
                // to find the topmost surface

#if DEBUG
                //ReferenceArray references
                //  = doc.FindReferencesByDirection(
                //    centerOfTopOfBox, viewDirection, view3D ); // 2011

                IList <ReferenceWithContext> references
                    = doc.FindReferencesWithContextByDirection(
                          centerOfTopOfBox, viewDirection, view); // 2012

                double closest = double.PositiveInfinity;

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

                //  Element re = doc.GetElement( r ); // 2012

                //  if( re.Id.IntegerValue == e.Id.IntegerValue
                //    && r.ProximityParameter < closest )
                //  {
                //    ret = r;
                //    closest = r.ProximityParameter;
                //  }
                //}

                foreach (ReferenceWithContext r in references)
                {
                    Element re = doc.GetElement(
                        r.GetReference()); // 2012

                    if (re.Id.IntegerValue == e.Id.IntegerValue &&
                        r.Proximity < closest)
                    {
                        ret     = r.GetReference();
                        closest = r.Proximity;
                    }
                }

                string stable_reference = null == ret ? null
          : ret.ConvertToStableRepresentation(doc);
#endif // DEBUG

                ReferenceIntersector ri
                    = new ReferenceIntersector(
                          e.Id, FindReferenceTarget.Element, view);

                ReferenceWithContext r2 = ri.FindNearest(
                    centerOfTopOfBox, viewDirection);

                if (null == r2)
                {
                    Debug.Print("ReferenceIntersector.FindNearest returned null!");
                }
                else
                {
                    ret = r2.GetReference();

                    Debug.Assert(stable_reference.Equals(ret
                                                         .ConvertToStableRepresentation(doc)),
                                 "expected same reference from "
                                 + "FindReferencesWithContextByDirection and "
                                 + "ReferenceIntersector");
                }
                t.RollBack();
            }
#endif // _2012
            #endregion // Revit 2012

            Options opt = doc.Application.Create
                          .NewGeometryOptions();

            opt.ComputeReferences = true;

            GeometryElement geo = e.get_Geometry(opt);

            foreach (GeometryObject obj in geo)
            {
                GeometryInstance inst = obj as GeometryInstance;

                if (null != inst)
                {
                    geo = inst.GetSymbolGeometry();
                    break;
                }
            }

            Solid solid = geo.OfType <Solid>()
                          .First <Solid>(sol => null != sol);

            double z = double.MinValue;

            foreach (Face f in solid.Faces)
            {
                BoundingBoxUV b        = f.GetBoundingBox();
                UV            p        = b.Min;
                UV            q        = b.Max;
                UV            midparam = p + 0.5 * (q - p);
                XYZ           midpoint = f.Evaluate(midparam);
                XYZ           normal   = f.ComputeNormal(midparam);

                if (Util.PointsUpwards(normal))
                {
                    if (midpoint.Z > z)
                    {
                        z   = midpoint.Z;
                        ret = f.Reference;
                    }
                }
            }
            return(ret);
        }
Ejemplo n.º 34
0
        /// <summary>
        /// Used to compare two references, just compare their ProximityParameter.
        /// </summary>
        /// <param name="a">First Reference to compare</param>
        /// <param name="b">Second Reference to compare</param>
        /// <returns>-1, 0, or 1</returns>
        private int CompareReferencesWithContext(ReferenceWithContext a, ReferenceWithContext b)
        {
            if (a.Proximity > b.Proximity)
            {
                return 1;
            }

            if (a.Proximity < b.Proximity)
            {
                return -1;
            }

            return 0;
        }