private void DrawSubstations(RawRectangleF bounds, int zoomLevel, bool showViolation) { foreach (var proxy in _substationProxies.Values) { proxy.Visible = false; if (proxy.BlackStartHidden) { continue; } // check visibility and bounds if (!bounds.Contains(proxy.Coordinates)) { continue; } if (!IsVisible(proxy, zoomLevel)) { continue; } MM_DisplayParameter Disp = proxy.Substation.SubstationDisplay(_violationViewer.ShownViolations, Surface); if (Disp.Blink && !showViolation) { Disp = MM_Repository.SubstationDisplay; } bool showingViolation = Disp != MM_Repository.SubstationDisplay; bool isInternal = proxy.Substation.IsInternal; var DrawColor = Disp.ForeColor; float width = Disp.Width; //If drawing the substation with voltage profile, update the color accordingly if (MM_Repository.SubstationDisplay.ShowSubstationVoltages && (!Disp.Blink || (Disp.Blink && showViolation))) { try { float WorstPu = proxy.Substation.Average_pU; if (float.IsNaN(WorstPu)) { DrawColor = Color.FromArgb(50, 50, 50); } else if ((WorstPu >= 1f + (MM_Repository.OverallDisplay.ContourThreshold / 100f) || WorstPu <= 1f - (MM_Repository.OverallDisplay.ContourThreshold / 100f))) { DrawColor = RelativeColor(WorstPu - 1f); } } catch { /* suppress errors */ } } if (proxy.BlackStartDim) { DrawColor = MM_Repository.OverallDisplay.BlackstartDim(DrawColor); } proxy.Color = DrawColor.ToDxColor4(); var solidColorBrush = Surface.Brushes.GetBrush(proxy.Color); bool drawBubbles = false; proxy.Visible = true; drawBubbles = MM_Repository.SubstationDisplay.GeneratorBubblesMode != MM_Substation_Display.MM_Generator_Bubble_Mode.None; bool fuelBubbleVisible = false; bool loadBubbleVisible = false; // Draw load squares if requested if (proxy.Substation.HasLoads && MM_Repository.SubstationDisplay.ShowLoadBubbles) { DrawLoadBubbles(proxy, zoomLevel); loadBubbleVisible = true; } if (drawBubbles && proxy.Substation.HasUnits) { DrawFuelBubbles(proxy, zoomLevel); fuelBubbleVisible = true; } if (MM_Repository.SubstationDisplay.ShowReserveZones && proxy.Substation.HasUnits) { ShowReserveZonesBubbles(proxy, zoomLevel); } // Draw unit substations if (proxy.Substation.HasUnits && (MM_Repository.SubstationDisplay.ShowSubstations == MM_Substation_Display.SubstationViewEnum.Units || MM_Repository.SubstationDisplay.ShowSubstations == MM_Substation_Display.SubstationViewEnum.All)) { if ((showingViolation || !fuelBubbleVisible)) { // scale down diamonds for substations if we are drawing bubbles float scale = 1.75f; using (var geom = SharpDxExtensions.CreatePathGeometry(Surface.Factory2D, true, true, new Vector2(proxy.Coordinates.X - (width * scale), proxy.Coordinates.Y), new Vector2(proxy.Coordinates.X, proxy.Coordinates.Y - (width * scale)), new Vector2(proxy.Coordinates.X + (width * scale), proxy.Coordinates.Y), new Vector2(proxy.Coordinates.X, proxy.Coordinates.Y + (width * scale)))) { Surface.RenderTarget2D.FillGeometry(geom, solidColorBrush); } } } else if ((showingViolation || !loadBubbleVisible)) { // we don't need to AA squares. this saves performance var aa = Surface.RenderTarget2D.AntialiasMode; Surface.RenderTarget2D.AntialiasMode = AntialiasMode.Aliased; Surface.RenderTarget2D.FillRectangle(new RectangleF(proxy.Coordinates.X - width, proxy.Coordinates.Y - width, width * 2f, width * 2f), solidColorBrush); Surface.RenderTarget2D.AntialiasMode = aa; } bool hasIcon = DrawIcons(proxy, showViolation); if (proxy.Substation.KVLevels != null) { foreach (MM_KVLevel Voltage in proxy.Substation.KVLevels) { if (zoomLevel >= Voltage.StationMW || zoomLevel >= Voltage.StationNames) { DrawText(proxy, zoomLevel, solidColorBrush, hasIcon); } } } } }