def match_rotation(source, target): """ Matches the rotation from source to target Params: source :: MODO item - Source item target :: MODO item - Target item """ source_item = get_item(source) target_item = get_item(target) # Reset TARGET rotation to get Rotation Zero values, and then # negate the rotation from the SOURCE world rotation matrix target_item.rotation.set((0, 0, 0)) target_zero_rot = modo.Matrix4( target_item.channel(WORLD_ROT_MATRIX_CHANNEL).get()) source_rot = modo.Matrix4( source_item.channel(WORLD_ROT_MATRIX_CHANNEL).get()) final_rot = source_rot * target_zero_rot.inverted() target_item.rotation.set(final_rot.asEuler(True), None, False, 'edit', True)
def __init__(self, cryexport_node): self.cryexport_node = cryexport_node self.scene_root = lx.eval1("query sceneservice scene.file ? current") if not self.scene_root: modo.dialogs.alert("Save File", "Please save file before exporting.") sys.exit() self.path = os.path.join( os.path.dirname(self.scene_root), self.collada_temp_path ) self.wpos_matrix = modo.Matrix4(self.cryexport_node.channel("wposMatrix").get()) self.submats = utils.get_submats_from_cryexport_node(self.cryexport_node) self.neat_name = self.cryexport_node.name.replace(_c.CRYEXPORTNODE_PREFIX, "") self.file_type = ( "1" if self.cryexport_node.channel(_c.CHANNEL_FILETYPE_NAME) is None else self.cryexport_node.channel(_c.CHANNEL_FILETYPE_NAME).get() ) self.exportable = ( "1" if self.cryexport_node.channel(_c.CHANNEL_EXPORTABLE_NAME) is None else self.cryexport_node.channel(_c.CHANNEL_EXPORTABLE_NAME).get() ) self.merge_objects = ( "0" if self.cryexport_node.channel(_c.CHANNEL_MERGE_OBJECTS_NAME) is None else self.cryexport_node.channel(_c.CHANNEL_MERGE_OBJECTS_NAME).get() ) self.groups = utils.get_groups_from_cryexport_node(self.cryexport_node)
def basic_Execute(self, msg, flags): # Get the value of our 'clear' argument, defaulting to 1 if it was not passed doClear = self.dyna_Int(0, 1) # Get the current scene scn = modo.Scene() # Iterate all selected items that have locator as super type for loc in scn.selectedByType(modo.c.LOCATOR_TYPE, superType=True): # Create list of rotation items # We assume the rotation item's index is the one following the the zero's index rotationItems = [t for t in loc.transforms if t.type == 'rotation'] # Find the zero rotation item zeroItem = next( (t for t in rotationItems if 'Rotation Zero' in t.name), None) if zeroItem: index = rotationItems.index(zeroItem) # Find the next transform item and verify that it is a rotation if len(rotationItems) >= index: rotation = rotationItems[index + 1] if not rotation.type == 'rotation': continue matZero = modo.Matrix4(zeroItem.channel('matrix').get()) matRot = modo.Matrix4(rotation.channel('matrix').get()) if doClear: # Multiply the matrices to get a single rotation matResult = matRot * matZero # Clear the zero item's rotation and set the rotation item values zeroItem.set((0, 0, 0)) rotation.set(matResult.asEuler()) else: # Multiply the matrices to get a single rotation matResult = matRot * matZero # Clear the rotation and apply the values to the zero rotation rotation.set((0, 0, 0)) zeroItem.set(matResult.asEuler())
def make_rotation_elements(self, node): m = modo.Matrix4(node.channel("worldMatrix").get()) x, y, z, rest = m.asRotateMatrix() return [ E.rotate({"sid": "rotation_z"}, utils.vtos(z)), E.rotate({"sid": "rotation_y"}, utils.vtos(y)), E.rotate({"sid": "rotation_x"}, utils.vtos(x)), ]
def match_translation(source, target): """ Matches the translation from source to target Params: source :: MODO item - Source item target :: MODO item - Target item """ source_item = get_item(source) target_item = get_item(target) # Reset TARGET position to get Position Zero values, and then # negate the translation from the SOURCE world position matrix target_item.position.set((0, 0, 0)) target_zero_pos = modo.Matrix4( target_item.channel(WORLD_POS_MATRIX_CHANNEL).get()) source_pos = modo.Matrix4( source_item.channel(WORLD_POS_MATRIX_CHANNEL).get()) final_pos = source_pos * target_zero_pos.inverted() target_item.position.set(final_pos.position)
# For these parts we will use TD-SDK scene = modo.Scene() itemSelected_ID = scene.selected selected_N = len(itemSelected_ID) fn_narrowAmount() for eachItem_ID in itemSelected_ID: # NOTE: Using worldMatrix(4) to get World Rotation gives us bad results when item is also scaled. # For that reason I used wrotMatrix(3) just for Rotation. See these posts: # http://community.foundry.com/discuss/topic/136620/convert-3x3-matrix-to-rotx-roty-rotz-solved # http://community.foundry.com/discuss/topic/136730/how-to-get-world-item-position-and-scale-using-td-sdk worldMatrix4 = modo.Matrix4(eachItem_ID.channel('worldMatrix').get()) wrotMatrix3 = modo.Matrix3(eachItem_ID.channel('wrotMatrix').get()) eachItem_P = worldMatrix4.position eachItem_R = wrotMatrix3.asEuler(degrees=True, order='zxy') eachItem_S = worldMatrix4.scale() # eachItem_R = worldMatrix4.asEuler(degrees=True, order='zxy') # This gives bad results when item is also Scaled # Create a locator, size 0 lx.eval('item.create locator') lx.eval('item.channel locator$size 0.0') # Change pos, rot and scale for our locator to match the item lx.eval('transform.channel pos.X {%s}' % eachItem_P[0]) lx.eval('transform.channel pos.Y {%s}' % eachItem_P[1]) lx.eval('transform.channel pos.Z {%s}' % eachItem_P[2])
def make_scale_element(self, node): m = modo.Matrix4(node.channel("worldMatrix").get()) return E.scale({"sid": "scale"}, utils.vtos(m.scale()))
def make_translate_element(self, node): m = modo.Matrix4(node.channel("worldMatrix").get()) return E.translate({"sid": "translation"}, utils.vtos(m.position))