first commit
This commit is contained in:
		
						commit
						ac8b22f196
					
				
							
								
								
									
										54
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					# ---> Qt
 | 
				
			||||||
 | 
					# C++ objects and libs
 | 
				
			||||||
 | 
					*.slo
 | 
				
			||||||
 | 
					*.lo
 | 
				
			||||||
 | 
					*.o
 | 
				
			||||||
 | 
					*.a
 | 
				
			||||||
 | 
					*.la
 | 
				
			||||||
 | 
					*.lai
 | 
				
			||||||
 | 
					*.so
 | 
				
			||||||
 | 
					*.so.*
 | 
				
			||||||
 | 
					*.dll
 | 
				
			||||||
 | 
					*.dylib
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Qt-es
 | 
				
			||||||
 | 
					object_script.*.Release
 | 
				
			||||||
 | 
					object_script.*.Debug
 | 
				
			||||||
 | 
					*_plugin_import.cpp
 | 
				
			||||||
 | 
					/.qmake.cache
 | 
				
			||||||
 | 
					/.qmake.stash
 | 
				
			||||||
 | 
					*.pro.user
 | 
				
			||||||
 | 
					*.pro.user.*
 | 
				
			||||||
 | 
					*.qbs.user
 | 
				
			||||||
 | 
					*.qbs.user.*
 | 
				
			||||||
 | 
					*.moc
 | 
				
			||||||
 | 
					moc_*.cpp
 | 
				
			||||||
 | 
					moc_*.h
 | 
				
			||||||
 | 
					qrc_*.cpp
 | 
				
			||||||
 | 
					ui_*.h
 | 
				
			||||||
 | 
					*.qmlc
 | 
				
			||||||
 | 
					*.jsc
 | 
				
			||||||
 | 
					Makefile*
 | 
				
			||||||
 | 
					*build-*
 | 
				
			||||||
 | 
					*.qm
 | 
				
			||||||
 | 
					*.prl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Qt unit tests
 | 
				
			||||||
 | 
					target_wrapper.*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# QtCreator
 | 
				
			||||||
 | 
					*.autosave
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# QtCreator Qml
 | 
				
			||||||
 | 
					*.qmlproject.user
 | 
				
			||||||
 | 
					*.qmlproject.user.*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# QtCreator CMake
 | 
				
			||||||
 | 
					CMakeLists.txt.user*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# QtCreator 4.8< compilation database 
 | 
				
			||||||
 | 
					compile_commands.json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# QtCreator local machine specific files for imported projects
 | 
				
			||||||
 | 
					*creator.user*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										151
									
								
								MousePicker.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								MousePicker.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,151 @@
 | 
				
			|||||||
 | 
					#include "MousePicker.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QtWidgets>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osg/Point>
 | 
				
			||||||
 | 
					#include <osg/MatrixTransform>
 | 
				
			||||||
 | 
					#include <osgViewer/Viewer>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MousePicker::MousePicker(QObject *parent)
 | 
				
			||||||
 | 
					    : QObject(parent)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // 防止老点绘制影响新点的求交运算
 | 
				
			||||||
 | 
					    currentDrawNode->setNodeMask(0xffffffff & (~0x00000004));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MousePicker::setRoot(osg::ref_ptr<osg::Group> root)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					//    root->addChild(currentDrawNode);
 | 
				
			||||||
 | 
					    root->addChild(drawNodeList);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MousePicker::activate(PickingMode _mode, osg::Node* node)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    disactivate();
 | 
				
			||||||
 | 
					    mode = _mode;
 | 
				
			||||||
 | 
					    isActivated = true;
 | 
				
			||||||
 | 
					    model = node;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool MousePicker::handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if(!isActivated){
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    osgViewer::Viewer* pViewer = dynamic_cast<osgViewer::Viewer*>( &aa );
 | 
				
			||||||
 | 
					    osgUtil::LineSegmentIntersector::Intersections intersections;
 | 
				
			||||||
 | 
					    pViewer->computeIntersections(ea, intersections, 0x00000004);
 | 
				
			||||||
 | 
					    if(intersections.empty()){
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    osg::Vec3 mouseWorldCoord = intersections.begin()->getWorldIntersectPoint();
 | 
				
			||||||
 | 
					    switch( ea.getEventType() ){
 | 
				
			||||||
 | 
					    case osgGA::GUIEventAdapter::PUSH:{
 | 
				
			||||||
 | 
					        if(ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON){
 | 
				
			||||||
 | 
					            if(!isDrawing){
 | 
				
			||||||
 | 
					                // 初始化lineGeometry
 | 
				
			||||||
 | 
					                lineGeometry = new osg::Geometry;
 | 
				
			||||||
 | 
					                lineGeometry->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
 | 
				
			||||||
 | 
					                currentDrawNode->addDrawable(lineGeometry);
 | 
				
			||||||
 | 
					                // 初始化vertexArray
 | 
				
			||||||
 | 
					                vertexArray = new osg::Vec3Array;
 | 
				
			||||||
 | 
					                vertexArray->push_back(mouseWorldCoord);
 | 
				
			||||||
 | 
					                osg::ref_ptr<osg::Vec4Array>  color = new osg::Vec4Array();
 | 
				
			||||||
 | 
					                color->push_back(osg::Vec4(0.0f, 0.8f, 0.8f, 0.5f) );
 | 
				
			||||||
 | 
					                lineGeometry->setColorArray(color, osg::Array::BIND_OVERALL);
 | 
				
			||||||
 | 
					                isDrawing = true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            vertexArray->push_back(mouseWorldCoord);
 | 
				
			||||||
 | 
					            vertexArray->dirty();
 | 
				
			||||||
 | 
					            pushPnt = mouseWorldCoord;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if(ea.getButton() == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON){
 | 
				
			||||||
 | 
					            // 当点击右键时, 退出编辑
 | 
				
			||||||
 | 
					            disactivate();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    case osgGA::GUIEventAdapter::RELEASE:{
 | 
				
			||||||
 | 
					        if(ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON){
 | 
				
			||||||
 | 
					            // 点击事件完成时
 | 
				
			||||||
 | 
					            if(pushPnt != mouseWorldCoord){
 | 
				
			||||||
 | 
					                // 当用户真正希望的是拖动视角时,弹出点击事件的录入操作,假装无事发生
 | 
				
			||||||
 | 
					                vertexArray->pop_back();
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            // 绘制相应点
 | 
				
			||||||
 | 
					//            currentDrawNode->addDrawable(createPointGeode(mouseWorldCoord));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            osg::MatrixTransform* mt = new osg::MatrixTransform;
 | 
				
			||||||
 | 
					            mt->setMatrix(
 | 
				
			||||||
 | 
					                        osg::Matrix::translate(mouseWorldCoord));
 | 
				
			||||||
 | 
					            mt->addChild(model);
 | 
				
			||||||
 | 
					            drawNodeList->addChild(mt);
 | 
				
			||||||
 | 
					            if(mode == LinePicker){
 | 
				
			||||||
 | 
					                // 如果是线要素则绘制该线段并显示长度
 | 
				
			||||||
 | 
					                lineGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, vertexArray->size()));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if(mode == AreaPicker){
 | 
				
			||||||
 | 
					                // 如果是面要素则绘制该面并显示面积
 | 
				
			||||||
 | 
					                lineGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, vertexArray->size()));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    case osgGA::GUIEventAdapter::MOVE:{
 | 
				
			||||||
 | 
					        if(isDrawing){
 | 
				
			||||||
 | 
					            // 绘制过程中,按不同的图形类型进行图形绘制的预览
 | 
				
			||||||
 | 
					            vertexArray->pop_back();
 | 
				
			||||||
 | 
					            vertexArray->push_back(mouseWorldCoord);
 | 
				
			||||||
 | 
					            vertexArray->dirty();
 | 
				
			||||||
 | 
					            if(mode == PointPicker){
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            // 根据MOVE的坐标实时更新lineGeometry
 | 
				
			||||||
 | 
					            lineGeometry->setVertexArray(vertexArray);
 | 
				
			||||||
 | 
					            lineGeometry->dirtyDisplayList();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    case osgGA::GUIEventAdapter::DOUBLECLICK:{
 | 
				
			||||||
 | 
					        if(isDrawing){
 | 
				
			||||||
 | 
					            // 当双击时,完成当前geode的编辑
 | 
				
			||||||
 | 
					            isDrawing = false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // 双击时应避免视角操作,故返回true
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MousePicker::disactivate()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    isDrawing = false;
 | 
				
			||||||
 | 
					    isActivated = false;
 | 
				
			||||||
 | 
					    emit editionDone(mode, vertexArray);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    currentDrawNode->removeChildren(0, currentDrawNode->getNumChildren());
 | 
				
			||||||
 | 
					    lineGeometry = nullptr;
 | 
				
			||||||
 | 
					    vertexArray = nullptr;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					osg::ref_ptr<osg::Geometry> MousePicker::createPointGeode(const osg::Vec3 &pos)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    osg::Geometry *geom = new osg::Geometry();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    osg::ref_ptr<osg::Vec3Array>  vertex = new osg::Vec3Array();
 | 
				
			||||||
 | 
					    vertex->push_back(pos);
 | 
				
			||||||
 | 
					    geom->setVertexArray(vertex.get());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    osg::ref_ptr<osg::Vec4Array>  color = new osg::Vec4Array();
 | 
				
			||||||
 | 
					    color->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f) );
 | 
				
			||||||
 | 
					    geom->setColorArray(color, osg::Array::BIND_OVERALL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    geom->getOrCreateStateSet()->setAttribute(new osg::Point(6.0f), osg::StateAttribute::ON);
 | 
				
			||||||
 | 
					    geom->getOrCreateStateSet()->setMode(GL_POINT_SMOOTH, osg::StateAttribute::ON);
 | 
				
			||||||
 | 
					    geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, 1));
 | 
				
			||||||
 | 
					    geom->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return geom;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										43
									
								
								MousePicker.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								MousePicker.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,43 @@
 | 
				
			|||||||
 | 
					#ifndef MOUSEPICKER_H
 | 
				
			||||||
 | 
					#define MOUSEPICKER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QtCore>
 | 
				
			||||||
 | 
					#include <QObject>
 | 
				
			||||||
 | 
					#include <osg/Geode>
 | 
				
			||||||
 | 
					#include <osgGA/GUIEventHandler>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum PickingMode{
 | 
				
			||||||
 | 
					    PointPicker = 0,
 | 
				
			||||||
 | 
					    LinePicker = 1,
 | 
				
			||||||
 | 
					    AreaPicker = 2,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MousePicker : public QObject, public osgGA::GUIEventHandler
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    Q_OBJECT
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    explicit MousePicker(QObject *parent = nullptr);
 | 
				
			||||||
 | 
					    void setRoot(osg::ref_ptr<osg::Group> root = nullptr);
 | 
				
			||||||
 | 
					    void activate(PickingMode _mode, osg::Node* model);
 | 
				
			||||||
 | 
					    bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa );
 | 
				
			||||||
 | 
					    void disactivate();
 | 
				
			||||||
 | 
					    static osg::ref_ptr<osg::Geometry> createPointGeode(const osg::Vec3 &pos);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					signals:
 | 
				
			||||||
 | 
					    void editionDone(PickingMode, osg::ref_ptr<osg::Vec3Array>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    bool isActivated = false;
 | 
				
			||||||
 | 
					    bool isDrawing = false;
 | 
				
			||||||
 | 
					    PickingMode mode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    osg::Vec3 pushPnt;
 | 
				
			||||||
 | 
					    osg::ref_ptr<osg::Node> model;
 | 
				
			||||||
 | 
					    osg::ref_ptr<osg::Group> drawNodeList = new osg::Group;
 | 
				
			||||||
 | 
					    osg::ref_ptr<osg::Geode> currentDrawNode = new osg::Geode;
 | 
				
			||||||
 | 
					    osg::ref_ptr<osg::Geometry> lineGeometry;
 | 
				
			||||||
 | 
					    osg::ref_ptr<osg::Vec3Array> vertexArray;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // MOUSEPICKER_H
 | 
				
			||||||
							
								
								
									
										18
									
								
								main.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								main.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					#include "mainwindow.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QApplication>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char *argv[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
 | 
				
			||||||
 | 
					    QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
 | 
				
			||||||
 | 
					    QApplication::setStyle("fusion");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto font = QFont("Microsoft YaHei UI");
 | 
				
			||||||
 | 
					    font.setPointSize(12);
 | 
				
			||||||
 | 
					    QApplication::setFont(font);
 | 
				
			||||||
 | 
					    QApplication a(argc, argv);
 | 
				
			||||||
 | 
					    MainWindow w;
 | 
				
			||||||
 | 
					    w.show();
 | 
				
			||||||
 | 
					    return a.exec();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										262
									
								
								mainwindow.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										262
									
								
								mainwindow.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,262 @@
 | 
				
			|||||||
 | 
					#include "mainwindow.h"
 | 
				
			||||||
 | 
					#include "ui_mainwindow.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QtWidgets>
 | 
				
			||||||
 | 
					#include <QtCore>
 | 
				
			||||||
 | 
					#include <QtXml>
 | 
				
			||||||
 | 
					#include <math.h>
 | 
				
			||||||
 | 
					#include <osgQOpenGL/osgQOpenGLWidget>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osg/Point>
 | 
				
			||||||
 | 
					#include <osg/MatrixTransform>
 | 
				
			||||||
 | 
					#include <osgViewer/Viewer>
 | 
				
			||||||
 | 
					#include <osgDB/ReadFile>
 | 
				
			||||||
 | 
					#include <osgGA/TrackballManipulator>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <Windows.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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<QUrl> urls = event->mimeData()->urls();
 | 
				
			||||||
 | 
					    if(urls.isEmpty()){
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    QList<QUrl>::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<float>( osgWidget->width()) / static_cast<float>( osgWidget->height() );
 | 
				
			||||||
 | 
					    osgWidget->getOsgViewer()->getCamera()->setProjectionMatrixAsPerspective( 30.f, aspectRatio, 1.f, 1000.f );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    osg::ref_ptr<osg::Light> 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<Item, QList<Item>> 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<Item> 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<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), [=](int index){
 | 
				
			||||||
 | 
					        modelChosen->clear();
 | 
				
			||||||
 | 
					        QList<Item> 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<osg::Vec3Array> 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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										60
									
								
								mainwindow.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								mainwindow.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,60 @@
 | 
				
			|||||||
 | 
					#ifndef MAINWINDOW_H
 | 
				
			||||||
 | 
					#define MAINWINDOW_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "myNodeVisitor.h"
 | 
				
			||||||
 | 
					#include "MousePicker.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QMainWindow>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osgQOpenGL/osgQOpenGLWidget>
 | 
				
			||||||
 | 
					#include <osgViewer/Viewer>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct Item
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    QString name;   //符号名称
 | 
				
			||||||
 | 
					    QString code;   //符号代码
 | 
				
			||||||
 | 
					    QString address;    //符号所在的相对路径
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool operator < ( const Item& item) const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return this->name < item.name;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QT_BEGIN_NAMESPACE
 | 
				
			||||||
 | 
					namespace Ui { class MainWindow; }
 | 
				
			||||||
 | 
					QT_END_NAMESPACE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MainWindow : public QMainWindow
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    Q_OBJECT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					   explicit MainWindow(QWidget *parent = nullptr);
 | 
				
			||||||
 | 
					    ~MainWindow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    void initOsg();
 | 
				
			||||||
 | 
					    void addModel(QString filename);
 | 
				
			||||||
 | 
					    void updateModel();
 | 
				
			||||||
 | 
					    void clearModel();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					    void dragEnterEvent(QDragEnterEvent* event = NULL);
 | 
				
			||||||
 | 
					    void dropEvent(QDropEvent* event);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    Ui::MainWindow *ui;
 | 
				
			||||||
 | 
					    osgQOpenGLWidget* osgWidget = new osgQOpenGLWidget;
 | 
				
			||||||
 | 
					    osg::Group* root = new osg::Group;
 | 
				
			||||||
 | 
					    osg::Geode* drawNode = new osg::Geode;
 | 
				
			||||||
 | 
					    myNodeVisitor nv;
 | 
				
			||||||
 | 
					    QString filename;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    MousePicker* mp;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string Utf8ToGbk(std::string str);
 | 
				
			||||||
 | 
					#endif // MAINWINDOW_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										61
									
								
								mainwindow.ui
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								mainwindow.ui
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					<ui version="4.0">
 | 
				
			||||||
 | 
					 <class>MainWindow</class>
 | 
				
			||||||
 | 
					 <widget class="QMainWindow" name="MainWindow">
 | 
				
			||||||
 | 
					  <property name="geometry">
 | 
				
			||||||
 | 
					   <rect>
 | 
				
			||||||
 | 
					    <x>0</x>
 | 
				
			||||||
 | 
					    <y>0</y>
 | 
				
			||||||
 | 
					    <width>1331</width>
 | 
				
			||||||
 | 
					    <height>600</height>
 | 
				
			||||||
 | 
					   </rect>
 | 
				
			||||||
 | 
					  </property>
 | 
				
			||||||
 | 
					  <property name="windowTitle">
 | 
				
			||||||
 | 
					   <string>MainWindow</string>
 | 
				
			||||||
 | 
					  </property>
 | 
				
			||||||
 | 
					  <widget class="QWidget" name="centralwidget"/>
 | 
				
			||||||
 | 
					  <widget class="QMenuBar" name="menubar">
 | 
				
			||||||
 | 
					   <property name="geometry">
 | 
				
			||||||
 | 
					    <rect>
 | 
				
			||||||
 | 
					     <x>0</x>
 | 
				
			||||||
 | 
					     <y>0</y>
 | 
				
			||||||
 | 
					     <width>1331</width>
 | 
				
			||||||
 | 
					     <height>30</height>
 | 
				
			||||||
 | 
					    </rect>
 | 
				
			||||||
 | 
					   </property>
 | 
				
			||||||
 | 
					   <widget class="QMenu" name="menuFile">
 | 
				
			||||||
 | 
					    <property name="title">
 | 
				
			||||||
 | 
					     <string>文件</string>
 | 
				
			||||||
 | 
					    </property>
 | 
				
			||||||
 | 
					    <addaction name="actionOpenModel"/>
 | 
				
			||||||
 | 
					    <addaction name="actionUpdateModel"/>
 | 
				
			||||||
 | 
					    <addaction name="actionZoomToExtent"/>
 | 
				
			||||||
 | 
					    <addaction name="actionEditModel"/>
 | 
				
			||||||
 | 
					   </widget>
 | 
				
			||||||
 | 
					   <addaction name="menuFile"/>
 | 
				
			||||||
 | 
					  </widget>
 | 
				
			||||||
 | 
					  <widget class="QStatusBar" name="statusbar"/>
 | 
				
			||||||
 | 
					  <action name="actionOpenModel">
 | 
				
			||||||
 | 
					   <property name="text">
 | 
				
			||||||
 | 
					    <string>打开模型</string>
 | 
				
			||||||
 | 
					   </property>
 | 
				
			||||||
 | 
					  </action>
 | 
				
			||||||
 | 
					  <action name="actionUpdateModel">
 | 
				
			||||||
 | 
					   <property name="text">
 | 
				
			||||||
 | 
					    <string>更新模型</string>
 | 
				
			||||||
 | 
					   </property>
 | 
				
			||||||
 | 
					  </action>
 | 
				
			||||||
 | 
					  <action name="actionZoomToExtent">
 | 
				
			||||||
 | 
					   <property name="text">
 | 
				
			||||||
 | 
					    <string>重置视角</string>
 | 
				
			||||||
 | 
					   </property>
 | 
				
			||||||
 | 
					  </action>
 | 
				
			||||||
 | 
					  <action name="actionEditModel">
 | 
				
			||||||
 | 
					   <property name="text">
 | 
				
			||||||
 | 
					    <string>模型编辑</string>
 | 
				
			||||||
 | 
					   </property>
 | 
				
			||||||
 | 
					  </action>
 | 
				
			||||||
 | 
					 </widget>
 | 
				
			||||||
 | 
					 <resources/>
 | 
				
			||||||
 | 
					 <connections/>
 | 
				
			||||||
 | 
					</ui>
 | 
				
			||||||
							
								
								
									
										147
									
								
								myNodeVisitor.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								myNodeVisitor.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,147 @@
 | 
				
			|||||||
 | 
					#include "myNodeVisitor.h"
 | 
				
			||||||
 | 
					#include "mainwindow.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osg/Texture2D>
 | 
				
			||||||
 | 
					#include <osg/ProxyNode>
 | 
				
			||||||
 | 
					#include <osg/PagedLOD>
 | 
				
			||||||
 | 
					#include <osgDB/ReadFile>
 | 
				
			||||||
 | 
					#include <osgDB/WriteFile>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					myNodeVisitor::myNodeVisitor()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    opt->setOptionString("WriteImageHint=IncludeFile");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void myNodeVisitor::apply(osg::Geode &node)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // 遍历Geode里面的所有Geometry,即形状(点、线、面)
 | 
				
			||||||
 | 
					    for(uint i = 0; i<node.getNumDrawables(); i++){
 | 
				
			||||||
 | 
					        osg::Geometry* pGeo = node.getDrawable(i)->asGeometry();
 | 
				
			||||||
 | 
					        if(pGeo){
 | 
				
			||||||
 | 
					            osg::Vec3Array* vertex = dynamic_cast<osg::Vec3Array*>(pGeo->getVertexArray());
 | 
				
			||||||
 | 
					            if (!vertex){
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            for (int i = 0; i < vertex->size(); i++){
 | 
				
			||||||
 | 
					                // 对于满足条件的点
 | 
				
			||||||
 | 
					                int index = pointsNearVertex((*vertex)[i]);
 | 
				
			||||||
 | 
					                if (index != -1)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    (*vertex)[i].z() = vertexArray->at(index).z();
 | 
				
			||||||
 | 
					                    affected = true;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (affected && !node.getName().empty()){
 | 
				
			||||||
 | 
					        // 和PagedLOD的处理方式一致
 | 
				
			||||||
 | 
					        newFileName = QString::fromStdString(node.getName()).split('.').first() + "~.osgb";
 | 
				
			||||||
 | 
					        node.accept(*tv);
 | 
				
			||||||
 | 
					        node.setName(newFileName.toStdString());
 | 
				
			||||||
 | 
					        // 写文件
 | 
				
			||||||
 | 
					        osgDB::writeNodeFile(node, (workingDir + '/' + newFileName).toStdString(), opt);
 | 
				
			||||||
 | 
					        childAffected = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void myNodeVisitor::apply(osg::Group &node)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    bool groupAffected = false;
 | 
				
			||||||
 | 
					    for(uint i = 0; i<node.getNumChildren(); i++){
 | 
				
			||||||
 | 
					        childAffected = false;
 | 
				
			||||||
 | 
					        node.getChild(i)->accept(*this);
 | 
				
			||||||
 | 
					        if(childAffected){
 | 
				
			||||||
 | 
					            groupAffected = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(groupAffected && !node.getName().empty()){
 | 
				
			||||||
 | 
					        // 和PagedLOD的处理方式一致
 | 
				
			||||||
 | 
					        newFileName = QString::fromStdString(node.getName()).split('.').first() + "~.osgb";
 | 
				
			||||||
 | 
					        node.accept(*tv);
 | 
				
			||||||
 | 
					        node.setName(newFileName.toStdString());
 | 
				
			||||||
 | 
					        // 写文件
 | 
				
			||||||
 | 
					        osgDB::writeNodeFile(node, (workingDir + '/' + newFileName).toStdString(), opt);
 | 
				
			||||||
 | 
					        childAffected = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void myNodeVisitor::apply(osg::PagedLOD &node)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    affected = false;
 | 
				
			||||||
 | 
					    childAffected = false;
 | 
				
			||||||
 | 
					    for(uint i = 0; i < node.getNumChildren(); i++){
 | 
				
			||||||
 | 
					        // 这个遍历过程可能会修改文件
 | 
				
			||||||
 | 
					        node.getChild(i)->accept(*this);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//    // 使用affected作为初步判断,以尽可能地减少计算量, 非affected文件都不会被修改
 | 
				
			||||||
 | 
					//    if(!affected && ! childAffected){
 | 
				
			||||||
 | 
					//        return;
 | 
				
			||||||
 | 
					//    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 如果真的被修改了文件,那么,
 | 
				
			||||||
 | 
					    workingDir = QString::fromStdString(node.getDatabasePath());
 | 
				
			||||||
 | 
					    //        for(uint i = 0; i < node.getNumFileNames(); i++){
 | 
				
			||||||
 | 
					    for(uint i = 1; i < node.getNumFileNames(); i++){
 | 
				
			||||||
 | 
					        // 遍历这个LOD文件中的所有子文件,即金字塔中更精细的那一层,他们也要改
 | 
				
			||||||
 | 
					        childAffected = false;
 | 
				
			||||||
 | 
					        // 读文件以继续遍历
 | 
				
			||||||
 | 
					        osg::ref_ptr<osg::Node> fileNode = osgDB::readNodeFile(workingDir.toStdString() + '/' + node.getFileName(i));
 | 
				
			||||||
 | 
					        if(!fileNode.valid()){
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // 将fileNode和文件名链接在一起,这样当节点被修改时,可以及时更新对应的文件
 | 
				
			||||||
 | 
					        fileNode->setName(node.getFileName(i));
 | 
				
			||||||
 | 
					        // 两个遍历器都要遍历
 | 
				
			||||||
 | 
					        fileNode->accept(*tv);
 | 
				
			||||||
 | 
					        fileNode->accept(*this);
 | 
				
			||||||
 | 
					        if(childAffected){
 | 
				
			||||||
 | 
					            //更改文件名链接
 | 
				
			||||||
 | 
					            node.setFileName(i, newFileName.toStdString());
 | 
				
			||||||
 | 
					            // 此时也应该相应地修改pLOD对应的文件
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(!node.getName().empty()){
 | 
				
			||||||
 | 
					        newFileName = QString::fromStdString(node.getName()).split('.').first() + "~.osgb";
 | 
				
			||||||
 | 
					        node.accept(*tv);
 | 
				
			||||||
 | 
					        node.setName(newFileName.toStdString());
 | 
				
			||||||
 | 
					        // 写文件
 | 
				
			||||||
 | 
					        osgDB::writeNodeFile(node, (workingDir + '/' + newFileName).toStdString(), opt);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 作为别人的儿子,文件被修改了
 | 
				
			||||||
 | 
					    childAffected = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool myNodeVisitor::pointInPolygon(osg::Vec3 &point)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    for(osg::ref_ptr<osg::Vec3Array> boundary: boundaryList){
 | 
				
			||||||
 | 
					        int i, j, nvert = boundary->size();
 | 
				
			||||||
 | 
					        bool c = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 射线法
 | 
				
			||||||
 | 
					        for (i = 0, j = nvert - 1; i < nvert; j = i++) {
 | 
				
			||||||
 | 
					            if (((boundary->at(i).y() >= point.y()) != (boundary->at(j).y() >= point.y())) &&
 | 
				
			||||||
 | 
					                    (point.x() <= (boundary->at(j).x() - boundary->at(i).x()) * (point.y() - boundary->at(i).y()) / (boundary->at(j).y() - boundary->at(i).y()) + boundary->at(i).x())
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                c = !c;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if(c && point.z() > boundary->at(0).z()){
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int myNodeVisitor::pointsNearVertex(osg::Vec3 &point)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    for(int i = 0; i < vertexArray->size(); i++){
 | 
				
			||||||
 | 
					        if(pow(point.x() - vertexArray->at(i).x(), 2) + pow(point.y() - vertexArray->at(i).y(), 2) < 4 && point.z() > vertexArray->at(i).z()){
 | 
				
			||||||
 | 
					            return i;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										35
									
								
								myNodeVisitor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								myNodeVisitor.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
				
			|||||||
 | 
					#ifndef MYNODEVISITOR_H
 | 
				
			||||||
 | 
					#define MYNODEVISITOR_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osg/NodeVisitor>
 | 
				
			||||||
 | 
					#include <osgUtil/Optimizer>
 | 
				
			||||||
 | 
					#include <osgDB/ReadFile>
 | 
				
			||||||
 | 
					#include <QtCore>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 深度优先的访问器
 | 
				
			||||||
 | 
					class myNodeVisitor : public osg::NodeVisitor
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    myNodeVisitor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void setPoints(osg::ref_ptr<osg::Vec3Array> _vertexArray) {vertexArray = _vertexArray;}
 | 
				
			||||||
 | 
					    void setBoundaryList(QList<osg::ref_ptr<osg::Vec3Array>> _boundaryList){ boundaryList = _boundaryList; }
 | 
				
			||||||
 | 
					    virtual void apply(osg::Geode &node) override;
 | 
				
			||||||
 | 
					    virtual void apply(osg::Group &node) override;
 | 
				
			||||||
 | 
					    virtual void apply(osg::PagedLOD &node) override;
 | 
				
			||||||
 | 
					    bool pointInPolygon(osg::Vec3& point);
 | 
				
			||||||
 | 
					    int pointsNearVertex(osg::Vec3& point);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    osgUtil::Optimizer::TextureVisitor* tv = new osgUtil::Optimizer::TextureVisitor(true, false, false, false, false, false);
 | 
				
			||||||
 | 
					    osgDB::ReaderWriter::Options* opt = new osgDB::ReaderWriter::Options;
 | 
				
			||||||
 | 
					    QString workingDir;
 | 
				
			||||||
 | 
					    QString newFileName;
 | 
				
			||||||
 | 
					    // 记录点位是否被修改,从而缩减计算量
 | 
				
			||||||
 | 
					    bool affected = false;
 | 
				
			||||||
 | 
					    bool childAffected = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    osg::ref_ptr<osg::Vec3Array> vertexArray;
 | 
				
			||||||
 | 
					    QList<osg::ref_ptr<osg::Vec3Array>> boundaryList;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					#endif // MYNODEVISITOR_H
 | 
				
			||||||
							
								
								
									
										45
									
								
								simulationMaster.pro
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								simulationMaster.pro
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					QT       += core gui opengl xml
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TARGET = simulationMaster
 | 
				
			||||||
 | 
					TEMPLATE = app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# The following define makes your compiler emit warnings if you use
 | 
				
			||||||
 | 
					# any Qt feature that has been marked deprecated (the exact warnings
 | 
				
			||||||
 | 
					# depend on your compiler). Please consult the documentation of the
 | 
				
			||||||
 | 
					# deprecated API in order to know how to port your code away from it.
 | 
				
			||||||
 | 
					DEFINES += QT_DEPRECATED_WARNINGS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# You can also make your code fail to compile if it uses deprecated APIs.
 | 
				
			||||||
 | 
					# In order to do so, uncomment the following line.
 | 
				
			||||||
 | 
					# You can also select to disable deprecated APIs only up to a certain version of Qt.
 | 
				
			||||||
 | 
					#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					INCLUDEPATH += C:/Users/16284/Desktop/qt/OSG-install/include
 | 
				
			||||||
 | 
					LIBS += -LC:/Users/16284/Desktop/qt/OSG-install/lib -losg -losgDB -losgQOpenGL -losgViewer -losgGA -lOpenThreads -losgUtil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SOURCES += \
 | 
				
			||||||
 | 
					    main.cpp \
 | 
				
			||||||
 | 
					    mainwindow.cpp\
 | 
				
			||||||
 | 
					  MousePicker.cpp \
 | 
				
			||||||
 | 
					  myNodeVisitor.cpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HEADERS += \
 | 
				
			||||||
 | 
					    mainwindow.h\
 | 
				
			||||||
 | 
					  myNodeVisitor.h \
 | 
				
			||||||
 | 
					  MousePicker.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FORMS += \
 | 
				
			||||||
 | 
					    mainwindow.ui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TRANSLATIONS += \
 | 
				
			||||||
 | 
					    simulationMaster_zh_CN.ts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Default rules for deployment.
 | 
				
			||||||
 | 
					qnx: target.path = /tmp/$${TARGET}/bin
 | 
				
			||||||
 | 
					else: unix:!android: target.path = /opt/$${TARGET}/bin
 | 
				
			||||||
 | 
					!isEmpty(target.path): INSTALLS += target
 | 
				
			||||||
							
								
								
									
										3
									
								
								simulationMaster_zh_CN.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								simulationMaster_zh_CN.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<!DOCTYPE TS>
 | 
				
			||||||
 | 
					<TS version="2.1" language="simulationMaster_zh_CN"></TS>
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user