#include "mainwindow.h" #include "ui_mainwindow.h" #include #include #include #include #include #include #include #include #include #include #include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); setAcceptDrops(true); QHBoxLayout * hlayout = new QHBoxLayout(ui->centralwidget); hlayout->addWidget(osgWidget); hlayout->setSizeConstraint(QLayout::SetNoConstraint); osgWidget->setMouseTracking(true); connect(osgWidget, &osgQOpenGLWidget::initialized, this, &MainWindow::initOsg); connect(ui->actionOpenModel, &QAction::triggered, [this](){ QString modelFile = QFileDialog::getOpenFileName(this, tr("3D Model File Selection"), "", "*.s3c; *.osg; *.osgb"); if(modelFile != ""){ addModel(modelFile); } }); connect(ui->actionUpdateModel, &QAction::triggered, this, &MainWindow::updateModel); connect(ui->actionZoomToExtent, &QAction::triggered, [this]{ osgWidget->getOsgViewer()->setCameraManipulator(new osgGA::TrackballManipulator()); }); } MainWindow::~MainWindow() { delete ui; } void MainWindow::dragEnterEvent(QDragEnterEvent *event) { event->acceptProposedAction(); } void MainWindow::dropEvent(QDropEvent *event) { QList urls = event->mimeData()->urls(); if(urls.isEmpty()){ return; } QList::iterator it; for(it = urls.begin(); it != urls.end(); it++){ QFileInfo fileInfo(it->toLocalFile()); if(fileInfo.isFile()){ addModel(fileInfo.filePath()); } } } void MainWindow::initOsg() { osgWidget->getOsgViewer()->setSceneData(root); osgWidget->getOsgViewer()->getCamera()->setSmallFeatureCullingPixelSize(-1.0f); osgWidget->getOsgViewer()->getCamera()->setClearColor(osg::Vec4(0.5,0.5,0.5,0.5)); osgWidget->getOsgViewer()->getCamera()->setNearFarRatio(0.0001); float aspectRatio = static_cast( osgWidget->width()) / static_cast( osgWidget->height() ); osgWidget->getOsgViewer()->getCamera()->setProjectionMatrixAsPerspective( 30.f, aspectRatio, 1.f, 1000.f ); osg::ref_ptr light = new osg::Light(); light->setLightNum(0); light->setDirection(osg::Vec3(0.0f, 0.0f, -1.0f)); light->setPosition(osg::Vec4(0.0f, 0.0f, 1000, 0.0f)); light->setAmbient(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); light->setDiffuse(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); // //设置恒衰减指数 // light->setConstantAttenuation(1.0f); // //设置线形衰减指数 // light->setLinearAttenuation(0.0f); // //设置二次方衰减指数 // light->setQuadraticAttenuation(0.0f); osgWidget->getOsgViewer()->setLight(light); mp = new MousePicker(this); osgWidget->getOsgViewer()->addEventHandler(mp); addModel("C:/Users/16284/Desktop/qt/Tile_+000_+005/Tile_+000_+005/Tile_+000_+005.osgb"); } void MainWindow::addModel(QString modelFile) { if(modelFile == filename){ return; } filename = modelFile; QString ext = filename.split('.').back().toLower(); osg::Group* layer = new osg::Group; if(ext == "osg" || ext == "osgb" || ext == "obj" || ext == "ive"){ clearModel(); osg::Node* node = osgDB::readNodeFile(Utf8ToGbk(filename.toStdString())); node->setName(filename.toStdString()); layer->addChild(node); } else if(ext == "s3c"){ QDir folder(filename); folder.cdUp(); QDir dataPath(folder.absolutePath() + "/Data"); clearModel(); QStringList tileFolderList = dataPath.entryList(); for(QString tileFolder: tileFolderList){ QString tileFile = dataPath.absolutePath() + '/' + tileFolder + '/' + tileFolder + ".osgb"; if(QDir().exists(tileFile)){ osg::Node* node = osgDB::readNodeFile(Utf8ToGbk(tileFile.toStdString())); node->setName(tileFolder.toStdString() + ".osgb"); layer->addChild(node); } } } else{ QMessageBox::warning(this, "simulationMaster", "Unsupported File Format! "); return; } root->addChild(layer); mp->setRoot(root); osgGA::TrackballManipulator* tm = new osgGA::TrackballManipulator(); tm->setAllowThrow(false); tm->setAnimationTime(1000); osgWidget->getOsgViewer()->setCameraManipulator(tm); } void MainWindow::updateModel() { // 选择模型更新基于的三维符号库 // QString libFileName = QFileDialog::getOpenFileName(this, "Plz choose the 3dl file", "", "*.3dl"); QString libFileName = QString::fromLocal8Bit("C:/Users/16284/Desktop/qt/LibMASTER/基础三维符号库.3dl"); if(libFileName == ""){ return; } QDir dir = QDir(libFileName); dir.cdUp(); // 将三维符号库读取到内存中 QMap> map; QDomDocument doc; QFile file(libFileName); file.open(QIODevice::ReadOnly); doc.setContent(&file); file.close(); QDomNode FLevNode = doc.documentElement().firstChild().toElement().firstChild(); //用来访问第一级符号 QDomNode SLevNode = FLevNode.toElement().firstChild(); //用来访问第二级符号 while(!FLevNode.isNull()){ if (FLevNode.toElement().tagName() == QStringLiteral("catagory")){ Item FirstItem; //存一级符号 QList SecondList; //某一级符号下,所有二级符号组成的列表 FirstItem.name = FLevNode.toElement().attribute("name").trimmed(); FirstItem.code = FLevNode.toElement().attribute("code").trimmed(); SLevNode = FLevNode.toElement().firstChild(); while(!SLevNode.isNull()){ if (SLevNode.toElement().tagName() == QStringLiteral("feature")){ Item SecondItem; //存二级符号 SecondItem.name = SLevNode.toElement().attribute("name").trimmed(); SecondItem.code = SLevNode.toElement().attribute("code").trimmed(); SecondItem.address = SLevNode.toElement().attribute("address").trimmed(); SecondList << SecondItem; } SLevNode = SLevNode.nextSibling(); } map.insert(FirstItem, SecondList); } FLevNode = FLevNode.nextSibling(); //访问下一个兄弟节点 } // 选择需要渲染的符号 QDialog dialog(this); QFormLayout form(&dialog); form.addRow(new QLabel(QStringLiteral("选择渲染使用的符号"))); // 获取符号类别名称 QComboBox *cataChosen = new QComboBox(&dialog); form.addRow(QStringLiteral("类别名称: "), cataChosen); // 获取符号类别编码 QComboBox *modelChosen = new QComboBox(&dialog); connect(cataChosen, static_cast(&QComboBox::currentIndexChanged), [=](int index){ modelChosen->clear(); QList itemList = map.values().at(index); for(int i = 0; i < itemList.count(); i++){ modelChosen->addItem(itemList.at(i).name); } }); for(int i = 0; i < map.count(); i++){ cataChosen->addItem(map.keys().at(i).name); } form.addRow(QStringLiteral("符号名称: "), modelChosen); // Add Cancel and OK button QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &dialog); form.addRow(&buttonBox); QObject::connect(&buttonBox, SIGNAL(accepted()), &dialog, SLOT(accept())); QObject::connect(&buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject())); dialog.adjustSize(); // dialog.setFixedWidth(250); // dialog.setFixedHeight(120); // Process when OK button is clicked int result = dialog.exec(); while(result == QDialog::Accepted){ if(cataChosen->currentIndex()==-1 || modelChosen->currentIndex()==-1){ QMessageBox::warning(this, "simulationMaster", "Plz choose the catagory and model"); result = dialog.exec(); continue; } Item item = map.values().at(cataChosen->currentIndex()).at(modelChosen->currentIndex()); // 根据item.address读取模型 osg::Node* model = osgDB::readNodeFile(Utf8ToGbk((dir.absolutePath() + '/' + item.address).toStdString())); mp->activate(PickingMode::PointPicker, model); // connect(mp, &MousePicker::editionDone, [=](PickingMode mode, osg::ref_ptr vertexArray) // { // if(vertexArray == nullptr){ // return; // } // if(mode == PickingMode::PointPicker){ // nv.setPoints(vertexArray); // root->getChild(0)->accept(nv); // } // }); break; } } void MainWindow::clearModel() { root->removeChildren(0, root->getNumChildren()); } std::string Utf8ToGbk(std::string str){ const char* src_str = str.data(); int len = MultiByteToWideChar(CP_UTF8, 0, src_str, -1, NULL, 0); wchar_t* wszGBK = new wchar_t[len + 1]; memset(wszGBK, 0, len * 2 + 2); MultiByteToWideChar(CP_UTF8, 0, src_str, -1, wszGBK, len); len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL); char* szGBK = new char[len + 1]; memset(szGBK, 0, len + 1); WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, szGBK, len, NULL, NULL); std::string strTemp(szGBK); if (wszGBK) delete[] wszGBK; if (szGBK) delete[] szGBK; return strTemp; }