示例#1
0
        protected void ScanSpacesFromElement(Element elm, MEPRevitGraph graph, HashSet <int> scannedElements)
        {
            var doc = elm.Document;

            if (elm is FamilyInstance) //elm.Category.Id.IntegerValue == (int)BuiltInCategory.OST_DuctTerminal || elm.Category.Id.IntegerValue == (int)BuiltInCategory.OST_MechanicalEquipment)
            {
                var fi  = elm as FamilyInstance;
                var org = (elm.Location as LocationPoint).Point;
                var pos = (elm.Location as LocationPoint).Point;

                var   phase = doc.GetElement(elm.CreatedPhaseId) as Phase;
                var   sp    = elm.Document.GetSpaceAtPoint(pos, phase);
                Level lvl   = null;

                if (sp == null)
                {
                    var lvPAram = elm.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM);
                    if (lvPAram != null)
                    {
                        lvl = doc.GetElement(lvPAram.AsElementId()) as Level;
                        if (lvl != null)
                        {
                            var lvPs = new XYZ(pos.X, pos.Y, lvl.ProjectElevation + 1);
                            sp = elm.Document.GetSpaceAtPoint(lvPs, phase);
                        }
                    }
                }


                if (sp == null)
                {
                    var lvPAram = elm.get_Parameter(BuiltInParameter.SCHEDULE_LEVEL_PARAM);
                    if (lvPAram != null)
                    {
                        lvl = doc.GetElement(lvPAram.AsElementId()) as Level;
                        if (lvl != null)
                        {
                            var lvPs = new XYZ(pos.X, pos.Y, lvl.ProjectElevation + 1);
                            sp = elm.Document.GetSpaceAtPoint(lvPs, phase);
                        }
                    }
                }

                if (sp == null)
                {
                    var hxOrt = fi.HandOrientation.Normalize().Negate();
                    pos = org + hxOrt.Multiply(1.64042); //stub is 1.64042 feet (0.5 meters)
                    sp  = elm.Document.GetSpaceAtPoint(pos, phase);
                }

                if (sp == null)
                {
                    var hxOrt = fi.HandOrientation.Normalize().Negate();
                    pos = org + hxOrt.Multiply(-1.64042); //stub is 1.64042 feet (0.5 meters)
                    sp  = elm.Document.GetSpaceAtPoint(pos, phase);
                }


                if (sp == null)
                {
                    pos = org + new XYZ(0, 0, -4);
                    sp  = elm.Document.GetSpaceAtPoint(pos, phase);
                }

                if (sp != null)
                {
                    scannedElements.Add(sp.Id.IntegerValue);

                    graph.AddConnection(elm, sp, pos, MEPPathConnectionType.Phyiscal, MEPGraph.Model.MEPEdgeTypes.IS_IN_SPACE);

                    if (elm.Category.Id.IntegerValue == (int)BuiltInCategory.OST_DuctTerminal)
                    {
                        //try to find out if this terminal is supply or extract
                        ConnectorManager currentCm = MEPUtils.GetConnectionManager(elm);

                        var inConn = currentCm != null?currentCm.Connectors.OfType <Connector>().Where(cn =>
                                                                                                       cn.Domain == Autodesk.Revit.DB.Domain.DomainHvac &&
                                                                                                       (cn.ConnectorType == ConnectorType.End || cn.ConnectorType == ConnectorType.Curve) &&
                                                                                                       cn.Direction == FlowDirectionType.In).FirstOrDefault() : null;

                        if (inConn != null)
                        {
                            graph.AddConnection(elm, sp, pos, MEPPathConnectionType.Analytical, MEPGraph.Model.MEPEdgeTypes.FLOWS_TO_SPACE);
                        }
                        else
                        {
                            graph.AddConnection(sp, elm, pos, MEPPathConnectionType.Analytical, MEPGraph.Model.MEPEdgeTypes.FLOWS_TO_SPACE);
                        }
                    }
                }

                if (lvl != null)
                {
                    graph.AddConnection(elm, lvl, MEPPathConnectionType.Proximity, MEPGraph.Model.MEPEdgeTypes.IS_ON);
                }
            }
        }
示例#2
0
        public virtual void ParseFrom(Element elm, MEPRevitGraphWriter writer)
        {
            var scannedElements = writer.Cache.ParsedElements;
            var cpTree          = writer.Cache.connectorsCache;
            var geoTree         = writer.Cache.geoCache;
            var maxDepth        = writer.Cache.MaxDepth;
            var graph           = writer.Graph;


            var elmStack = new Stack <Tuple <Element, XYZ> >();

            elmStack.Push(new Tuple <Element, XYZ>(elm, null));


            var previouseConnections = new HashSet <Connector>();

            while (elmStack.Count >= 1)
            {
                var currentElementAndpt = elmStack.Pop();
                var currentElement      = currentElementAndpt.Item1;
                var orgPoint            = currentElementAndpt.Item2;
                scannedElements.Add(currentElement.Id.IntegerValue);

                ConnectorManager currentCm = Utils.MEPUtils.GetConnectionManager(currentElement);
                if (currentCm == null)
                {
                    continue;
                }

                var connStack = new Stack <Connector>();
                foreach (var conn in currentCm.Connectors.OfType <Connector>().Where(cn => cn.ConnectorType == ConnectorType.End || cn.ConnectorType == ConnectorType.Curve))// && !previouseConnections.Any(pc => pc.IsConnectedTo(cn))))
                {
                    connStack.Push(conn);
                }

                XYZ nextOrigin = null;
                while (connStack.Count >= 1)
                {
                    var       currentConn   = connStack.Pop();
                    Connector nextConnector = null;
                    Element   nextElement   = null;
                    nextOrigin = currentConn.Origin;
                    MEPRevitEdge edge = null;

                    var meps     = GetSectionForConnctor(currentConn);
                    var edgeType = MEPGraph.Model.MEPEdgeTypes.FLOWS_TO;
                    switch (currentConn.Domain)
                    {
                    case Autodesk.Revit.DB.Domain.DomainCableTrayConduit:
                        edgeType = MEPGraph.Model.MEPEdgeTypes.CABLETRAY_FLOW_TO;
                        break;

                    case Autodesk.Revit.DB.Domain.DomainElectrical:
                        edgeType = MEPGraph.Model.MEPEdgeTypes.ELECTRICAL_FLOW_TO;
                        break;

                    case Autodesk.Revit.DB.Domain.DomainPiping:
                        edgeType = MEPGraph.Model.MEPEdgeTypes.HYDRONIC_FLOW_TO;
                        break;

                    case Autodesk.Revit.DB.Domain.DomainHvac:
                        edgeType = MEPGraph.Model.MEPEdgeTypes.AIR_FLOW_TO;
                        break;

                    case Autodesk.Revit.DB.Domain.DomainUndefined:
                        edgeType = MEPGraph.Model.MEPEdgeTypes.FLOWS_TO;
                        break;
                    }

                    if (currentConn.IsConnected)
                    {
                        //var ci = currentConn.GetMEPConnectorInfo();
                        //connection search
                        nextConnector = currentConn.AllRefs.OfType <Connector>().Where(cn => (cn.ConnectorType == ConnectorType.End || cn.ConnectorType == ConnectorType.Curve) && cn.IsConnectedTo(currentConn) && cn.Owner.Id.IntegerValue != currentElement.Id.IntegerValue).FirstOrDefault();
                        if (nextConnector != null)
                        {
                            previouseConnections.Add(currentConn);
                            edge        = graph.AddConnection(currentConn, nextConnector, MEPPathConnectionType.Phyiscal, edgeType);
                            nextElement = nextConnector.Owner;
                        }
                    }

                    if (nextConnector == null)
                    {
                        //geometry search
                        var connPoint         = currentConn.Origin;
                        var nearPoints        = cpTree.GetNearby(connPoint, 1F);
                        var nearPointsOrdered = nearPoints.Where(el => el.OriginatingElement.IntegerValue != currentElement.Id.IntegerValue).OrderBy(d => d.Point.DistanceTo(connPoint)).ToList();
                        var nearest           = nearPointsOrdered.FirstOrDefault();
                        if (nearest != null)
                        {
                            var distance = nearest.Point.DistanceTo(connPoint);
                            if (distance < 0.01F)
                            {
                                var nearElm = elm.Document.GetElement(nearest.OriginatingElement);
                                if (nearElm != null)
                                {
                                    var mepm = MEPUtils.GetConnectionManager(nearElm);
#if REVIT2016
                                    nextConnector = (mepm != null) ? mepm.Connectors.OfType <Connector>().Where(cn => (cn.ConnectorType == ConnectorType.End || cn.ConnectorType == ConnectorType.Curve) && cn.Id == nearest.ConnectorIndex).FirstOrDefault() : null;
#else
                                    throw new Exception("Only supported in Revit 2016 onwards");
#endif
                                    if (nextConnector != null)
                                    {
                                        previouseConnections.Add(currentConn);
                                        edge        = graph.AddConnection(currentConn, nextConnector, MEPPathConnectionType.Proximity, edgeType);
                                        nextElement = nextConnector.Owner;
                                        //nextOrigin = nextConnector.Origin;
                                    }
                                }
                            }
                        }

                        if (nextConnector == null && geoTree != null)
                        {
                            //todo: curve - point intersection check
                            var colBox       = new HLBoundingBoxXYZ(connPoint, new XYZ(0.1, 0.1, 0.1));
                            var nearbyCurves = geoTree.GetColliding(colBox);

                            var nearbyCurve = nearbyCurves.OfType <CurveGeometrySegment>().Where(nb => nb.OriginatingElement.IntegerValue != currentConn.Owner.Id.IntegerValue).OrderBy(nd => nd.Geometry.Distance(connPoint)).FirstOrDefault();
                            if (nearbyCurve != null)
                            {
                                var distance = nearbyCurve.Geometry.Distance(connPoint);
                                //check if connector is sitting near or with extent of the mepcurve
                                var tolerence = 0.01;
                                if (distance < tolerence ||
                                    nearbyCurve.Radius > 0.001 && distance <= (nearbyCurve.Radius + tolerence) ||
                                    nearbyCurve.Width > 0.001 && distance <= (nearbyCurve.Width + tolerence) ||
                                    nearbyCurve.Height > 0.001 && distance <= (nearbyCurve.Height + tolerence))
                                {
                                    //how to add this connection to the graph with no next connector??
                                    var orgElme = elm.Document.GetElement(nearbyCurve.OriginatingElement);
                                    edge        = graph.AddConnection(currentConn, connPoint, orgElme, MEPPathConnectionType.ProximityNoConnector, edgeType);
                                    nextElement = orgElme;
                                    //nextOrigin = connPoint;
                                }
                            }
                        }
                    }

                    if (edge != null && edge.Length < 0.1)
                    {
                        if (meps != null)
                        {
                            edge.Length = meps.TotalCurveLength;
                            edge.SetWeight("Roughness", meps.Roughness);
                            edge.SetWeight("ReynoldsNumber", meps.ReynoldsNumber);
                            edge.SetWeight("Velocity", meps.Velocity);
                            edge.SetWeight("VelocityPressure", meps.VelocityPressure);
                            edge.SetWeight("Flow", meps.Flow);
                        }
                        else if (orgPoint != null && nextOrigin != null)
                        {
                            var length = Math.Abs(orgPoint.DistanceTo(nextOrigin));
                            //very crude way to get length, should really be using MEPSection
                            if (length >= 0.1)
                            {
                                edge.Length = length;
                            }
                        }
                    }


                    ScanSpacesFromElement(currentConn, graph, scannedElements, nextElement == null);


                    var currentDepth = elmStack.Count;
                    if (nextElement != null && (maxDepth == -1 || currentDepth < maxDepth) && !scannedElements.Contains(nextElement.Id.IntegerValue))// && !graph.ContainsElement(nextElement))
                    {
                        elmStack.Push(new Tuple <Element, XYZ>(nextElement, nextOrigin));

                        //ScanFromElement(elm, graph, cpTree, maxDepth, currentDepth++);
                    }
                }

                //check curve for nearby unconnected points
                if (cpTree != null && currentElement is MEPCurve)
                {
                    //point - curve intersection check
                    var curveElm = currentElement as MEPCurve;

                    var locCurve     = curveElm.Location as LocationCurve;
                    var curve        = locCurve.Curve;
                    var nearbyCurve  = new CurveGeometrySegment(curve, currentElement);
                    var P1           = curve.GetEndPoint(0);
                    var P2           = curve.GetEndPoint(1);
                    var curveAsLine  = curve is Line ? curve as Line : Line.CreateBound(P1, P2);
                    var nearbyCurves = cpTree.GetNearby(curveAsLine, (float)nearbyCurve.MaxDimension);

                    foreach (var cb in nearbyCurves)
                    {
                        if (cb.OriginatingElement.IntegerValue == currentElement.Id.IntegerValue)
                        {
                            continue;
                        }
                        if (P1.DistanceTo(cb.Point) < 0.01)
                        {
                            continue;
                        }
                        if (P2.DistanceTo(cb.Point) < 0.01)
                        {
                            continue;
                        }

                        var tolerence = 0.01;
                        var cnpoint   = curveAsLine.Project(cb.Point);
                        var distance  = cnpoint.Distance;

                        //distance check is a crude way to check this element is sitting in the duct/pipe, could be nearby but intended to be connected.
                        if (distance < (nearbyCurve.MaxDimension / 2) + tolerence)
                        {
                            var orgElme = elm.Document.GetElement(cb.OriginatingElement);
                            if (orgElme == null)
                            {
                                continue;
                            }
                            var cmgr = MEPUtils.GetConnectionManager(orgElme);
                            if (cmgr == null)
                            {
                                continue;
                            }
#if REVIT2016
                            var nc = cmgr.Connectors.OfType <Connector>().FirstOrDefault(cn => cn.Id == cb.ConnectorIndex);
#else
                            Connector nc = null;
#endif
                            if (nc == null || nc.IsConnected)
                            {
                                continue;
                            }

                            //further check that direction of point intersects curve
                            var prjInX  = nc.CoordinateSystem.OfPoint(new XYZ(0, 0, 5));
                            var prjInnX = nc.CoordinateSystem.OfPoint(new XYZ(0, 0, -5));

                            var prjLine = Line.CreateBound(prjInnX, prjInX);
                            var ix      = curveAsLine.Intersect(prjLine);
                            if (ix != SetComparisonResult.Overlap)
                            {
                                continue;
                            }


                            var edge = graph.AddConnection(nc, cnpoint.XYZPoint, currentElement, MEPPathConnectionType.ProximityNoConnector, MEPGraph.Model.MEPEdgeTypes.FLOWS_TO);

                            if (orgPoint != null)
                            {
                                edge.Length = Math.Abs(orgPoint.DistanceTo(cnpoint.XYZPoint));
                            }


                            if (!scannedElements.Contains(orgElme.Id.IntegerValue) && !elmStack.Any(el => el.Item1 == orgElme))// && !graph.ContainsElement(nextElement))
                            {
                                elmStack.Push(new Tuple <Element, XYZ>(orgElme, cnpoint.XYZPoint));
                            }
                        }
                    }
                }

                ScanSpacesFromElement(currentElement, graph, scannedElements);
            }
        }
示例#3
0
        public void Write(ICollection <Element> scanElements, ICollection <Element> geoSerchElements, int maxDepth, bool doGeometryMatch, Document doc)
        {
            Cache.connectorsCache = new PointOctree <ConnectorPointGeometrySegment>(6.56168F, XYZ.Zero, 2F);
            Cache.MaxDepth        = maxDepth;
            Cache.geoCache        = new BoundsOctree <GeometrySegment>(2, XYZ.Zero, 2F, 1.001f);
            Cache.geoCacheWriter  = new BoundsOctreeElementWriter(Cache.geoCache);
            Cache.ParsedElements  = new HashSet <int>();
            Cache.rayhitCache     = new PointOctree <FaceIntersectRay>(2, XYZ.Zero, 2F);

            var dsCount = geoSerchElements.Count;

            foreach (var elm in geoSerchElements)
            {
                var cmn = MEPUtils.GetConnectionManager(elm);
                if (cmn != null)
                {
                    foreach (var conn in cmn.Connectors.OfType <Connector>())
                    {
#if REVIT2016
                        var gesseg = new ConnectorPointGeometrySegment(elm.Id, conn.Origin, conn.Id);
                        Cache.connectorsCache.Add(gesseg, conn.Origin);
#else
                        throw new Exception("Only supported in Revit 2016 onwards");
#endif
                    }
                }

                if (doGeometryMatch)
                {
                    Cache.geoCacheWriter.AddElement(elm, true);
                }
            }

            if (doGeometryMatch)
            {
                var li = DocUtils.GetLinkInstances(doc);
                dsCount = li.Count();
                //cache geometry in linked documents. The geometry is expected to remain static, or changed as a block, so we don't need to keep track of each element.
                foreach (var linkedInstance in li)
                {
                    Transform docTransform        = linkedInstance.GetTotalTransform();
                    Transform docTransformInverse = docTransform.Inverse;

                    //RevitLinkType linkType = (RevitLinkType)rDoc.GetElement(linkedInstance.GetTypeId()) as RevitLinkType;
                    var ldoc = linkedInstance.GetLinkDocument();// HLRevitUtilities.GetLinkedDocumentFromType(_rdoc.Application, linkType);
                    if (ldoc == null)
                    {
                        continue;
                    }

                    var lnGeoCol    = new FilteredElementCollector(ldoc);
                    var lnGeoFilter = new ElementMulticategoryFilter(new BuiltInCategory[] { BuiltInCategory.OST_Floors, BuiltInCategory.OST_Roofs });

                    foreach (var lnelm in lnGeoCol.WherePasses(lnGeoFilter).WhereElementIsNotElementType().ToElements())
                    {
                        Cache.geoCacheWriter.AddElement(lnelm, true, docTransformInverse);
                    }
                }
            }


            var elmcache    = new HashSet <int>();
            var parserCount = Parsers.Count;

            foreach (var parser in Parsers)
            {
                parser.InitializeGraph(this);
                var elms = scanElements.Where(el => parser.CanParse(el)).ToList();
                dsCount = elms.Count();

                foreach (var elm in elms)
                {
                    parser.ParseFrom(elm, this);
                }
                parser.FinalizeGraph(this);
            }
        }
示例#4
0
 public virtual bool CanParse(Element elm)
 {
     return(MEPUtils.GetConnectionManager(elm) != null);
 }
        protected void ScanSpacesFromElement(Element elm, MEPRevitGraph graph, HashSet <int> scannedElements, Transform hostTx, Document SpacesModel)
        {
            var elmDoc = elm.Document;

            var gpNode = graph.AddElement(elm, true);

            if (elm is FamilyInstance) //elm.Category.Id.IntegerValue == (int)BuiltInCategory.OST_DuctTerminal || elm.Category.Id.IntegerValue == (int)BuiltInCategory.OST_MechanicalEquipment)
            {
                var fi  = elm as FamilyInstance;
                var org = (elm.Location as LocationPoint).Point;
                var pos = (elm.Location as LocationPoint).Point;

                if (fi.HasSpatialElementCalculationPoint)
                {
                    pos = fi.GetSpatialElementCalculationPoint();
                }

                pos = hostTx.OfPoint(pos);

                Level lvl = null;
                //need to do phase mapping if elmDoc is not the same as the SpacesModel
                var phase = SpacesModel.GetElement(elm.CreatedPhaseId) as Phase;

                var sp = fi.Space;

                if (sp == null)
                {
                    sp = SpacesModel.GetSpaceAtPoint(pos, phase);
                }

                if (lvl == null)
                {
                    var lvPAram = elm.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM);
                    if (lvPAram != null)
                    {
                        lvl = elmDoc.GetElement(lvPAram.AsElementId()) as Level;
                    }
                }


                if (lvl == null)
                {
                    var lvPAram = elm.get_Parameter(BuiltInParameter.SCHEDULE_LEVEL_PARAM);
                    if (lvPAram != null)
                    {
                        lvl = elmDoc.GetElement(lvPAram.AsElementId()) as Level;
                    }
                }

                if (lvl == null && sp != null)
                {
                    lvl = sp.Level;
                }

                if (lvl == null)
                {
                    lvl = elmDoc.GetElement(fi.LevelId) as Level;
                }

                //check around element for a space
                double chDistance = 3.28084; //3.28084 = 1m

                if (sp == null)
                {
                    var hxOrt = fi.HandOrientation.Normalize().Negate();
                    pos = org + hxOrt.Multiply(-chDistance);
                    pos = hostTx.OfPoint(pos);
                    sp  = SpacesModel.GetSpaceAtPoint(pos, phase);
                }


                if (sp == null)
                {
                    var hxOrt = fi.HandOrientation.Normalize().Negate();
                    pos = org + hxOrt.Multiply(chDistance);
                    pos = hostTx.OfPoint(pos);
                    sp  = SpacesModel.GetSpaceAtPoint(pos, phase);
                }

                if (sp == null)
                {
                    var hxOrt = fi.FacingOrientation.Normalize().Negate();
                    pos = org + hxOrt.Multiply(-chDistance);
                    pos = hostTx.OfPoint(pos);
                    sp  = SpacesModel.GetSpaceAtPoint(pos, phase);
                }

                if (sp == null)
                {
                    var hxOrt = fi.FacingOrientation.Normalize().Negate();
                    pos = org + hxOrt.Multiply(chDistance);
                    pos = hostTx.OfPoint(pos);
                    sp  = SpacesModel.GetSpaceAtPoint(pos, phase);
                }

                if (sp == null)
                {
                    pos = org + new XYZ(0, 0, -chDistance);
                    pos = hostTx.OfPoint(pos);
                    sp  = SpacesModel.GetSpaceAtPoint(pos, phase);
                }

                if (sp != null && sp.Level != null)
                {
                    lvl = sp.Level;
                }

                if (sp == null && lvl != null)
                {
                    var lvPs = new XYZ(pos.X, pos.Y, lvl.ProjectElevation + 2);
                    lvPs = hostTx.OfPoint(lvPs);
                    sp   = elm.Document.GetSpaceAtPoint(lvPs, phase);
                }

                if (sp != null)
                {
                    scannedElements.Add(sp.Id.IntegerValue);

                    graph.AddConnection(elm, sp, pos, MEPPathConnectionType.Phyiscal, Model.MEPEdgeTypes.IS_IN_SPACE);

                    if (elm.Category.Id.IntegerValue == (int)BuiltInCategory.OST_DuctTerminal)
                    {
                        //try to find out if this terminal is supply or extract
                        ConnectorManager currentCm = MEPUtils.GetConnectionManager(elm);

                        var inConn = currentCm != null?currentCm.Connectors.OfType <Connector>().Where(cn =>
                                                                                                       cn.Domain == Autodesk.Revit.DB.Domain.DomainHvac &&
                                                                                                       (cn.ConnectorType == ConnectorType.End || cn.ConnectorType == ConnectorType.Curve) &&
                                                                                                       cn.Direction == FlowDirectionType.In).FirstOrDefault() : null;

                        if (inConn != null)
                        {
                            graph.AddConnection(elm, sp, pos, MEPPathConnectionType.Analytical, Model.MEPEdgeTypes.FLOWS_TO_SPACE);
                        }
                        else
                        {
                            graph.AddConnection(sp, elm, pos, MEPPathConnectionType.Analytical, Model.MEPEdgeTypes.FLOWS_TO_SPACE);
                        }
                    }
                }

                if (lvl != null)
                {
                    gpNode.LevelId = lvl.Id.IntegerValue;
                }
            }
        }