Beispiel #1
0
        /// <summary>
        /// Make a line from start point to end point with the direction and style
        /// </summary>
        /// <param name="startpt">start point</param>
        /// <param name="endpt">end point</param>
        /// <param name="direction">the direction which decide the plane</param>
        /// <param name="style">line style name</param>
        public void MakeLine(Autodesk.Revit.DB.XYZ startpt, Autodesk.Revit.DB.XYZ endpt, Autodesk.Revit.DB.XYZ direction, string style)
        {
            try
            {
                m_LineCount = m_LineCount + 1;
                Line line = m_app.Application.Create.NewLineBound(startpt, endpt);
                // Line must lie in the sketch plane.  Use the direction of the line to construct a plane that hosts the target line.
                XYZ rotatedDirection = XYZ.BasisX;

                // If the direction is not vertical, cross the direction vector with Z to get a vector rotated ninety degrees.  That vector,
                // plus the original vector, form the axes of the sketch plane.
                if (!direction.IsAlmostEqualTo(XYZ.BasisZ) && !direction.IsAlmostEqualTo(-XYZ.BasisZ))
                {
                    rotatedDirection = direction.Normalize().CrossProduct(XYZ.BasisZ);
                }
                Plane       geometryPlane = m_app.Application.Create.NewPlane(direction, rotatedDirection, startpt);
                SketchPlane skplane       = m_app.ActiveUIDocument.Document.Create.NewSketchPlane(geometryPlane);
                ModelCurve  mcurve        = m_app.ActiveUIDocument.Document.Create.NewModelCurve(line, skplane);
                m_app.ActiveUIDocument.Document.Regenerate();
                ElementArray lsArr = mcurve.LineStyles;
                foreach (Autodesk.Revit.DB.Element e in lsArr)
                {
                    if (e.Name == style)
                    {
                        mcurve.LineStyle = e;
                        break;
                    }
                }
                m_app.ActiveUIDocument.Document.Regenerate();
            }
            catch (System.Exception ex)
            {
                m_outputInfo.Add("Failed to create lines: " + ex.ToString());
            }
        }
Beispiel #2
0
        /// <summary>
        /// Get an edge from the form by its endpoints
        /// </summary>
        /// <param name="form">The form contains the edge</param>
        /// <param name="startPoint">Start point of the edge</param>
        /// <param name="endPoint">End point of the edge</param>
        /// <returns>The edge found</returns>
        private Edge GetEdgeByEndPoints(Form form, Autodesk.Revit.DB.XYZ startPoint, Autodesk.Revit.DB.XYZ endPoint)
        {
            Edge edge = null;

            // Get all edges of the form
            EdgeArray edges      = null;
            Options   geoOptions = m_revitApp.Create.NewGeometryOptions();

            geoOptions.ComputeReferences = true;
            Autodesk.Revit.DB.GeometryElement geoElement = form.get_Geometry(geoOptions);
            foreach (GeometryObject geoObject in geoElement.Objects)
            {
                Solid solid = geoObject as Solid;
                if (null == solid)
                {
                    continue;
                }
                edges = solid.Edges;
            }

            // Traverse the edges and look for the edge with the right endpoints
            foreach (Edge ed in edges)
            {
                Autodesk.Revit.DB.XYZ rpPos1 = ed.Evaluate(0);
                Autodesk.Revit.DB.XYZ rpPos2 = ed.Evaluate(1);
                if ((startPoint.IsAlmostEqualTo(rpPos1) && endPoint.IsAlmostEqualTo(rpPos2)) ||
                    (startPoint.IsAlmostEqualTo(rpPos2) && endPoint.IsAlmostEqualTo(rpPos1)))
                {
                    edge = ed;
                    break;
                }
            }

            return(edge);
        }
Beispiel #3
0
        /// <summary>
        /// Create a based-line family instance by face
        /// </summary>
        /// <param name="startP">the start point</param>
        /// <param name="endP">the end point</param>
        /// <param name="faceIndex">the index of the selected face</param>
        /// <param name="familySymbolIndex">the index of the selected family symbol</param>
        /// <returns></returns>
        public bool CreateLineFamilyInstance(Autodesk.Revit.DB.XYZ startP, Autodesk.Revit.DB.XYZ endP, int faceIndex
                                             , int familySymbolIndex)
        {
            Face face = m_faceList[faceIndex];

            Autodesk.Revit.DB.XYZ projectedStartP = Project(face.Triangulate().Vertices as List <XYZ>, startP);
            Autodesk.Revit.DB.XYZ projectedEndP   = Project(face.Triangulate().Vertices as List <XYZ>, endP);

            if (projectedStartP.IsAlmostEqualTo(projectedEndP))
            {
                return(false);
            }

            Line line = Line.CreateBound(projectedStartP, projectedEndP);

            if (!m_familySymbolList[familySymbolIndex].IsActive)
            {
                m_familySymbolList[familySymbolIndex].Activate();
            }
            FamilyInstance instance = m_revitDoc.Document.Create.NewFamilyInstance(face, line
                                                                                   , m_familySymbolList[familySymbolIndex]);

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

            instanceId.Add(instance.Id);
            m_revitDoc.Selection.SetElementIds(instanceId);
            return(true);
        }
Beispiel #4
0
        /// <summary>
        /// Compute the angle between two edges
        /// </summary>
        /// <param name="edgeA">The 1st edge</param>
        /// <param name="edgeB">The 2nd edge</param>
        /// <returns>The angle of the 2 edges</returns>
        private double AngleBetweenEdges(Edge edgeA, Edge edgeB)
        {
            Autodesk.Revit.DB.XYZ vectorA = null;
            Autodesk.Revit.DB.XYZ vectorB = null;

            // find coincident vertices
            Autodesk.Revit.DB.XYZ A_0 = edgeA.Evaluate(0);
            Autodesk.Revit.DB.XYZ A_1 = edgeA.Evaluate(1);
            Autodesk.Revit.DB.XYZ B_0 = edgeB.Evaluate(0);
            Autodesk.Revit.DB.XYZ B_1 = edgeB.Evaluate(1);
            if (A_0.IsAlmostEqualTo(B_0))
            {
                vectorA = edgeA.ComputeDerivatives(0).BasisX.Normalize();
                vectorB = edgeA.ComputeDerivatives(0).BasisX.Normalize();
            }
            else if (A_0.IsAlmostEqualTo(B_1))
            {
                vectorA = edgeA.ComputeDerivatives(0).BasisX.Normalize();
                vectorB = edgeB.ComputeDerivatives(1).BasisX.Normalize();
            }
            else if (A_1.IsAlmostEqualTo(B_0))
            {
                vectorA = edgeA.ComputeDerivatives(1).BasisX.Normalize();
                vectorB = edgeB.ComputeDerivatives(0).BasisX.Normalize();
            }
            else if (A_1.IsAlmostEqualTo(B_1))
            {
                vectorA = edgeA.ComputeDerivatives(1).BasisX.Normalize();
                vectorB = edgeB.ComputeDerivatives(1).BasisX.Normalize();
            }

            if (A_1.IsAlmostEqualTo(B_0) || A_0.IsAlmostEqualTo(B_1))
            {
                vectorA = vectorA.Negate();
            }

            if (null == vectorA || null == vectorB)
            {
                return(0d);
            }
            double angle = Math.Acos(vectorA.DotProduct(vectorB));

            return(angle);
        }
Beispiel #5
0
        /// <summary>
        /// Create a based-line family instance by face
        /// </summary>
        /// <param name="startP">the start point</param>
        /// <param name="endP">the end point</param>
        /// <param name="faceIndex">the index of the selected face</param>
        /// <param name="familySymbolIndex">the index of the selected family symbol</param>
        /// <returns></returns>
        public bool CreateLineFamilyInstance(Autodesk.Revit.DB.XYZ startP, Autodesk.Revit.DB.XYZ endP, int faceIndex
                                             , int familySymbolIndex)
        {
            Face face = m_faceList[faceIndex];

            Autodesk.Revit.DB.XYZ projectedStartP = Project(face.Triangulate().Vertices as List <XYZ>, startP);
            Autodesk.Revit.DB.XYZ projectedEndP   = Project(face.Triangulate().Vertices as List <XYZ>, endP);

            if (projectedStartP.IsAlmostEqualTo(projectedEndP))
            {
                return(false);
            }

            Line           line     = m_appCreator.NewLine(projectedStartP, projectedEndP, true);
            FamilyInstance instance = m_revitDoc.Document.Create.NewFamilyInstance(face, line
                                                                                   , m_familySymbolList[familySymbolIndex]);

            m_revitDoc.Selection.Elements.Clear();
            m_revitDoc.Selection.Elements.Add(instance);
            return(true);
        }
Beispiel #6
0
        /// <summary>
        /// OK button click event
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonOK_Click(object sender, EventArgs e)
        {
            DeleteLines();
            if (!UpdateData(false))
            {
                return;
            }
            m_outputInfo.Clear();
            m_stopWatch.Start();
            Transaction transaction = new Transaction(m_doc, "RayTraceBounce");

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

            m_outputInfo.Add(elapsedTime + "\n" + "Lines = " + m_LineCount + "\n" + "Rays = " + m_RayCount);
            m_stopWatch.Reset();
            OutputInformation();
        }
Beispiel #7
0
        /// <summary>
        /// This method will find out a route to avoid the obstruction.
        /// </summary>
        /// <param name="pipe">Pipe to resolve</param>
        /// <param name="section">Pipe's one obstruction</param>
        /// <returns>A route which can avoid the obstruction</returns>
        private Line FindRoute(Pipe pipe, Section section)
        {
            // Perpendicular direction minimal length.
            double minLength = pipe.Diameter * 2;

            // Parallel direction jump step.
            double jumpStep = pipe.Diameter;

            // Calculate the directions in which to find the solution.
            List <Autodesk.Revit.DB.XYZ> dirs = new List <Autodesk.Revit.DB.XYZ>();

            Autodesk.Revit.DB.XYZ crossDir = null;
            foreach (ReferenceWithContext gref in section.Refs)
            {
                Element elem                 = m_rvtDoc.GetElement(gref.GetReference());
                Line    locationLine         = (elem.Location as LocationCurve).Curve as Line;
                Autodesk.Revit.DB.XYZ refDir = locationLine.GetEndPoint(1) - locationLine.GetEndPoint(0);
                refDir = refDir.Normalize();
                if (refDir.IsAlmostEqualTo(section.PipeCenterLineDirection) || refDir.IsAlmostEqualTo(-section.PipeCenterLineDirection))
                {
                    continue;
                }
                crossDir = refDir.CrossProduct(section.PipeCenterLineDirection);
                dirs.Add(crossDir.Normalize());
                break;
            }

            // When all the obstruction are parallel with the centerline of the pipe,
            // We can't calculate the direction from the vector.Cross method.
            if (dirs.Count == 0)
            {
                // Calculate perpendicular directions with dir in four directions.
                List <Autodesk.Revit.DB.XYZ> perDirs = PerpendicularDirs(section.PipeCenterLineDirection, 4);
                dirs.Add(perDirs[0]);
                dirs.Add(perDirs[1]);
            }

            Line foundLine = null;

            while (null == foundLine)
            {
                // Extend the section interval by jumpStep.
                section.Inflate(0, jumpStep);
                section.Inflate(1, jumpStep);

                // Find solution in the given directions.
                for (int i = 0; null == foundLine && i < dirs.Count; i++)
                {
                    // Calculate the intersections.
                    List <ReferenceWithContext> obs1 = m_detector.Obstructions(section.Start, dirs[i]);
                    List <ReferenceWithContext> obs2 = m_detector.Obstructions(section.End, dirs[i]);

                    // Filter out the intersection result.
                    Filter(pipe, obs1);
                    Filter(pipe, obs2);

                    // Find out the minimal intersections in two opposite direction.
                    ReferenceWithContext[] mins1 = GetClosestSectionsToOrigin(obs1);
                    ReferenceWithContext[] mins2 = GetClosestSectionsToOrigin(obs2);

                    // Find solution in the given direction and its opposite direction.
                    for (int j = 0; null == foundLine && j < 2; j++)
                    {
                        if (mins1[j] != null && Math.Abs(mins1[j].Proximity) < minLength ||
                            mins2[j] != null && Math.Abs(mins2[j].Proximity) < minLength)
                        {
                            continue;
                        }

                        // Calculate the maximal height that the parallel line can be reached.
                        double maxHight = 1000 * pipe.Diameter;
                        if (mins1[j] != null && mins2[j] != null)
                        {
                            maxHight = Math.Min(Math.Abs(mins1[j].Proximity), Math.Abs(mins2[j].Proximity));
                        }
                        else if (mins1[j] != null)
                        {
                            maxHight = Math.Abs(mins1[j].Proximity);
                        }
                        else if (mins2[j] != null)
                        {
                            maxHight = Math.Abs(mins2[j].Proximity);
                        }

                        Autodesk.Revit.DB.XYZ dir = (j == 1) ? dirs[i] : -dirs[i];

                        // Calculate the parallel line which can avoid obstructions.
                        foundLine = FindParallelLine(pipe, section, dir, maxHight);
                    }
                }
            }
            return(foundLine);
        }