/// <summary> /// Now that the portData has been set for the new ports, we recreate the connections we /// so mercilessly destroyed, restoring peace and balance to the world once again. /// </summary> /// <param name="inportConnections"></param> /// <param name="outportConnections"> List of the connections that were killed</param> private void LoadAndCreateConnectors(OrderedDictionary inportConnections, OrderedDictionary outportConnections) { //----------------------------Inputs--------------------------------- /* Input Port connections are matched only if the name is the same */ for (int i = 0; i < InPortData.Count; i++) { string varName = InPortData[i].ToolTipString; if (inportConnections.Contains(varName)) { if (inportConnections[varName] != null) { foreach (var startPortModel in (inportConnections[varName] as List<PortModel>)) { NodeModel startNode = startPortModel.Owner; var connector = ConnectorModel.Make( startNode, this, startPortModel.Index, i); } outportConnections[varName] = null; } } } //----------------------------Outputs-------------------------------- /*The matching is done in three parts: *Step 1: * First, it tries to match the connectors wrt to the defined * variable name. Hence it first checks to see if any of the old * variable names are present. If so, if there were any connectors * presnt then it makes the new connectors. As it iterates through * the new ports, it also finds the ports that didnt exist before */ List<int> undefinedIndices = new List<int>(); for (int i = 0; i < OutPortData.Count; i++) { string varName = OutPortData[i].ToolTipString; if (outportConnections.Contains(varName)) { if (outportConnections[varName] != null) { foreach (var endPortModel in (outportConnections[varName] as List<PortModel>)) { NodeModel endNode = endPortModel.Owner; var connector = ConnectorModel.Make(this, endNode, i, endPortModel.Index); } outportConnections[varName] = null; } } else undefinedIndices.Add(i); } /* *Step 2: * The second priority is to match the connections to the previous * indices. For all the ports that were not previously defined, it * now checks if that "numbered" port had any connections * previously, ie, if the old third port had 2 connections, then * these would go to the new 3rd port (if it is not a variable that * was defined before) */ for (int i = 0; i < undefinedIndices.Count; i++) { int index = undefinedIndices[i]; if (index < outportConnections.Count && outportConnections[index] != null) { foreach (PortModel endPortModel in (outportConnections[index] as List<PortModel>)) { NodeModel endNode = endPortModel.Owner; var connector = ConnectorModel.Make(this, endNode, index, endPortModel.Index); } outportConnections[index] = null; undefinedIndices.Remove(index); i--; } } /* *Step 2: * The final step. Now that the priorties are finished, the * function tries to reuse any existing connections by attaching * them to any ports that have not already been given connections */ List<List<PortModel>> unusedConnections = outportConnections.Values.Cast<List<PortModel>>() .Where(portModelList => portModelList != null) .ToList(); while (undefinedIndices.Count > 0 && unusedConnections.Count != 0) { foreach (PortModel endPortModel in unusedConnections[0]) { NodeModel endNode = endPortModel.Owner; ConnectorModel connector = ConnectorModel.Make( this, endNode, undefinedIndices[0], endPortModel.Index); } undefinedIndices.RemoveAt(0); unusedConnections.RemoveAt(0); } }
/// <summary> /// Reduces the number of rows, based on the entries inside rows parameter. /// E.g. rows = { "Insert", "Day", "Of", "Week", "Here" }, maxRows == 3 /// Result { "Insert", "Day", "Of Week Here" } /// </summary> /// <param name="rows">Incoming rows</param> /// <param name="maxRows">Max number of rows</param> internal static IEnumerable<string> ReduceRowCount(List<string> rows, int maxRows) { if (rows == null || maxRows <= 0) throw new ArgumentException(); var results = new List<string>(); foreach (var row in rows) { // There are still room in the results list. if (results.Count < maxRows) { results.Add(row); continue; } // Already full, keep appending to last row. var lastRow = results.Last(); results.Remove(lastRow); results.Add(lastRow + " " + row); } return results; }
public override Value Evaluate(FSharpList<Value> args) { if (_reference.ElementReferenceType != ElementReferenceType.REFERENCE_TYPE_SURFACE && _reference.ElementReferenceType != ElementReferenceType.REFERENCE_TYPE_LINEAR ) { ElementId refElementId = _reference.ElementId; Element refElement = dynRevitSettings.Doc.Document.GetElement(refElementId); if (refElement is ReferencePoint) { ReferencePoint rp = refElement as ReferencePoint; XYZ rpXYZ = rp.Position; return Value.NewContainer(rpXYZ); } GeometryObject thisObjectPoint = SelectedElement.GetGeometryObjectFromReference(_reference); if (!(thisObjectPoint is Autodesk.Revit.DB.Point)) throw new Exception("Could not use face or edge which is not part of the model"); var thisPoint = thisObjectPoint as Autodesk.Revit.DB.Point; XYZ pointXYZ = thisPoint.Coord; return Value.NewContainer(pointXYZ); } GeometryObject thisObject = SelectedElement.GetGeometryObjectFromReference(_reference); Autodesk.Revit.DB.Transform thisTrf = null; if (_init && (old_refXyz == null || !_reference.Equals(old_refXyz))) _init = false; { GeometryObject geomObj = SelectedElement.get_Geometry(new Options()); var geomElement = geomObj as GeometryElement; // ugly code to detect if transform for geometry object is needed or not // filed request to provide this info via API, but meanwhile ... foreach (GeometryObject geob in geomElement) { if (!(geob is GeometryInstance)) continue; var ginsta = geob as GeometryInstance; GeometryElement gSymbolElement = ginsta.GetSymbolGeometry(); var geometryElements = new List<GeometryElement> { gSymbolElement }; bool found = false; for (; geometryElements.Count > 0 && !found;) { GeometryElement thisGeometryElement = geometryElements[0]; geometryElements.Remove(thisGeometryElement); foreach (GeometryObject geobSym in thisGeometryElement) { if (geobSym is GeometryElement) { geometryElements.Add(geobSym as GeometryElement); continue; } if ((thisObject is Curve) && (geobSym is Curve) && (thisObject == geobSym)) { found = true; break; } if (thisObject is Curve) continue; if ((thisObject is Autodesk.Revit.DB.Face) && (geobSym is Autodesk.Revit.DB.Face) && (thisObject == geobSym)) { found = true; break; } if ((thisObject is Edge) && (geobSym is Autodesk.Revit.DB.Face)) { var edge = thisObject as Edge; //use GetFace after r2013 support is dropped if (geobSym == edge.get_Face(0) || geobSym == edge.get_Face(1)) { found = true; break; } } if (!(geobSym is Solid)) continue; FaceArray solidFaces = ((Solid)geobSym).Faces; int numFaces = solidFaces.Size; for (int index = 0; index < numFaces && !found; index++) { Autodesk.Revit.DB.Face faceAt = solidFaces.get_Item(index); if ((thisObject is Autodesk.Revit.DB.Face) && (thisObject == faceAt)) { found = true; break; } if (thisObject is Edge) { var edge = thisObject as Edge; //use GetFace after r2013 support is dropped if (faceAt == edge.get_Face(0) || faceAt == edge.get_Face(1)) { found = true; break; } } } } } if (found) { thisTrf = ginsta.Transform; break; } } if (thisObject == null) throw new Exception("could not resolve reference for XYZ on Element"); } XYZ thisXYZ; if (_reference.ElementReferenceType == ElementReferenceType.REFERENCE_TYPE_SURFACE && thisObject is Autodesk.Revit.DB.Face) { var face = thisObject as Autodesk.Revit.DB.Face; if (!_init) { _param0 = _reference.UVPoint[0]; _param1 = _reference.UVPoint[1]; _init = true; } var uv = new UV(_param0, _param1); thisXYZ = face.Evaluate(uv); if (thisTrf != null) thisXYZ = thisTrf.OfPoint(thisXYZ); } else if (_reference.ElementReferenceType == ElementReferenceType.REFERENCE_TYPE_LINEAR) { Curve curve; if (thisObject is Edge) { var edge = (Edge)SelectedElement.GetGeometryObjectFromReference(_reference); curve = edge.AsCurve(); } else curve = (Curve)SelectedElement.GetGeometryObjectFromReference(_reference); if (curve != null) { if (_init) thisXYZ = curve.Evaluate(_param0, true); else { XYZ curPoint = _reference.GlobalPoint; if (thisTrf != null) { Autodesk.Revit.DB.Transform inverseTrf = thisTrf.Inverse; curPoint = inverseTrf.OfPoint(_reference.GlobalPoint); } IntersectionResult thisResult = curve.Project(curPoint); _param0 = curve.ComputeNormalizedParameter(thisResult.Parameter); _init = true; } thisXYZ = curve.Evaluate(_param0, true); _param1 = -1.0; } else throw new Exception("could not evaluate point on face or edge of the element"); if (thisTrf != null) thisXYZ = thisTrf.OfPoint(thisXYZ); } else throw new Exception("could not evaluate point on face or edge of the element"); old_refXyz = _reference; return Value.NewContainer(thisXYZ); }
/// <summary> /// This function gets the nodes which have created the elements with the /// given element IDs /// </summary> /// <param name="ids">The given element IDs</param> /// <returns>the related nodes</returns> public static IEnumerable<NodeModel> GetNodesFromElementIds(IEnumerable<ElementId> ids) { List<NodeModel> nodes = new List<NodeModel>(); if (!ids.Any()) return nodes.AsEnumerable(); var workspace = dynSettings.Controller.DynamoModel.CurrentWorkspace; ProtoCore.Core core = null; if (dynSettings.Controller != null) { var engine = dynSettings.Controller.EngineController; if ((engine != null) && (engine.LiveRunnerCore != null)) core = engine.LiveRunnerCore; } if (core == null) return null; // Selecting all nodes that are either a DSFunction, // a DSVarArgFunction or a CodeBlockNodeModel into a list. var nodeGuids = workspace.Nodes.Where((n) => { return (n is DSFunction || (n is DSVarArgFunction) || (n is CodeBlockNodeModel)); }).Select((n) => n.GUID); var nodeTraceDataList = core.GetCallsitesForNodes(nodeGuids); List<ElementId> copiedIds = new List<ElementId>(ids); bool areElementsFoundForThisNode; foreach (Guid guid in nodeTraceDataList.Keys) { areElementsFoundForThisNode = false; List<ElementId> idsToRemove = new List<ElementId>(); foreach (ProtoCore.CallSite cs in nodeTraceDataList[guid]) { foreach (ProtoCore.CallSite.SingleRunTraceData srtd in cs.TraceData) { List<ISerializable> traceData = srtd.RecursiveGetNestedData(); foreach (ISerializable thingy in traceData) { SerializableId sid = thingy as SerializableId; if (sid != null) { ElementId tempId = null; foreach (var id in copiedIds) { if (sid.IntID == id.IntegerValue) { //FOUND ONE tempId = id; areElementsFoundForThisNode = true; } } if (tempId != null) copiedIds.Remove(tempId); if (!copiedIds.Any()) { if (areElementsFoundForThisNode) { NodeModel inm = workspace.Nodes.Where((n) => n.GUID == guid).FirstOrDefault(); nodes.Add(inm); } return nodes.AsEnumerable(); } } } } } if (areElementsFoundForThisNode) { NodeModel inm = workspace.Nodes.Where((n) => n.GUID == guid).FirstOrDefault(); nodes.Add(inm); } } return nodes.AsEnumerable(); }