How to rotate around pivot


CAD practitioner

I don't understand how to make multiple transformations or how to rotate around a pivot to get a valid result. I'm not sure if it is a problem with the order in which it should happen or am I misunderstanding things how it is meant to work. The gp_Trsf seems to make one transformation at a time and therefor multiple gp_Trsf must be chained to get the result.

As per documentation of opencascade ( I need to create a gp_Trsf for every transformation and chain them using TopLoc_Location.Multiplied().

This is what I do so far:

TopLoc_Location rotate(TopLoc_Location& world, double angle, int axis, gp_XYZ rotationPosition) {
    gp_Quaternion RX(gp::DX(), 0.);
    gp_Quaternion RY(gp::DY(), 0.);
    gp_Quaternion RZ(gp::DZ(), 0.);

    switch (axis) {
        case 1: RX.Set(gp_Quaternion(gp::DX(), angle / 180 * M_PI)); break;
        case 2: RY.Set(gp_Quaternion(gp::DY(), angle / 180 * M_PI)); break;
        case 3: RZ.Set(gp_Quaternion(gp::DZ(), angle / 180 * M_PI)); break;

    gp_Quaternion RA(RZ * RY * RX);
    gp_Trsf compoundTransform = gp_Trsf(world);
    TopLoc_Location result;

    gp_XYZ compoundPosition = gp_XYZ(compoundTransform.TranslationPart());
    gp_XYZ distanceToPivot = compoundPosition.Subtracted(rotationPosition);

    // 0
    TopLoc_Location compoundPositionLocation = TopLoc_Location(world);

    // 1
    // Bring object which should be rotated to actual rotate position
    gp_Trsf rotationPositionTrsf;
    TopLoc_Location rotationPositionLocation(rotationPositionTrsf);

    // 2
    // The rotation itsself
    gp_Trsf rotationTrsf;
    TopLoc_Location rotationLocation(rotationTrsf);

    // 3
    // Objekt auf die Differenz schieben vom eigentlichen Drehpunkt damit wieder auf Originalposition
    gp_Trsf rotationCompoundDifferenceTrsf;
    TopLoc_Location rotationCompoundDifferenceLocation(rotationCompoundDifferenceTrsf);

    result = compoundPositionLocation * rotationPositionLocation * rotationLocation * rotationCompoundDifferenceLocation;
    return result;

This is the process in screenshots, the red arrow points to the pivot and the yellow to 0,0,0:
it works and looks like this when turning 90 degree on the pivot (25, 758, 33) and looks like this:

When doing the same with the opposite bracket assembly is won't work:
It already has a rotate information which I'm multiplying with when doing the rotate but the offset is not working. I tried quite a few different ways but it does not end in the location where it should be. I also suspect that I didn't understand how the rotation works?

I already had that question on occ forum but digged a little deeper since. If I've got an answer I will reply to both.

Any help or hint is appreciated...



Staff member
Hi mmaenz,

Sorry that did not answer so long…
At last, I understand what your case is and what might be the solution for you.

Example of rotating AIS_Shape around a pivot exists in a ready presentation AIS_Manipulator in OCCT. When you investigate the code of it, I think, you find the solution. The pivot is the position given to the manipulator. Your case is ‘AIS_MM_Rotation’ processing.

The logic that you need to implement (if follow this way) is the next:
1. Preparing gp_Trsf that contains the location and angle. The lines of interest here are:
    case AIS_MM_Rotation:
      const gp_Pnt aPosLoc   = myStartPosition.Location();
      const gp_Ax1 aCurrAxis = getAx1FromAx2Dir (myStartPosition, myCurrentIndex);
      gp_Trsf aNewTrsf;
      aNewTrsf.SetRotation (aCurrAxis, anAngle);
2. Combine this transformation with the transformation of TopoDS_Shape/AIS_Shape. In your model (on attached snapshots), the brackets have own transformation, so you need to combine it with the new transformation. In AIS_Manipulator the code that relates to it is:
 void AIS_Manipulator::Transform (const gp_Trsf& theTrsf)
   const Handle(AIS_InteractiveObject)& anObj = anObjIter.ChangeValue();
   const gp_Trsf& anOldTrsf = aTrsfIter.Value();
   anObj->SetLocalTransformation (theTrsf * anOldTrsf);
Here, if you need to have this transformation in TopoDS_Shape, use setting location of it.

Sample, how the manipulator works, you may found in DRAW of OCCT, or in repository ‘’. It’s discussed in ‘’.

Concerning preparing TopLoc_Location, we usually do not make it by ourselves manually. It is generated by using some of OCCT methods inside. You may think about this class like as a chain of gp_Trsf, you understand it correctly. Here, if you need not the history of the transformations (by some custom reasons), you may prepare only one gp_Trsf and give it to TopoDS_Shape.

Best regards