Gui: Added classic trackball orbit style (#20535)
* Gui: add classic trackball orbit * Gui: add rounded arcball orbit
This commit is contained in:
@@ -64,7 +64,9 @@ public:
|
||||
enum OrbitStyle {
|
||||
Turntable,
|
||||
Trackball,
|
||||
FreeTurntable
|
||||
FreeTurntable,
|
||||
TrackballClassic,
|
||||
RoundedArcball
|
||||
};
|
||||
|
||||
static constexpr float defaultSphereRadius = 0.8F;
|
||||
@@ -87,7 +89,112 @@ public:
|
||||
|
||||
SbVec3f project(const SbVec2f &point) override
|
||||
{
|
||||
return inherited::project(point);
|
||||
if (orbit != RoundedArcball) {
|
||||
return inherited::project(point);
|
||||
}
|
||||
|
||||
// Rounded Arcball implementation
|
||||
// based on SbSphereSheetProjector in Open Inventor
|
||||
SbVec3f result;
|
||||
SbLine workingLine = getWorkingLine(point);
|
||||
|
||||
if (needSetup) {
|
||||
setupPlane();
|
||||
}
|
||||
|
||||
SbVec3f planeIntersection;
|
||||
|
||||
SbVec3f sphereIntersection, dontCare;
|
||||
SbBool hitSphere;
|
||||
if (intersectFront == TRUE) {
|
||||
hitSphere = sphere.intersect(workingLine, sphereIntersection, dontCare);
|
||||
}
|
||||
else {
|
||||
hitSphere = sphere.intersect(workingLine, dontCare, sphereIntersection);
|
||||
}
|
||||
|
||||
if (hitSphere) {
|
||||
// drop the sphere intersection onto the tolerance plane
|
||||
|
||||
SbLine projectLine(sphereIntersection, sphereIntersection + planeDir);
|
||||
if (!tolPlane.intersect(projectLine, planeIntersection))
|
||||
#ifdef DEBUG
|
||||
SoDebugError::post("SbSphereSheetProjector::project",
|
||||
"Couldn't intersect working line with plane");
|
||||
#else
|
||||
/* Do nothing */;
|
||||
#endif
|
||||
}
|
||||
else if (!tolPlane.intersect(workingLine, planeIntersection))
|
||||
#ifdef DEBUG
|
||||
SoDebugError::post("SbSphereSheetProjector::project", "Couldn't intersect with plane");
|
||||
#else
|
||||
/* Do nothing */;
|
||||
#endif
|
||||
|
||||
// Three possibilities:
|
||||
// (1) Intersection is on the sphere inside where the fillet
|
||||
// hits it
|
||||
// (2) Intersection is on the fillet
|
||||
// (3) Intersection is on the plane
|
||||
float distance = (planeIntersection - planePoint).length();
|
||||
|
||||
// Amount of filleting
|
||||
// 0 = no fillet (just sphere and plane)
|
||||
// infinity = only fillet
|
||||
float border = 0.5;
|
||||
|
||||
// Radius where the fillet meets the plane in "squished space"
|
||||
float r_a = 1.0F + border;
|
||||
// Radius where the sphere meets the fillet in "squished space"
|
||||
float r_i = 2.0 / (r_a + 1.0 / r_a);
|
||||
|
||||
// Distance squared in "squished space"
|
||||
float d_2 = (distance * distance) * r_a * r_a;
|
||||
// Distance in "squished space"
|
||||
float d = std::sqrt(d_2);
|
||||
|
||||
// Compute how far off the plane we are
|
||||
float offsetDist = 0.0;
|
||||
|
||||
if (d > r_a) {
|
||||
// On the plane
|
||||
offsetDist = 0.0;
|
||||
}
|
||||
else if (d < r_i) {
|
||||
// On the sphere inside the fillet
|
||||
offsetDist = std::sqrt(1.0 - d_2);
|
||||
}
|
||||
else {
|
||||
// On the fillet
|
||||
float d_r = r_a - d;
|
||||
float a = border * (1.0 + border / 2.0);
|
||||
offsetDist = a - std::sqrt((a + d_r) * (a - d_r));
|
||||
}
|
||||
|
||||
SbVec3f offset;
|
||||
if (orientToEye) {
|
||||
if (viewVol.getProjectionType() == SbViewVolume::PERSPECTIVE) {
|
||||
offset = workingProjPoint - planeIntersection;
|
||||
}
|
||||
else {
|
||||
worldToWorking.multDirMatrix(viewVol.zVector(), offset);
|
||||
}
|
||||
|
||||
offset.normalize();
|
||||
}
|
||||
else {
|
||||
offset.setValue(0, 0, 1);
|
||||
}
|
||||
if (intersectFront == FALSE) {
|
||||
offset *= -1.0;
|
||||
}
|
||||
|
||||
offset *= offsetDist;
|
||||
result = planeIntersection + offset;
|
||||
|
||||
lastPoint = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
SbRotation getRotation(const SbVec3f &point1, const SbVec3f &point2) override
|
||||
@@ -99,6 +206,9 @@ public:
|
||||
if (orbit == FreeTurntable) {
|
||||
return getFreeTurntable(point1, point2);
|
||||
}
|
||||
if (orbit == TrackballClassic) {
|
||||
return getTrackballClassic(point1, point2);
|
||||
}
|
||||
|
||||
return rot;
|
||||
}
|
||||
@@ -164,6 +274,22 @@ private:
|
||||
return zrot * xrot;
|
||||
}
|
||||
|
||||
SbRotation getTrackballClassic(const SbVec3f &point1, const SbVec3f &point2) const
|
||||
{
|
||||
// Classic trackball
|
||||
SbRotation zrot;
|
||||
SbRotation yrot;
|
||||
SbVec3f dif = point1 - point2;
|
||||
|
||||
SbVec3f zaxis(1,0,0);
|
||||
zrot.setValue(zaxis, dif[1]);
|
||||
|
||||
SbVec3f yaxis(0,1,0);
|
||||
yrot.setValue(yaxis, -dif[0]);
|
||||
|
||||
return zrot * yrot;
|
||||
}
|
||||
|
||||
private:
|
||||
SbMatrix worldToScreen;
|
||||
OrbitStyle orbit{Trackball};
|
||||
@@ -415,7 +541,7 @@ std::shared_ptr<NavigationAnimation> NavigationStyle::setCameraOrientation(const
|
||||
}
|
||||
|
||||
// or set the pose directly
|
||||
|
||||
|
||||
// Distance from rotation center to camera position in camera coordinate system
|
||||
const SbVec3f rotationCenterDistanceCam = camera->focalDistance.getValue() * SbVec3f(0, 0, 1);
|
||||
|
||||
@@ -447,7 +573,7 @@ std::shared_ptr<NavigationAnimation> NavigationStyle::translateCamera(const SbVe
|
||||
}
|
||||
|
||||
// or set the pose directly
|
||||
|
||||
|
||||
camera->position = camera->position.getValue() + translation;
|
||||
|
||||
return {};
|
||||
@@ -580,21 +706,21 @@ void NavigationStyle::reorientCamera(SoCamera* camera, const SbRotation& rotatio
|
||||
// Fix issue with near clipping in orthogonal view
|
||||
if (camera->getTypeId().isDerivedFrom(SoOrthographicCamera::getClassTypeId())) {
|
||||
|
||||
// The center of the bounding sphere in camera coordinate system
|
||||
SbVec3f center;
|
||||
// The center of the bounding sphere in camera coordinate system
|
||||
SbVec3f center;
|
||||
camera->orientation.getValue().inverse().multVec(boundingSphere.getCenter() - camera->position.getValue(), center);
|
||||
|
||||
SbVec3f dir;
|
||||
camera->orientation.getValue().multVec(SbVec3f(0, 0, -1), dir);
|
||||
SbVec3f dir;
|
||||
camera->orientation.getValue().multVec(SbVec3f(0, 0, -1), dir);
|
||||
|
||||
// Reposition the camera but keep the focal point the same
|
||||
// nearDistance is 0 and farDistance is the diameter of the bounding sphere
|
||||
float repositionDistance = -center.getValue()[2] - boundingSphere.getRadius();
|
||||
camera->position = camera->position.getValue() + repositionDistance * dir;
|
||||
camera->nearDistance = 0;
|
||||
camera->farDistance = 2 * boundingSphere.getRadius() + 1;
|
||||
camera->focalDistance = camera->focalDistance.getValue() - repositionDistance;
|
||||
}
|
||||
// Reposition the camera but keep the focal point the same
|
||||
// nearDistance is 0 and farDistance is the diameter of the bounding sphere
|
||||
float repositionDistance = -center.getValue()[2] - boundingSphere.getRadius();
|
||||
camera->position = camera->position.getValue() + repositionDistance * dir;
|
||||
camera->nearDistance = 0;
|
||||
camera->farDistance = 2 * boundingSphere.getRadius() + 1;
|
||||
camera->focalDistance = camera->focalDistance.getValue() - repositionDistance;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -687,13 +813,13 @@ void NavigationStyle::zoom(SoCamera * cam, float diffvalue)
|
||||
// frustum (similar to glFrustum())
|
||||
if (!t.isDerivedFrom(SoPerspectiveCamera::getClassTypeId()) &&
|
||||
tname != "FrustumCamera") {
|
||||
/* static SbBool first = true;
|
||||
if (first) {
|
||||
SoDebugError::postWarning("SoGuiFullViewerP::zoom",
|
||||
"Unknown camera type, "
|
||||
/* static SbBool first = true;
|
||||
if (first) {
|
||||
SoDebugError::postWarning("SoGuiFullViewerP::zoom",
|
||||
"Unknown camera type, "
|
||||
"will zoom by moving position, but this might not be correct.");
|
||||
first = false;
|
||||
}*/
|
||||
}*/
|
||||
}
|
||||
|
||||
const float oldfocaldist = cam->focalDistance.getValue();
|
||||
@@ -888,7 +1014,9 @@ void NavigationStyle::spin(const SbVec2f & pointerpos)
|
||||
float sensitivity = getSensitivity();
|
||||
|
||||
// Adjust the spin projector sphere to the screen position of the rotation center when the mouse intersects an object
|
||||
if (getOrbitStyle() == Trackball && rotationCenterMode & RotationCenterMode::ScenePointAtCursor && rotationCenterFound && rotationCenterIsScenePointAtCursor) {
|
||||
if ((getOrbitStyle() == Trackball || getOrbitStyle() == TrackballClassic || getOrbitStyle() == RoundedArcball)
|
||||
&& rotationCenterMode & RotationCenterMode::ScenePointAtCursor && rotationCenterFound
|
||||
&& rotationCenterIsScenePointAtCursor) {
|
||||
const auto pointOnScreen = viewer->getPointOnViewport(rotationCenter);
|
||||
const auto sphereCenter = 2 * normalizePixelPos(pointOnScreen) - SbVec2f {1, 1};
|
||||
|
||||
@@ -1293,23 +1421,23 @@ void NavigationStyle::startSelection(NavigationStyle::SelectionMode mode)
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case Lasso:
|
||||
mouseSelection = new PolyPickerSelection();
|
||||
break;
|
||||
case Rectangle:
|
||||
mouseSelection = new RectangleSelection();
|
||||
break;
|
||||
case Rubberband:
|
||||
mouseSelection = new RubberbandSelection();
|
||||
break;
|
||||
case BoxZoom:
|
||||
mouseSelection = new BoxZoomSelection();
|
||||
break;
|
||||
case Clip:
|
||||
mouseSelection = new PolyClipSelection();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case Lasso:
|
||||
mouseSelection = new PolyPickerSelection();
|
||||
break;
|
||||
case Rectangle:
|
||||
mouseSelection = new RectangleSelection();
|
||||
break;
|
||||
case Rubberband:
|
||||
mouseSelection = new RubberbandSelection();
|
||||
break;
|
||||
case BoxZoom:
|
||||
mouseSelection = new BoxZoomSelection();
|
||||
break;
|
||||
case Clip:
|
||||
mouseSelection = new PolyClipSelection();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (mouseSelection)
|
||||
@@ -1344,7 +1472,7 @@ SbBool NavigationStyle::isSelecting() const
|
||||
const std::vector<SbVec2s>& NavigationStyle::getPolygon(SelectionRole* role) const
|
||||
{
|
||||
if (role)
|
||||
*role = this->selectedRole;
|
||||
*role = this->selectedRole;
|
||||
return pcPolygon;
|
||||
}
|
||||
|
||||
@@ -1420,59 +1548,59 @@ void NavigationStyle::setViewingMode(const ViewerMode newmode)
|
||||
}
|
||||
|
||||
switch (newmode) {
|
||||
case DRAGGING:
|
||||
// Set up initial projection point for the projector object when
|
||||
// first starting a drag operation.
|
||||
animator->stop();
|
||||
viewer->showRotationCenter(true);
|
||||
case DRAGGING:
|
||||
// Set up initial projection point for the projector object when
|
||||
// first starting a drag operation.
|
||||
animator->stop();
|
||||
viewer->showRotationCenter(true);
|
||||
|
||||
#if (COIN_MAJOR_VERSION * 100 + COIN_MINOR_VERSION * 10 + COIN_MICRO_VERSION < 403)
|
||||
findBoundingSphere();
|
||||
findBoundingSphere();
|
||||
#endif
|
||||
|
||||
this->spinprojector->project(this->lastmouseposition);
|
||||
this->interactiveCountInc();
|
||||
this->clearLog();
|
||||
break;
|
||||
this->spinprojector->project(this->lastmouseposition);
|
||||
this->interactiveCountInc();
|
||||
this->clearLog();
|
||||
break;
|
||||
|
||||
case SPINNING:
|
||||
this->interactiveCountInc();
|
||||
viewer->getSoRenderManager()->scheduleRedraw();
|
||||
break;
|
||||
case SPINNING:
|
||||
this->interactiveCountInc();
|
||||
viewer->getSoRenderManager()->scheduleRedraw();
|
||||
break;
|
||||
|
||||
case PANNING:
|
||||
animator->stop();
|
||||
setupPanningPlane(viewer->getSoRenderManager()->getCamera());
|
||||
this->interactiveCountInc();
|
||||
break;
|
||||
case PANNING:
|
||||
animator->stop();
|
||||
setupPanningPlane(viewer->getSoRenderManager()->getCamera());
|
||||
this->interactiveCountInc();
|
||||
break;
|
||||
|
||||
case ZOOMING:
|
||||
animator->stop();
|
||||
this->interactiveCountInc();
|
||||
break;
|
||||
case ZOOMING:
|
||||
animator->stop();
|
||||
this->interactiveCountInc();
|
||||
break;
|
||||
|
||||
case BOXZOOM:
|
||||
animator->stop();
|
||||
this->interactiveCountInc();
|
||||
break;
|
||||
case BOXZOOM:
|
||||
animator->stop();
|
||||
this->interactiveCountInc();
|
||||
break;
|
||||
|
||||
default: // include default to avoid compiler warnings.
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (oldmode) {
|
||||
case SPINNING:
|
||||
case DRAGGING:
|
||||
viewer->showRotationCenter(false);
|
||||
[[fallthrough]];
|
||||
case PANNING:
|
||||
case ZOOMING:
|
||||
case BOXZOOM:
|
||||
this->interactiveCountDec();
|
||||
break;
|
||||
case SPINNING:
|
||||
case DRAGGING:
|
||||
viewer->showRotationCenter(false);
|
||||
[[fallthrough]];
|
||||
case PANNING:
|
||||
case ZOOMING:
|
||||
case BOXZOOM:
|
||||
this->interactiveCountDec();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
viewer->setCursorRepresentation(newmode);
|
||||
@@ -1569,20 +1697,20 @@ void NavigationStyle::syncWithEvent(const SoEvent * const ev)
|
||||
auto const event = static_cast<const SoKeyboardEvent *>(ev);
|
||||
const SbBool press = event->getState() == SoButtonEvent::DOWN ? true : false;
|
||||
switch (event->getKey()) {
|
||||
case SoKeyboardEvent::LEFT_CONTROL:
|
||||
case SoKeyboardEvent::RIGHT_CONTROL:
|
||||
this->ctrldown = press;
|
||||
break;
|
||||
case SoKeyboardEvent::LEFT_SHIFT:
|
||||
case SoKeyboardEvent::RIGHT_SHIFT:
|
||||
this->shiftdown = press;
|
||||
break;
|
||||
case SoKeyboardEvent::LEFT_ALT:
|
||||
case SoKeyboardEvent::RIGHT_ALT:
|
||||
this->altdown = press;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case SoKeyboardEvent::LEFT_CONTROL:
|
||||
case SoKeyboardEvent::RIGHT_CONTROL:
|
||||
this->ctrldown = press;
|
||||
break;
|
||||
case SoKeyboardEvent::LEFT_SHIFT:
|
||||
case SoKeyboardEvent::RIGHT_SHIFT:
|
||||
this->shiftdown = press;
|
||||
break;
|
||||
case SoKeyboardEvent::LEFT_ALT:
|
||||
case SoKeyboardEvent::RIGHT_ALT:
|
||||
this->altdown = press;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1594,17 +1722,17 @@ void NavigationStyle::syncWithEvent(const SoEvent * const ev)
|
||||
|
||||
// SoDebugError::postInfo("processSoEvent", "button = %d", button);
|
||||
switch (button) {
|
||||
case SoMouseButtonEvent::BUTTON1:
|
||||
this->button1down = press;
|
||||
break;
|
||||
case SoMouseButtonEvent::BUTTON2:
|
||||
this->button2down = press;
|
||||
break;
|
||||
case SoMouseButtonEvent::BUTTON3:
|
||||
this->button3down = press;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case SoMouseButtonEvent::BUTTON1:
|
||||
this->button1down = press;
|
||||
break;
|
||||
case SoMouseButtonEvent::BUTTON2:
|
||||
this->button2down = press;
|
||||
break;
|
||||
case SoMouseButtonEvent::BUTTON3:
|
||||
this->button3down = press;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1645,43 +1773,43 @@ SbBool NavigationStyle::processKeyboardEvent(const SoKeyboardEvent * const event
|
||||
SbBool processed = false;
|
||||
const SbBool press = event->getState() == SoButtonEvent::DOWN ? true : false;
|
||||
switch (event->getKey()) {
|
||||
case SoKeyboardEvent::LEFT_CONTROL:
|
||||
case SoKeyboardEvent::RIGHT_CONTROL:
|
||||
this->ctrldown = press;
|
||||
break;
|
||||
case SoKeyboardEvent::LEFT_SHIFT:
|
||||
case SoKeyboardEvent::RIGHT_SHIFT:
|
||||
this->shiftdown = press;
|
||||
break;
|
||||
case SoKeyboardEvent::LEFT_ALT:
|
||||
case SoKeyboardEvent::RIGHT_ALT:
|
||||
this->altdown = press;
|
||||
break;
|
||||
case SoKeyboardEvent::S:
|
||||
case SoKeyboardEvent::HOME:
|
||||
case SoKeyboardEvent::LEFT_ARROW:
|
||||
case SoKeyboardEvent::UP_ARROW:
|
||||
case SoKeyboardEvent::RIGHT_ARROW:
|
||||
case SoKeyboardEvent::DOWN_ARROW:
|
||||
case SoKeyboardEvent::LEFT_CONTROL:
|
||||
case SoKeyboardEvent::RIGHT_CONTROL:
|
||||
this->ctrldown = press;
|
||||
break;
|
||||
case SoKeyboardEvent::LEFT_SHIFT:
|
||||
case SoKeyboardEvent::RIGHT_SHIFT:
|
||||
this->shiftdown = press;
|
||||
break;
|
||||
case SoKeyboardEvent::LEFT_ALT:
|
||||
case SoKeyboardEvent::RIGHT_ALT:
|
||||
this->altdown = press;
|
||||
break;
|
||||
case SoKeyboardEvent::S:
|
||||
case SoKeyboardEvent::HOME:
|
||||
case SoKeyboardEvent::LEFT_ARROW:
|
||||
case SoKeyboardEvent::UP_ARROW:
|
||||
case SoKeyboardEvent::RIGHT_ARROW:
|
||||
case SoKeyboardEvent::DOWN_ARROW:
|
||||
if (!this->isViewing())
|
||||
this->setViewing(true);
|
||||
break;
|
||||
this->setViewing(true);
|
||||
break;
|
||||
case SoKeyboardEvent::PAGE_UP:
|
||||
{
|
||||
processed = true;
|
||||
const SbVec2f posn = normalizePixelPos(event->getPosition());
|
||||
doZoom(viewer->getSoRenderManager()->getCamera(), getDelta(), posn);
|
||||
break;
|
||||
}
|
||||
processed = true;
|
||||
const SbVec2f posn = normalizePixelPos(event->getPosition());
|
||||
doZoom(viewer->getSoRenderManager()->getCamera(), getDelta(), posn);
|
||||
break;
|
||||
}
|
||||
case SoKeyboardEvent::PAGE_DOWN:
|
||||
{
|
||||
processed = true;
|
||||
const SbVec2f posn = normalizePixelPos(event->getPosition());
|
||||
doZoom(viewer->getSoRenderManager()->getCamera(), -getDelta(), posn);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
processed = true;
|
||||
const SbVec2f posn = normalizePixelPos(event->getPosition());
|
||||
doZoom(viewer->getSoRenderManager()->getCamera(), -getDelta(), posn);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return processed;
|
||||
|
||||
@@ -103,7 +103,9 @@ public:
|
||||
enum OrbitStyle {
|
||||
Turntable,
|
||||
Trackball,
|
||||
FreeTurntable
|
||||
FreeTurntable,
|
||||
TrackballClassic,
|
||||
RoundedArcball,
|
||||
};
|
||||
|
||||
enum class RotationCenterMode {
|
||||
|
||||
@@ -475,7 +475,9 @@ Select a set and then press the button to view said configurations.</string>
|
||||
<string>Rotation orbit style.
|
||||
Trackball: moving the mouse horizontally will rotate the part around the y-axis
|
||||
Turntable: the part will be rotated around the z-axis (with constrained axes).
|
||||
Free Turntable: the part will be rotated around the z-axis.</string>
|
||||
Free Turntable: the part will be rotated around the z-axis.
|
||||
Trackball Classic: moving the mouse will rotate the part allowing precession
|
||||
Rounded Arcball: moving the mouse in the corners of the screen will only roll the part.</string>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
@@ -495,6 +497,16 @@ Free Turntable: the part will be rotated around the z-axis.</string>
|
||||
<string>Free Turntable</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Trackball Classic</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Rounded Arcball</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
|
||||
@@ -612,6 +612,8 @@ def retranslateUi():
|
||||
aTurntable.setText(translate("NavigationIndicator", "Turntable"))
|
||||
aFreeTurntable.setText(translate("NavigationIndicator", "Free Turntable"))
|
||||
aTrackball.setText(translate("NavigationIndicator", "Trackball"))
|
||||
aTrackballClassic.setText(translate("NavigationIndicator", "Trackball Classic"))
|
||||
aRoundedArcball.setText(translate("NavigationIndicator", "Rounded Arcball"))
|
||||
a0.setText(translate("NavigationIndicator", "Undefined"))
|
||||
|
||||
|
||||
@@ -648,10 +650,18 @@ aTrackball.setCheckable(True)
|
||||
aFreeTurntable = QtGui.QAction(gOrbit)
|
||||
aFreeTurntable.setObjectName("NavigationIndicator_FreeTurntable")
|
||||
aFreeTurntable.setCheckable(True)
|
||||
aTrackballClassic = QtGui.QAction(gOrbit)
|
||||
aTrackballClassic.setObjectName("NavigationIndicator_TrackballClassic")
|
||||
aTrackballClassic.setCheckable(True)
|
||||
aRoundedArcball = QtGui.QAction(gOrbit)
|
||||
aRoundedArcball.setObjectName("NavigationIndicator_RoundedArcball")
|
||||
aRoundedArcball.setCheckable(True)
|
||||
|
||||
menuOrbit.addAction(aTurntable)
|
||||
menuOrbit.addAction(aTrackball)
|
||||
menuOrbit.addAction(aFreeTurntable)
|
||||
menuOrbit.addAction(aTrackballClassic)
|
||||
menuOrbit.addAction(aRoundedArcball)
|
||||
|
||||
menuSettings.addMenu(menuOrbit)
|
||||
menuSettings.addSeparator()
|
||||
@@ -795,6 +805,10 @@ def onOrbit():
|
||||
pView.SetInt("OrbitStyle", 1)
|
||||
elif aFreeTurntable.isChecked():
|
||||
pView.SetInt("OrbitStyle", 2)
|
||||
elif aTrackballClassic.isChecked():
|
||||
pView.SetInt("OrbitStyle", 3)
|
||||
elif aRoundedArcball.isChecked():
|
||||
pView.SetInt("OrbitStyle", 4)
|
||||
|
||||
|
||||
def onOrbitShow():
|
||||
@@ -808,6 +822,10 @@ def onOrbitShow():
|
||||
aTrackball.setChecked(True)
|
||||
elif OrbitStyle == 2:
|
||||
aFreeTurntable.setChecked(True)
|
||||
elif OrbitStyle == 3:
|
||||
aTrackballClassic.setChecked(True)
|
||||
elif OrbitStyle == 4:
|
||||
aRoundedArcball.setChecked(True)
|
||||
gOrbit.blockSignals(False)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user