Skip to content

Commit

Permalink
[OMEdit] Heuristics for scaling vector visualizers (#9389)
Browse files Browse the repository at this point in the history
* Fix dumping of BCONST and ENUM_LITERAL

* Fix clearing all tabs messages

* Mechanism to sync frames and postpone GUI messages

* Improve efficiency by avoiding casts and searches

* Fix usage of osg::ref_ptr get() & valid() methods

* Fix setting name and state set of geodes/nodes

* Fix setting color and transparency of geodes/nodes

* Fix including OSG headers for visualization

* Fix drawables memory leak deteriorating frame rate

* Fix drawables dirty bound to redo bounding spheres

* Set offsets on OSG shapes rather than on positions

* Put vectors in AutoTransform for automatic scaling

* Adjust initial scales of vectors' radius & length
  • Loading branch information
anotheruserofgithub committed Sep 26, 2022
1 parent a86f55e commit d85e729
Show file tree
Hide file tree
Showing 21 changed files with 958 additions and 315 deletions.
6 changes: 5 additions & 1 deletion OMCompiler/Compiler/Template/VisualXMLTpl.tpl
Expand Up @@ -140,9 +140,13 @@ end dumpVecExp;
template dumpExp (DAE.Exp expIn)
::=
match expIn
case expIn as ENUM_LITERAL(__) then
<<
<enum><%intString(index)%></enum>
>>
case expIn as BCONST(__) then
<<
<bexp><%ExpressionDump.printExpStr(expIn)%></bexp>
<bconst><%ExpressionDump.printExpStr(expIn)%></bconst>
>>
case expIn as CREF(__) then
<<
Expand Down
2 changes: 1 addition & 1 deletion OMEdit/CMakeLists.txt
Expand Up @@ -12,7 +12,7 @@ set(CMAKE_CXX_EXTENSIONS OFF)


find_package(Qt5 COMPONENTS Widgets PrintSupport WebKitWidgets Xml XmlPatterns OpenGL Network Svg REQUIRED)
find_package(OpenSceneGraph COMPONENTS osgViewer osgDB osgGA REQUIRED)
find_package(OpenSceneGraph COMPONENTS osg osgViewer osgUtil osgDB osgGA REQUIRED)

# Configure omedit_config.h. This will be generated in the build directory
configure_file(omedit_config.h.in omedit_config.h)
Expand Down
4 changes: 3 additions & 1 deletion OMEdit/OMEditLIB/Animation/AbstractAnimationWindow.cpp
Expand Up @@ -416,7 +416,9 @@ bool AbstractAnimationWindow::loadVisualization()
mpVisualization->setUpScene();
mpVisualization->initVisualization();
//add scene for the chosen visualization
mpViewerWidget->getSceneView()->setSceneData(mpVisualization->getOMVisScene()->getScene().getRootNode());
mpViewerWidget->getSceneView()->setSceneData(mpVisualization->getOMVisScene()->getScene().getRootNode().get());
//choose suitable scales for the vector visualizers so that they fit well in the scene
mpVisualization->chooseVectorScales(mpViewerWidget->getSceneView(), mpViewerWidget->getFrameMutex(), std::bind(&ViewerWidget::frame, mpViewerWidget));
}
//add window title
setWindowTitle(QString::fromStdString(mFileName));
Expand Down
10 changes: 7 additions & 3 deletions OMEdit/OMEditLIB/Animation/AbstractVisualizer.cpp
Expand Up @@ -101,6 +101,7 @@ std::string VisualizerAttribute::getValueString() const
AbstractVisualizerObject::AbstractVisualizerObject(const VisualizerType type)
: mVisualizerType(type),
mStateSetAction(StateSetAction::update),
mTransformNode(nullptr),
mTextureImagePath(""),
mTransparency(0.0),
_id(""),
Expand Down Expand Up @@ -154,12 +155,15 @@ VisualizerAttribute getVisualizerAttributeForNode(const rapidxml::xml_node<>* no
if (strcmp("cref", node->name()) == 0) {
oa.cref = std::string(node->value());
oa.isConst = false;
} else if (strcmp("bconst", node->name()) == 0) {
oa.exp = (strcmp("true", node->value()) == 0);
oa.isConst = true;
} else if (strcmp("enum", node->name()) == 0) {
oa.exp = std::strtol(node->value(), nullptr, 0);
oa.isConst = true;
} else if (strcmp("exp", node->name()) == 0) {
oa.exp = std::strtof(node->value(), nullptr);
oa.isConst = true;
} else if (strcmp("bexp", node->name()) == 0) {
oa.exp = (strcmp("true", node->value()) == 0);
oa.isConst = true;
}
return oa;
}
17 changes: 14 additions & 3 deletions OMEdit/OMEditLIB/Animation/AbstractVisualizer.h
Expand Up @@ -35,17 +35,18 @@
#ifndef ABSTRACTVISUALIZER_H
#define ABSTRACTVISUALIZER_H

#include <string>
#include <iostream>

#include "rapidxml.hpp"

#include <QOpenGLContext> // must be included before OSG headers
#include <QColor>

#include <osg/Vec3f>
#include <osg/Matrix>
#include <osg/Uniform>
#include <osg/Transform>

#include <QColor>
#include "rapidxml.hpp"

enum class VisualizerType {shape, vector, surface};

Expand Down Expand Up @@ -94,18 +95,27 @@ class VisualizerAttribute
unsigned int fmuValueRef;
};

class ShapeObject;
class VectorObject;
typedef void SurfaceObject;

class AbstractVisualizerObject
{
public:
AbstractVisualizerObject(const VisualizerType type);
virtual ~AbstractVisualizerObject() = 0;
virtual void dumpVisualizerAttributes() const;
virtual ShapeObject* asShape() {return nullptr;}
virtual VectorObject* asVector() {return nullptr;}
virtual SurfaceObject* asSurface() {return nullptr;}
virtual bool isShape() const final {return mVisualizerType == VisualizerType::shape;}
virtual bool isVector() const final {return mVisualizerType == VisualizerType::vector;}
virtual bool isSurface() const final {return mVisualizerType == VisualizerType::surface;}
virtual VisualizerType getVisualizerType() const final {return mVisualizerType;}
virtual StateSetAction getStateSetAction() const final {return mStateSetAction;}
virtual void setStateSetAction(const StateSetAction action) final {mStateSetAction = action;}
virtual osg::ref_ptr<osg::Transform> getTransformNode() const final {return mTransformNode;}
virtual void setTransformNode(const osg::ref_ptr<osg::Transform> transform) final {mTransformNode = transform;}
virtual std::string getTextureImagePath() const final {return mTextureImagePath;}
virtual void setTextureImagePath(const std::string texture) final {mTextureImagePath = texture;}
virtual float getTransparency() const final {return mTransparency;}
Expand All @@ -117,6 +127,7 @@ class AbstractVisualizerObject
private:
VisualizerType mVisualizerType;
StateSetAction mStateSetAction;
osg::ref_ptr<osg::Transform> mTransformNode;
std::string mTextureImagePath;
float mTransparency;
public:
Expand Down
1 change: 1 addition & 0 deletions OMEdit/OMEditLIB/Animation/Shape.h
Expand Up @@ -44,6 +44,7 @@ class ShapeObject : public AbstractVisualizerObject
~ShapeObject() = default;
ShapeObject(const ShapeObject&) = default;
ShapeObject& operator=(const ShapeObject&) = default;
ShapeObject* asShape() override final {return this;}
void dumpVisualizerAttributes() const override;
public:
std::string _type;
Expand Down
28 changes: 9 additions & 19 deletions OMEdit/OMEditLIB/Animation/Vector.cpp
Expand Up @@ -31,7 +31,11 @@

#include "Vector.h"

#include <cmath>
VectorQuantity& operator++(VectorQuantity& quantity)
{
quantity = static_cast<VectorQuantity>(static_cast<int>(quantity) + 1);
return quantity;
}

std::ostream& operator<<(std::ostream& os, const VectorQuantity quantity)
{
Expand All @@ -58,6 +62,10 @@ std::ostream& operator<<(std::ostream& os, const VectorQuantity quantity)

VectorObject::VectorObject()
: AbstractVisualizerObject(VisualizerType::vector),
mScaleLength(1.0),
mScaleRadius(1.0),
mScaleTransf(1.0),
mAutoScaleCancellationRequired(false),
_quantity(VisualizerAttribute(0.0)),
_headAtOrigin(VisualizerAttribute(0.0)),
_twoHeadedArrow(VisualizerAttribute(0.0))
Expand All @@ -75,21 +83,3 @@ void VectorObject::dumpVisualizerAttributes() const
std::cout << "headAtOrigin " << _headAtOrigin.getValueString() << " = " << (hasHeadAtOrigin() ? "true" : "false") << std::endl;
std::cout << "twoHeadedArrow " << _twoHeadedArrow.getValueString() << " = " << (isTwoHeadedArrow() ? "true" : "false") << std::endl;
}

float VectorObject::getScale() const
{
switch (getQuantity())
{
case VectorQuantity::force:
return kScaleForce;
case VectorQuantity::torque:
return kScaleTorque;
default:
return 1;
}
}

float VectorObject::getLength() const
{
return std::sqrt(std::pow(_coords[0].exp, 2) + std::pow(_coords[1].exp, 2) + std::pow(_coords[2].exp, 2)) / getScale();
}
44 changes: 33 additions & 11 deletions OMEdit/OMEditLIB/Animation/Vector.h
Expand Up @@ -34,8 +34,13 @@

#include "AbstractVisualizer.h"

#include <cmath>
#include <limits>

/*! Equivalent to Modelica.Mechanics.MultiBody.Types.VectorQuantity */
enum class VectorQuantity {force = 1, torque, velocity, acceleration, angularVelocity, angularAcceleration, relativePosition};
enum class VectorQuantity {force = 1, torque, velocity, acceleration, angularVelocity, angularAcceleration, relativePosition, END, BEGIN = force};

VectorQuantity& operator++(VectorQuantity& quantity);

std::ostream& operator<<(std::ostream& os, const VectorQuantity quantity);

Expand All @@ -46,21 +51,38 @@ class VectorObject : public AbstractVisualizerObject
~VectorObject() = default;
VectorObject(const VectorObject&) = default;
VectorObject& operator=(const VectorObject&) = default;
VectorObject* asVector() override final {return this;}
void dumpVisualizerAttributes() const override;
float getScale() const;
float getLength() const;
float getRadius() const {return kRadius;}
float getHeadLength() const {return kHeadLength;}
float getHeadRadius() const {return kHeadRadius;}
void setScaleLength(const float scale) {mScaleLength = scale;}
void setScaleRadius(const float scale) {mScaleRadius = scale;}
void setScaleTransf(const float scale) {mScaleTransf = scale;}
float getScaleTransf() const {return mScaleTransf;}
void setAutoScaleCancellationRequired(const bool required) {mAutoScaleCancellationRequired = required;}
bool getAutoScaleCancellationRequired() const {return mAutoScaleCancellationRequired;}
float getLength () const {return mScaleTransf * mScaleLength * std::sqrt(_coords[0].exp * _coords[0].exp + _coords[1].exp * _coords[1].exp + _coords[2].exp * _coords[2].exp);}
float getRadius () const {return mScaleTransf * mScaleRadius * kRadius ;}
float getHeadLength() const {return mScaleTransf * mScaleRadius * kHeadLength;}
float getHeadRadius() const {return mScaleTransf * mScaleRadius * kHeadRadius;}
VectorQuantity getQuantity() const {return static_cast<VectorQuantity>(_quantity.exp);}
bool hasHeadAtOrigin() const {return _headAtOrigin.exp;}
bool isTwoHeadedArrow() const {return _twoHeadedArrow.exp;}
bool isAdjustableRadius() const {return getQuantity() != VectorQuantity::relativePosition;}
bool isAdjustableLength() const {return getQuantity() != VectorQuantity::relativePosition;}
bool isScaleInvariant () const {return getQuantity() != VectorQuantity::relativePosition;}
bool isDrawnOnTop () const {return getQuantity() != VectorQuantity::relativePosition;}
public:
static constexpr float kRadius = 0.0125; //!< Modelica.Mechanics.MultiBody.World.defaultArrowDiameter / 2 = 1 / 40 / 2 = 0.0125
static constexpr float kHeadLength = 0.1000; //!< Modelica.Mechanics.MultiBody.Types.Defaults.ArrowHeadLengthFraction * (2 * kRadius) = 4 * 0.025 = 0.1000
static constexpr float kHeadRadius = 0.0375; //!< Modelica.Mechanics.MultiBody.Types.Defaults.ArrowHeadWidthFraction * (2 * kRadius) / 2 = 3 * 0.025 / 2 = 0.0375
static constexpr float kScaleForce = 1000; //!< Modelica.Mechanics.MultiBody.World.defaultN_to_m = 1000
static constexpr float kScaleTorque = 1000; //!< Modelica.Mechanics.MultiBody.World.defaultNm_to_m = 1000
static constexpr char kAutoScaleRenderBinName[] = "RenderBin"; //!< See class RenderBinPrototypeList in osgUtil/RenderBin.cpp
static constexpr int kAutoScaleRenderBinNum = std::numeric_limits<int>::max(); //!< To be rendered last
private:
const float kRadius = 0.0125; //!< Modelica.Mechanics.MultiBody.World.defaultArrowDiameter / 2 = 1 / 40 / 2 = 0.0125
const float kHeadLength = 0.1000; //!< Modelica.Mechanics.MultiBody.Types.Defaults.ArrowHeadLengthFraction * (2 * kRadius) = 4 * 0.025 = 0.1000
const float kHeadRadius = 0.0375; //!< Modelica.Mechanics.MultiBody.Types.Defaults.ArrowHeadWidthFraction * (2 * kRadius) / 2 = 3 * 0.025 / 2 = 0.0375
const float kScaleForce = 1200; //!< Modelica.Mechanics.MultiBody.Examples.Elementary.ForceAndTorque.world.defaultN_to_m = 1200
const float kScaleTorque = 120; //!< Modelica.Mechanics.MultiBody.Examples.Elementary.ForceAndTorque.world.defaultNm_to_m = 120
float mScaleLength;
float mScaleRadius;
float mScaleTransf;
bool mAutoScaleCancellationRequired;
public:
VisualizerAttribute _coords[3];
VisualizerAttribute _quantity;
Expand Down

0 comments on commit d85e729

Please sign in to comment.