Files
create/src/Gui/SplitView3DInventor.cpp
xtemp09 414c803ff3 [GUI] Radial gradient implementation
This commit implements radial gradient as background and adds the option
to settings. It also renames "Color gradient" as "Linear gradient",
keeping Linear gradient default. Internally, it remains unchanged for
compatibility.

Radio gradient is more suitable for CAD, since it gives a more balanced
color distribution across the screen, improving visibility of model and
sketches with a halo-like effect.
2023-04-02 16:33:01 +07:00

845 lines
31 KiB
C++

/***************************************************************************
* Copyright (c) 2006 Werner Mayer <wmayer[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QSplitter>
# include <Inventor/nodes/SoDirectionalLight.h>
# include <Inventor/nodes/SoOrthographicCamera.h>
# include <Inventor/nodes/SoPerspectiveCamera.h>
#endif
#include <Base/Builder3D.h>
#include <Base/Interpreter.h>
#include "SplitView3DInventor.h"
#include "Application.h"
#include "Camera.h"
#include "Document.h"
#include "NavigationStyle.h"
#include "SoFCSelectionAction.h"
#include "View3DInventorViewer.h"
#include "View3DPy.h"
using namespace Gui;
TYPESYSTEM_SOURCE_ABSTRACT(Gui::AbstractSplitView,Gui::MDIView)
AbstractSplitView::AbstractSplitView(Gui::Document* pcDocument, QWidget* parent, Qt::WindowFlags wflags)
: MDIView(pcDocument,parent, wflags)
{
_viewerPy = nullptr;
// important for highlighting
setMouseTracking(true);
}
AbstractSplitView::~AbstractSplitView()
{
hGrp->Detach(this);
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it) {
delete *it;
}
if (_viewerPy) {
Base::PyGILStateLocker lock;
Py_DECREF(_viewerPy);
}
}
void AbstractSplitView::deleteSelf()
{
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it) {
(*it)->setSceneGraph(nullptr);
}
MDIView::deleteSelf();
}
void AbstractSplitView::setDocumentOfViewers(Gui::Document* document)
{
for (auto view : _viewer) {
view->setDocument(document);
}
}
void AbstractSplitView::viewAll()
{
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
(*it)->viewAll();
}
bool AbstractSplitView::containsViewProvider(const ViewProvider* vp) const
{
for (auto it = _viewer.begin(); it != _viewer.end(); ++it) {
if ((*it)->containsViewProvider(vp))
return true;
}
return false;
}
void AbstractSplitView::setupSettings()
{
// attach Parameter Observer
hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
hGrp->Attach(this);
// apply the user settings
OnChange(*hGrp,"EyeDistance");
OnChange(*hGrp,"CornerCoordSystem");
OnChange(*hGrp,"CornerCoordSystemSize");
OnChange(*hGrp,"UseAutoRotation");
OnChange(*hGrp,"Gradient");
OnChange(*hGrp,"RadialGradient");
OnChange(*hGrp,"BackgroundColor");
OnChange(*hGrp,"BackgroundColor2");
OnChange(*hGrp,"BackgroundColor3");
OnChange(*hGrp,"BackgroundColor4");
OnChange(*hGrp,"UseBackgroundColorMid");
OnChange(*hGrp,"ShowFPS");
OnChange(*hGrp,"UseVBO");
OnChange(*hGrp,"Orthographic");
OnChange(*hGrp,"HeadlightColor");
OnChange(*hGrp,"HeadlightDirection");
OnChange(*hGrp,"HeadlightIntensity");
OnChange(*hGrp,"EnableBacklight");
OnChange(*hGrp,"BacklightColor");
OnChange(*hGrp,"BacklightDirection");
OnChange(*hGrp,"BacklightIntensity");
OnChange(*hGrp,"NavigationStyle");
OnChange(*hGrp,"OrbitStyle");
OnChange(*hGrp,"Sensitivity");
OnChange(*hGrp,"ResetCursorPosition");
OnChange(*hGrp,"PickRadius");
}
View3DInventorViewer* AbstractSplitView::getViewer(unsigned int n) const
{
return (_viewer.size() > n ? _viewer[n] : nullptr);
}
/// Observer message from the ParameterGrp
void AbstractSplitView::OnChange(ParameterGrp::SubjectType &rCaller,ParameterGrp::MessageType Reason)
{
const ParameterGrp& rGrp = static_cast<ParameterGrp&>(rCaller);
if (strcmp(Reason,"HeadlightColor") == 0) {
unsigned long headlight = rGrp.GetUnsigned("HeadlightColor",ULONG_MAX); // default color (white)
float transparency;
SbColor headlightColor;
headlightColor.setPackedValue((uint32_t)headlight, transparency);
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
(*it)->getHeadlight()->color.setValue(headlightColor);
}
else if (strcmp(Reason,"HeadlightDirection") == 0) {
try {
std::string pos = rGrp.GetASCII("HeadlightDirection");
Base::Vector3f dir = Base::to_vector(pos);
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
(*it)->getHeadlight()->direction.setValue(dir.x, dir.y, dir.z);
}
catch (const std::exception&) {
// ignore exception
}
}
else if (strcmp(Reason,"HeadlightIntensity") == 0) {
long value = rGrp.GetInt("HeadlightIntensity", 100);
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
(*it)->getHeadlight()->intensity.setValue((float)value/100.0f);
}
else if (strcmp(Reason,"EnableBacklight") == 0) {
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
(*it)->setBacklight(rGrp.GetBool("EnableBacklight", false));
}
else if (strcmp(Reason,"BacklightColor") == 0) {
unsigned long backlight = rGrp.GetUnsigned("BacklightColor",ULONG_MAX); // default color (white)
float transparency;
SbColor backlightColor;
backlightColor.setPackedValue((uint32_t)backlight, transparency);
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
(*it)->getBacklight()->color.setValue(backlightColor);
}
else if (strcmp(Reason,"BacklightDirection") == 0) {
try {
std::string pos = rGrp.GetASCII("BacklightDirection");
Base::Vector3f dir = Base::to_vector(pos);
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
(*it)->getBacklight()->direction.setValue(dir.x, dir.y, dir.z);
}
catch (const std::exception&) {
// ignore exception
}
}
else if (strcmp(Reason,"BacklightIntensity") == 0) {
long value = rGrp.GetInt("BacklightIntensity", 100);
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
(*it)->getBacklight()->intensity.setValue((float)value/100.0f);
}
else if (strcmp(Reason,"EnablePreselection") == 0) {
SoFCEnableHighlightAction cAct(rGrp.GetBool("EnablePreselection", true));
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
cAct.apply((*it)->getSceneGraph());
}
else if (strcmp(Reason,"EnableSelection") == 0) {
SoFCEnableSelectionAction cAct(rGrp.GetBool("EnableSelection", true));
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
cAct.apply((*it)->getSceneGraph());
}
else if (strcmp(Reason,"HighlightColor") == 0) {
float transparency;
SbColor highlightColor(0.8f, 0.1f, 0.1f);
auto highlight = (unsigned long)(highlightColor.getPackedValue());
highlight = rGrp.GetUnsigned("HighlightColor", highlight);
highlightColor.setPackedValue((uint32_t)highlight, transparency);
SoSFColor col; col.setValue(highlightColor);
SoFCHighlightColorAction cAct(col);
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
cAct.apply((*it)->getSceneGraph());
}
else if (strcmp(Reason,"SelectionColor") == 0) {
float transparency;
SbColor selectionColor(0.1f, 0.8f, 0.1f);
auto selection = (unsigned long)(selectionColor.getPackedValue());
selection = rGrp.GetUnsigned("SelectionColor", selection);
selectionColor.setPackedValue((uint32_t)selection, transparency);
SoSFColor col; col.setValue(selectionColor);
SoFCSelectionColorAction cAct(col);
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
cAct.apply((*it)->getSceneGraph());
}
else if (strcmp(Reason,"NavigationStyle") == 0) {
// tmp. disabled will be activated after redesign of 3d viewer
// check whether the simple or the Full Mouse model is used
//std::string model = rGrp.GetASCII("NavigationStyle",CADNavigationStyle::getClassTypeId().getName());
//Base::Type type = Base::Type::fromName(model.c_str());
//for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
// (*it)->setNavigationType(type);
}
else if (strcmp(Reason,"OrbitStyle") == 0) {
int style = rGrp.GetInt("OrbitStyle",1);
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
(*it)->navigationStyle()->setOrbitStyle(NavigationStyle::OrbitStyle(style));
}
else if (strcmp(Reason,"Sensitivity") == 0) {
float val = rGrp.GetFloat("Sensitivity",2.0f);
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
(*it)->navigationStyle()->setSensitivity(val);
}
else if (strcmp(Reason,"ResetCursorPosition") == 0) {
bool on = rGrp.GetBool("ResetCursorPosition",false);
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
(*it)->navigationStyle()->setResetCursorPosition(on);
}
else if (strcmp(Reason,"EyeDistance") == 0) {
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
(*it)->getSoRenderManager()->setStereoOffset(rGrp.GetFloat("EyeDistance",5.0));
}
else if (strcmp(Reason,"CornerCoordSystem") == 0) {
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
(*it)->setFeedbackVisibility(rGrp.GetBool("CornerCoordSystem",true));
}
else if (strcmp(Reason,"CornerCoordSystemSize") == 0) {
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
(*it)->setFeedbackSize(rGrp.GetInt("CornerCoordSystemSize",10));
}
else if (strcmp(Reason,"UseAutoRotation") == 0) {
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
(*it)->setAnimationEnabled(rGrp.GetBool("UseAutoRotation",false));
}
else if ( strcmp(Reason,"Gradient") == 0 || strcmp(Reason, "RadialGradient") == 0 ) {
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
(*it)->setGradientBackground(rGrp.GetBool("Gradient", true) || rGrp.GetBool("RadialGradient", true));
}
else if (strcmp(Reason,"ShowFPS") == 0) {
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
(*it)->setEnabledFPSCounter(rGrp.GetBool("ShowFPS",false));
}
else if (strcmp(Reason,"UseVBO") == 0) {
// Disable VBO for split screen as this leads to random crashes
//for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
// (*it)->setEnabledVBO(rGrp.GetBool("UseVBO",false));
}
else if (strcmp(Reason,"Orthographic") == 0) {
// check whether a perspective or orthogrphic camera should be set
if (rGrp.GetBool("Orthographic", true)) {
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
(*it)->setCameraType(SoOrthographicCamera::getClassTypeId());
}
else {
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
(*it)->setCameraType(SoPerspectiveCamera::getClassTypeId());
}
}
else if (strcmp(Reason, "PickRadius") == 0) {
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
(*it)->setPickRadius(rGrp.GetFloat("PickRadius", 5.0f));
}
else {
unsigned long col1 = rGrp.GetUnsigned("BackgroundColor",3940932863UL);
unsigned long col2 = rGrp.GetUnsigned("BackgroundColor2",859006463UL); // default color (dark blue)
unsigned long col3 = rGrp.GetUnsigned("BackgroundColor3",2880160255UL); // default color (blue/grey)
unsigned long col4 = rGrp.GetUnsigned("BackgroundColor4",1869583359UL); // default color (blue/grey)
float r1,g1,b1,r2,g2,b2,r3,g3,b3,r4,g4,b4;
r1 = ((col1 >> 24) & 0xff) / 255.0; g1 = ((col1 >> 16) & 0xff) / 255.0; b1 = ((col1 >> 8) & 0xff) / 255.0;
r2 = ((col2 >> 24) & 0xff) / 255.0; g2 = ((col2 >> 16) & 0xff) / 255.0; b2 = ((col2 >> 8) & 0xff) / 255.0;
r3 = ((col3 >> 24) & 0xff) / 255.0; g3 = ((col3 >> 16) & 0xff) / 255.0; b3 = ((col3 >> 8) & 0xff) / 255.0;
r4 = ((col4 >> 24) & 0xff) / 255.0; g4 = ((col4 >> 16) & 0xff) / 255.0; b4 = ((col4 >> 8) & 0xff) / 255.0;
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it) {
(*it)->setBackgroundColor(QColor::fromRgbF(r1, g1, b1));
if (!rGrp.GetBool("UseBackgroundColorMid",false))
(*it)->setGradientBackgroundColor(SbColor(r2, g2, b2), SbColor(r3, g3, b3),
rGrp.GetBool("RadialGradient", false) );
else
(*it)->setGradientBackgroundColor(SbColor(r2, g2, b2), SbColor(r3, g3, b3), SbColor(r4, g4, b4),
rGrp.GetBool("RadialGradient", false) );
}
}
}
void AbstractSplitView::onUpdate()
{
update();
}
const char *AbstractSplitView::getName() const
{
return "SplitView3DInventor";
}
bool AbstractSplitView::onMsg(const char* pMsg, const char**)
{
if (strcmp("ViewFit",pMsg) == 0 ) {
viewAll();
return true;
}
else if (strcmp("ViewBottom",pMsg) == 0) {
SbRotation rot(Camera::rotation(Camera::Bottom));
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it) {
SoCamera* cam = (*it)->getSoRenderManager()->getCamera();
cam->orientation.setValue(rot);
(*it)->viewAll();
}
return true;
}
else if (strcmp("ViewFront",pMsg) == 0) {
SbRotation rot(Camera::rotation(Camera::Front));
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it) {
SoCamera* cam = (*it)->getSoRenderManager()->getCamera();
cam->orientation.setValue(rot);
(*it)->viewAll();
}
return true;
}
else if (strcmp("ViewLeft",pMsg) == 0) {
SbRotation rot(Camera::rotation(Camera::Left));
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it) {
SoCamera* cam = (*it)->getSoRenderManager()->getCamera();
cam->orientation.setValue(rot);
(*it)->viewAll();
}
return true;
}
else if (strcmp("ViewRear",pMsg) == 0) {
SbRotation rot(Camera::rotation(Camera::Rear));
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it) {
SoCamera* cam = (*it)->getSoRenderManager()->getCamera();
cam->orientation.setValue(rot);
(*it)->viewAll();
}
return true;
}
else if (strcmp("ViewRight",pMsg) == 0) {
SbRotation rot(Camera::rotation(Camera::Right));
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it) {
SoCamera* cam = (*it)->getSoRenderManager()->getCamera();
cam->orientation.setValue(rot);
(*it)->viewAll();
}
return true;
}
else if (strcmp("ViewTop",pMsg) == 0) {
SbRotation rot(Camera::rotation(Camera::Top));
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it) {
SoCamera* cam = (*it)->getSoRenderManager()->getCamera();
cam->orientation.setValue(rot);
(*it)->viewAll();
}
return true;
}
else if (strcmp("ViewAxo",pMsg) == 0) {
SbRotation rot(Camera::rotation(Camera::Isometric));
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it) {
SoCamera* cam = (*it)->getSoRenderManager()->getCamera();
cam->orientation.setValue(rot);
(*it)->viewAll();
}
return true;
}
return false;
}
bool AbstractSplitView::onHasMsg(const char* pMsg) const
{
if (strcmp("ViewFit",pMsg) == 0) {
return true;
}
else if (strcmp("ViewBottom",pMsg) == 0) {
return true;
}
else if (strcmp("ViewFront",pMsg) == 0) {
return true;
}
else if (strcmp("ViewLeft",pMsg) == 0) {
return true;
}
else if (strcmp("ViewRear",pMsg) == 0) {
return true;
}
else if (strcmp("ViewRight",pMsg) == 0) {
return true;
}
else if (strcmp("ViewTop",pMsg) == 0) {
return true;
}
else if (strcmp("ViewAxo",pMsg) == 0) {
return true;
}
return false;
}
void AbstractSplitView::setOverrideCursor(const QCursor& aCursor)
{
Q_UNUSED(aCursor);
//_viewer->getWidget()->setCursor(aCursor);
}
PyObject *AbstractSplitView::getPyObject()
{
if (!_viewerPy)
_viewerPy = new AbstractSplitViewPy(this);
Py_INCREF(_viewerPy);
return _viewerPy;
}
void AbstractSplitView::setPyObject(PyObject *)
{
throw Base::AttributeError("Attribute is read-only");
}
int AbstractSplitView::getSize()
{
return static_cast<int>(_viewer.size());
}
// ------------------------------------------------------
void AbstractSplitViewPy::init_type()
{
behaviors().name("AbstractSplitViewPy");
behaviors().doc("Python binding class for the Inventor viewer class");
// you must have overwritten the virtual functions
behaviors().supportRepr();
behaviors().supportGetattr();
behaviors().supportSetattr();
behaviors().supportSequenceType();
add_varargs_method("fitAll",&AbstractSplitViewPy::fitAll,"fitAll()");
add_varargs_method("viewBottom",&AbstractSplitViewPy::viewBottom,"viewBottom()");
add_varargs_method("viewFront",&AbstractSplitViewPy::viewFront,"viewFront()");
add_varargs_method("viewLeft",&AbstractSplitViewPy::viewLeft,"viewLeft()");
add_varargs_method("viewRear",&AbstractSplitViewPy::viewRear,"viewRear()");
add_varargs_method("viewRight",&AbstractSplitViewPy::viewRight,"viewRight()");
add_varargs_method("viewTop",&AbstractSplitViewPy::viewTop,"viewTop()");
add_varargs_method("viewAxometric",&AbstractSplitViewPy::viewIsometric,"viewAxometric()");
add_varargs_method("viewIsometric",&AbstractSplitViewPy::viewIsometric,"viewIsometric()");
add_varargs_method("getViewer",&AbstractSplitViewPy::getViewer,"getViewer(index)");
add_varargs_method("close",&AbstractSplitViewPy::close,"close()");
add_varargs_method("cast_to_base", &AbstractSplitViewPy::cast_to_base, "cast_to_base() cast to MDIView class");
behaviors().readyType();
}
AbstractSplitViewPy::AbstractSplitViewPy(AbstractSplitView *vi)
: base(vi)
{
}
AbstractSplitViewPy::~AbstractSplitViewPy()
{
}
Py::Object AbstractSplitViewPy::cast_to_base(const Py::Tuple&)
{
return Gui::MDIViewPy::create(base.getMDIViewPtr());
}
Py::Object AbstractSplitViewPy::repr()
{
std::ostringstream s_out;
if (!getSplitViewPtr())
throw Py::RuntimeError("Cannot print representation of deleted object");
s_out << "AbstractSplitView";
return Py::String(s_out.str());
}
// Since with PyCXX it's not possible to make a sub-class of MDIViewPy
// a trick is to use MDIViewPy as class member and override getattr() to
// join the attributes of both classes. This way all methods of MDIViewPy
// appear for SheetViewPy, too.
Py::Object AbstractSplitViewPy::getattr(const char * attr)
{
getSplitViewPtr();
std::string name( attr );
if (name == "__dict__" || name == "__class__") {
Py::Dict dict_self(BaseType::getattr("__dict__"));
Py::Dict dict_base(base.getattr("__dict__"));
for (const auto& it : dict_base) {
dict_self.setItem(it.first, it.second);
}
return dict_self;
}
try {
return BaseType::getattr(attr);
}
catch (Py::AttributeError& e) {
e.clear();
return base.getattr(attr);
}
}
AbstractSplitView* AbstractSplitViewPy::getSplitViewPtr()
{
auto view = qobject_cast<AbstractSplitView*>(base.getMDIViewPtr());
if (!(view && view->getViewer(0)))
throw Py::RuntimeError("Object already deleted");
return view;
}
Py::Object AbstractSplitViewPy::fitAll(const Py::Tuple& args)
{
if (!PyArg_ParseTuple(args.ptr(), ""))
throw Py::Exception();
try {
getSplitViewPtr()->onMsg("ViewFit", nullptr);
}
catch (const Base::Exception& e) {
throw Py::RuntimeError(e.what());
}
catch (const std::exception& e) {
throw Py::RuntimeError(e.what());
}
catch(...) {
throw Py::RuntimeError("Unknown C++ exception");
}
return Py::None();
}
Py::Object AbstractSplitViewPy::viewBottom(const Py::Tuple& args)
{
if (!PyArg_ParseTuple(args.ptr(), ""))
throw Py::Exception();
try {
getSplitViewPtr()->onMsg("ViewBottom", nullptr);
}
catch (const Base::Exception& e) {
throw Py::RuntimeError(e.what());
}
catch (const std::exception& e) {
throw Py::RuntimeError(e.what());
}
catch(...) {
throw Py::RuntimeError("Unknown C++ exception");
}
return Py::None();
}
Py::Object AbstractSplitViewPy::viewFront(const Py::Tuple& args)
{
if (!PyArg_ParseTuple(args.ptr(), ""))
throw Py::Exception();
try {
getSplitViewPtr()->onMsg("ViewFront", nullptr);
}
catch (const Base::Exception& e) {
throw Py::RuntimeError(e.what());
}
catch (const std::exception& e) {
throw Py::RuntimeError(e.what());
}
catch(...) {
throw Py::RuntimeError("Unknown C++ exception");
}
return Py::None();
}
Py::Object AbstractSplitViewPy::viewLeft(const Py::Tuple& args)
{
if (!PyArg_ParseTuple(args.ptr(), ""))
throw Py::Exception();
try {
getSplitViewPtr()->onMsg("ViewLeft", nullptr);
}
catch (const Base::Exception& e) {
throw Py::RuntimeError(e.what());
}
catch (const std::exception& e) {
throw Py::RuntimeError(e.what());
}
catch(...) {
throw Py::RuntimeError("Unknown C++ exception");
}
return Py::None();
}
Py::Object AbstractSplitViewPy::viewRear(const Py::Tuple& args)
{
if (!PyArg_ParseTuple(args.ptr(), ""))
throw Py::Exception();
try {
getSplitViewPtr()->onMsg("ViewRear", nullptr);
}
catch (const Base::Exception& e) {
throw Py::RuntimeError(e.what());
}
catch (const std::exception& e) {
throw Py::RuntimeError(e.what());
}
catch(...) {
throw Py::RuntimeError("Unknown C++ exception");
}
return Py::None();
}
Py::Object AbstractSplitViewPy::viewRight(const Py::Tuple& args)
{
if (!PyArg_ParseTuple(args.ptr(), ""))
throw Py::Exception();
try {
getSplitViewPtr()->onMsg("ViewRight", nullptr);
}
catch (const Base::Exception& e) {
throw Py::RuntimeError(e.what());
}
catch (const std::exception& e) {
throw Py::RuntimeError(e.what());
}
catch(...) {
throw Py::RuntimeError("Unknown C++ exception");
}
return Py::None();
}
Py::Object AbstractSplitViewPy::viewTop(const Py::Tuple& args)
{
if (!PyArg_ParseTuple(args.ptr(), ""))
throw Py::Exception();
try {
getSplitViewPtr()->onMsg("ViewTop", nullptr);
}
catch (const Base::Exception& e) {
throw Py::RuntimeError(e.what());
}
catch (const std::exception& e) {
throw Py::RuntimeError(e.what());
}
catch(...) {
throw Py::RuntimeError("Unknown C++ exception");
}
return Py::None();
}
Py::Object AbstractSplitViewPy::viewIsometric(const Py::Tuple& args)
{
if (!PyArg_ParseTuple(args.ptr(), ""))
throw Py::Exception();
try {
getSplitViewPtr()->onMsg("ViewAxo", nullptr);
}
catch (const Base::Exception& e) {
throw Py::RuntimeError(e.what());
}
catch (const std::exception& e) {
throw Py::RuntimeError(e.what());
}
catch(...) {
throw Py::RuntimeError("Unknown C++ exception");
}
return Py::None();
}
Py::Object AbstractSplitViewPy::getViewer(const Py::Tuple& args)
{
int viewIndex;
if (!PyArg_ParseTuple(args.ptr(), "i", &viewIndex))
throw Py::Exception();
try {
Gui::View3DInventorViewer* view = getSplitViewPtr()->getViewer(viewIndex);
if (!view)
throw Py::IndexError("Index out of range");
return Py::asObject(view->getPyObject());
}
catch (const Base::Exception& e) {
throw Py::RuntimeError(e.what());
}
catch (const std::exception& e) {
throw Py::RuntimeError(e.what());
}
catch (const Py::Exception&) {
// re-throw
throw;
}
catch(...) {
throw Py::RuntimeError("Unknown C++ exception");
}
}
Py::Object AbstractSplitViewPy::sequence_item(Py_ssize_t viewIndex)
{
AbstractSplitView* view = getSplitViewPtr();
if (viewIndex >= view->getSize() || viewIndex < 0)
throw Py::IndexError("Index out of range");
PyObject* viewer = view->getViewer(viewIndex)->getPyObject();
return Py::asObject(viewer);
}
PyCxx_ssize_t AbstractSplitViewPy::sequence_length()
{
AbstractSplitView* view = getSplitViewPtr();
return view->getSize();
}
Py::Object AbstractSplitViewPy::close(const Py::Tuple& args)
{
if (!PyArg_ParseTuple(args.ptr(), ""))
throw Py::Exception();
AbstractSplitView* view = getSplitViewPtr();
view->close();
if (view->parentWidget())
view->parentWidget()->deleteLater();
return Py::None();
}
// ------------------------------------------------------
TYPESYSTEM_SOURCE_ABSTRACT(Gui::SplitView3DInventor, Gui::AbstractSplitView)
SplitView3DInventor::SplitView3DInventor(int views, Gui::Document* pcDocument, QWidget* parent, Qt::WindowFlags wflags)
: AbstractSplitView(pcDocument,parent, wflags)
{
// attach parameter Observer
hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
hGrp->Attach(this);
//anti-aliasing settings
bool smoothing = false;
bool glformat = false;
int samples = View3DInventorViewer::getNumSamples();
QtGLFormat f;
if (samples > 1) {
glformat = true;
f.setSamples(samples);
}
else if (samples > 0) {
smoothing = true;
}
// minimal 2 views
while (views < 2)
views ++;
QSplitter* mainSplitter = nullptr;
// if views < 3 show them as a row
if (views <= 3) {
mainSplitter = new QSplitter(Qt::Horizontal, this);
for (int i=0; i < views; i++) {
if (glformat)
_viewer.push_back(new View3DInventorViewer(f, mainSplitter));
else
_viewer.push_back(new View3DInventorViewer(mainSplitter));
}
}
else {
mainSplitter = new QSplitter(Qt::Vertical, this);
auto topSplitter = new QSplitter(Qt::Horizontal, mainSplitter);
auto botSplitter = new QSplitter(Qt::Horizontal, mainSplitter);
if (glformat) {
_viewer.push_back(new View3DInventorViewer(f, topSplitter));
_viewer.push_back(new View3DInventorViewer(f, topSplitter));
}
else {
_viewer.push_back(new View3DInventorViewer(topSplitter));
_viewer.push_back(new View3DInventorViewer(topSplitter));
}
for (int i=2;i<views;i++) {
if (glformat)
_viewer.push_back(new View3DInventorViewer(f, botSplitter));
else
_viewer.push_back(new View3DInventorViewer(botSplitter));
}
topSplitter->setOpaqueResize(true);
botSplitter->setOpaqueResize(true);
}
if (smoothing) {
for (std::vector<int>::size_type i = 0; i != _viewer.size(); i++)
_viewer[i]->getSoRenderManager()->getGLRenderAction()->setSmoothing(true);
}
mainSplitter->show();
setCentralWidget(mainSplitter);
setDocumentOfViewers(pcDocument);
// apply the user settings
setupSettings();
}
SplitView3DInventor::~SplitView3DInventor()
{
}
#include "moc_SplitView3DInventor.cpp"