396 lines
11 KiB
C++
396 lines
11 KiB
C++
#include "workspace/WorkSpace.h"
|
|
|
|
#include <QUUID>
|
|
#include <QFileInfo>
|
|
#include <QDir>
|
|
|
|
#include "workspace/WorkSpaceXMLParse.h"
|
|
#include "workspace/WorkSpaceXMLWrite.h"
|
|
#include "workspace/CommandManager.h"
|
|
|
|
#include "workspace/WorkSpaceItem.h"
|
|
#include "workspace/Timestep.h"
|
|
#include "workspace/LampStatus.h"
|
|
|
|
#include "xml/tinyxml2.h"
|
|
#include "common/SpdLogger.h"
|
|
#include "entities/Entity.h"
|
|
#include "utils/FileUtils.h"
|
|
#include <QProcess>
|
|
//#include "workspace/WorkSpaceItemGroup.h"
|
|
//#include "workspace/WorkSpaceRiverGroup.h"
|
|
//#include "workspace/WorkSpaceRiverNetGroup.h"
|
|
|
|
Q_DECLARE_METATYPE(WorkSpace*)
|
|
|
|
WorkSpace::WorkSpace(QObject* parent) noexcept
|
|
: QObject(parent) {
|
|
uuid_ = QUuid::createUuid().toString();
|
|
homeViewpoint_ = osgEarth::Viewpoint("home", 120.000000, 25.000000, 100.000000, -2.500000, -90.000000, 8200000.000000);
|
|
cmdMgr_ = std::make_unique<CommandManager>();
|
|
}
|
|
|
|
WorkSpace::WorkSpace(const QString& path, QObject* parent)
|
|
: QObject(parent)
|
|
, path_(path){
|
|
uuid_ = QUuid::createUuid().toString();
|
|
homeViewpoint_ = osgEarth::Viewpoint("home", 120.000000, 25.000000, 100.000000, -2.500000, -90.000000, 8200000.000000);
|
|
cmdMgr_ = std::make_unique<CommandManager>();
|
|
}
|
|
|
|
const QString WorkSpace::GetDir() const {
|
|
QFileInfo info(path_);
|
|
return info.absolutePath();
|
|
}
|
|
|
|
void WorkSpace::SetCommondFilePath(const QString& path) {
|
|
QFileInfo fileInfo(path);
|
|
QString dirPath = QString("%1/%2").arg(GetDir(), fileInfo.fileName());
|
|
bool sucess = FileUtils::CopyFileToPath(path, dirPath, true);
|
|
LOG_INFO("copy commond file {}: {} to {}",
|
|
path.toLocal8Bit().data(),
|
|
dirPath.toLocal8Bit().data(),
|
|
sucess);
|
|
commondPath_ = fileInfo.fileName();
|
|
}
|
|
|
|
const QString WorkSpace::GetCommondFilePath() const {
|
|
QString path = QString("%1/%2").arg(GetDir(), commondPath_);
|
|
return path;
|
|
}
|
|
|
|
void WorkSpace::SetSimMatlab(const QString& path) {
|
|
QFileInfo fileInfo(path);
|
|
QString dirPath = QString("%1/%2").arg(GetDir(), fileInfo.fileName());
|
|
bool sucess = FileUtils::CopyFileToPath(path, dirPath, true);
|
|
LOG_INFO("copy simmatlab file {}: {} to {}",
|
|
path.toLocal8Bit().data(),
|
|
dirPath.toLocal8Bit().data(),
|
|
sucess);
|
|
simMatlabPath_ = fileInfo.fileName();
|
|
}
|
|
|
|
const QString WorkSpace::GetSimMatlab() const {
|
|
QString path = QString("%1/%2").arg(GetDir(), simMatlabPath_);
|
|
return path;
|
|
}
|
|
|
|
void WorkSpace::SetWavePath(const QString& path)
|
|
{
|
|
QFileInfo fileInfo(path);
|
|
QString dirPath = QString("%1/%2").arg(GetDir(), fileInfo.fileName());
|
|
bool sucess = FileUtils::CopyFileToPath(path, dirPath, true);
|
|
LOG_INFO("copy Wave file {}: {} to {}",
|
|
path.toLocal8Bit().data(),
|
|
dirPath.toLocal8Bit().data(),
|
|
sucess);
|
|
waveFile_ = fileInfo.fileName();
|
|
}
|
|
|
|
const QString WorkSpace::GetWavePath() const
|
|
{
|
|
QString path = QString("%1/%2").arg(GetDir(), waveFile_);
|
|
return path;
|
|
}
|
|
|
|
void WorkSpace::SetReportPath(const QString& path)
|
|
{
|
|
QFileInfo fileInfo(path);
|
|
QString dirPath = QString("%1/%2").arg(GetDir(), fileInfo.fileName());
|
|
bool sucess = FileUtils::CopyFileToPath(path, dirPath, true);
|
|
LOG_INFO("copy Wave file {}: {} to {}",
|
|
path.toLocal8Bit().data(),
|
|
dirPath.toLocal8Bit().data(),
|
|
sucess);
|
|
reportFile_ = fileInfo.fileName();
|
|
}
|
|
|
|
const QString WorkSpace::GetReportPath() const
|
|
{
|
|
QString path = QString("%1/%2").arg(GetDir(), reportFile_);
|
|
return path;
|
|
}
|
|
|
|
void WorkSpace::SetRDPath(const QString& path)
|
|
{
|
|
QFileInfo fileInfo(path);
|
|
QString dirPath = QString("%1/%2").arg(GetDir(), fileInfo.fileName());
|
|
bool sucess = FileUtils::CopyFileToPath(path, dirPath, true);
|
|
LOG_INFO("copy RD file {}: {} to {}",
|
|
path.toLocal8Bit().data(),
|
|
dirPath.toLocal8Bit().data(),
|
|
sucess);
|
|
rdFile_ = fileInfo.fileName();
|
|
}
|
|
|
|
std::vector<FileEntry> WorkSpace::GetFileEntries(FileEntryType type) const {
|
|
auto it = files_.find(type);
|
|
if (it == files_.end()) {
|
|
return {};
|
|
}
|
|
return it->second;
|
|
}
|
|
|
|
WorkSpace::FileEntryResult WorkSpace::CreateFileEntry(FileEntryType type) {
|
|
auto& vec = files_[type];
|
|
if (vec.size() >= 9) {
|
|
return FileEntryResult::LimitExceeded;
|
|
}
|
|
// push a placeholder; actual filename may be set elsewhere via SetWavePath/SetRDPath/etc
|
|
vec.push_back(FileEntry{ type, QString() });
|
|
++filesSeq_;
|
|
// Notify listeners (e.g., PropertyBrowser) to refresh workspace properties
|
|
emit FilesChanged(type);
|
|
return FileEntryResult::Ok;
|
|
}
|
|
|
|
bool WorkSpace::SetFileEntryCount(FileEntryType type, int count) {
|
|
if (count < 0) count = 0;
|
|
if (count > 9) count = 9;
|
|
auto& vec = files_[type];
|
|
if (static_cast<int>(vec.size()) == count) {
|
|
return true;
|
|
}
|
|
if (static_cast<int>(vec.size()) < count) {
|
|
int toAdd = count - static_cast<int>(vec.size());
|
|
for (int i = 0; i < toAdd; ++i) {
|
|
vec.push_back(FileEntry{ type, QString() });
|
|
}
|
|
} else {
|
|
vec.resize(count);
|
|
}
|
|
++filesSeq_;
|
|
emit FilesChanged(type);
|
|
return true;
|
|
}
|
|
|
|
bool WorkSpace::SetFileEntryPath(FileEntryType type, int index, const QString& path) {
|
|
auto& vec = files_[type];
|
|
if (index < 0 || index >= static_cast<int>(vec.size())) {
|
|
return false;
|
|
}
|
|
QFileInfo fileInfo(path);
|
|
if (!fileInfo.exists()) {
|
|
return false;
|
|
}
|
|
QString dirPath = QString("%1/%2").arg(GetDir(), fileInfo.fileName());
|
|
bool sucess = FileUtils::CopyFileToPath(path, dirPath, true);
|
|
LOG_INFO("copy grouped file {}: {} to {}",
|
|
path.toLocal8Bit().data(),
|
|
dirPath.toLocal8Bit().data(),
|
|
sucess);
|
|
if (!sucess) {
|
|
return false;
|
|
}
|
|
vec[index].fileName = fileInfo.fileName();
|
|
++filesSeq_;
|
|
emit FilesChanged(type);
|
|
return true;
|
|
}
|
|
|
|
QString WorkSpace::GetFileEntryAbsPath(FileEntryType type, int index) const {
|
|
auto it = files_.find(type);
|
|
if (it == files_.end()) {
|
|
return QString();
|
|
}
|
|
const auto& vec = it->second;
|
|
if (index < 0 || index >= static_cast<int>(vec.size())) {
|
|
return QString();
|
|
}
|
|
const QString& name = vec[index].fileName;
|
|
if (name.isEmpty()) {
|
|
return QString();
|
|
}
|
|
return QString("%1/%2").arg(GetDir(), name);
|
|
}
|
|
|
|
const QString WorkSpace::GetRDPath() const
|
|
{
|
|
QString path = QString("%1/%2").arg(GetDir(), rdFile_);
|
|
return path;
|
|
}
|
|
|
|
void WorkSpace::AddEntity(Entity* entity) {
|
|
if (nullptr == entity) {
|
|
LOG_WARN("entity is nullptr");
|
|
return;
|
|
}
|
|
LOG_INFO("add entity: {}", entity->GetName().toLocal8Bit().constData());
|
|
entities_.push_back(entity);
|
|
entity->SetWorkspace(this);
|
|
|
|
emit EntityAdded(entity);
|
|
}
|
|
|
|
void WorkSpace::RemoveEntity(Entity* entity) {
|
|
auto itor = std::find_if(entities_.begin(), entities_.end(),
|
|
[this, entity](const auto* item) { return item == entity; });
|
|
if (itor != entities_.end()) {
|
|
emit EntityRemoved(entity);
|
|
entities_.erase(itor);
|
|
}
|
|
}
|
|
|
|
bool WorkSpace::TrackEntity(Entity* entity) {
|
|
dyt_check(nullptr != entity);
|
|
if (trackedEntity_ == entity) {
|
|
LOG_INFO("entity already tracked: {}", entity->GetName().toStdString());
|
|
return true;
|
|
}
|
|
|
|
if (nullptr == scene_) {
|
|
LOG_WARN("scene is nullptr, cannot track entity: {}", entity->GetName().toStdString());
|
|
return false;
|
|
}
|
|
if (trackedEntity_ != entity) {
|
|
UntrackEntity();
|
|
}
|
|
trackedEntity_ = entity;
|
|
|
|
auto mt = entity->GetRootComponent()->GetMatrixTransform();
|
|
LOG_INFO("track entity: {}", entity->GetName().toStdString());
|
|
return scene_->TrackEntity(mt, true);
|
|
}
|
|
|
|
void WorkSpace::UntrackEntity() {
|
|
if (trackedEntity_ != nullptr) {
|
|
if (scene_ != nullptr) {
|
|
LOG_INFO("untrack entity: {}", trackedEntity_->GetName().toStdString());
|
|
auto mt = trackedEntity_->GetRootComponent()->GetMatrixTransform();
|
|
scene_->TrackEntity(mt, false);
|
|
}
|
|
}
|
|
trackedEntity_ = nullptr;
|
|
}
|
|
|
|
void WorkSpace::SetActiveScene(OEScene* scene) {
|
|
dyt_check(nullptr != scene);
|
|
scene_ = scene;
|
|
|
|
//osgEarth::Viewpoint vp;
|
|
//vp.name() = "home";
|
|
//vp.focalPoint()->set(scene->GetSrs(), -121.488, 46.2054, 0, osgEarth::AltitudeMode::ALTMODE_ABSOLUTE);
|
|
//vp.pitch() = -50.0;
|
|
//vp.range() = 100000;
|
|
//homeViewpoint_ = vp;
|
|
}
|
|
|
|
bool WorkSpace::SetTimestep(Timestep* timestep) {
|
|
if (!timestep) {
|
|
return false;
|
|
}
|
|
|
|
if (nullptr != timestep_ && timestep_ != timestep) {
|
|
timestep_->deleteLater();
|
|
}
|
|
|
|
timestep_ = timestep;
|
|
emit TimestepChanged(timestep_);
|
|
return true;
|
|
}
|
|
|
|
bool WorkSpace::SetTimestepPath(const QString& path) {
|
|
Timestep* timestep = Timestep::Load(path, this);
|
|
|
|
return SetTimestep(timestep);
|
|
}
|
|
|
|
bool WorkSpace::SetLampStatus(class LampStatus* lampStatus) {
|
|
if (!lampStatus) {
|
|
return false;
|
|
}
|
|
|
|
if (nullptr != lampStatus_ && lampStatus_ != lampStatus) {
|
|
lampStatus_->deleteLater();
|
|
}
|
|
|
|
lampStatus_ = lampStatus;
|
|
emit LampStatusChanged(lampStatus_);
|
|
return true;
|
|
}
|
|
|
|
bool WorkSpace::SetLampPath(const QString& path) {
|
|
LampStatus* timestep = LampStatus::Load(path, this);
|
|
|
|
return SetLampStatus(timestep);
|
|
}
|
|
|
|
bool WorkSpace::Save(const QString& path) {
|
|
path_ = path;
|
|
return Save();
|
|
}
|
|
|
|
bool WorkSpace::Save() {
|
|
WorkSpaceXMLWrite xmlWrite(this);
|
|
return xmlWrite.Save(path_);
|
|
}
|
|
|
|
bool WorkSpace::Load(const QString& dyt) {
|
|
if (leaded_) {
|
|
LOG_INFO("dyt {} loaded", dyt.toStdString());
|
|
return true;
|
|
}
|
|
LOG_INFO("dyt {} loading", dyt.toLocal8Bit().constData());
|
|
path_ = dyt;
|
|
WorkSpaceXMLParse parse(this);
|
|
bool success = parse.Load(dyt);
|
|
if (!success) {
|
|
path_ = "";
|
|
}
|
|
leaded_ = success;
|
|
return success;
|
|
}
|
|
|
|
void WorkSpace::Unlaod() {
|
|
if (!leaded_) {
|
|
LOG_INFO("dyt {} unloaded", name_.toStdString());
|
|
return;
|
|
}
|
|
while (!entities_.empty()) {
|
|
auto entity = entities_.front();
|
|
entity->Destory();
|
|
}
|
|
leaded_ = false;
|
|
}
|
|
|
|
void WorkSpace::Begin() {
|
|
for (auto item : entities_) {
|
|
item->Begin();
|
|
}
|
|
}
|
|
|
|
void WorkSpace::OnFrame(double dt) {
|
|
if (nullptr != lampStatus_) {
|
|
double current = timestep_->GetCurrent();
|
|
lampStatus_->OnFrame(current);
|
|
}
|
|
|
|
for (auto item : entities_) {
|
|
item->Update(dt);
|
|
}
|
|
}
|
|
|
|
void WorkSpace::End() {
|
|
for (auto item : entities_) {
|
|
item->End();
|
|
}
|
|
}
|
|
|
|
void WorkSpace::OnLoaded() {
|
|
if (nullptr != lampStatus_) {
|
|
emit LampStatusChanged(lampStatus_);
|
|
}
|
|
if (nullptr != timestep_) {
|
|
emit TimestepChanged(timestep_);
|
|
}
|
|
// Execute commands configured for onLoad
|
|
ExecuteCommands(CommandWhen::OnLoad);
|
|
}
|
|
|
|
void WorkSpace::ExecuteCommands(CommandWhen when) {
|
|
if (!cmdMgr_) {
|
|
cmdMgr_ = std::make_unique<CommandManager>();
|
|
}
|
|
cmdMgr_->Execute(this, when);
|
|
}
|