private Duct createVAVConnection(Objects.Edge edge, ElementId ductType, ElementId system, IList <Objects.Node> nodes, IList <MEPCurve> curves, IList <FamilyInstance> vavs, IList <FamilyInstance> fittings) { Objects.Node n1 = nodes.Single(n => n.Id == edge.Node1); Objects.Node n2 = nodes.Single(n => n.Id == edge.Node2); Objects.Node vavNode = n1; if (n1.NodeType != Objects.Node.NodeTypeEnum.Vav) { vavNode = n2; } Objects.Node corrNode = n1; if (n1.NodeType != Objects.Node.NodeTypeEnum.Other) { corrNode = n2; } // find the nearest VAV to vavNode; // determine if we need to shift the connector on the corridor var fi = isFittingAtPoint(corrNode.Location, fittings, 0.1); MEPCurve toConnect = null; if (fi != null) { MEPController.MoveFittingAway(fi, edge.Diameter, out toConnect); } Duct d = MEPController.MakeDuct(_uiDoc.Document, vavNode.Location, corrNode.Location, ductType, system, edge.Diameter, 0.0); Connector tap = MEPController.GetNearestConnector(d, corrNode.Location); if (toConnect == null) { toConnect = findNearestCurve(corrNode.Location, curves, 0.05); } FamilyInstance fi2 = MEPController.MakeTakeOff(tap, toConnect); if (fi2 != null) { fittings.Add(fi2); } // connect to the Vav try { FamilyInstance fiVav = findNearest(vavs, vavNode.Location); Connector vavConn = MEPController.GetProperConnector(fiVav, FlowDirectionType.In, DuctSystemType.SupplyAir); Connector vavEnd = MEPController.GetNearestConnector(d, vavNode.Location); MEPController.Connect(vavConn, vavEnd); } catch { } return(d); }
public void DrawSolution(Objects.Solution sol, IList <Objects.Node> nodes, ElementId system, ElementId ductType) { Transaction t = null; if (_uiDoc.Document.IsModifiable == false) { t = new Transaction(_uiDoc.Document, "Create Ductwork"); t.Start(); } Utilities.AVFUtility.Clear(_uiDoc); // start with the corridor IList <Objects.Edge> corrEdges = sol.GetCorridorEdges(nodes); List <Duct> corrDucts = new List <Duct>(); List <Duct> allDucts = new List <Duct>(); SubTransaction st = new SubTransaction(_uiDoc.Document); st.Start(); foreach (var edge in corrEdges) { Objects.Node n1 = nodes.Single(n => n.Id == edge.Node1); Objects.Node n2 = nodes.Single(n => n.Id == edge.Node2); Duct d = MEPController.MakeDuct(_uiDoc.Document, n1.Location, n2.Location, ductType, system, edge.Diameter, 0.0); corrDucts.Add(d); allDucts.Add(d); } st.Commit(); _uiDoc.Document.Regenerate(); IList <FamilyInstance> fittings = MEPController.JoinDucts(corrDucts); IList <Objects.Edge> vavEdges = sol.GetVAVEdges(nodes); IList <MEPCurve> crvDucts = corrDucts.Cast <MEPCurve>().ToList(); var vavInstances = GetAllVAVs(); foreach (var edge in vavEdges) { //Objects.Node n1 = nodes.Single(n => n.Id == edge.Node1); //Objects.Node n2 = nodes.Single(n => n.Id == edge.Node2); //MEPController.MakeDuct(_uiDoc.Document, n1.Location, n2.Location, ductType, system, edge.Diameter, 0.0); Duct d = createVAVConnection(edge, ductType, system, nodes, crvDucts, vavInstances, fittings); } IList <Objects.Edge> shaftEdges = sol.GetShaftEdges(nodes); foreach (var edge in shaftEdges) { Objects.Node n1 = nodes.Single(n => n.Id == edge.Node1); Objects.Node n2 = nodes.Single(n => n.Id == edge.Node2); MEPController.MakeDuct(_uiDoc.Document, n1.Location, n2.Location, ductType, system, edge.Diameter, 0.0); } if (t != null) { t.Commit(); } }
public Objects.Network BuildNetwork(IList <Objects.Space> spaces, IList <FamilyInstance> VAVs, IList <FamilyInstance> shafts, IList <Line> corridorLines, bool biDirectional = false) { // here we want to start with a node for every VAV, linked to the appropriate space. // then project the VAV onto the corridor lines. // then build the edges... Objects.Network network = new Objects.Network(); List <Objects.Node> nodes = new List <Objects.Node>(); List <Objects.Edge> edges = new List <Objects.Edge>(); network.Edges = edges; network.Nodes = nodes; network.Spaces = spaces.ToList(); _ductWorkElevation = (VAVs.First().Location as LocationPoint).Point.Z; corridorLines = resetLines(corridorLines); // figure out the current phase. Phase phase = _uiDoc.Document.GetElement(_uiDoc.ActiveGraphicalView.get_Parameter(BuiltInParameter.VIEW_PHASE).AsElementId()) as Phase; foreach (var vav in VAVs) { XYZ location = (vav.Location as LocationPoint).Point; Connector c = MEPController.GetProperConnector(vav, FlowDirectionType.In, DuctSystemType.SupplyAir); if (c != null) { location = c.Origin; } location = normalizeZ(location); Objects.Node n = new Objects.Node() { Location = location, Name = "VAV-" + vav.Id.IntegerValue, NodeType = Objects.Node.NodeTypeEnum.Vav }; // determine the related space. var relatedSpace = vav.get_Space(phase); if (relatedSpace != null) { n.SpaceId = relatedSpace.UniqueId; } // while we are at it, get the connection point to the corridor XYZ connection = getClosest(location, corridorLines, true); // does this node already exist? Objects.Node connNode = lookupExisting(location, nodes); if (connNode == null) { // make a new one. connNode = new Objects.Node() { NodeType = Objects.Node.NodeTypeEnum.Other, Name = "Corridor", Location = connection }; nodes.Add(connNode); } // adding this later. nodes.Add(n); // make an edge from VAV to corridor. Objects.Edge edge = new Objects.Edge() { Node1 = n.Id, Node2 = connNode.Id, Distance = n.Location.DistanceTo(connNode.Location) }; log("Made edge from " + n.Name + " to " + connNode.Name); edges.Add(edge); } // now let's do the same thing with the shaft. foreach (var shaft in shafts) { XYZ location = (shaft.Location as LocationPoint).Point; location = normalizeZ(location); // shaft name is based on the mark Parameter mark = shaft.get_Parameter(BuiltInParameter.ALL_MODEL_MARK); string name = (String.IsNullOrEmpty(mark.AsString()) ? shaft.Id.IntegerValue.ToString() : mark.AsString()); Objects.Node n = new Objects.Node() { Location = location, Name = "Shaft-" + name, NodeType = Objects.Node.NodeTypeEnum.Shaft }; // now we need to find where this connects to the //CURRENT SIMPLIFICATION: NO SHAFT WILL BE ON TOP OF A CENTERLINE. // COME BACK AND FIX THIS LATER! XYZ connection = getClosest(location, corridorLines, true); Objects.Node connNode = lookupExisting(connection, nodes); if (connNode == null) { // make a new node connNode = new Objects.Node() { NodeType = Objects.Node.NodeTypeEnum.Other, Name = "Corridor-To-Shaft", Location = connection }; nodes.Add(connNode); } // add this later. nodes.Add(n); // make an edge that connects Objects.Edge edge = new Objects.Edge() { Node1 = connNode.Id, Node2 = n.Id, Distance = (connNode.Location.DistanceTo(n.Location)) }; log("Made edge from " + connNode.Name + " to " + n.Name); edges.Add(edge); } // see if we have any corridor line intersects/overlaps for (int i = 0; i < corridorLines.Count; i++) { for (int j = i + 1; j < corridorLines.Count; j++) { log("Checking Corrdor Lines " + i + " vs. " + j); IntersectionResultArray outInts = null; var result = corridorLines[i].Intersect(corridorLines[j], out outInts); log(" => result: " + result); switch (result) { case SetComparisonResult.Overlap: foreach (IntersectionResult res in outInts) { XYZ tmp = normalizeZ(res.XYZPoint); Objects.Node n1 = lookupExisting(tmp, nodes); if (n1 == null) { n1 = new Objects.Node() { Location = res.XYZPoint, NodeType = Objects.Node.NodeTypeEnum.Other, Name = "CorridorOverlap" }; nodes.Add(n1); } } break; } } } // then we need to connect the corridor nodes foreach (var cl in corridorLines) { // for each centerline, we want the endpoints of the centerline, and an ordered list of edges that cover it (including all of the midpoints from nodes). IList <Objects.Node> onLine = getNodesOnLine(cl, nodes); // see if we have to add the endpoints, or if they're already there. Objects.Node n1 = lookupExisting(cl.GetEndPoint(0), nodes); Objects.Node n2 = lookupExisting(cl.GetEndPoint(1), nodes); if (n1 == null) { n1 = new Objects.Node() { Location = cl.GetEndPoint(0), NodeType = Objects.Node.NodeTypeEnum.Other, Name = "CorridorEnd" }; onLine.Add(n1); nodes.Add(n1); } if (n2 == null) { n2 = new Objects.Node() { Location = cl.GetEndPoint(1), NodeType = Objects.Node.NodeTypeEnum.Other, Name = "CorridorEnd" }; onLine.Add(n2); nodes.Add(n2); } // now we want to sort these things based on the distance from n1. onLine = onLine.OrderBy(n => n.Location.DistanceTo(n1.Location)).ToList(); // make edges between each thing. for (int i = 1; i < onLine.Count; i++) { Objects.Edge corrEdge = new Objects.Edge() { Node1 = onLine[i - 1].Id, Node2 = onLine[i].Id, Distance = onLine[i - 1].Location.DistanceTo(onLine[i].Location) }; log("Made corridor edge from " + onLine[i - 1].Name + " to " + onLine[i].Name); edges.Add(corrEdge); if (biDirectional) { Objects.Edge c2 = new Objects.Edge() { Node2 = onLine[i - 1].Id, Node1 = onLine[i].Id, Distance = onLine[i - 1].Location.DistanceTo(onLine[i].Location) }; log("Made corridor edge from " + onLine[i].Name + " to " + onLine[i - 1].Name); edges.Add(c2); } } } return(network); }