Need help on rotation

Hi,

I'm working on a little viewer and actually I have a problem understanding rotation. Out of curiosity I tried V3D_View::Rotate with the angles from spinboxes, but only rotation around X-axis works as expected. Rotation around Y- or Z-axis don't rotate around the axis, but around a centerline between two axis. That results in strange views like "Rotation_weird.jpg".

any way - I want to achieve a different rotation. If I understand things right, V3E_View::Rotation changes camera position, whereas gp_Trsf modifies geometry. I'd like to workout a rotation based on 3 spinboxes, which neither changes geometry, nor camera position. The 3D-model should rotate in place without changing grid position/rotation and every vertices should return the same coordinates as before rotation.

How could I achieve that? I load the model from cad-file, which generates one shape. I then explore the shape to get all faces, which I display in context. But I don't display toplevel shape. The blue box is generated from bounds of toplevel shape, but it's actually unrelated to the faces.

I'd like to rotate only a single object and have all faces follow that transformation. Guess I should implement some relation between faces and boundary box. But how?

Kirill Gavrilov's picture

If you want to rotate the camera - rotate Graphic3d_Camera object, which is returned by V3d_View::Camera() method. If you want to rotate an object - compute local transformation to it with AIS_InteractiveContext::SetLocation() or similar. If you display multiple interactive objects that should follow some common transformation - just assign it to all objects.

DjangoReinhard's picture

Thank you for your support!

Rotating camera looks a bit better, but does not work with absolute angle values. Context::SetLocation looks like what I was looking for. Especially in combination with Context::ResetLocation. But as predicted, gp_Trsf changes geometry values, so curve position and other parameters are useless (for me) after rotation.

Is there a way to access unrotated curve parameters? ... or is there a way to keep an invisible original and rotate a visual copy?

Kirill Gavrilov's picture

Rotating camera looks a bit better, but does not work with absolute angle values.

You may define your initial camera orientation and apply transformation to it. Rotation part of gp_Trsf could be initialized from gp_Quaternion, which can be initialized from gp_EulerSequence, if you prefer using angles.

DjangoReinhard's picture

Thank you for your attention!

I stil don't really understand, what's going on with rotation. I change camera position by buttons and V3d_View::SetProj(V3d_XposYnegZpos) or the like. That works fine.

With the model I have one problem, that import from step has different orientation as import from brep. So I need to rotate and possibly translate model for initial position. I would like to save/register that position/rotation as my initial state, that becomes active after a call to ResetLocation.

After having set the initial position, model can be rotated by any axis. That does not really work as expected. I painted 3 lines as axis before importing the model. Those axis will be rotated with the model. When I i.e. rotate the model around Y-axis by 90° - any following rotation around X- or Z-axis rotate the model in the same way. So no rotation around X- or Z-axis anymore.

My code is this:

void OcctQtViewer::rotate(double dA, double dB, double dC) {
  qDebug() << "OcctQtViewer::rotate(" << dA << "/" << dB << "/" << dC << ")";
  gp_Trsf  rotX, rotY, rotZ;

  rotX.SetRotation(gp_Ax1({0, 0, 0}, {1, 0, 0}), dA);
  rotY.SetRotation(gp_Ax1({0, 0, 0}, {0, 1, 0}), dB);
  rotZ.SetRotation(gp_Ax1({0, 0, 0}, {0, 0, 1}), dC);
  TopLoc_Location       rotAll(rotX * rotY * rotZ);
  AIS_ListOfInteractive shapes;

  myContext->DisplayedObjects(shapes);
  for (Handle(AIS_InteractiveObject)& s : shapes) {
      qDebug() << s->get_type_name();
      if (s->DynamicType() == STANDARD_TYPE(AIS_ViewCube)) continue;
      myContext->SetLocation(s, rotAll);
      }
  myView->Invalidate();
  update();
  }

How can I do better?

Please forgive me for not understanding euler-wikipedia. I am not a mathematician. If you know some prose for laymen, I would devour it with pleasure.

Attachments: