internal NNTPCommands FindWork(VirtualConnection vConnection) { //List<int> vCons; if (vConnection == null) { return(null); } if (vConnection.Server == null) { return(null); } NNTPCommands vCom = SearchRandomStack(vConnection); if (vCom != null) { return(vCom); } if (vConnection.Server.Priority == ServerPriority.Low) { return(null); } return(SearchRandomSlot(vConnection)); }
internal IndexedCollection SwitchStack(int SlotID, VirtualConnection vConnection) { IndexedCollection iStack = null; List <int> AvailableStacks = null; while (true) { if (!SlotExist(SlotID)) { return(null); } if (vConnection.Cancelled) { return(null); } AvailableStacks = SmartStack(vConnection); if (AvailableStacks.Count == 0) { return(null); } foreach (int ServerID in AvailableStacks) { iStack = Stack(ServerID, SlotID); if (iStack != null) { return(iStack); } } } }
private List <int> SmartStack(VirtualConnection vConnection) { int SmallestStack = 0; List <int> ActiveSlots = WaitingSlots; List <int> AvailableStacks = new List <int>(); foreach (VirtualServer vServer in List()) { if (!ServerActive(vServer.ID)) { continue; } int iLoad = WorkLoad(vServer.ID, ActiveSlots); if (AvailableStacks.Count == 0 || iLoad <= SmallestStack) { if (SmallestStack > 0) { AvailableStacks.Clear(); } AvailableStacks.Add(vServer.ID); SmallestStack = iLoad; } } if ((AvailableStacks.Count == 0) && (ServerActive(vConnection.Server.ID))) { AvailableStacks.Add(vConnection.Server.ID); } return(AvailableStacks); }
public static (List <List <IShape> >, List <(IShape, List <IShape>)>) Run(int min, int max, uint times) { Rules rules = new Rules(); rules.AddRule( new Attributes( ), (Quad quad) => { Vertex b1 = quad.l1.Bisect(); Vertex b2 = quad.l2.Bisect(); Vertex b3 = quad.l3.Bisect(); Vertex b4 = quad.l4.Bisect(); Vertex c = (b1 + b2 + b3 + b4) / 4f; Quad q4 = new Quad(rules, quad.Attributes.Copy(), (0, 0), (b4, c, b3, quad.v4)); Quad q1 = new Quad(rules, quad.Attributes.Copy(), (1, 0), (quad.v1, b1, c, b4)); Quad q3 = new Quad(rules, quad.Attributes.Copy(), (0, 1), (c, b2, quad.v3, b3)); Quad q2 = new Quad(rules, quad.Attributes.Copy(), (1, 1), (b1, quad.v2, b2, c)); if (quad.VC == null || !quad.VC.Persistant) { VirtualConnection.Connect(q4, q1, false, false, true); VirtualConnection.Connect(q3, q2, true, false, true); } return(new List <IShape> { q1, q2, q3, q4 }); }
public void DisconnectSocket(Socket socket, bool recordUndo, bool saveAssets = false) { if (!socket.IsConnected) { return; } if (recordUndo) { RecordUndo(GraphAction.Disconnect.ToString()); } List <string> socketConnectionIds = socket.GetConnectionIds(); foreach (string connectionId in socketConnectionIds) { if (!ConnectionsDatabase.ContainsKey(connectionId)) { continue; } VirtualConnection vc = ConnectionsDatabase[connectionId]; vc.OutputSocket.RemoveConnection(connectionId); vc.InputSocket.RemoveConnection(connectionId); EditorUtility.SetDirty(vc.OutputNode); EditorUtility.SetDirty(vc.InputNode); ConnectionsDatabase.Remove(connectionId); } CurrentGraph.SetDirty(saveAssets); GraphEvent.Send(GraphEvent.EventType.EVENT_NODE_DISCONNECTED, socket.NodeId); }
protected override void OnPreviewMouseDown(MouseButtonEventArgs e) { base.OnPreviewMouseDown(e); m_currentPosition = e.GetPosition(this); m_originPoint = m_currentPosition; m_hittestElement = this.HitTest <BaseNodeControl>(m_currentPosition); if (m_hittestElement != null) // if node based element is clicked { var connector = m_hittestElement as ConnectorControl; if (connector != null) { var sourceConnector = connector; // if connector is already connected and Ctrl key pressed - start nodes reconnection if (connector.ConnectionPoint.IsConnected && (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))) { var connections = m_connections.Where(c => c.Value.Source.Equals(connector) || c.Value.Destination.Equals(connector)).ToList(); if (connections.Any()) { var record = connections.First(); // this is not a misstake. // If this is Source connector for connection then virtual connection should start from // oposit connector which is Destination and vice versa. if (record.Value.Source.Equals(connector)) { sourceConnector = (ConnectorControl)record.Value.Destination; } else { sourceConnector = (ConnectorControl)record.Value.Source; } Diagram.Connections.Remove(record.Key); } } // if it is connector - create virtual connection // virtual elements excluded from hit test var virtualConnector = new VirtualConnectionPoint(sourceConnector) { X = m_currentPosition.X, Y = m_currentPosition.Y }; Children.Add(virtualConnector); var virtualConnection = new VirtualConnection(sourceConnector.ConnectionPoint); var virtualConnectionContainer = new ConnectionContainerControl(sourceConnector, virtualConnector, virtualConnection, false); m_connections.Add(virtualConnection, virtualConnectionContainer); Children.Add(virtualConnectionContainer); m_hittestElement = virtualConnector; } m_hittestElement.CaptureMouse(); } }
internal void LogError(NNTPError zErr, VirtualConnection vConnection) { if (zSeg != null) { zSeg.LogError(ID, zErr); } if (vConnection != null) { vConnection.LogError(ID, zErr); } }
private NNTPCommands SearchRandomStack(VirtualConnection vConnection) { foreach (IndexedCollection vStack in WaitingStacks(vConnection.Server.ID)) { NNTPCommands zCommand = (NNTPCommands)vStack.Take(); if (zCommand != null) { return(zCommand); } } return(null); }
private NNTPCommands SearchRandomSlot(VirtualConnection vConnection) { foreach (VirtualSlot vSlot in RandomSlots()) // Global queue { NNTPCommands zCommand = (NNTPCommands)vSlot.Take(vConnection); if (zCommand != null) { return(zCommand); } } return(null); }
public Stream OpenVirtualConnection() { // Improve discoverability of read-loop errors (in case the developer doesn't add an OnError listener) ThrowIfReadLoopFailed(); var id = Interlocked.Increment(ref _nextInnerStreamId); var newInnerStream = new VirtualConnection(id, this); lock (_activeInnerStreams) { _activeInnerStreams.Add(id, newInnerStream); } return newInnerStream; }
internal void Progress(long AddedBytes, VirtualConnection vConnection) { if (zSeg != null) { long rBytes = Interlocked.Read(ref AddedBytes); zSeg.Progress(rBytes); VirtualSlot vSlot = vConnection.Scheduler.Slots.Item(zSeg.SlotID); if (vSlot != null) { vSlot.Progress(rBytes); } } }
internal void Statistics(long AddedBytes, long RealTime, VirtualConnection vConnection) { if (zSeg != null) { long lTime = Interlocked.Read(ref RealTime); long rBytes = Interlocked.Read(ref AddedBytes); zSeg.Statistics(rBytes, lTime); VirtualSlot vSlot = vConnection.Scheduler.Slots.Item(zSeg.SlotID); if (vSlot != null) { vSlot.Statistics(rBytes, lTime); } } }
private void ValidateConnectionsDatabase() { if (m_connectionsDatabase == null) { return; } var invalidKeys = new List <string>(); //temp keys list foreach (string key in ConnectionsDatabase.Keys) { if (ConnectionsDatabase[key] == null) { invalidKeys.Add(key); //null virtual connection -> remove key continue; } VirtualConnection v = ConnectionsDatabase[key]; if (v.OutputNode == null) { invalidKeys.Add(key); //null output node -> remove key continue; } if (v.InputNode == null) { invalidKeys.Add(key); //null input node -> remove key continue; } if (v.OutputSocket == null) { invalidKeys.Add(key); //null output socket -> remove key continue; } if (v.InputSocket == null) { invalidKeys.Add(key); //null input socket -> remove key } } foreach (string invalidKey in invalidKeys) { ConnectionsDatabase.Remove(invalidKey); //remove invalid keys } }
public override async ValueTask <Connection> AcceptAsync(IConnectionProperties options = null, CancellationToken cancellationToken = default) { using CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(_cts.Token, cancellationToken); var network = new VirtualNetwork(); var serverConnection = new VirtualConnection(network, isServer: true); var clientConnection = new VirtualConnection(network, isServer: false); while (true) { TaskCompletionSource <Connection> tcs = await _pendingConnects.Reader.ReadAsync(cancellationToken); if (tcs.TrySetResult(clientConnection)) { return(serverConnection); } } }
/// <summary> Draws the connection curves of a virtual connection </summary> /// <param name="vc">Target virtual connection being drawn</param> private void DrawConnectionCurve(VirtualConnection vc) { //connect m_connectionAlpha = 1f; if (m_mode == GraphMode.Connect) { m_connectionAlpha = 0.5f; } m_normalColor = DGUI.Utility.IsProSkin ? DGUI.Colors.GetDColor(ColorName.UnityDark).Light : DGUI.Colors.GetDColor(ColorName.UnityLight).Dark; m_outputColor = DGUI.Colors.GetDColor(DGUI.Colors.NodyOutputColorName).Normal; m_inputColor = DGUI.Colors.GetDColor(DGUI.Colors.NodyInputColorName).Normal; m_normalColor.a = m_connectionAlpha; m_outputColor.a = m_connectionAlpha; m_inputColor.a = m_connectionAlpha; m_connectionColor = m_normalColor; m_animateInput = false; m_animateOutput = false; //A node is selected and the Alt Key is not pressed -> show the connection color depending on socket type of this node (if it is an output or an input one) if (WindowSettings.SelectedNodes.Count == 1 && !m_altKeyPressed) { // Node selectedNode = NodesDatabase[m_selectedNodes.Ids[0]]; Node selectedNode = WindowSettings.SelectedNodes[0]; if (selectedNode == null) { return; } if (selectedNode.ContainsConnection(vc.ConnectionId)) { if (selectedNode == vc.OutputNode) { //color for output connection m_connectionColor = m_outputColor; m_animateOutput = true; } if (selectedNode == vc.InputNode) { //color for input connection m_connectionColor = m_inputColor; m_animateInput = true; } } } float currentCurveWidth = NodySettings.Instance.CurveWidth; if (EditorApplication.isPlaying) { if (vc.InputNode.GetConnection(vc.ConnectionId).Ping) { vc.Ping.value = true; vc.Ping.target = false; vc.InputNode.GetConnection(vc.ConnectionId).Ping = false; } else if (vc.OutputNode.GetConnection(vc.ConnectionId).Ping) { vc.Ping.value = true; vc.Ping.target = false; vc.OutputNode.GetConnection(vc.ConnectionId).Ping = false; } if (vc.Ping.faded > 0) { m_connectionColor = Color.LerpUnclamped(m_connectionColor, DGUI.Colors.GetDColor(DGUI.Colors.ActionColorName).Normal, vc.Ping.faded); currentCurveWidth = NodySettings.Instance.CurveWidth * (1 + 2 * vc.Ping.faded); } } else if (vc.Ping.faded > 0) { vc.Ping.value = false; vc.Ping.target = false; } m_dotColor = m_connectionColor; if (m_altKeyPressed) //delete mode is enabled -> check if we should color the connection to RED { //check this connection's points by testing if the mouse if hovering over one of this connection's virtual points bool colorTheConnectionRed = vc.InputVirtualPoint == m_currentHoveredVirtualPoint || vc.OutputVirtualPoint == m_currentHoveredVirtualPoint; if (colorTheConnectionRed) { m_connectionColor = Color.red; //set the connection color to RED -> as the developer might want to remove this connection currentCurveWidth += 1; //make the red curve just a tiny bit more thick to make it stand out even better } } m_connectionBackgroundColor = new Color(m_connectionColor.r * 0.2f, m_connectionColor.g * 0.2f, m_connectionColor.b * 0.2f, m_connectionAlpha - 0.2f); HandleMaterial.SetPass(0); HandleUtility.handleMaterial.SetPass(0); Handles.DrawBezier(vc.OutputVirtualPoint.Rect.position, vc.InputVirtualPoint.Rect.position, vc.OutputTangent, vc.InputTangent, m_connectionBackgroundColor, null, currentCurveWidth + 2); Handles.DrawBezier(vc.OutputVirtualPoint.Rect.position, vc.InputVirtualPoint.Rect.position, vc.OutputTangent, vc.InputTangent, m_connectionColor, null, currentCurveWidth); if (!HasFocus) { return; //if the window does not have focus -> return (DO NOT PLAY ANIMATION) } if (!MouseInsideWindow) { return; //if the mouse is not inside the window -> return (DO NOT PLAY ANIMATION) } if (!m_animateInput && !m_animateOutput) { return; //if the animation is not enabled for both points -> return (DO NOT PLAY ANIMATION) } m_numberOfPoints = (int)(Vector2.Distance(vc.OutputVirtualPoint.Rect.position, vc.InputVirtualPoint.Rect.position) * NodySettings.Instance.CurvePointsMultiplier); //points multiplier - useful for a smooth dot travel - smaller means fewer travel point (makes the point 'jumpy') and higher means more travel points (make the point move smoothly) if (m_numberOfPoints <= 0) { return; } m_bezierPoints = Handles.MakeBezierPoints(vc.OutputVirtualPoint.Rect.position, vc.InputVirtualPoint.Rect.position, vc.OutputTangent, vc.InputTangent, m_numberOfPoints); m_dotPointIndex = 0; m_numberOfPoints--; //we set the number of points as the bezierPoints length - 1 if (m_animateInput) { m_dotPointIndex = (int)(AnimationTime * m_numberOfPoints); } else if (m_animateOutput) { m_dotPointIndex = m_numberOfPoints - (int)((1 - AnimationTime) * m_numberOfPoints); } m_dotPointIndex = Mathf.Clamp(m_dotPointIndex, 0, m_numberOfPoints); m_dotPoint = m_bezierPoints[m_dotPointIndex]; m_dotSize = currentCurveWidth * 2; //make the dot a bit brighter m_dotColor = new Color(m_dotColor.r * 1.2f, m_dotColor.g * 1.2f, m_dotColor.b * 1.2f, m_dotColor.a); GUI.color = m_dotColor; GUI.Box(new Rect(m_dotPoint.x - m_dotSize / 2, m_dotPoint.y - m_dotSize / 2, m_dotSize, m_dotSize), "", DotStyle); GUI.color = Color.white; }
private void CalculateConnectionCurve(VirtualConnection vc) { //get the lists of all the calculated virtual points for both sockets List <VirtualPoint> outputVirtualPoints = PointsDatabase[vc.OutputSocket.Id]; List <VirtualPoint> inputVirtualPoints = PointsDatabase[vc.InputSocket.Id]; //get both OutputSocket and InputSocket rects converted to WorldSpace Rect outputSocketWorldRect = GetSocketWorldRect(vc.OutputSocket); Rect inputSocketWorldRect = GetSocketWorldRect(vc.InputSocket); //get position values needed to determine the connection points and curve settings // float outputSocketCenter = (outputSocketWorldRect.center.x + PanOffset.x) / Zoom; float outputSocketCenter = outputSocketWorldRect.center.x; // float inputSocketCenter = (inputSocketWorldRect.center.x + PanOffset.x) / Zoom; float inputSocketCenter = inputSocketWorldRect.center.x; //get the closest virtual points for both sockets float minDistance = 100000; foreach (VirtualPoint outputVirtualPoint in outputVirtualPoints) { foreach (VirtualPoint inputVirtualPoint in inputVirtualPoints) { float currentDistance = Vector2.Distance(outputVirtualPoint.Rect.position, inputVirtualPoint.Rect.position); if (currentDistance > minDistance) { continue; } vc.OutputVirtualPoint = outputVirtualPoint; vc.InputVirtualPoint = inputVirtualPoint; minDistance = currentDistance; } } //set both the output and the input points as their respective tangents Vector2 zoomedPanOffset = CurrentPanOffset / CurrentZoom; Vector2 outputPoint = vc.OutputVirtualPoint.Rect.position - zoomedPanOffset; Vector2 inputPoint = vc.InputVirtualPoint.Rect.position - zoomedPanOffset; float outputNodeWidth = vc.OutputNode.GetWidth(); float inputNodeWidth = vc.InputNode.GetWidth(); float widthDifference = outputNodeWidth > inputNodeWidth ? outputNodeWidth - inputNodeWidth : inputNodeWidth - outputNodeWidth; vc.OutputTangent = outputPoint + zoomedPanOffset; vc.InputTangent = inputPoint + zoomedPanOffset; //UP TO THIS POINT WE HAVE A STRAIGHT LINE //from here we start calculating the custom tangent values -> thus turning our connection line into a dynamic curve Vector2 outputTangentArcDirection; //output point tangent Vector2 inputTangentArcDirection; //input point tangent //OUTPUT RIGHT CONNECTION if (outputSocketCenter < inputSocketCenter && outputSocketCenter <= inputPoint.x || outputSocketCenter >= inputSocketCenter && outputPoint.x >= inputSocketCenter && outputSocketCenter <= inputPoint.x) { // DDebug.Log("OUTPUT RIGHT"); if (outputPoint.x <= inputSocketCenter + widthDifference / 2 && inputSocketCenter > outputPoint.x) { outputTangentArcDirection = Vector2.right; inputTangentArcDirection = Vector2.left; } else { outputTangentArcDirection = Vector2.right; inputTangentArcDirection = Vector2.right; } } //OUTPUT LEFT CONNECTION else { // DDebug.Log("OUTPUT LEFT"); if (outputPoint.x >= inputSocketCenter) { outputTangentArcDirection = Vector2.left; inputTangentArcDirection = Vector2.right; } else { outputTangentArcDirection = Vector2.left; inputTangentArcDirection = Vector2.left; } } //set the curve strength (curvature) to be dynamic, by taking into account the distance between the connection points float outputCurveStrength = minDistance * (NodySettings.Instance.CurveStrengthModifier + vc.OutputSocket.CurveModifier); float inputCurveStrength = minDistance * (NodySettings.Instance.CurveStrengthModifier + vc.InputSocket.CurveModifier); //update the tangents with the dynamic values vc.OutputTangent += outputTangentArcDirection * outputCurveStrength; vc.InputTangent += inputTangentArcDirection * inputCurveStrength; }
public static (List <List <IShape> >, List <(IShape, List <IShape>)>) Run(int min, int max, uint times) { Rules rules = new Rules(); rules.AddRule( new Attributes( ("Floors", new ScalarAttribute(3f)) ), (Start start) => { Vertex[] v1 = start.l2.Sections(0.3f, 0.65f); Vertex[] v2 = start.l4.Sections(0.35f, 0.7f); Floor f1 = new Floor(rules, start.Attributes.Copy(), (0, 2), (start.v1, start.v2, v1[1], v2[0])); Floor f2 = new Floor(rules, start.Attributes.Copy(), (0, 1), (v2[0], v1[1], v1[0], v2[1])); Floor f3 = new Floor(rules, start.Attributes.Copy(), (0, 0), (v2[1], v1[0], start.v3, start.v4)); return(new List <IShape> { f1, f2, f3 }); } ); rules.AddRule( new Attributes( ("Floors", new ScalarAttribute(2f)), ("Wide", new ScalarAttribute(0f)) ), (Start start) => { Vertex[] v1 = start.l1.Sections(4); Vertex[] v2 = start.l3.Sections(4); Attributes a = start.Attributes.Copy(); a.Set("RoofSlanted", new ScalarAttribute(1f)); Vertical s1 = new Vertical(rules, a.Copy(), (0, 0), (start.v1, v1[3], v2[0], start.v4)); Vertical s2 = new Vertical(rules, start.Attributes.Copy(), (1, 0), (v1[3], v1[2], v2[1], v2[0])); Vertical s3 = new Vertical(rules, start.Attributes.Copy(), (2, 0), (v1[2], v1[1], v2[2], v2[1])); Vertical s4 = new Vertical(rules, start.Attributes.Copy(), (3, 0), (v1[1], v1[0], v2[3], v2[2])); Vertical s5 = new Vertical(rules, a.Copy(), (4, 0), (v1[0], start.v2, start.v3, v2[3])); VirtualConnection.Connect(s1, s5, true, false, true); return(new List <IShape> { s1, s2, s3, s4, s5 }); } ); rules.AddRule( new Attributes( ("Floors", new ScalarAttribute(2f)), ("Wide", new ScalarAttribute(1f)) ), (Start start) => { Vertex[] v1 = start.l1.Sections(10); Vertex[] v2 = start.l3.Sections(10); Vertical s1 = new Vertical(rules, start.Attributes.Copy(), (0, 0), (start.v1, v1[9], v2[0], start.v4)); Vertical s2 = new Vertical(rules, start.Attributes.Copy(), (1, 0), (v1[9], v1[8], v2[1], v2[0])); Vertical s3 = new Vertical(rules, start.Attributes.Copy(), (2, 0), (v1[8], v1[7], v2[2], v2[1])); Vertical s4 = new Vertical(rules, start.Attributes.Copy(), (3, 0), (v1[7], v1[6], v2[3], v2[2])); Vertical s5 = new Vertical(rules, start.Attributes.Copy(), (4, 0), (v1[6], v1[5], v2[4], v2[3])); Vertical s6 = new Vertical(rules, start.Attributes.Copy(), (5, 0), (v1[5], v1[4], v2[5], v2[4])); Vertical s7 = new Vertical(rules, start.Attributes.Copy(), (6, 0), (v1[4], v1[3], v2[6], v2[5])); Vertical s8 = new Vertical(rules, start.Attributes.Copy(), (7, 0), (v1[3], v1[2], v2[7], v2[6])); Vertical s9 = new Vertical(rules, start.Attributes.Copy(), (8, 0), (v1[2], v1[1], v2[8], v2[7])); Vertical s10 = new Vertical(rules, start.Attributes.Copy(), (9, 0), (v1[1], v1[0], v2[9], v2[8])); Vertical s11 = new Vertical(rules, start.Attributes.Copy(), (10, 0), (v1[0], start.v2, start.v3, v2[9])); return(new List <IShape> { s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11 }); } ); rules.AddRule( new Attributes( ("RoofSlanted", new ScalarAttribute(0f)) ), (Vertical vertical) => { Vertex[] v1 = vertical.l2.Sections(0.3f, 0.65f); Vertex[] v2 = vertical.l4.Sections(0.35f, 0.7f); Section s1 = new Section(rules, vertical.Attributes.Copy(), (0, 2), (vertical.v1, vertical.v2, v1[1], v2[0])); Section s2 = new Section(rules, vertical.Attributes.Copy(), (0, 1), (v2[0], v1[1], v1[0], v2[1])); Roof r = new Roof(rules, vertical.Attributes.Copy(), (0, 0), (v2[1], v1[0], vertical.v3, vertical.v4)); return(new List <IShape> { s1, s2, r }); } ); rules.AddRule( new Attributes( ("RoofSlanted", new ScalarAttribute(1f)) ), (Vertical vertical) => { Vertex[] v1 = vertical.l2.Sections(0.3f, 0.65f); Vertex[] v2 = vertical.l4.Sections(0.35f, 0.7f); Section s = new Section(rules, vertical.Attributes.Copy(), (0, 2), (vertical.v1, vertical.v2, v1[1], v2[0])); Roof r = new Roof(rules, vertical.Attributes.Copy(), (0, 1), (v2[0], v1[1], v1[0], v2[1])); return(new List <IShape> { s, r }); } ); rules.AddRule( new Attributes( ("RoofSlanted", new ScalarAttribute(1f)) ), (Roof roof) => { Vertex v = roof.l2.Bisect(); Triad t = new Triad(rules, roof.Attributes.Copy(), (0, 0), (v, roof.v1, roof.v2)); return(new List <IShape> { t }); } ); rules.AddRule( new Attributes( ("RoofSize", new ScalarAttribute(1f)), ("RoofSlanted", new ScalarAttribute(0f)) ), (Roof roof) => { Vertex v1 = roof.l2.Bisect(0.6f); Vertex v2 = roof.l4.Bisect(0.4f); Quad q = new Quad(rules, roof.Attributes.Copy(), (0, 0), (roof.v2, v1, v2, roof.v1)); return(new List <IShape> { q }); } ); rules.AddRule( new Attributes( ("RoofSize", new ScalarAttribute(2f)), ("RoofSlanted", new ScalarAttribute(0f)) ), (Roof roof) => { Vertex v1 = roof.l2.Bisect(0.7f); Vertex v2 = roof.l4.Bisect(0.3f); Quad q = new Quad(rules, roof.Attributes.Copy(), (0, 0), (roof.v2, v1, v2, roof.v1)); return(new List <IShape> { q }); } ); rules.AddRule( new Attributes( ("RoofSize", new ScalarAttribute(3f)), ("RoofSlanted", new ScalarAttribute(0f)) ), (Roof roof) => { Vertex v1 = roof.l2.Bisect(0.8f); Vertex v2 = roof.l4.Bisect(0.2f); Quad q = new Quad(rules, roof.Attributes.Copy(), (0, 0), (roof.v2, v1, v2, roof.v1)); return(new List <IShape> { q }); } ); rules.AddRule( new Attributes( ("Sections", new ScalarAttribute(5f)) ), (Floor floor) => { Vertex[] v1 = floor.l1.Sections(4); Vertex[] v2 = floor.l3.Sections(4); Section s1 = new Section(rules, floor.Attributes.Copy(), (0, 0), (floor.v1, v1[3], v2[0], floor.v4)); Section s2 = new Section(rules, floor.Attributes.Copy(), (1, 0), (v1[3], v1[2], v2[1], v2[0])); Section s3 = new Section(rules, floor.Attributes.Copy(), (2, 0), (v1[2], v1[1], v2[2], v2[1])); Section s4 = new Section(rules, floor.Attributes.Copy(), (3, 0), (v1[1], v1[0], v2[3], v2[2])); Section s5 = new Section(rules, floor.Attributes.Copy(), (4, 0), (v1[0], floor.v2, floor.v3, v2[3])); return(new List <IShape> { s1, s2, s3, s4, s5 }); } ); rules.AddRule( new Attributes( ("Sections", new ScalarAttribute(4f)) ), (Floor floor) => { Vertex[] v1 = floor.l1.Sections(3); Vertex[] v2 = floor.l3.Sections(3); Section s1 = new Section(rules, floor.Attributes.Copy(), (0, 0), (floor.v1, v1[2], v2[0], floor.v4)); Section s2 = new Section(rules, floor.Attributes.Copy(), (1, 0), (v1[2], v1[1], v2[1], v2[0])); Section s3 = new Section(rules, floor.Attributes.Copy(), (2, 0), (v1[1], v1[0], v2[2], v2[1])); Section s4 = new Section(rules, floor.Attributes.Copy(), (4, 0), (v1[0], floor.v2, floor.v3, v2[2])); return(new List <IShape> { s1, s2, s3, s4 }); } ); rules.AddRule( new Attributes( ("Door", new ScalarAttribute(0f)), ("Corn", new ScalarAttribute(1f)), ("Bar", new ScalarAttribute(1f)), ("Stairs", new ScalarAttribute(0f)) ), (Section section) => { Vertex[] v1 = section.l2.Sections(0.1f, 0.85f); Vertex[] v2 = section.l4.Sections(0.15f, 0.9f); Attributes a = section.Attributes.Copy(); a.Set("Corn", new ScalarAttribute(0f)); a.Set("Bar", new ScalarAttribute(0f)); Attributes b = a.Copy(); b.Set("R", new ScalarAttribute(255f)); b.Set("G", new ScalarAttribute(255f)); b.Set("B", new ScalarAttribute(255f)); Cornice c = new Cornice(rules, b.Copy(), (0, 0), (section.v1, section.v2, v1[1], v2[0])); Section s = new Section(rules, a, (0, 1), (v2[0], v1[1], v1[0], v2[1])); Bar bar = new Bar(rules, b.Copy(), (0, 2), (v2[1], v1[0], section.v3, section.v4)); return(new List <IShape> { c, s, bar }); } ); rules.AddRule( new Attributes( ("Door", new ScalarAttribute(0f)), ("Corn", new ScalarAttribute(1f)), ("Bar", new ScalarAttribute(0f)), ("Stairs", new ScalarAttribute(0f)) ), (Section section) => { Vertex[] v1 = section.l2.Sections(0.1f); Vertex[] v2 = section.l4.Sections(0.9f); Attributes a = section.Attributes.Copy(); a.Set("Corn", new ScalarAttribute(0f)); a.Set("Bar", new ScalarAttribute(0f)); Attributes b = a.Copy(); b.Set("R", new ScalarAttribute(255f)); b.Set("G", new ScalarAttribute(255f)); b.Set("B", new ScalarAttribute(255f)); Section s = new Section(rules, a, (0, 0), (section.v1, section.v2, v1[0], v2[0])); Cornice c = new Cornice(rules, b, (0, 1), (v2[0], v1[0], section.v3, section.v4)); return(new List <IShape> { s, c }); } ); rules.AddRule( new Attributes( ("Corn", new ScalarAttribute(0f)), ("Bar", new ScalarAttribute(0f)), ("Door", new ScalarAttribute(0f)), ("Sections", new ScalarAttribute(4f)), ("Stairs", new ScalarAttribute(0f)) ), (Section section) => { Vertex[] v1 = section.l1.Sections(0.25f, 0.75f); Vertex[] v2 = section.l3.Sections(0.25f, 0.75f); Line l1 = new Line(v1[0], v2[1]); Line l2 = new Line(v1[1], v2[0]); Vertex[] v3 = l1.Sections(0.1f, 0.82f); Vertex[] v4 = l2.Sections(0.1f, 0.82f); Quad q1 = new Quad(rules, section.Attributes.Copy(), (0, 0), (section.v1, section.v4, v2[0], v1[1])); Quad q2 = new Quad(rules, section.Attributes.Copy(), (0, 2), (v1[0], v2[1], section.v3, section.v2)); Quad q3 = new Quad(rules, section.Attributes.Copy(), (0, 3), (v2[0], v4[0], v3[0], v2[1])); Quad q4 = new Quad(rules, section.Attributes.Copy(), (0, 4), (v1[1], v4[1], v3[1], v1[0])); Attributes a = section.Attributes.Copy(); a.Set("R", new ScalarAttribute(255f)); a.Set("G", new ScalarAttribute(255f)); a.Set("B", new ScalarAttribute(255f)); Window w = new Window(rules, a, (1, 0), (v4[0], v4[1], v3[1], v3[0])); return(new List <IShape> { q1, q2, q3, q4, w }); } ); rules.AddRule( new Attributes( ("Corn", new ScalarAttribute(0f)), ("Bar", new ScalarAttribute(0f)), ("Door", new ScalarAttribute(0f)), ("Sections", new ScalarAttribute(5f)), ("Stairs", new ScalarAttribute(0f)) ), (Section section) => { Vertex[] v1 = section.l1.Sections(0.2f, 0.8f); Vertex[] v2 = section.l3.Sections(0.2f, 0.8f); Line l1 = new Line(v1[0], v2[1]); Line l2 = new Line(v1[1], v2[0]); Vertex[] v3 = l1.Sections(0.1f, 0.82f); Vertex[] v4 = l2.Sections(0.1f, 0.82f); Quad q1 = new Quad(rules, section.Attributes.Copy(), (0, 0), (section.v1, section.v4, v2[0], v1[1])); Quad q2 = new Quad(rules, section.Attributes.Copy(), (0, 2), (v1[0], v2[1], section.v3, section.v2)); Quad q3 = new Quad(rules, section.Attributes.Copy(), (0, 3), (v2[0], v4[0], v3[0], v2[1])); Quad q4 = new Quad(rules, section.Attributes.Copy(), (0, 4), (v1[1], v4[1], v3[1], v1[0])); Window w = new Window(rules, section.Attributes.Copy(), (1, 0), (v4[0], v4[1], v3[1], v3[0])); return(new List <IShape> { q1, q2, q3, q4, w }); } ); rules.AddRule( new Attributes( ("Stairs", new ScalarAttribute(1f)) ), (Section section) => { Vertex[] v1 = section.l1.Sections(0.15f, 0.85f); Vertex[] v2 = section.l3.Sections(0.15f, 0.85f); Quad q1 = new Quad(rules, section.Attributes.Copy(), (0, 0), (section.v1, section.v4, v2[0], v1[1])); Quad q2 = new Quad(rules, section.Attributes.Copy(), (0, 2), (v1[0], v2[1], section.v3, section.v2)); Window w = new Window(rules, section.Attributes.Copy(), (1, 0), (v2[0], v1[1], v1[0], v2[1])); return(new List <IShape> { q1, q2, w }); } ); rules.AddRule( new Attributes( ("Door", new RangeAttribute(1f, 2f)) ), (Section section) => { Vertex[] v1 = section.l2.Sections(0.20f, 0.25f); Vertex[] v2 = section.l4.Sections(0.75f, 0.8f); Line l = new Line(v1[1], v2[0]); Vertex[] v3 = l.Sections(0.07f, 0.93f); Vertex[] v4 = section.l1.Sections(0.07f, 0.93f); // Upper area Door door = new Door(rules, section.Attributes.Copy(), (1, 0), (v4[1], v4[0], v3[1], v3[0])); Quad mid = new Quad(rules, section.Attributes.Copy(), (2, 0), (v2[0], v1[1], v1[0], v2[1])); Quad upper = new Quad(rules, section.Attributes.Copy(), (3, 0), (v2[1], v1[0], section.v3, section.v4)); // Sides Quad side1 = new Quad(rules, section.Attributes.Copy(), (0, 1), (section.v1, v2[0], v3[0], v4[1])); Quad side2 = new Quad(rules, section.Attributes.Copy(), (1, 1), (section.v2, v4[0], v3[1], v1[1])); return(new List <IShape> { door, mid, upper, side1, side2 }); } ); rules.AddRule( new Attributes( ), (Window window) => { Vertex[] v1 = window.l1.Sections(0.05f, 0.95f); Vertex[] v2 = window.l3.Sections(0.05f, 0.95f); Line l1 = new Line(v1[0], v2[1]); Line l2 = new Line(v1[1], v2[0]); Vertex[] v3 = l1.Sections(0.1f, 0.9f); Vertex[] v4 = l2.Sections(0.1f, 0.9f); Quad q1 = new Quad(rules, window.Attributes.Copy(), (0, 0), (window.v1, window.v4, v2[0], v1[1])); Quad q2 = new Quad(rules, window.Attributes.Copy(), (0, 2), (v1[0], v2[1], window.v3, window.v2)); Quad q3 = new Quad(rules, window.Attributes.Copy(), (0, 3), (v2[0], v4[0], v3[0], v2[1])); Quad q4 = new Quad(rules, window.Attributes.Copy(), (0, 4), (v1[1], v4[1], v3[1], v1[0])); Glass g = new Glass(rules, window.Attributes.Copy(), (1, 0), (v4[0], v4[1], v3[1], v3[0])); return(new List <IShape> { q1, q2, q3, q4, g }); }