summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Project/Bus.cpp67
-rw-r--r--Project/Bus.h3
-rw-r--r--Project/BusForm.cpp32
-rw-r--r--Project/Capacitor.cpp74
-rw-r--r--Project/Capacitor.h3
-rw-r--r--Project/ConnectionLine.cpp2
-rw-r--r--Project/Constant.cpp2
-rw-r--r--Project/ControlEditor.cpp4
-rw-r--r--Project/ControlEditor.h3
-rw-r--r--Project/ControlElement.cpp4
-rw-r--r--Project/ControlElement.h4
-rw-r--r--Project/ControlElementSolver.cpp6
-rw-r--r--Project/DataReport.cpp12
-rw-r--r--Project/Divider.cpp2
-rw-r--r--Project/ElectricCalculation.cpp48
-rw-r--r--Project/Electromechanical.cpp30
-rw-r--r--Project/Element.cpp52
-rw-r--r--Project/Element.h37
-rw-r--r--Project/ElementFormBase.h2
-rw-r--r--Project/Exponential.cpp4
-rw-r--r--Project/Fault.cpp30
-rw-r--r--Project/Gain.cpp4
-rw-r--r--Project/GeneralPropertiesForm.cpp4
-rw-r--r--Project/GeneratorStabForm.cpp7
-rw-r--r--Project/GeneratorStabForm.h5
-rw-r--r--Project/GraphAutoLayout.cpp2
-rw-r--r--Project/HarmCurrentForm.cpp12
-rw-r--r--Project/IOControl.cpp32
-rw-r--r--Project/IOControl.h2
-rw-r--r--Project/IndMotor.cpp11
-rw-r--r--Project/IndMotor.h1
-rw-r--r--Project/IndMotorForm.cpp40
-rw-r--r--Project/Inductor.cpp89
-rw-r--r--Project/Inductor.h3
-rw-r--r--Project/Limiter.cpp4
-rw-r--r--Project/Line.cpp98
-rw-r--r--Project/Line.h11
-rw-r--r--Project/LineForm.cpp52
-rw-r--r--Project/Load.cpp69
-rw-r--r--Project/Load.h3
-rw-r--r--Project/Machines.cpp60
-rw-r--r--Project/Machines.h2
-rw-r--r--Project/MainFrame.cpp44
-rw-r--r--Project/MainFrameBase.cpp2
-rw-r--r--Project/MathExpression.cpp8
-rw-r--r--Project/MathOperation.cpp6
-rw-r--r--Project/Multiplier.cpp2
-rw-r--r--Project/OpenGLText.cpp38
-rw-r--r--Project/OpenGLText.h4
-rw-r--r--Project/PowerElement.cpp40
-rw-r--r--Project/PowerElement.h11
-rw-r--r--Project/PowerQuality.cpp2
-rw-r--r--Project/Project.project2
-rw-r--r--Project/PropertiesData.h5
-rw-r--r--Project/PropertiesForm.wxcp2
-rw-r--r--Project/RateLimiter.cpp4
-rw-r--r--Project/ReactiveShuntElementForm.cpp32
-rw-r--r--Project/Shunt.cpp24
-rw-r--r--Project/Shunt.h1
-rw-r--r--Project/SimulationsSettingsForm.cpp16
-rw-r--r--Project/StabilityEventList.cpp2
-rw-r--r--Project/Sum.cpp10
-rw-r--r--Project/SwitchingForm.cpp6
-rw-r--r--Project/SyncGenerator.cpp13
-rw-r--r--Project/SyncGenerator.h1
-rw-r--r--Project/SyncMachineForm.cpp5
-rw-r--r--Project/SyncMachineForm.h5
-rw-r--r--Project/SyncMotor.cpp4
-rw-r--r--Project/SyncMotor.h1
-rw-r--r--Project/Text.cpp36
-rw-r--r--Project/Text.h2
-rw-r--r--Project/TransferFunction.cpp4
-rw-r--r--Project/Transformer.cpp86
-rw-r--r--Project/Transformer.h1
-rw-r--r--Project/TransformerForm.cpp36
-rw-r--r--Project/Workspace.cpp8
-rw-r--r--Project/Workspace.h40
-rw-r--r--Project/WorkspaceDC.cpp136
-rw-r--r--Project/WorkspaceDC.h21
-rw-r--r--Project/compile_flags.txt2
-rw-r--r--Project/main.cpp10
-rw-r--r--Project/win_resources.apsbin0 -> 208832 bytes
82 files changed, 1284 insertions, 320 deletions
diff --git a/Project/Bus.cpp b/Project/Bus.cpp
index 5c8c190..d3465cc 100644
--- a/Project/Bus.cpp
+++ b/Project/Bus.cpp
@@ -101,6 +101,73 @@ void Bus::Draw(wxPoint2DDouble translation, double scale) const
}
}
+void Bus::DrawDC(wxPoint2DDouble translation, double scale, wxGraphicsContext* gc) const
+{
+ wxPoint2DDouble gcPosition = m_position - wxPoint2DDouble(m_width / 2.0, m_height / 2.0);
+ wxGraphicsMatrix identityMatrix = gc->GetTransform();
+ identityMatrix.Set(); // Set to identity
+
+ gc->SetPen(*wxTRANSPARENT_PEN);
+
+ // Draw selection (layer 1)
+ if (m_selected) {
+ // If the object is selected, the matrix is reset to remove scale effects applied to it, thus keeping the
+ // edges with fixed sizes for all zoom levels.
+ gc->PushState();
+ gc->SetTransform(identityMatrix);
+ // The matrix was reset, so we must use screen coordinates (WorldToScreen).
+ wxPoint2DDouble screenPt = WorldToScreen(translation, scale);
+ gc->Translate(screenPt.m_x, screenPt.m_y);
+ gc->Rotate(wxDegToRad(m_angle));
+ gc->Translate(-screenPt.m_x, -screenPt.m_y);
+
+ gc->SetBrush(wxBrush(m_selectionColour.GetDcRGBA()));
+
+ wxPoint2DDouble pts[4] = { WorldToScreen(translation, scale, -(m_width / 2.0), -(m_height / 2.0)) -
+ wxPoint2DDouble(m_borderSize, m_borderSize),
+ WorldToScreen(translation, scale, -(m_width / 2.0), (m_height / 2.0)) -
+ wxPoint2DDouble(m_borderSize, -m_borderSize),
+ WorldToScreen(translation, scale, (m_width / 2.0), (m_height / 2.0)) -
+ wxPoint2DDouble(-m_borderSize, -m_borderSize),
+ WorldToScreen(translation, scale, (m_width / 2.0), -(m_height / 2.0)) -
+ wxPoint2DDouble(-m_borderSize, m_borderSize) };
+ gc->DrawLines(4, pts);
+ gc->PopState();
+ }
+
+ gc->PushState();
+ gc->Translate(m_position.m_x, m_position.m_y);
+ gc->Rotate(wxDegToRad(m_angle));
+ gc->Translate(-m_position.m_x, -m_position.m_y);
+
+ if (m_dynEvent)
+ gc->SetBrush(wxBrush(m_dynamicEventColour.GetDcRGBA()));
+ else
+ gc->SetBrush(wxBrush(m_busColour.GetDcRGBA()));
+
+ gc->DrawRectangle(gcPosition.m_x, gcPosition.m_y, m_width, m_height);
+
+ gc->PopState();
+
+ // Draw pickbox (layer 3)
+ if (m_showPickbox) {
+ gc->PushState();
+ gc->SetTransform(identityMatrix);
+
+ wxPoint2DDouble screenPt = WorldToScreen(translation, scale);
+ gc->Translate(screenPt.m_x, screenPt.m_y);
+ gc->Rotate(wxDegToRad(m_angle));
+ gc->Translate(-screenPt.m_x, -screenPt.m_y);
+
+ wxPoint2DDouble pbPosition[2] = { WorldToScreen(translation, scale, m_width / 2.0) - wxPoint2DDouble(4, 4),
+ WorldToScreen(translation, scale, -m_width / 2.0) - wxPoint2DDouble(4, 4)};
+ DrawDCPickbox(pbPosition[0], gc);
+ DrawDCPickbox(pbPosition[1], gc);
+
+ gc->PopState();
+ }
+}
+
bool Bus::Contains(wxPoint2DDouble position) const
{
wxPoint2DDouble ptR = RotateAtPosition(position, -m_angle);
diff --git a/Project/Bus.h b/Project/Bus.h
index b01a315..0b4bb53 100644
--- a/Project/Bus.h
+++ b/Project/Bus.h
@@ -86,6 +86,7 @@ class Bus : public PowerElement
virtual bool Contains(wxPoint2DDouble position) const;
virtual bool Intersects(wxRect2DDouble rect) const;
virtual void Draw(wxPoint2DDouble translation, double scale) const;
+ virtual void DrawDC(wxPoint2DDouble translation, double scale, wxGraphicsContext* gc) const;
virtual void Rotate(bool clockwise = true);
virtual wxCursor GetBestPickboxCursor() const;
virtual void MovePickbox(wxPoint2DDouble position);
@@ -93,7 +94,7 @@ class Bus : public PowerElement
virtual bool GetContextMenu(wxMenu& menu);
virtual wxString GetTipText() const;
virtual BusElectricalData GetElectricalData() const { return m_electricalData; }
- virtual void SetElectricalData(BusElectricalData electricalData) { m_electricalData = electricalData; }
+ virtual void SetElectricalData(const BusElectricalData& electricalData) { m_electricalData = electricalData; }
virtual bool ShowForm(wxWindow* parent, Element* element);
virtual bool GetPlotData(ElementPlotData& plotData, PlotStudy study = STABILITY);
diff --git a/Project/BusForm.cpp b/Project/BusForm.cpp
index 9f942f3..d97c235 100644
--- a/Project/BusForm.cpp
+++ b/Project/BusForm.cpp
@@ -33,7 +33,7 @@ BusForm::BusForm(wxWindow* parent, Bus* bus) : BusFormBase(parent)
m_textCtrlName->SetValue(bus->GetElectricalData().name);
m_textCtrlNomVoltage->SetValue(bus->StringFromDouble(bus->GetElectricalData().nominalVoltage));
- if(bus->GetElectricalData().nominalVoltageUnit == UNIT_V)
+ if(bus->GetElectricalData().nominalVoltageUnit == ElectricalUnit::UNIT_V)
m_choiceNomVoltage->SetSelection(0);
else
m_choiceNomVoltage->SetSelection(1);
@@ -45,29 +45,29 @@ BusForm::BusForm(wxWindow* parent, Bus* bus) : BusFormBase(parent)
m_checkBoxFault->SetValue(bus->GetElectricalData().hasFault);
switch(bus->GetElectricalData().faultType) {
- case FAULT_THREEPHASE: {
+ case FaultData::FAULT_THREEPHASE: {
m_choiceFaultType->SetSelection(0);
} break;
- case FAULT_2LINE: {
+ case FaultData::FAULT_2LINE: {
m_choiceFaultType->SetSelection(1);
} break;
- case FAULT_2LINE_GROUND: {
+ case FaultData::FAULT_2LINE_GROUND: {
m_choiceFaultType->SetSelection(2);
} break;
- case FAULT_LINE_GROUND: {
+ case FaultData::FAULT_LINE_GROUND: {
m_choiceFaultType->SetSelection(3);
} break;
default:
break;
}
switch(bus->GetElectricalData().faultLocation) {
- case FAULT_LINE_A: {
+ case FaultData::FAULT_LINE_A: {
m_choiceFaultPlace->SetSelection(0);
} break;
- case FAULT_LINE_B: {
+ case FaultData::FAULT_LINE_B: {
m_choiceFaultPlace->SetSelection(1);
} break;
- case FAULT_LINE_C: {
+ case FaultData::FAULT_LINE_C: {
m_choiceFaultPlace->SetSelection(2);
} break;
default:
@@ -99,7 +99,7 @@ void BusForm::OnButtonOKClick(wxCommandEvent& event)
if(!m_bus->DoubleFromString(m_parent, m_textCtrlNomVoltage->GetValue(), data.nominalVoltage,
_("Value entered incorrectly in the field \"Rated voltage\".")))
return;
- data.nominalVoltageUnit = m_choiceNomVoltage->GetSelection() == 0 ? UNIT_V : UNIT_kV;
+ data.nominalVoltageUnit = m_choiceNomVoltage->GetSelection() == 0 ? ElectricalUnit::UNIT_V : ElectricalUnit::UNIT_kV;
data.isVoltageControlled = m_checkBoxCtrlVoltage->GetValue();
if(data.isVoltageControlled) {
if(!m_bus->DoubleFromString(m_parent, m_textCtrlCtrlVoltage->GetValue(), data.controlledVoltage,
@@ -112,28 +112,28 @@ void BusForm::OnButtonOKClick(wxCommandEvent& event)
data.hasFault = m_checkBoxFault->GetValue();
switch(m_choiceFaultType->GetSelection()) {
case 0: {
- data.faultType = FAULT_THREEPHASE;
+ data.faultType = FaultData::FAULT_THREEPHASE;
} break;
case 1: {
- data.faultType = FAULT_2LINE;
+ data.faultType = FaultData::FAULT_2LINE;
} break;
case 2: {
- data.faultType = FAULT_2LINE_GROUND;
+ data.faultType = FaultData::FAULT_2LINE_GROUND;
} break;
case 3: {
- data.faultType = FAULT_LINE_GROUND;
+ data.faultType = FaultData::FAULT_LINE_GROUND;
} break;
}
switch(m_choiceFaultPlace->GetSelection()) {
case 0: {
- data.faultLocation = FAULT_LINE_A;
+ data.faultLocation = FaultData::FAULT_LINE_A;
} break;
case 1: {
- data.faultLocation = FAULT_LINE_B;
+ data.faultLocation = FaultData::FAULT_LINE_B;
} break;
case 2: {
- data.faultLocation = FAULT_LINE_C;
+ data.faultLocation = FaultData::FAULT_LINE_C;
} break;
}
diff --git a/Project/Capacitor.cpp b/Project/Capacitor.cpp
index 76dc3fd..f7ae32a 100644
--- a/Project/Capacitor.cpp
+++ b/Project/Capacitor.cpp
@@ -112,6 +112,80 @@ void Capacitor::Draw(wxPoint2DDouble translation, double scale) const
}
}
+void Capacitor::DrawDC(wxPoint2DDouble translation, double scale, wxGraphicsContext* gc) const
+{
+ OpenGLColour elementColour;
+ if (m_online) {
+ if (m_dynEvent)
+ elementColour = m_dynamicEventColour;
+ else
+ elementColour = m_onlineElementColour;
+ }
+ else
+ elementColour = m_offlineElementColour;
+
+ if (m_inserted) {
+ std::vector<wxPoint2DDouble> capPts;
+ capPts.push_back(wxPoint2DDouble(m_position.m_x - m_width / 2.0, m_position.m_y - m_height / 2.0));
+ capPts.push_back(wxPoint2DDouble(m_position.m_x + m_width / 2.0, m_position.m_y - m_height / 2.0));
+ capPts.push_back(wxPoint2DDouble(m_position.m_x - m_width / 2.0, m_position.m_y - m_height / 2.0 + 10.0));
+ capPts.push_back(wxPoint2DDouble(m_position.m_x + m_width / 2.0, m_position.m_y - m_height / 2.0 + 10.0));
+
+ if (m_selected) {
+ gc->SetPen(wxPen(wxColour(m_selectionColour.GetDcRGBA()), 2 + m_borderSize * 2.0));
+ gc->SetBrush(*wxTRANSPARENT_BRUSH);
+
+ gc->DrawLines(m_pointList.size(), &m_pointList[0]);
+
+ // Push the current matrix on stack.
+ gc->PushState();
+ // Rotate the matrix around the object position.
+ gc->Translate(m_position.m_x, m_position.m_y);
+ gc->Rotate(wxDegToRad(m_angle));
+ gc->Translate(-m_position.m_x, -m_position.m_y);
+
+ gc->DrawLines(2, &capPts[0]);
+ gc->DrawLines(2, &capPts[2]);
+
+ DrawDCGround(m_position + wxPoint2DDouble(0, -m_height / 2.0 + 10.0), gc);
+
+ gc->PopState();
+
+ // Draw node selection.
+ gc->SetPen(*wxTRANSPARENT_PEN);
+ gc->SetBrush(wxBrush(wxColour(m_selectionColour.GetDcRGBA())));
+ DrawDCCircle(m_pointList[0], 5.0 + m_borderSize / scale, 10, gc);
+ }
+ // Draw Capacitor (layer 2).
+ // Draw node.
+ gc->SetPen(*wxTRANSPARENT_PEN);
+ gc->SetBrush(wxBrush(wxColour(elementColour.GetDcRGBA())));
+ DrawDCCircle(m_pointList[0], 5.0, 10, gc);
+
+ gc->SetPen(wxPen(wxColour(elementColour.GetDcRGBA()), 2));
+ gc->SetBrush(*wxTRANSPARENT_BRUSH);
+ gc->DrawLines(m_pointList.size(), &m_pointList[0]);
+
+ DrawDCSwitches(gc);
+
+ // Push the current matrix on stack.
+ gc->PushState();
+ // Rotate the matrix around the object position.
+ gc->Translate(m_position.m_x, m_position.m_y);
+ gc->Rotate(wxDegToRad(m_angle));
+ gc->Translate(-m_position.m_x, -m_position.m_y);
+
+ gc->SetPen(wxPen(wxColour(elementColour.GetDcRGBA()), 2));
+ gc->SetBrush(*wxTRANSPARENT_BRUSH);
+ gc->DrawLines(2, &capPts[0]);
+ gc->DrawLines(2, &capPts[2]);
+
+ DrawDCGround(m_position + wxPoint2DDouble(0, -m_height / 2.0 + 10.0), gc);
+
+ gc->PopState();
+ }
+}
+
void Capacitor::Rotate(bool clockwise)
{
double rotAngle = m_rotationAngle;
diff --git a/Project/Capacitor.h b/Project/Capacitor.h
index 8cf1c64..c98070d 100644
--- a/Project/Capacitor.h
+++ b/Project/Capacitor.h
@@ -25,7 +25,7 @@ class ReactiveShuntElementForm;
struct CapacitorElectricalData {
wxString name;
double reactivePower = 100.0;
- ElectricalUnit reactivePowerUnit = UNIT_MVAr;
+ ElectricalUnit reactivePowerUnit = ElectricalUnit::UNIT_MVAr;
};
/**
@@ -45,6 +45,7 @@ class Capacitor : public Shunt
virtual Element* GetCopy();
virtual bool AddParent(Element* parent, wxPoint2DDouble position);
virtual void Draw(wxPoint2DDouble translation, double scale) const;
+ virtual void DrawDC(wxPoint2DDouble translation, double scale, wxGraphicsContext* gc) const;
virtual bool Contains(wxPoint2DDouble position) const;
virtual bool Intersects(wxRect2DDouble rect) const;
virtual void Rotate(bool clockwise = true);
diff --git a/Project/ConnectionLine.cpp b/Project/ConnectionLine.cpp
index 80752da..1a858a4 100644
--- a/Project/ConnectionLine.cpp
+++ b/Project/ConnectionLine.cpp
@@ -166,7 +166,7 @@ void ConnectionLine::StartMove(wxPoint2DDouble position)
wxPoint2DDouble ConnectionLine::GetMidPoint() const { return ((m_pointList[2] + m_pointList[3]) / 2.0); }
bool ConnectionLine::SetParentLine(ConnectionLine* parent)
{
- if(m_nodeList[0]->GetNodeType() != Node::NODE_IN) return false;
+ if(m_nodeList[0]->GetNodeType() != Node::NodeType::NODE_IN) return false;
if(!parent) return false;
m_type = ELEMENT_LINE;
diff --git a/Project/Constant.cpp b/Project/Constant.cpp
index c81a0cf..40d6c2d 100644
--- a/Project/Constant.cpp
+++ b/Project/Constant.cpp
@@ -22,7 +22,7 @@ Constant::Constant(int id) : ControlElement(id)
{
SetValue(m_value);
m_angle = 180.0;
- Node* nodeOut = new Node(m_position + wxPoint2DDouble(m_width / 2, 0), Node::NODE_OUT, m_borderSize);
+ Node* nodeOut = new Node(m_position + wxPoint2DDouble(m_width / 2, 0), Node::NodeType::NODE_OUT, m_borderSize);
nodeOut->SetAngle(180.0);
nodeOut->StartMove(m_position);
m_nodeList.push_back(nodeOut);
diff --git a/Project/ControlEditor.cpp b/Project/ControlEditor.cpp
index cdd172e..709fb25 100644
--- a/Project/ControlEditor.cpp
+++ b/Project/ControlEditor.cpp
@@ -131,10 +131,10 @@ void ControlElementButton::OnLeftClickUp(wxMouseEvent& event)
event.Skip();
}
-ControlEditor::ControlEditor(wxWindow* parent, int ioflags) : ControlEditorBase(parent)
+ControlEditor::ControlEditor(wxWindow* parent, wxGLContext* sharedGLContext, int ioflags) : ControlEditorBase(parent)
{
BuildControlElementPanel();
- m_glContext = new wxGLContext(m_glCanvas);
+ m_glContext = new wxGLContext(m_glCanvas, sharedGLContext);
m_glContext->SetCurrent(*m_glCanvas);
m_camera = new Camera();
m_selectionRect = wxRect2DDouble(0, 0, 0, 0);
diff --git a/Project/ControlEditor.h b/Project/ControlEditor.h
index f77f350..2aed0e9 100644
--- a/Project/ControlEditor.h
+++ b/Project/ControlEditor.h
@@ -23,6 +23,7 @@
#include <wx/dcclient.h>
#include <wx/dcscreen.h>
#include <wx/graphics.h>
+#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
@@ -119,7 +120,7 @@ class ControlEditor : public ControlEditorBase
MODE_DRAG_PASTE
};
- ControlEditor(wxWindow* parent,
+ ControlEditor(wxWindow* parent, wxGLContext* sharedGLContext,
int ioflags = IOControl::IN_TERMINAL_VOLTAGE | IOControl::IN_VELOCITY | IOControl::OUT_FIELD_VOLTAGE |
IOControl::OUT_MEC_POWER);
virtual ~ControlEditor();
diff --git a/Project/ControlElement.cpp b/Project/ControlElement.cpp
index 5e8a80d..2af9a6f 100644
--- a/Project/ControlElement.cpp
+++ b/Project/ControlElement.cpp
@@ -108,7 +108,7 @@ void ControlElement::DrawNodes() const
for(auto it = m_nodeList.begin(), itEnd = m_nodeList.end(); it != itEnd; ++it) {
Node* node = *it;
DrawCircle(node->GetPosition(), node->GetRadius(), 10, GL_POLYGON);
- if(node->GetNodeType() == Node::NODE_IN) { DrawTriangle(node->GetInTrianglePts()); }
+ if(node->GetNodeType() == Node::NodeType::NODE_IN) { DrawTriangle(node->GetInTrianglePts()); }
}
}
@@ -167,7 +167,7 @@ void ControlElement::SaveControlNodes(rapidxml::xml_document<>& doc, rapidxml::x
auto angle = XMLParser::AppendNode(doc, nodeN, "Angle");
XMLParser::SetNodeValue(doc, angle, node->GetAngle());
auto nodeType = XMLParser::AppendNode(doc, nodeN, "Type");
- XMLParser::SetNodeValue(doc, nodeType, node->GetNodeType());
+ XMLParser::SetNodeValue(doc, nodeType, static_cast<int>(node->GetNodeType()));
id++;
}
}
diff --git a/Project/ControlElement.h b/Project/ControlElement.h
index 51f8df3..30e7d90 100644
--- a/Project/ControlElement.h
+++ b/Project/ControlElement.h
@@ -30,9 +30,9 @@
class Node
{
public:
- enum NodeType { NODE_IN = 0, NODE_OUT };
+ enum class NodeType { NODE_IN = 0, NODE_OUT };
- Node(wxPoint2DDouble position = wxPoint2DDouble(0, 0), NodeType nodeType = NODE_IN, double borderSize = 0.0);
+ Node(wxPoint2DDouble position = wxPoint2DDouble(0, 0), NodeType nodeType = NodeType::NODE_IN, double borderSize = 0.0);
~Node();
wxRect2DDouble GetRect() const { return m_rect; }
diff --git a/Project/ControlElementSolver.cpp b/Project/ControlElementSolver.cpp
index 7849313..037da84 100644
--- a/Project/ControlElementSolver.cpp
+++ b/Project/ControlElementSolver.cpp
@@ -62,10 +62,10 @@ void ControlElementSolver::Initialize(wxWindow* parent, double timeStep, double
haveInput = haveOutput = false;
for(auto it = ioList.begin(), itEnd = ioList.end(); it != itEnd; ++it) {
IOControl* io = *it;
- if(io->GetType() == Node::NODE_OUT && !haveInput) {
+ if(io->GetType() == Node::NodeType::NODE_OUT && !haveInput) {
m_inputControl = io;
haveInput = true;
- } else if(io->GetType() == Node::NODE_IN) {
+ } else if(io->GetType() == Node::NodeType::NODE_IN) {
m_outputControl = io;
haveOutput = true;
}
@@ -329,7 +329,7 @@ ConnectionLine* ControlElementSolver::SolveNextElement(ConnectionLine* currentLi
auto nodeList = element->GetNodeList();
for(auto itN = nodeList.begin(), itNEnd = nodeList.end(); itN != itNEnd; ++itN) {
Node* node = *itN;
- if(node->GetNodeType() == Node::NODE_OUT) outNode = node;
+ if(node->GetNodeType() == Node::NodeType::NODE_OUT) outNode = node;
}
if(!outNode) return NULL;
diff --git a/Project/DataReport.cpp b/Project/DataReport.cpp
index 1511079..49572b7 100644
--- a/Project/DataReport.cpp
+++ b/Project/DataReport.cpp
@@ -335,10 +335,10 @@ void DataReport::FillValues(GridSelection gridToFill)
double basePower = m_workspace->GetProperties()->GetSimulationPropertiesData().basePower;
switch(m_workspace->GetProperties()->GetSimulationPropertiesData().basePowerUnit) {
- case UNIT_kVA: {
+ case ElectricalUnit::UNIT_kVA: {
basePower *= 1e3;
} break;
- case UNIT_MVA: {
+ case ElectricalUnit::UNIT_MVA: {
basePower *= 1e6;
} break;
default:
@@ -485,7 +485,7 @@ void DataReport::FillValues(GridSelection gridToFill)
auto data = bus->GetElectricalData();
double vb = std::abs(data.nominalVoltage);
- if(data.nominalVoltageUnit == UNIT_kV) vb *= 1e3;
+ if(data.nominalVoltageUnit == ElectricalUnit::UNIT_kV) vb *= 1e3;
double kVoltage = 1.0;
if(m_gridPFBuses->GetCellValue(0, 2) == m_voltageChoices[1])
kVoltage = vb;
@@ -523,7 +523,7 @@ void DataReport::FillValues(GridSelection gridToFill)
auto data = line->GetPUElectricalData(basePower);
double vb = data.nominalVoltage;
- if(data.nominalVoltageUnit == UNIT_kV) vb *= 1e3;
+ if(data.nominalVoltageUnit == ElectricalUnit::UNIT_kV) vb *= 1e3;
double zb = (vb * vb) / basePower;
wxString busName1 = "-";
@@ -567,10 +567,10 @@ void DataReport::FillValues(GridSelection gridToFill)
double vb = 0.0;
if(data.baseVoltage == 0) {
vb = data.primaryNominalVoltage;
- if(data.primaryNominalVoltageUnit == UNIT_kV) vb *= 1e3;
+ if(data.primaryNominalVoltageUnit == ElectricalUnit::UNIT_kV) vb *= 1e3;
} else {
vb = data.secondaryNominalVoltage;
- if(data.secondaryNominalVoltageUnit == UNIT_kV) vb *= 1e3;
+ if(data.secondaryNominalVoltageUnit == ElectricalUnit::UNIT_kV) vb *= 1e3;
}
double zb = (vb * vb) / basePower;
diff --git a/Project/Divider.cpp b/Project/Divider.cpp
index e723de3..1becac4 100644
--- a/Project/Divider.cpp
+++ b/Project/Divider.cpp
@@ -39,7 +39,7 @@ bool Divider::Solve(double* input, double timeStep)
std::vector<double> inputVector;
for(auto itN = m_nodeList.begin(), itNEnd = m_nodeList.end(); itN != itNEnd; ++itN) {
Node* node = *itN;
- if(node->GetNodeType() != Node::NODE_OUT) {
+ if(node->GetNodeType() != Node::NodeType::NODE_OUT) {
if(!node->IsConnected()) {
inputVector.push_back(0.0);
} else {
diff --git a/Project/ElectricCalculation.cpp b/Project/ElectricCalculation.cpp
index a2db413..24c92ba 100644
--- a/Project/ElectricCalculation.cpp
+++ b/Project/ElectricCalculation.cpp
@@ -352,9 +352,9 @@ void ElectricCalculation::UpdateElementsPowerFlow(std::vector<std::complex<doubl
data.powerFlow[1] = v2 * std::conj(data.current[1]);
if(data.powerFlow[0].real() > data.powerFlow[1].real())
- line->SetPowerFlowDirection(PF_BUS1_TO_BUS2);
+ line->SetPowerFlowDirection(PowerFlowDirection::PF_BUS1_TO_BUS2);
else
- line->SetPowerFlowDirection(PF_BUS2_TO_BUS1);
+ line->SetPowerFlowDirection(PowerFlowDirection::PF_BUS2_TO_BUS1);
line->SetElectricalData(data);
}
@@ -389,9 +389,9 @@ void ElectricCalculation::UpdateElementsPowerFlow(std::vector<std::complex<doubl
data.powerFlow[1] = v2 * std::conj(data.current[1]);
if(data.powerFlow[0].real() > data.powerFlow[1].real())
- transformer->SetPowerFlowDirection(PF_BUS1_TO_BUS2);
+ transformer->SetPowerFlowDirection(PowerFlowDirection::PF_BUS1_TO_BUS2);
else
- transformer->SetPowerFlowDirection(PF_BUS2_TO_BUS1);
+ transformer->SetPowerFlowDirection(PowerFlowDirection::PF_BUS2_TO_BUS1);
transformer->SetElectricaData(data);
}
@@ -405,13 +405,13 @@ void ElectricCalculation::UpdateElementsPowerFlow(std::vector<std::complex<doubl
double reactivePower = data.qValue * systemPowerBase;
switch(data.reactivePowerUnit) {
- case UNIT_PU: {
+ case ElectricalUnit::UNIT_PU: {
reactivePower /= systemPowerBase;
} break;
- case UNIT_kVAr: {
+ case ElectricalUnit::UNIT_kVAr: {
reactivePower /= 1e3;
} break;
- case UNIT_MVAr: {
+ case ElectricalUnit::UNIT_MVAr: {
reactivePower /= 1e6;
} break;
default:
@@ -455,9 +455,9 @@ void ElectricCalculation::UpdateElementsPowerFlow(std::vector<std::complex<doubl
loadPower += std::complex<double>(childData.activePower, childData.reactivePower);
if(childData.activePower >= 0.0)
- load->SetPowerFlowDirection(PF_TO_ELEMENT);
+ load->SetPowerFlowDirection(PowerFlowDirection::PF_TO_ELEMENT);
else
- load->SetPowerFlowDirection(PF_TO_BUS);
+ load->SetPowerFlowDirection(PowerFlowDirection::PF_TO_BUS);
}
}
for(auto itim = m_indMotorList.begin(); itim != m_indMotorList.end(); itim++) {
@@ -467,9 +467,9 @@ void ElectricCalculation::UpdateElementsPowerFlow(std::vector<std::complex<doubl
loadPower += std::complex<double>(childData.activePower, childData.reactivePower);
if(childData.activePower >= 0.0)
- indMotor->SetPowerFlowDirection(PF_TO_ELEMENT);
+ indMotor->SetPowerFlowDirection(PowerFlowDirection::PF_TO_ELEMENT);
else
- indMotor->SetPowerFlowDirection(PF_TO_BUS);
+ indMotor->SetPowerFlowDirection(PowerFlowDirection::PF_TO_BUS);
}
}
@@ -484,13 +484,13 @@ void ElectricCalculation::UpdateElementsPowerFlow(std::vector<std::complex<doubl
(power[i].real() + loadPower.real()) * systemPowerBase / (double)(syncGeneratorsOnBus.size());
switch(childData.activePowerUnit) {
- case UNIT_PU: {
+ case ElectricalUnit::UNIT_PU: {
activePower /= systemPowerBase;
} break;
- case UNIT_kW: {
+ case ElectricalUnit::UNIT_kW: {
activePower /= 1e3;
} break;
- case UNIT_MW: {
+ case ElectricalUnit::UNIT_MW: {
activePower /= 1e6;
} break;
default:
@@ -516,13 +516,13 @@ void ElectricCalculation::UpdateElementsPowerFlow(std::vector<std::complex<doubl
reactivePower /= (double)(syncGeneratorsOnBus.size() + syncMotorsOnBus.size());
switch(childData.reactivePowerUnit) {
- case UNIT_PU: {
+ case ElectricalUnit::UNIT_PU: {
reactivePower /= systemPowerBase;
} break;
- case UNIT_kVAr: {
+ case ElectricalUnit::UNIT_kVAr: {
reactivePower /= 1e3;
} break;
- case UNIT_MVAr: {
+ case ElectricalUnit::UNIT_MVAr: {
reactivePower /= 1e6;
} break;
default:
@@ -532,9 +532,9 @@ void ElectricCalculation::UpdateElementsPowerFlow(std::vector<std::complex<doubl
}
if(childData.activePower >= 0.0)
- generator->SetPowerFlowDirection(PF_TO_BUS);
+ generator->SetPowerFlowDirection(PowerFlowDirection::PF_TO_BUS);
else
- generator->SetPowerFlowDirection(PF_TO_ELEMENT);
+ generator->SetPowerFlowDirection(PowerFlowDirection::PF_TO_ELEMENT);
generator->SetElectricalData(childData);
}
@@ -585,13 +585,13 @@ void ElectricCalculation::UpdateElementsPowerFlow(std::vector<std::complex<doubl
reactivePower *= systemPowerBase;
switch(childData.reactivePowerUnit) {
- case UNIT_PU: {
+ case ElectricalUnit::UNIT_PU: {
reactivePower /= systemPowerBase;
} break;
- case UNIT_kVAr: {
+ case ElectricalUnit::UNIT_kVAr: {
reactivePower /= 1e3;
} break;
- case UNIT_MVAr: {
+ case ElectricalUnit::UNIT_MVAr: {
reactivePower /= 1e6;
} break;
default:
@@ -601,9 +601,9 @@ void ElectricCalculation::UpdateElementsPowerFlow(std::vector<std::complex<doubl
}
if(childData.activePower > 0.0)
- syncMotor->SetPowerFlowDirection(PF_TO_ELEMENT);
+ syncMotor->SetPowerFlowDirection(PowerFlowDirection::PF_TO_ELEMENT);
else
- syncMotor->SetPowerFlowDirection(PF_TO_BUS);
+ syncMotor->SetPowerFlowDirection(PowerFlowDirection::PF_TO_BUS);
syncMotor->SetElectricalData(childData);
diff --git a/Project/Electromechanical.cpp b/Project/Electromechanical.cpp
index 8d97d5b..307b2da 100644
--- a/Project/Electromechanical.cpp
+++ b/Project/Electromechanical.cpp
@@ -207,14 +207,14 @@ void Electromechanical::SetEvent(double currentTime)
for(unsigned int i = 0; i < swData.swType.size(); ++i) {
if(EventTrigger(swData.swTime[i], currentTime)) {
// Remove machine (only connected machines)
- if(swData.swType[i] == SW_REMOVE && generator->IsOnline()) {
+ if(swData.swType[i] == SwitchingType::SW_REMOVE && generator->IsOnline()) {
generator->SetOnline(false);
int n = static_cast<Bus*>(generator->GetParentList()[0])->GetElectricalData().number;
m_yBus[n][n] -= GetSyncMachineAdmittance(generator);
}
// Insert machine (only disconnected machines)
- if(swData.swType[i] == SW_INSERT && !generator->IsOnline() && generator->GetParentList().size() == 1) {
+ if(swData.swType[i] == SwitchingType::SW_INSERT && !generator->IsOnline() && generator->GetParentList().size() == 1) {
if(generator->SetOnline(true)) {
int n = static_cast<Bus*>(generator->GetParentList()[0])->GetElectricalData().number;
m_yBus[n][n] += GetSyncMachineAdmittance(generator);
@@ -231,7 +231,7 @@ void Electromechanical::SetEvent(double currentTime)
for(unsigned int i = 0; i < swData.swType.size(); ++i) {
if(EventTrigger(swData.swTime[i], currentTime)) {
// Remove machine (only connected machines)
- if(swData.swType[i] == SW_REMOVE && motor->IsOnline() && motor->GetParentList().size() == 1) {
+ if(swData.swType[i] == SwitchingType::SW_REMOVE && motor->IsOnline() && motor->GetParentList().size() == 1) {
auto data = motor->GetElectricalData();
motor->SetOnline(false);
int n = static_cast<Bus*>(motor->GetParentList()[0])->GetElectricalData().number;
@@ -239,7 +239,7 @@ void Electromechanical::SetEvent(double currentTime)
}
// Insert machine (only disconnected machines)
- if(swData.swType[i] == SW_INSERT && !motor->IsOnline() && motor->GetParentList().size() == 1) {
+ if(swData.swType[i] == SwitchingType::SW_INSERT && !motor->IsOnline() && motor->GetParentList().size() == 1) {
auto data = motor->GetElectricalData();
if(motor->SetOnline(true)) {
int n = static_cast<Bus*>(motor->GetParentList()[0])->GetElectricalData().number;
@@ -257,7 +257,7 @@ void Electromechanical::SetEvent(double currentTime)
for(unsigned int i = 0; i < swData.swType.size(); ++i) {
if(EventTrigger(swData.swTime[i], currentTime)) {
// Remove load (only connected loads)
- if(swData.swType[i] == SW_REMOVE && load->IsOnline() && load->GetParentList().size() == 1) {
+ if(swData.swType[i] == SwitchingType::SW_REMOVE && load->IsOnline() && load->GetParentList().size() == 1) {
load->SetOnline(false);
auto data = load->GetPUElectricalData(m_powerSystemBase);
Bus* parentBus = static_cast<Bus*>(load->GetParentList()[0]);
@@ -268,7 +268,7 @@ void Electromechanical::SetEvent(double currentTime)
}
// Insert load (only disconnected load)
- if(swData.swType[i] == SW_INSERT && !load->IsOnline() && load->GetParentList().size() == 1) {
+ if(swData.swType[i] == SwitchingType::SW_INSERT && !load->IsOnline() && load->GetParentList().size() == 1) {
if(load->SetOnline(true)) {
auto data = load->GetPUElectricalData(m_powerSystemBase);
Bus* parentBus = static_cast<Bus*>(load->GetParentList()[0]);
@@ -289,7 +289,7 @@ void Electromechanical::SetEvent(double currentTime)
for(unsigned int i = 0; i < swData.swType.size(); ++i) {
if(EventTrigger(swData.swTime[i], currentTime)) {
// Remove line (only connected lines)
- if(swData.swType[i] == SW_REMOVE && line->IsOnline()) {
+ if(swData.swType[i] == SwitchingType::SW_REMOVE && line->IsOnline()) {
line->SetOnline(false);
auto data = line->GetElectricalData();
@@ -307,7 +307,7 @@ void Electromechanical::SetEvent(double currentTime)
}
// Insert line (only disconnected lines)
- if(swData.swType[i] == SW_INSERT && !line->IsOnline() && line->GetParentList().size() == 2) {
+ if(swData.swType[i] == SwitchingType::SW_INSERT && !line->IsOnline() && line->GetParentList().size() == 2) {
if(line->SetOnline(true)) {
auto data = line->GetElectricalData();
@@ -335,7 +335,7 @@ void Electromechanical::SetEvent(double currentTime)
for(unsigned int i = 0; i < swData.swType.size(); ++i) {
if(EventTrigger(swData.swTime[i], currentTime)) {
// Remove transformer (only connected transformers)
- if(swData.swType[i] == SW_REMOVE && transformer->IsOnline()) {
+ if(swData.swType[i] == SwitchingType::SW_REMOVE && transformer->IsOnline()) {
transformer->SetOnline(false);
auto data = transformer->GetElectricalData();
@@ -364,7 +364,7 @@ void Electromechanical::SetEvent(double currentTime)
}
// Insert transformer (only disconnected transformers)
- if(swData.swType[i] == SW_INSERT && !transformer->IsOnline() &&
+ if(swData.swType[i] == SwitchingType::SW_INSERT && !transformer->IsOnline() &&
transformer->GetParentList().size() == 2) {
if(transformer->SetOnline(true)) {
auto data = transformer->GetElectricalData();
@@ -404,7 +404,7 @@ void Electromechanical::SetEvent(double currentTime)
for(unsigned int i = 0; i < swData.swType.size(); ++i) {
if(EventTrigger(swData.swTime[i], currentTime)) {
// Remove capacitor (only connected capacitors)
- if(swData.swType[i] == SW_REMOVE && capacitor->IsOnline()) {
+ if(swData.swType[i] == SwitchingType::SW_REMOVE && capacitor->IsOnline()) {
capacitor->SetOnline(false);
auto data = capacitor->GetPUElectricalData(m_powerSystemBase);
int n = static_cast<Bus*>(capacitor->GetParentList()[0])->GetElectricalData().number;
@@ -412,7 +412,7 @@ void Electromechanical::SetEvent(double currentTime)
}
// Insert capacitor (only disconnected capacitors)
- if(swData.swType[i] == SW_INSERT && !capacitor->IsOnline() && capacitor->GetParentList().size() == 1) {
+ if(swData.swType[i] == SwitchingType::SW_INSERT && !capacitor->IsOnline() && capacitor->GetParentList().size() == 1) {
if(capacitor->SetOnline(true)) {
auto data = capacitor->GetPUElectricalData(m_powerSystemBase);
int n = static_cast<Bus*>(capacitor->GetParentList()[0])->GetElectricalData().number;
@@ -430,7 +430,7 @@ void Electromechanical::SetEvent(double currentTime)
for(unsigned int i = 0; i < swData.swType.size(); ++i) {
if(EventTrigger(swData.swTime[i], currentTime)) {
// Remove inductor (only connected inductors)
- if(swData.swType[i] == SW_REMOVE && inductor->IsOnline()) {
+ if(swData.swType[i] == SwitchingType::SW_REMOVE && inductor->IsOnline()) {
inductor->SetOnline(false);
auto data = inductor->GetPUElectricalData(m_powerSystemBase);
int n = static_cast<Bus*>(inductor->GetParentList()[0])->GetElectricalData().number;
@@ -438,7 +438,7 @@ void Electromechanical::SetEvent(double currentTime)
}
// Insert inductor (only disconnected inductors)
- if(swData.swType[i] == SW_INSERT && !inductor->IsOnline() && inductor->GetParentList().size() == 1) {
+ if(swData.swType[i] == SwitchingType::SW_INSERT && !inductor->IsOnline() && inductor->GetParentList().size() == 1) {
if(inductor->SetOnline(true)) {
auto data = inductor->GetPUElectricalData(m_powerSystemBase);
int n = static_cast<Bus*>(inductor->GetParentList()[0])->GetElectricalData().number;
@@ -1816,7 +1816,7 @@ bool Electromechanical::CalculateIndMachinesTransientValues(IndMotor* motor)
double p = dataPU.activePower;
double v = std::abs(data.terminalVoltage);
- //[Ref.] Induction Motor Static Models for Power Flow and Voltage Stability Studies
+ //[Ref.] Induction Motor Static Models for Power Flow and Voltage stability Studies
// If the motor is offline, calculate the nominal slip to user-defined power input and 1.0 p.u. voltage
if(!motor->IsOnline()) v = 1.0;
double r1 = data.r1t;
diff --git a/Project/Element.cpp b/Project/Element.cpp
index 46aaa7d..a108957 100644
--- a/Project/Element.cpp
+++ b/Project/Element.cpp
@@ -19,6 +19,8 @@
#ifdef USING_WX_3_0_X
#include "DegreesAndRadians.h"
#endif
+#include <wx/pen.h>
+#include <wx/brush.h>
Element::Element() { m_selectionColour.SetRGBA(0.0, 0.5, 1.0, 0.5); }
Element::~Element() {}
@@ -40,6 +42,18 @@ void Element::DrawCircle(wxPoint2DDouble position, double radius, int numSegment
glEnd();
}
+void Element::DrawDCCircle(wxPoint2DDouble position, double radius, int numSegments, wxGraphicsContext* gc) const
+{
+ wxPoint2DDouble* pts = new wxPoint2DDouble[numSegments + 1];
+ for (int i = 0; i < numSegments; i++) {
+ double theta = 2.0 * 3.1415926 * double(i) / double(numSegments);
+ pts[i] = wxPoint2DDouble(radius * std::cos(theta) + position.m_x, radius * std::sin(theta) + position.m_y);
+ }
+ pts[numSegments] = pts[0];
+ gc->DrawLines(numSegments + 1, pts);
+ delete[] pts;
+}
+
void Element::DrawArc(wxPoint2DDouble position,
double radius,
double initAngle,
@@ -57,6 +71,20 @@ void Element::DrawArc(wxPoint2DDouble position,
glEnd();
}
+void Element::DrawDCArc(wxPoint2DDouble position, double radius, double initAngle, double finalAngle, int numSegments, wxGraphicsContext* gc) const
+{
+ double initAngRad = wxDegToRad(initAngle);
+ double finalAngRad = wxDegToRad(finalAngle);
+ wxPoint2DDouble* points = new wxPoint2DDouble[numSegments + 2];
+ for (int i = 0; i <= numSegments; i++) {
+ double theta = initAngRad + (finalAngRad - initAngRad) * double(i) / double(numSegments);
+ points[i] = wxPoint2DDouble(radius * std::cos(theta) + position.m_x, radius * std::sin(theta) + position.m_y);
+ }
+
+ gc->DrawLines(numSegments + 1, points);
+ delete[] points;
+}
+
void Element::DrawTriangle(std::vector<wxPoint2DDouble> points, GLenum mode) const
{
glBegin(mode);
@@ -64,6 +92,12 @@ void Element::DrawTriangle(std::vector<wxPoint2DDouble> points, GLenum mode) con
glEnd();
}
+void Element::DrawDCTriangle(std::vector<wxPoint2DDouble> points, wxGraphicsContext* gc) const
+{
+ points.emplace_back(points[0]);
+ gc->DrawLines(4, &points[0]);
+}
+
void Element::DrawRectangle(wxPoint2DDouble position, double width, double height, GLenum mode) const
{
glBegin(mode); // TODO: GL_QUADS é obsoleto (OpenGL 3.0+), encontrar outra solução.
@@ -100,6 +134,13 @@ void Element::DrawPickbox(wxPoint2DDouble position) const
DrawRectangle(position, 8.0, 8.0, GL_LINE_LOOP);
}
+void Element::DrawDCPickbox(wxPoint2DDouble position, wxGraphicsContext* gc) const
+{
+ gc->SetPen(wxPen(wxColour(0, 0, 0, 255)));
+ gc->SetBrush(wxBrush(wxColour(255, 255, 255, 204)));
+ gc->DrawRectangle(position.m_x, position.m_y, 8, 8);
+}
+
wxPoint2DDouble Element::RotateAtPosition(wxPoint2DDouble pointToRotate, double angle, bool degrees) const
{
double radAngle = angle;
@@ -350,9 +391,9 @@ void Element::ReplaceParent(Element* oldParent, Element* newParent)
void Element::AddChild(Element* child) { m_childList.push_back(child); }
void Element::RemoveChild(Element* child)
{
- for(auto it = m_childList.begin(); it != m_childList.end(); ++it) {
- Element* element = *it;
- if(element == child) m_childList.erase(it--);
+ for(auto it = m_childList.begin(); it != m_childList.end();) {
+ if (*it == child) it = m_childList.erase(it);
+ else ++it;
}
}
@@ -371,6 +412,11 @@ void OpenGLColour::SetRGBA(GLdouble red, GLdouble green, GLdouble blue, GLdouble
rgba[3] = alpha;
}
+wxColour OpenGLColour::GetDcRGBA() const
+{
+ return wxColour(rgba[0] * 255, rgba[1] * 255, rgba[2] * 255, rgba[3] * 255);
+}
+
OpenGLColour::OpenGLColour() { SetRGBA(1.0, 1.0, 1.0, 1.0); }
OpenGLColour::OpenGLColour(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha)
{
diff --git a/Project/Element.h b/Project/Element.h
index b31a81a..2c845ec 100644
--- a/Project/Element.h
+++ b/Project/Element.h
@@ -24,7 +24,9 @@
#include <wx/menu.h>
#include <wx/stdpaths.h>
#include <wx/filename.h>
+#include <windows.h>
#include <GL/gl.h>
+#include <wx/graphics.h>
#include <complex>
@@ -101,6 +103,7 @@ class OpenGLColour
* @return RGBA colour.
*/
const GLdouble* GetRGBA() const { return rgba; }
+ wxColour GetDcRGBA() const;
protected:
GLdouble rgba[4];
};
@@ -297,12 +300,19 @@ class Element
*/
virtual wxString GetTipText() const { return wxEmptyString; }
/**
- * @brief Draw the element.
+ * @brief Draw the element using OpenGL.
* @param translation Translation of the system.
* @param scale Scale of the system.
*/
virtual void Draw(wxPoint2DDouble translation, double scale) const {}
/**
+ * @brief Draw the element using GDI+.
+ * @param translation Translation of the system.
+ * @param scale Scale of the system.
+ * @param gc Graphics context
+ */
+ virtual void DrawDC(wxPoint2DDouble translation, double scale, wxGraphicsContext* gc) const {}
+ /**
* @brief Rotate the element.
* @param clockwise True to rotate clockwise, false to rotate counter-clockwise.
*/
@@ -443,6 +453,15 @@ class Element
* @param mode OpenGl primitive.
*/
virtual void DrawCircle(wxPoint2DDouble position, double radius, int numSegments, GLenum mode = GL_LINE_LOOP) const;
+
+ /**
+ * @brief Draw a circle using device context.
+ * @param position Circle position.
+ * @param radius Circle radius
+ * @param numSegments Num of segments of the circle.
+ * @param gl Device context.
+ */
+ virtual void DrawDCCircle(wxPoint2DDouble position, double radius, int numSegments, wxGraphicsContext* gc) const;
virtual void DrawArc(wxPoint2DDouble position,
double radius,
double initAngle,
@@ -450,6 +469,8 @@ class Element
int numSegments,
GLenum mode = GL_LINE_LOOP) const;
+ virtual void DrawDCArc(wxPoint2DDouble position, double radius, double initAngle, double finalAngle, int numSegments, wxGraphicsContext* gc) const;
+
/**
* @brief Draw rectangle.
* @param position Rectangle position.
@@ -474,6 +495,13 @@ class Element
virtual void DrawTriangle(std::vector<wxPoint2DDouble> points, GLenum mode = GL_TRIANGLES) const;
/**
+ * @brief Draw a triangle.
+ * @param points Triangle vertices.
+ * @param gc Device context.
+ */
+ virtual void DrawDCTriangle(std::vector<wxPoint2DDouble> points, wxGraphicsContext* gc) const;
+
+ /**
* @brief Draw a point.
* @param position Point position.
* @param size Point size.
@@ -494,6 +522,13 @@ class Element
virtual void DrawPickbox(wxPoint2DDouble position) const;
/**
+ * @brief Draw pickbox using direct context.
+ * @param position Pickbox position.
+ * @param gc Direct context.
+ */
+ virtual void DrawDCPickbox(wxPoint2DDouble position, wxGraphicsContext* gc) const;
+
+ /**
* @brief Rotate a point as element position being the origin.
* @param pointToRotate Point that will be rotated.
* @param angle Angle of rotation.
diff --git a/Project/ElementFormBase.h b/Project/ElementFormBase.h
index c8fe7f0..9556f7d 100644
--- a/Project/ElementFormBase.h
+++ b/Project/ElementFormBase.h
@@ -386,7 +386,7 @@ class GeneratorStabFormBase : public wxDialog
wxButton* GetButtonCancel() { return m_ButtonCancel; }
GeneratorStabFormBase(wxWindow* parent,
wxWindowID id = wxID_ANY,
- const wxString& title = _("Generator: Stability"),
+ const wxString& title = _("Generator: stability"),
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxSize(-1, -1),
long style = wxDEFAULT_DIALOG_STYLE);
diff --git a/Project/Exponential.cpp b/Project/Exponential.cpp
index 136a2fa..61e5bff 100644
--- a/Project/Exponential.cpp
+++ b/Project/Exponential.cpp
@@ -21,9 +21,9 @@
Exponential::Exponential(int id) : ControlElement(id)
{
m_width = m_height = 36.0;
- Node* nodeIn = new Node(m_position + wxPoint2DDouble(-18, 0), Node::NODE_IN, m_borderSize);
+ Node* nodeIn = new Node(m_position + wxPoint2DDouble(-18, 0), Node::NodeType::NODE_IN, m_borderSize);
nodeIn->StartMove(m_position);
- Node* nodeOut = new Node(m_position + wxPoint2DDouble(18, 0), Node::NODE_OUT, m_borderSize);
+ Node* nodeOut = new Node(m_position + wxPoint2DDouble(18, 0), Node::NodeType::NODE_OUT, m_borderSize);
nodeOut->SetAngle(180.0);
nodeOut->StartMove(m_position);
m_nodeList.push_back(nodeIn);
diff --git a/Project/Fault.cpp b/Project/Fault.cpp
index a71d2ce..cf4dc61 100644
--- a/Project/Fault.cpp
+++ b/Project/Fault.cpp
@@ -60,8 +60,8 @@ bool Fault::RunFaultCalculation(double systemPowerBase)
// Get fault parameters.
int fNumber = -1;
- FaultData fType = FAULT_THREEPHASE;
- FaultData fLocation = FAULT_LINE_A;
+ FaultData fType = FaultData::FAULT_THREEPHASE;
+ FaultData fLocation = FaultData::FAULT_LINE_A;
std::complex<double> fImpedance = std::complex<double>(0.0, 0.0);
for(auto it = m_busList.begin(), itEnd = m_busList.end(); it != itEnd; ++it) {
Bus* bus = *it;
@@ -90,27 +90,27 @@ bool Fault::RunFaultCalculation(double systemPowerBase)
std::complex<double> a2 = std::complex<double>(-0.5, -0.866025403784);
switch(fType) {
- case FAULT_THREEPHASE: {
+ case FaultData::FAULT_THREEPHASE: {
fCurrentPos = preFaultVoltage / (m_zBusPos[fNumber][fNumber] + fImpedance);
} break;
- case FAULT_2LINE: {
+ case FaultData::FAULT_2LINE: {
fCurrentPos = preFaultVoltage / (m_zBusPos[fNumber][fNumber] + m_zBusNeg[fNumber][fNumber] + fImpedance);
switch(fLocation) {
- case FAULT_LINE_A: {
+ case FaultData::FAULT_LINE_A: {
fCurrentNeg = -a2 * fCurrentPos;
} break;
- case FAULT_LINE_B: {
+ case FaultData::FAULT_LINE_B: {
fCurrentNeg = -fCurrentPos;
} break;
- case FAULT_LINE_C: {
+ case FaultData::FAULT_LINE_C: {
fCurrentNeg = -a * fCurrentPos;
} break;
default:
break;
}
} break;
- case FAULT_2LINE_GROUND: {
+ case FaultData::FAULT_2LINE_GROUND: {
std::complex<double> z1 = m_zBusPos[fNumber][fNumber];
std::complex<double> z2 = m_zBusNeg[fNumber][fNumber];
std::complex<double> z0 = m_zBusZero[fNumber][fNumber];
@@ -119,15 +119,15 @@ bool Fault::RunFaultCalculation(double systemPowerBase)
fCurrentPos = (preFaultVoltage * (z2 + z0 + zf_3)) / (z1 * z2 + z2 * z0 + z2 * zf_3 + z1 * z0 + z1 * zf_3);
switch(fLocation) {
- case FAULT_LINE_A: {
+ case FaultData::FAULT_LINE_A: {
fCurrentNeg = -a2 * ((preFaultVoltage - z1 * fCurrentPos) / z2);
fCurrentZero = -a * ((preFaultVoltage - z1 * fCurrentPos) / (z0 + zf_3));
} break;
- case FAULT_LINE_B: {
+ case FaultData::FAULT_LINE_B: {
fCurrentNeg = -((preFaultVoltage - z1 * fCurrentPos) / z2);
fCurrentZero = -((preFaultVoltage - z1 * fCurrentPos) / (z0 + zf_3));
} break;
- case FAULT_LINE_C: {
+ case FaultData::FAULT_LINE_C: {
fCurrentNeg = -a * ((preFaultVoltage - z1 * fCurrentPos) / z2);
fCurrentZero = -a2 * ((preFaultVoltage - z1 * fCurrentPos) / (z0 + zf_3));
} break;
@@ -135,20 +135,20 @@ bool Fault::RunFaultCalculation(double systemPowerBase)
break;
}
} break;
- case FAULT_LINE_GROUND: {
+ case FaultData::FAULT_LINE_GROUND: {
fCurrentPos =
preFaultVoltage / (m_zBusPos[fNumber][fNumber] + m_zBusNeg[fNumber][fNumber] +
m_zBusZero[fNumber][fNumber] + std::complex<double>(3.0, 0.0) * fImpedance);
switch(fLocation) {
- case FAULT_LINE_A: {
+ case FaultData::FAULT_LINE_A: {
fCurrentNeg = fCurrentPos;
fCurrentZero = fCurrentPos;
} break;
- case FAULT_LINE_B: {
+ case FaultData::FAULT_LINE_B: {
fCurrentNeg = a * fCurrentPos;
fCurrentZero = a2 * fCurrentPos;
} break;
- case FAULT_LINE_C: {
+ case FaultData::FAULT_LINE_C: {
fCurrentNeg = a2 * fCurrentPos;
fCurrentZero = a * fCurrentPos;
} break;
diff --git a/Project/Gain.cpp b/Project/Gain.cpp
index 2977f1f..596d8ad 100644
--- a/Project/Gain.cpp
+++ b/Project/Gain.cpp
@@ -22,9 +22,9 @@ Gain::Gain(int id) : ControlElement(id)
{
m_triPts.resize(3);
SetValue(m_value);
- Node* nodeIn = new Node(m_position + wxPoint2DDouble(-m_width / 2, 0), Node::NODE_IN, m_borderSize);
+ Node* nodeIn = new Node(m_position + wxPoint2DDouble(-m_width / 2, 0), Node::NodeType::NODE_IN, m_borderSize);
nodeIn->StartMove(m_position);
- Node* nodeOut = new Node(m_position + wxPoint2DDouble(m_width / 2, 0), Node::NODE_OUT, m_borderSize);
+ Node* nodeOut = new Node(m_position + wxPoint2DDouble(m_width / 2, 0), Node::NodeType::NODE_OUT, m_borderSize);
nodeOut->SetAngle(180.0);
nodeOut->StartMove(m_position);
m_nodeList.push_back(nodeIn);
diff --git a/Project/GeneralPropertiesForm.cpp b/Project/GeneralPropertiesForm.cpp
index 2761d16..c6ef565 100644
--- a/Project/GeneralPropertiesForm.cpp
+++ b/Project/GeneralPropertiesForm.cpp
@@ -65,7 +65,9 @@ bool GeneralPropertiesForm::ValidateData()
auto checkData = m_properties->GetGeneralPropertiesData();
bool hasChanges = false;
- wxTextFile file("config.ini");
+ //wxTextFile file("config.ini");
+ wxFileName fn(wxStandardPaths::Get().GetExecutablePath());
+ wxTextFile file(fn.GetPath() + wxFileName::GetPathSeparator() + "config.ini");
if(!file.Create()) {
if(!file.Open()) {
// Fail to access the file.
diff --git a/Project/GeneratorStabForm.cpp b/Project/GeneratorStabForm.cpp
index 3eb3a39..f22ecdb 100644
--- a/Project/GeneratorStabForm.cpp
+++ b/Project/GeneratorStabForm.cpp
@@ -21,12 +21,13 @@
#include "SwitchingForm.h"
#include "SyncGenerator.h"
-GeneratorStabForm::GeneratorStabForm(wxWindow* parent, SyncGenerator* syncGenerator)
+GeneratorStabForm::GeneratorStabForm(wxWindow* parent, SyncGenerator* syncGenerator, wxGLContext* sharedGLContext)
: GeneratorStabFormBase(parent)
{
SetSize(GetBestSize());
m_syncGenerator = syncGenerator;
m_parent = parent;
+ m_sharedGLContext = sharedGLContext;
SyncGeneratorElectricalData data = syncGenerator->GetElectricalData();
@@ -75,7 +76,7 @@ void GeneratorStabForm::OnEditAVRButtonClick(wxCommandEvent& event)
data.avr = new ControlElementContainer();
m_syncGenerator->SetElectricalData(data);
}
- ControlEditor* cEditor = new ControlEditor(m_parent, IOControl::IN_TERMINAL_VOLTAGE | IOControl::IN_ACTIVE_POWER |
+ ControlEditor* cEditor = new ControlEditor(NULL, m_sharedGLContext, IOControl::IN_TERMINAL_VOLTAGE | IOControl::IN_ACTIVE_POWER |
IOControl::IN_REACTIVE_POWER | IOControl::IN_INITIAL_TERMINAL_VOLTAGE | IOControl::IN_VELOCITY |
IOControl::IN_INITIAL_VELOCITY | IOControl::IN_DELTA_VELOCITY | IOControl::IN_DELTA_ACTIVE_POWER |
IOControl::OUT_FIELD_VOLTAGE);
@@ -105,7 +106,7 @@ void GeneratorStabForm::OnSpeedGovernorButtonClick(wxCommandEvent& event)
m_syncGenerator->SetElectricalData(data);
}
ControlEditor* cEditor =
- new ControlEditor(NULL, IOControl::IN_VELOCITY | IOControl::IN_ACTIVE_POWER | IOControl::IN_REACTIVE_POWER |
+ new ControlEditor(NULL, m_sharedGLContext, IOControl::IN_VELOCITY | IOControl::IN_ACTIVE_POWER | IOControl::IN_REACTIVE_POWER |
IOControl::IN_INITIAL_VELOCITY | IOControl::IN_INITIAL_MEC_POWER | IOControl::OUT_MEC_POWER);
cEditor->SetElementsList(data.speedGov->GetControlElementsList());
cEditor->SetConnectionsList(data.speedGov->GetConnectionLineList());
diff --git a/Project/GeneratorStabForm.h b/Project/GeneratorStabForm.h
index 14bcd11..3f1305c 100644
--- a/Project/GeneratorStabForm.h
+++ b/Project/GeneratorStabForm.h
@@ -18,6 +18,7 @@
#ifndef GENERATORSTABFORM_H
#define GENERATORSTABFORM_H
+#include <wx/glcanvas.h>
#include "ElementFormBase.h"
class SwitchingForm;
@@ -35,7 +36,7 @@ class ControlElementContainer;
class GeneratorStabForm : public GeneratorStabFormBase
{
public:
- GeneratorStabForm(wxWindow* parent, SyncGenerator* syncGenerator);
+ GeneratorStabForm(wxWindow* parent, SyncGenerator* syncGenerator, wxGLContext* sharedGLContext);
virtual ~GeneratorStabForm();
protected:
@@ -46,10 +47,12 @@ class GeneratorStabForm : public GeneratorStabFormBase
virtual void OnOKButtonClick(wxCommandEvent& event);
virtual void OnSpeedGovernorButtonClick(wxCommandEvent& event);
virtual void OnSwitchingButtonClick(wxCommandEvent& event);
+ wxGLContext* GetSharedGLContext() const { return m_sharedGLContext; }
virtual bool ValidateData();
SyncGenerator* m_syncGenerator = NULL;
wxWindow* m_parent = NULL;
+ wxGLContext* m_sharedGLContext = NULL;
};
#endif // GENERATORSTABFORM_H
diff --git a/Project/GraphAutoLayout.cpp b/Project/GraphAutoLayout.cpp
index 972ce25..bf3bc91 100644
--- a/Project/GraphAutoLayout.cpp
+++ b/Project/GraphAutoLayout.cpp
@@ -34,7 +34,7 @@ void GraphAutoLayout::AddLink(size_t index1, size_t index2, float weight)
m_nodes.push_back(node);
}
// Add an edge
- m_edges.push_back((GraphLayoutEdge){.node1 = m_nodes[index1], .node2 = m_nodes[index2], .weight = weight});
+ m_edges.push_back({.node1 = m_nodes[index1], .node2 = m_nodes[index2], .weight = weight});
}
void GraphAutoLayout::Compute(size_t iterations)
diff --git a/Project/HarmCurrentForm.cpp b/Project/HarmCurrentForm.cpp
index 812124c..3a14cc6 100644
--- a/Project/HarmCurrentForm.cpp
+++ b/Project/HarmCurrentForm.cpp
@@ -16,7 +16,7 @@ HarmCurrentForm::HarmCurrentForm(wxWindow* parent, HarmCurrent* harmCurrent) : H
for(unsigned int i = 0; i < data.harmonicOrder.size(); ++i) {
long item = m_listCtrlHarmCurrentList->InsertItem(m_maxID, wxString::Format("%d", data.harmonicOrder[i]));
m_listCtrlHarmCurrentList->SetItem(item, 1, m_harmCurrent->StringFromDouble(data.injHarmCurrent[i], 1));
- m_listCtrlHarmCurrentList->SetItem(item, 2, data.injHarmCurrentUnit[i] == UNIT_A ? _("A") : _("p.u."));
+ m_listCtrlHarmCurrentList->SetItem(item, 2, data.injHarmCurrentUnit[i] == ElectricalUnit::UNIT_A ? _("A") : _("p.u."));
m_listCtrlHarmCurrentList->SetItem(item, 3, m_harmCurrent->StringFromDouble(data.injHarmAngle[i], 1));
m_maxID++;
}
@@ -50,9 +50,9 @@ bool HarmCurrentForm::ValidateData()
if(!m_listCtrlHarmCurrentList->GetItemText(item, 1).ToDouble(&injCurrent)) { return false; }
injHarmCurrent.push_back(injCurrent);
if(m_listCtrlHarmCurrentList->GetItemText(item, 2) == "A")
- injHarmCurrentUnit.push_back(UNIT_A);
+ injHarmCurrentUnit.push_back(ElectricalUnit::UNIT_A);
else
- injHarmCurrentUnit.push_back(UNIT_PU);
+ injHarmCurrentUnit.push_back(ElectricalUnit::UNIT_PU);
double injCAngle = 0.0;
if(!m_listCtrlHarmCurrentList->GetItemText(item, 3).ToDouble(&injCAngle)) { return false; }
injHarmAngle.push_back(injCAngle);
@@ -124,9 +124,9 @@ void HarmCurrentForm::SortList()
if(!m_listCtrlHarmCurrentList->GetItemText(item, 1).ToDouble(&injCurrent)) return;
injHarmCurrent.push_back(injCurrent);
if(m_listCtrlHarmCurrentList->GetItemText(item, 2) == "A")
- injHarmCurrentUnit.push_back(UNIT_A);
+ injHarmCurrentUnit.push_back(ElectricalUnit::UNIT_A);
else
- injHarmCurrentUnit.push_back(UNIT_PU);
+ injHarmCurrentUnit.push_back(ElectricalUnit::UNIT_PU);
double injCAngle = 0.0;
if(!m_listCtrlHarmCurrentList->GetItemText(item, 3).ToDouble(&injCAngle)) return;
injHarmAngle.push_back(injCAngle);
@@ -165,7 +165,7 @@ void HarmCurrentForm::SortList()
for(unsigned int i = 0; i < harmonicOrder.size(); ++i) {
long item = m_listCtrlHarmCurrentList->InsertItem(m_maxID, wxString::Format("%d", harmonicOrder[i]));
m_listCtrlHarmCurrentList->SetItem(item, 1, m_harmCurrent->StringFromDouble(injHarmCurrent[i], 1));
- m_listCtrlHarmCurrentList->SetItem(item, 2, injHarmCurrentUnit[i] == UNIT_A ? _("A") : _("p.u."));
+ m_listCtrlHarmCurrentList->SetItem(item, 2, injHarmCurrentUnit[i] == ElectricalUnit::UNIT_A ? _("A") : _("p.u."));
m_listCtrlHarmCurrentList->SetItem(item, 3, m_harmCurrent->StringFromDouble(injHarmAngle[i], 1));
m_maxID++;
}
diff --git a/Project/IOControl.cpp b/Project/IOControl.cpp
index 114e8bf..9a3cd73 100644
--- a/Project/IOControl.cpp
+++ b/Project/IOControl.cpp
@@ -22,7 +22,7 @@ IOControl::IOControl(int ioFlags, int id) : ControlElement(id)
{
m_ioFlags = ioFlags;
- Node* node = new Node(m_position, Node::NODE_IN, m_borderSize);
+ Node* node = new Node(m_position, Node::NodeType::NODE_IN, m_borderSize);
m_nodeList.push_back(node);
if(ioFlags & IN_TERMINAL_VOLTAGE)
@@ -157,47 +157,47 @@ wxString IOControl::GenerateText()
switch(m_value) {
case IN_TERMINAL_VOLTAGE: {
- m_ioNodeType = Node::NODE_OUT;
+ m_ioNodeType = Node::NodeType::NODE_OUT;
return _("Vt");
} break;
case IN_VELOCITY: {
- m_ioNodeType = Node::NODE_OUT;
+ m_ioNodeType = Node::NodeType::NODE_OUT;
return omega;
} break;
case IN_ACTIVE_POWER: {
- m_ioNodeType = Node::NODE_OUT;
+ m_ioNodeType = Node::NodeType::NODE_OUT;
return _("P");
} break;
case IN_REACTIVE_POWER: {
- m_ioNodeType = Node::NODE_OUT;
+ m_ioNodeType = Node::NodeType::NODE_OUT;
return _("Q");
} break;
case OUT_FIELD_VOLTAGE: {
- m_ioNodeType = Node::NODE_IN;
+ m_ioNodeType = Node::NodeType::NODE_IN;
return _("Vf");
} break;
case OUT_MEC_POWER: {
- m_ioNodeType = Node::NODE_IN;
+ m_ioNodeType = Node::NodeType::NODE_IN;
return _("Pm");
} break;
case IN_INITIAL_TERMINAL_VOLTAGE: {
- m_ioNodeType = Node::NODE_OUT;
+ m_ioNodeType = Node::NodeType::NODE_OUT;
return _("Vt") + subZero;
} break;
case IN_INITIAL_MEC_POWER: {
- m_ioNodeType = Node::NODE_OUT;
+ m_ioNodeType = Node::NodeType::NODE_OUT;
return _("Pm") + subZero;
} break;
case IN_INITIAL_VELOCITY: {
- m_ioNodeType = Node::NODE_OUT;
+ m_ioNodeType = Node::NodeType::NODE_OUT;
return omega + subZero;
} break;
case IN_DELTA_VELOCITY: {
- m_ioNodeType = Node::NODE_OUT;
+ m_ioNodeType = Node::NodeType::NODE_OUT;
return capDelta + omega;
} break;
case IN_DELTA_ACTIVE_POWER: {
- m_ioNodeType = Node::NODE_OUT;
+ m_ioNodeType = Node::NodeType::NODE_OUT;
return capDelta + _("P");
} break;
}
@@ -233,22 +233,22 @@ void IOControl::UpdatePoints()
}
node->SetNodeType(m_ioNodeType);
if(m_angle == 0.0) {
- if(m_ioNodeType == Node::NODE_IN)
+ if(m_ioNodeType == Node::NodeType::NODE_IN)
node->SetPosition(m_position + wxPoint2DDouble(-m_width / 2, 0));
else
node->SetPosition(m_position + wxPoint2DDouble(m_width / 2 - 2, 0));
} else if(m_angle == 90.0) {
- if(m_ioNodeType == Node::NODE_IN)
+ if(m_ioNodeType == Node::NodeType::NODE_IN)
node->SetPosition(m_position + wxPoint2DDouble(0, -m_height / 2));
else
node->SetPosition(m_position + wxPoint2DDouble(0, m_height / 2 - 2));
} else if(m_angle == 180.0) {
- if(m_ioNodeType == Node::NODE_IN)
+ if(m_ioNodeType == Node::NodeType::NODE_IN)
node->SetPosition(m_position + wxPoint2DDouble(m_width / 2, 0));
else
node->SetPosition(m_position + wxPoint2DDouble(2 - m_width / 2, 0));
} else if(m_angle == 270.0) {
- if(m_ioNodeType == Node::NODE_IN)
+ if(m_ioNodeType == Node::NodeType::NODE_IN)
node->SetPosition(m_position + wxPoint2DDouble(0, m_height / 2));
else
node->SetPosition(m_position + wxPoint2DDouble(0, 2 - m_height / 2));
diff --git a/Project/IOControl.h b/Project/IOControl.h
index 0af3429..0fe2f40 100644
--- a/Project/IOControl.h
+++ b/Project/IOControl.h
@@ -75,7 +75,7 @@ class IOControl : public ControlElement
IOFlags m_value;
int m_ioFlags;
- Node::NodeType m_ioNodeType = Node::NODE_IN;
+ Node::NodeType m_ioNodeType = Node::NodeType::NODE_IN;
OpenGLText* m_glText = NULL;
};
diff --git a/Project/IndMotor.cpp b/Project/IndMotor.cpp
index 4df2bb1..621eb5e 100644
--- a/Project/IndMotor.cpp
+++ b/Project/IndMotor.cpp
@@ -32,6 +32,17 @@ void IndMotor::DrawSymbol() const
DrawLine(mPts);
}
+void IndMotor::DrawDCSymbol(wxGraphicsContext* gc) const
+{
+ std::vector<wxPoint2DDouble> mPts;
+ mPts.push_back(wxPoint2DDouble(-10, 13) + m_position);
+ mPts.push_back(wxPoint2DDouble(-10, -13) + m_position);
+ mPts.push_back(wxPoint2DDouble(0, 2) + m_position);
+ mPts.push_back(wxPoint2DDouble(10, -13) + m_position);
+ mPts.push_back(wxPoint2DDouble(10, 13) + m_position);
+ gc->DrawLines(mPts.size(), &mPts[0]);
+}
+
bool IndMotor::GetContextMenu(wxMenu& menu)
{
menu.Append(ID_EDIT_ELEMENT, _("Edit induction motor"));
diff --git a/Project/IndMotor.h b/Project/IndMotor.h
index 0aa6937..7e20a2f 100644
--- a/Project/IndMotor.h
+++ b/Project/IndMotor.h
@@ -124,6 +124,7 @@ class IndMotor : public Machines
virtual Element* GetCopy();
virtual void DrawSymbol() const;
+ virtual void DrawDCSymbol(wxGraphicsContext* gc) const;
virtual bool GetContextMenu(wxMenu& menu);
virtual wxString GetTipText() const;
virtual bool ShowForm(wxWindow* parent, Element* element);
diff --git a/Project/IndMotorForm.cpp b/Project/IndMotorForm.cpp
index 8517aef..c4187f2 100644
--- a/Project/IndMotorForm.cpp
+++ b/Project/IndMotorForm.cpp
@@ -30,13 +30,13 @@ IndMotorForm::IndMotorForm(wxWindow* parent, IndMotor* indMotor) : IndMotorFormB
m_textCtrlnominalPower->SetValue(IndMotor::StringFromDouble(data.ratedPower));
switch(data.activePowerUnit) {
- case UNIT_VA: {
+ case ElectricalUnit::UNIT_VA: {
m_choiceNominalPower->SetSelection(0);
} break;
- case UNIT_kVA: {
+ case ElectricalUnit::UNIT_kVA: {
m_choiceNominalPower->SetSelection(1);
} break;
- case UNIT_MVA: {
+ case ElectricalUnit::UNIT_MVA: {
m_choiceNominalPower->SetSelection(2);
} break;
default:
@@ -45,16 +45,16 @@ IndMotorForm::IndMotorForm(wxWindow* parent, IndMotor* indMotor) : IndMotorFormB
m_textCtrlActivePower->SetValue(IndMotor::StringFromDouble(data.activePower));
switch(data.activePowerUnit) {
- case UNIT_PU: {
+ case ElectricalUnit::UNIT_PU: {
m_choiceActivePower->SetSelection(0);
} break;
case UNIT_W: {
m_choiceActivePower->SetSelection(1);
} break;
- case UNIT_kW: {
+ case ElectricalUnit::UNIT_kW: {
m_choiceActivePower->SetSelection(2);
} break;
- case UNIT_MW: {
+ case ElectricalUnit::UNIT_MW: {
m_choiceActivePower->SetSelection(3);
} break;
default:
@@ -63,16 +63,16 @@ IndMotorForm::IndMotorForm(wxWindow* parent, IndMotor* indMotor) : IndMotorFormB
m_textCtrlReactivePower->SetValue(IndMotor::StringFromDouble(data.reactivePower));
switch(data.reactivePowerUnit) {
- case UNIT_PU: {
+ case ElectricalUnit::UNIT_PU: {
m_choiceReactivePower->SetSelection(0);
} break;
- case UNIT_VAr: {
+ case ElectricalUnit::UNIT_VAr: {
m_choiceReactivePower->SetSelection(1);
} break;
- case UNIT_kVAr: {
+ case ElectricalUnit::UNIT_kVAr: {
m_choiceReactivePower->SetSelection(2);
} break;
- case UNIT_MVAr: {
+ case ElectricalUnit::UNIT_MVAr: {
m_choiceReactivePower->SetSelection(3);
} break;
default:
@@ -130,13 +130,13 @@ bool IndMotorForm::ValidateData()
return false;
switch(m_choiceNominalPower->GetSelection()) {
case 0: {
- data.activePowerUnit = UNIT_VA;
+ data.activePowerUnit = ElectricalUnit::UNIT_VA;
} break;
case 1: {
- data.activePowerUnit = UNIT_kVA;
+ data.activePowerUnit = ElectricalUnit::UNIT_kVA;
} break;
case 2: {
- data.activePowerUnit = UNIT_MVA;
+ data.activePowerUnit = ElectricalUnit::UNIT_MVA;
} break;
}
@@ -145,16 +145,16 @@ bool IndMotorForm::ValidateData()
return false;
switch(m_choiceActivePower->GetSelection()) {
case 0: {
- data.activePowerUnit = UNIT_PU;
+ data.activePowerUnit = ElectricalUnit::UNIT_PU;
} break;
case 1: {
data.activePowerUnit = UNIT_W;
} break;
case 2: {
- data.activePowerUnit = UNIT_kW;
+ data.activePowerUnit = ElectricalUnit::UNIT_kW;
} break;
case 3: {
- data.activePowerUnit = UNIT_MW;
+ data.activePowerUnit = ElectricalUnit::UNIT_MW;
} break;
}
@@ -163,16 +163,16 @@ bool IndMotorForm::ValidateData()
return false;
switch(m_choiceReactivePower->GetSelection()) {
case 0: {
- data.reactivePowerUnit = UNIT_PU;
+ data.reactivePowerUnit = ElectricalUnit::UNIT_PU;
} break;
case 1: {
- data.reactivePowerUnit = UNIT_VAr;
+ data.reactivePowerUnit = ElectricalUnit::UNIT_VAr;
} break;
case 2: {
- data.reactivePowerUnit = UNIT_kVAr;
+ data.reactivePowerUnit = ElectricalUnit::UNIT_kVAr;
} break;
case 3: {
- data.reactivePowerUnit = UNIT_MVAr;
+ data.reactivePowerUnit = ElectricalUnit::UNIT_MVAr;
} break;
}
diff --git a/Project/Inductor.cpp b/Project/Inductor.cpp
index 9bfd599..8bd056d 100644
--- a/Project/Inductor.cpp
+++ b/Project/Inductor.cpp
@@ -110,6 +110,75 @@ void Inductor::Draw(wxPoint2DDouble translation, double scale) const
}
}
+void Inductor::DrawDC(wxPoint2DDouble translation, double scale, wxGraphicsContext* gc) const
+{
+ OpenGLColour elementColour;
+ if (m_online) {
+ if (m_dynEvent)
+ elementColour = m_dynamicEventColour;
+ else
+ elementColour = m_onlineElementColour;
+ }
+ else
+ elementColour = m_offlineElementColour;
+
+ if (m_inserted) {
+ if (m_selected) {
+ gc->SetPen(wxPen(wxColour(m_selectionColour.GetDcRGBA()), 2 + m_borderSize * 2.0));
+ gc->SetBrush(*wxTRANSPARENT_BRUSH);
+
+ gc->DrawLines(m_pointList.size(), &m_pointList[0]);
+
+ // Push the current matrix on stack.
+ gc->PushState();
+ // Rotate the matrix around the object position.
+ gc->Translate(m_position.m_x, m_position.m_y);
+ gc->Rotate(wxDegToRad(m_angle));
+ gc->Translate(-m_position.m_x, -m_position.m_y);
+
+ DrawDCArc(m_position + wxPoint2DDouble(0, -m_height / 2.0 + 10.0), 10, 45, 270, 30, gc);
+ DrawDCArc(m_position + wxPoint2DDouble(0, -m_height / 2.0 + 25.0), 10, 45, 315, 30, gc);
+ DrawDCArc(m_position + wxPoint2DDouble(0, -m_height / 2.0 + 40.0), 10, 90, 315, 30, gc);
+
+ DrawDCGround(m_position + wxPoint2DDouble(0, -m_height / 2.0 + 50.0), gc);
+
+ gc->PopState();
+
+ // Draw node selection.
+ gc->SetPen(*wxTRANSPARENT_PEN);
+ gc->SetBrush(wxBrush(wxColour(m_selectionColour.GetDcRGBA())));
+ DrawDCCircle(m_pointList[0], 5.0 + m_borderSize / scale, 10, gc);
+ }
+ // Draw Inductor (layer 2).
+ gc->SetPen(*wxTRANSPARENT_PEN);
+ gc->SetBrush(wxBrush(wxColour(elementColour.GetDcRGBA())));
+ DrawDCCircle(m_pointList[0], 5.0, 10, gc);
+
+ gc->SetPen(wxPen(wxColour(elementColour.GetDcRGBA()), 2));
+ gc->SetBrush(*wxTRANSPARENT_BRUSH);
+ gc->DrawLines(m_pointList.size(), &m_pointList[0]);
+
+ DrawDCSwitches(gc);
+
+ // Push the current matrix on stack.
+ gc->PushState();
+ // Rotate the matrix around the object position.
+ gc->Translate(m_position.m_x, m_position.m_y);
+ gc->Rotate(wxDegToRad(m_angle));
+ gc->Translate(-m_position.m_x, -m_position.m_y);
+
+ gc->SetPen(wxPen(wxColour(elementColour.GetDcRGBA()), 2));
+ gc->SetBrush(*wxTRANSPARENT_BRUSH);
+ DrawDCArc(m_position + wxPoint2DDouble(0, -m_height / 2.0 + 10.0), 10, 45, 270, 10, gc);
+ DrawDCArc(m_position + wxPoint2DDouble(0, -m_height / 2.0 + 25.0), 10, 45, 315, 10, gc);
+ DrawDCArc(m_position + wxPoint2DDouble(0, -m_height / 2.0 + 40.0), 10, 90, 315, 10, gc);
+
+ DrawDCGround(m_position + wxPoint2DDouble(0, -m_height / 2.0 + 50.0), gc);
+
+ gc->PopState();
+ }
+}
+
void Inductor::Rotate(bool clockwise)
{
double rotAngle = m_rotationAngle;
@@ -152,17 +221,17 @@ InductorElectricalData Inductor::GetPUElectricalData(double systemPowerBase)
{
InductorElectricalData data = m_electricalData;
switch(data.reactivePowerUnit) {
- case UNIT_VAr: {
+ case ElectricalUnit::UNIT_VAr: {
data.reactivePower = data.reactivePower / systemPowerBase;
- data.reactivePowerUnit = UNIT_PU;
+ data.reactivePowerUnit = ElectricalUnit::UNIT_PU;
} break;
- case UNIT_kVAr: {
+ case ElectricalUnit::UNIT_kVAr: {
data.reactivePower = (data.reactivePower * 1e3) / systemPowerBase;
- data.reactivePowerUnit = UNIT_PU;
+ data.reactivePowerUnit = ElectricalUnit::UNIT_PU;
} break;
- case UNIT_MVAr: {
+ case ElectricalUnit::UNIT_MVAr: {
data.reactivePower = (data.reactivePower * 1e6) / systemPowerBase;
- data.reactivePowerUnit = UNIT_PU;
+ data.reactivePowerUnit = ElectricalUnit::UNIT_PU;
} break;
default:
break;
@@ -193,16 +262,16 @@ wxString Inductor::GetTipText() const
tipText += "\n";
tipText += _("\nQ = ") + wxString::FromDouble(reactivePower, 5);
switch(m_electricalData.reactivePowerUnit) {
- case UNIT_PU: {
+ case ElectricalUnit::UNIT_PU: {
tipText += _(" p.u.");
} break;
- case UNIT_VAr: {
+ case ElectricalUnit::UNIT_VAr: {
tipText += _(" VAr");
} break;
- case UNIT_kVAr: {
+ case ElectricalUnit::UNIT_kVAr: {
tipText += _(" kVAr");
} break;
- case UNIT_MVAr: {
+ case ElectricalUnit::UNIT_MVAr: {
tipText += _(" MVAr");
} break;
default:
diff --git a/Project/Inductor.h b/Project/Inductor.h
index 0362dcf..d613a4c 100644
--- a/Project/Inductor.h
+++ b/Project/Inductor.h
@@ -25,7 +25,7 @@ class ReactiveShuntElementForm;
struct InductorElectricalData {
wxString name;
double reactivePower = 100.0;
- ElectricalUnit reactivePowerUnit = UNIT_MVAr;
+ ElectricalUnit reactivePowerUnit = ElectricalUnit::UNIT_MVAr;
};
/**
@@ -45,6 +45,7 @@ class Inductor : public Shunt
virtual Element* GetCopy();
virtual bool AddParent(Element* parent, wxPoint2DDouble position);
virtual void Draw(wxPoint2DDouble translation, double scale) const;
+ virtual void DrawDC(wxPoint2DDouble translation, double scale, wxGraphicsContext* gc) const;
virtual bool Contains(wxPoint2DDouble position) const;
virtual bool Intersects(wxRect2DDouble rect) const;
virtual void Rotate(bool clockwise = true);
diff --git a/Project/Limiter.cpp b/Project/Limiter.cpp
index 74fbf3d..33ecb66 100644
--- a/Project/Limiter.cpp
+++ b/Project/Limiter.cpp
@@ -21,9 +21,9 @@
Limiter::Limiter(int id) : ControlElement(id)
{
m_width = m_height = 36.0;
- Node* nodeIn = new Node(m_position + wxPoint2DDouble(-18, 0), Node::NODE_IN, m_borderSize);
+ Node* nodeIn = new Node(m_position + wxPoint2DDouble(-18, 0), Node::NodeType::NODE_IN, m_borderSize);
nodeIn->StartMove(m_position);
- Node* nodeOut = new Node(m_position + wxPoint2DDouble(18, 0), Node::NODE_OUT, m_borderSize);
+ Node* nodeOut = new Node(m_position + wxPoint2DDouble(18, 0), Node::NodeType::NODE_OUT, m_borderSize);
nodeOut->SetAngle(180.0);
nodeOut->StartMove(m_position);
m_nodeList.push_back(nodeIn);
diff --git a/Project/Line.cpp b/Project/Line.cpp
index d143355..9750b82 100644
--- a/Project/Line.cpp
+++ b/Project/Line.cpp
@@ -101,6 +101,80 @@ void Line::Draw(wxPoint2DDouble translation, double scale) const
}
}
+void Line::DrawDC(wxPoint2DDouble translation, double scale, wxGraphicsContext* gc) const
+{
+ //gc->SetBrush(*wxTRANSPARENT_BRUSH);
+
+ wxGraphicsMatrix identityMatrix = gc->GetTransform();
+ identityMatrix.Set(); // Set to identity
+
+ OpenGLColour elementColour;
+ if (m_online) {
+ if (m_dynEvent)
+ elementColour = m_dynamicEventColour;
+ else
+ elementColour = m_onlineElementColour;
+
+ }
+ else
+ elementColour = m_offlineElementColour;
+
+ std::vector<wxPoint2DDouble> pointList = m_pointList;
+ if (!m_inserted && pointList.size() > 0) {
+ wxPoint2DDouble secondPoint = m_position;
+ if (pointList.size() > 2) { secondPoint = pointList[2]; }
+ pointList[1] = GetSwitchPoint(m_parentList[0], pointList[0], secondPoint);
+ pointList.push_back(m_position);
+ }
+
+ // Line selected (Layer 1).
+ if (m_selected) {
+ gc->SetPen(wxPen(wxColour(m_selectionColour.GetDcRGBA()), 2 + m_borderSize * 2.0));
+ gc->SetBrush(*wxTRANSPARENT_BRUSH);
+ if (pointList.size() > 0)
+ gc->DrawLines(pointList.size(), &pointList[0]);
+
+ // Draw nodes selection.
+ gc->SetPen(*wxTRANSPARENT_PEN);
+ gc->SetBrush(wxBrush(wxColour(m_selectionColour.GetDcRGBA())));
+ if (pointList.size() > 0) {
+ DrawDCCircle(pointList[0], 5.0 + m_borderSize / scale, 10, gc);
+ if (m_inserted) { DrawDCCircle(pointList[pointList.size() - 1], 5.0 + m_borderSize / scale, 10, gc); }
+ }
+ }
+
+ // Draw line (Layer 2)
+ gc->SetPen(wxPen(wxColour(elementColour.GetDcRGBA()), 2));
+ gc->SetBrush(*wxTRANSPARENT_BRUSH);
+ if(pointList.size() > 0)
+ gc->DrawLines(pointList.size(), &pointList[0]);
+
+ if (m_inserted) {
+ DrawDCSwitches(gc);
+ DrawDCPowerFlowPts(gc);
+ }
+
+ // Draw nodes.
+ gc->SetPen(*wxTRANSPARENT_PEN);
+ gc->SetBrush(wxBrush(wxColour(elementColour.GetDcRGBA())));
+ if (pointList.size() > 0) {
+ DrawDCCircle(pointList[0], 5.0, 10, gc);
+ if (m_inserted) { DrawDCCircle(pointList[pointList.size() - 1], 5.0, 10, gc); }
+ }
+
+ // Draw pickboxes (Layer 3).
+ if (m_showPickbox) {
+ gc->PushState();
+ gc->SetTransform(identityMatrix);
+
+ for (int i = 2; i < (int)m_pointList.size() - 2; i++) {
+ DrawDCPickbox(WorldToScreen(m_pointList[i], translation - wxPoint2DDouble(4 / scale, 4 / scale), scale), gc);
+ }
+
+ gc->PopState();
+ }
+}
+
void Line::Move(wxPoint2DDouble position)
{
if(!m_parentList[0]) {
@@ -445,13 +519,13 @@ void Line::UpdatePowerFlowArrowsPosition()
{
std::vector<wxPoint2DDouble> edges;
switch(m_pfDirection) {
- case PF_NONE: {
+ case PowerFlowDirection::PF_NONE: {
m_powerFlowArrow.clear();
} break;
- case PF_BUS1_TO_BUS2: {
+ case PowerFlowDirection::PF_BUS1_TO_BUS2: {
for(int i = 1; i < (int)m_pointList.size() - 1; i++) { edges.push_back(m_pointList[i]); }
} break;
- case PF_BUS2_TO_BUS1: {
+ case PowerFlowDirection::PF_BUS2_TO_BUS1: {
for(int i = (int)m_pointList.size() - 2; i > 0; i--) { edges.push_back(m_pointList[i]); }
} break;
default:
@@ -521,33 +595,33 @@ LineElectricalData Line::GetPUElectricalData(double systemBasePower)
// Resistance
double r = data.resistance;
- if(data.resistanceUnit == UNIT_OHM_km) r *= data.lineSize;
- if(data.resistanceUnit == UNIT_PU) {
+ if(data.resistanceUnit == ElectricalUnit::UNIT_OHM_km) r *= data.lineSize;
+ if(data.resistanceUnit == ElectricalUnit::UNIT_PU) {
if(data.useLinePower) data.resistance = (r * lineBaseImpedance) / systemBaseImpedance;
} else {
data.resistance = r / systemBaseImpedance;
}
- data.resistanceUnit = UNIT_PU;
+ data.resistanceUnit = ElectricalUnit::UNIT_PU;
// Inductive reactance
double x = data.indReactance;
- if(data.indReactanceUnit == UNIT_OHM_km) x *= data.lineSize;
- if(data.indReactanceUnit == UNIT_PU) {
+ if(data.indReactanceUnit == ElectricalUnit::UNIT_OHM_km) x *= data.lineSize;
+ if(data.indReactanceUnit == ElectricalUnit::UNIT_PU) {
if(data.useLinePower) data.indReactance = (x * lineBaseImpedance) / systemBaseImpedance;
} else {
data.indReactance = x / systemBaseImpedance;
}
- data.indReactanceUnit = UNIT_PU;
+ data.indReactanceUnit = ElectricalUnit::UNIT_PU;
// Capacitive susceptance
double b = data.capSusceptance;
- if(data.capSusceptanceUnit == UNIT_OHM_km) b *= data.lineSize;
- if(data.capSusceptanceUnit == UNIT_PU) {
+ if(data.capSusceptanceUnit == ElectricalUnit::UNIT_OHM_km) b *= data.lineSize;
+ if(data.capSusceptanceUnit == ElectricalUnit::UNIT_PU) {
if(data.useLinePower) data.capSusceptance = (b * lineBaseImpedance) / systemBaseImpedance;
} else {
data.capSusceptance = b / systemBaseImpedance;
}
- data.capSusceptanceUnit = UNIT_PU;
+ data.capSusceptanceUnit = ElectricalUnit::UNIT_PU;
// Fault
diff --git a/Project/Line.h b/Project/Line.h
index 75df0f2..3597367 100644
--- a/Project/Line.h
+++ b/Project/Line.h
@@ -25,15 +25,15 @@ struct LineElectricalData {
// General
wxString name = "";
double nominalVoltage = 138.0;
- ElectricalUnit nominalVoltageUnit = UNIT_kV;
+ ElectricalUnit nominalVoltageUnit = ElectricalUnit::UNIT_kV;
double nominalPower = 100.0;
- ElectricalUnit nominalPowerUnit = UNIT_MVA;
+ ElectricalUnit nominalPowerUnit = ElectricalUnit::UNIT_MVA;
double resistance = 0.0;
- ElectricalUnit resistanceUnit = UNIT_PU;
+ ElectricalUnit resistanceUnit = ElectricalUnit::UNIT_PU;
double indReactance = 1.0;
- ElectricalUnit indReactanceUnit = UNIT_PU;
+ ElectricalUnit indReactanceUnit = ElectricalUnit::UNIT_PU;
double capSusceptance = 0.0;
- ElectricalUnit capSusceptanceUnit = UNIT_PU;
+ ElectricalUnit capSusceptanceUnit = ElectricalUnit::UNIT_PU;
double lineSize = 100.0;
bool useLinePower = false;
@@ -64,6 +64,7 @@ class Line : public Branch
~Line();
virtual bool Contains(wxPoint2DDouble position) const;
virtual void Draw(wxPoint2DDouble translation, double scale) const;
+ virtual void DrawDC(wxPoint2DDouble translation, double scale, wxGraphicsContext* gc) const;
virtual void Move(wxPoint2DDouble position);
virtual void StartMove(wxPoint2DDouble position);
virtual void MoveNode(Element* parent, wxPoint2DDouble position);
diff --git a/Project/LineForm.cpp b/Project/LineForm.cpp
index f0df0c7..204595a 100644
--- a/Project/LineForm.cpp
+++ b/Project/LineForm.cpp
@@ -47,10 +47,10 @@ LineForm::LineForm(wxWindow* parent, Line* line) : LineFormBase(parent)
wxString nominalVoltageStr = Line::StringFromDouble(data.nominalVoltage);
switch(data.nominalVoltageUnit) {
- case UNIT_V: {
+ case ElectricalUnit::UNIT_V: {
nominalVoltageStr += " V";
} break;
- case UNIT_kV: {
+ case ElectricalUnit::UNIT_kV: {
nominalVoltageStr += " kV";
} break;
default:
@@ -60,13 +60,13 @@ LineForm::LineForm(wxWindow* parent, Line* line) : LineFormBase(parent)
m_textCtrlNominalPower->SetValue(Line::StringFromDouble(data.nominalPower));
switch(data.nominalPowerUnit) {
- case UNIT_VA: {
+ case ElectricalUnit::UNIT_VA: {
m_choiceNominalPower->SetSelection(0);
} break;
- case UNIT_kVA: {
+ case ElectricalUnit::UNIT_kVA: {
m_choiceNominalPower->SetSelection(1);
} break;
- case UNIT_MVA: {
+ case ElectricalUnit::UNIT_MVA: {
m_choiceNominalPower->SetSelection(2);
} break;
default:
@@ -75,13 +75,13 @@ LineForm::LineForm(wxWindow* parent, Line* line) : LineFormBase(parent)
m_textCtrlResistance->SetValue(Line::StringFromDouble(data.resistance));
switch(data.resistanceUnit) {
- case UNIT_PU: {
+ case ElectricalUnit::UNIT_PU: {
m_choiceResistance->SetSelection(0);
} break;
- case UNIT_OHM: {
+ case ElectricalUnit::UNIT_OHM: {
m_choiceResistance->SetSelection(1);
} break;
- case UNIT_OHM_km: {
+ case ElectricalUnit::UNIT_OHM_km: {
m_choiceResistance->SetSelection(2);
} break;
default:
@@ -90,13 +90,13 @@ LineForm::LineForm(wxWindow* parent, Line* line) : LineFormBase(parent)
m_textCtrlReactance->SetValue(Line::StringFromDouble(data.indReactance));
switch(data.indReactanceUnit) {
- case UNIT_PU: {
+ case ElectricalUnit::UNIT_PU: {
m_choiceReactance->SetSelection(0);
} break;
- case UNIT_OHM: {
+ case ElectricalUnit::UNIT_OHM: {
m_choiceReactance->SetSelection(1);
} break;
- case UNIT_OHM_km: {
+ case ElectricalUnit::UNIT_OHM_km: {
m_choiceReactance->SetSelection(2);
} break;
default:
@@ -105,13 +105,13 @@ LineForm::LineForm(wxWindow* parent, Line* line) : LineFormBase(parent)
m_textCtrlSusceptance->SetValue(Line::StringFromDouble(data.capSusceptance));
switch(data.capSusceptanceUnit) {
- case UNIT_PU: {
+ case ElectricalUnit::UNIT_PU: {
m_choiceSusceptance->SetSelection(0);
} break;
- case UNIT_S: {
+ case ElectricalUnit::UNIT_S: {
m_choiceSusceptance->SetSelection(1);
} break;
- case UNIT_S_km: {
+ case ElectricalUnit::UNIT_S_km: {
m_choiceSusceptance->SetSelection(2);
} break;
default:
@@ -161,13 +161,13 @@ bool LineForm::ValidateData()
return false;
switch(m_choiceNominalPower->GetSelection()) {
case 0: {
- data.nominalPowerUnit = UNIT_VA;
+ data.nominalPowerUnit = ElectricalUnit::UNIT_VA;
} break;
case 1: {
- data.nominalPowerUnit = UNIT_kVA;
+ data.nominalPowerUnit = ElectricalUnit::UNIT_kVA;
} break;
case 2: {
- data.nominalPowerUnit = UNIT_MVA;
+ data.nominalPowerUnit = ElectricalUnit::UNIT_MVA;
} break;
}
@@ -176,13 +176,13 @@ bool LineForm::ValidateData()
return false;
switch(m_choiceResistance->GetSelection()) {
case 0: {
- data.resistanceUnit = UNIT_PU;
+ data.resistanceUnit = ElectricalUnit::UNIT_PU;
} break;
case 1: {
- data.resistanceUnit = UNIT_OHM;
+ data.resistanceUnit = ElectricalUnit::UNIT_OHM;
} break;
case 2: {
- data.resistanceUnit = UNIT_OHM_km;
+ data.resistanceUnit = ElectricalUnit::UNIT_OHM_km;
} break;
}
@@ -191,13 +191,13 @@ bool LineForm::ValidateData()
return false;
switch(m_choiceReactance->GetSelection()) {
case 0: {
- data.indReactanceUnit = UNIT_PU;
+ data.indReactanceUnit = ElectricalUnit::UNIT_PU;
} break;
case 1: {
- data.indReactanceUnit = UNIT_OHM;
+ data.indReactanceUnit = ElectricalUnit::UNIT_OHM;
} break;
case 2: {
- data.indReactanceUnit = UNIT_OHM_km;
+ data.indReactanceUnit = ElectricalUnit::UNIT_OHM_km;
} break;
}
@@ -206,13 +206,13 @@ bool LineForm::ValidateData()
return false;
switch(m_choiceSusceptance->GetSelection()) {
case 0: {
- data.capSusceptanceUnit = UNIT_PU;
+ data.capSusceptanceUnit = ElectricalUnit::UNIT_PU;
} break;
case 1: {
- data.capSusceptanceUnit = UNIT_S;
+ data.capSusceptanceUnit = ElectricalUnit::UNIT_S;
} break;
case 2: {
- data.capSusceptanceUnit = UNIT_S_km;
+ data.capSusceptanceUnit = ElectricalUnit::UNIT_S_km;
} break;
}
diff --git a/Project/Load.cpp b/Project/Load.cpp
index d9f1b2a..22c9cd9 100644
--- a/Project/Load.cpp
+++ b/Project/Load.cpp
@@ -116,6 +116,75 @@ void Load::Draw(wxPoint2DDouble translation, double scale) const
}
}
+void Load::DrawDC(wxPoint2DDouble translation, double scale, wxGraphicsContext* gc) const
+{
+ OpenGLColour elementColour;
+ if (m_online) {
+ if (m_dynEvent)
+ elementColour = m_dynamicEventColour;
+ else
+ elementColour = m_onlineElementColour;
+ }
+ else
+ elementColour = m_offlineElementColour;
+
+ if (m_inserted) {
+ // Draw Selection (layer 1).
+ if (m_selected) {
+ gc->SetPen(wxPen(wxColour(m_selectionColour.GetDcRGBA()), 2 + m_borderSize * 2.0));
+ gc->SetBrush(*wxTRANSPARENT_BRUSH);
+
+ gc->DrawLines(m_pointList.size(), &m_pointList[0]);
+
+ gc->SetPen(*wxTRANSPARENT_PEN);
+ gc->SetBrush(wxBrush(wxColour(m_selectionColour.GetDcRGBA())));
+
+ std::vector<wxPoint2DDouble> selTriangPts;
+ selTriangPts.push_back(m_triangPts[0] + m_position +
+ wxPoint2DDouble(-m_borderSize / scale, -m_borderSize / scale));
+ selTriangPts.push_back(m_triangPts[1] + m_position +
+ wxPoint2DDouble(m_borderSize / scale, -m_borderSize / scale));
+ selTriangPts.push_back(m_triangPts[2] + m_position + wxPoint2DDouble(0.0, m_borderSize / scale));
+
+ // Push the current matrix on stack.
+ gc->PushState();
+ // Rotate the matrix around the object position.
+ gc->Translate(m_position.m_x, m_position.m_y);
+ gc->Rotate(wxDegToRad(m_angle));
+ gc->Translate(-m_position.m_x, -m_position.m_y);
+ DrawDCTriangle(selTriangPts, gc);
+ gc->PopState();
+
+ // Draw node selection.
+ DrawDCCircle(m_pointList[0], 5.0 + m_borderSize / scale, 10, gc);
+ }
+
+ // Draw Load (layer 2).
+ gc->SetPen(wxPen(wxColour(elementColour.GetDcRGBA()), 2));
+ gc->SetBrush(*wxTRANSPARENT_BRUSH);
+ gc->DrawLines(m_pointList.size(), &m_pointList[0]);
+
+ // Draw node.
+ gc->SetPen(*wxTRANSPARENT_PEN);
+ gc->SetBrush(wxBrush(wxColour(elementColour.GetDcRGBA())));
+ DrawDCCircle(m_pointList[0], 5.0, 10, gc);
+
+ DrawDCSwitches(gc);
+ DrawDCPowerFlowPts(gc);
+
+ std::vector<wxPoint2DDouble> triangPts;
+ for (int i = 0; i < 3; i++) { triangPts.push_back(m_triangPts[i] + m_position); }
+ gc->PushState();
+ gc->Translate(m_position.m_x, m_position.m_y);
+ gc->Rotate(wxDegToRad(m_angle));
+ gc->Translate(-m_position.m_x, -m_position.m_y);
+ gc->SetPen(*wxTRANSPARENT_PEN);
+ gc->SetBrush(wxBrush(wxColour(elementColour.GetDcRGBA())));
+ DrawDCTriangle(triangPts, gc);
+ gc->PopState();
+ }
+}
+
void Load::Rotate(bool clockwise)
{
double rotAngle = m_rotationAngle;
diff --git a/Project/Load.h b/Project/Load.h
index 4fa01ad..56b1549 100644
--- a/Project/Load.h
+++ b/Project/Load.h
@@ -80,13 +80,14 @@ class Load : public Shunt
virtual Element* GetCopy();
virtual bool AddParent(Element* parent, wxPoint2DDouble position);
virtual void Draw(wxPoint2DDouble translation, double scale) const;
+ virtual void DrawDC(wxPoint2DDouble translation, double scale, wxGraphicsContext* gc) const;
virtual void Rotate(bool clockwise = true);
virtual bool GetContextMenu(wxMenu& menu);
virtual wxString GetTipText() const;
virtual bool ShowForm(wxWindow* parent, Element* element);
LoadElectricalData GetElectricalData() { return m_electricalData; }
LoadElectricalData GetPUElectricalData(double systemPowerBase);
- void SetElectricalData(LoadElectricalData electricalData) { m_electricalData = electricalData; }
+ void SetElectricalData(const LoadElectricalData& electricalData) { m_electricalData = electricalData; }
virtual bool GetPlotData(ElementPlotData& plotData, PlotStudy study = STABILITY);
virtual rapidxml::xml_node<>* SaveElement(rapidxml::xml_document<>& doc, rapidxml::xml_node<>* elementListNode);
diff --git a/Project/Machines.cpp b/Project/Machines.cpp
index 8ee940f..351fd16 100644
--- a/Project/Machines.cpp
+++ b/Project/Machines.cpp
@@ -98,6 +98,60 @@ void Machines::Draw(wxPoint2DDouble translation, double scale) const
}
}
+void Machines::DrawDC(wxPoint2DDouble translation, double scale, wxGraphicsContext* gc) const
+{
+ OpenGLColour elementColour;
+ if (m_online) {
+ if (m_dynEvent)
+ elementColour = m_dynamicEventColour;
+ else
+ elementColour = m_onlineElementColour;
+ }
+ else
+ elementColour = m_offlineElementColour;
+
+ if (m_inserted) {
+ // Draw Selection (layer 1).
+ if (m_selected) {
+ gc->SetPen(wxPen(wxColour(m_selectionColour.GetDcRGBA()), 2 + m_borderSize * 2.0));
+ gc->SetBrush(*wxTRANSPARENT_BRUSH);
+ gc->DrawLines(m_pointList.size(), &m_pointList[0]);
+
+ gc->SetPen(*wxTRANSPARENT_PEN);
+ gc->SetBrush(wxBrush(wxColour(m_selectionColour.GetDcRGBA())));
+ DrawDCCircle(m_position, 25.0 + (m_borderSize + 1.5) / scale, 20, gc);
+
+ // Draw nodes selection.
+ DrawDCCircle(m_pointList[0], 5.0 + m_borderSize / scale, 10, gc);
+ }
+
+ // Draw Machines (layer 2).
+ // Draw node.
+ gc->SetPen(*wxTRANSPARENT_PEN);
+ gc->SetBrush(wxBrush(wxColour(elementColour.GetDcRGBA())));
+ DrawDCCircle(m_pointList[0], 5.0, 10, gc);
+
+ gc->SetPen(wxPen(wxColour(elementColour.GetDcRGBA()), 2));
+ gc->SetBrush(*wxTRANSPARENT_BRUSH);
+ gc->DrawLines(m_pointList.size(), &m_pointList[0]);
+ DrawDCCircle(m_position, 25.0, 20.0, gc);
+
+ DrawDCSwitches(gc);
+ DrawDCPowerFlowPts(gc);
+
+ gc->SetPen(*wxTRANSPARENT_PEN);
+ gc->SetBrush(*wxWHITE_BRUSH);
+ DrawDCCircle(m_position, 25.0, 20.0, gc);
+
+ gc->SetPen(wxPen(wxColour(elementColour.GetDcRGBA()), 2));
+ gc->SetBrush(*wxTRANSPARENT_BRUSH);
+ DrawDCCircle(m_position, 25.0, 20.0, gc);
+
+ // Draw machine symbol.
+ DrawDCSymbol(gc);
+ }
+}
+
void Machines::UpdateSwitchesPosition()
{
if(m_parentList[0]) {
@@ -246,14 +300,14 @@ void Machines::UpdatePowerFlowArrowsPosition()
{
std::vector<wxPoint2DDouble> edges;
switch(m_pfDirection) {
- case PF_NONE: {
+ case PowerFlowDirection::PF_NONE: {
m_powerFlowArrow.clear();
} break;
- case PF_TO_BUS: {
+ case PowerFlowDirection::PF_TO_BUS: {
edges.push_back(m_pointList[2]);
edges.push_back(m_pointList[1]);
} break;
- case PF_TO_ELEMENT: {
+ case PowerFlowDirection::PF_TO_ELEMENT: {
edges.push_back(m_pointList[1]);
edges.push_back(m_pointList[2]);
} break;
diff --git a/Project/Machines.h b/Project/Machines.h
index db6f449..e3aa844 100644
--- a/Project/Machines.h
+++ b/Project/Machines.h
@@ -41,6 +41,7 @@ class Machines : public PowerElement
virtual bool AddParent(Element* parent, wxPoint2DDouble position);
virtual bool Contains(wxPoint2DDouble position) const { return m_rect.Contains(position); }
virtual void Draw(wxPoint2DDouble translation, double scale) const;
+ virtual void DrawDC(wxPoint2DDouble translation, double scale, wxGraphicsContext* gc) const;
virtual bool Intersects(wxRect2DDouble rect) const { return m_rect.Intersects(rect); }
virtual void Move(wxPoint2DDouble position);
virtual void MoveNode(Element* element, wxPoint2DDouble position);
@@ -52,6 +53,7 @@ class Machines : public PowerElement
virtual void UpdateNodes();
virtual void Rotate(bool clockwise = true);
virtual void DrawSymbol() const {}
+ virtual void DrawDCSymbol(wxGraphicsContext* gc) const {}
virtual void SetPowerFlowDirection(PowerFlowDirection pfDirection);
protected:
diff --git a/Project/MainFrame.cpp b/Project/MainFrame.cpp
index 3447ed5..36712d5 100644
--- a/Project/MainFrame.cpp
+++ b/Project/MainFrame.cpp
@@ -37,6 +37,7 @@
#include "Transformer.h"
#include "Workspace.h"
#include "artProvider/ArtMetro.h"
+#include "WorkspaceDC.h"
MainFrame::MainFrame() : MainFrameBase(NULL) {}
MainFrame::MainFrame(wxWindow* parent, wxLocale* locale, PropertiesData* initProperties, wxString openPath)
@@ -50,7 +51,7 @@ MainFrame::MainFrame(wxWindow* parent, wxLocale* locale, PropertiesData* initPro
if(openPath != "") {
EnableCurrentProjectRibbon();
Workspace* newWorkspace = new Workspace(this, _("Open project"), this->GetStatusBar(), m_sharedGLContext);
- if(!m_sharedGLContext) m_sharedGLContext = newWorkspace->GetOpenGLContext();
+ if(!m_sharedGLContext) m_sharedGLContext = newWorkspace->GetSharedGLContext();
FileHanding fileHandling(newWorkspace);
if(fileHandling.OpenProject(openPath)) {
@@ -192,9 +193,19 @@ void MainFrame::OnNewClick(wxRibbonButtonBarEvent& event)
{
EnableCurrentProjectRibbon();
- Workspace* newWorkspace = new Workspace(this, wxString::Format(_("New project %d"), m_projectNumber),
- this->GetStatusBar(), m_sharedGLContext);
- if(!m_sharedGLContext) m_sharedGLContext = newWorkspace->GetOpenGLContext();
+ Workspace* newWorkspace;
+ if (m_generalProperties->GetGeneralPropertiesData().useOpenGL) {
+ newWorkspace = new Workspace(this, wxString::Format(_("New project %d"), m_projectNumber),
+ this->GetStatusBar(), m_sharedGLContext);
+ if (!m_sharedGLContext) m_sharedGLContext = newWorkspace->GetSharedGLContext();
+ }
+ else {
+ newWorkspace = new WorkspaceDC(this, wxString::Format(_("New project %d"), m_projectNumber),
+ this->GetStatusBar());
+ }
+ // Set general properties in new Workspace
+ newWorkspace->GetProperties()->SetGeneralPropertiesData(m_generalProperties->GetGeneralPropertiesData());
+
m_workspaceList.push_back(newWorkspace);
m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_DISABLESOL, true);
@@ -308,9 +319,22 @@ void MainFrame::OnOpenClick(wxRibbonButtonBarEvent& event)
wxFileName fileName(openFileDialog.GetPath());
EnableCurrentProjectRibbon();
- Workspace* newWorkspace = new Workspace(this, _("Open project"), this->GetStatusBar(), m_sharedGLContext);
- if(!m_sharedGLContext) m_sharedGLContext = newWorkspace->GetOpenGLContext();
+ Workspace* newWorkspace;
+ if (m_generalProperties->GetGeneralPropertiesData().useOpenGL) {
+ newWorkspace = new Workspace(this, wxString::Format(_("New project %d"), m_projectNumber),
+ this->GetStatusBar(), m_sharedGLContext);
+ // If none shared OpenGL context is loaded, get from this workspace.
+ if (!m_sharedGLContext) m_sharedGLContext = newWorkspace->GetSharedGLContext();
+ }
+ else {
+ newWorkspace = new WorkspaceDC(this, wxString::Format(_("New project %d"), m_projectNumber),
+ this->GetStatusBar());
+ }
+
+ // Set general properties in new workspace.
+ newWorkspace->GetProperties()->SetGeneralPropertiesData(m_generalProperties->GetGeneralPropertiesData());
+
FileHanding fileHandling(newWorkspace);
if(fileHandling.OpenProject(fileName)) {
newWorkspace->SetSavedPath(fileName);
@@ -507,7 +531,7 @@ void MainFrame::OnImportClick(wxRibbonButtonBarEvent& event)
// Import file(s)
EnableCurrentProjectRibbon();
- if(!m_sharedGLContext) m_sharedGLContext = impWorkspace->GetOpenGLContext();
+ if(!m_sharedGLContext) m_sharedGLContext = impWorkspace->GetSharedGLContext();
m_workspaceList.push_back(impWorkspace);
m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_DISABLESOL, true);
@@ -532,14 +556,14 @@ void MainFrame::NotebookPageClosing(wxAuiNotebookEvent& event)
auto it = m_workspaceList.begin();
while(it != m_workspaceList.end()) {
if(*it == m_auiNotebook->GetCurrentPage()) {
- if((*it)->GetOpenGLContext() == m_sharedGLContext) m_sharedGLContext = NULL;
+ if((*it)->GetSharedGLContext() == m_sharedGLContext) m_sharedGLContext = NULL;
m_workspaceList.erase(it);
break;
}
it++;
}
if(!m_sharedGLContext && m_workspaceList.size() != 0) {
- m_sharedGLContext = m_workspaceList[0]->GetOpenGLContext();
+ m_sharedGLContext = m_workspaceList[0]->GetSharedGLContext();
}
event.Skip();
}
@@ -610,7 +634,7 @@ int MainFrame::RunPSPTest()
Workspace* newWorkspace = new Workspace(this, wxString::Format(_("New project %d"), m_projectNumber),
this->GetStatusBar(), m_sharedGLContext);
- if(!m_sharedGLContext) m_sharedGLContext = newWorkspace->GetOpenGLContext();
+ if(!m_sharedGLContext) m_sharedGLContext = newWorkspace->GetSharedGLContext();
m_workspaceList.push_back(newWorkspace);
m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_DISABLESOL, true);
diff --git a/Project/MainFrameBase.cpp b/Project/MainFrameBase.cpp
index 3e1da85..295b3e6 100644
--- a/Project/MainFrameBase.cpp
+++ b/Project/MainFrameBase.cpp
@@ -261,7 +261,7 @@ MainFrameBase::MainFrameBase(wxWindow* parent,
wxXmlResource::Get()->LoadBitmap(wxT("powerFLow32")),
_("Calculate the circuit power flow"), wxRIBBON_BUTTON_NORMAL);
- m_ribbonButtonBarSimulations->AddButton(ID_RIBBON_RUNSTAB, _("Run Stability"),
+ m_ribbonButtonBarSimulations->AddButton(ID_RIBBON_RUNSTAB, _("Run stability"),
wxXmlResource::Get()->LoadBitmap(wxT("playStopped32")),
_("Run the stability calculations"), wxRIBBON_BUTTON_HYBRID);
diff --git a/Project/MathExpression.cpp b/Project/MathExpression.cpp
index 066825f..e6515b5 100644
--- a/Project/MathExpression.cpp
+++ b/Project/MathExpression.cpp
@@ -45,11 +45,11 @@ MathExpression::MathExpression(int id) : ControlElement(id)
} else {
nodePosition = m_position + wxPoint2DDouble(-m_width / 2, 9 + 18 * i - m_height / 2);
}
- Node* nodeIn = new Node(nodePosition, Node::NODE_IN, m_borderSize);
+ Node* nodeIn = new Node(nodePosition, Node::NodeType::NODE_IN, m_borderSize);
nodeIn->StartMove(m_position);
m_nodeList.push_back(nodeIn);
}
- Node* nodeOut = new Node(m_position + wxPoint2DDouble(m_width / 2, 0), Node::NODE_OUT, m_borderSize);
+ Node* nodeOut = new Node(m_position + wxPoint2DDouble(m_width / 2, 0), Node::NodeType::NODE_OUT, m_borderSize);
nodeOut->SetAngle(180.0);
nodeOut->StartMove(m_position);
m_nodeList.push_back(nodeOut);
@@ -165,7 +165,7 @@ bool MathExpression::Solve(double* input, double timeStep)
int i = 3;
for(auto itN = m_nodeList.begin(), itNEnd = m_nodeList.end(); itN != itNEnd; ++itN) {
Node* node = *itN;
- if(node->GetNodeType() != Node::NODE_OUT) {
+ if(node->GetNodeType() != Node::NodeType::NODE_OUT) {
if(!node->IsConnected()) {
m_inputValues[i] = 0.0; // Node not connected means zero value as input.
} else {
@@ -243,7 +243,7 @@ void MathExpression::UpdatePoints()
void MathExpression::AddInNode()
{
- Node* newNode = new Node(wxPoint2DDouble(0, 0), Node::NODE_IN, m_borderSize);
+ Node* newNode = new Node(wxPoint2DDouble(0, 0), Node::NodeType::NODE_IN, m_borderSize);
newNode->SetAngle(m_angle);
m_nodeList.insert(m_nodeList.end() - 1, newNode);
}
diff --git a/Project/MathOperation.cpp b/Project/MathOperation.cpp
index 5f544ce..c9128aa 100644
--- a/Project/MathOperation.cpp
+++ b/Project/MathOperation.cpp
@@ -21,11 +21,11 @@
MathOperation::MathOperation(int id) : ControlElement(id)
{
m_width = m_height = 36.0;
- Node* nodeIn1 = new Node(m_position + wxPoint2DDouble(-18, -9), Node::NODE_IN, m_borderSize);
+ Node* nodeIn1 = new Node(m_position + wxPoint2DDouble(-18, -9), Node::NodeType::NODE_IN, m_borderSize);
nodeIn1->StartMove(m_position);
- Node* nodeIn2 = new Node(m_position + wxPoint2DDouble(-18, 9), Node::NODE_IN, m_borderSize);
+ Node* nodeIn2 = new Node(m_position + wxPoint2DDouble(-18, 9), Node::NodeType::NODE_IN, m_borderSize);
nodeIn2->StartMove(m_position);
- Node* nodeOut = new Node(m_position + wxPoint2DDouble(18, 0), Node::NODE_OUT, m_borderSize);
+ Node* nodeOut = new Node(m_position + wxPoint2DDouble(18, 0), Node::NodeType::NODE_OUT, m_borderSize);
nodeOut->SetAngle(180.0);
nodeOut->StartMove(m_position);
m_nodeList.push_back(nodeIn1);
diff --git a/Project/Multiplier.cpp b/Project/Multiplier.cpp
index 7a9bcd8..75ce701 100644
--- a/Project/Multiplier.cpp
+++ b/Project/Multiplier.cpp
@@ -38,7 +38,7 @@ bool Multiplier::Solve(double* input, double timeStep)
std::vector<double> inputVector;
for(auto itN = m_nodeList.begin(), itNEnd = m_nodeList.end(); itN != itNEnd; ++itN) {
Node* node = *itN;
- if(node->GetNodeType() != Node::NODE_OUT) {
+ if(node->GetNodeType() != Node::NodeType::NODE_OUT) {
if(!node->IsConnected()) {
inputVector.push_back(1.0);
} else {
diff --git a/Project/OpenGLText.cpp b/Project/OpenGLText.cpp
index 5e1c40b..0dca4eb 100644
--- a/Project/OpenGLText.cpp
+++ b/Project/OpenGLText.cpp
@@ -16,7 +16,9 @@
*/
#include <wx/log.h>
+#include <wx/graphics.h>
#include "OpenGLText.h"
+#include <algorithm>
OpenGLText::OpenGLText() { Init(); }
OpenGLText::OpenGLText(wxString text)
@@ -69,11 +71,40 @@ void OpenGLText::Draw(wxPoint2DDouble position, double angle) const
}
}
+void OpenGLText::DrawDC(wxPoint2DDouble position, wxGraphicsContext* gc, double angle) const
+{
+ gc->SetFont(wxFont(m_fontSize, m_fontFamily, m_fontStyle, m_fontWeight), wxColour(0, 0 , 0 , 255));
+ gc->DrawText(m_text, position.m_x, position.m_y, angle);
+}
+
void OpenGLText::SetText(wxString text)
{
m_text = text;
- TextToBitmap();
- LoadTextTexture();
+ bool contextValid = false;
+#ifdef __LINUX__
+ if(glXGetCurrentContext()) contextValid = true;
+#endif
+#ifdef __APPLE__
+ if(aglGetCurrentContext()) contextValid = true;
+#endif
+#ifdef __WINDOWS__
+ if (wglGetCurrentContext()) contextValid = true;
+#endif
+
+ if (contextValid) {
+ TextToBitmap();
+ LoadTextTexture();
+ }
+ else
+ {
+ // If the context is not valid, the text still can be rendered using wxDC.
+ // So, the text size must be calculated
+ wxFont font = wxFont(m_fontSize, m_fontFamily, m_fontStyle, m_fontWeight);
+
+ wxMemoryDC memDC;
+ memDC.SetFont(font);
+ m_bitmapSize = memDC.GetTextExtent(m_text);
+ }
}
int OpenGLText::RoundToPowerOfTwo(int value, int min)
@@ -81,7 +112,8 @@ int OpenGLText::RoundToPowerOfTwo(int value, int min)
//[Ref] https://stackoverflow.com/questions/466204/rounding-up-to-next-power-of-2
double baseOfTwo = std::log(static_cast<double>(value)) / std::log(2.0);
int powerOfTwo = static_cast<int>(std::pow(2.0, static_cast<int>(std::ceil(baseOfTwo))));
- return std::max(min, powerOfTwo);
+ //return std::max(min, powerOfTwo);
+ return min > powerOfTwo ? min : powerOfTwo;
}
void OpenGLText::TextToBitmap()
diff --git a/Project/OpenGLText.h b/Project/OpenGLText.h
index 5417ad3..885782e 100644
--- a/Project/OpenGLText.h
+++ b/Project/OpenGLText.h
@@ -18,8 +18,10 @@
#ifndef OPENGLTEXT_H
#define OPENGLTEXT_H
+#include <windows.h>
#include <GL/gl.h>
#include <wx/dcmemory.h>
+#include <algorithm>
/**
* @class OpenGLText
@@ -36,6 +38,7 @@ class OpenGLText
virtual ~OpenGLText();
virtual void Draw(wxPoint2DDouble position, double angle = 0.0) const;
+ virtual void DrawDC(wxPoint2DDouble position, wxGraphicsContext* gc, double angle = 0.0) const;
virtual OpenGLText* GetCopy();
virtual void SetText(wxString text);
@@ -54,6 +57,7 @@ class OpenGLText
void TextToBitmap();
void LoadTextTexture();
+
wxString m_text = _("Text");
int m_fontSize = 10;
wxFontWeight m_fontWeight = wxFONTWEIGHT_NORMAL;
diff --git a/Project/PowerElement.cpp b/Project/PowerElement.cpp
index 326c1c8..870a30e 100644
--- a/Project/PowerElement.cpp
+++ b/Project/PowerElement.cpp
@@ -19,6 +19,7 @@
#ifdef USING_WX_3_0_X
#include "DegreesAndRadians.h"
#endif
+#include <wx/brush.h>
PowerElement::PowerElement() : Element()
{
@@ -107,6 +108,36 @@ void PowerElement::DrawSwitches() const
}
}
+void PowerElement::DrawDCSwitches(wxGraphicsContext* gc) const
+{
+ gc->SetPen(*wxTRANSPARENT_PEN);
+
+ int i = 0;
+ for (auto parent : m_parentList) {
+ if (parent) {
+ if (m_online) {
+ gc->SetBrush(wxBrush(wxColour(m_closedSwitchColour.GetDcRGBA())));
+ }
+ else {
+ gc->SetBrush(wxBrush(wxColour(m_openedSwitchColour.GetDcRGBA())));
+ }
+
+ gc->PushState();
+ gc->Translate(m_switchRect[i].GetPosition().m_x + m_switchSize / 2.0,
+ m_switchRect[i].GetPosition().m_y + m_switchSize / 2.0);
+ gc->Rotate(wxDegToRad(parent->GetAngle()));
+ gc->Translate(-m_switchRect[i].GetPosition().m_x - m_switchSize / 2.0,
+ -m_switchRect[i].GetPosition().m_y - m_switchSize / 2.0);
+
+ wxPoint2DDouble switchPos = m_switchRect[i].GetPosition();
+ gc->DrawRectangle(switchPos.m_x, switchPos.m_y, m_switchSize, m_switchSize);
+
+ gc->PopState();
+ }
+ i++;
+ }
+}
+
void PowerElement::CalculatePowerFlowPts(std::vector<wxPoint2DDouble> edges)
{
double arrowRate = 100.0; // One arrow to each "arrowRate" distance in pixels.
@@ -159,6 +190,15 @@ void PowerElement::DrawPowerFlowPts() const
}
}
+void PowerElement::DrawDCPowerFlowPts(wxGraphicsContext* gc) const
+{
+ gc->SetPen(*wxTRANSPARENT_PEN);
+ if (m_online) {
+ gc->SetBrush(wxBrush(wxColour(m_powerFlowArrowColour.GetDcRGBA())));
+ for (auto arrow : m_powerFlowArrow) { DrawDCTriangle(arrow, gc); }
+ }
+}
+
double PowerElement::GetValueFromUnit(double value, ElectricalUnit valueUnit)
{
switch(valueUnit) {
diff --git a/Project/PowerElement.h b/Project/PowerElement.h
index 031834e..2a106cb 100644
--- a/Project/PowerElement.h
+++ b/Project/PowerElement.h
@@ -158,6 +158,11 @@ class PowerElement : public Element
virtual void DrawSwitches() const;
/**
+ * @brief Draw switch using device context.
+ */
+ virtual void DrawDCSwitches(wxGraphicsContext* gc) const;
+
+ /**
* @brief Calculate the points of the power flow arrows.
* @param edges Points of the element that arrows point.
*/
@@ -169,6 +174,12 @@ class PowerElement : public Element
virtual void DrawPowerFlowPts() const;
/**
+ * @brief Draw power flow arrows using device context.
+ * @param gc Device context.
+ */
+ virtual void DrawDCPowerFlowPts(wxGraphicsContext* gc) const;
+
+ /**
* @brief Set nominal voltage of the element.
* @param nominalVoltage Value of the nominal voltage.
* @param nominalVoltageUnit Unit of the nominal voltage.
diff --git a/Project/PowerQuality.cpp b/Project/PowerQuality.cpp
index c8fcd91..6478132 100644
--- a/Project/PowerQuality.cpp
+++ b/Project/PowerQuality.cpp
@@ -183,7 +183,7 @@ bool PowerQuality::CalculateDistortions(double systemPowerBase)
// Bus voltage
double voltage = busData.nominalVoltage;
- if(busData.nominalVoltageUnit == UNIT_kV) voltage *= 1e3;
+ if(busData.nominalVoltageUnit == ElectricalUnit::UNIT_kV) voltage *= 1e3;
auto puData = harmCurrent->GetPUElectricalData(systemPowerBase, voltage);
diff --git a/Project/Project.project b/Project/Project.project
index 82b109b..25c00fe 100644
--- a/Project/Project.project
+++ b/Project/Project.project
@@ -118,6 +118,7 @@
</VirtualDirectory>
</VirtualDirectory>
<VirtualDirectory Name="main GUI">
+ <File Name="WorkspaceDC.cpp"/>
<File Name="Camera.cpp"/>
<File Name="MainFrame.cpp"/>
<File Name="Workspace.cpp"/>
@@ -251,6 +252,7 @@
</VirtualDirectory>
</VirtualDirectory>
<VirtualDirectory Name="main GUI">
+ <File Name="WorkspaceDC.h"/>
<File Name="Camera.h"/>
<File Name="MainFrame.h"/>
<File Name="Workspace.h"/>
diff --git a/Project/PropertiesData.h b/Project/PropertiesData.h
index 588cc00..b8361fe 100644
--- a/Project/PropertiesData.h
+++ b/Project/PropertiesData.h
@@ -28,7 +28,7 @@ enum GUITheme { THEME_LIGHT = 0, THEME_DARK };
struct SimulationData {
// General simulation data
double basePower = 100.0;
- ElectricalUnit basePowerUnit = UNIT_MVA;
+ ElectricalUnit basePowerUnit = ElectricalUnit::UNIT_MVA;
bool faultAfterPowerFlow = false;
bool scPowerAfterPowerFlow = false;
bool harmDistortionAfterPowerFlow = false;
@@ -42,7 +42,7 @@ struct SimulationData {
double newtonInertia = 1.0;
double gaussTolerance = 1e-2;
- // Stability
+ // stability
double stabilityFrequency = 60.0;
double timeStep = 1e-2;
double stabilitySimulationTime = 10.0;
@@ -67,6 +67,7 @@ struct SimulationData {
struct GeneralData {
wxLanguage language = wxLANGUAGE_ENGLISH;
GUITheme theme = THEME_LIGHT;
+ bool useOpenGL = true;
};
struct FreqResponseData {
diff --git a/Project/PropertiesForm.wxcp b/Project/PropertiesForm.wxcp
index 63265ec..367e85e 100644
--- a/Project/PropertiesForm.wxcp
+++ b/Project/PropertiesForm.wxcp
@@ -3727,7 +3727,7 @@
}, {
"type": "string",
"m_label": "Label:",
- "m_value": "Stability"
+ "m_value": "stability"
}, {
"type": "bitmapPicker",
"m_label": "Bitmap File:",
diff --git a/Project/RateLimiter.cpp b/Project/RateLimiter.cpp
index dedd910..94b61ac 100644
--- a/Project/RateLimiter.cpp
+++ b/Project/RateLimiter.cpp
@@ -21,9 +21,9 @@
RateLimiter::RateLimiter(int id) : ControlElement(id)
{
m_width = m_height = 36.0;
- Node* nodeIn = new Node(m_position + wxPoint2DDouble(-18, 0), Node::NODE_IN, m_borderSize);
+ Node* nodeIn = new Node(m_position + wxPoint2DDouble(-18, 0), Node::NodeType::NODE_IN, m_borderSize);
nodeIn->StartMove(m_position);
- Node* nodeOut = new Node(m_position + wxPoint2DDouble(18, 0), Node::NODE_OUT, m_borderSize);
+ Node* nodeOut = new Node(m_position + wxPoint2DDouble(18, 0), Node::NodeType::NODE_OUT, m_borderSize);
nodeOut->SetAngle(180.0);
nodeOut->StartMove(m_position);
m_nodeList.push_back(nodeIn);
diff --git a/Project/ReactiveShuntElementForm.cpp b/Project/ReactiveShuntElementForm.cpp
index 985127d..aceba3e 100644
--- a/Project/ReactiveShuntElementForm.cpp
+++ b/Project/ReactiveShuntElementForm.cpp
@@ -30,16 +30,16 @@ ReactiveShuntElementForm::ReactiveShuntElementForm(wxWindow* parent, Capacitor*
m_textCtrlReactivePower->SetValue(Capacitor::StringFromDouble(data.reactivePower));
switch(data.reactivePowerUnit) {
- case UNIT_PU: {
+ case ElectricalUnit::UNIT_PU: {
m_choiceReactivePower->SetSelection(0);
} break;
- case UNIT_VAr: {
+ case ElectricalUnit::UNIT_VAr: {
m_choiceReactivePower->SetSelection(1);
} break;
- case UNIT_kVAr: {
+ case ElectricalUnit::UNIT_kVAr: {
m_choiceReactivePower->SetSelection(2);
} break;
- case UNIT_MVAr: {
+ case ElectricalUnit::UNIT_MVAr: {
m_choiceReactivePower->SetSelection(3);
} break;
default:
@@ -59,16 +59,16 @@ ReactiveShuntElementForm::ReactiveShuntElementForm(wxWindow* parent, Inductor* i
m_textCtrlReactivePower->SetValue(Inductor::StringFromDouble(data.reactivePower));
switch(data.reactivePowerUnit) {
- case UNIT_PU: {
+ case ElectricalUnit::UNIT_PU: {
m_choiceReactivePower->SetSelection(0);
} break;
- case UNIT_VAr: {
+ case ElectricalUnit::UNIT_VAr: {
m_choiceReactivePower->SetSelection(1);
} break;
- case UNIT_kVAr: {
+ case ElectricalUnit::UNIT_kVAr: {
m_choiceReactivePower->SetSelection(2);
} break;
- case UNIT_MVAr: {
+ case ElectricalUnit::UNIT_MVAr: {
m_choiceReactivePower->SetSelection(3);
} break;
default:
@@ -114,16 +114,16 @@ bool ReactiveShuntElementForm::ValidateData()
return false;
switch(m_choiceReactivePower->GetSelection()) {
case 0: {
- data.reactivePowerUnit = UNIT_PU;
+ data.reactivePowerUnit = ElectricalUnit::UNIT_PU;
} break;
case 1: {
- data.reactivePowerUnit = UNIT_VAr;
+ data.reactivePowerUnit = ElectricalUnit::UNIT_VAr;
} break;
case 2: {
- data.reactivePowerUnit = UNIT_kVAr;
+ data.reactivePowerUnit = ElectricalUnit::UNIT_kVAr;
} break;
case 3: {
- data.reactivePowerUnit = UNIT_MVAr;
+ data.reactivePowerUnit = ElectricalUnit::UNIT_MVAr;
} break;
}
@@ -138,16 +138,16 @@ bool ReactiveShuntElementForm::ValidateData()
return false;
switch(m_choiceReactivePower->GetSelection()) {
case 0: {
- data.reactivePowerUnit = UNIT_PU;
+ data.reactivePowerUnit = ElectricalUnit::UNIT_PU;
} break;
case 1: {
- data.reactivePowerUnit = UNIT_VAr;
+ data.reactivePowerUnit = ElectricalUnit::UNIT_VAr;
} break;
case 2: {
- data.reactivePowerUnit = UNIT_kVAr;
+ data.reactivePowerUnit = ElectricalUnit::UNIT_kVAr;
} break;
case 3: {
- data.reactivePowerUnit = UNIT_MVAr;
+ data.reactivePowerUnit = ElectricalUnit::UNIT_MVAr;
} break;
}
diff --git a/Project/Shunt.cpp b/Project/Shunt.cpp
index 63def85..0522457 100644
--- a/Project/Shunt.cpp
+++ b/Project/Shunt.cpp
@@ -165,18 +165,36 @@ void Shunt::DrawGround(wxPoint2DDouble position) const
DrawLine(groundPts, GL_LINES);
}
+void Shunt::DrawDCGround(wxPoint2DDouble position, wxGraphicsContext* gc) const
+{
+ std::vector<wxPoint2DDouble> groundPts;
+ groundPts.push_back(position);
+ groundPts.push_back(position + wxPoint2DDouble(0, 10));
+ groundPts.push_back(position + wxPoint2DDouble(-10, 10));
+ groundPts.push_back(position + wxPoint2DDouble(10, 10));
+ groundPts.push_back(position + wxPoint2DDouble(-6, 15));
+ groundPts.push_back(position + wxPoint2DDouble(6, 15));
+ groundPts.push_back(position + wxPoint2DDouble(-3, 20));
+ groundPts.push_back(position + wxPoint2DDouble(3, 20));
+
+ gc->DrawLines(2, &groundPts[0]);
+ gc->DrawLines(2, &groundPts[2]);
+ gc->DrawLines(2, &groundPts[4]);
+ gc->DrawLines(2, &groundPts[6]);
+}
+
void Shunt::UpdatePowerFlowArrowsPosition()
{
std::vector<wxPoint2DDouble> edges;
switch(m_pfDirection) {
- case PF_NONE: {
+ case PowerFlowDirection::PF_NONE: {
m_powerFlowArrow.clear();
} break;
- case PF_TO_BUS: {
+ case PowerFlowDirection::PF_TO_BUS: {
edges.push_back(m_pointList[2]);
edges.push_back(m_pointList[1]);
} break;
- case PF_TO_ELEMENT: {
+ case PowerFlowDirection::PF_TO_ELEMENT: {
edges.push_back(m_pointList[1]);
edges.push_back(m_pointList[2]);
} break;
diff --git a/Project/Shunt.h b/Project/Shunt.h
index 94424a4..20969b1 100644
--- a/Project/Shunt.h
+++ b/Project/Shunt.h
@@ -49,6 +49,7 @@ class Shunt : public PowerElement
void UpdateSwitchesPosition();
void UpdatePowerFlowArrowsPosition();
void DrawGround(wxPoint2DDouble position) const;
+ void DrawDCGround(wxPoint2DDouble position, wxGraphicsContext* gc) const;
bool m_inserted = false;
};
diff --git a/Project/SimulationsSettingsForm.cpp b/Project/SimulationsSettingsForm.cpp
index 5b3cb1c..6f1c987 100644
--- a/Project/SimulationsSettingsForm.cpp
+++ b/Project/SimulationsSettingsForm.cpp
@@ -26,13 +26,13 @@ SimulationsSettingsForm::SimulationsSettingsForm(wxWindow* parent, PropertiesDat
m_textCtrlbasePower->SetValue(Element::StringFromDouble(data.basePower));
switch(data.basePowerUnit) {
- case UNIT_VA: {
+ case ElectricalUnit::UNIT_VA: {
m_choiceBasePower->SetSelection(0);
} break;
- case UNIT_kVA: {
+ case ElectricalUnit::UNIT_kVA: {
m_choiceBasePower->SetSelection(1);
} break;
- case UNIT_MVA: {
+ case ElectricalUnit::UNIT_MVA: {
m_choiceBasePower->SetSelection(2);
} break;
default: {
@@ -102,13 +102,13 @@ bool SimulationsSettingsForm::ValidateData()
return false;
switch(m_choiceBasePower->GetSelection()) {
case 0: {
- data.basePowerUnit = UNIT_VA;
+ data.basePowerUnit = ElectricalUnit::UNIT_VA;
} break;
case 1: {
- data.basePowerUnit = UNIT_kVA;
+ data.basePowerUnit = ElectricalUnit::UNIT_kVA;
} break;
default: {
- data.basePowerUnit = UNIT_MVA;
+ data.basePowerUnit = ElectricalUnit::UNIT_MVA;
} break;
}
data.faultAfterPowerFlow = m_checkBoxFaultAfterPF->GetValue();
@@ -153,10 +153,10 @@ bool SimulationsSettingsForm::ValidateData()
_("Value entered incorrectly in the field \"System frequency\".")))
return false;
if(!Element::DoubleFromString(this, m_textCtrlStabTolerance->GetValue(), data.stabilityTolerance,
- _("Value entered incorrectly in the field \"Tolerance (Stability)\".")))
+ _("Value entered incorrectly in the field \"Tolerance (stability)\".")))
return false;
if(!Element::IntFromString(this, m_textCtrlStabMaxIterations->GetValue(), data.stabilityMaxIterations,
- _("Value entered incorrectly in the field \"Max. iterations (Stability)\".")))
+ _("Value entered incorrectly in the field \"Max. iterations (stability)\".")))
return false;
if(!Element::IntFromString(this, m_textCtrlCtrlStepRatio->GetValue(), data.controlTimeStepRatio,
_("Value entered incorrectly in the field \"Controls step ratio\".")))
diff --git a/Project/StabilityEventList.cpp b/Project/StabilityEventList.cpp
index a0c7922..f976ead 100644
--- a/Project/StabilityEventList.cpp
+++ b/Project/StabilityEventList.cpp
@@ -148,7 +148,7 @@ void StabilityEventList::SetPowerElementSwitchingEvent(PowerElement* element, wx
{
SwitchingData swData = element->GetSwitchingData();
for(unsigned int i = 0; i < swData.swTime.size(); ++i) {
- if(swData.swType[i] == SW_INSERT) {
+ if(swData.swType[i] == SwitchingType::SW_INSERT) {
AddEvent(swData.swTime[i], _("Switching"), _("Insertion of \"") + elementName + _("\""), m_blueColour);
} else {
AddEvent(swData.swTime[i], _("Switching"), _("Removal of \"") + elementName + _("\""), m_redColour);
diff --git a/Project/Sum.cpp b/Project/Sum.cpp
index 9908497..a2235fd 100644
--- a/Project/Sum.cpp
+++ b/Project/Sum.cpp
@@ -22,12 +22,12 @@
Sum::Sum(int id) : ControlElement(id)
{
m_width = m_height = 36.0;
- Node* nodeIn1 = new Node(m_position + wxPoint2DDouble(-m_width / 2, 9 - m_height / 2), Node::NODE_IN, m_borderSize);
+ Node* nodeIn1 = new Node(m_position + wxPoint2DDouble(-m_width / 2, 9 - m_height / 2), Node::NodeType::NODE_IN, m_borderSize);
nodeIn1->StartMove(m_position);
Node* nodeIn2 =
- new Node(m_position + wxPoint2DDouble(-m_width / 2, 27 - m_height / 2), Node::NODE_IN, m_borderSize);
+ new Node(m_position + wxPoint2DDouble(-m_width / 2, 27 - m_height / 2), Node::NodeType::NODE_IN, m_borderSize);
nodeIn2->StartMove(m_position);
- Node* nodeOut = new Node(m_position + wxPoint2DDouble(m_width / 2, 0), Node::NODE_OUT, m_borderSize);
+ Node* nodeOut = new Node(m_position + wxPoint2DDouble(m_width / 2, 0), Node::NodeType::NODE_OUT, m_borderSize);
nodeOut->SetAngle(180.0);
nodeOut->StartMove(m_position);
m_nodeList.push_back(nodeIn1);
@@ -154,7 +154,7 @@ void Sum::UpdatePoints()
void Sum::AddInNode()
{
- Node* newNode = new Node(wxPoint2DDouble(0, 0), Node::NODE_IN, m_borderSize);
+ Node* newNode = new Node(wxPoint2DDouble(0, 0), Node::NodeType::NODE_IN, m_borderSize);
newNode->SetAngle(m_angle);
m_nodeList.insert(m_nodeList.end() - 1, newNode);
}
@@ -208,7 +208,7 @@ bool Sum::Solve(double* input, double timeStep)
std::vector<double> inputVector;
for(auto itN = m_nodeList.begin(), itNEnd = m_nodeList.end(); itN != itNEnd; ++itN) {
Node* node = *itN;
- if(node->GetNodeType() != Node::NODE_OUT) {
+ if(node->GetNodeType() != Node::NodeType::NODE_OUT) {
if(!node->IsConnected()) {
inputVector.push_back(0.0);
} else {
diff --git a/Project/SwitchingForm.cpp b/Project/SwitchingForm.cpp
index 8a52553..8b3a5fd 100644
--- a/Project/SwitchingForm.cpp
+++ b/Project/SwitchingForm.cpp
@@ -37,7 +37,7 @@ SwitchingForm::SwitchingForm(wxWindow* parent, PowerElement* element) : Switchin
SwitchingData data = element->GetSwitchingData();
for(int i = 0; i < (int)data.swType.size(); i++) {
- long index = m_listCtrlSwitchings->InsertItem(m_maxID, data.swType[i] == SW_INSERT ? _("Insert") : _("Remove"));
+ long index = m_listCtrlSwitchings->InsertItem(m_maxID, data.swType[i] == SwitchingType::SW_INSERT ? _("Insert") : _("Remove"));
m_listCtrlSwitchings->SetItem(index, 1, wxString::FromDouble(data.swTime[i]));
m_maxID++;
}
@@ -67,9 +67,9 @@ void SwitchingForm::OnOKButtonClick(wxCommandEvent& event)
SwitchingData data;
for(int i = 0; i < (int)itemList.size(); i++) {
if(m_listCtrlSwitchings->GetItemText(itemList[i], 0) == _("Insert"))
- data.swType.push_back(SW_INSERT);
+ data.swType.push_back(SwitchingType::SW_INSERT);
else
- data.swType.push_back(SW_REMOVE);
+ data.swType.push_back(SwitchingType::SW_REMOVE);
double swTime;
m_listCtrlSwitchings->GetItemText(itemList[i], 1).ToDouble(&swTime);
diff --git a/Project/SyncGenerator.cpp b/Project/SyncGenerator.cpp
index 78082d2..49571ac 100644
--- a/Project/SyncGenerator.cpp
+++ b/Project/SyncGenerator.cpp
@@ -15,6 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+#include "Workspace.h"
#include "ControlElementContainer.h"
#include "SyncGenerator.h"
#include "SyncMachineForm.h"
@@ -51,6 +52,15 @@ void SyncGenerator::DrawSymbol() const
for(int i = 0; i < (int)m_sinePts.size(); i++) { sinePts.push_back(m_sinePts[i] + m_position); }
DrawLine(sinePts);
}
+
+void SyncGenerator::DrawDCSymbol(wxGraphicsContext* gc) const
+{
+ // Draw sine.
+ std::vector<wxPoint2DDouble> sinePts;
+ for (unsigned int i = 0; i < m_sinePts.size(); i++) { sinePts.push_back(m_sinePts[i] + m_position); }
+ gc->DrawLines(sinePts.size(), &sinePts[0]);
+}
+
bool SyncGenerator::GetContextMenu(wxMenu& menu)
{
menu.Append(ID_EDIT_ELEMENT, _("Edit Generator"));
@@ -60,7 +70,8 @@ bool SyncGenerator::GetContextMenu(wxMenu& menu)
bool SyncGenerator::ShowForm(wxWindow* parent, Element* element)
{
- SyncMachineForm* generatorForm = new SyncMachineForm(parent, this);
+ Workspace* ws = static_cast<Workspace*>(parent);
+ SyncMachineForm* generatorForm = new SyncMachineForm(parent, this, ws->GetSharedGLContext());
generatorForm->SetTitle(_("Generator"));
if(generatorForm->ShowModal() == wxID_OK) {
generatorForm->Destroy();
diff --git a/Project/SyncGenerator.h b/Project/SyncGenerator.h
index 1a25a0e..e696ca4 100644
--- a/Project/SyncGenerator.h
+++ b/Project/SyncGenerator.h
@@ -148,6 +148,7 @@ class SyncGenerator : public Machines
virtual Element* GetCopy();
virtual void Init();
virtual void DrawSymbol() const;
+ virtual void DrawDCSymbol(wxGraphicsContext* gc) const;
virtual bool GetContextMenu(wxMenu& menu);
virtual bool ShowForm(wxWindow* parent, Element* element);
virtual wxString GetTipText() const;
diff --git a/Project/SyncMachineForm.cpp b/Project/SyncMachineForm.cpp
index 486a043..3c27a7c 100644
--- a/Project/SyncMachineForm.cpp
+++ b/Project/SyncMachineForm.cpp
@@ -20,7 +20,7 @@
#include "SyncGenerator.h"
#include "SyncMotor.h"
-SyncMachineForm::SyncMachineForm(wxWindow* parent, SyncGenerator* syncGenerator) : SyncMachineFormBase(parent)
+SyncMachineForm::SyncMachineForm(wxWindow* parent, SyncGenerator* syncGenerator, wxGLContext* sharedGLContext) : SyncMachineFormBase(parent)
{
SetSize(GetBestSize());
ReplaceStaticTextLabelChar(m_staticTextPosResistance, L'\u2081');
@@ -32,6 +32,7 @@ SyncMachineForm::SyncMachineForm(wxWindow* parent, SyncGenerator* syncGenerator)
Layout();
m_syncGenerator = syncGenerator;
m_parent = parent;
+ m_sharedGLContext = sharedGLContext;
SyncGeneratorElectricalData data = syncGenerator->GetElectricalData();
@@ -286,7 +287,7 @@ void SyncMachineForm::OnStabilityButtonClick(wxCommandEvent& event)
{
if(ValidateData()) {
if(m_syncGenerator) {
- GeneratorStabForm* stabForm = new GeneratorStabForm(m_parent, m_syncGenerator);
+ GeneratorStabForm* stabForm = new GeneratorStabForm(m_parent, m_syncGenerator, m_sharedGLContext);
if(stabForm->ShowModal() == wxID_OK) {
stabForm->Destroy();
EndModal(wxID_OK);
diff --git a/Project/SyncMachineForm.h b/Project/SyncMachineForm.h
index 793ca79..421a975 100644
--- a/Project/SyncMachineForm.h
+++ b/Project/SyncMachineForm.h
@@ -17,6 +17,7 @@
#ifndef SYNCMACHINEFORM_H
#define SYNCMACHINEFORM_H
+#include <wx/glcanvas.h>
#include "ElementFormBase.h"
@@ -34,7 +35,7 @@ class SyncMotor;
class SyncMachineForm : public SyncMachineFormBase
{
public:
- SyncMachineForm(wxWindow* parent, SyncGenerator* syncGenerator);
+ SyncMachineForm(wxWindow* parent, SyncGenerator* syncGenerator, wxGLContext* sharedGLContext);
SyncMachineForm(wxWindow* parent, SyncMotor* syncMotor);
virtual ~SyncMachineForm();
@@ -44,6 +45,7 @@ class SyncMachineForm : public SyncMachineFormBase
virtual void OnCheckMinReactive(wxCommandEvent& event);
virtual void OnOKButtonClick(wxCommandEvent& event);
virtual void OnStabilityButtonClick(wxCommandEvent& event);
+ wxGLContext* GetSharedGLContext() const { return m_sharedGLContext; }
virtual bool ValidateData();
virtual void ReplaceStaticTextLabelChar(wxStaticText* staticText, wchar_t newChar);
@@ -51,5 +53,6 @@ class SyncMachineForm : public SyncMachineFormBase
SyncGenerator* m_syncGenerator = NULL;
SyncMotor* m_syncMotor = NULL;
wxWindow* m_parent = NULL;
+ wxGLContext* m_sharedGLContext = NULL;
};
#endif // SYNCMACHINEFORM_H
diff --git a/Project/SyncMotor.cpp b/Project/SyncMotor.cpp
index 8283a25..716a432 100644
--- a/Project/SyncMotor.cpp
+++ b/Project/SyncMotor.cpp
@@ -22,6 +22,10 @@ SyncMotor::SyncMotor() : Machines() {}
SyncMotor::SyncMotor(wxString name) : Machines() { m_electricalData.name = name; }
SyncMotor::~SyncMotor() {}
void SyncMotor::DrawSymbol() const { DrawArc(m_position, 12, 30, 330, 10, GL_LINE_STRIP); }
+void SyncMotor::DrawDCSymbol(wxGraphicsContext* gc) const
+{
+ DrawDCArc(m_position, 12, 30, 330, 10, gc);
+}
bool SyncMotor::GetContextMenu(wxMenu& menu)
{
menu.Append(ID_EDIT_ELEMENT, _("Edit Synchronous Condenser"));
diff --git a/Project/SyncMotor.h b/Project/SyncMotor.h
index 772ef7b..694aa90 100644
--- a/Project/SyncMotor.h
+++ b/Project/SyncMotor.h
@@ -140,6 +140,7 @@ class SyncMotor : public Machines
virtual Element* GetCopy();
virtual void DrawSymbol() const;
+ virtual void DrawDCSymbol(wxGraphicsContext* gc) const;
virtual bool GetContextMenu(wxMenu& menu);
virtual wxString GetTipText() const;
virtual SyncMotorElectricalData GetElectricalData() { return m_electricalData; }
diff --git a/Project/Text.cpp b/Project/Text.cpp
index f73b425..3a22c7a 100644
--- a/Project/Text.cpp
+++ b/Project/Text.cpp
@@ -79,6 +79,42 @@ void Text::Draw(wxPoint2DDouble translation, double scale)
glPopMatrix();
}
+void Text::DrawDC(wxPoint2DDouble translation, double scale, wxGraphicsContext* gc)
+{
+ // Draw selection rectangle
+
+ // Push the current matrix on stack.
+ gc->PushState();
+ // Rotate the matrix around the object position.
+ gc->Translate(m_position.m_x, m_position.m_y);
+ gc->Rotate(wxDegToRad(m_angle));
+ gc->Translate(-m_position.m_x, -m_position.m_y);
+
+ if (m_selected) {
+ glColor4d(0.0, 0.5, 1.0, 0.5);
+ gc->SetPen(*wxTRANSPARENT_PEN);
+ gc->SetBrush(wxBrush(wxColour(0, 125, 255, 125)));
+ wxPoint2DDouble pos = m_position - wxPoint2DDouble(m_borderSize / 2.0 + m_width / 2, m_borderSize / 2.0 + m_height / 2);
+ gc->DrawRectangle(pos.m_x, pos.m_y, m_rect.m_width, m_rect.m_height);
+ }
+
+ // Draw text (layer 2)
+ //gc->SetPen(wxPen(wxColour(0, 0, 0, 255)));
+ //gc->SetBrush(*wxTRANSPARENT_BRUSH);
+ wxPoint2DDouble pos = m_position - wxPoint2DDouble(m_width / 2, m_height / 2);
+ if (m_isMultlineText) {
+ for (unsigned int i = 0; i < m_openGLTextList.size(); ++i) {
+ m_openGLTextList[i]->DrawDC(
+ pos +
+ wxPoint2DDouble(0.0, (m_height * static_cast<double>(i) / static_cast<double>(m_numberOfLines))), gc);
+ }
+ }
+ else if (m_openGLTextList.size() > 0) {
+ m_openGLTextList[0]->DrawDC(pos, gc);
+ }
+ gc->PopState();
+}
+
bool Text::Intersects(wxRect2DDouble rect) const
{
if(m_angle == 0.0 || m_angle == 180.0) return m_rect.Intersects(rect);
diff --git a/Project/Text.h b/Project/Text.h
index 19e3876..2f4c0ff 100644
--- a/Project/Text.h
+++ b/Project/Text.h
@@ -18,6 +18,7 @@
#ifndef TEXT_H
#define TEXT_H
+#include <windows.h>
#include <GL/gl.h>
#include <wx/dcmemory.h>
@@ -86,6 +87,7 @@ class Text : public GraphicalElement
virtual bool AddParent(Element* parent, wxPoint2DDouble position) { return true; };
virtual bool Contains(wxPoint2DDouble position) const;
virtual void Draw(wxPoint2DDouble translation, double scale);
+ virtual void DrawDC(wxPoint2DDouble translation, double scale, wxGraphicsContext* gc);
virtual bool Intersects(wxRect2DDouble rect) const;
virtual void Rotate(bool clockwise = true);
virtual bool ShowForm(wxWindow* parent, std::vector<Element*> elementList);
diff --git a/Project/TransferFunction.cpp b/Project/TransferFunction.cpp
index b78d74a..e650ca6 100644
--- a/Project/TransferFunction.cpp
+++ b/Project/TransferFunction.cpp
@@ -39,9 +39,9 @@ TransferFunction::TransferFunction(int id) : ControlElement(id)
m_denominator.push_back(1);
UpdateTFText();
- Node* node1 = new Node(m_position + wxPoint2DDouble(-m_width / 2, 0), Node::NODE_IN, m_borderSize);
+ Node* node1 = new Node(m_position + wxPoint2DDouble(-m_width / 2, 0), Node::NodeType::NODE_IN, m_borderSize);
node1->StartMove(m_position);
- Node* node2 = new Node(m_position + wxPoint2DDouble(m_width / 2, 0), Node::NODE_OUT, m_borderSize);
+ Node* node2 = new Node(m_position + wxPoint2DDouble(m_width / 2, 0), Node::NodeType::NODE_OUT, m_borderSize);
node2->SetAngle(180.0);
node2->StartMove(m_position);
m_nodeList.push_back(node1);
diff --git a/Project/Transformer.cpp b/Project/Transformer.cpp
index 024a851..bd212d7 100644
--- a/Project/Transformer.cpp
+++ b/Project/Transformer.cpp
@@ -179,6 +179,92 @@ void Transformer::Draw(wxPoint2DDouble translation, double scale) const
}
}
+void Transformer::DrawDC(wxPoint2DDouble translation, double scale, wxGraphicsContext* gc) const
+{
+ OpenGLColour elementColour;
+ if (m_online) {
+ if (m_dynEvent)
+ elementColour = m_dynamicEventColour;
+ else
+ elementColour = m_onlineElementColour;
+ }
+ else
+ elementColour = m_offlineElementColour;
+
+ if (m_inserted) {
+ // Draw selection (layer 1).
+ if (m_selected) {
+ gc->SetPen(wxPen(wxColour(m_selectionColour.GetDcRGBA()), 2 + m_borderSize * 2.0));
+ gc->SetBrush(*wxTRANSPARENT_BRUSH);
+ gc->DrawLines(m_pointList.size(), &m_pointList[0]);
+
+ // Push the current matrix on stack.
+ gc->PushState();
+ // Rotate the matrix around the object position.
+ gc->Translate(m_position.m_x, m_position.m_y);
+ gc->Rotate(wxDegToRad(m_angle));
+ gc->Translate(-m_position.m_x, -m_position.m_y);
+
+ gc->SetPen(*wxTRANSPARENT_PEN);
+ gc->SetBrush(wxBrush(wxColour(m_selectionColour.GetDcRGBA())));
+ DrawDCCircle(m_rect.GetPosition() + wxPoint2DDouble(20.0, 20.0), 20 + (m_borderSize + 1.5) / scale, 20, gc);
+ DrawDCCircle(m_rect.GetPosition() + wxPoint2DDouble(50.0, 20.0), 20 + (m_borderSize + 1.5) / scale, 20, gc);
+
+ gc->PopState();
+
+ // Draw nodes selection.
+ gc->SetPen(*wxTRANSPARENT_PEN);
+ gc->SetBrush(wxBrush(wxColour(m_selectionColour.GetDcRGBA())));
+ if (m_pointList.size() > 0) {
+ DrawDCCircle(m_pointList[0], 5.0 + m_borderSize / scale, 10, gc);
+ if (m_inserted) { DrawDCCircle(m_pointList[m_pointList.size() - 1], 5.0 + m_borderSize / scale, 10, gc); }
+ }
+ }
+
+ // Draw transformer (layer 2).
+ // Transformer line
+ gc->SetPen(wxPen(wxColour(elementColour.GetDcRGBA()), 2));
+ gc->SetBrush(*wxTRANSPARENT_BRUSH);
+ gc->DrawLines(m_pointList.size(), &m_pointList[0]);
+
+ // Draw nodes.
+ gc->SetPen(*wxTRANSPARENT_PEN);
+ gc->SetBrush(wxBrush(wxColour(elementColour.GetDcRGBA())));
+ if (m_pointList.size() > 0) {
+ DrawDCCircle(m_pointList[0], 5.0, 10, gc);
+ if (m_inserted) { DrawDCCircle(m_pointList[m_pointList.size() - 1], 5.0, 10, gc); }
+ }
+
+ DrawDCSwitches(gc);
+ DrawDCPowerFlowPts(gc);
+
+ // Push the current matrix on stack.
+ gc->PushState();
+ // Rotate the matrix around the object position.
+ gc->Translate(m_position.m_x, m_position.m_y);
+ gc->Rotate(wxDegToRad(m_angle));
+ gc->Translate(-m_position.m_x, -m_position.m_y);
+
+ glColor4d(1.0, 1.0, 1.0, 1.0);
+ gc->SetPen(*wxTRANSPARENT_PEN);
+ gc->SetBrush(*wxWHITE_BRUSH);
+ DrawDCCircle(m_rect.GetPosition() + wxPoint2DDouble(20.0, 20.0), 20, 20, gc);
+ DrawDCCircle(m_rect.GetPosition() + wxPoint2DDouble(50.0, 20.0), 20, 20, gc);
+
+ gc->SetPen(wxPen(wxColour(elementColour.GetDcRGBA()), 2));
+ gc->SetBrush(*wxTRANSPARENT_BRUSH);
+ DrawDCCircle(m_rect.GetPosition() + wxPoint2DDouble(20.0, 20.0), 20, 20, gc);
+ DrawDCCircle(m_rect.GetPosition() + wxPoint2DDouble(50.0, 20.0), 20, 20, gc);
+
+ // Point
+ gc->SetPen(*wxTRANSPARENT_PEN);
+ gc->SetBrush(wxBrush(wxColour(elementColour.GetDcRGBA())));
+ DrawDCCircle(m_rect.GetPosition(), 4, 10, gc);
+
+ gc->PopState();
+ }
+}
+
bool Transformer::Intersects(wxRect2DDouble rect) const
{
if(m_angle == 0.0 || m_angle == 180.0) return m_rect.Intersects(rect);
diff --git a/Project/Transformer.h b/Project/Transformer.h
index 46dfe77..207f6d1 100644
--- a/Project/Transformer.h
+++ b/Project/Transformer.h
@@ -86,6 +86,7 @@ class Transformer : public Branch
virtual bool AddParent(Element* parent, wxPoint2DDouble position);
virtual bool Contains(wxPoint2DDouble position) const;
virtual void Draw(wxPoint2DDouble translation, double scale) const;
+ virtual void DrawDC(wxPoint2DDouble translation, double scale, wxGraphicsContext* gc) const;
virtual bool Intersects(wxRect2DDouble rect) const;
virtual void Rotate(bool clockwise = true);
virtual void Move(wxPoint2DDouble position);
diff --git a/Project/TransformerForm.cpp b/Project/TransformerForm.cpp
index 7c921c4..a41d1bd 100644
--- a/Project/TransformerForm.cpp
+++ b/Project/TransformerForm.cpp
@@ -47,10 +47,10 @@ TransformerForm::TransformerForm(wxWindow* parent, Transformer* transformer) : T
wxString primVoltStr = Transformer::StringFromDouble(data.primaryNominalVoltage);
switch(data.primaryNominalVoltageUnit) {
- case UNIT_V: {
+ case ElectricalUnit::UNIT_V: {
primVoltStr += " V";
} break;
- case UNIT_kV: {
+ case ElectricalUnit::UNIT_kV: {
primVoltStr += " kV";
} break;
default:
@@ -58,10 +58,10 @@ TransformerForm::TransformerForm(wxWindow* parent, Transformer* transformer) : T
}
wxString secVoltStr = Transformer::StringFromDouble(data.secondaryNominalVoltage);
switch(data.secondaryNominalVoltageUnit) {
- case UNIT_V: {
+ case ElectricalUnit::UNIT_V: {
secVoltStr += " V";
} break;
- case UNIT_kV: {
+ case ElectricalUnit::UNIT_kV: {
secVoltStr += " kV";
} break;
default:
@@ -75,13 +75,13 @@ TransformerForm::TransformerForm(wxWindow* parent, Transformer* transformer) : T
m_textCtrlNominalPower->SetValue(Transformer::StringFromDouble(data.nominalPower));
switch(data.nominalPowerUnit) {
- case UNIT_VA: {
+ case ElectricalUnit::UNIT_VA: {
m_choiceNominalPower->SetSelection(0);
} break;
- case UNIT_kVA: {
+ case ElectricalUnit::UNIT_kVA: {
m_choiceNominalPower->SetSelection(1);
} break;
- case UNIT_MVA: {
+ case ElectricalUnit::UNIT_MVA: {
m_choiceNominalPower->SetSelection(2);
} break;
default:
@@ -90,10 +90,10 @@ TransformerForm::TransformerForm(wxWindow* parent, Transformer* transformer) : T
m_textCtrlResistance->SetValue(Transformer::StringFromDouble(data.resistance));
switch(data.resistanceUnit) {
- case UNIT_PU: {
+ case ElectricalUnit::UNIT_PU: {
m_choiceResistance->SetSelection(0);
} break;
- case UNIT_OHM: {
+ case ElectricalUnit::UNIT_OHM: {
m_choiceResistance->SetSelection(1);
} break;
default:
@@ -102,10 +102,10 @@ TransformerForm::TransformerForm(wxWindow* parent, Transformer* transformer) : T
m_textCtrlReactance->SetValue(Transformer::StringFromDouble(data.indReactance));
switch(data.indReactanceUnit) {
- case UNIT_PU: {
+ case ElectricalUnit::UNIT_PU: {
m_choiceReactance->SetSelection(0);
} break;
- case UNIT_OHM: {
+ case ElectricalUnit::UNIT_OHM: {
m_choiceReactance->SetSelection(1);
} break;
default:
@@ -155,13 +155,13 @@ bool TransformerForm::ValidateData()
return false;
switch(m_choiceNominalPower->GetSelection()) {
case 0: {
- data.nominalPowerUnit = UNIT_VA;
+ data.nominalPowerUnit = ElectricalUnit::UNIT_VA;
} break;
case 1: {
- data.nominalPowerUnit = UNIT_kVA;
+ data.nominalPowerUnit = ElectricalUnit::UNIT_kVA;
} break;
case 2: {
- data.nominalPowerUnit = UNIT_MVA;
+ data.nominalPowerUnit = ElectricalUnit::UNIT_MVA;
} break;
}
@@ -170,10 +170,10 @@ bool TransformerForm::ValidateData()
return false;
switch(m_choiceResistance->GetSelection()) {
case 0: {
- data.resistanceUnit = UNIT_PU;
+ data.resistanceUnit = ElectricalUnit::UNIT_PU;
} break;
case 1: {
- data.resistanceUnit = UNIT_OHM;
+ data.resistanceUnit = ElectricalUnit::UNIT_OHM;
} break;
}
@@ -182,10 +182,10 @@ bool TransformerForm::ValidateData()
return false;
switch(m_choiceReactance->GetSelection()) {
case 0: {
- data.indReactanceUnit = UNIT_PU;
+ data.indReactanceUnit = ElectricalUnit::UNIT_PU;
} break;
case 1: {
- data.indReactanceUnit = UNIT_OHM;
+ data.indReactanceUnit = ElectricalUnit::UNIT_OHM;
} break;
}
diff --git a/Project/Workspace.cpp b/Project/Workspace.cpp
index 82989b5..9cd1bb6 100644
--- a/Project/Workspace.cpp
+++ b/Project/Workspace.cpp
@@ -83,13 +83,13 @@ void Workspace::OnPaint(wxPaintEvent& event)
if(!m_glCanvas->IsShown()) return;
wxPaintDC dc(m_glCanvas);
+
m_glContext->SetCurrent(*m_glCanvas);
SetViewport();
// Set GLCanvas scale and translation.
glScaled(m_camera->GetScale(), m_camera->GetScale(), 0.0); // Scale
glTranslated(m_camera->GetTranslation().m_x, m_camera->GetTranslation().m_y, 0.0); // Translation
-
// Draw
// Elements
@@ -122,6 +122,7 @@ void Workspace::OnPaint(wxPaintEvent& event)
glEnd();
glFlush(); // Sends all pending information directly to the GPU.
+
m_glCanvas->SwapBuffers();
event.Skip();
}
@@ -983,7 +984,7 @@ void Workspace::RotateSelectedElements(bool clockwise)
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(); ++it) {
+ for(auto it = m_elementList.begin(); it != m_elementList.end();) {
Element* element = *it;
if(element->IsSelected()) {
@@ -1010,9 +1011,10 @@ void Workspace::DeleteSelectedElements()
}
}
- m_elementList.erase(it--);
+ it = m_elementList.erase(it);
if(element) delete element;
}
+ else it++;
}
for(auto it = m_textList.begin(); it != m_textList.end(); ++it) {
diff --git a/Project/Workspace.h b/Project/Workspace.h
index a48ad4e..3ac9b3a 100644
--- a/Project/Workspace.h
+++ b/Project/Workspace.h
@@ -18,6 +18,7 @@
#ifndef WORKSPACE_H
#define WORKSPACE_H
+#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <wx/dcclient.h>
@@ -103,7 +104,7 @@ class Workspace : public WorkspaceBase
Workspace();
Workspace(wxWindow* parent, wxString name = wxEmptyString, wxStatusBar* statusBar = NULL, wxGLContext* sharedGLContext = NULL);
- ~Workspace();
+ virtual ~Workspace();
wxString GetName() const { return m_name; }
std::vector<Element*> GetElementList() const;
@@ -122,8 +123,8 @@ class Workspace : public WorkspaceBase
void SetWorkspaceMode(WorkspaceMode mode) { m_mode = mode; }
void SetSavedPath(wxFileName savedPath) { m_savedPath = savedPath; }
void SetJustOpened(bool justOpened) { m_justOpened = justOpened; }
- void Redraw() { m_glCanvas->Refresh(); }
- wxGLContext* GetOpenGLContext() { return m_glContext; }
+ virtual void Redraw() { m_glCanvas->Refresh(); }
+ wxGLContext* GetSharedGLContext() const { return m_glContext; }
void RotateSelectedElements(bool clockwise = true);
void DeleteSelectedElements();
bool GetElementsCorners(wxPoint2DDouble& leftUpCorner,
@@ -152,22 +153,23 @@ class Workspace : public WorkspaceBase
bool RunHarmonicDistortion();
bool RunFrequencyResponse();
- protected:
- virtual void OnMiddleDoubleClick(wxMouseEvent& event);
- virtual void OnIdle(wxIdleEvent& event);
- virtual void OnTimer(wxTimerEvent& event);
- virtual void OnLeftDoubleClick(wxMouseEvent& event);
- virtual void OnRightClickDown(wxMouseEvent& event);
- virtual void OnLeftClickUp(wxMouseEvent& event);
- virtual void OnScroll(wxMouseEvent& event);
- virtual void OnMiddleDown(wxMouseEvent& event);
- virtual void OnMiddleUp(wxMouseEvent& event);
- virtual void OnMouseMotion(wxMouseEvent& event);
- virtual void OnKeyDown(wxKeyEvent& event);
- virtual void OnLeftClickDown(wxMouseEvent& event);
- virtual void OnPaint(wxPaintEvent& event);
- virtual void OnPopupClick(wxCommandEvent& event);
-
+
+ virtual void OnMiddleDoubleClick(wxMouseEvent& event);
+ virtual void OnIdle(wxIdleEvent& event);
+ virtual void OnTimer(wxTimerEvent& event);
+ virtual void OnLeftDoubleClick(wxMouseEvent& event);
+ virtual void OnRightClickDown(wxMouseEvent& event);
+ virtual void OnLeftClickUp(wxMouseEvent& event);
+ virtual void OnScroll(wxMouseEvent& event);
+ virtual void OnMiddleDown(wxMouseEvent& event);
+ virtual void OnMiddleUp(wxMouseEvent& event);
+ virtual void OnMouseMotion(wxMouseEvent& event);
+ virtual void OnKeyDown(wxKeyEvent& event);
+ virtual void OnLeftClickDown(wxMouseEvent& event);
+ virtual void OnPaint(wxPaintEvent& event);
+ virtual void OnPopupClick(wxCommandEvent& event);
+
+protected:
void SetViewport();
void UpdateStatusBar();
diff --git a/Project/WorkspaceDC.cpp b/Project/WorkspaceDC.cpp
new file mode 100644
index 0000000..947b248
--- /dev/null
+++ b/Project/WorkspaceDC.cpp
@@ -0,0 +1,136 @@
+#include "WorkspaceDC.h"
+
+#include "Camera.h"
+#include "Element.h"
+#include "Workspace.h"
+//#include "Bus.h"
+#include "Capacitor.h"
+#include "ElementDataObject.h"
+#include "HarmCurrent.h"
+#include "IndMotor.h"
+#include "Inductor.h"
+#include "Line.h"
+#include "Load.h"
+#include "SyncGenerator.h"
+#include "SyncMotor.h"
+#include "Transformer.h"
+
+#include "Text.h"
+
+#include "Electromechanical.h"
+#include "Fault.h"
+#include "PowerFlow.h"
+#include "PowerQuality.h"
+
+#include "ChartView.h"
+#include "ElementPlotData.h"
+
+#include "PropertiesData.h"
+
+#include "FrequencyResponseForm.h"
+
+WorkspaceDC::WorkspaceDC()
+{
+}
+
+WorkspaceDC::WorkspaceDC(wxWindow* parent, wxString name, wxStatusBar* statusBar) : Workspace(parent, name, statusBar, nullptr)
+{
+ // Disconnect events from GLCanvas
+ m_glCanvas->Disconnect(wxEVT_PAINT, wxPaintEventHandler(Workspace::OnPaint), NULL, this);
+ m_glCanvas->Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(Workspace::OnLeftClickDown), NULL, this);
+ m_glCanvas->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(Workspace::OnKeyDown), NULL, this);
+ m_glCanvas->Disconnect(wxEVT_MOTION, wxMouseEventHandler(Workspace::OnMouseMotion), NULL, this);
+ m_glCanvas->Disconnect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(Workspace::OnMiddleDown), NULL, this);
+ m_glCanvas->Disconnect(wxEVT_MIDDLE_UP, wxMouseEventHandler(Workspace::OnMiddleUp), NULL, this);
+ m_glCanvas->Disconnect(wxEVT_LEFT_UP, wxMouseEventHandler(Workspace::OnLeftClickUp), NULL, this);
+ m_glCanvas->Disconnect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(Workspace::OnScroll), NULL, this);
+ m_glCanvas->Disconnect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(Workspace::OnRightClickDown), NULL, this);
+ m_glCanvas->Disconnect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(Workspace::OnLeftDoubleClick), NULL, this);
+ m_glCanvas->Disconnect(wxEVT_IDLE, wxIdleEventHandler(Workspace::OnIdle), NULL, this);
+ m_glCanvas->Disconnect(wxEVT_MIDDLE_DCLICK, wxMouseEventHandler(Workspace::OnMiddleDoubleClick), NULL, this);
+
+ // Reconnect events to this
+ this->Connect(wxEVT_PAINT, wxPaintEventHandler(WorkspaceDC::OnPaint), NULL, this); // Connect to overloaded method
+ this->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(Workspace::OnLeftClickDown), NULL, this);
+ this->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(Workspace::OnKeyDown), NULL, this);
+ this->Connect(wxEVT_MOTION, wxMouseEventHandler(Workspace::OnMouseMotion), NULL, this);
+ this->Connect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(Workspace::OnMiddleDown), NULL, this);
+ this->Connect(wxEVT_MIDDLE_UP, wxMouseEventHandler(Workspace::OnMiddleUp), NULL, this);
+ this->Connect(wxEVT_LEFT_UP, wxMouseEventHandler(Workspace::OnLeftClickUp), NULL, this);
+ this->Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(Workspace::OnScroll), NULL, this);
+ this->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(Workspace::OnRightClickDown), NULL, this);
+ this->Connect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(Workspace::OnLeftDoubleClick), NULL, this);
+ this->Connect(wxEVT_IDLE, wxIdleEventHandler(WorkspaceDC::OnIdle), NULL, this); // Connect to overloaded method
+ this->Connect(wxEVT_MIDDLE_DCLICK, wxMouseEventHandler(Workspace::OnMiddleDoubleClick), NULL, this);
+
+ this->GetSizer()->Remove(this->GetSizer()->GetChildren()[0]->GetId()); // remove m_glCanvas object from sizer
+
+ //for (int i = 0; i < this->GetSizer()->GetChildren().GetCount(); ++i) {
+ //wxMessageBox(wxString::Format("%d", this->GetSizer()->GetChildren()[i]->GetId()));
+ //}
+
+ delete m_glCanvas; // Delete GLcanvas to allow drawing with wxDC
+ m_glCanvas = nullptr;
+ SetBackgroundColour(wxColour(255, 255, 255));
+ SetBackgroundStyle(wxBG_STYLE_PAINT); // To allow wxBufferedPaintDC works properly.
+ Redraw();
+}
+
+WorkspaceDC::~WorkspaceDC()
+{
+ // Disconnect events
+ this->Disconnect(wxEVT_PAINT, wxPaintEventHandler(WorkspaceDC::OnPaint), NULL, this);
+ this->Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(Workspace::OnLeftClickDown), NULL, this);
+ this->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(Workspace::OnKeyDown), NULL, this);
+ this->Disconnect(wxEVT_MOTION, wxMouseEventHandler(Workspace::OnMouseMotion), NULL, this);
+ this->Disconnect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(Workspace::OnMiddleDown), NULL, this);
+ this->Disconnect(wxEVT_MIDDLE_UP, wxMouseEventHandler(Workspace::OnMiddleUp), NULL, this);
+ this->Disconnect(wxEVT_LEFT_UP, wxMouseEventHandler(Workspace::OnLeftClickUp), NULL, this);
+ this->Disconnect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(Workspace::OnScroll), NULL, this);
+ this->Disconnect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(Workspace::OnRightClickDown), NULL, this);
+ this->Disconnect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(Workspace::OnLeftDoubleClick), NULL, this);
+ this->Disconnect(wxEVT_IDLE, wxIdleEventHandler(WorkspaceDC::OnIdle), NULL, this);
+ this->Disconnect(wxEVT_MIDDLE_DCLICK, wxMouseEventHandler(Workspace::OnMiddleDoubleClick), NULL, this);
+
+ // Recreate the GLCanvas. This is necessary to prevent WorkspaceBase destructor access nullpr.
+ // Also avoid the code editing of WorkspaceBase, since is automatically generated by wxCrafter.
+ // TODO(?): Find a better way to solve this problem.
+ m_glCanvas = new wxGLCanvas(this);
+}
+
+void WorkspaceDC::OnPaint(wxPaintEvent& event)
+{
+ wxBufferedPaintDC dc(this);
+ dc.Clear();
+ wxGraphicsContext* gc = wxGraphicsContext::Create(dc);
+
+
+ // Draw
+ if (gc) {
+
+ gc->Scale(m_camera->GetScale(), m_camera->GetScale());
+ gc->Translate(m_camera->GetTranslation().m_x, m_camera->GetTranslation().m_y);
+
+ // Elements
+ for (auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
+ Element* element = *it;
+ element->DrawDC(m_camera->GetTranslation(), m_camera->GetScale(), gc);
+ }
+
+ // Texts
+ for (auto it = m_textList.begin(); it != m_textList.end(); ++it) {
+ Text* text = *it;
+ text->DrawDC(m_camera->GetTranslation(), m_camera->GetScale(), gc);
+ }
+
+ // Selection rectangle
+ //dc.SetPen(wxPen(wxColour(0, 125, 255)));
+ gc->SetPen(wxPen(wxColour(0, 125, 255, 255)));
+ gc->SetBrush(wxBrush(wxColour(0, 125, 255, 125)));
+ //dc.SetBrush(wxBrush(wxColour(0, 125, 255, 125)));
+ gc->DrawRectangle(m_selectionRect.m_x, m_selectionRect.m_y, m_selectionRect.m_width, m_selectionRect.m_height);
+
+ delete gc;
+ }
+ event.Skip();
+}
diff --git a/Project/WorkspaceDC.h b/Project/WorkspaceDC.h
new file mode 100644
index 0000000..609663a
--- /dev/null
+++ b/Project/WorkspaceDC.h
@@ -0,0 +1,21 @@
+#pragma once
+#include "Workspace.h"
+
+#include <wx/graphics.h>
+//#include <wx/dcclient.h>
+#include <wx/dcbuffer.h>
+
+class WorkspaceDC : public Workspace
+{
+public:
+ WorkspaceDC();
+ WorkspaceDC(wxWindow* parent, wxString name = wxEmptyString, wxStatusBar* statusBar = nullptr);
+ ~WorkspaceDC();
+
+ virtual void Redraw() { this->Refresh(); }
+
+ protected:
+ virtual void OnPaint(wxPaintEvent& event);
+ virtual void OnIdle(wxIdleEvent& event) {} // Prevent OpenGL checks
+};
+
diff --git a/Project/compile_flags.txt b/Project/compile_flags.txt
index 350b93a..2bba831 100644
--- a/Project/compile_flags.txt
+++ b/Project/compile_flags.txt
@@ -8,4 +8,4 @@
-DNDEBUG
-DUNICODE
-target
-x86_64-pc-windows-gnu
+i686-pc-windows-gnu
diff --git a/Project/main.cpp b/Project/main.cpp
index a9bf579..c4b0dc6 100644
--- a/Project/main.cpp
+++ b/Project/main.cpp
@@ -71,6 +71,14 @@ class MainApp : public wxApp
data.theme = THEME_DARK;
}
}
+ if (tag == "useOpenGL") {
+ if (tagValue == "yes") {
+ data.useOpenGL = true;
+ }
+ else if (tagValue == "no") {
+ data.useOpenGL = false;
+ }
+ }
}
file.Close();
} else { // Create default init file.
@@ -79,12 +87,14 @@ class MainApp : public wxApp
// Default parameters.
file.AddLine("lang=en");
file.AddLine("theme=light");
+ file.AddLine("useOpenGL=yes");
file.Write();
file.Close();
data.language = wxLANGUAGE_ENGLISH;
data.theme = THEME_LIGHT;
+ data.useOpenGL = true;
propertiesData->SetGeneralPropertiesData(data);
}
diff --git a/Project/win_resources.aps b/Project/win_resources.aps
new file mode 100644
index 0000000..88c78d4
--- /dev/null
+++ b/Project/win_resources.aps
Binary files differ