Change Rooms Level

# -*- coding: utf-8 -*-

# ╦╔╦╗╔═╗╔═╗╦═╗╔╦╗╔═╗
# ║║║║╠═╝║ ║╠╦╝ ║ ╚═╗
# ╩╩ ╩╩  ╚═╝╩╚═ ╩ ╚═╝ IMPORTS
#==================================================
from Autodesk.Revit.DB import *
from Autodesk.Revit.UI.Selection import ObjectType, PickBoxStyle, Selection, ISelectionFilter
from pyrevit import forms

# .NET Imports
import clr
clr.AddReference("System")
from System.Collections.Generic import List
from Snippets._convert import convert_internal_units

# ╦  ╦╔═╗╦═╗╦╔═╗╔╗ ╦  ╔═╗╔═╗
# ╚╗╔╝╠═╣╠╦╝║╠═╣╠╩╗║  ║╣ ╚═╗
#  ╚╝ ╩ ╩╩╚═╩╩ ╩╚═╝╩═╝╚═╝╚═╝ VARIABLES
#==================================================
uidoc = __revit__.ActiveUIDocument
doc   = __revit__.ActiveUIDocument.Document
selection = uidoc.Selection # type: Selection

all_rooms = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms).WhereElementIsNotElementType().ToElements()
all_level  = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Levels).WhereElementIsNotElementType().ToElements()


# ╔═╗╦ ╦╔╗╔╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
# ╠╣ ║ ║║║║║   ║ ║║ ║║║║╚═╗
# ╚  ╚═╝╝╚╝╚═╝ ╩ ╩╚═╝╝╚╝╚═╝
#==================================================

def select_desired_levels():
    """Select Levels From and To"""
    all_room_level_ids = {r.LevelId for r in all_rooms}
    room_dict_levels = {doc.GetElement(lvl_id).Name: doc.GetElement(lvl_id) for lvl_id in all_room_level_ids if lvl_id != ElementId(-1)}
    all_dict_levels = {lvl.Name: lvl for lvl in all_level}

    try:
        from rpw.ui.forms import (FlexForm, ComboBox, Separator, Button, CheckBox, Label)
        components = [Label('Get Rooms From Level'),
                      ComboBox('level_from', room_dict_levels),
                      Label('Move to New Level:'),
                      ComboBox('level_to', all_dict_levels),
                      Separator(),
                      Button('Change Room Levels')]
        form = FlexForm(__title__, components)
        form.show()
        return form.values
    except:
        forms.alert('Could not get User Input. Please Try Again.', title=__title__, exitscript=True)

class UnplacedRoomWarning(IFailuresPreprocessor):
    def PreprocessFailures(self, failuresAccessor):
        failures = failuresAccessor.GetFailureMessages()

        for failure in failures:
            if failure.GetSeverity() == FailureSeverity.Warning:
                if failure.GetFailureDefinitionId() == BuiltInFailures.RoomFailures.RoomUnplaceWarning or \
                   failure.GetFailureDefinitionId() == BuiltInFailures.RoomFailures.RoomHeightNegative:
                    failuresAccessor.DeleteWarning(failure)
            else:
                failuresAccessor.ResolveFailure(failure)
                return FailureProcessingResult.ProceedWithCommit
        return FailureProcessingResult.Continue


# ╔╦╗╔═╗╦╔╗╔
# ║║║╠═╣║║║║
# ╩ ╩╩ ╩╩╝╚╝ MAIN
#==================================================
# Get Values
user_input = select_desired_levels()

level_from = user_input['level_from']
level_to   = user_input['level_to']


rooms_to_change = [room for room in all_rooms if room.LevelId == level_from.Id]

try:
    with TransactionGroup(doc, 'Change Room Levels') as tg:
        tg.Start()

        for room in rooms_to_change:
            print(room)
            room_loc = room.Location
            room_pt = room.Location.Point
            offset = room.get_Parameter(BuiltInParameter.ROOM_UPPER_OFFSET).AsDouble()

            with Transaction(doc, 'Unplace Room') as t1:
                t1.Start()
                fail_options = t1.GetFailureHandlingOptions()
                fail_options.SetFailuresPreprocessor(UnplacedRoomWarning())
                t1.SetFailureHandlingOptions(fail_options)
                room.Unplace()
                t1.Commit()

            with Transaction(doc,'New Room') as t2:
                t2.Start()
                topo     = doc.get_PlanTopology(level_to)
                circuits = topo.Circuits

                for circuit in circuits:
                    if not circuit.IsRoomLocated:
                        newRoom = doc.Create.NewRoom(room, circuit)
                        newRoom.get_Parameter(BuiltInParameter.ROOM_UPPER_LEVEL).Set(level_to.Id)
                        newRoom.get_Parameter(BuiltInParameter.ROOM_UPPER_OFFSET).Set(offset)
                        move = XYZ(room_pt.X - room_loc.Point.X, room_pt.Y - room_loc.Point.Y, room_loc.Point.Z)
                        ElementTransformUtils.MoveElement(doc, newRoom.Id, move)
                        break
                t2.Commit()
        tg.Assimilate()
except:
    import traceback
    print(traceback.format_exc())

⌨️ Happy Coding!
Erik Frits