From 2aef0cfa612c39e2a640e8838e381067abcdb4ee Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 20 Mar 2023 10:48:29 +0100 Subject: [PATCH] Gui: move class Camera to own source files --- src/Gui/Camera.cpp | 142 ++++++++++++++++++++++++++++++++ src/Gui/Camera.h | 53 ++++++++++++ src/Gui/SoFCDB.cpp | 2 +- src/Gui/SplitView3DInventor.cpp | 1 + src/Gui/View3DInventor.cpp | 1 + src/Gui/View3DPy.cpp | 114 +------------------------ src/Gui/View3DPy.h | 18 ---- 7 files changed, 199 insertions(+), 132 deletions(-) create mode 100644 src/Gui/Camera.cpp create mode 100644 src/Gui/Camera.h diff --git a/src/Gui/Camera.cpp b/src/Gui/Camera.cpp new file mode 100644 index 0000000000..b8df02bc26 --- /dev/null +++ b/src/Gui/Camera.cpp @@ -0,0 +1,142 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later + +/*************************************************************************** + * Copyright (c) 2023 Werner Mayer * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + **************************************************************************/ + +#include "PreCompiled.h" + +#include "Camera.h" + +using namespace Gui; + + +/** + Formulas to get quaternion for axonometric views: + + \code +from math import sqrt, degrees, asin, atan +p1=App.Rotation(App.Vector(1,0,0),90) +p2=App.Rotation(App.Vector(0,0,1),alpha) +p3=App.Rotation(p2.multVec(App.Vector(1,0,0)),beta) +p4=p3.multiply(p2).multiply(p1) + +from pivy import coin +c=Gui.ActiveDocument.ActiveView.getCameraNode() +c.orientation.setValue(*p4.Q) + \endcode + + The angles alpha and beta depend on the type of axonometry + Isometric: + \code +alpha=45 +beta=degrees(asin(-sqrt(1.0/3.0))) + \endcode + + Dimetric: + \code +alpha=degrees(asin(sqrt(1.0/8.0))) +beta=degrees(-asin(1.0/3.0)) + \endcode + + Trimetric: + \code +alpha=30.0 +beta=-35.0 + \endcode + + Verification code that the axonomtries are correct: + + \code +from pivy import coin +c=Gui.ActiveDocument.ActiveView.getCameraNode() +vo=App.Vector(c.getViewVolume().getMatrix().multVecMatrix(coin.SbVec3f(0,0,0)).getValue()) +vx=App.Vector(c.getViewVolume().getMatrix().multVecMatrix(coin.SbVec3f(10,0,0)).getValue()) +vy=App.Vector(c.getViewVolume().getMatrix().multVecMatrix(coin.SbVec3f(0,10,0)).getValue()) +vz=App.Vector(c.getViewVolume().getMatrix().multVecMatrix(coin.SbVec3f(0,0,10)).getValue()) +(vx-vo).Length +(vy-vo).Length +(vz-vo).Length + +# Projection +vo.z=0 +vx.z=0 +vy.z=0 +vz.z=0 + +(vx-vo).Length +(vy-vo).Length +(vz-vo).Length + \endcode + + See also: + http://www.mathematik.uni-marburg.de/~thormae/lectures/graphics1/graphics_6_2_ger_web.html#1 + http://www.mathematik.uni-marburg.de/~thormae/lectures/graphics1/code_v2/Axonometric/qt/Axonometric.cpp + https://de.wikipedia.org/wiki/Arkussinus_und_Arkuskosinus +*/ + +SbRotation Camera::rotation(Camera::Orientation view) +{ + switch (view) { + case Top: + return SbRotation(0, 0, 0, 1); + case Bottom: + return SbRotation(1, 0, 0, 0); + case Front: { + auto root = (float)(sqrt(2.0)/2.0); + return SbRotation(root, 0, 0, root); + } + case Rear: { + auto root = (float)(sqrt(2.0)/2.0); + return SbRotation(0, root, root, 0); + } + case Right: + return SbRotation(0.5, 0.5, 0.5, 0.5); + case Left: + return SbRotation(-0.5, 0.5, 0.5, -0.5); + case Isometric: + //from math import sqrt, degrees, asin + //p1=App.Rotation(App.Vector(1,0,0),45) + //p2=App.Rotation(App.Vector(0,0,1),-45) + //p3=p2.multiply(p1) + //return SbRotation(0.353553f, -0.146447f, -0.353553f, 0.853553f); + + //from math import sqrt, degrees, asin + //p1=App.Rotation(App.Vector(1,0,0),90) + //p2=App.Rotation(App.Vector(0,0,1),135) + //p3=App.Rotation(App.Vector(-1,1,0),degrees(asin(-sqrt(1.0/3.0)))) + //p4=p3.multiply(p2).multiply(p1) + //return SbRotation(0.17592, 0.424708, 0.820473, 0.339851); + + //from math import sqrt, degrees, asin + //p1=App.Rotation(App.Vector(1,0,0),90) + //p2=App.Rotation(App.Vector(0,0,1),45) + //#p3=App.Rotation(App.Vector(1,1,0),45) + //p3=App.Rotation(App.Vector(1,1,0),degrees(asin(-sqrt(1.0/3.0)))) + //p4=p3.multiply(p2).multiply(p1) + return SbRotation(0.424708f, 0.17592f, 0.339851f, 0.820473f); + case Dimetric: + return SbRotation(0.567952f, 0.103751f, 0.146726f, 0.803205f); + case Trimetric: + return SbRotation(0.446015f, 0.119509f, 0.229575f, 0.856787f); + default: + return SbRotation(0, 0, 0, 1); + } +} diff --git a/src/Gui/Camera.h b/src/Gui/Camera.h new file mode 100644 index 0000000000..027a5791ef --- /dev/null +++ b/src/Gui/Camera.h @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later + +/*************************************************************************** + * Copyright (c) 2023 Werner Mayer * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + **************************************************************************/ + +#ifndef GUI_CAMERA_H +#define GUI_CAMERA_H + +#include +#include +#include + +namespace Gui { + +class GuiExport Camera +{ +public: + enum Orientation { + Top, + Bottom, + Front, + Rear, + Right, + Left, + Isometric, + Dimetric, + Trimetric, + }; + + static SbRotation rotation(Orientation view); +}; + +} + +#endif // GUI_CAMERA_H diff --git a/src/Gui/SoFCDB.cpp b/src/Gui/SoFCDB.cpp index 4df76c4fe3..1fb8002705 100644 --- a/src/Gui/SoFCDB.cpp +++ b/src/Gui/SoFCDB.cpp @@ -48,6 +48,7 @@ #include #include "SoFCDB.h" +#include "Camera.h" #include "Flag.h" #include "GestureNavigationStyle.h" #include "NavigationStyle.h" @@ -68,7 +69,6 @@ #include "SoMouseWheelEvent.h" #include "SoNavigationDragger.h" #include "SoTextLabel.h" -#include "View3DPy.h" #include "Inventor/MarkerBitmaps.h" #include "Inventor/SmSwitchboard.h" #include "Inventor/SoAutoZoomTranslation.h" diff --git a/src/Gui/SplitView3DInventor.cpp b/src/Gui/SplitView3DInventor.cpp index e21896bf47..76a33b4f7b 100644 --- a/src/Gui/SplitView3DInventor.cpp +++ b/src/Gui/SplitView3DInventor.cpp @@ -34,6 +34,7 @@ #include "SplitView3DInventor.h" #include "Application.h" +#include "Camera.h" #include "Document.h" #include "NavigationStyle.h" #include "SoFCSelectionAction.h" diff --git a/src/Gui/View3DInventor.cpp b/src/Gui/View3DInventor.cpp index 547e313fcc..196a22ad1d 100644 --- a/src/Gui/View3DInventor.cpp +++ b/src/Gui/View3DInventor.cpp @@ -57,6 +57,7 @@ #include "View3DInventor.h" #include "View3DSettings.h" #include "Application.h" +#include "Camera.h" #include "Document.h" #include "FileDialog.h" #include "MainWindow.h" diff --git a/src/Gui/View3DPy.cpp b/src/Gui/View3DPy.cpp index 1c8f8bd29a..2f5608be3e 100644 --- a/src/Gui/View3DPy.cpp +++ b/src/Gui/View3DPy.cpp @@ -52,6 +52,7 @@ #include "View3DPy.h" +#include "Camera.h" #include "Document.h" #include "NavigationStyle.h" #include "PythonWrapper.h" @@ -373,119 +374,6 @@ Py::Object View3DInventorPy::boxZoom(const Py::Tuple& args, const Py::Dict& kwds return Py::None(); } -/** - Formulas to get quaternion for axonometric views: - - \code -from math import sqrt, degrees, asin, atan -p1=App.Rotation(App.Vector(1,0,0),90) -p2=App.Rotation(App.Vector(0,0,1),alpha) -p3=App.Rotation(p2.multVec(App.Vector(1,0,0)),beta) -p4=p3.multiply(p2).multiply(p1) - -from pivy import coin -c=Gui.ActiveDocument.ActiveView.getCameraNode() -c.orientation.setValue(*p4.Q) - \endcode - - The angles alpha and beta depend on the type of axonometry - Isometric: - \code -alpha=45 -beta=degrees(asin(-sqrt(1.0/3.0))) - \endcode - - Dimetric: - \code -alpha=degrees(asin(sqrt(1.0/8.0))) -beta=degrees(-asin(1.0/3.0)) - \endcode - - Trimetric: - \code -alpha=30.0 -beta=-35.0 - \endcode - - Verification code that the axonomtries are correct: - - \code -from pivy import coin -c=Gui.ActiveDocument.ActiveView.getCameraNode() -vo=App.Vector(c.getViewVolume().getMatrix().multVecMatrix(coin.SbVec3f(0,0,0)).getValue()) -vx=App.Vector(c.getViewVolume().getMatrix().multVecMatrix(coin.SbVec3f(10,0,0)).getValue()) -vy=App.Vector(c.getViewVolume().getMatrix().multVecMatrix(coin.SbVec3f(0,10,0)).getValue()) -vz=App.Vector(c.getViewVolume().getMatrix().multVecMatrix(coin.SbVec3f(0,0,10)).getValue()) -(vx-vo).Length -(vy-vo).Length -(vz-vo).Length - -# Projection -vo.z=0 -vx.z=0 -vy.z=0 -vz.z=0 - -(vx-vo).Length -(vy-vo).Length -(vz-vo).Length - \endcode - - See also: - http://www.mathematik.uni-marburg.de/~thormae/lectures/graphics1/graphics_6_2_ger_web.html#1 - http://www.mathematik.uni-marburg.de/~thormae/lectures/graphics1/code_v2/Axonometric/qt/Axonometric.cpp - https://de.wikipedia.org/wiki/Arkussinus_und_Arkuskosinus -*/ - -SbRotation Camera::rotation(Camera::Orientation view) -{ - switch (view) { - case Top: - return SbRotation(0, 0, 0, 1); - case Bottom: - return SbRotation(1, 0, 0, 0); - case Front: { - auto root = (float)(sqrt(2.0)/2.0); - return SbRotation(root, 0, 0, root); - } - case Rear: { - auto root = (float)(sqrt(2.0)/2.0); - return SbRotation(0, root, root, 0); - } - case Left: - return SbRotation(-0.5, 0.5, 0.5, -0.5); - case Right: - return SbRotation(0.5, 0.5, 0.5, 0.5); - case Isometric: - //from math import sqrt, degrees, asin - //p1=App.Rotation(App.Vector(1,0,0),45) - //p2=App.Rotation(App.Vector(0,0,1),-45) - //p3=p2.multiply(p1) - //return SbRotation(0.353553f, -0.146447f, -0.353553f, 0.853553f); - - //from math import sqrt, degrees, asin - //p1=App.Rotation(App.Vector(1,0,0),90) - //p2=App.Rotation(App.Vector(0,0,1),135) - //p3=App.Rotation(App.Vector(-1,1,0),degrees(asin(-sqrt(1.0/3.0)))) - //p4=p3.multiply(p2).multiply(p1) - //return SbRotation(0.17592, 0.424708, 0.820473, 0.339851); - - //from math import sqrt, degrees, asin - //p1=App.Rotation(App.Vector(1,0,0),90) - //p2=App.Rotation(App.Vector(0,0,1),45) - //#p3=App.Rotation(App.Vector(1,1,0),45) - //p3=App.Rotation(App.Vector(1,1,0),degrees(asin(-sqrt(1.0/3.0)))) - //p4=p3.multiply(p2).multiply(p1) - return SbRotation(0.424708f, 0.17592f, 0.339851f, 0.820473f); - case Dimetric: - return SbRotation(0.567952f, 0.103751f, 0.146726f, 0.803205f); - case Trimetric: - return SbRotation(0.446015f, 0.119509f, 0.229575f, 0.856787f); - default: - return SbRotation(0, 0, 0, 1); - } -} - Py::Object View3DInventorPy::viewBottom(const Py::Tuple& args) { if (!PyArg_ParseTuple(args.ptr(), "")) diff --git a/src/Gui/View3DPy.h b/src/Gui/View3DPy.h index 76700d65f0..eb7355207c 100644 --- a/src/Gui/View3DPy.h +++ b/src/Gui/View3DPy.h @@ -35,24 +35,6 @@ namespace Gui { class View3DInventor; -class Camera -{ -public: - enum Orientation { - Top, - Bottom, - Front, - Rear, - Left, - Right, - Isometric, - Dimetric, - Trimetric, - }; - - static SbRotation rotation(Orientation view); -}; - class View3DInventorPy : public Py::PythonExtension { public: