summaryrefslogtreecommitdiffstats
path: root/Project/Workspace.cpp
diff options
context:
space:
mode:
authorThales Lima Oliveira <thaleslima.ufu@gmail.com>2020-07-07 23:12:04 -0300
committerThales Lima Oliveira <thaleslima.ufu@gmail.com>2020-07-07 23:12:04 -0300
commitab30228b1a57053323363674fa7f137c0329a180 (patch)
tree50849a3680d61a2428665cc1035f1f4215870acb /Project/Workspace.cpp
parent6c0e98a2727d07e1fbb38b78c27d68e98ad09465 (diff)
downloadPSP.git-ab30228b1a57053323363674fa7f137c0329a180.tar.gz
PSP.git-ab30228b1a57053323363674fa7f137c0329a180.tar.xz
PSP.git-ab30228b1a57053323363674fa7f137c0329a180.zip
Voltage heat map implemented
Voltage heat map implemented using modern OpenGL =) New external library required: -GLEW -GLFW -GLM (incorporeted at the source) Old memory leaks fixed =)
Diffstat (limited to 'Project/Workspace.cpp')
-rw-r--r--Project/Workspace.cpp1453
1 files changed, 840 insertions, 613 deletions
diff --git a/Project/Workspace.cpp b/Project/Workspace.cpp
index bf0eee7..17c8134 100644
--- a/Project/Workspace.cpp
+++ b/Project/Workspace.cpp
@@ -18,7 +18,7 @@
#include "Camera.h"
#include "Element.h"
#include "Workspace.h"
-//#include "Bus.h"
+ //#include "Bus.h"
#include "Capacitor.h"
#include "ElementDataObject.h"
#include "HarmCurrent.h"
@@ -44,6 +44,10 @@
#include "FrequencyResponseForm.h"
+#include "HMPlane.h"
+#include "Shader.h"
+#include "Renderer.h"
+
// Workspace
Workspace::Workspace() : WorkspaceBase(nullptr) {}
Workspace::Workspace(wxWindow* parent, wxString name, wxStatusBar* statusBar, wxGLContext* sharedGLContext)
@@ -56,60 +60,95 @@ Workspace::Workspace(wxWindow* parent, wxString name, wxStatusBar* statusBar, wx
m_camera = new Camera();
m_selectionRect = wxRect2DDouble(0, 0, 0, 0);
- for(int i = 0; i < NUM_ELEMENTS; ++i) { m_elementNumber[i] = 1; }
+ for (int i = 0; i < NUM_ELEMENTS; ++i) { m_elementNumber[i] = 1; }
- const int widths[4] = {-3, -1, 100, 100};
+ const int widths[4] = { -3, -1, 100, 100 };
m_statusBar->SetStatusWidths(4, widths);
m_properties = new PropertiesData();
-
+
m_glCanvas->SetBackgroundStyle(wxBG_STYLE_CUSTOM);
+
+ m_width = static_cast<float>(m_glCanvas->GetSize().x) - 1.0;
+ m_height = static_cast<float>(m_glCanvas->GetSize().y) - 1.0;
+ m_renderer = new Renderer();
}
Workspace::~Workspace()
{
- for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
- if(*it) delete *it;
+ for (auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
+ if (*it) delete* it;
}
- for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) {
- if(*it) delete *it;
+ for (auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) {
+ if (*it) delete* it;
}
- if(m_camera) delete m_camera;
- if(m_glContext) delete m_glContext;
- if(m_tipWindow) delete m_tipWindow;
- if(m_properties) delete m_properties;
+
+ delete m_hmPlane;
+
+ if (m_camera) delete m_camera;
+ //if (m_isThisContextShared) {
+ delete m_glContext;
+ m_glContext = nullptr;
+ //}
+ if (m_tipWindow) delete m_tipWindow;
+ if (m_properties) delete m_properties;
}
void Workspace::OnPaint(wxPaintEvent& event)
{
- if(!m_glCanvas->IsShown()) return;
+ if (!m_glCanvas->IsShown()) return;
+
-
//dc.Clear();
//m_glContext->SetCurrent(*m_glCanvas);
m_glCanvas->SetCurrent(*m_glContext);
wxPaintDC dc(m_glCanvas);
-
+
SetViewport();
- // Set GLCanvas scale and translation.
- glScaled(m_camera->GetScale(), m_camera->GetScale(), 0.0); // Scale
+ // Set GLCanvas scale and translation
+ // Legacy OpenGL
+ glScaled(m_camera->GetScale(), m_camera->GetScale(), 0.0); // Scale
glTranslated(m_camera->GetTranslation().m_x, m_camera->GetTranslation().m_y, 0.0); // Translation
+ // Modern OpenGL
+ m_projMatrix = glm::ortho(0.0f, m_width, m_height, 0.0f, -1.0f, 1.0f);
+ //m_projMatrix = glm::scale(m_projMatrix, glm::vec3(m_camera->GetScale(), m_camera->GetScale(), 1.0));
+ //m_projMatrix = glm::translate(m_projMatrix, glm::vec3(m_camera->GetTranslation().m_x, m_camera->GetTranslation().m_y, 0.0));
+
+
+ m_renderer->Clear();
+
// Draw
+ // HMPlane
+ if (m_hmPlane && m_showHM) {
+ m_hmPlane->Draw(*m_renderer, m_projMatrix);
+ }
+
// Elements
- for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
+ for (auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
Element* element = *it;
element->Draw(m_camera->GetTranslation(), m_camera->GetScale());
}
// Texts
- for(auto it = m_textList.begin(); it != m_textList.end(); ++it) {
+ for (auto it = m_textList.begin(); it != m_textList.end(); ++it) {
Text* text = *it;
text->Draw(m_camera->GetTranslation(), m_camera->GetScale());
}
+
+ if (m_hmPlane && m_showHM) {
+ // Reset legacy OpenGL zoom/translation
+ glPushMatrix();
+ glLoadIdentity();
+ //m_projMatrix = glm::mat4(1.0);
+ //m_projMatrix = glm::ortho(0.0f, m_width, m_height, 0.0f, -1.0f, 1.0f);
+ m_hmPlane->DrawLabel(*m_renderer, m_projMatrix, 20.0f, 20.0f);
+ glPopMatrix();
+ }
+
// Selection rectangle
glLineWidth(1.0);
glColor4d(0.0, 0.5, 1.0, 1.0);
@@ -135,7 +174,7 @@ void Workspace::OnPaint(wxPaintEvent& event)
void Workspace::SetViewport()
{
-
+
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE);
glClearColor(1.0, 1.0, 1.0, 1.0); // White background.
@@ -152,7 +191,7 @@ void Workspace::SetViewport()
// Viewport fit the screen.
glViewport(0, 0, width, height);
-
+ // Set viewport to legacy OpenGL
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, width, height, 0.0);
@@ -169,23 +208,24 @@ void Workspace::OnLeftClickDown(wxMouseEvent& event)
bool showNewElementForm = false;
bool clickOnSwitch = false;
- if(m_mode == WorkspaceMode::MODE_INSERT_TEXT || m_mode == WorkspaceMode::MODE_PASTE || m_mode == WorkspaceMode::MODE_DRAG_PASTE) {
+ if (m_mode == WorkspaceMode::MODE_INSERT_TEXT || m_mode == WorkspaceMode::MODE_PASTE || m_mode == WorkspaceMode::MODE_DRAG_PASTE) {
m_mode = WorkspaceMode::MODE_EDIT;
- } else if(m_mode == WorkspaceMode::MODE_INSERT || m_mode == WorkspaceMode::MODE_DRAG_INSERT || m_mode == WorkspaceMode::MODE_DRAG_INSERT_TEXT) {
+ }
+ else if (m_mode == WorkspaceMode::MODE_INSERT || m_mode == WorkspaceMode::MODE_DRAG_INSERT || m_mode == WorkspaceMode::MODE_DRAG_INSERT_TEXT) {
// Get the last element inserted on the list.
newElement = *(m_elementList.end() - 1);
- for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
+ for (auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
Element* element = *it;
// Clicked in any element.
- if(element->Contains(m_camera->ScreenToWorld(clickPoint))) {
+ if (element->Contains(m_camera->ScreenToWorld(clickPoint))) {
// Click at a bus.
- if(typeid(*element) == typeid(Bus)) {
+ if (typeid(*element) == typeid(Bus)) {
// Select the bus.
element->SetSelected();
foundElement = true; // Element found.
// Add the new element's parent. If the element being inserted returns true, back to
// edit mode.
- if(newElement->AddParent(element, m_camera->ScreenToWorld(clickPoint))) {
+ if (newElement->AddParent(element, m_camera->ScreenToWorld(clickPoint))) {
ValidateElementsVoltages();
m_timer->Stop();
showNewElementForm = true;
@@ -195,13 +235,14 @@ void Workspace::OnLeftClickDown(wxMouseEvent& event)
}
}
// The line element can have an undefined number of points.
- if(!foundElement) {
- if(typeid(*newElement) == typeid(Line)) { newElement->AddPoint(m_camera->ScreenToWorld(clickPoint)); }
+ if (!foundElement) {
+ if (typeid(*newElement) == typeid(Line)) { newElement->AddPoint(m_camera->ScreenToWorld(clickPoint)); }
}
foundElement = true;
- } else {
+ }
+ else {
bool clickPickbox = false;
- for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
+ for (auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
PowerElement* element = *it;
element->ResetPickboxes(); // Reset pickbox state.
@@ -209,44 +250,44 @@ void Workspace::OnLeftClickDown(wxMouseEvent& event)
element->StartMove(m_camera->ScreenToWorld(clickPoint));
// Click in selected element node.
- if(element->NodeContains(m_camera->ScreenToWorld(clickPoint)) != 0 && element->IsSelected()) {
+ if (element->NodeContains(m_camera->ScreenToWorld(clickPoint)) != 0 && element->IsSelected()) {
m_mode = WorkspaceMode::MODE_MOVE_NODE;
m_disconnectedElement = true;
foundElement = true;
}
// Click in an element.
- else if(element->Contains(m_camera->ScreenToWorld(clickPoint))) {
- if(!foundElement) {
+ else if (element->Contains(m_camera->ScreenToWorld(clickPoint))) {
+ if (!foundElement) {
// Select and show pickbox.
element->SetSelected();
element->ShowPickbox();
foundElement = true;
}
// If pickbox contains the click, move the pickbox
- if(element->PickboxContains(m_camera->ScreenToWorld(clickPoint))) {
+ if (element->PickboxContains(m_camera->ScreenToWorld(clickPoint))) {
m_mode = WorkspaceMode::MODE_MOVE_PICKBOX;
clickPickbox = true;
}
// If didn't found a pickbox, move the element
- if(!clickPickbox) { m_mode = WorkspaceMode::MODE_MOVE_ELEMENT; }
+ if (!clickPickbox) { m_mode = WorkspaceMode::MODE_MOVE_ELEMENT; }
}
// Click in a switch.
- else if(element->SwitchesContains(m_camera->ScreenToWorld(clickPoint))) {
+ else if (element->SwitchesContains(m_camera->ScreenToWorld(clickPoint))) {
element->SetOnline(element->IsOnline() ? false : true);
clickOnSwitch = true;
}
}
// Text element
- for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) {
+ for (auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) {
Text* text = *it;
text->StartMove(m_camera->ScreenToWorld(clickPoint));
- if(text->Contains(m_camera->ScreenToWorld(clickPoint))) {
- if(!foundElement) {
+ if (text->Contains(m_camera->ScreenToWorld(clickPoint))) {
+ if (!foundElement) {
text->SetSelected();
m_mode = WorkspaceMode::MODE_MOVE_ELEMENT;
foundElement = true;
@@ -255,7 +296,7 @@ void Workspace::OnLeftClickDown(wxMouseEvent& event)
}
}
- if(!foundElement) {
+ if (!foundElement) {
m_mode = WorkspaceMode::MODE_SELECTION_RECT;
m_startSelRect = m_camera->ScreenToWorld(clickPoint);
}
@@ -263,13 +304,13 @@ void Workspace::OnLeftClickDown(wxMouseEvent& event)
Redraw();
UpdateStatusBar();
- if(showNewElementForm) {
- if(newElement) {
+ if (showNewElementForm) {
+ if (newElement) {
newElement->ShowForm(this, newElement);
- if(m_continuousCalc) RunStaticStudies();
+ if (m_continuousCalc) RunStaticStudies();
}
}
- if(clickOnSwitch && m_continuousCalc) RunStaticStudies();
+ if (clickOnSwitch && m_continuousCalc) RunStaticStudies();
event.Skip();
}
@@ -280,15 +321,15 @@ void Workspace::OnLeftDoubleClick(wxMouseEvent& event)
bool clickOnSwitch = false;
bool redraw = false;
- for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
+ for (auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
PowerElement* element = *it;
// Click in an element.
- if(element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
+ if (element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
bool elementIsBus = false;
Bus oldBus;
Bus* currentBus = nullptr;
- if((currentBus = dynamic_cast<Bus*>(element))) {
+ if ((currentBus = dynamic_cast<Bus*>(element))) {
elementIsBus = true;
oldBus = *currentBus;
}
@@ -299,19 +340,19 @@ void Workspace::OnLeftDoubleClick(wxMouseEvent& event)
// If the edited element is a bus and was changed the rated voltage, this voltage must be
// propagated through the lines
- if(elementIsBus) {
+ if (elementIsBus) {
// The voltage was changed
- if(oldBus.GetElectricalData().nominalVoltage != currentBus->GetElectricalData().nominalVoltage ||
- oldBus.GetElectricalData().nominalVoltageUnit !=
- currentBus->GetElectricalData().nominalVoltageUnit) {
+ if (oldBus.GetElectricalData().nominalVoltage != currentBus->GetElectricalData().nominalVoltage ||
+ oldBus.GetElectricalData().nominalVoltageUnit !=
+ currentBus->GetElectricalData().nominalVoltageUnit) {
// Check if the bus has line as child.
std::vector<Element*> childList = element->GetChildList();
- for(auto itc = childList.begin(), itcEnd = childList.end(); itc != itcEnd; ++itc) {
+ for (auto itc = childList.begin(), itcEnd = childList.end(); itc != itcEnd; ++itc) {
Element* child = *itc;
- if(typeid(*child) == typeid(Line)) {
+ if (typeid(*child) == typeid(Line)) {
wxMessageDialog msgDialog(this, _("Do you want to change the rated voltage of the path?"),
- _("Warning"), wxYES_NO | wxCENTRE | wxICON_WARNING);
- if(msgDialog.ShowModal() == wxID_YES)
+ _("Warning"), wxYES_NO | wxCENTRE | wxICON_WARNING);
+ if (msgDialog.ShowModal() == wxID_YES)
ValidateBusesVoltages(element);
else {
auto data = currentBus->GetElectricalData();
@@ -328,56 +369,56 @@ void Workspace::OnLeftDoubleClick(wxMouseEvent& event)
}
// Click in a switch.
- else if(element->SwitchesContains(m_camera->ScreenToWorld(event.GetPosition()))) {
+ else if (element->SwitchesContains(m_camera->ScreenToWorld(event.GetPosition()))) {
element->SetOnline(element->IsOnline() ? false : true);
clickOnSwitch = true;
}
}
// Text element
- for(auto it = m_textList.begin(); it != m_textList.end(); ++it) {
+ for (auto it = m_textList.begin(); it != m_textList.end(); ++it) {
Text* text = *it;
- if(text->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
+ if (text->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
text->ShowForm(this, GetElementList());
redraw = true;
}
}
- if(elementEdited) {
+ if (elementEdited) {
UpdateTextElements();
- if(m_continuousCalc) RunStaticStudies();
+ if (m_continuousCalc) RunStaticStudies();
}
- if(clickOnSwitch && m_continuousCalc) RunStaticStudies();
+ if (clickOnSwitch && m_continuousCalc) RunStaticStudies();
- if(redraw) Redraw();
+ if (redraw) Redraw();
m_timer->Start();
}
void Workspace::OnRightClickDown(wxMouseEvent& event)
{
bool redraw = false;
- if(m_mode == WorkspaceMode::MODE_EDIT) {
- for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
+ if (m_mode == WorkspaceMode::MODE_EDIT) {
+ for (auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
Element* element = *it;
- if(element->IsSelected()) {
+ if (element->IsSelected()) {
// Show context menu.
- if(element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
+ if (element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
element->ShowPickbox(false);
wxMenu menu;
- if(element->GetContextMenu(menu)) {
+ if (element->GetContextMenu(menu)) {
m_timer->Stop();
menu.SetClientData(element);
menu.Bind(wxEVT_COMMAND_MENU_SELECTED, &Workspace::OnPopupClick, this);
PopupMenu(&menu);
redraw = true;
- if(!menu.GetClientData()) break;
+ if (!menu.GetClientData()) break;
}
element->ResetPickboxes();
}
}
}
}
- if(redraw) Redraw();
+ if (redraw) Redraw();
m_timer->Start();
}
@@ -390,22 +431,22 @@ void Workspace::OnLeftClickUp(wxMouseEvent& event)
bool updateVoltages = false;
auto itnp = m_elementList.begin();
- for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
+ for (auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
Element* element = *it;
// The user was moving a pickbox.
- if(m_mode == WorkspaceMode::MODE_MOVE_PICKBOX) {
+ if (m_mode == WorkspaceMode::MODE_MOVE_PICKBOX) {
// Catch only the element that have the pickbox shown.
- if(element->IsPickboxShown()) {
+ if (element->IsPickboxShown()) {
// If the element is a bus, check if a node is outside.
- if(typeid(*element) == typeid(Bus)) {
+ if (typeid(*element) == typeid(Bus)) {
// Get all the bus children.
- for(int i = 0; i < (int)m_elementList.size(); i++) {
+ for (int i = 0; i < (int)m_elementList.size(); i++) {
Element* child = m_elementList[i];
- for(int j = 0; j < (int)child->GetParentList().size(); j++) {
+ for (int j = 0; j < (int)child->GetParentList().size(); j++) {
Element* parent = child->GetParentList()[j];
// The child have a parent that is the element.
- if(parent == element) {
+ if (parent == element) {
child->UpdateNodes();
m_disconnectedElement = true;
}
@@ -415,18 +456,20 @@ void Workspace::OnLeftClickUp(wxMouseEvent& event)
}
}
- if(m_mode == WorkspaceMode::MODE_SELECTION_RECT) {
- if(element->Intersects(m_selectionRect)) {
+ if (m_mode == WorkspaceMode::MODE_SELECTION_RECT) {
+ if (element->Intersects(m_selectionRect)) {
element->SetSelected();
- } else if(!event.ControlDown()) {
+ }
+ else if (!event.ControlDown()) {
element->SetSelected(false);
}
- } else if(m_mode == WorkspaceMode::MODE_MOVE_NODE) {
- if(element->IsSelected()) {
- for(int i = 0; i < (int)m_elementList.size(); i++) {
+ }
+ else if (m_mode == WorkspaceMode::MODE_MOVE_NODE) {
+ if (element->IsSelected()) {
+ for (int i = 0; i < (int)m_elementList.size(); i++) {
Element* parent = m_elementList[i];
- if(typeid(*parent) == typeid(Bus)) {
- if(element->SetNodeParent(parent)) {
+ if (typeid(*parent) == typeid(Bus)) {
+ if (element->SetNodeParent(parent)) {
parent->AddChild(element);
findNewParent = true;
itnp = it;
@@ -437,15 +480,17 @@ void Workspace::OnLeftClickUp(wxMouseEvent& event)
}
// element->ResetNodes();
}
- } else {
+ }
+ else {
// Deselect
- if(!event.ControlDown()) {
- if(!element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) { element->SetSelected(false); }
+ if (!event.ControlDown()) {
+ if (!element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) { element->SetSelected(false); }
}
- if(element->PickboxContains(m_camera->ScreenToWorld(event.GetPosition()))) {
+ if (element->PickboxContains(m_camera->ScreenToWorld(event.GetPosition()))) {
foundPickbox = true;
- } else {
+ }
+ else {
element->ShowPickbox(false);
element->ResetPickboxes();
}
@@ -453,35 +498,43 @@ void Workspace::OnLeftClickUp(wxMouseEvent& event)
}
// Text element
- for(auto it = m_textList.begin(); it != m_textList.end(); it++) {
+ for (auto it = m_textList.begin(); it != m_textList.end(); it++) {
Text* text = *it;
- if(m_mode == WorkspaceMode::MODE_SELECTION_RECT) {
- if(text->Intersects(m_selectionRect)) {
+ if (m_mode == WorkspaceMode::MODE_SELECTION_RECT) {
+ if (text->Intersects(m_selectionRect)) {
text->SetSelected();
- } else if(!event.ControlDown()) {
+ }
+ else if (!event.ControlDown()) {
text->SetSelected(false);
}
- } else if(!event.ControlDown()) {
- if(!text->Contains(m_camera->ScreenToWorld(event.GetPosition()))) { text->SetSelected(false); }
+ }
+ else if (!event.ControlDown()) {
+ if (!text->Contains(m_camera->ScreenToWorld(event.GetPosition()))) { text->SetSelected(false); }
}
}
- if(findNewParent) {
+ if (findNewParent) {
std::rotate(itnp, itnp + 1, m_elementList.end());
updateVoltages = true;
}
- if(!foundPickbox) { SetCursor(wxCURSOR_ARROW); }
+ if (!foundPickbox) { SetCursor(wxCURSOR_ARROW); }
- if(m_mode != WorkspaceMode::MODE_INSERT) { m_mode = WorkspaceMode::MODE_EDIT; }
+ if (m_mode != WorkspaceMode::MODE_INSERT) { m_mode = WorkspaceMode::MODE_EDIT; }
- if(updateVoltages) { ValidateElementsVoltages(); }
+ if (updateVoltages) { ValidateElementsVoltages(); }
- if(m_continuousCalc && m_disconnectedElement) {
+ if (m_continuousCalc && m_disconnectedElement) {
m_disconnectedElement = false;
RunStaticStudies();
}
m_selectionRect = wxRect2DDouble(0, 0, 0, 0);
+
+ if (m_hmPlane && m_showHM) {
+ m_showHMTimer = true;
+ m_timerHeatMap->Start();
+ }
+
Redraw();
UpdateStatusBar();
}
@@ -489,124 +542,136 @@ void Workspace::OnLeftClickUp(wxMouseEvent& event)
void Workspace::OnMouseMotion(wxMouseEvent& event)
{
bool redraw = false;
- switch(m_mode) {
- case WorkspaceMode::MODE_INSERT: {
- Element* newElement = *(m_elementList.end() - 1); // Get the last element in the list.
- newElement->SetPosition(m_camera->ScreenToWorld(event.GetPosition()));
- redraw = true;
- } break;
-
- case WorkspaceMode::MODE_INSERT_TEXT: {
- Text* newText = *(m_textList.end() - 1);
- newText->SetPosition(m_camera->ScreenToWorld(event.GetPosition()));
- redraw = true;
- } break;
-
- case WorkspaceMode::MODE_DRAG:
- case WorkspaceMode::MODE_DRAG_INSERT:
- case WorkspaceMode::MODE_DRAG_INSERT_TEXT:
- case WorkspaceMode::MODE_DRAG_PASTE: {
- m_camera->SetTranslation(event.GetPosition());
- redraw = true;
- } break;
-
- case WorkspaceMode::MODE_EDIT: {
- bool foundPickbox = false;
- for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
- Element* element = *it;
- if(element->IsSelected()) {
- // Show element pickbox (when it has) if the mouse is over the selected object.
- if(element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
- element->ShowPickbox();
- redraw = true;
-
- // If the mouse is over a pickbox set correct mouse cursor.
- if(element->PickboxContains(m_camera->ScreenToWorld(event.GetPosition()))) {
- foundPickbox = true;
- SetCursor(element->GetBestPickboxCursor());
- } else if(!foundPickbox) {
- SetCursor(wxCURSOR_ARROW);
- element->ResetPickboxes();
- }
- } else if(!foundPickbox) {
- if(element->IsPickboxShown()) redraw = true;
+ switch (m_mode) {
+ case WorkspaceMode::MODE_INSERT: {
+ Element* newElement = *(m_elementList.end() - 1); // Get the last element in the list.
+ newElement->SetPosition(m_camera->ScreenToWorld(event.GetPosition()));
+ redraw = true;
+ } break;
+
+ case WorkspaceMode::MODE_INSERT_TEXT: {
+ Text* newText = *(m_textList.end() - 1);
+ newText->SetPosition(m_camera->ScreenToWorld(event.GetPosition()));
+ redraw = true;
+ } break;
+
+ case WorkspaceMode::MODE_DRAG:
+ case WorkspaceMode::MODE_DRAG_INSERT:
+ case WorkspaceMode::MODE_DRAG_INSERT_TEXT:
+ case WorkspaceMode::MODE_DRAG_PASTE: {
+ m_camera->SetTranslation(event.GetPosition());
+ redraw = true;
+ } break;
+
+ case WorkspaceMode::MODE_EDIT: {
+ bool foundPickbox = false;
+ for (auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
+ Element* element = *it;
+ if (element->IsSelected()) {
+ // Show element pickbox (when it has) if the mouse is over the selected object.
+ if (element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
+ element->ShowPickbox();
+ redraw = true;
- element->ShowPickbox(false);
- element->ResetPickboxes();
+ // If the mouse is over a pickbox set correct mouse cursor.
+ if (element->PickboxContains(m_camera->ScreenToWorld(event.GetPosition()))) {
+ foundPickbox = true;
+ SetCursor(element->GetBestPickboxCursor());
+ }
+ else if (!foundPickbox) {
SetCursor(wxCURSOR_ARROW);
+ element->ResetPickboxes();
}
}
- }
- } break;
+ else if (!foundPickbox) {
+ if (element->IsPickboxShown()) redraw = true;
- case WorkspaceMode::MODE_MOVE_NODE: {
- for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
- Element* element = *it;
- if(element->IsSelected()) {
- element->MoveNode(nullptr, m_camera->ScreenToWorld(event.GetPosition()));
- redraw = true;
+ element->ShowPickbox(false);
+ element->ResetPickboxes();
+ SetCursor(wxCURSOR_ARROW);
}
}
- } break;
+ }
+ } break;
- case WorkspaceMode::MODE_MOVE_PICKBOX: {
- for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
- Element* element = *it;
- if(element->IsSelected()) {
- element->MovePickbox(m_camera->ScreenToWorld(event.GetPosition()));
- redraw = true;
- }
+ case WorkspaceMode::MODE_MOVE_NODE: {
+ for (auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
+ Element* element = *it;
+ if (element->IsSelected()) {
+ element->MoveNode(nullptr, m_camera->ScreenToWorld(event.GetPosition()));
+ redraw = true;
}
- } break;
+ }
+ } break;
- case WorkspaceMode::MODE_MOVE_ELEMENT:
- case WorkspaceMode::MODE_PASTE: {
- for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
- Element* element = *it;
- if(element->IsSelected()) {
- element->Move(m_camera->ScreenToWorld(event.GetPosition()));
- // Move child nodes
- std::vector<Element*> childList = element->GetChildList();
- for(auto it = childList.begin(), itEnd = childList.end(); it != itEnd; ++it) {
- (*it)->MoveNode(element, m_camera->ScreenToWorld(event.GetPosition()));
- }
- redraw = true;
- }
- }
- // Text element motion
- for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; it++) {
- Text* text = *it;
- if(text->IsSelected()) {
- text->Move(m_camera->ScreenToWorld(event.GetPosition()));
- redraw = true;
- }
+ case WorkspaceMode::MODE_MOVE_PICKBOX: {
+ for (auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
+ Element* element = *it;
+ if (element->IsSelected()) {
+ element->MovePickbox(m_camera->ScreenToWorld(event.GetPosition()));
+ redraw = true;
}
- } break;
+ }
+ if (m_hmPlane && m_showHM) {
+ m_hmPlane->Clear();
+ }
+ } break;
- case WorkspaceMode::MODE_SELECTION_RECT: {
- wxPoint2DDouble currentPos = m_camera->ScreenToWorld(event.GetPosition());
- double x, y, w, h;
- if(currentPos.m_x < m_startSelRect.m_x) {
- x = currentPos.m_x;
- w = m_startSelRect.m_x - currentPos.m_x;
- } else {
- x = m_startSelRect.m_x;
- w = currentPos.m_x - m_startSelRect.m_x;
+ case WorkspaceMode::MODE_MOVE_ELEMENT:
+ case WorkspaceMode::MODE_PASTE: {
+ for (auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
+ Element* element = *it;
+ if (element->IsSelected()) {
+ element->Move(m_camera->ScreenToWorld(event.GetPosition()));
+ // Move child nodes
+ std::vector<Element*> childList = element->GetChildList();
+ for (auto it = childList.begin(), itEnd = childList.end(); it != itEnd; ++it) {
+ (*it)->MoveNode(element, m_camera->ScreenToWorld(event.GetPosition()));
+ }
+ redraw = true;
}
- if(currentPos.m_y < m_startSelRect.m_y) {
- y = currentPos.m_y;
- h = m_startSelRect.m_y - currentPos.m_y;
- } else {
- y = m_startSelRect.m_y;
- h = currentPos.m_y - m_startSelRect.m_y;
+ }
+ // Text element motion
+ for (auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; it++) {
+ Text* text = *it;
+ if (text->IsSelected()) {
+ text->Move(m_camera->ScreenToWorld(event.GetPosition()));
+ redraw = true;
}
+ }
+ if (m_hmPlane && m_showHM) {
+ m_hmPlane->Clear();
+ }
+ } break;
+
+ case WorkspaceMode::MODE_SELECTION_RECT: {
+ wxPoint2DDouble currentPos = m_camera->ScreenToWorld(event.GetPosition());
+ double x, y, w, h;
+ if (currentPos.m_x < m_startSelRect.m_x) {
+ x = currentPos.m_x;
+ w = m_startSelRect.m_x - currentPos.m_x;
+ }
+ else {
+ x = m_startSelRect.m_x;
+ w = currentPos.m_x - m_startSelRect.m_x;
+ }
+ if (currentPos.m_y < m_startSelRect.m_y) {
+ y = currentPos.m_y;
+ h = m_startSelRect.m_y - currentPos.m_y;
+ }
+ else {
+ y = m_startSelRect.m_y;
+ h = currentPos.m_y - m_startSelRect.m_y;
+ }
- m_selectionRect = wxRect2DDouble(x, y, w, h);
- redraw = true;
- } break;
+ m_selectionRect = wxRect2DDouble(x, y, w, h);
+ redraw = true;
+ } break;
}
- if(redraw) Redraw();
+ if (redraw) {
+ Redraw();
+ }
m_camera->UpdateMousePosition(event.GetPosition());
UpdateStatusBar();
m_timer->Start(); // Restart the timer.
@@ -616,57 +681,74 @@ void Workspace::OnMouseMotion(wxMouseEvent& event)
void Workspace::OnMiddleDown(wxMouseEvent& event)
{
// Set to drag mode.
- switch(m_mode) {
- case WorkspaceMode::MODE_INSERT: {
- m_mode = WorkspaceMode::MODE_DRAG_INSERT;
- } break;
- case WorkspaceMode::MODE_INSERT_TEXT: {
- m_mode = WorkspaceMode::MODE_DRAG_INSERT_TEXT;
- } break;
- case WorkspaceMode::MODE_PASTE: {
- m_mode = WorkspaceMode::MODE_DRAG_PASTE;
- } break;
- default: {
- m_mode = WorkspaceMode::MODE_DRAG;
- } break;
+ switch (m_mode) {
+ case WorkspaceMode::MODE_INSERT: {
+ m_mode = WorkspaceMode::MODE_DRAG_INSERT;
+ } break;
+ case WorkspaceMode::MODE_INSERT_TEXT: {
+ m_mode = WorkspaceMode::MODE_DRAG_INSERT_TEXT;
+ } break;
+ case WorkspaceMode::MODE_PASTE: {
+ m_mode = WorkspaceMode::MODE_DRAG_PASTE;
+ } break;
+ default: {
+ m_mode = WorkspaceMode::MODE_DRAG;
+ } break;
}
m_camera->StartTranslation(m_camera->ScreenToWorld(event.GetPosition()));
UpdateStatusBar();
+
+ if (m_hmPlane && m_showHM) {
+ m_hmPlane->Clear();
+ }
+
event.Skip();
}
void Workspace::OnMiddleUp(wxMouseEvent& event)
{
- switch(m_mode) {
- case WorkspaceMode::MODE_DRAG_INSERT: {
- m_mode = WorkspaceMode::MODE_INSERT;
- } break;
- case WorkspaceMode::MODE_DRAG_INSERT_TEXT: {
- m_mode = WorkspaceMode::MODE_INSERT_TEXT;
- } break;
- case WorkspaceMode::MODE_DRAG_PASTE: {
- m_mode = WorkspaceMode::MODE_PASTE;
- } break;
- case WorkspaceMode::MODE_INSERT:
- case WorkspaceMode::MODE_INSERT_TEXT:
- case WorkspaceMode::MODE_PASTE: {
- // Does nothing.
- } break;
- default: {
- m_mode = WorkspaceMode::MODE_EDIT;
- } break;
+ switch (m_mode) {
+ case WorkspaceMode::MODE_DRAG_INSERT: {
+ m_mode = WorkspaceMode::MODE_INSERT;
+ } break;
+ case WorkspaceMode::MODE_DRAG_INSERT_TEXT: {
+ m_mode = WorkspaceMode::MODE_INSERT_TEXT;
+ } break;
+ case WorkspaceMode::MODE_DRAG_PASTE: {
+ m_mode = WorkspaceMode::MODE_PASTE;
+ } break;
+ case WorkspaceMode::MODE_INSERT:
+ case WorkspaceMode::MODE_INSERT_TEXT:
+ case WorkspaceMode::MODE_PASTE: {
+ // Does nothing.
+ } break;
+ default: {
+ m_mode = WorkspaceMode::MODE_EDIT;
+ } break;
}
UpdateStatusBar();
+
+ if (m_hmPlane && m_showHM) {
+ UpdateHeatMap();
+ Redraw();
+ }
+
event.Skip();
}
void Workspace::OnScroll(wxMouseEvent& event)
{
- if(event.GetWheelRotation() > 0)
+ if (event.GetWheelRotation() > 0)
m_camera->SetScale(event.GetPosition(), +0.05);
else
m_camera->SetScale(event.GetPosition(), -0.05);
+ if (m_hmPlane && m_showHM) {
+ m_hmPlane->Clear();
+ m_showHMTimer = true;
+ m_timerHeatMap->Start();
+ }
+
UpdateStatusBar();
Redraw();
}
@@ -674,167 +756,181 @@ void Workspace::OnScroll(wxMouseEvent& event)
void Workspace::OnKeyDown(wxKeyEvent& event)
{
bool insertingElement = false;
- if(m_mode == WorkspaceMode::MODE_INSERT || m_mode == WorkspaceMode::MODE_INSERT_TEXT) insertingElement = true;
+ if (m_mode == WorkspaceMode::MODE_INSERT || m_mode == WorkspaceMode::MODE_INSERT_TEXT) insertingElement = true;
char key = event.GetUnicodeKey();
- if(key != WXK_NONE) {
- switch(key) {
- case WXK_ESCAPE: // Cancel operations.
- {
- if(m_mode == WorkspaceMode::MODE_INSERT) {
- m_elementList.pop_back(); // Removes the last element being inserted.
- m_mode = WorkspaceMode::MODE_EDIT;
- Redraw();
- } else if(m_mode == WorkspaceMode::MODE_INSERT_TEXT) {
- m_textList.pop_back();
- m_mode = WorkspaceMode::MODE_EDIT;
- Redraw();
- }
- } break;
- case WXK_DELETE: // Delete selected elements
- {
- DeleteSelectedElements();
- } break;
- case 'A': {
- if(!insertingElement) {
- Text* newBus = new Text(m_camera->ScreenToWorld(event.GetPosition()));
- m_textList.push_back(newBus);
- m_mode = WorkspaceMode::MODE_INSERT_TEXT;
- m_statusBar->SetStatusText(_("Insert Text: Click to insert, ESC to cancel."));
- Redraw();
- }
- } break;
- case 'F': {
- if(event.GetModifiers() == wxMOD_SHIFT) { Fit(); }
- } break;
- case 'R': // Rotate the selected elements.
- {
- RotateSelectedElements(event.GetModifiers() != wxMOD_SHIFT);
- } break;
- case 'B': // Insert a bus.
- {
- if(!insertingElement) {
- Bus* newBus = new Bus(m_camera->ScreenToWorld(event.GetPosition()),
- wxString::Format(_("Bus %d"), GetElementNumber(ID_BUS)));
- IncrementElementNumber(ID_BUS);
- m_elementList.push_back(newBus);
+ if (key != WXK_NONE) {
+ switch (key) {
+ case WXK_ESCAPE: // Cancel operations.
+ {
+ if (m_mode == WorkspaceMode::MODE_INSERT) {
+ m_elementList.pop_back(); // Removes the last element being inserted.
+ m_mode = WorkspaceMode::MODE_EDIT;
+ Redraw();
+ }
+ else if (m_mode == WorkspaceMode::MODE_INSERT_TEXT) {
+ m_textList.pop_back();
+ m_mode = WorkspaceMode::MODE_EDIT;
+ Redraw();
+ }
+ } break;
+ case WXK_DELETE: // Delete selected elements
+ {
+ DeleteSelectedElements();
+ } break;
+ case 'A': {
+ if (!insertingElement) {
+ Text* newBus = new Text(m_camera->ScreenToWorld(event.GetPosition()));
+ m_textList.push_back(newBus);
+ m_mode = WorkspaceMode::MODE_INSERT_TEXT;
+ m_statusBar->SetStatusText(_("Insert Text: Click to insert, ESC to cancel."));
+ Redraw();
+ }
+ } break;
+ case 'F': {
+ if (event.GetModifiers() == wxMOD_SHIFT) { Fit(); }
+ } break;
+ case 'R': // Rotate the selected elements.
+ {
+ RotateSelectedElements(event.GetModifiers() != wxMOD_SHIFT);
+ } break;
+ case 'B': // Insert a bus.
+ {
+ if (!insertingElement) {
+ Bus* newBus = new Bus(m_camera->ScreenToWorld(event.GetPosition()),
+ wxString::Format(_("Bus %d"), GetElementNumber(ID_BUS)));
+ IncrementElementNumber(ID_BUS);
+ m_elementList.push_back(newBus);
+ m_mode = WorkspaceMode::MODE_INSERT;
+ m_statusBar->SetStatusText(_("Insert Bus: Click to insert, ESC to cancel."));
+ Redraw();
+ }
+ } break;
+ case 'L': {
+ if (!insertingElement) {
+ if (!event.ControlDown() && event.ShiftDown()) { // Insert a load.
+ Load* newLoad = new Load(wxString::Format(_("Load %d"), GetElementNumber(ID_LOAD)));
+ IncrementElementNumber(ID_LOAD);
+ m_elementList.push_back(newLoad);
m_mode = WorkspaceMode::MODE_INSERT;
- m_statusBar->SetStatusText(_("Insert Bus: Click to insert, ESC to cancel."));
- Redraw();
+ m_statusBar->SetStatusText(_("Insert Load: Click on a buses, ESC to cancel."));
}
- } break;
- case 'L': {
- if(!insertingElement) {
- if(!event.ControlDown() && event.ShiftDown()) { // Insert a load.
- Load* newLoad = new Load(wxString::Format(_("Load %d"), GetElementNumber(ID_LOAD)));
- IncrementElementNumber(ID_LOAD);
- m_elementList.push_back(newLoad);
- m_mode = WorkspaceMode::MODE_INSERT;
- m_statusBar->SetStatusText(_("Insert Load: Click on a buses, ESC to cancel."));
- } else if(!event.ControlDown() && !event.ShiftDown()) { // Insert a power line.
- Line* newLine = new Line(wxString::Format(_("Line %d"), GetElementNumber(ID_LINE)));
- IncrementElementNumber(ID_LINE);
- m_elementList.push_back(newLine);
- m_mode = WorkspaceMode::MODE_INSERT;
- m_statusBar->SetStatusText(_("Insert Line: Click on two buses, ESC to cancel."));
- }
- Redraw();
- }
- // Tests - Ctrl + Shift + L
- } break;
- case 'T': // Insert a transformer.
- {
- if(!insertingElement) {
- Transformer* newTransformer =
- new Transformer(wxString::Format(_("Transformer %d"), GetElementNumber(ID_TRANSFORMER)));
- IncrementElementNumber(ID_TRANSFORMER);
- m_elementList.push_back(newTransformer);
+ else if (!event.ControlDown() && !event.ShiftDown()) { // Insert a power line.
+ Line* newLine = new Line(wxString::Format(_("Line %d"), GetElementNumber(ID_LINE)));
+ IncrementElementNumber(ID_LINE);
+ m_elementList.push_back(newLine);
m_mode = WorkspaceMode::MODE_INSERT;
- m_statusBar->SetStatusText(_("Insert Transformer: Click on two buses, ESC to cancel."));
- Redraw();
+ m_statusBar->SetStatusText(_("Insert Line: Click on two buses, ESC to cancel."));
}
- } break;
- case 'G': // Insert a generator.
- {
- if(!insertingElement) {
- SyncGenerator* newGenerator =
- new SyncGenerator(wxString::Format(_("Generator %d"), GetElementNumber(ID_SYNCGENERATOR)));
- IncrementElementNumber(ID_SYNCGENERATOR);
- m_elementList.push_back(newGenerator);
+ Redraw();
+ }
+ // Tests - Ctrl + Shift + L
+ } break;
+ case 'T': // Insert a transformer.
+ {
+ if (!insertingElement) {
+ Transformer* newTransformer =
+ new Transformer(wxString::Format(_("Transformer %d"), GetElementNumber(ID_TRANSFORMER)));
+ IncrementElementNumber(ID_TRANSFORMER);
+ m_elementList.push_back(newTransformer);
+ m_mode = WorkspaceMode::MODE_INSERT;
+ m_statusBar->SetStatusText(_("Insert Transformer: Click on two buses, ESC to cancel."));
+ Redraw();
+ }
+ } break;
+ case 'G': // Insert a generator.
+ {
+ if (!insertingElement) {
+ SyncGenerator* newGenerator =
+ new SyncGenerator(wxString::Format(_("Generator %d"), GetElementNumber(ID_SYNCGENERATOR)));
+ IncrementElementNumber(ID_SYNCGENERATOR);
+ m_elementList.push_back(newGenerator);
+ m_mode = WorkspaceMode::MODE_INSERT;
+ m_statusBar->SetStatusText(_("Insert Generator: Click on a buses, ESC to cancel."));
+ Redraw();
+ }
+ } break;
+ case 'I': {
+ if (!insertingElement) {
+ if (event.GetModifiers() == wxMOD_SHIFT) { // Insert an inductor.
+ Inductor* newInductor =
+ new Inductor(wxString::Format(_("Inductor %d"), GetElementNumber(ID_INDUCTOR)));
+ IncrementElementNumber(ID_INDUCTOR);
+ m_elementList.push_back(newInductor);
m_mode = WorkspaceMode::MODE_INSERT;
- m_statusBar->SetStatusText(_("Insert Generator: Click on a buses, ESC to cancel."));
- Redraw();
+ m_statusBar->SetStatusText(_("Insert Inductor: Click on a buses, ESC to cancel."));
}
- } break;
- case 'I': {
- if(!insertingElement) {
- if(event.GetModifiers() == wxMOD_SHIFT) { // Insert an inductor.
- Inductor* newInductor =
- new Inductor(wxString::Format(_("Inductor %d"), GetElementNumber(ID_INDUCTOR)));
- IncrementElementNumber(ID_INDUCTOR);
- m_elementList.push_back(newInductor);
- m_mode = WorkspaceMode::MODE_INSERT;
- m_statusBar->SetStatusText(_("Insert Inductor: Click on a buses, ESC to cancel."));
- } else // Insert an induction motor.
- {
- IndMotor* newIndMotor =
- new IndMotor(wxString::Format(_("Induction motor %d"), GetElementNumber(ID_INDMOTOR)));
- IncrementElementNumber(ID_INDMOTOR);
- m_elementList.push_back(newIndMotor);
- m_mode = WorkspaceMode::MODE_INSERT;
- m_statusBar->SetStatusText(_("Insert Induction Motor: Click on a buses, ESC to cancel."));
- }
- Redraw();
+ else // Insert an induction motor.
+ {
+ IndMotor* newIndMotor =
+ new IndMotor(wxString::Format(_("Induction motor %d"), GetElementNumber(ID_INDMOTOR)));
+ IncrementElementNumber(ID_INDMOTOR);
+ m_elementList.push_back(newIndMotor);
+ m_mode = WorkspaceMode::MODE_INSERT;
+ m_statusBar->SetStatusText(_("Insert Induction Motor: Click on a buses, ESC to cancel."));
}
- } break;
- case 'K': // Insert a synchronous condenser.
- {
- if(!insertingElement) {
- SyncMotor* newSyncCondenser =
- new SyncMotor(wxString::Format(_("Synchronous condenser %d"), GetElementNumber(ID_SYNCMOTOR)));
- IncrementElementNumber(ID_SYNCMOTOR);
- m_elementList.push_back(newSyncCondenser);
+ Redraw();
+ }
+ } break;
+ case 'K': // Insert a synchronous condenser.
+ {
+ if (!insertingElement) {
+ SyncMotor* newSyncCondenser =
+ new SyncMotor(wxString::Format(_("Synchronous condenser %d"), GetElementNumber(ID_SYNCMOTOR)));
+ IncrementElementNumber(ID_SYNCMOTOR);
+ m_elementList.push_back(newSyncCondenser);
+ m_mode = WorkspaceMode::MODE_INSERT;
+ m_statusBar->SetStatusText(_("Insert Synchronous Condenser: Click on a buses, ESC to cancel."));
+ Redraw();
+ }
+ } break;
+ case 'C': {
+ if (!insertingElement) {
+ if (event.GetModifiers() == wxMOD_SHIFT) { // Insert a capacitor.
+ Capacitor* newCapacitor =
+ new Capacitor(wxString::Format(_("Capacitor %d"), GetElementNumber(ID_CAPACITOR)));
+ IncrementElementNumber(ID_CAPACITOR);
+ m_elementList.push_back(newCapacitor);
m_mode = WorkspaceMode::MODE_INSERT;
- m_statusBar->SetStatusText(_("Insert Synchronous Condenser: Click on a buses, ESC to cancel."));
+ m_statusBar->SetStatusText(_("Insert Capacitor: Click on a buses, ESC to cancel."));
Redraw();
}
- } break;
- case 'C': {
- if(!insertingElement) {
- if(event.GetModifiers() == wxMOD_SHIFT) { // Insert a capacitor.
- Capacitor* newCapacitor =
- new Capacitor(wxString::Format(_("Capacitor %d"), GetElementNumber(ID_CAPACITOR)));
- IncrementElementNumber(ID_CAPACITOR);
- m_elementList.push_back(newCapacitor);
- m_mode = WorkspaceMode::MODE_INSERT;
- m_statusBar->SetStatusText(_("Insert Capacitor: Click on a buses, ESC to cancel."));
- Redraw();
- } else if(event.GetModifiers() == wxMOD_CONTROL) { // Copy.
- CopySelection();
- }
+ else if (event.GetModifiers() == wxMOD_CONTROL) { // Copy.
+ CopySelection();
}
- } break;
- case 'H': {
- if(!insertingElement) {
- if(event.GetModifiers() == wxMOD_SHIFT) { // Insert an harmonic current source.
- HarmCurrent* newHarmCurrent = new HarmCurrent(
- wxString::Format(_("Harmonic Current %d"), GetElementNumber(ID_HARMCURRENT)));
- IncrementElementNumber(ID_HARMCURRENT);
- m_elementList.push_back(newHarmCurrent);
- m_mode = WorkspaceMode::MODE_INSERT;
- m_statusBar->SetStatusText(
- _("Insert Harmonic Current Source: Click on a buses, ESC to cancel."));
+ }
+ } break;
+ case 'H': {
+ if (!insertingElement) {
+ if (event.ShiftDown() && event.ControlDown()) {
+ if (!m_showHM) {
+ m_showHM = true;
+ UpdateHeatMap();
}
- Redraw();
+ else {
+ m_showHM = false;
+ }
+
}
- } break;
- case 'V': {
- if(!insertingElement) {
- if(event.GetModifiers() == wxMOD_CONTROL) { Paste(); }
+ else if (event.GetModifiers() == wxMOD_SHIFT) { // Insert an harmonic current source.
+ HarmCurrent* newHarmCurrent = new HarmCurrent(
+ wxString::Format(_("Harmonic Current %d"), GetElementNumber(ID_HARMCURRENT)));
+ IncrementElementNumber(ID_HARMCURRENT);
+ m_elementList.push_back(newHarmCurrent);
+ m_mode = WorkspaceMode::MODE_INSERT;
+ m_statusBar->SetStatusText(
+ _("Insert Harmonic Current Source: Click on a buses, ESC to cancel."));
}
- } break;
- default:
- break;
+ Redraw();
+ }
+ } break;
+ case 'V': {
+ if (!insertingElement) {
+ if (event.GetModifiers() == wxMOD_CONTROL) { Paste(); }
+ }
+ } break;
+ default:
+ break;
}
}
@@ -844,31 +940,31 @@ void Workspace::OnKeyDown(wxKeyEvent& event)
void Workspace::UpdateStatusBar()
{
- switch(m_mode) {
- case WorkspaceMode::MODE_DRAG: {
- m_statusBar->SetStatusText(_("MODE: DRAG"), 1);
- } break;
-
- case WorkspaceMode::MODE_PASTE:
- case WorkspaceMode::MODE_DRAG_PASTE: {
- m_statusBar->SetStatusText(_("MODE: PASTE"), 1);
- }
-
- case WorkspaceMode::MODE_INSERT:
- case WorkspaceMode::MODE_INSERT_TEXT:
- case WorkspaceMode::MODE_DRAG_INSERT:
- case WorkspaceMode::MODE_DRAG_INSERT_TEXT: {
- m_statusBar->SetStatusText(_("MODE: INSERT"), 1);
- } break;
+ switch (m_mode) {
+ case WorkspaceMode::MODE_DRAG: {
+ m_statusBar->SetStatusText(_("MODE: DRAG"), 1);
+ } break;
+
+ case WorkspaceMode::MODE_PASTE:
+ case WorkspaceMode::MODE_DRAG_PASTE: {
+ m_statusBar->SetStatusText(_("MODE: PASTE"), 1);
+ }
- case WorkspaceMode::MODE_MOVE_ELEMENT:
- case WorkspaceMode::MODE_MOVE_PICKBOX:
- case WorkspaceMode::MODE_MOVE_NODE:
- case WorkspaceMode::MODE_SELECTION_RECT:
- case WorkspaceMode::MODE_EDIT: {
- m_statusBar->SetStatusText(wxT(""));
- m_statusBar->SetStatusText(_("MODE: EDIT"), 1);
- } break;
+ case WorkspaceMode::MODE_INSERT:
+ case WorkspaceMode::MODE_INSERT_TEXT:
+ case WorkspaceMode::MODE_DRAG_INSERT:
+ case WorkspaceMode::MODE_DRAG_INSERT_TEXT: {
+ m_statusBar->SetStatusText(_("MODE: INSERT"), 1);
+ } break;
+
+ case WorkspaceMode::MODE_MOVE_ELEMENT:
+ case WorkspaceMode::MODE_MOVE_PICKBOX:
+ case WorkspaceMode::MODE_MOVE_NODE:
+ case WorkspaceMode::MODE_SELECTION_RECT:
+ case WorkspaceMode::MODE_EDIT: {
+ m_statusBar->SetStatusText(wxT(""));
+ m_statusBar->SetStatusText(_("MODE: EDIT"), 1);
+ } break;
}
m_statusBar->SetStatusText(wxString::Format(_("ZOOM: %d%%"), (int)(m_camera->GetScale() * 100.0)), 2);
@@ -877,95 +973,162 @@ void Workspace::UpdateStatusBar()
3);
}
+void Workspace::UpdateHeatMap()
+{
+ if (m_hmPlane && m_showHM) {
+ m_hmPlane->Clear();
+
+ wxRect2DDouble screenRect(-100, -100, m_width + 200.0, m_height + 200.0);
+
+ // Get new voltage range
+ std::vector<Bus*> busList;
+ float minVoltage, maxVoltage;
+ if (m_hmAutomaticLabel) {
+ minVoltage = 10.0f;
+ maxVoltage = 0.0f;
+ }
+ else {
+ minVoltage = m_hmPlane->GetMinLimit();
+ maxVoltage = m_hmPlane->GetMaxLimit();
+ }
+
+ for (auto* element : m_elementList) {
+ if (Bus* bus = dynamic_cast<Bus*>(element)) {
+ if (m_hmAutomaticLabel) {
+ const float voltage = std::abs(bus->GetElectricalData().voltage);
+ if (minVoltage > voltage) minVoltage = voltage;
+ if (maxVoltage < voltage) maxVoltage = voltage;
+ }
+ busList.push_back(bus);
+ }
+ }
+ if (m_hmAutomaticLabel) {
+ m_hmPlane->SetLabelLimits(minVoltage, maxVoltage);
+ }
+
+ for (Bus* bus : busList) {
+ const float voltage = std::abs(bus->GetElectricalData().voltage);
+ float depth = 2.0f * (voltage - (maxVoltage + minVoltage) / 2.0f) / (maxVoltage - minVoltage);
+ if (depth < -1.0) depth = -1.0;
+ if (depth > 1.0) depth = 1.0;
+
+ wxRect2DDouble rect = bus->GetRect();
+ rect = wxRect2DDouble(
+ (rect.m_x - 100.0f) * m_camera->GetScale() + m_camera->GetTranslation().m_x * m_camera->GetScale(),
+ (rect.m_y - 50.0f) * m_camera->GetScale() + m_camera->GetTranslation().m_y * m_camera->GetScale(),
+ (rect.m_width + 200.0f) * m_camera->GetScale(),
+ (rect.m_height + 100.0f) * m_camera->GetScale());
+
+ if (screenRect.Contains(rect))
+ m_hmPlane->SetRectSlope(rect, M_PI * static_cast<float>(bus->GetAngle()) / 180.0f, depth);
+ }
+
+ m_hmPlane->UpdateCoords();
+
+ int iterations = std::lround(3.3 * std::powf(m_camera->GetScale(), 0.62));
+ if (iterations < 1) iterations = 1;
+ m_hmPlane->SmoothPlane(iterations);
+ }
+}
+
void Workspace::OnPopupClick(wxCommandEvent& event)
{
+ bool redrawHM = false;
+
wxMenu* menu = static_cast<wxMenu*>(event.GetEventObject());
Element* element = static_cast<Element*>(menu->GetClientData());
- switch(event.GetId()) {
- case ID_EDIT_ELEMENT: {
- if(element->ShowForm(this, element)) UpdateTextElements();
- } break;
- case ID_LINE_ADD_NODE: {
- Line* line = static_cast<Line*>(element);
- line->AddNode(m_camera->GetMousePosition());
- Redraw();
- } break;
- case ID_LINE_REMOVE_NODE: {
- Line* line = static_cast<Line*>(element);
- line->RemoveNode(m_camera->GetMousePosition());
- Redraw();
- } break;
- case ID_ROTATE_CLOCK: {
- element->Rotate();
- for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
- Element* iElement = *it;
- // Parent's element rotating...
- for(int i = 0; i < (int)iElement->GetParentList().size(); i++) {
- Element* parent = iElement->GetParentList()[i];
- if(parent == element) { iElement->RotateNode(parent); }
- }
+ switch (event.GetId()) {
+ case ID_EDIT_ELEMENT: {
+ if (element->ShowForm(this, element)) UpdateTextElements();
+ } break;
+ case ID_LINE_ADD_NODE: {
+ Line* line = static_cast<Line*>(element);
+ line->AddNode(m_camera->GetMousePosition());
+ Redraw();
+ } break;
+ case ID_LINE_REMOVE_NODE: {
+ Line* line = static_cast<Line*>(element);
+ line->RemoveNode(m_camera->GetMousePosition());
+ Redraw();
+ } break;
+ case ID_ROTATE_CLOCK: {
+ element->Rotate();
+ for (auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
+ Element* iElement = *it;
+ // Parent's element rotating...
+ for (int i = 0; i < (int)iElement->GetParentList().size(); i++) {
+ Element* parent = iElement->GetParentList()[i];
+ if (parent == element) { iElement->RotateNode(parent); }
}
- Redraw();
- } break;
- case ID_ROTATE_COUNTERCLOCK: {
- element->Rotate(false);
- for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
- Element* iElement = *it;
- // Parent's element rotating...
- for(int i = 0; i < (int)iElement->GetParentList().size(); i++) {
- Element* parent = iElement->GetParentList()[i];
- if(parent == element) { iElement->RotateNode(parent, false); }
- }
+ }
+ redrawHM = true;
+ Redraw();
+ } break;
+ case ID_ROTATE_COUNTERCLOCK: {
+ element->Rotate(false);
+ for (auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
+ Element* iElement = *it;
+ // Parent's element rotating...
+ for (int i = 0; i < (int)iElement->GetParentList().size(); i++) {
+ Element* parent = iElement->GetParentList()[i];
+ if (parent == element) { iElement->RotateNode(parent, false); }
}
- Redraw();
- } break;
- case ID_DELETE: {
- for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
- Element* iElement = *it;
-
- if(element == iElement) {
- // Remove child/parent.
- std::vector<Element*> childList = element->GetChildList();
- for(auto itc = childList.begin(), itEnd = childList.end(); itc != itEnd; ++itc) {
- Element* child = *itc;
- if(child) {
- child->RemoveParent(element);
- element->RemoveChild(child);
- }
- }
- std::vector<Element*> parentList = element->GetParentList();
- for(auto itp = parentList.begin(), itEnd = parentList.end(); itp != itEnd; ++itp) {
- Element* parent = *itp;
- if(parent) { parent->RemoveChild(element); }
+ }
+ redrawHM = true;
+ Redraw();
+ } break;
+ case ID_DELETE: {
+ for (auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
+ Element* iElement = *it;
+
+ if (element == iElement) {
+ // Remove child/parent.
+ std::vector<Element*> childList = element->GetChildList();
+ for (auto itc = childList.begin(), itEnd = childList.end(); itc != itEnd; ++itc) {
+ Element* child = *itc;
+ if (child) {
+ child->RemoveParent(element);
+ element->RemoveChild(child);
}
+ }
+ std::vector<Element*> parentList = element->GetParentList();
+ for (auto itp = parentList.begin(), itEnd = parentList.end(); itp != itEnd; ++itp) {
+ Element* parent = *itp;
+ if (parent) { parent->RemoveChild(element); }
+ }
- for(auto itt = m_textList.begin(); itt != m_textList.end(); ++itt) {
- Text* text = *itt;
- if(text->GetElement() == element) {
- m_textList.erase(itt--);
- if(text) delete text;
- }
+ for (auto itt = m_textList.begin(); itt != m_textList.end(); ++itt) {
+ Text* text = *itt;
+ if (text->GetElement() == element) {
+ m_textList.erase(itt--);
+ if (text) delete text;
}
-
- m_elementList.erase(it);
- if(element) delete element;
- menu->SetClientData(nullptr);
- break;
}
+
+ m_elementList.erase(it);
+ if (element) delete element;
+ menu->SetClientData(nullptr);
+ break;
}
- } break;
+ }
+ } break;
+ }
+ if (redrawHM && m_hmPlane && m_showHM) {
+ m_hmPlane->Clear();
+ m_showHMTimer = true;
+ m_timerHeatMap->Start();
}
}
void Workspace::RotateSelectedElements(bool clockwise)
{
- for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
+ for (auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
Element* element = *it;
// Parent's element rotating...
- for(int i = 0; i < (int)element->GetParentList().size(); i++) {
+ for (int i = 0; i < (int)element->GetParentList().size(); i++) {
Element* parent = element->GetParentList()[i];
- if(parent) { // Check if parent is not null
- if(parent->IsSelected()) {
+ if (parent) { // Check if parent is not null
+ if (parent->IsSelected()) {
element->RotateNode(parent, clockwise);
// Update the positions used on motion action, the element will not be necessarily
// moved.
@@ -973,87 +1136,96 @@ void Workspace::RotateSelectedElements(bool clockwise)
}
}
}
- if(element->IsSelected()) {
+ if (element->IsSelected()) {
element->Rotate(clockwise);
element->StartMove(m_camera->GetMousePosition());
}
}
// Rotate text element
- for(auto it = m_textList.begin(); it != m_textList.end(); it++) {
+ for (auto it = m_textList.begin(); it != m_textList.end(); it++) {
Text* text = *it;
- if(text->IsSelected()) {
+ if (text->IsSelected()) {
text->Rotate(clockwise);
text->StartMove(m_camera->GetMousePosition());
}
}
+ if (m_hmPlane && m_showHM) {
+ m_hmPlane->Clear();
+ m_showHMTimer = true;
+ m_timerHeatMap->Start();
+ }
Redraw();
}
void Workspace::DeleteSelectedElements()
{
// Don't set the end of the list at the loop's begin.
- for(auto it = m_elementList.begin(); it != m_elementList.end();) {
+ for (auto it = m_elementList.begin(); it != m_elementList.end();) {
Element* element = *it;
- if(element->IsSelected()) {
+ if (element->IsSelected()) {
// Remove child/parent.
std::vector<Element*> childList = element->GetChildList();
- for(auto itc = childList.begin(), itEnd = childList.end(); itc != itEnd; ++itc) {
+ for (auto itc = childList.begin(), itEnd = childList.end(); itc != itEnd; ++itc) {
Element* child = *itc;
- if(child) {
+ if (child) {
child->RemoveParent(element);
element->RemoveChild(child);
}
}
std::vector<Element*> parentList = element->GetParentList();
- for(auto itp = parentList.begin(), itEnd = parentList.end(); itp != itEnd; ++itp) {
+ for (auto itp = parentList.begin(), itEnd = parentList.end(); itp != itEnd; ++itp) {
Element* parent = *itp;
- if(parent) { parent->RemoveChild(element); }
+ if (parent) { parent->RemoveChild(element); }
}
- for(auto itt = m_textList.begin(); itt != m_textList.end(); ++itt) {
+ for (auto itt = m_textList.begin(); itt != m_textList.end(); ++itt) {
Text* text = *itt;
- if(text->GetElement() == element) {
+ if (text->GetElement() == element) {
m_textList.erase(itt--);
- if(text) delete text;
+ if (text) delete text;
}
}
it = m_elementList.erase(it);
- if(element) delete element;
+ if (element) delete element;
}
else it++;
}
- for(auto it = m_textList.begin(); it != m_textList.end(); ++it) {
+ for (auto it = m_textList.begin(); it != m_textList.end(); ++it) {
Text* text = *it;
- if(text->IsSelected()) {
+ if (text->IsSelected()) {
m_textList.erase(it--);
- if(text) delete text;
+ if (text) delete text;
}
}
-
+ if (m_hmPlane && m_showHM) {
+ m_hmPlane->Clear();
+ m_showHMTimer = true;
+ m_timerHeatMap->Start();
+ }
Redraw();
}
bool Workspace::GetElementsCorners(wxPoint2DDouble& leftUpCorner,
- wxPoint2DDouble& rightDownCorner,
- std::vector<Element*> elementList)
+ wxPoint2DDouble& rightDownCorner,
+ std::vector<Element*> elementList)
{
- if(elementList.size() == 0) return false;
+ if (elementList.size() == 0) return false;
elementList[0]->CalculateBoundaries(leftUpCorner, rightDownCorner);
- for(auto it = elementList.begin() + 1, itEnd = elementList.end(); it != itEnd; it++) {
+ for (auto it = elementList.begin() + 1, itEnd = elementList.end(); it != itEnd; it++) {
Element* element = *it;
wxPoint2DDouble leftUp;
wxPoint2DDouble rightDown;
element->CalculateBoundaries(leftUp, rightDown);
- if(leftUp.m_x < leftUpCorner.m_x) leftUpCorner.m_x = leftUp.m_x;
- if(leftUp.m_y < leftUpCorner.m_y) leftUpCorner.m_y = leftUp.m_y;
- if(rightDown.m_x > rightDownCorner.m_x) rightDownCorner.m_x = rightDown.m_x;
- if(rightDown.m_y > rightDownCorner.m_y) rightDownCorner.m_y = rightDown.m_y;
+ if (leftUp.m_x < leftUpCorner.m_x) leftUpCorner.m_x = leftUp.m_x;
+ if (leftUp.m_y < leftUpCorner.m_y) leftUpCorner.m_y = leftUp.m_y;
+ if (rightDown.m_x > rightDownCorner.m_x) rightDownCorner.m_x = rightDown.m_x;
+ if (rightDown.m_y > rightDownCorner.m_y) rightDownCorner.m_y = rightDown.m_y;
}
return true;
}
@@ -1063,9 +1235,9 @@ void Workspace::Fit()
wxPoint2DDouble leftUpCorner(0, 0);
wxPoint2DDouble rightDownCorner(0, 0);
std::vector<Element*> elementList = GetElementList();
- for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) { elementList.push_back(*it); }
+ for (auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) { elementList.push_back(*it); }
- if(!GetElementsCorners(leftUpCorner, rightDownCorner, elementList)) return;
+ if (!GetElementsCorners(leftUpCorner, rightDownCorner, elementList)) return;
wxPoint2DDouble middleCoords = (leftUpCorner + rightDownCorner) / 2.0;
int width = 0.0;
@@ -1076,13 +1248,18 @@ void Workspace::Fit()
double scaleY = double(height) / (rightDownCorner.m_y - leftUpCorner.m_y);
double scale = scaleX < scaleY ? scaleX : scaleY;
- if(scale > m_camera->GetZoomMax()) scale = m_camera->GetZoomMax();
- if(scale < m_camera->GetZoomMin()) scale = m_camera->GetZoomMin();
+ if (scale > m_camera->GetZoomMax()) scale = m_camera->GetZoomMax();
+ if (scale < m_camera->GetZoomMin()) scale = m_camera->GetZoomMin();
m_camera->SetScale(scale);
m_camera->StartTranslation(middleCoords);
m_camera->SetTranslation(wxPoint2DDouble(width / 2, height / 2));
+
+ if (m_hmPlane && m_showHM) {
+ UpdateHeatMap();
+ }
+
Redraw();
}
@@ -1091,16 +1268,16 @@ void Workspace::ValidateBusesVoltages(Element* initialBus)
double nominalVoltage = static_cast<Bus*>(initialBus)->GetElectricalData().nominalVoltage;
ElectricalUnit nominalVoltageUnit = static_cast<Bus*>(initialBus)->GetElectricalData().nominalVoltageUnit;
- for(auto it = m_elementList.begin(); it != m_elementList.end(); it++) {
+ for (auto it = m_elementList.begin(); it != m_elementList.end(); it++) {
Element* child = *it;
- if(typeid(*child) == typeid(Line)) {
- if(child->GetParentList()[0] && child->GetParentList()[1]) {
+ if (typeid(*child) == typeid(Line)) {
+ if (child->GetParentList()[0] && child->GetParentList()[1]) {
BusElectricalData data1 = static_cast<Bus*>(child->GetParentList()[0])->GetElectricalData();
BusElectricalData data2 = static_cast<Bus*>(child->GetParentList()[1])->GetElectricalData();
- if(data1.nominalVoltage != data2.nominalVoltage ||
- data1.nominalVoltageUnit != data2.nominalVoltageUnit) {
+ if (data1.nominalVoltage != data2.nominalVoltage ||
+ data1.nominalVoltageUnit != data2.nominalVoltageUnit) {
data1.nominalVoltage = nominalVoltage;
data2.nominalVoltage = nominalVoltage;
data1.nominalVoltageUnit = nominalVoltageUnit;
@@ -1120,14 +1297,14 @@ void Workspace::ValidateBusesVoltages(Element* initialBus)
void Workspace::ValidateElementsVoltages()
{
- for(auto it = m_elementList.begin(); it != m_elementList.end(); it++) {
+ for (auto it = m_elementList.begin(); it != m_elementList.end(); it++) {
PowerElement* child = *it;
std::vector<double> nominalVoltage;
std::vector<ElectricalUnit> nominalVoltageUnit;
- for(int i = 0; i < (int)child->GetParentList().size(); i++) {
+ for (int i = 0; i < (int)child->GetParentList().size(); i++) {
Bus* parent = static_cast<Bus*>(child->GetParentList()[i]);
- if(parent) {
+ if (parent) {
nominalVoltage.push_back(parent->GetElectricalData().nominalVoltage);
nominalVoltageUnit.push_back(parent->GetElectricalData().nominalVoltageUnit);
}
@@ -1140,38 +1317,40 @@ bool Workspace::RunPowerFlow()
{
auto simProp = m_properties->GetSimulationPropertiesData();
double basePower = simProp.basePower;
- if(simProp.basePowerUnit == ElectricalUnit::UNIT_MVA)
+ if (simProp.basePowerUnit == ElectricalUnit::UNIT_MVA)
basePower *= 1e6;
- else if(simProp.basePowerUnit == ElectricalUnit::UNIT_kVA)
+ else if (simProp.basePowerUnit == ElectricalUnit::UNIT_kVA)
basePower *= 1e3;
PowerFlow pf(GetElementList());
bool result = false;
wxStopWatch sw;
- switch(simProp.powerFlowMethod) {
- case GAUSS_SEIDEL: {
- result = pf.RunGaussSeidel(basePower, simProp.powerFlowMaxIterations, simProp.powerFlowTolerance,
- simProp.initAngle, simProp.accFator);
- } break;
- case NEWTON_RAPHSON: {
- result = pf.RunNewtonRaphson(basePower, simProp.powerFlowMaxIterations, simProp.powerFlowTolerance,
- simProp.initAngle, simProp.newtonInertia);
- } break;
- case GAUSS_NEWTON: {
- result =
- pf.RunGaussNewton(basePower, simProp.powerFlowMaxIterations, simProp.powerFlowTolerance,
- simProp.initAngle, simProp.accFator, simProp.gaussTolerance, simProp.newtonInertia);
- } break;
+ switch (simProp.powerFlowMethod) {
+ case GAUSS_SEIDEL: {
+ result = pf.RunGaussSeidel(basePower, simProp.powerFlowMaxIterations, simProp.powerFlowTolerance,
+ simProp.initAngle, simProp.accFator);
+ } break;
+ case NEWTON_RAPHSON: {
+ result = pf.RunNewtonRaphson(basePower, simProp.powerFlowMaxIterations, simProp.powerFlowTolerance,
+ simProp.initAngle, simProp.newtonInertia);
+ } break;
+ case GAUSS_NEWTON: {
+ result =
+ pf.RunGaussNewton(basePower, simProp.powerFlowMaxIterations, simProp.powerFlowTolerance,
+ simProp.initAngle, simProp.accFator, simProp.gaussTolerance, simProp.newtonInertia);
+ } break;
}
sw.Pause();
- if(!result) {
+ if (!result) {
wxMessageDialog msgDialog(this, pf.GetErrorMessage(), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
msgDialog.ShowModal();
- } else {
+ }
+ else {
m_statusBar->SetStatusText(
wxString::Format(_("Power flow converge with %d iterations (%ld ms)"), pf.GetIterations(), sw.Time()));
}
UpdateTextElements();
+ UpdateHeatMap();
Redraw();
return result;
@@ -1181,14 +1360,14 @@ bool Workspace::UpdateTextElements()
{
bool isTexturesOK = true;
double basePower = m_properties->GetSimulationPropertiesData().basePower;
- if(m_properties->GetSimulationPropertiesData().basePowerUnit == ElectricalUnit::UNIT_kVA)
+ if (m_properties->GetSimulationPropertiesData().basePowerUnit == ElectricalUnit::UNIT_kVA)
basePower *= 1e3;
- else if(m_properties->GetSimulationPropertiesData().basePowerUnit == ElectricalUnit::UNIT_MVA)
+ else if (m_properties->GetSimulationPropertiesData().basePowerUnit == ElectricalUnit::UNIT_MVA)
basePower *= 1e6;
- for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) {
+ for (auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) {
Text* text = *it;
text->UpdateText(basePower);
- if(!text->IsGLTextOK()) isTexturesOK = false;
+ if (!text->IsGLTextOK()) isTexturesOK = false;
}
return isTexturesOK;
}
@@ -1199,23 +1378,23 @@ void Workspace::CopySelection()
std::vector<Element*> selectedElements;
// The buses need to be numerated to associate the child's parents to the copies.
int busNumber = 0;
- for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
+ for (auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
Element* element = *it;
- if(typeid(*element) == typeid(Bus)) {
+ if (typeid(*element) == typeid(Bus)) {
Bus* bus = static_cast<Bus*>(element);
auto data = bus->GetElectricalData();
data.number = busNumber;
bus->SetElectricalData(data);
busNumber++;
}
- if(element->IsSelected()) { selectedElements.push_back(element); }
+ if (element->IsSelected()) { selectedElements.push_back(element); }
}
- for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) {
+ for (auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) {
Text* text = *it;
- if(text->IsSelected()) { selectedElements.push_back(text); }
+ if (text->IsSelected()) { selectedElements.push_back(text); }
}
ElementDataObject* dataObject = new ElementDataObject(selectedElements);
- if(wxTheClipboard->Open()) {
+ if (wxTheClipboard->Open()) {
wxTheClipboard->SetData(dataObject);
wxTheClipboard->Close();
}
@@ -1223,18 +1402,19 @@ void Workspace::CopySelection()
bool Workspace::Paste()
{
- if(wxTheClipboard->Open()) {
+ if (wxTheClipboard->Open()) {
ElementDataObject dataObject;
- if(wxTheClipboard->IsSupported(dataObject.GetFormat())) {
- if(!wxTheClipboard->GetData(dataObject)) {
+ if (wxTheClipboard->IsSupported(dataObject.GetFormat())) {
+ if (!wxTheClipboard->GetData(dataObject)) {
wxMessageDialog dialog(this, _("It was not possible to paste from clipboard."), _("Error"),
- wxOK | wxCENTER | wxICON_ERROR, wxDefaultPosition);
+ wxOK | wxCENTER | wxICON_ERROR, wxDefaultPosition);
dialog.ShowModal();
wxTheClipboard->Close();
return false;
}
- } else {
+ }
+ else {
wxTheClipboard->Close();
return false;
}
@@ -1248,9 +1428,9 @@ bool Workspace::Paste()
// Paste buses (parents).
auto parentList = elementsLists->parentList;
std::vector<Bus*> pastedBusList; // To set new parents;
- for(auto it = parentList.begin(), itEnd = parentList.end(); it != itEnd; ++it) {
+ for (auto it = parentList.begin(), itEnd = parentList.end(); it != itEnd; ++it) {
Element* copy = (*it)->GetCopy();
- if(copy) {
+ if (copy) {
pastedElements.push_back(copy);
pastedBusList.push_back(static_cast<Bus*>(copy));
m_elementList.push_back(static_cast<PowerElement*>(copy));
@@ -1259,39 +1439,40 @@ bool Workspace::Paste()
// Paste other elements.
auto elementLists = elementsLists->elementList;
- for(auto it = elementLists.begin(), itEnd = elementLists.end(); it != itEnd; ++it) {
+ for (auto it = elementLists.begin(), itEnd = elementLists.end(); it != itEnd; ++it) {
Element* copy = (*it)->GetCopy();
- if(copy) {
+ if (copy) {
// Check if is text element
- if(Text* text = dynamic_cast<Text*>(copy)) {
+ if (Text* text = dynamic_cast<Text*>(copy)) {
// Check if element associated with the text exists.
bool elementExist = false;
- for(int i = 0; i < (int)m_elementList.size(); i++) {
- if(text->GetElement() == m_elementList[i]) {
+ for (int i = 0; i < (int)m_elementList.size(); i++) {
+ if (text->GetElement() == m_elementList[i]) {
elementExist = true;
break;
}
}
- if(elementExist) {
+ if (elementExist) {
pastedElements.push_back(copy);
m_textList.push_back(text);
}
- } else {
+ }
+ else {
// Change the parent if copied, otherwise remove it.
- for(unsigned int j = 0; j < copy->GetParentList().size(); j++) {
+ for (unsigned int j = 0; j < copy->GetParentList().size(); j++) {
Bus* currentParent = static_cast<Bus*>(copy->GetParentList()[j]);
- if(currentParent) {
+ if (currentParent) {
int parentID = currentParent->GetID();
bool parentCopied = false;
- for(int k = 0; k < (int)pastedBusList.size(); k++) {
+ for (int k = 0; k < (int)pastedBusList.size(); k++) {
Bus* newParent = pastedBusList[k];
- if(parentID == newParent->GetID()) {
+ if (parentID == newParent->GetID()) {
parentCopied = true;
copy->ReplaceParent(currentParent, newParent);
break;
}
}
- if(!parentCopied) copy->RemoveParent(currentParent);
+ if (!parentCopied) copy->RemoveParent(currentParent);
}
}
@@ -1302,22 +1483,22 @@ bool Workspace::Paste()
}
// Update buses childs
- for(auto it = pastedBusList.begin(), itEnd = pastedBusList.end(); it != itEnd; ++it) {
+ for (auto it = pastedBusList.begin(), itEnd = pastedBusList.end(); it != itEnd; ++it) {
Bus* bus = *it;
std::vector<Element*> childList = bus->GetChildList();
- for(auto it = childList.begin(), itEnd = childList.end(); it != itEnd; ++it) {
+ for (auto it = childList.begin(), itEnd = childList.end(); it != itEnd; ++it) {
Element* currentChild = *it;
int childID = currentChild->GetID();
bool childCopied = false;
- for(int i = 0; i < (int)pastedElements.size(); i++) {
+ for (int i = 0; i < (int)pastedElements.size(); i++) {
Element* newChild = pastedElements[i];
- if(childID == newChild->GetID()) {
+ if (childID == newChild->GetID()) {
childCopied = true;
bus->ReplaceChild(currentChild, newChild);
break;
}
}
- if(!childCopied) bus->RemoveChild(currentChild);
+ if (!childCopied) bus->RemoveChild(currentChild);
}
}
@@ -1326,18 +1507,19 @@ bool Workspace::Paste()
wxPoint2DDouble leftUpCorner, rightDownCorner;
GetElementsCorners(leftUpCorner, rightDownCorner, pastedElements);
wxPoint2DDouble startPosition = (leftUpCorner + rightDownCorner) / 2.0;
- for(auto it = pastedElements.begin(), itEnd = pastedElements.end(); it != itEnd; ++it) {
+ for (auto it = pastedElements.begin(), itEnd = pastedElements.end(); it != itEnd; ++it) {
Element* element = *it;
element->StartMove(startPosition);
element->Move(m_camera->GetMousePosition());
- for(int i = 0; i < (int)element->GetParentList().size(); i++) {
+ for (int i = 0; i < (int)element->GetParentList().size(); i++) {
Element* parent = element->GetParentList()[i];
element->MoveNode(parent, m_camera->GetMousePosition());
}
}
- } else {
+ }
+ else {
wxMessageDialog dialog(this, _("It was not possible to paste from clipboard."), _("Error"),
- wxOK | wxCENTER | wxICON_ERROR, wxDefaultPosition);
+ wxOK | wxCENTER | wxICON_ERROR, wxDefaultPosition);
dialog.ShowModal();
return false;
}
@@ -1352,25 +1534,34 @@ bool Workspace::Paste()
void Workspace::UnselectAll()
{
- for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; it++) {
+ for (auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; it++) {
Element* element = *it;
element->SetSelected(false);
}
- for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; it++) {
+ for (auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; it++) {
Text* text = *it;
text->SetSelected(false);
}
}
+void Workspace::EnableHeatMap(const bool& enable)
+{
+ m_showHM = enable;
+ if (m_showHM) {
+ UpdateHeatMap();
+ }
+ Redraw();
+}
+
void Workspace::UpdateElementsID()
{
int id = 0;
- for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
+ for (auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
Element* element = *it;
element->SetID(id);
id++;
}
- for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) {
+ for (auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) {
Text* text = *it;
text->SetID(id);
id++;
@@ -1378,16 +1569,16 @@ void Workspace::UpdateElementsID()
}
void Workspace::OnTimer(wxTimerEvent& event)
{
- if(m_tipWindow) {
+ if (m_tipWindow) {
m_tipWindow->Close();
m_tipWindow = nullptr;
}
- if(m_mode == WorkspaceMode::MODE_EDIT) {
- for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
+ if (m_mode == WorkspaceMode::MODE_EDIT) {
+ for (auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
Element* element = *it;
- if(element->Contains(m_camera->GetMousePosition())) {
+ if (element->Contains(m_camera->GetMousePosition())) {
wxString tipText = element->GetTipText();
- if(!tipText.IsEmpty()) {
+ if (!tipText.IsEmpty()) {
m_tipWindow = new wxTipWindow(this, tipText, 10000, &m_tipWindow);
// Creates a very tiny bounding rect to remove the tip on any mouse movement.
m_tipWindow->SetBoundingRect(wxRect(wxGetMousePosition(), wxSize(1, 1)));
@@ -1403,7 +1594,7 @@ void Workspace::OnTimer(wxTimerEvent& event)
void Workspace::SetTextList(std::vector<Text*> textList)
{
m_textList.clear();
- for(auto it = textList.begin(), itEnd = textList.end(); it != itEnd; ++it) m_textList.push_back(*it);
+ for (auto it = textList.begin(), itEnd = textList.end(); it != itEnd; ++it) m_textList.push_back(*it);
UpdateTextElements();
}
@@ -1411,16 +1602,27 @@ void Workspace::SetTextList(std::vector<Text*> textList)
void Workspace::SetElementList(std::vector<Element*> elementList)
{
m_elementList.clear();
- for(auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it)
+ for (auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it)
m_elementList.push_back(static_cast<PowerElement*>(*it));
}
void Workspace::OnIdle(wxIdleEvent& event)
{
- // The OpenGL element (m_glCanvas) must be completely initialized (showed) to draw properly the textures.
+ // The OpenGL element (m_glCanvas) must be completely initialized (showed) to draw properly the textures and init glew.
// TODO(?): Find other solution to text displayed wrong on opened file.
- if(m_justOpened) {
- if(UpdateTextElements()) m_justOpened = false;
+ if (m_justOpened) {
+ if (UpdateTextElements()) m_justOpened = false;
+ if (glewInit() != GLEW_OK)
+ wxMessageBox("Erro ao iniciar glew ='(");
+ else
+ {
+ // Load and create shader
+ m_basicShader = new Shader("..//data//shaders//Basic.shader");
+ m_hmLabelShader = new Shader("..//data//shaders//HMLabel.shader");
+ float limits[2] = { 1.05, 0.95 };
+ m_hmPlane = new HMPlane(m_basicShader, m_hmLabelShader, m_width, m_height, limits);
+ }
+
Redraw();
}
}
@@ -1429,8 +1631,8 @@ std::vector<Element*> Workspace::GetAllElements() const
{
std::vector<Element*> allElements;
- for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) allElements.push_back(*it);
- for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) allElements.push_back(*it);
+ for (auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) allElements.push_back(*it);
+ for (auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) allElements.push_back(*it);
return allElements;
}
@@ -1439,7 +1641,7 @@ bool Workspace::RunFault()
{
Fault fault(GetElementList());
bool result = fault.RunFaultCalculation(100e6);
- if(!result) {
+ if (!result) {
wxMessageDialog msgDialog(this, fault.GetErrorMessage(), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
msgDialog.ShowModal();
}
@@ -1453,7 +1655,7 @@ bool Workspace::RunFault()
std::vector<Element*> Workspace::GetElementList() const
{
std::vector<Element*> elementList;
- for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) elementList.push_back(*it);
+ for (auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) elementList.push_back(*it);
return elementList;
}
@@ -1461,7 +1663,7 @@ bool Workspace::RunSCPower()
{
Fault fault(GetElementList());
bool result = fault.RunSCPowerCalcutation(100e6);
- if(!result) {
+ if (!result) {
wxMessageDialog msgDialog(this, fault.GetErrorMessage(), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
msgDialog.ShowModal();
}
@@ -1481,7 +1683,7 @@ bool Workspace::RunStability()
wxStopWatch sw;
bool result = stability.RunStabilityCalculation();
sw.Pause();
- if(!result) {
+ if (!result) {
wxMessageDialog msgDialog(this, stability.GetErrorMessage(), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
msgDialog.ShowModal();
}
@@ -1494,14 +1696,14 @@ bool Workspace::RunStability()
wxMessageDialog msgDialog(
this,
wxString::Format(_("The program took %ld ms to run this system.\nDo you wish to open the stability graphics?"),
- sw.Time()),
+ sw.Time()),
_("Question"), wxYES_NO | wxCENTRE | wxICON_QUESTION);
- if(msgDialog.ShowModal() == wxID_YES) {
+ if (msgDialog.ShowModal() == wxID_YES) {
std::vector<ElementPlotData> plotDataList;
- for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
+ for (auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
PowerElement* element = *it;
ElementPlotData plotData;
- if(element->GetPlotData(plotData)) plotDataList.push_back(plotData);
+ if (element->GetPlotData(plotData)) plotDataList.push_back(plotData);
}
ElementPlotData plotData;
@@ -1529,25 +1731,28 @@ bool Workspace::RunStaticStudies()
pfStatus = RunPowerFlow();
- if(m_properties->GetSimulationPropertiesData().faultAfterPowerFlow) {
- if(pfStatus) faultStatus = RunFault();
- } else {
+ if (m_properties->GetSimulationPropertiesData().faultAfterPowerFlow) {
+ if (pfStatus) faultStatus = RunFault();
+ }
+ else {
faultStatus = true;
}
- if(m_properties->GetSimulationPropertiesData().scPowerAfterPowerFlow) {
- if(pfStatus) scStatus = RunSCPower();
- } else {
+ if (m_properties->GetSimulationPropertiesData().scPowerAfterPowerFlow) {
+ if (pfStatus) scStatus = RunSCPower();
+ }
+ else {
scStatus = true;
}
- if(m_properties->GetSimulationPropertiesData().harmDistortionAfterPowerFlow) {
- if(pfStatus) harmStatus = RunHarmonicDistortion();
- } else {
+ if (m_properties->GetSimulationPropertiesData().harmDistortionAfterPowerFlow) {
+ if (pfStatus) harmStatus = RunHarmonicDistortion();
+ }
+ else {
harmStatus = true;
}
- if(pfStatus && faultStatus && scStatus && harmStatus) return true;
+ if (pfStatus && faultStatus && scStatus && harmStatus) return true;
return false;
}
@@ -1556,11 +1761,11 @@ bool Workspace::RunHarmonicDistortion()
{
auto simProp = m_properties->GetSimulationPropertiesData();
double basePower = simProp.basePower;
- if(simProp.basePowerUnit == ElectricalUnit::UNIT_MVA)
+ if (simProp.basePowerUnit == ElectricalUnit::UNIT_MVA)
basePower *= 1e6;
- else if(simProp.basePowerUnit == ElectricalUnit::UNIT_kVA)
+ else if (simProp.basePowerUnit == ElectricalUnit::UNIT_kVA)
basePower *= 1e3;
- if(!RunPowerFlow()) return false;
+ if (!RunPowerFlow()) return false;
PowerQuality pq(GetElementList());
bool result = pq.CalculateDistortions(basePower);
@@ -1574,42 +1779,43 @@ bool Workspace::RunFrequencyResponse()
{
// Get bus list
std::vector<Bus*> busList;
- for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
- if(Bus* bus = dynamic_cast<Bus*>(*it)) { busList.push_back(bus); }
+ for (auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
+ if (Bus* bus = dynamic_cast<Bus*>(*it)) { busList.push_back(bus); }
}
auto data = m_properties->GetFreqRespData();
FrequencyResponseForm frForm(this, busList, data.injBusNumber, data.initFreq, data.finalFreq, data.stepFreq);
- if(frForm.ShowModal() == wxID_OK) {
+ if (frForm.ShowModal() == wxID_OK) {
data.initFreq = frForm.GetInitFreq();
data.finalFreq = frForm.GetEndFreq();
data.stepFreq = frForm.GetStepFreq();
data.injBusNumber = frForm.GetInjBusNumber();
m_properties->SetFreqRespData(data);
- } else
+ }
+ else
return false;
auto simProp = m_properties->GetSimulationPropertiesData();
double basePower = simProp.basePower;
- if(simProp.basePowerUnit == ElectricalUnit::UNIT_MVA)
+ if (simProp.basePowerUnit == ElectricalUnit::UNIT_MVA)
basePower *= 1e6;
- else if(simProp.basePowerUnit == ElectricalUnit::UNIT_kVA)
+ else if (simProp.basePowerUnit == ElectricalUnit::UNIT_kVA)
basePower *= 1e3;
PowerQuality pq(GetElementList());
bool result = pq.CalculateFrequencyResponse(simProp.stabilityFrequency, data.initFreq, data.finalFreq,
- data.stepFreq, data.injBusNumber, basePower);
+ data.stepFreq, data.injBusNumber, basePower);
wxMessageDialog msgDialog(
this, wxString::Format(_("Calculations done.\nDo you wish to open the frequency response graphics?")),
_("Question"), wxYES_NO | wxCENTRE | wxICON_QUESTION);
- if(msgDialog.ShowModal() == wxID_YES) {
+ if (msgDialog.ShowModal() == wxID_YES) {
std::vector<ElementPlotData> plotDataList;
- for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
+ for (auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
PowerElement* element = *it;
ElementPlotData plotData;
- if(element->GetPlotData(plotData, PlotStudy::FREQRESPONSE)) plotDataList.push_back(plotData);
+ if (element->GetPlotData(plotData, PlotStudy::FREQRESPONSE)) plotDataList.push_back(plotData);
}
ChartView* cView = new ChartView(this, plotDataList, pq.GetFrequencies());
@@ -1621,3 +1827,24 @@ bool Workspace::RunFrequencyResponse()
return result;
}
+void Workspace::OnResize(wxSizeEvent& event)
+{
+ m_width = static_cast<float>(m_glCanvas->GetSize().x) - 1.0f;
+ m_height = static_cast<float>(m_glCanvas->GetSize().y) - 1.0f;
+
+ if (m_hmPlane && m_showHM) {
+ m_hmPlane->Resize(m_width, m_height);
+ m_showHMTimer = true;
+ m_timerHeatMap->Start();
+ }
+
+ event.Skip();
+}
+void Workspace::OnHeatMapTime(wxTimerEvent& event)
+{
+ if (m_showHMTimer) {
+ UpdateHeatMap();
+ Redraw();
+ m_showHMTimer = false;
+ }
+}