示例#1
0
        public void AddElement(Element elm)
        {
            if (_pointStree == null)
            {
                return;
            }

            var elmid = elm.Id.IntegerValue;

            HashSet <GeometrySegment> segList;

            if (SegmentCache.ContainsKey(elmid))
            {
                segList = SegmentCache[elmid];
            }
            else
            {
                segList = new HashSet <GeometrySegment>();
            }

            if (elm.Location is LocationPoint)
            {
                var lpoint = elm.Location as LocationPoint;
                PointGeometrySegment psg = null;
                if (elm is FamilyInstance)
                {
                    var fi = elm as FamilyInstance;
                    psg = new PointGeometrySegment(elm.Id, lpoint.Point, fi.FacingOrientation, fi.HandOrientation, fi.FacingFlipped, fi.HandFlipped);
                }
                else
                {
                    psg = new PointGeometrySegment(elm.Id, lpoint.Point);
                }

                _pointStree.Add(psg, lpoint.Point);
            }
            else if (elm.Location is LocationCurve)
            {
                var curve = elm.Location as LocationCurve;
                if (curve == null)
                {
                    return;
                }

                var cseg = new CurveGeometrySegment(curve.Curve, elm);
                segList.Add(cseg);
                _pointStree.Add(cseg, cseg.MidPoint);
            }


            if (!SegmentCache.ContainsKey(elmid))
            {
                SegmentCache.Add(elmid, segList);
            }
        }
示例#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 AddElement(Element elm, bool includeGeometry, Transform tx = null)
        {
            if (_boundsStree == null || elm == null)
            {
                return;
            }


            var elmid = elm.Id.IntegerValue;

            HashSet <GeometrySegment> segList;

            if (SegmentCache.ContainsKey(elmid))
            {
                segList = SegmentCache[elmid];
            }
            else
            {
                segList = new HashSet <GeometrySegment>();
            }

            if (includeGeometry || elm is FamilyInstance)
            {
                var gop = defaultGeomOptions;
                if (elm.Category != null && _geoOptionsOverrides.ContainsKey(elm.Category.Id.IntegerValue))
                {
                    gop = _geoOptionsOverrides[elm.Category.Id.IntegerValue];
                }

                var egeo = elm.get_Geometry(gop);
                if (egeo == null)
                {
                    return;
                }

                if (tx != null)
                {
                    egeo = egeo.GetTransformed(tx);
                }

                var allSolids = GeoUtils.GetAllSolidsInGeometry(egeo);
                foreach (var sld in allSolids)
                {
                    if (!solidIsValid(sld))
                    {
                        continue;
                    }

                    var hlbbox = GeoUtils.GetGeoBoundingBox(sld, Transform.Identity);
                    if (hlbbox == null)
                    {
                        continue;
                    }
                    var geoSegment = new SolidGeometrySegment(sld, elm, hlbbox);
                    segList.Add(geoSegment);
                    _boundsStree.Add(geoSegment, hlbbox);
                }
            }

            if (elm.Location is LocationCurve)
            {
                var curve = elm.Location as LocationCurve;
                if (curve == null)
                {
                    return;
                }
                var acCurve = curve.Curve;

                if (tx != null)
                {
                    acCurve = acCurve.CreateTransformed(tx);
                }

                var cseg = new CurveGeometrySegment(acCurve, elm);
                segList.Add(cseg);
                _boundsStree.Add(cseg, cseg.Bounds);
            }


            if (!SegmentCache.ContainsKey(elmid))
            {
                SegmentCache.Add(elmid, segList);
            }
        }