SOLVED Reset Rotate With Compensate Points?

Hi,

I have a previously related thread but it seems like Rotate is not an option for the modeling command. So I was wondering if I can hack my way through it.

Manually, you can reset rotate with compensate points with the following method (video illustration also below)

  1. Enable Axis
  2. Through the Coordinate Manager (World) set rotation axis to zero. You cant set it through the attribute manager, it won't work.
  3. Disable Axis.

I tried the following code but it doesn't work

# Select an object

c4d.CallCommand(12102) # Enable Axis
obj[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_X] = 0
obj[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_Y] = 0
obj[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_Z] = 0
c4d.CallCommand(12102) # Disable Axis

Video Link (Unable to post videos on forum)
https://www.dropbox.com/s/6sqvydfhot22uqt/c4d313_reset_rotation_compensate.mp4?dl=0

Hi @bentraje this is not possible out of the box you would need to redo the whole logic yourself.
This imply setting the matrix to the new expected rotation, and then compensate all points so it looks like only the axis moved. Then you also need to take care of normal as explained here CAD Normal Tag flipped after Polyon merge (join) and axis repositioning - how realign? and even children objects.

With that's said find bellow a basic example without handling the normal or even children objects. This topic have been asked several times so feel free to search on PluginCafe for something like GetAllPoints or SetAllPoints you will most likely find a lot of similar questions.

import c4d


def main() -> None:
    
    # Get current Matrix
    mg = op.GetMg()
    
    # extracts the scale of the current matrix
    scale = c4d.Vector( mg.v1.GetLength(),
                        mg.v2.GetLength(),
                        mg.v3.GetLength())

    # Builds a new matrix with the expected rotation
    HPB_rot = c4d.Vector()
    m = c4d.utils.HPBToMatrix(HPB_rot)

    m.off = mg.off
    m.v1 = m.v1.GetNormalized() * scale.x
    m.v2 = m.v2.GetNormalized() * scale.y
    m.v3 = m.v3.GetNormalized() * scale.z

    # Applies the new matrix, so scale and position should not change while rotation should be equal to #HPB_rot#
    op.SetMg(m)
    
    # Computes the transformation that happened from initial state to the current state
    transform = ~op.GetMg()*mg
    
    # Transforms all points to compensate the axis change
    transformedPoints: list[c4d.Vector] = [transform * p for p in op.GetAllPoints()]
    op.SetAllPoints(transformedPoints)
    op.Message(c4d.MSG_UPDATE)
    c4d.EventAdd()
    

if __name__ == '__main__':
    main()

Cheers,
Maxime.

@m_adam

Gotcha.
Yea this is my last resort if its possible natively. Hehe.

Thanks for the confirmation and for the pointers to look at.

For some fortunate happpenstance, found a code snippet that does this:

https://gist.github.com/andreberg/885210