diff options
-rw-r--r-- | Project/ImportForm.cpp | 575 | ||||
-rw-r--r-- | Project/ImportForm.h | 80 | ||||
-rw-r--r-- | Project/MainFrame.cpp | 78 | ||||
-rw-r--r-- | Project/Project.mk | 2 |
4 files changed, 541 insertions, 194 deletions
diff --git a/Project/ImportForm.cpp b/Project/ImportForm.cpp index cadc5f0..352efc9 100644 --- a/Project/ImportForm.cpp +++ b/Project/ImportForm.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2018 Thales Lima Oliveira <thales@ufu.br> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + #include "Bus.h" #include "Capacitor.h" #include "ImportForm.h" @@ -5,7 +22,9 @@ #include "Inductor.h" #include "Line.h" #include "Load.h" +#include "PropertiesData.h" #include "SyncGenerator.h" +#include "SyncMotor.h" #include "Transformer.h" #include "Workspace.h" @@ -43,140 +62,293 @@ bool ImportForm::ImportSelectedFiles() if(!parseAnarede.Parse()) return false; double scale = 1.25; + double mvaBasePower = parseAnarede.GetMVAPowerBase(); + auto simProp = m_workspace->GetProperties()->GetSimulationPropertiesData(); + simProp.basePower = mvaBasePower; + m_workspace->GetProperties()->SetSimulationPropertiesData(simProp); + std::vector<Element*> elementList; std::vector<Bus*> busList; std::vector<SyncGenerator*> syncGeneratorList; + std::vector<SyncMotor*> syncMotorList; std::vector<Load*> loadList; std::vector<Inductor*> indList; + std::vector<Capacitor*> capList; std::vector<IndMotor*> indMotorList; std::vector<Transformer*> transformerList; std::vector<Line*> lineList; auto components = parseAnarede.GetComponents(); for(auto it = components.begin(), itEnd = components.end(); it != itEnd; ++it) { - switch((*it).type) { + switch((*it)->type) { case ANA_BUS: { - Bus* bus = new Bus(wxPoint2DDouble((*it).position.m_x * scale, (*it).position.m_y * scale)); - bus->SetID((*it).id); - bus->SetWidth((*it).length * scale); - // bus->SetPosition(bus->GetPosition()); // Update bus rect + Bus* bus = new Bus(wxPoint2DDouble((*it)->position.m_x * scale, (*it)->position.m_y * scale)); + bus->SetID((*it)->id); + bus->SetWidth((*it)->length * scale); bus->StartMove(bus->GetPosition()); - if((*it).rotationID == 0) { + if((*it)->rotationID == 0) { bus->Move(bus->GetPosition() + wxPoint2DDouble(bus->GetWidth() / 2, bus->GetHeight() / 2)); - } else if((*it).rotationID == 1) { - for(int i = 0; i < (*it).rotationID * 2; ++i) bus->Rotate(); + } else if((*it)->rotationID == 1) { + for(int i = 0; i < (*it)->rotationID * 2; ++i) bus->Rotate(); bus->Move(bus->GetPosition() + wxPoint2DDouble(-bus->GetHeight() / 2, bus->GetWidth() / 2)); - } else if((*it).rotationID == 2) { - for(int i = 0; i < (*it).rotationID * 2; ++i) bus->Rotate(); + } else if((*it)->rotationID == 2) { + for(int i = 0; i < (*it)->rotationID * 2; ++i) bus->Rotate(); bus->Move(bus->GetPosition() + wxPoint2DDouble(-bus->GetWidth() / 2, -bus->GetHeight() / 2)); - } else if((*it).rotationID == 3) { - for(int i = 0; i < (*it).rotationID * 2; ++i) bus->Rotate(); + } else if((*it)->rotationID == 3) { + for(int i = 0; i < (*it)->rotationID * 2; ++i) bus->Rotate(); bus->Move(bus->GetPosition() + wxPoint2DDouble(-bus->GetHeight() / 2, -bus->GetWidth() / 2)); } + // Electrical data + auto data = bus->GetElectricalData(); + ParseAnarede::BusData* busData = parseAnarede.GetBusDataFromID((*it)->electricalID); + if(busData) { + data.number = busData->id; + data.name = busData->busName; + switch(busData->type) { + case 0: + case 3: { + data.isVoltageControlled = false; + data.slackBus = false; + } break; + case 1: { + data.isVoltageControlled = true; + data.slackBus = false; + } break; + case 2: { + data.isVoltageControlled = true; + data.slackBus = true; + } break; + default: { + return false; + } break; + } + data.voltage = std::complex<double>(busData->voltage * std::cos(wxDegToRad(busData->angle)), + busData->voltage * std::sin(wxDegToRad(busData->angle))); + data.controlledVoltage = busData->voltage; + } else + return false; + + bus->SetElectricalData(data); busList.push_back(bus); } break; - case ANA_GENERATOR: - case ANA_IND_GENERATOR: { + case ANA_GENERATOR: { // Find parent bus - Bus* parentBus = GetBusFromID(busList, (*it).busConnectionID[0].first); + Bus* parentBus = GetBusFromID(busList, (*it)->busConnectionID[0].first); + wxPoint2DDouble nodePos = + parseAnarede.GetNodePositionFromID(parentBus, scale, (*it)->busConnectionNode[0].second); + + ParseAnarede::BusData* busData = parseAnarede.GetBusDataFromID((*it)->busConnectionID[0].second); + bool isMotor = false; + if(busData->genPower.real() <= 0.0) isMotor = true; + Machines* machine = NULL; + + if(!isMotor) { + SyncGenerator* syncGenerator = new SyncGenerator(); + + auto data = syncGenerator->GetElectricalData(); + data.name = _("Generator") + wxT(" (") + busData->busName + wxT(")"); + data.activePower = busData->genPower.real(); + data.reactivePower = busData->genPower.imag(); + data.minReactive = busData->minReactivePower; + data.maxReactive = busData->maxReactivePower; + + syncGenerator->SetElectricalData(data); + + machine = syncGenerator; + } else { + SyncMotor* syncMotor = new SyncMotor(); + + auto data = syncMotor->GetElectricalData(); + data.name = _("Synchronous compensator") + wxT(" (") + busData->busName + wxT(")"); + data.activePower = busData->genPower.real() == 0.0 ? 0.0 : -busData->genPower.real(); + data.reactivePower = busData->genPower.imag(); + data.minReactive = busData->minReactivePower; + data.maxReactive = busData->maxReactivePower; + + syncMotor->SetElectricalData(data); + + machine = syncMotor; + } + + if(machine) { + machine->SetID((*it)->id); + machine->AddParent(parentBus, nodePos); + + machine->StartMove(machine->GetPosition()); + machine->Move(wxPoint2DDouble((*it)->position.m_x * scale, (*it)->position.m_y * scale)); + + for(int i = 0; i < 2; ++i) machine->Rotate(false); // Set to ANAREDE default rotation + for(int i = 0; i < (*it)->rotationID * 2; ++i) machine->Rotate(); + + if(!isMotor) + syncGeneratorList.push_back(static_cast<SyncGenerator*>(machine)); + else + syncMotorList.push_back(static_cast<SyncMotor*>(machine)); + } + } break; + case ANA_IND_GENERATOR: { + // Same as ANA_GENERATOR, but with a transformer connecting the bus + Bus* parentBus = GetBusFromID(busList, (*it)->busConnectionID[0].first); wxPoint2DDouble nodePos = - parseAnarede.GetNodePositionFromID(parentBus, scale, (*it).busConnectionNode[0].second); + parseAnarede.GetNodePositionFromID(parentBus, scale, (*it)->busConnectionNode[0].second); + + wxPoint2DDouble genPosition((*it)->position.m_x * scale, + (*it)->position.m_y * scale); // Element position. + // Calculate the new generator position: + wxPoint2DDouble offset; + double angle = wxRadToDeg(std::atan2(genPosition.m_y - nodePos.m_y, genPosition.m_x - nodePos.m_x)); + + int tRot = 0; // Number of transformer rotations + int bRot = 0; // Number of bus rotations + if(angle >= -45 && angle <= 45) { + offset = wxPoint2DDouble(75.0, 0.0); + tRot = 4; + bRot = 2; + } else if(angle < -45 && angle > -135) { + offset = wxPoint2DDouble(0.0, -75.0); + tRot = 2; + } else if(angle <= -135 || angle >= 135) { + offset = wxPoint2DDouble(-75.0, 0.0); + bRot = 2; + } else { + offset = wxPoint2DDouble(0.0, 75.0); + tRot = 6; + } + + // Auxiliary bus + Bus* auxBus = new Bus(genPosition); + for(int i = 0; i < bRot; ++i) auxBus->Rotate(); + // Transformer + Transformer* transformer = new Transformer(); + transformer->AddParent(auxBus, auxBus->GetPosition()); + transformer->AddParent(parentBus, nodePos); + for(int i = 0; i < tRot; ++i) transformer->Rotate(); + transformer->StartMove(transformer->GetPosition()); + transformer->Move(genPosition - offset); SyncGenerator* syncGenerator = new SyncGenerator(); - syncGenerator->SetID((*it).id); - syncGenerator->AddParent(parentBus, nodePos); + syncGenerator->SetID((*it)->id); + syncGenerator->AddParent(auxBus, auxBus->GetPosition()); syncGenerator->StartMove(syncGenerator->GetPosition()); - syncGenerator->Move(wxPoint2DDouble((*it).position.m_x * scale, (*it).position.m_y * scale)); + syncGenerator->Move(genPosition + offset); for(int i = 0; i < 2; ++i) syncGenerator->Rotate(false); // Set to ANAREDE default rotation - for(int i = 0; i < (*it).rotationID * 2; ++i) syncGenerator->Rotate(); + for(int i = 0; i < (*it)->rotationID * 2; ++i) syncGenerator->Rotate(); syncGeneratorList.push_back(syncGenerator); + + busList.push_back(auxBus); + transformerList.push_back(transformer); + syncGeneratorList.push_back(syncGenerator); } break; case ANA_LOAD: case ANA_IND_LOAD: { - Bus* parentBus = GetBusFromID(busList, (*it).busConnectionID[0].first); + Bus* parentBus = GetBusFromID(busList, (*it)->busConnectionID[0].first); wxPoint2DDouble nodePos = - parseAnarede.GetNodePositionFromID(parentBus, scale, (*it).busConnectionNode[0].second); + parseAnarede.GetNodePositionFromID(parentBus, scale, (*it)->busConnectionNode[0].second); Load* load = new Load(); - load->SetID((*it).id); + load->SetID((*it)->id); load->AddParent(parentBus, nodePos); load->StartMove(load->GetPosition()); - load->Move(wxPoint2DDouble((*it).position.m_x * scale, (*it).position.m_y * scale)); + load->Move(wxPoint2DDouble((*it)->position.m_x * scale, (*it)->position.m_y * scale)); - for(int i = 0; i < (*it).rotationID * 2; ++i) load->Rotate(); + for(int i = 0; i < (*it)->rotationID * 2; ++i) load->Rotate(); loadList.push_back(load); } break; case ANA_SHUNT: case ANA_IND_SHUNT: { - Bus* parentBus = GetBusFromID(busList, (*it).busConnectionID[0].first); + Bus* parentBus = GetBusFromID(busList, (*it)->busConnectionID[0].first); wxPoint2DDouble nodePos = - parseAnarede.GetNodePositionFromID(parentBus, scale, (*it).busConnectionNode[0].second); - - Inductor* ind = new Inductor(); - ind->SetID((*it).id); - ind->AddParent(parentBus, nodePos); - - ind->StartMove(ind->GetPosition()); - // Offset (ind->GetHeight() / 2 + 10) to adequate the y coordinate - ind->Move(wxPoint2DDouble((*it).position.m_x * scale, - (*it).position.m_y * scale + ind->GetHeight() / 2 + 10)); - if((*it).rotationID != 0) { - // Remove offset in position - ind->Move(wxPoint2DDouble((*it).position.m_x * scale, (*it).position.m_y * scale)); - // Get the rotated point ralated to the offset - wxPoint2DDouble movePt = - ind->RotateAtPosition(ind->GetPosition() + wxPoint2DDouble(0, ind->GetHeight() / 2 + 10), - (*it).rotationID * 90.0, true); - ind->Move(movePt); - - for(int i = 0; i < (*it).rotationID * 2; ++i) ind->Rotate(); + parseAnarede.GetNodePositionFromID(parentBus, scale, (*it)->busConnectionNode[0].second); + + ParseAnarede::BusData* busData = parseAnarede.GetBusDataFromID((*it)->busConnectionID[0].second); + bool isInductor = false; + if(busData->shuntReactive <= 0.0) isInductor = true; + Shunt* shuntElement = NULL; + if(!isInductor) { + Capacitor* cap = new Capacitor(); + auto data = cap->GetElectricalData(); + data.name = _("Capacitor") + wxT("(") + busData->busName + wxT(")"); + data.reactivePower = busData->shuntReactive; + cap->SetElectricalData(data); + shuntElement = cap; + } else { + Inductor* ind = new Inductor(); + auto data = ind->GetElectricalData(); + data.name = _("Inductor") + wxT("(") + busData->busName + wxT(")"); + data.reactivePower = -busData->shuntReactive; + ind->SetElectricalData(data); + shuntElement = ind; } - indList.push_back(ind); + if(shuntElement) { + shuntElement->SetID((*it)->id); + shuntElement->AddParent(parentBus, nodePos); + + shuntElement->StartMove(shuntElement->GetPosition()); + // Offset (ind->GetHeight() / 2 + 10) to adequate the y coordinate + shuntElement->Move(wxPoint2DDouble( + (*it)->position.m_x * scale, (*it)->position.m_y * scale + shuntElement->GetHeight() / 2 + 10)); + if((*it)->rotationID != 0) { + // Remove offset in position + shuntElement->Move(wxPoint2DDouble((*it)->position.m_x * scale, (*it)->position.m_y * scale)); + // Get the rotated point ralated to the offset + wxPoint2DDouble movePt = shuntElement->RotateAtPosition( + shuntElement->GetPosition() + wxPoint2DDouble(0, shuntElement->GetHeight() / 2 + 10), + (*it)->rotationID * 90.0, true); + shuntElement->Move(movePt); + + for(int i = 0; i < (*it)->rotationID * 2; ++i) shuntElement->Rotate(); + } + + if(!isInductor) + capList.push_back(static_cast<Capacitor*>(shuntElement)); + else + indList.push_back(static_cast<Inductor*>(shuntElement)); + } } break; case ANA_MIT: { // Find parent bus - Bus* parentBus = GetBusFromID(busList, (*it).busConnectionID[0].first); + Bus* parentBus = GetBusFromID(busList, (*it)->busConnectionID[0].first); wxPoint2DDouble nodePos = - parseAnarede.GetNodePositionFromID(parentBus, scale, (*it).busConnectionNode[0].second); + parseAnarede.GetNodePositionFromID(parentBus, scale, (*it)->busConnectionNode[0].second); IndMotor* indMotor = new IndMotor(); - indMotor->SetID((*it).id); + indMotor->SetID((*it)->id); indMotor->AddParent(parentBus, nodePos); indMotor->StartMove(indMotor->GetPosition()); - indMotor->Move(wxPoint2DDouble((*it).position.m_x * scale, (*it).position.m_y * scale)); + indMotor->Move(wxPoint2DDouble((*it)->position.m_x * scale, (*it)->position.m_y * scale)); for(int i = 0; i < 2; ++i) indMotor->Rotate(false); // Set to ANAREDE default rotation - for(int i = 0; i < (*it).rotationID * 2; ++i) indMotor->Rotate(); + for(int i = 0; i < (*it)->rotationID * 2; ++i) indMotor->Rotate(); indMotorList.push_back(indMotor); } break; case ANA_TRANSFORMER: { - Bus* parentBus1 = GetBusFromID(busList, (*it).busConnectionID[0].first); - Bus* parentBus2 = GetBusFromID(busList, (*it).busConnectionID[1].first); + Bus* parentBus1 = GetBusFromID(busList, (*it)->busConnectionID[0].first); + Bus* parentBus2 = GetBusFromID(busList, (*it)->busConnectionID[1].first); wxPoint2DDouble nodePos1 = - parseAnarede.GetNodePositionFromID(parentBus1, scale, (*it).busConnectionNode[0].second); + parseAnarede.GetNodePositionFromID(parentBus1, scale, (*it)->busConnectionNode[0].second); wxPoint2DDouble nodePos2 = - parseAnarede.GetNodePositionFromID(parentBus2, scale, (*it).busConnectionNode[1].second); + parseAnarede.GetNodePositionFromID(parentBus2, scale, (*it)->busConnectionNode[1].second); Transformer* transformer = new Transformer(); - transformer->SetID((*it).id); + transformer->SetID((*it)->id); transformer->AddParent(parentBus1, nodePos1); transformer->AddParent(parentBus2, nodePos2); transformer->StartMove(transformer->GetPosition()); - transformer->Move(wxPoint2DDouble((*it).position.m_x * scale, (*it).position.m_y * scale)); + transformer->Move(wxPoint2DDouble((*it)->position.m_x * scale, (*it)->position.m_y * scale)); for(int i = 0; i < 2; ++i) transformer->Rotate(); // Set to ANAREDE default rotation - for(int i = 0; i < (*it).rotationID * 2; ++i) transformer->Rotate(); + for(int i = 0; i < (*it)->rotationID * 2; ++i) transformer->Rotate(); transformerList.push_back(transformer); } break; @@ -187,19 +359,20 @@ bool ImportForm::ImportSelectedFiles() auto powerLines = parseAnarede.GetLines(); for(auto it = powerLines.begin(), itEnd = powerLines.end(); it != itEnd; ++it) { - if((*it).type == ANA_LINE) { - Bus* parentBus1 = GetBusFromID(busList, (*it).busConnectionID[0].first); - Bus* parentBus2 = GetBusFromID(busList, (*it).busConnectionID[1].first); + if((*it)->type == ANA_LINE) { + Bus* parentBus1 = GetBusFromID(busList, (*it)->busConnectionID[0].first); + Bus* parentBus2 = GetBusFromID(busList, (*it)->busConnectionID[1].first); wxPoint2DDouble nodePos1 = - parseAnarede.GetNodePositionFromID(parentBus1, scale, (*it).busConnectionNode[0].second); + parseAnarede.GetNodePositionFromID(parentBus1, scale, (*it)->busConnectionNode[0].second); wxPoint2DDouble nodePos2 = - parseAnarede.GetNodePositionFromID(parentBus2, scale, (*it).busConnectionNode[1].second); + parseAnarede.GetNodePositionFromID(parentBus2, scale, (*it)->busConnectionNode[1].second); Line* line = new Line(); - line->SetID((*it).id); + line->SetID((*it)->id); line->AddParent(parentBus1, nodePos1); - for(unsigned int i = 0; i < (*it).nodesPosition.size(); ++i) - line->AddPoint(wxPoint2DDouble((*it).nodesPosition[i].m_x * scale, (*it).nodesPosition[i].m_y * scale)); + for(unsigned int i = 0; i < (*it)->nodesPosition.size(); ++i) + line->AddPoint( + wxPoint2DDouble((*it)->nodesPosition[i].m_x * scale, (*it)->nodesPosition[i].m_y * scale)); line->AddParent(parentBus2, nodePos2); lineList.push_back(line); @@ -209,8 +382,10 @@ bool ImportForm::ImportSelectedFiles() for(auto it = busList.begin(), itEnd = busList.end(); it != itEnd; ++it) elementList.push_back(*it); for(auto it = syncGeneratorList.begin(), itEnd = syncGeneratorList.end(); it != itEnd; ++it) elementList.push_back(*it); + for(auto it = syncMotorList.begin(), itEnd = syncMotorList.end(); it != itEnd; ++it) elementList.push_back(*it); for(auto it = loadList.begin(), itEnd = loadList.end(); it != itEnd; ++it) elementList.push_back(*it); for(auto it = indList.begin(), itEnd = indList.end(); it != itEnd; ++it) elementList.push_back(*it); + for(auto it = capList.begin(), itEnd = capList.end(); it != itEnd; ++it) elementList.push_back(*it); for(auto it = indMotorList.begin(), itEnd = indMotorList.end(); it != itEnd; ++it) elementList.push_back(*it); for(auto it = transformerList.begin(), itEnd = transformerList.end(); it != itEnd; ++it) elementList.push_back(*it); for(auto it = lineList.begin(), itEnd = lineList.end(); it != itEnd; ++it) elementList.push_back(*it); @@ -248,39 +423,39 @@ bool ParseAnarede::Parse() case 'C': { // Component int parsePosition = 1; - Component component; + Component* component = new Component(); - component.id = wxAtoi(GetLSTLineNextValue(line, parsePosition)); + component->id = wxAtoi(GetLSTLineNextValue(line, parsePosition)); // Check if is component type is valid - if(StrToElementType(GetLSTLineNextValue(line, parsePosition), component.type)) { - if(component.type == ANA_BUS) { - if(!GetLenghtAndRotationFromBusCode(GetLSTLineNextValue(line, parsePosition), component.length, - component.rotationID)) + if(StrToElementType(GetLSTLineNextValue(line, parsePosition), component->type)) { + if(component->type == ANA_BUS) { + if(!GetLenghtAndRotationFromBusCode(GetLSTLineNextValue(line, parsePosition), component->length, + component->rotationID)) return false; } else { - component.rotationID = wxAtoi(GetLSTLineNextValue(line, parsePosition)); + component->rotationID = wxAtoi(GetLSTLineNextValue(line, parsePosition)); } parsePosition += 2; // Jump to position - if(!GetLSTLineNextValue(line, parsePosition).ToCDouble(&component.position.m_x)) return false; - if(!GetLSTLineNextValue(line, parsePosition).ToCDouble(&component.position.m_y)) return false; + if(!GetLSTLineNextValue(line, parsePosition).ToCDouble(&component->position.m_x)) return false; + if(!GetLSTLineNextValue(line, parsePosition).ToCDouble(&component->position.m_y)) return false; parsePosition += 8; // Jump to electrical ID - component.electricalID = wxAtoi(GetLSTLineNextValue(line, parsePosition)); + component->electricalID = wxAtoi(GetLSTLineNextValue(line, parsePosition)); // Bus connection IDs - if(component.type != ANA_BUS) { + if(component->type != ANA_BUS) { int fromBus = wxAtoi(GetLSTLineNextValue(line, parsePosition)); // Origin bus int toBus = 0; // If the component is a transformer, parse the next value (toBus) - if(component.type == ANA_TRANSFORMER) { + if(component->type == ANA_TRANSFORMER) { toBus = wxAtoi(GetLSTLineNextValue(line, parsePosition)); // Destiny bus } // Iterate through the already parsed components (the buses is saved first) for(auto it = m_components.begin(), itEnd = m_components.end(); it != itEnd; ++it) { - if((*it).type == ANA_BUS) { - if(fromBus == (*it).electricalID) { - component.busConnectionID[0] = std::make_pair((*it).id, fromBus); - } else if(toBus == (*it).electricalID) { - component.busConnectionID[1] = std::make_pair((*it).id, toBus); + if((*it)->type == ANA_BUS) { + if(fromBus == (*it)->electricalID) { + component->busConnectionID[0] = std::make_pair((*it)->id, fromBus); + } else if(toBus == (*it)->electricalID) { + component->busConnectionID[1] = std::make_pair((*it)->id, toBus); } } } @@ -291,10 +466,10 @@ bool ParseAnarede::Parse() case 'L': { // Line int parsePosition = 1; - PowerLine pLine; + PowerLine* pLine = new PowerLine(); - pLine.id = wxAtoi(GetLSTLineNextValue(line, parsePosition)); - pLine.type = static_cast<ElementTypeAnarede>(wxAtoi(GetLSTLineNextValue(line, parsePosition))); + pLine->id = wxAtoi(GetLSTLineNextValue(line, parsePosition)); + pLine->type = static_cast<ElementTypeAnarede>(wxAtoi(GetLSTLineNextValue(line, parsePosition))); parsePosition += 4; // Jump to from bus int fromBus = wxAtoi(GetLSTLineNextValue(line, parsePosition)); // Origin bus @@ -302,15 +477,15 @@ bool ParseAnarede::Parse() // Iterate through the already parsed components for(auto it = m_components.begin(), itEnd = m_components.end(); it != itEnd; ++it) { - if((*it).type == ANA_BUS) { - if(fromBus == (*it).id) { - pLine.busConnectionID[0] = std::make_pair((*it).id, (*it).electricalID); - } else if(toBus == (*it).id) { - pLine.busConnectionID[1] = std::make_pair((*it).id, (*it).electricalID); + if((*it)->type == ANA_BUS) { + if(fromBus == (*it)->id) { + pLine->busConnectionID[0] = std::make_pair((*it)->id, (*it)->electricalID); + } else if(toBus == (*it)->id) { + pLine->busConnectionID[1] = std::make_pair((*it)->id, (*it)->electricalID); } } } - pLine.electricalID = wxAtoi(GetLSTLineNextValue(line, parsePosition)); + pLine->electricalID = wxAtoi(GetLSTLineNextValue(line, parsePosition)); m_lines.push_back(pLine); } break; @@ -333,33 +508,33 @@ bool ParseAnarede::Parse() if(data5 != -1) { // Iterate through parsed lines for(auto it = m_lines.begin(), itEnd = m_lines.end(); it != itEnd; ++it) { - if(data5 == (*it).id) { - (*it).busConnectionNode[0] = std::make_pair(data1, data2); - (*it).busConnectionNode[1] = std::make_pair(data3, data4); + if(data5 == (*it)->id) { + (*it)->busConnectionNode[0] = std::make_pair(data1, data2); + (*it)->busConnectionNode[1] = std::make_pair(data3, data4); for(int i = 0; i < data6; ++i) { wxPoint2DDouble nodePt; if(!GetLSTLineNextValue(line, parsePosition).ToCDouble(&nodePt.m_x)) return false; if(!GetLSTLineNextValue(line, parsePosition).ToCDouble(&nodePt.m_y)) return false; - (*it).nodesPosition.push_back(nodePt); + (*it)->nodesPosition.push_back(nodePt); } } } } else { // Iterate through parsed components for(auto it = m_components.begin(), itEnd = m_components.end(); it != itEnd; ++it) { - if(data1 == (*it).id) { - if((*it).type == ANA_BUS) { + if(data1 == (*it)->id) { + if((*it)->type == ANA_BUS) { // If the data1 is a bus ID, the element is a element with different data order. // Find the correct element ID with data3 for(auto itDiff = m_components.begin(), itDiffEnd = m_components.end(); itDiff != itDiffEnd; ++itDiff) { - if(data3 == (*itDiff).id) { - (*itDiff).busConnectionNode[data4 - 1] = std::make_pair(data1, data2); + if(data3 == (*itDiff)->id) { + (*itDiff)->busConnectionNode[data4 - 1] = std::make_pair(data1, data2); break; } } } else { - (*it).busConnectionNode[data2 - 1] = std::make_pair(data3, data4); + (*it)->busConnectionNode[data2 - 1] = std::make_pair(data3, data4); break; } } @@ -501,48 +676,144 @@ bool ParseAnarede::ParsePWFExeCode(wxString data, wxString exeCode) wxString rest = ""; lineData = data.BeforeFirst('\n', &rest); data = rest; - BusData busData; - if(!GetPWFStructuredData(lineData, 0, 5, busData.id)) return false; + BusData* busData = new BusData(); + + if(!GetPWFStructuredData(lineData, 0, 5, busData->id)) return false; wxString isOnlineCode = lineData.Mid(6, 1); - if(isOnlineCode == "L") - busData.isOnline = true; + if(isOnlineCode == "L" || isOnlineCode == " ") + busData->isOnline = true; else if(isOnlineCode == "D") - busData.isOnline = false; + busData->isOnline = false; else return false; - if(!GetPWFStructuredData(lineData, 7, 1, busData.type)) return false; - if(!GetPWFStructuredData(lineData, 8, 2, busData.voltageBase)) return false; - busData.busName = lineData.Mid(10, 12).Trim(); - if(!GetPWFStructuredData(lineData, 24, 4, busData.voltage, 1)) return false; - if(!GetPWFStructuredData(lineData, 28, 4, busData.angle)) return false; + if(!GetPWFStructuredData(lineData, 7, 1, busData->type)) return false; + if(!GetPWFStructuredData(lineData, 8, 2, busData->voltageBase)) return false; + busData->busName = lineData.Mid(10, 12).Trim(); + if(!GetPWFStructuredData(lineData, 24, 4, busData->voltage, 1)) return false; + if(!GetPWFStructuredData(lineData, 28, 4, busData->angle)) return false; double pg, qg; if(!GetPWFStructuredData(lineData, 32, 5, pg)) return false; if(!GetPWFStructuredData(lineData, 37, 5, qg)) return false; - busData.genPower = std::complex<double>(pg, qg); - if(!GetPWFStructuredData(lineData, 42, 5, busData.minReactivePower)) return false; - if(!GetPWFStructuredData(lineData, 47, 5, busData.maxReactivePower)) return false; - if(!GetPWFStructuredData(lineData, 52, 6, busData.ctrlBusID)) return false; + busData->genPower = std::complex<double>(pg, qg); + if(!GetPWFStructuredData(lineData, 42, 5, busData->minReactivePower)) return false; + if(!GetPWFStructuredData(lineData, 47, 5, busData->maxReactivePower)) return false; + if(!GetPWFStructuredData(lineData, 52, 6, busData->ctrlBusID)) return false; double pl, ql; if(!GetPWFStructuredData(lineData, 58, 5, pl)) return false; if(!GetPWFStructuredData(lineData, 63, 5, ql)) return false; - busData.loadPower = std::complex<double>(pl, ql); - if(!GetPWFStructuredData(lineData, 68, 5, busData.shuntReactive)) return false; - - wxMessageBox(wxString::Format("ID = %d\nonline = %d\ntype = %d\nbaseVoltage = %d\nName = \"%s\"\nTensao = " - "%f\nAngulo = %f\nPg = %f\nQg = %f\nminQ = %f\nmaxQ = %f\nctrlBus = %d\nPl = " - "%f\nQl = %f\nshuntMVA = %f", - busData.id, busData.isOnline, busData.type, busData.voltageBase, - busData.busName, busData.voltage, busData.angle, busData.genPower.real(), - busData.genPower.imag(), busData.minReactivePower, busData.maxReactivePower, - busData.ctrlBusID, busData.loadPower.real(), busData.loadPower.imag(), - busData.shuntReactive)); + busData->loadPower = std::complex<double>(pl, ql); + if(!GetPWFStructuredData(lineData, 68, 5, busData->shuntReactive)) return false; + + m_busData.push_back(busData); + } + } else if(exeCode == "DLIN") { + wxString lineData = ""; + while(data != "") { + wxString rest = ""; + lineData = data.BeforeFirst('\n', &rest); + data = rest; + BranchData* branchData = new BranchData(); + + if(!GetPWFStructuredData(lineData, 15, 2, branchData->id)) return false; + int from, to; + if(!GetPWFStructuredData(lineData, 0, 5, from)) return false; + if(!GetPWFStructuredData(lineData, 10, 5, to)) return false; + branchData->busConnections = std::make_pair(from, to); + + wxString isOnlineCode = lineData.Mid(6, 1) + lineData.Mid(9, 1) + lineData.Mid(17, 1); + if(isOnlineCode.Find('D') == wxNOT_FOUND) + branchData->isOnline = true; + else + branchData->isOnline = false; + if(!GetPWFStructuredData(lineData, 20, 6, branchData->resistance, 4)) return false; + if(!GetPWFStructuredData(lineData, 26, 6, branchData->indReactance, 4)) return false; + if(!GetPWFStructuredData(lineData, 32, 6, branchData->capSusceptance, 4)) return false; + if(!GetPWFStructuredData(lineData, 38, 5, branchData->tap, 2)) return false; + if(!GetPWFStructuredData(lineData, 53, 5, branchData->phaseShift, 3)) return false; + + m_branchData.push_back(branchData); + } + } else if(exeCode == "DCAI") { + wxString lineData = ""; + while(data != "") { + wxString rest = ""; + lineData = data.BeforeFirst('\n', &rest); + data = rest; + IndElementData* indData = new IndElementData(); + ; + indData->type = ANA_IND_LOAD; + + if(!GetPWFStructuredData(lineData, 9, 2, indData->id)) return false; + if(!GetPWFStructuredData(lineData, 0, 5, indData->busConnection)) return false; + + wxString isOnlineCode = lineData.Mid(13, 1); + if(isOnlineCode == "L" || isOnlineCode == " ") + indData->isOnline = true; + else if(isOnlineCode == "D") + indData->isOnline = false; + else + return false; + + double pl, ql; + if(!GetPWFStructuredData(lineData, 22, 5, pl)) return false; + if(!GetPWFStructuredData(lineData, 28, 5, ql)) return false; + indData->power = std::complex<double>(pl, ql); + // Unities in operation + if(!GetPWFStructuredData(lineData, 18, 3, indData->numUnits)) return false; + + m_indElementData.push_back(indData); + } + } else if(exeCode == "DGEI") { + wxString lineData = ""; + while(data != "") { + wxString rest = ""; + lineData = data.BeforeFirst('\n', &rest); + data = rest; + IndGenData* genData = new IndGenData(); + genData->type = ANA_IND_GENERATOR; + + if(!GetPWFStructuredData(lineData, 9, 2, genData->id)) return false; + if(!GetPWFStructuredData(lineData, 0, 5, genData->busConnection)) return false; + + wxString isOnlineCode = lineData.Mid(12, 1); + if(isOnlineCode == "L" || isOnlineCode == " ") + genData->isOnline = true; + else if(isOnlineCode == "D") + genData->isOnline = false; + else + return false; + + double pg, qg; + if(!GetPWFStructuredData(lineData, 22, 5, pg)) return false; + if(!GetPWFStructuredData(lineData, 27, 5, qg)) return false; + genData->power = std::complex<double>(pg, qg); + // Unities in operation + if(!GetPWFStructuredData(lineData, 16, 3, genData->numUnits)) return false; + if(!GetPWFStructuredData(lineData, 32, 5, genData->minReactivePower)) return false; + if(!GetPWFStructuredData(lineData, 37, 5, genData->maxReactivePower)) return false; + if(!GetPWFStructuredData(lineData, 42, 6, genData->xt, 2)) return false; + if(!GetPWFStructuredData(lineData, 49, 5, genData->xd, 4)) return false; + if(!GetPWFStructuredData(lineData, 54, 5, genData->xq, 4)) return false; + if(!GetPWFStructuredData(lineData, 59, 5, genData->xl, 4)) return false; + if(!GetPWFStructuredData(lineData, 69, 5, genData->ratedPower, 3)) return false; + + m_indElementData.push_back(genData); } } + return true; } -bool ParseAnarede::GetPWFStructuredData(wxString data, int startPos, int dataLenght, int& value, int decimalPos) +bool ParseAnarede::GetPWFStructuredData(wxString data, + unsigned int startPos, + unsigned int dataLenght, + int& value, + int decimalPos) { + if(data.length() < startPos || data.length() < (startPos + dataLenght)) { + value = 0; + return true; + } wxString strValue = data.Mid(startPos, dataLenght); strValue.Replace(' ', '0'); long lValue = 0; @@ -551,11 +822,55 @@ bool ParseAnarede::GetPWFStructuredData(wxString data, int startPos, int dataLen return true; } -bool ParseAnarede::GetPWFStructuredData(wxString data, int startPos, int dataLenght, double& value, int decimalPos) +bool ParseAnarede::GetPWFStructuredData(wxString data, + unsigned int startPos, + unsigned int dataLenght, + double& value, + int decimalPos) { + if(data.length() < startPos || data.length() < (startPos + dataLenght)) { + value = 0.0; + return true; + } wxString strValue = data.Mid(startPos, dataLenght); if(strValue.Find('-') == wxNOT_FOUND) strValue.Replace(' ', '0'); - if(decimalPos != -1) strValue.insert(decimalPos, '.'); + if(decimalPos != -1 && strValue.Find('.') == wxNOT_FOUND) strValue.insert(decimalPos, '.'); if(!strValue.ToCDouble(&value)) return false; return true; } + +ParseAnarede::BusData* ParseAnarede::GetBusDataFromID(int id) +{ + for(auto it = m_busData.begin(), itEnd = m_busData.end(); it != itEnd; ++it) { + if((*it)->id == id) return *it; + } + return NULL; +} + +ParseAnarede::BranchData* ParseAnarede::GetBranchDataFromID(int id, int fromBus, int toBus) { return NULL; } + +ParseAnarede::IndElementData* ParseAnarede::GetIndElementDataFromID(int id, int bus) { return NULL; } + +void ParseAnarede::ClearData() +{ + for(auto it = m_components.begin(), itEnd = m_components.end(); it != itEnd; ++it) { + if(*it) delete *it; + } + m_components.clear(); + for(auto it = m_lines.begin(), itEnd = m_lines.end(); it != itEnd; ++it) { + if(*it) delete *it; + } + m_lines.clear(); + for(auto it = m_busData.begin(), itEnd = m_busData.end(); it != itEnd; ++it) { + if(*it) delete *it; + } + m_busData.clear(); + for(auto it = m_branchData.begin(), itEnd = m_branchData.end(); it != itEnd; ++it) { + if(*it) delete *it; + } + m_branchData.clear(); + for(auto it = m_indElementData.begin(), itEnd = m_indElementData.end(); it != itEnd; ++it) { + if(*it) delete *it; + } + m_indElementData.clear(); +}
\ No newline at end of file diff --git a/Project/ImportForm.h b/Project/ImportForm.h index e977cbd..f561bcd 100644 --- a/Project/ImportForm.h +++ b/Project/ImportForm.h @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2018 Thales Lima Oliveira <thales@ufu.br> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + #ifndef IMPORTFORM_H #define IMPORTFORM_H @@ -11,12 +28,15 @@ class Workspace; class Bus; class SyncGenerator; +class SyncMotor; class Load; class Capacitor; class Inductor; +class Capacitor; class IndMotor; class Transformer; class Line; +class PropertiesData; /** * @class ImportForm @@ -120,43 +140,67 @@ class ParseAnarede double phaseShift = 0.0; /**< Transformer phase shift */ }; struct IndElementData { - int id = 0; /**< Group electrical ID */ - ElementTypeAnarede type = ANA_IND_GENERATOR; /**< Element type */ - bool isOnline = true; /**< Element is online */ - std::complex<double> loadPower = std::complex<double>(0, 0); /**< Element power */ - int numUnits = 0; /**< Number of unities */ + int id = 0; /**< Group electrical ID */ + int busConnection = 0; /**< Branch connection ID */ + ElementTypeAnarede type = ANA_IND_GENERATOR; /**< Element type */ + bool isOnline = true; /**< Element is online */ + std::complex<double> power = std::complex<double>(0, 0); /**< Element power */ + int numUnits = 0; /**< Number of unities */ + }; + struct IndGenData : IndElementData { + double minReactivePower = -9999.0; /**< Minimal reactive power */ + double maxReactivePower = 99999.0; /**< Maximum reactive power */ + double xt = 1.0; /**< Transformer reactance of each generator */ + double xd = 1.0; /**< Synchronous direct-axis reactance of each generator */ + double xq = 1.0; /**< Synchronous quadrature-axis reactance of each generator */ + double xl = 1.0; /**< Leakage reactance of each generator */ + double ratedPower = 100.0; /**< Rated power of each generator */ }; ParseAnarede(wxFileName lstFile, wxFileName pwfFile); - ~ParseAnarede() {} + ~ParseAnarede() { ClearData(); } bool Parse(); - std::vector<Component> GetComponents() const { return m_components; } - std::vector<PowerLine> GetLines() const { return m_lines; } - std::vector<BranchData> GetBranchData() const { return m_branchData; } - std::vector<BusData> GetBusData() const { return m_busData; } - std::vector<IndElementData> GetIndElementData() const { return m_indElementData; } + std::vector<Component*> GetComponents() const { return m_components; } + std::vector<PowerLine*> GetLines() const { return m_lines; } + std::vector<BranchData*> GetBranchData() const { return m_branchData; } + std::vector<BusData*> GetBusData() const { return m_busData; } + std::vector<IndElementData*> GetIndElementData() const { return m_indElementData; } wxString GetProjectName() const { return m_projectName; } + double GetMVAPowerBase() const { return m_mvaBase; } wxPoint2DDouble GetNodePositionFromID(Bus* bus, double scale, int nodeID); + BusData* GetBusDataFromID(int id); + BranchData* GetBranchDataFromID(int id, int fromBus, int toBus); + IndElementData* GetIndElementDataFromID(int id, int bus); + + void ClearData(); protected: bool GetLenghtAndRotationFromBusCode(wxString code, double& lenght, int& rotationID); wxString GetLSTLineNextValue(wxString line, int& currentPos); bool StrToElementType(wxString strType, ElementTypeAnarede& type); bool ParsePWFExeCode(wxString data, wxString exeCode); - bool GetPWFStructuredData(wxString data, int startPos, int dataLenght, int& value, int decimalPos = -1); - bool GetPWFStructuredData(wxString data, int startPos, int dataLenght, double& value, int decimalPos = -1); + bool GetPWFStructuredData(wxString data, + unsigned int startPos, + unsigned int dataLenght, + int& value, + int decimalPos = -1); + bool GetPWFStructuredData(wxString data, + unsigned int startPos, + unsigned int dataLenght, + double& value, + int decimalPos = -1); wxFileName m_lstFile; wxFileName m_pwfFile; - std::vector<Component> m_components; - std::vector<PowerLine> m_lines; - std::vector<BusData> m_busData; - std::vector<BranchData> m_branchData; - std::vector<IndElementData> m_indElementData; + std::vector<Component*> m_components; + std::vector<PowerLine*> m_lines; + std::vector<BusData*> m_busData; + std::vector<BranchData*> m_branchData; + std::vector<IndElementData*> m_indElementData; wxString m_projectName = _("Imported project"); double m_mvaBase = 100.0; diff --git a/Project/MainFrame.cpp b/Project/MainFrame.cpp index 649db8e..7d129b4 100644 --- a/Project/MainFrame.cpp +++ b/Project/MainFrame.cpp @@ -15,26 +15,26 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include "MainFrame.h" -#include "artProvider/ArtMetro.h" -#include "Workspace.h" +#include "AboutForm.h" #include "Bus.h" -#include "Line.h" -#include "Transformer.h" -#include "SyncGenerator.h" -#include "IndMotor.h" -#include "SyncMotor.h" -#include "Load.h" -#include "Inductor.h" #include "Capacitor.h" -#include "FileHanding.h" -#include "GeneralPropertiesForm.h" -#include "SimulationsSettingsForm.h" -#include "PropertiesData.h" #include "ChartView.h" #include "DataReport.h" -#include "AboutForm.h" +#include "FileHanding.h" +#include "GeneralPropertiesForm.h" #include "ImportForm.h" +#include "IndMotor.h" +#include "Inductor.h" +#include "Line.h" +#include "Load.h" +#include "MainFrame.h" +#include "PropertiesData.h" +#include "SimulationsSettingsForm.h" +#include "SyncGenerator.h" +#include "SyncMotor.h" +#include "Transformer.h" +#include "Workspace.h" +#include "artProvider/ArtMetro.h" MainFrame::MainFrame() : MainFrameBase(NULL) {} MainFrame::MainFrame(wxWindow* parent, wxLocale* locale, PropertiesData* initProperties, wxString openPath) @@ -167,8 +167,8 @@ void MainFrame::OnNewClick(wxRibbonButtonBarEvent& event) { EnableCurrentProjectRibbon(); - Workspace* newWorkspace = - new Workspace(this, wxString::Format(_("New project %d"), m_projectNumber), this->GetStatusBar(), m_sharedGLContext); + Workspace* newWorkspace = new Workspace(this, wxString::Format(_("New project %d"), m_projectNumber), + this->GetStatusBar(), m_sharedGLContext); if(!m_sharedGLContext) m_sharedGLContext = newWorkspace->GetOpenGLContext(); m_workspaceList.push_back(newWorkspace); @@ -215,9 +215,7 @@ void MainFrame::OnDataReportClick(wxRibbonButtonBarEvent& event) void MainFrame::OnDeleteClick(wxRibbonButtonBarEvent& event) { Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage()); - if(workspace) { - workspace->DeleteSelectedElements(); - } + if(workspace) { workspace->DeleteSelectedElements(); } } void MainFrame::OnDisableSolutionClick(wxRibbonButtonBarEvent& event) { @@ -239,20 +237,16 @@ void MainFrame::OnEnableSolutionClick(wxRibbonButtonBarEvent& event) m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_DISABLESOL, false); } -//void MainFrame::OnExpImpClick(wxRibbonButtonBarEvent& event) {} +// void MainFrame::OnExpImpClick(wxRibbonButtonBarEvent& event) {} void MainFrame::OnFaultClick(wxRibbonButtonBarEvent& event) { - if(Workspace* workspace = dynamic_cast<Workspace*>(m_auiNotebook->GetCurrentPage())) { - workspace->RunFault(); - } + if(Workspace* workspace = dynamic_cast<Workspace*>(m_auiNotebook->GetCurrentPage())) { workspace->RunFault(); } } void MainFrame::OnFitClick(wxRibbonButtonBarEvent& event) { Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage()); - if(workspace) { - workspace->Fit(); - } + if(workspace) { workspace->Fit(); } } void MainFrame::OnMoveClick(wxRibbonButtonBarEvent& event) @@ -274,9 +268,7 @@ void MainFrame::OnMoveClick(wxRibbonButtonBarEvent& event) // Set the move position to the average of selected elements. for(auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it) { Element* element = *it; - if(element->IsSelected()) { - element->StartMove(averagePos); - } + if(element->IsSelected()) { element->StartMove(averagePos); } } workspace->SetWorkspaceMode(Workspace::MODE_MOVE_ELEMENT); } @@ -321,9 +313,7 @@ void MainFrame::OnPasteClick(wxRibbonButtonBarEvent& event) {} void MainFrame::OnPowerFlowClick(wxRibbonButtonBarEvent& event) { Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage()); - if(workspace) { - workspace->RunPowerFlow(); - } + if(workspace) { workspace->RunPowerFlow(); } } void MainFrame::OnRedoClick(wxRibbonButtonBarEvent& event) {} @@ -331,17 +321,13 @@ void MainFrame::OnResetVoltagesClick(wxRibbonButtonBarEvent& event) {} void MainFrame::OnRunStabilityClick(wxRibbonButtonBarEvent& event) { Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage()); - if(workspace) { - workspace->RunStability(); - } + if(workspace) { workspace->RunStability(); } } void MainFrame::OnSCPowerClick(wxRibbonButtonBarEvent& event) { Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage()); - if(workspace) { - workspace->RunSCPower(); - } + if(workspace) { workspace->RunSCPower(); } } void MainFrame::OnSaveAsClick(wxRibbonButtonBarEvent& event) @@ -485,8 +471,14 @@ void MainFrame::OnImportClick(wxRibbonButtonBarEvent& event) ImportForm importForm(this, impWorkspace); if(importForm.ShowModal() == wxID_OK) { // Import file(s) + EnableCurrentProjectRibbon(); + if(!m_sharedGLContext) m_sharedGLContext = impWorkspace->GetOpenGLContext(); m_workspaceList.push_back(impWorkspace); + + m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_DISABLESOL, true); + m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_ENABLESOL, false); + m_auiNotebook->AddPage(impWorkspace, impWorkspace->GetName(), true); m_auiNotebook->Layout(); impWorkspace->Redraw(); @@ -521,17 +513,13 @@ void MainFrame::NotebookPageClosing(wxAuiNotebookEvent& event) void MainFrame::OnRotClockClick(wxRibbonButtonBarEvent& event) { Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage()); - if(workspace) { - workspace->RotateSelectedElements(); - } + if(workspace) { workspace->RotateSelectedElements(); } } void MainFrame::OnRotCounterClockClick(wxRibbonButtonBarEvent& event) { Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage()); - if(workspace) { - workspace->RotateSelectedElements(false); - } + if(workspace) { workspace->RotateSelectedElements(false); } } void MainFrame::OnGeneralSettingsClick(wxRibbonButtonBarEvent& event) diff --git a/Project/Project.mk b/Project/Project.mk index 7f0ab83..c0a13dc 100644 --- a/Project/Project.mk +++ b/Project/Project.mk @@ -13,7 +13,7 @@ CurrentFileName := CurrentFilePath := CurrentFileFullPath := User :=NDSE-69 -Date :=02/04/2018 +Date :=03/04/2018 CodeLitePath :="C:/Program Files/CodeLite" LinkerName :=C:/TDM-GCC-64/bin/g++.exe SharedObjectLinkerName :=C:/TDM-GCC-64/bin/g++.exe -shared -fPIC |