This class presents an obstruction of a Pipe.
Пример #1
0
        /// <summary>
        /// Resolve one obstruction of Pipe.
        /// </summary>
        /// <param name="pipe">Pipe to resolve</param>
        /// <param name="section">One pipe's obstruction</param>
        private void Resolve(Pipe pipe, Section section)
        {
            // Find out a parallel line of pipe centerline, which can avoid the obstruction.
            Line offset = FindRoute(pipe, section);

            // Construct a section line according to the given section.
            Line sectionLine = Line.get_Bound(section.Start, section.End);

            // Construct two side lines, which can avoid the obstruction too.
            Line side1 = Line.get_Bound(sectionLine.get_EndPoint(0), offset.get_EndPoint(0));
            Line side2 = Line.get_Bound(offset.get_EndPoint(1), sectionLine.get_EndPoint(1));

            //
            // Create an "U" shape, which connected with three pipes and two elbows, to round the obstruction.
            //
            PipeType pipeType = pipe.PipeType;
            Autodesk.Revit.DB.XYZ  start = side1.get_EndPoint(0);
            Autodesk.Revit.DB.XYZ  startOffset = offset.get_EndPoint(0);
            Autodesk.Revit.DB.XYZ  endOffset = offset.get_EndPoint(1);
            Autodesk.Revit.DB.XYZ  end = side2.get_EndPoint(1);

            // Create three side pipes of "U" shape.
            Pipe pipe1 = m_rvtDoc.Create.NewPipe(start, startOffset, pipeType);
            Pipe pipe2 = m_rvtDoc.Create.NewPipe(startOffset, endOffset, pipeType);
            Pipe pipe3 = m_rvtDoc.Create.NewPipe(endOffset, end, pipeType);

            // Copy parameters from pipe to other three created pipes.
            CopyParameters(pipe, pipe1);
            CopyParameters(pipe, pipe2);
            CopyParameters(pipe, pipe3);

            // Add the created three pipes to current section.
            section.Pipes.Add(pipe1);
            section.Pipes.Add(pipe2);
            section.Pipes.Add(pipe3);

            // Create the first elbow to connect two neighbor pipes of "U" shape.
            Connector conn1 = FindConnector(pipe1, startOffset);
            Connector conn2 = FindConnector(pipe2, startOffset);
            m_rvtDoc.Create.NewElbowFitting(conn1, conn2);

            // Create the second elbow to connect another two neighbor pipes of "U" shape.
            Connector conn3 = FindConnector(pipe2, endOffset);
            Connector conn4 = FindConnector(pipe3, endOffset);
            m_rvtDoc.Create.NewElbowFitting(conn3, conn4);
        }
Пример #2
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.get_EndPoint(1) - locationLine.get_EndPoint(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;
        }
Пример #3
0
        /// <summary>
        /// Find a line Parallel to pipe's centerline to avoid the obstruction.
        /// </summary>
        /// <param name="pipe">Pipe who has obstructions</param>
        /// <param name="section">Pipe's one obstruction</param>
        /// <param name="dir">Offset Direction of the parallel line</param>
        /// <param name="maxLength">Maximum offset distance</param>
        /// <returns>Parallel line which can avoid the obstruction</returns>
        private Line FindParallelLine(Pipe pipe, Section section, Autodesk.Revit.DB.XYZ  dir, double maxLength)
        {
            double step = pipe.Diameter;
            double hight = 2 * pipe.Diameter;
            while (hight <= maxLength)
            {
                Autodesk.Revit.DB.XYZ  detal = dir * hight;
                Line line = Line.get_Bound(section.Start + detal, section.End + detal);
                List<ReferenceWithContext> refs = m_detector.Obstructions(line);
                Filter(pipe, refs);

                if (refs.Count == 0)
                {
                    return line;
                }
                hight += step;
            }
            return null;
        }
Пример #4
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;
        }
Пример #5
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);
        }
Пример #6
0
        /// <summary>
        /// Detect the obstructions of pipe and resolve them.
        /// </summary>
        /// <param name="pipe">Pipe to resolve</param>
        private void Resolve(Pipe pipe)
        {
            var parameter    = pipe.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM);
            var levelId      = parameter.AsElementId();
            var systemTypeId = m_pipingSystemType.Id;
            // Get the centerline of pipe.
            Line pipeLine = (pipe.Location as LocationCurve).Curve as Line;

            // Calculate the intersection references with pipe's centerline.
            List <ReferenceWithContext> obstructionRefArr = m_detector.Obstructions(pipeLine);

            // Filter out the references, just allow Pipe, Beam, and Duct.
            Filter(pipe, obstructionRefArr);

            if (obstructionRefArr.Count == 0)
            {
                // There are no intersection found.
                return;
            }

            // Calculate the direction of pipe's centerline.
            Autodesk.Revit.DB.XYZ dir = pipeLine.GetEndPoint(1) - pipeLine.GetEndPoint(0);

            // Build the sections from the intersection references.
            List <Section> sections = Section.BuildSections(obstructionRefArr, dir.Normalize());

            // Merge the neighbor sections if the distance of them is too close.
            for (int i = sections.Count - 2; i >= 0; i--)
            {
                Autodesk.Revit.DB.XYZ detal = sections[i].End - sections[i + 1].Start;
                if (detal.GetLength() < pipe.Diameter * 3)
                {
                    sections[i].Refs.AddRange(sections[i + 1].Refs);
                    sections.RemoveAt(i + 1);
                }
            }

            // Resolve the obstructions one by one.
            foreach (Section sec in sections)
            {
                Resolve(pipe, sec);
            }

            // Connect the neighbor sections with pipe and elbow fittings.
            //
            for (int i = 1; i < sections.Count; i++)
            {
                // Get the end point from the previous section.
                Autodesk.Revit.DB.XYZ start = sections[i - 1].End;

                // Get the start point from the current section.
                Autodesk.Revit.DB.XYZ end = sections[i].Start;

                // Create a pipe between two neighbor section.
                Pipe tmpPipe = Pipe.Create(m_rvtDoc, systemTypeId, pipe.PipeType.Id, levelId, start, end);

                // Copy pipe's parameters values to tmpPipe.
                CopyParameters(pipe, tmpPipe);

                // Create elbow fitting to connect previous section with tmpPipe.
                Connector      conn1 = FindConnector(sections[i - 1].Pipes[2], start);
                Connector      conn2 = FindConnector(tmpPipe, start);
                FamilyInstance fi    = m_rvtDoc.Create.NewElbowFitting(conn1, conn2);

                // Create elbow fitting to connect current section with tmpPipe.
                Connector      conn3 = FindConnector(sections[i].Pipes[0], end);
                Connector      conn4 = FindConnector(tmpPipe, end);
                FamilyInstance f2    = m_rvtDoc.Create.NewElbowFitting(conn3, conn4);
            }

            // Find two connectors which pipe's two ends connector connected to.
            Connector startConn = FindConnectedTo(pipe, pipeLine.GetEndPoint(0));
            Connector endConn   = FindConnectedTo(pipe, pipeLine.GetEndPoint(1));

            Pipe startPipe = null;

            if (null != startConn)
            {
                // Create a pipe between pipe's start connector and pipe's start section.
                startPipe = Pipe.Create(m_rvtDoc, pipe.PipeType.Id, levelId, startConn, sections[0].Start);
            }
            else
            {
                // Create a pipe between pipe's start point and pipe's start section.
                startPipe = Pipe.Create(m_rvtDoc, systemTypeId, pipe.PipeType.Id, levelId, sections[0].Start, pipeLine.GetEndPoint(0));
            }

            // Copy parameters from pipe to startPipe.
            CopyParameters(pipe, startPipe);

            // Connect the startPipe and first section with elbow fitting.
            Connector      connStart1 = FindConnector(startPipe, sections[0].Start);
            Connector      connStart2 = FindConnector(sections[0].Pipes[0], sections[0].Start);
            FamilyInstance fii        = m_rvtDoc.Create.NewElbowFitting(connStart1, connStart2);

            Pipe endPipe = null;
            int  count   = sections.Count;

            if (null != endConn)
            {
                // Create a pipe between pipe's end connector and pipe's end section.
                endPipe = Pipe.Create(m_rvtDoc, pipe.PipeType.Id, levelId, endConn, sections[count - 1].End);
            }
            else
            {
                // Create a pipe between pipe's end point and pipe's end section.
                endPipe = Pipe.Create(m_rvtDoc, systemTypeId, pipe.PipeType.Id, levelId, sections[count - 1].End, pipeLine.GetEndPoint(1));
            }

            // Copy parameters from pipe to endPipe.
            CopyParameters(pipe, endPipe);

            // Connect the endPipe and last section with elbow fitting.
            Connector      connEnd1 = FindConnector(endPipe, sections[count - 1].End);
            Connector      connEnd2 = FindConnector(sections[count - 1].Pipes[2], sections[count - 1].End);
            FamilyInstance fiii     = m_rvtDoc.Create.NewElbowFitting(connEnd1, connEnd2);

            // Delete the pipe after resolved.
            m_rvtDoc.Delete(pipe.Id);
        }