public void Write(MEPRevitGraph mepGraph, Autodesk.Revit.DB.Document rootDoc) { var track = new Dictionary <MEPRevitNode, PendingNode>(); var models = new Dictionary <string, PendingNode>(); var types = new Dictionary <string, PendingNode>(); var levels = new Dictionary <string, PendingNode>(); var rootModelNode = new Model.Model(); var rootModelIdent = DocUtils.GetDocumentIdent(rootDoc); rootModelNode.Name = rootDoc.PathName; rootModelNode.ExtendedProperties.Add("Identity", rootModelIdent); rootModelNode.ExtendedProperties.Add("DateTimeStamp", System.DateTime.Now.ToShortDateString()); var rootparams = MEPGraphUtils.GetNodePropsWithElementProps(rootModelNode, rootDoc.ProjectInformation); var seid = _gdbClient.Push(rootModelNode, rootparams); models.Add(rootModelIdent, seid); //add the nodes foreach (var mepNode in mepGraph.Nodes) { var npNode = mepNode.AsAbstractNode; var elmAbParams = npNode.GetAllProperties(); if (!string.IsNullOrEmpty(mepNode.OrginDocIdent)) { var elmNode = mepNode.AsElementNode; var elmParms = elmNode.GetAllProperties(); var elmdoc = DocUtils.GetDocument(mepNode.OrginDocIdent, rootDoc.Application); var elm = elmdoc.GetElement(new Autodesk.Revit.DB.ElementId(mepNode.OriginId)); if (elm != null) { elmParms = MEPGraphUtils.GetNodePropsWithElementProps(elmNode, elm); elmAbParams = MEPGraphUtils.GetNodePropsWithElementProps(npNode, elm); } var atid = _gdbClient.Push(npNode, elmAbParams); track.Add(mepNode, atid); var elmid = _gdbClient.Push(elmNode, elmParms); //relate the element node to the abstracted model node _gdbClient.Relate(atid, elmid, Model.MEPEdgeTypes.REALIZED_BY.ToString(), null); PendingNode modelId = null; //create up model nodes if (models.ContainsKey(mepNode.OrginDocIdent)) { modelId = models[mepNode.OrginDocIdent]; } else { var modelNode = new Model.Model(); modelNode.ExtendedProperties.Add("Identity", mepNode.OrginDocIdent); var mparams = modelNode.GetAllProperties(); var ldoc = DocUtils.GetDocument(mepNode.OrginDocIdent, rootDoc.Application); if (ldoc != null) { mparams = MEPGraphUtils.GetNodePropsWithElementProps(modelNode, ldoc.ProjectInformation); } modelId = _gdbClient.Push(modelNode, mparams); models.Add(mepNode.OrginDocIdent, modelId); } var elmedgeProps = MEPGraphUtils.GetEdgeProps(elm); //connect up model node to element node _gdbClient.Relate(elmid, modelId, Model.MEPEdgeTypes.IS_IN.ToString(), elmedgeProps); Autodesk.Revit.DB.Element typeElm = null; if (elm is Autodesk.Revit.DB.FamilyInstance) { typeElm = (elm as Autodesk.Revit.DB.FamilyInstance).Symbol; } else { var mpType = elm.GetTypeId(); typeElm = elmdoc.GetElement(mpType); } //create type nodes if (typeElm != null) { PendingNode tsId = null; if (!types.ContainsKey(typeElm.UniqueId)) { var edgeProps = MEPGraphUtils.GetEdgeProps(typeElm); var tsNode = new Model.ElementType(); tsNode.Name = typeElm.Name; var tsprops1 = MEPGraphUtils.GetNodePropsWithElementProps(tsNode, typeElm); tsId = _gdbClient.Push(tsNode, tsprops1); types.Add(typeElm.UniqueId, tsId); var tselmNode = new Model.ModelElement(); var tsprops2 = MEPGraphUtils.GetNodePropsWithElementProps(tsNode, typeElm); var tselmId = _gdbClient.Push(tselmNode, tsprops2); _gdbClient.Relate(tsId, tselmId, Model.MEPEdgeTypes.REALIZED_BY.ToString(), null); _gdbClient.Relate(tselmId, modelId, Model.MEPEdgeTypes.IS_IN.ToString(), edgeProps); } else { tsId = types[typeElm.UniqueId]; } _gdbClient.Relate(atid, tsId, Model.MEPEdgeTypes.IS_OF.ToString(), null); } //create level nodes var lvl = elmdoc.GetElement(new Autodesk.Revit.DB.ElementId(mepNode.LevelId)); if (lvl != null) { var edgeProps = MEPGraphUtils.GetEdgeProps(lvl); PendingNode lvlId = null; if (!levels.ContainsKey(lvl.UniqueId)) { var lvlNode = new Model.Level(); lvlNode.Name = lvl.Name; var lvlprops = MEPGraphUtils.GetNodePropsWithElementProps(lvlNode, lvl); lvlId = _gdbClient.Push(lvlNode, lvlprops); levels.Add(lvl.UniqueId, lvlId); _gdbClient.Relate(lvlId, modelId, Model.MEPEdgeTypes.IS_IN.ToString(), edgeProps); } else { lvlId = levels[lvl.UniqueId]; } _gdbClient.Relate(atid, lvlId, Model.MEPEdgeTypes.IS_ON.ToString(), null); } } else { var modelId = _gdbClient.Push(npNode, elmAbParams); track.Add(mepNode, modelId); } } //now add the adjacencies foreach (var mepEdge in mepGraph.Edges) { if (!track.ContainsKey(mepEdge.ThisNode)) { continue; } if (!track.ContainsKey(mepEdge.NextNode)) { continue; } var nid1 = track[mepEdge.ThisNode]; var nid2 = track[mepEdge.NextNode]; var edPArams = new Dictionary <string, object>(); foreach (var wkvp in mepEdge.Weights) { edPArams.Add(wkvp.Key, wkvp.Value); } _gdbClient.Relate(nid1, nid2, mepEdge.AsNodeEdge.EdgeType.ToString(), edPArams); } //add systems and connections foreach (var system in mepGraph.Systems) { var sysNode = new Model.System(); var syselm = rootDoc.GetElement(new Autodesk.Revit.DB.ElementId(system)); var srops = MEPGraphUtils.GetNodePropsWithElementProps(sysNode, syselm); var sysNodeId = _gdbClient.Push(sysNode, srops); var tselmNode = new Model.ModelElement(); tselmNode.ExtendedProperties.Add("UniqueId", syselm.UniqueId); var emprops = MEPGraphUtils.GetNodePropsWithElementProps(tselmNode, syselm); var tselmId = _gdbClient.Push(tselmNode, emprops); _gdbClient.Relate(sysNodeId, tselmId, Model.MEPEdgeTypes.REALIZED_BY.ToString(), null); var edgeProps = MEPGraphUtils.GetEdgeProps(syselm); _gdbClient.Relate(tselmId, seid, Model.MEPEdgeTypes.IS_IN.ToString(), edgeProps); var stypeId = syselm.GetTypeId(); var typeElm = rootDoc.GetElement(stypeId); if (typeElm != null) { PendingNode tsId = null; if (!types.ContainsKey(typeElm.UniqueId)) { var stypeedgeProps = MEPGraphUtils.GetEdgeProps(typeElm); var tsNode = new Model.ElementType(); tsNode.Name = typeElm.Name; var tsprops1 = MEPGraphUtils.GetNodePropsWithElementProps(tsNode, typeElm); tsId = _gdbClient.Push(tsNode, tsprops1); types.Add(typeElm.UniqueId, tsId); var sysTypeelmNode = new Model.ModelElement(); var tsprops2 = MEPGraphUtils.GetNodePropsWithElementProps(tsNode, typeElm); var sysTypeelmId = _gdbClient.Push(sysTypeelmNode, tsprops2); _gdbClient.Relate(tsId, sysTypeelmId, Model.MEPEdgeTypes.REALIZED_BY.ToString(), null); _gdbClient.Relate(tselmId, seid, Model.MEPEdgeTypes.IS_IN.ToString(), stypeedgeProps); } else { tsId = types[typeElm.UniqueId]; } _gdbClient.Relate(sysNodeId, tsId, Model.MEPEdgeTypes.IS_OF.ToString(), null); } var snodes = mepGraph.GetAllNodesForSystem(system); foreach (var snd in snodes) { if (!track.ContainsKey(snd)) { continue; } var rid = track[snd]; _gdbClient.Relate(rid, sysNodeId, Model.MEPEdgeTypes.ABSTRACTED_BY.ToString(), null); } } AsyncContext.Run(() => _gdbClient.CommitAsync()); //var task = Task.Run(() => AsyncContext.Run(() => _gdbClient.CommitAsync())); //task.Wait(); }
public void ParseFrom(Element elm, MEPRevitGraphWriter writer) { var space = elm as Autodesk.Revit.DB.Mechanical.Space; if (space == null) { return; } if (space.Volume < 0.5) { return; } 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 lvl = space.Level; if (lvl != null) { graph.AddConnection(elm, lvl, MEPPathConnectionType.Proximity, MEPEdgeTypes.IS_ON); } //get elements in the space //get areas with edges and add to walls var sbopt = new SpatialElementBoundaryOptions(); sbopt.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish; sbopt.StoreFreeBoundaryFaces = true; //var geoOpt = new Options(); //var spgeo = space.get_Geometry(geoOpt); //get nearby spaces by extending bb of space //foreach each face of space geometry //split into uv gripd //construct line from each point //get intersect with faces on nearby faces //if it hits increment area count for direction var doc = space.Document; SpatialElementGeometryCalculator sg = new SpatialElementGeometryCalculator(doc, sbopt); var spgets = sg.CalculateSpatialElementGeometry(space); var spgeo = spgets.GetGeometry(); //var spbb = spgeo.GetBoundingBox(); var spbb = elm.get_BoundingBox(null); //var spbbhl = new HLBoundingBoxXYZ(spbb); //spbbhl.Size = spbbhl.Size + new XYZ(2, 2, 4); //get faces var uvdensity = 0.75; var maxDistance = 4D; //var nearbyFaces = nearbySpaces.OfType<SolidGeometrySegment>().Where(spc => spc.OriginatingElement != space.Id).SelectMany(sp => sp.Geometry.Faces.OfType<Face>()); var rayIncidents = new HashSet <FaceIntersectRay>(); //get all the faces in the geometry var spfaces = spgeo.Faces.OfType <Face>().ToList(); foreach (var gface in spfaces) { //extract the faces which bound with other elements (Walls, floors, ceilings, windows etc) var sfaceInfos = spgets.GetBoundaryFaceInfo(gface); foreach (var sfaceInfo in sfaceInfos) { //get the geo face and element of this bounding face var sface = sfaceInfo.GetSubface(); var elmId = sfaceInfo.SpatialBoundaryElement; var lelm = GetElementFromLinkedElement(elmId, doc); var docIdent = string.Empty; //if (lelm == null) continue; //ignore this face if it doesn't resolve to a valid element //find the bounding uv box so we can work out a grid of points var fbb = sface.GetBoundingBox(); var uExt = uvdensity; // (fbb.Max.U - fbb.Min.U) / uvdensity; var vExt = uvdensity; // (fbb.Max.V - fbb.Min.V) / uvdensity; var u = fbb.Min.U; var v = fbb.Min.V; //var sb = new GeoLib.C2DPolygon(); //construct grid for ray tracing Stack <UV> gridPoints = new Stack <UV>(); while (u <= fbb.Max.U) { v = fbb.Min.V; while (v <= fbb.Max.V) { var uvp = new UV(u, v); v += uvdensity; if (!sface.IsInside(uvp)) { continue; //only include points that are actually on this face } gridPoints.Push(uvp); } u += uvdensity; } var nerbyCheckCats = new int[] { }; IList <ElementId> hostElms = new List <ElementId>(); if (lelm != null && !(lelm is HostObject)) { var n = lelm; } if (lelm != null) { docIdent = DocUtils.GetDocumentIdent(lelm.Document); //get cutting elemtns if it's a wall so we can find door and windows if (lelm is HostObject) { var whost = lelm as HostObject; hostElms = whost.FindInserts(true, true, true, true); //build oct tree of hostelems so we can quickly ray trace them later foreach (var hostElm in hostElms) { //ignoring any link and transform for now var ehl = whost.Document.GetElement(hostElm); writer.Cache.geoCacheWriter.AddElement(ehl, true); } } //we need the nearby check to find the cut out elements nerbyCheckCats = new int[] { (int)BuiltInCategory.OST_Doors, (int)BuiltInCategory.OST_Windows }; } else { nerbyCheckCats = new int[] { (int)BuiltInCategory.OST_Doors, (int)BuiltInCategory.OST_Windows, (int)BuiltInCategory.OST_Floors, (int)BuiltInCategory.OST_Walls, (int)BuiltInCategory.OST_Roofs }; //we need the nearby check to find the bounding element switch (sfaceInfo.SubfaceType) { case SubfaceType.Bottom: nerbyCheckCats = new int[] { (int)BuiltInCategory.OST_Floors }; break; case SubfaceType.Top: nerbyCheckCats = new int[] { (int)BuiltInCategory.OST_Roofs, (int)BuiltInCategory.OST_Floors, (int)BuiltInCategory.OST_Windows }; break; case SubfaceType.Side: nerbyCheckCats = new int[] { (int)BuiltInCategory.OST_Doors, (int)BuiltInCategory.OST_Windows, (int)BuiltInCategory.OST_Walls }; break; } } //option 1 - brute force ray trace //option 2 - construct 2d polygon from edges of each face, translate each face into the same plane, then boolean intersect, get area of each intersect //calc space boundaries at midpoint? Face optLastIntermeidateFace = null; SolidGeometrySegment optLastIntermeidateSegment = null; Face optLastHitFace = null; SolidGeometrySegment optLastHitSegment = null; var arWeight = sface.Area / gridPoints.Count; while (gridPoints.Count > 0) { var pt = gridPoints.Pop(); var rayIncident = new FaceIntersectRay(); var nv = sface.ComputeNormal(pt).Normalize(); //var mx = sface.ComputeSecondDerivatives(pt).MixedDerivative.Normalize(); rayIncident.SourceElement = space; rayIncident.SourceFace = sface; rayIncident.SourceUV = pt; rayIncident.RayVecotor = nv; rayIncident.IntermediatDocIdent = docIdent; rayIncident.IntermeidateElement = lelm != null ? lelm.Id : ElementId.InvalidElementId; rayIncident.AreaWeight = arWeight; rayIncident.SubFaceType = sfaceInfo.SubfaceType; rayIncidents.Add(rayIncident); var sp = sface.Evaluate(pt); rayIncident.SourceXYZ = sp; var ray = Line.CreateBound(sp, sp + nv * 4); var rayBB = new HLBoundingBoxXYZ(sp, (sp + nv * 4), true); //rayBB.Size = rayBB.Size + new XYZ(0.5, 0.5, 0.5); //Plane geoPlane = Plane.c(sp, sp + nv * 5, sp + nv * 5 + (mx * 0.2)); //SketchPlane skPlane = SketchPlane.Create(doc, geoPlane); //doc.Create.NewModelCurve(ray, skPlane); //check cache for hit on otherside, if there is one nearby on this face we can ignore it as we're not including both sides //var nearbyrayHits = writer.Cache.rayhitCache.GetNearby(ray, 0.4F); //var validSimilarHit = nearbyrayHits.FirstOrDefault(rh => rh.HittingSegment != null && rh.HittingSegment.OriginatingElement == space.Id && rh.IntermeidateElement == rayIncident.IntermeidateElement); //if (validSimilarHit != null && sface.IsInside(validSimilarHit.HittingUV)) //{ // rayIncident.Ignore = true; // log.Info("Got hit on other side, ignoring"); // continue; // } if (optLastIntermeidateFace != null) { IntersectionResultArray issRes = null; var issGeoHit = getIntersect(pt, optLastIntermeidateFace, sface, maxDistance, out issRes, out double distance, nv, doc); if (issGeoHit) { rayIncident.IntermediatDocIdent = optLastIntermeidateSegment.OriginatingDocIdent; rayIncident.IntermeidateElement = optLastIntermeidateSegment.OriginatingElement; } else { optLastIntermeidateFace = null; optLastIntermeidateSegment = null; } } GeometrySegment[] nearbyElements = null; if (optLastIntermeidateFace == null) { nearbyElements = geoTree.GetColliding(rayBB); var nearbyCutoutElements = nearbyElements.Where(iel => (hostElms.Count == 0 || hostElms.Contains(iel.OriginatingElement)) && nerbyCheckCats.Contains(iel.OriginatingElementCategory.IntegerValue)) .OfType <SolidGeometrySegment>(); IntersectionResultArray isRes = null; bool isGeoHit = false; foreach (var extSegment in nearbyCutoutElements) { foreach (var extFace in extSegment.Geometry.Faces.OfType <Face>()) { isGeoHit = getIntersect(pt, extFace, sface, maxDistance, out isRes, out double distance, nv, doc); if (isGeoHit) { rayIncident.IntermediatDocIdent = extSegment.OriginatingDocIdent; rayIncident.IntermeidateElement = extSegment.OriginatingElement; optLastIntermeidateFace = extFace; optLastIntermeidateSegment = extSegment; break; } } if (isGeoHit) { break; } } } if (optLastHitFace != null) { var isHit = getIntersect(pt, optLastHitFace, sface, maxDistance, out var isRe, out double distance, nv, doc); var isRes = isRe; //project point onto other face instead? var srcXYZ = sface.Evaluate(pt); var otXYZRes = optLastHitFace.Project(srcXYZ); if (isHit) { var itx = isRes.OfType <IntersectionResult>().FirstOrDefault(); rayIncident.HittingFace = optLastHitFace; rayIncident.HittingSegment = optLastHitSegment; rayIncident.HittingUV = itx.UVPoint; rayIncident.HittingXYZ = itx.XYZPoint; rayIncident.Distance = distance; nv = sface.ComputeNormal(pt).Normalize(); continue; //shortcut if we find a hit on the same face again } else { optLastHitFace = null; optLastHitSegment = null; } } if (nearbyElements == null) { nearbyElements = geoTree.GetColliding(rayBB, (ob) => { return(ob.OriginatingElementCategory.IntegerValue == (int)BuiltInCategory.OST_MEPSpaces); }); } //BoundingBoxIntersectsFilter bif = new BoundingBoxIntersectsFilter(new Outline(sp - new XYZ(0.1, 0.1, 0.1), (sp + nv * 2) + new XYZ(0.1, 0.1, 0.1))); //var sfv = new FilteredElementCollector(space.Document); //var sepl = sfv.WherePasses(bif).ToElements(); var nearbySpaces = nearbyElements.Where(ne => ne.OriginatingElementCategory.IntegerValue == (int)BuiltInCategory.OST_MEPSpaces).OfType <SolidGeometrySegment>().Distinct().ToList(); //find the extents of this face which face faces on other nearby faces (whaaat?) //check each face of each nearby space for intersect with ray foreach (var nearSpace in nearbySpaces) { var isHit = false; foreach (var otFace in nearSpace.Geometry.Faces.OfType <Face>()) { isHit = getIntersect(pt, otFace, sface, maxDistance, out var isRe, out double distance, nv, doc); var isRes = isRe; //project point onto other face instead? var srcXYZ = sface.Evaluate(pt); var otXYZRes = otFace.Project(srcXYZ); if (isHit) { if (nearSpace.OriginatingElement.IntegerValue != elm.Id.IntegerValue) { var itx = isRes.OfType <IntersectionResult>().FirstOrDefault(); rayIncident.HittingFace = otFace; rayIncident.HittingSegment = nearSpace; rayIncident.HittingUV = itx.UVPoint; rayIncident.HittingXYZ = itx.XYZPoint; rayIncident.Distance = distance; nv = sface.ComputeNormal(pt).Normalize(); //optimization: check this face again first for the next ray check, since it's likely to be another hit optLastHitFace = otFace; optLastHitSegment = nearSpace; rayIncident.Ignore = false; } else { if (distance < 0.1) { isHit = false; //looks like we hit our own face, ouch! } rayIncident.Ignore = true; } break; } } if (isHit) { break; } } } } /* * space * face * intermediate element (Wall/window/door) * face (space) * face * * * add connection * this space -> section -> other space * wall ------------^ */ } //var ec = new elmComparer(); var srcNode = graph.AddElement(space); double minIncluedArea = 4; VectorBucketiser vbw = new VectorBucketiser(8, 5); var includeRays = rayIncidents.Where(r => !r.Ignore); var outsideNode = graph.Nodes.FirstOrDefault(n => n.Name == "Outside"); var groundNode = graph.Nodes.FirstOrDefault(n => n.Name == "Ground"); //group by the intermediate element (wall/floor/etc) foreach (var docGroup in includeRays.GroupBy(ri => ri.IntermediatDocIdent))//, ec)) { var sdoc = DocUtils.GetDocument(docGroup.Key, elm.Document.Application); foreach (var intermediateElemGroup in docGroup.GroupBy(ri => ri.IntermeidateElement.IntegerValue))//, ec)) { var selmid = new ElementId(intermediateElemGroup.Key); Element selm = sdoc != null?sdoc.GetElement(selmid) : null; //group similar vectors into buckets foreach (var rayVectorBuckets in intermediateElemGroup.GroupBy(ri => vbw.GetBucket(ri.RayVecotor))) { var rg = rayVectorBuckets.ToList(); var gs = rg.GroupBy(vr => vr.HittingSegment == null ? null : vr.HittingSegment.OriginatingElement).ToList(); //group each vector and intermediate element by the element it hits foreach (var orgElmGroup in gs) { //find a section already matching this section //actually easier to treat each path as separate sections //var edNodes = graph.GetEdges(intermediateElemGroup.Key).Where(ed => ed.NextNode.AsAbstractNode.Name == "Surface" //&& ed.NextNode.Connections.Any(cn => cn.NextNode.OriginId == spNode.OriginId)).Where(ed => ed.; var apporxIntersect = orgElmGroup.Sum(et => et.AreaWeight); var vector = orgElmGroup.First().RayVecotor; if (apporxIntersect < minIncluedArea) { continue; } var direction = VectorBucketiser.GetZeroClamppedPoint(orgElmGroup.First().RayVecotor); //should be rayVectorGroup.Key.AverageVector, but not yet implemented; MEPRevitNode spNode = null; if (orgElmGroup.Key != null) { var otherSpace = doc.GetElement(orgElmGroup.Key); spNode = graph.AddElement(otherSpace); } else { if (selm != null && (selm.Name.ToLower().Contains("exterior") || selm is Autodesk.Revit.DB.Opening || selm.Name.ToLower().Contains("window") || selm is Autodesk.Revit.DB.RoofBase)) { if (outsideNode == null) { outsideNode = new MEPRevitNode("Outside", "Boundary", "OutsideBoundary", new MEPGraph.Model.Environment()); } spNode = outsideNode; } else if (selm != null && (selm.Name.ToLower().Contains("floor") || selm is Autodesk.Revit.DB.Floor)) { if (groundNode == null) { groundNode = new MEPRevitNode("Ground", "Boundary", "GroundBoundary", new MEPGraph.Model.Environment()); } spNode = groundNode; } else { spNode = new MEPRevitNode("Void", "Boundary", "OtherBoundary", new MEPGraph.Model.VoidVolume()); continue; //ignore void boundaries for now } } var sectionN = graph.NewSection(selm, MEPGraph.Model.MEPEdgeTypes.IS_ON); if (selm == null) { var emptyBondary = new MEPRevitNode(); emptyBondary.AsAbstractNode.Name = "OpenBoundary"; var cl = graph.AddConnection(emptyBondary, sectionN, MEPPathConnectionType.SectionOf, MEPGraph.Model.MEPEdgeTypes.IS_ON); cl.AsNodeEdge.ExtendedProperties.Add("rvid", intermediateElemGroup.Key); } sectionN.AsAbstractNode.Name = "Surface"; var edgesf = graph.AddConnection(srcNode, sectionN, MEPPathConnectionType.Analytical, MEPGraph.Model.MEPEdgeTypes.BOUNDED_BY); //total up intersecting area var sampleIntersect = orgElmGroup.First(); edgesf.SetWeight("Area", apporxIntersect); //edgesf.SetWeight("Direction", new HoareLea.MEPGraph.Model.MEPPoint(direction.X, direction.Y, direction.Z)); edgesf.SetWeight("DirectionX", direction.X); edgesf.SetWeight("DirectionY", direction.Y); edgesf.SetWeight("DirectionZ", direction.Z); edgesf.SetWeight("SubFaceType", (int)sampleIntersect.SubFaceType); /* * HLBoundingBoxXYZ bb = new HLBoundingBoxXYZ(); * foreach (var et in orgElmGroup) * { * if (et.HittingXYZ != null) * { * bb.ExpandToContain(et.HittingXYZ); * } * } * if (!bb.IsInvalid) * { * sectionN.BoundingBox = bb; * var avgCenterPoint = bb.MidPoint; * var size = bb.Size; * sectionN.SetProperty("OriginX", avgCenterPoint.X); * sectionN.SetProperty("OriginY", avgCenterPoint.Y); * sectionN.SetProperty("OriginZ", avgCenterPoint.Z); * sectionN.SetProperty("SizeX", size.X); * sectionN.SetProperty("SizeY", size.Y); * sectionN.SetProperty("SizeZ", size.Z); * }*/ var edgest = graph.AddConnection(sectionN, spNode, MEPPathConnectionType.Analytical, MEPGraph.Model.MEPEdgeTypes.BOUNDED_BY); var directionn = direction;//.Negate(); edgest.SetWeight("Area", apporxIntersect); edgest.SetWeight("DirectionX", directionn.X); edgest.SetWeight("DirectionY", directionn.Y); edgest.SetWeight("DirectionZ", directionn.Z); edgest.SetWeight("SubFaceType", (int)sampleIntersect.SubFaceType); } } } } }
public void Write(MEPRevitGraph mepGraph, BuildingGraphMapping clientMapping, Autodesk.Revit.DB.Document rootDoc) { var track = new Dictionary <MEPRevitNode, PendingNode>(); var models = new Dictionary <string, PendingNode>(); var types = new Dictionary <string, PendingNode>(); var levels = new Dictionary <string, PendingNode>(); var rootModelNode = new Model.RevitModel(); var rootModelIdent = DocUtils.GetDocumentIdent(rootDoc); rootModelNode.Name = rootDoc.PathName; rootModelNode.ExtendedProperties.Add("Identity", rootModelIdent); rootModelNode.ExtendedProperties.Add("DateTimeStamp", System.DateTime.Now.ToShortDateString()); var schema = _gdbClient.GetSchema(); //gather data from the graph about nodes which already exist string dGather = @"query($modelIdent:String){ Model (Identity:$modelIdent){ Identity ModelElements { UniqueId AbstractElement { NodeType: __typename Name ... on Space{ Number Name Area Id } ... on Level{ Name Elevation } } } } }"; var vars = new Dictionary <string, object>(); vars.Add("modelIdent", rootModelIdent); var res = _gdbClient.ExecuteQuery(dGather, vars); var dbModels = res.Result.Model; dynamic dbRootModel = null; Dictionary <string, dynamic> modElmCache = new Dictionary <string, dynamic>(); if (models != null) { foreach (var model in models) { dbRootModel = model; foreach (var modelElement in dbModels.ModelElements) { var meID = modelElement.UniqueId.Value; if (meID == null) { continue; } if (!modElmCache.ContainsKey(meID)) { modElmCache.Add(modelElement.UniqueId.Value, modelElement); } else { //there shouldn't be multiple modElmCache[meID] = modelElement; } } } } var rootparams = MEPGraphUtils.GetNodePropsWithElementProps(rootModelNode, rootDoc.ProjectInformation, schema, clientMapping, true); PendingNode seid = null; if (dbRootModel == null) { seid = _gdbClient.Push(rootModelNode.Label, rootparams); } else { seid = _gdbClient.Push(rootModelNode.Label, rootparams); } models.Add(rootModelIdent, seid); var exprops = new Dictionary <string, object>(); exprops.Add("test", 1); //add the nodes foreach (var mepNode in mepGraph.Nodes) { var npNode = mepNode.AsAbstractNode; var elmAbParams = npNode.GetAllProperties(); if (!string.IsNullOrEmpty(mepNode.OrginDocIdent)) { var elmNode = mepNode.AsElementNode; var elmParms = elmNode.GetAllProperties(); var elmdoc = DocUtils.GetDocument(mepNode.OrginDocIdent, rootDoc.Application); var elm = elmdoc.GetElement(new Autodesk.Revit.DB.ElementId(mepNode.OriginId)); if (elm != null) { elmParms = MEPGraphUtils.GetNodePropsWithElementProps(elmNode, elm, schema, clientMapping, true); elmAbParams = MEPGraphUtils.GetNodePropsWithElementProps(npNode, elm, schema, clientMapping, true); } var atid = _gdbClient.Push(npNode.Label, elmAbParams); track.Add(mepNode, atid); var elmid = _gdbClient.Push(elmNode.Label, elmParms); //relate the element node to the abstracted model node _gdbClient.Relate(atid, elmid, Model.MEPEdgeTypes.REALIZED_BY, null); PendingNode modelId = null; //create up model nodes if (models.ContainsKey(mepNode.OrginDocIdent)) { modelId = models[mepNode.OrginDocIdent]; } else { var modelNode = new Model.RevitModel(); modelNode.ExtendedProperties.Add("Identity", mepNode.OrginDocIdent); var mparams = modelNode.GetAllProperties(); var ldoc = DocUtils.GetDocument(mepNode.OrginDocIdent, rootDoc.Application); if (ldoc != null) { mparams = MEPGraphUtils.GetNodePropsWithElementProps(modelNode, ldoc.ProjectInformation, schema, clientMapping, true); } modelId = _gdbClient.Push(modelNode.Label, mparams); models.Add(mepNode.OrginDocIdent, modelId); } var elmedgeProps = MEPGraphUtils.GetEdgeProps(elm); //connect up model node to element node _gdbClient.Relate(elmid, modelId, Model.MEPEdgeTypes.IS_IN, elmedgeProps); Autodesk.Revit.DB.Element typeElm = null; if (elm is Autodesk.Revit.DB.FamilyInstance) { typeElm = (elm as Autodesk.Revit.DB.FamilyInstance).Symbol; } else { var mpType = elm.GetTypeId(); typeElm = elmdoc.GetElement(mpType); } //create type nodes if (typeElm != null) { PendingNode tsId = null; if (!types.ContainsKey(typeElm.UniqueId)) { var edgeProps = MEPGraphUtils.GetEdgeProps(typeElm); var tsNode = new Model.ElementType(); tsNode.Name = typeElm.Name; var tsprops1 = MEPGraphUtils.GetNodePropsWithElementProps(tsNode, typeElm, schema, clientMapping, true); tsId = _gdbClient.Push(tsNode.Label, tsprops1); types.Add(typeElm.UniqueId, tsId); var tselmNode = new Model.ModelElement(); var tsprops2 = MEPGraphUtils.GetNodePropsWithElementProps(tsNode, typeElm, schema, clientMapping, true); var tselmId = _gdbClient.Push(tselmNode.Label, tsprops2); _gdbClient.Relate(tsId, tselmId, Model.MEPEdgeTypes.REALIZED_BY, exprops); _gdbClient.Relate(tselmId, modelId, Model.MEPEdgeTypes.IS_IN, edgeProps); } else { tsId = types[typeElm.UniqueId]; } _gdbClient.Relate(atid, tsId, Model.MEPEdgeTypes.IS_OF, exprops); } //create level nodes var lvl = elmdoc.GetElement(new Autodesk.Revit.DB.ElementId(mepNode.LevelId)); if (lvl != null) { var edgeProps = MEPGraphUtils.GetEdgeProps(lvl); PendingNode lvlId = null; if (!levels.ContainsKey(lvl.UniqueId)) { var lvlNode = new Model.Level(); lvlNode.Name = lvl.Name; var lvlprops = MEPGraphUtils.GetNodePropsWithElementProps(lvlNode, lvl, schema, clientMapping, true); lvlId = _gdbClient.Push(lvlNode.Label, lvlprops); levels.Add(lvl.UniqueId, lvlId); _gdbClient.Relate(lvlId, modelId, Model.MEPEdgeTypes.IS_IN, edgeProps); } else { lvlId = levels[lvl.UniqueId]; } _gdbClient.Relate(atid, lvlId, Model.MEPEdgeTypes.IS_ON, exprops); } } else { var modelId = _gdbClient.Push(npNode.Label, elmAbParams); track.Add(mepNode, modelId); } } //now add the adjacencies foreach (var mepEdge in mepGraph.Edges) { if (!track.ContainsKey(mepEdge.ThisNode)) { continue; } if (!track.ContainsKey(mepEdge.NextNode)) { continue; } var nid1 = track[mepEdge.ThisNode]; var nid2 = track[mepEdge.NextNode]; var edPArams = new Dictionary <string, object>(); foreach (var wkvp in mepEdge.Weights) { edPArams.Add(wkvp.Key, wkvp.Value); } _gdbClient.Relate(nid1, nid2, mepEdge.AsNodeEdge.EdgeType, edPArams); } //add systems and connections foreach (var system in mepGraph.Systems) { var sysNode = new Model.System(); var syselm = rootDoc.GetElement(new Autodesk.Revit.DB.ElementId(system)); var srops = MEPGraphUtils.GetNodePropsWithElementProps(sysNode, syselm, schema, clientMapping, true); var sysNodeId = _gdbClient.Push(sysNode.Label, srops); var tselmNode = new Model.ModelElement(); tselmNode.ExtendedProperties.Add("UniqueId", syselm.UniqueId); var emprops = MEPGraphUtils.GetNodePropsWithElementProps(tselmNode, syselm, schema, clientMapping, true); var tselmId = _gdbClient.Push(tselmNode.Label, emprops); _gdbClient.Relate(sysNodeId, tselmId, Model.MEPEdgeTypes.REALIZED_BY, null); var edgeProps = MEPGraphUtils.GetEdgeProps(syselm); _gdbClient.Relate(tselmId, seid, Model.MEPEdgeTypes.IS_IN, edgeProps); var stypeId = syselm.GetTypeId(); var typeElm = rootDoc.GetElement(stypeId); if (typeElm != null) { PendingNode tsId = null; if (!types.ContainsKey(typeElm.UniqueId)) { var stypeedgeProps = MEPGraphUtils.GetEdgeProps(typeElm); var tsNode = new Model.ElementType(); tsNode.Name = typeElm.Name; var tsprops1 = MEPGraphUtils.GetNodePropsWithElementProps(tsNode, typeElm, schema, clientMapping, true); tsId = _gdbClient.Push(tsNode.Label, tsprops1); types.Add(typeElm.UniqueId, tsId); var sysTypeelmNode = new Model.ModelElement(); var tsprops2 = MEPGraphUtils.GetNodePropsWithElementProps(tsNode, typeElm, schema, clientMapping, true); var sysTypeelmId = _gdbClient.Push(sysTypeelmNode.Label, tsprops2); _gdbClient.Relate(tsId, sysTypeelmId, Model.MEPEdgeTypes.REALIZED_BY, null); _gdbClient.Relate(tselmId, seid, Model.MEPEdgeTypes.IS_IN, stypeedgeProps); } else { tsId = types[typeElm.UniqueId]; } _gdbClient.Relate(sysNodeId, tsId, Model.MEPEdgeTypes.IS_OF, null); } var snodes = mepGraph.GetAllNodesForSystem(system); foreach (var snd in snodes) { if (!track.ContainsKey(snd)) { continue; } var rid = track[snd]; _gdbClient.Relate(rid, sysNodeId, Model.MEPEdgeTypes.ABSTRACTED_BY, null); } } _gdbClient.Commit(); }