from Autodesk.Revit.DB import *
from Autodesk.Revit.UI.Selection import ObjectType, PickBoxStyle, Selection, ISelectionFilter
from pyrevit import forms
import clr
clr.AddReference("System")
from System.Collections.Generic import List
from Snippets._convert import convert_internal_units
uidoc = __revit__.ActiveUIDocument
doc = __revit__.ActiveUIDocument.Document
selection = uidoc.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
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())