Skip to content

Commit

Permalink
picking, transparency, invisibility for 3dviewer with shift+right click
Browse files Browse the repository at this point in the history
  • Loading branch information
vwaurich authored and adeas31 committed Feb 10, 2017
1 parent 2cc9a7f commit 24a7ac7
Show file tree
Hide file tree
Showing 10 changed files with 843 additions and 12 deletions.
1 change: 1 addition & 0 deletions OMEdit/OMEditGUI/Animation/AbstractAnimationWindow.h
Expand Up @@ -53,6 +53,7 @@ class AbstractAnimationWindow : public QMainWindow
public:
AbstractAnimationWindow(QWidget *pParent);
ViewerWidget* getViewerWidget() {return mpViewerWidget;}
VisualizerAbstract* getVisualizer() {return mpVisualizer;}
void openAnimationFile(QString fileName, bool stashCamera=false);
virtual void createActions();
void clearView();
Expand Down
5 changes: 3 additions & 2 deletions OMEdit/OMEditGUI/Animation/Shapes.cpp
Expand Up @@ -65,7 +65,8 @@ ShapeObject::ShapeObject()
_height(ShapeObjectAttribute(0.1)),
_specCoeff(ShapeObjectAttribute(0.7)),
_mat(osg::Matrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)),
_extra(ShapeObjectAttribute(0.0))
_extra(ShapeObjectAttribute(0.0)),
mTransparent(0.0)
{
_r[0] = ShapeObjectAttribute(0.1);
_r[1] = ShapeObjectAttribute(0.1);
Expand Down Expand Up @@ -114,10 +115,10 @@ void ShapeObject::dumpVisAttributes() const
std::cout << " " << _mat(2, 0) << ", " << _mat(2, 1) << ", " << _mat(2, 2) << ", " << _mat(2, 3) << std::endl;
std::cout << " " << _mat(3, 0) << ", " << _mat(3, 1) << ", " << _mat(3, 2) << ", " << _mat(3, 3) << std::endl;
std::cout << "extra " << _extra.getValueString() << std::endl;
std::cout << "transparency " << mTransparent << std::endl;

}


/*
double getShapeAttrFMU(const char* attr, rapidxml::xml_node<>* node, double time, fmi1_import_t* fmu)
{
Expand Down
4 changes: 4 additions & 0 deletions OMEdit/OMEditGUI/Animation/Shapes.h
Expand Up @@ -68,6 +68,8 @@ class ShapeObject
ShapeObject& operator=(const ShapeObject&) = default;
void dumpVisAttributes() const;
//void fetchVisAttributes(rapidxml::xml_node<>* node, ModelicaMatReader matReader,/* fmi1_import_t* fmu,*/ double time, bool useFMU);
void setTransparency(float transp){mTransparent = transp;};
float getTransparency(){return mTransparent;};
public:
std::string _id;
std::string _type;
Expand All @@ -84,6 +86,8 @@ class ShapeObject
ShapeObjectAttribute _specCoeff;
osg::Matrix _mat;
ShapeObjectAttribute _extra;
private:
float mTransparent;
};

struct rAndT
Expand Down
149 changes: 149 additions & 0 deletions OMEdit/OMEditGUI/Animation/ViewerWidget.cpp
Expand Up @@ -39,6 +39,7 @@
#include <cassert>

#include "ViewerWidget.h"
#include "Modeling/MessagesWidget.h"

/*!
* \brief Viewer::setUpThreading
Expand Down Expand Up @@ -71,6 +72,8 @@ ViewerWidget::ViewerWidget(QWidget* parent, Qt::WindowFlags flags)
mpGraphicsWindow = new osgViewer::GraphicsWindowEmbedded(x(), y(), width(), height());
mpViewer = new Viewer;
mpSceneView = new osgViewer::View();
mpAnimationWidget = qobject_cast<AbstractAnimationWindow*>(parent);

// widget resolution
int height = rect().height();
int width = rect().width();
Expand Down Expand Up @@ -194,13 +197,158 @@ void ViewerWidget::mousePressEvent(QMouseEvent *event)
break;
case Qt::RightButton:
button = 3;
if((event->modifiers() == Qt::ShiftModifier))
{
//qt counts pixels from upper left corner and osg from bottom left corner
pickShape(event->x(), this->height() - event->y());
showShapePickContextMenu(event->pos());
return;
}
break;
default:
break;
}
getEventQueue()->mouseButtonPress(static_cast<float>(event->x()), static_cast<float>(event->y()), button);
}

/*!
* \brief ViewerWidget::pickShape
* Picks the name of the selected shape in the osg view
* \param x - mouse position pixel in x direction in osg system
* \param y - mouse position pixel in y direction in osg system
*/
void ViewerWidget::pickShape(int x, int y)
{
//std::cout<<"pickShape "<<x<<" and "<<y<<std::endl;
osgUtil::LineSegmentIntersector::Intersections intersections;
if (mpSceneView->computeIntersections(mpSceneView->getCamera(),osgUtil::Intersector::WINDOW , x, y, intersections))
{
//take the first intersection with a facette only
osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin();

if (!hitr->nodePath.empty() && !(hitr->nodePath.back()->getName().empty()))
{
mSelectedShape = hitr->nodePath.back()->getName();
//std::cout<<"Object identified by name "<<mSelectedShape<<std::endl;
}
else if (hitr->drawable.valid())
{
mSelectedShape = hitr->drawable->className();
//std::cout<<"Object identified by its drawable "<<mSelectedShape<<std::endl;
}

}
}

/*!
* \brief ViewerWidget::showShapePickContextMenu
* \param pos
*/
void ViewerWidget::showShapePickContextMenu(const QPoint& pos)
{
QString name = QString::fromStdString(mSelectedShape);
//std::cout<<"SHOW CONTEXT "<<name.toStdString()<<" compare "<<QString::compare(name,QString(""))<< std::endl;
//the context widget
QMenu contextMenu(tr("Context menu"), this);
QMenu shapeMenu(name, this);
shapeMenu.setIcon(QIcon(":/Resources/icons/animation.svg"));
QAction action0(QIcon(":/Resources/icons/undo.svg"), "Reset All Shapes", this);
QAction action1(QIcon(":/Resources/icons/transparency.svg"),"Change Transparency", this);
QAction action2(QIcon(":/Resources/icons/invisible.svg"),"Make Shape Invisible", this);

//if a shape is picked, we can set it transparent
if (0 != QString::compare(name,QString("")))
{
contextMenu.addMenu(&shapeMenu);
shapeMenu.addAction( &action1);
shapeMenu.addAction( &action2);
connect(&action1, SIGNAL(triggered()), this, SLOT(changeShapeTransparency()));
connect(&action2, SIGNAL(triggered()), this, SLOT(makeShapeInvisible()));
}
contextMenu.addAction(&action0);
connect(&action0, SIGNAL(triggered()), this, SLOT(removeTransparencyForAllShapes()));
contextMenu.exec(this->mapToGlobal(pos));
}

/*!
* \brief ViewerWidget::changeShapeTransparency
* changes the transparency selection of a shape
*/
void ViewerWidget::changeShapeTransparency()
{
ShapeObject* shape = nullptr;
if((shape = mpAnimationWidget->getVisualizer()->getBaseData()->getShapeObjectByID(mSelectedShape)))
{
if (shape->_type.compare("dxf") == 0)
{
QString msg = QString("Transparency is not applicable for DXF-Files.");
MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::Modelica, "", false, 0, 0, 0, 0, msg, Helper::scriptingKind,
Helper::notificationLevel));
mSelectedShape = "";
}
else
{
if (shape->getTransparency() == 0)
{
shape->setTransparency(0.5);
}
else
{
shape->setTransparency(0.0);
}
mpAnimationWidget->getVisualizer()->updateVisAttributes(mpAnimationWidget->getVisualizer()->getTimeManager()->getVisTime());
mpAnimationWidget->updateScene();
mSelectedShape = "";
}
}
}

/*!
* \brief ViewerWidget::makeShapeInvisible
* suppresses the visualization of this shape
*/
void ViewerWidget::makeShapeInvisible()
{
ShapeObject* shape = nullptr;
if((shape = mpAnimationWidget->getVisualizer()->getBaseData()->getShapeObjectByID(mSelectedShape)))
{
if (shape->_type.compare("dxf") == 0)
{
QString msg = QString("Invisibility is not applicable for DXF-Files.");
MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::Modelica, "", false, 0, 0, 0, 0, msg, Helper::scriptingKind,
Helper::notificationLevel));
mSelectedShape = "";
}
else
{
shape->setTransparency(1.0);
mpAnimationWidget->getVisualizer()->updateVisAttributes(mpAnimationWidget->getVisualizer()->getTimeManager()->getVisTime());
mpAnimationWidget->updateScene();
mSelectedShape = "";
}
}
}

/*!
* \brief ViewerWidget::removeTransparancyForAllShapes
* sets all transparency settings back to default (nothing is transparent)
*
*/
void ViewerWidget::removeTransparencyForAllShapes()
{
if (mpAnimationWidget->getVisualizer() != NULL)
{
std::vector<ShapeObject>* shapes = nullptr;
shapes = &mpAnimationWidget->getVisualizer()->getBaseData()->_shapes;
for(std::vector<ShapeObject>::iterator shape = shapes->begin() ; shape < shapes->end(); ++shape )
{
shape->setTransparency(0.0);
}
mpAnimationWidget->getVisualizer()->updateVisAttributes(mpAnimationWidget->getVisualizer()->getTimeManager()->getVisTime());
mpAnimationWidget->updateScene();
}
}

/*!
* \brief ViewerWidget::mouseReleaseEvent
* Passes the QWidget::mouseReleaseEvent() to Graphics Window.
Expand All @@ -221,6 +369,7 @@ void ViewerWidget::mouseReleaseEvent(QMouseEvent *event)
break;
case Qt::RightButton:
button = 3;
mSelectedShape = "";
break;
default:
break;
Expand Down
19 changes: 18 additions & 1 deletion OMEdit/OMEditGUI/Animation/ViewerWidget.h
Expand Up @@ -38,6 +38,14 @@
#include <osgViewer/GraphicsWindow>
#include <osgViewer/CompositeViewer>

#include<iostream>

#include<QMenu>

#include "AbstractAnimationWindow.h"
#include "Util/Helper.h"


/*!
* \note We need to create two files with same class name since Qt meta object compiler doesn't handle ifdef.
* OpenGLWidget.h uses QOpenGLWidget and GLWidget.h uses QGLWidget
Expand Down Expand Up @@ -66,6 +74,9 @@ class ViewerWidget : public GLWidget
public:
ViewerWidget(QWidget *pParent = 0, Qt::WindowFlags flags = 0);
osgViewer::View* getSceneView() {return mpSceneView;}
std::string getSelectedShape(){return mSelectedShape;};
void setSelectedShape(std::string shape){mSelectedShape = shape;};
void pickShape(int x, int y);
protected:
virtual void paintEvent(QPaintEvent *paintEvent);
virtual void paintGL();
Expand All @@ -77,13 +88,19 @@ class ViewerWidget : public GLWidget
virtual void mouseReleaseEvent(QMouseEvent *event);
virtual void wheelEvent(QWheelEvent *event);
virtual bool event(QEvent* event);
void showShapePickContextMenu(const QPoint& pos);
private:
osgGA::EventQueue* getEventQueue() const;

osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> mpGraphicsWindow;
osg::ref_ptr<Viewer> mpViewer;
//osg viewer scene
osgViewer::View* mpSceneView;
std::string mSelectedShape;
AbstractAnimationWindow *mpAnimationWidget;
public slots:
void changeShapeTransparency();
void removeTransparencyForAllShapes();
void makeShapeInvisible();
};

#endif // VIEWERWIDGET_H
60 changes: 55 additions & 5 deletions OMEdit/OMEditGUI/Animation/Visualizer.cpp
Expand Up @@ -44,6 +44,24 @@ OMVisualBase::OMVisualBase(const std::string& modelFile, const std::string& path
{
}

/*!
* \brief OMVisualBase::getShapeObjectByID
* get the shapeObject with the same shapeID
*\param the name of the shape
*\return the selected shape
*/
ShapeObject* OMVisualBase::getShapeObjectByID(std::string shapeID)
{
for(std::vector<ShapeObject>::iterator shape =_shapes.begin() ; shape < _shapes.end(); ++shape )
{
if(shape->_id == shapeID) {
return &(*shape);
}
}
return 0;
}


void OMVisualBase::initXMLDoc()
{
// Check if the XML file is available.
Expand Down Expand Up @@ -377,7 +395,6 @@ int OSGScene::setUpScene(std::vector<ShapeObject> allShapes)
//std::cout<<"Its a CAD and the filename is "<<shape._fileName<<std::endl;
osg::ref_ptr<osg::Node> node = osgDB::readNodeFile(shape._fileName);
osg::ref_ptr<osg::StateSet> ss = node->getOrCreateStateSet();

ss->setAttribute(material.get());
node->setStateSet(ss);
transf->addChild(node.get());
Expand Down Expand Up @@ -443,9 +460,9 @@ void UpdateVisitor::apply(osg::MatrixTransform& node)
*/
void UpdateVisitor::apply(osg::Geode& node)
{
//std::cout<<"GEODE "<< _shape._id<<" "<<std::endl;
//std::cout<<"GEODE "<< _shape._id<<" "<<_shape.getTransparency()<<std::endl;
osg::ref_ptr<osg::StateSet> ss = node.getOrCreateStateSet();

node.setName(_shape._id);
//its a drawable and not a cad file so we have to create a new drawable
if (_shape._type.compare("dxf") != 0 and (_shape._type.compare("stl") != 0))
{
Expand Down Expand Up @@ -493,17 +510,50 @@ void UpdateVisitor::apply(osg::Geode& node)
//std::cout<<"SHAPE "<<draw->getShape()->className()<<std::endl;
node.addDrawable(draw.get());
}
//dxf files are treated separately since they are constructed natively, including color
if (_shape._type.compare("dxf") != 0)
{
//osg::Material *material = dynamic_cast<osg::Material*>(ss->getAttribute(osg::StateAttribute::MATERIAL));
osg::ref_ptr<osg::Material> material = new osg::Material;
osg::Material *material;
if (NULL == node.getStateSet()->getAttribute(osg::StateAttribute::MATERIAL))
material = new osg::Material();
else
material = dynamic_cast<osg::Material*>(ss->getAttribute(osg::StateAttribute::MATERIAL));

material->setDiffuse(osg::Material::FRONT, osg::Vec4f(_shape._color[0].exp / 255, _shape._color[1].exp / 255, _shape._color[2].exp / 255, 1.0));
ss->setAttribute(material);
node.setStateSet(ss);
//set transparency
if (_shape.getTransparency())
makeTransparent(node, _shape.getTransparency());
}

traverse(node);
}

/*!
* \brief UpdateVisitor::makeTransparent
* makes a geode transparent
* \param event
*/
void UpdateVisitor::makeTransparent(osg::Geode& node, float transpCoeff)
{
node.getStateSet()->setMode( GL_BLEND, osg::StateAttribute::ON );
node.getStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
osg::Material *material;
if (NULL == node.getStateSet()->getAttribute(osg::StateAttribute::MATERIAL))
{
material = new osg::Material();
}
else
{
material = dynamic_cast<osg::Material*>(node.getStateSet()->getAttribute(osg::StateAttribute::MATERIAL));
}
material->setTransparency(osg::Material::FRONT_AND_BACK, transpCoeff);
node.getStateSet()->setAttributeAndModes(material, osg::StateAttribute::OVERRIDE);
}



InfoVisitor::InfoVisitor()
: _level(0)
{
Expand Down

0 comments on commit 24a7ac7

Please sign in to comment.