def reload_links(linktype=DB.ExternalFileReferenceType.RevitLink): try: extrefs = query.get_links(linktype) for ref in extrefs: logger.debug(ref) if extrefs: refcount = len(extrefs) if refcount > 1: selected_extrefs = \ forms.SelectFromCheckBoxes.show( extrefs, title='Select Links to Reload', width=500, button_name='Reload', checked_only=True ) if not selected_extrefs: script.exit() elif refcount == 1: selected_extrefs = extrefs for extref in selected_extrefs: print("Reloading...\n\t{0}{1}".format( str(extref.linktype) + ':', extref.path)) if linktype in need_tsaxn_dict: with revit.Transaction('Reload Links'): extref.reload() else: extref.reload() except Exception as load_err: logger.debug('Load error: %s' % load_err) forms.alert('Model is not saved yet. Can not acquire location.')
def get_source_sheets(): sheet_elements = forms.select_sheets(button_name='Select TitleBlocks', use_selection=True, include_placeholder=False) if not sheet_elements: script.exit() return sheet_elements
def reload_links(linktype=DB.ExternalFileReferenceType.RevitLink): try: extrefs = query.get_links(linktype) #for ref in extrefs: #logger.debug(ref) if extrefs: refcount = len(extrefs) if refcount > 1: selected_extrefs = \ forms.SelectFromCheckBoxes.show( extrefs, title='Select Links to Reload', width=500, button_name='Reload', checked_only=True ) if not selected_extrefs: script.exit() elif refcount == 1: selected_extrefs = extrefs for extref in selected_extrefs: extref.reload() except Exception as load_err: #logger.debug('Load error: %s' % load_err) forms.alert('Model is not saved yet or link no loaded.')
def _get_printmanager(self): try: return self.selected_doc.PrintManager except Exception as printerr: logger.critical('Error getting printer manager from document. ' 'Most probably there is not a printer defined ' 'on your system. | %s', printerr) script.exit()
def reload_links(linktype=DB.ExternalFileReferenceType.RevitLink): """Reload links of selected type""" try: extrefs = query.get_links(linktype) for ref in extrefs: logger.debug(ref) if extrefs: refcount = len(extrefs) if refcount > 1: selected_extrefs = \ forms.SelectFromList.show( extrefs, title='Select Links to Reload', width=500, button_name='Reload', multiselect=True ) if not selected_extrefs: script.exit() elif refcount == 1: selected_extrefs = extrefs if revit.doc.IsWorkshared\ and linktype == DB.ExternalFileReferenceType.RevitLink: reload_locally = forms.alert( 'Do you want to reload links locally, without taking '\ 'ownership and without affecting other users?\n'\ 'Clicking "No" will reload for all users.', title='Reload locally?', yes=True, no=True) else: reload_locally = False for extref in selected_extrefs: print("Reloading...\n\t{0}{1}" .format(str(extref.linktype) + ':', extref.path)) if linktype in need_tsaxn_dict: with revit.Transaction('Reload Links'): extref.reload() elif linktype \ and linktype == DB.ExternalFileReferenceType.RevitLink: if reload_locally: try: if not extref.link.LocallyUnloaded: extref.link.UnloadLocally(None) extref.link.RevertLocalUnloadStatus() except Exception as local_reload_err: logger.debug( 'Error while locally reloading ' 'linked model: %s' % local_reload_err) else: extref.reload() else: extref.reload() except Exception as reload_err: logger.debug('Load error: %s' % reload_err) forms.alert('Model is not saved yet. Can not acquire location.')
def _print_combined_sheets_in_order(self): print_mgr = revit.doc.PrintManager print_mgr.PrintRange = DB.PrintRange.Select viewsheet_settings = print_mgr.ViewSheetSetting sheet_set = DB.ViewSet() # add non-printable char in front of sheet Numbers # to push revit to sort them per user original_sheetnums = [] with revit.Transaction('Fix Sheet Numbers') as t: for idx, sheet in enumerate(self.sheets_lb.ItemsSource): sht = sheet.revit_sheet original_sheetnums.append(sht.SheetNumber) sht.SheetNumber = NPC * (idx + 1) + sht.SheetNumber sheet_set.Insert(sht) # Collect existing sheet sets cl = DB.FilteredElementCollector(revit.doc) viewsheetsets = cl.OfClass(framework.get_type(DB.ViewSheetSet))\ .WhereElementIsNotElementType()\ .ToElements() all_viewsheetsets = {vss.Name: vss for vss in viewsheetsets} sheetsetname = 'OrderedPrintSet' with revit.Transaction('Update Ordered Print Set') as t: # Delete existing matching sheet set if sheetsetname in all_viewsheetsets: viewsheet_settings.CurrentViewSheetSet = \ all_viewsheetsets[sheetsetname] viewsheet_settings.Delete() viewsheet_settings.CurrentViewSheetSet.Views = sheet_set viewsheet_settings.SaveAs(sheetsetname) print_mgr.PrintOrderReverse = self.reverse_print try: print_mgr.CombinedFile = True except Exception as e: forms.alert(str(e) + '\nSet printer correctly in Print settings.') script.exit() print_mgr.PrintToFile = True # [BB] Added savepath to join command print_mgr.PrintToFileName = op.join(savepath, 'Ordered Sheet Set.pdf') print_mgr.Apply() print_mgr.SubmitPrint() # now fix the sheet names with revit.Transaction('Restore Sheet Numbers') as t: for sheet, sheetnum in zip(self.sheets_lb.ItemsSource, original_sheetnums): sht = sheet.revit_sheet sht.SheetNumber = sheetnum
def run(self, sender, args): count_changed = 0 # find not empty parameter definition_set = self.parameter_to_set.Definition definition_get = self.parameter_to_get.Definition not_empty_list = [] skip_ids = [] for e in self.selection: param = e.get_Parameter(definition_set) param_get = e.get_Parameter(definition_get) if param.AsString() != '' and param.AsString() != None and param.AsString() != param_get.AsString(): not_empty_list.append("Target: %s, Source: %s" % (self.parameter_value_get(param), self.parameter_value_get(param_get))) skip_ids.append(e.Id) if len(not_empty_list) > 0: len_limit = 10 len_not_empty_list = len(not_empty_list) if len_not_empty_list > len_limit: not_empty_list = not_empty_list[:len_limit] + [' + %d more...' % (len_not_empty_list - len_limit)] text = "%d elements have values already. Replace them?\n" % len_not_empty_list + "\n".join(not_empty_list) a = TaskDialog.Show(__title__, text, TaskDialogCommonButtons.Yes | TaskDialogCommonButtons.No) if str(a) == "Yes": skip_ids = [] t = Transaction(doc, __title__) t.Start() for e in self.selection: if e.Id in skip_ids: continue param = e.get_Parameter(definition_set) param_get = e.get_Parameter(definition_get) result = self.parameter_value_set(param, param_get) if result: count_changed += 1 else: logger.error("Cannot sum different types") script.exit() self.write_config() if count_changed: t.Commit() TaskDialog.Show(__title__, "%d of %d elements updated" % (count_changed, len(self.selection),)) else: t.RollBack() TaskDialog.Show(__title__, "Nothing was changed")
def GetInstanceParameters(_cat): el = DB.FilteredElementCollector(doc) \ .WhereElementIsNotElementType() \ .OfCategory(_cat) \ .ToElements() if not el: forms.alert("No elements of this category found in the project.") script.exit() parameters = [p.Definition.Name for p in el[0].Parameters \ if p.StorageType == DB.StorageType.String and \ p.Definition.ParameterType == DB.ParameterType.Text and \ not p.IsReadOnly] return parameters
def search(self, pattern): """ Searches in the target directory for the given glob pattern. Adds absolute paths to self.paths. Parameters ---------- pattern : str Glob pattern """ result = pathlib.Path(self.directory).rglob(pattern) for path in result: logger.debug('Found file: {}'.format(path)) self.paths.add(str(path)) if len(self.paths) == 0: logger.debug('No {} files in "{}" found.'.format( pattern, self.directory)) forms.alert('No {} files in "{}" found.'.format( pattern, self.directory)) script.exit()
def create_sheets(self, sender, args): self.Close() if self._process_sheet_code(): if self.sheet_cb.IsChecked: create_func = self._create_sheet transaction_msg = 'Batch Create Sheets' if not self._ask_for_titleblock(): script.exit() else: create_func = self._create_placeholder transaction_msg = 'Batch Create Placeholders' with DB.TransactionGroup(revit.doc, transaction_msg) as tg: tg.Start() for sheet_num, sheet_name in self._sheet_dict.items(): logger.debug('Creating Sheet: {}:{}'.format( sheet_num, sheet_name)) create_func(sheet_num, sheet_name) tg.Assimilate()
def filter_group_types(groups_dict): """Create a dict of group types Returns: dict[DB.ElementId, DB.ElementId]: dict of group {type_id: element_id} """ keys_map = { "%s (%d instances)" % ( revit.query.get_name(revit.doc.GetElement(gt_id)), len(groups_dict[gt_id]), ): gt_id for gt_id in groups_dict.keys() } picked_group_types = forms.SelectFromList.show( sorted(keys_map.keys()), multiselect=True, button_name="Select Group Types", ) if not picked_group_types: script.exit() picked_group_type_ids = [ keys_map[group_name] for group_name in picked_group_types ] return {k: v for k, v in groups_dict.items() if k in picked_group_type_ids}
def _print_combined_sheets_in_order(self): # make sure we can access the print config print_mgr = self._get_printmanager() with revit.TransactionGroup('Print Sheets in Order'): if not print_mgr: return with revit.Transaction('Set Printer Settings'): print_mgr.PrintSetup.CurrentPrintSetting = \ self.selected_print_setting print_mgr.SelectNewPrintDriver(self.selected_printer) print_mgr.PrintRange = DB.PrintRange.Select # add non-printable char in front of sheet Numbers # to push revit to sort them per user sheet_set = DB.ViewSet() original_sheetnums = [] with revit.Transaction('Fix Sheet Numbers'): for idx, sheet in enumerate(self.sheet_list): rvtsheet = sheet.revit_sheet original_sheetnums.append(rvtsheet.SheetNumber) rvtsheet.SheetNumber = \ NPC * (idx + 1) + rvtsheet.SheetNumber if sheet.printable: sheet_set.Insert(rvtsheet) # Collect existing sheet sets cl = DB.FilteredElementCollector(revit.doc) viewsheetsets = cl.OfClass(framework.get_type(DB.ViewSheetSet))\ .WhereElementIsNotElementType()\ .ToElements() all_viewsheetsets = {vss.Name: vss for vss in viewsheetsets} sheetsetname = 'OrderedPrintSet' with revit.Transaction('Remove Previous Print Set'): # Delete existing matching sheet set if sheetsetname in all_viewsheetsets: print_mgr.ViewSheetSetting.CurrentViewSheetSet = \ all_viewsheetsets[sheetsetname] print_mgr.ViewSheetSetting.Delete() with revit.Transaction('Update Ordered Print Set'): try: viewsheet_settings = print_mgr.ViewSheetSetting viewsheet_settings.CurrentViewSheetSet.Views = \ sheet_set viewsheet_settings.SaveAs(sheetsetname) except Exception as viewset_err: sheet_report = '' for sheet in sheet_set: sheet_report += '{} {}\n'.format( sheet.SheetNumber if isinstance( sheet, DB.ViewSheet) else '---', type(sheet)) logger.critical( 'Error setting sheet set on print mechanism. ' 'These items are included in the viewset ' 'object:\n%s', sheet_report) raise viewset_err # set print job configurations print_mgr.PrintOrderReverse = self.reverse_print try: print_mgr.CombinedFile = True except Exception as e: forms.alert( str(e) + '\nSet printer correctly in Print settings.') script.exit() print_mgr.PrintToFile = True print_mgr.PrintToFileName = \ op.join(r'C:\\', 'Ordered Sheet Set.pdf') print_mgr.Apply() print_mgr.SubmitPrint() # now fix the sheet names with revit.Transaction('Restore Sheet Numbers'): for sheet, sheetnum in zip(self.sheet_list, original_sheetnums): rvtsheet = sheet.revit_sheet rvtsheet.SheetNumber = sheetnum
def main(): sourceSheet = forms.select_sheets(multiple=False) if sourceSheet is None: script.exit() #GETTING SOURCE VIEWPORTS COORDINATES sourceViewportIds = sourceSheet.GetAllViewports() sourceViewports = [] sourceViewportNums = [] sourcePts = [] for i in sourceViewportIds: sourceViewports.append(doc.GetElement(i)) sourcePts.append(doc.GetElement(i).GetBoxCenter()) sourceViewportNums.append( doc.GetElement(i).get_Parameter( BuiltInParameter.VIEWPORT_DETAIL_NUMBER).AsString()) locationDict = {} if len(sourceViewports) >= 1: locationDict = dict(zip(sourceViewportNums, sourcePts)) elif len(sourceViewports) < 1: forms.alert('No viewport on selected source sheet.') script.exit() if sourceViewports is None: script.exit() #GETTING VIEWPORTS ON THE SPECIFIED SHEET destSheets = forms.select_sheets() if destSheets is None: script.exit() allCategories = doc.Settings.Categories catIds = [] # Filter categories to just model categories + Matchlines and Scope Boxes for c in allCategories: if c.CategoryType == DB.CategoryType.Annotation: catIds.append(c.Id) elif c.CategoryType == DB.CategoryType.Model: if c.Name == 'Lighting Fixtures': catIds.append(c.Id) linkInstances = DB.FilteredElementCollector(doc)\ .OfClass(DB.RevitLinkInstance)\ .WhereElementIsNotElementType()\ .ToElements() linkInstanceIds = [] for link in linkInstances: linkInstanceIds.append(link.Id) #APPLYING SOURCE VIEW COORDINATES TO DESTINATION VIEWS with revit.Transaction('Align Multiple Viewports'): for svp in sourceViewports: view = doc.GetElement(svp.ViewId) hide_objects(view, catIds, linkInstanceIds) for sheet in destSheets: destViewports = [] temp = sheet.GetAllViewports() for i in temp: destViewports.append(doc.GetElement(i)) for dvp in destViewports: view = doc.GetElement(dvp.ViewId) hide_objects(view, catIds, linkInstanceIds) if len(destViewports) == len(sourceViewports): for vp in destViewports: viewNumber = vp.get_Parameter( BuiltInParameter.VIEWPORT_DETAIL_NUMBER).AsString() mappedLocation = locationDict.get(viewNumber, None) vp.SetBoxCenter(mappedLocation) unhide_objects(vp) else: forms.alert('Numbers of viewports don\'t match.') for svp in sourceViewports: unhide_objects(svp)
def error(msg): forms.alert(msg) script.exit()
"URL_Installation Manual": BuiltInParameterGroup.PG_IDENTITY_DATA, "URL_Product Page": BuiltInParameterGroup.PG_IDENTITY_DATA, "URL_Specification Manual": BuiltInParameterGroup.PG_IDENTITY_DATA, } logger = script.get_logger() # ensure active document is a family document forms.check_familydoc(revit.doc, exitscript=True) app = revit.doc.Application # make sure user has saved open models in case the tool crashes if not forms.alert( "Make sure your models are saved and synced. " "Hit OK to continue...", cancel=True ): script.exit() # get current shared parameter file sharedParametersFile = app.OpenSharedParameterFile() sharedGroups = sharedParametersFile.Groups # get current family parameters family_params = revit.doc.FamilyManager.GetParameters() existing_list = [] replace_list = [] shared_replace_list = [] for fparam in family_params: for key, values in std_params.items(): if fparam.Definition.Name == key:
def __init__(self, xaml_file_name, reset_config=False): forms.WPFWindow.__init__(self, xaml_file_name) # verify keynote file existence self._kfile = revit.query.get_local_keynote_file(doc=revit.doc) self._kfile_handler = None if not self._kfile: self._kfile_ext = \ revit.query.get_external_keynote_file(doc=revit.doc) self._kfile_handler = 'unknown' # mak sure ADC is available if self._kfile_handler == 'unknown': if adc.is_available(): self._kfile_handler = 'adc' # check if keynote file is being synced by ADC # use the drive:// path for adc communications # adc module takes both remote or local paths, # but remote is faster lookup local_kfile = adc.get_local_path(self._kfile_ext) if local_kfile: # check is someone else has locked the file locked, owner = adc.is_locked(self._kfile_ext) if locked: forms.alert( "Keynote file is being modified and locked by " "{}. Please try again later".format(owner), exitscript=True) # force sync to get the latest contents adc.sync_file(self._kfile_ext) adc.lock_file(self._kfile_ext) # now that adc communication is done, # replace with local path self._kfile = local_kfile self.Title += ' (BIM360)' else: forms.alert("Can not get keynote file from {}".format( adc.ADC_NAME), exitscript=True) else: forms.alert( "This model is using a keynote file that seems to be " "managed by {long} ({short}). But {short} is not " "running, or is not installed. Please install/run the " "{short} and open the keynote manager again".format( long=adc.ADC_NAME, short=adc.ADC_SHORTNAME), exitscript=True) # byt this point we must have a local path to the keynote file if not self._kfile or not op.exists(self._kfile): self._kfile = None forms.alert("Keynote file is not accessible. " "Please select a keynote file.") self._change_kfile() # if a keynote file is still not set, return if not self._kfile: raise Exception('Keynote file is not setup.') # if a keynote file is still not set, return if not os.access(self._kfile, os.W_OK): raise Exception('Keynote file is read-only.') self._conn = None try: self._conn = kdb.connect(self._kfile) except System.TimeoutException as toutex: forms.alert(toutex.Message, expanded="{}::__init__()".format( self.__class__.__name__), exitscript=True) except Exception as ex: logger.debug('Connection failed | %s' % ex) res = forms.alert( "Existing keynote file needs to be converted to " "a format usable by this tool. The resulting keynote " "file is still readble by Revit and could be shared " "with other projects. Users should NOT be making changes to " "the existing keynote file during the conversion process.\n" "Are you sure you want to convert?", options=[ "Convert", "Select a different keynote file", "Give me more info" ]) if res: if res == "Convert": try: self._convert_existing() forms.alert("Conversion completed!") if not self._conn: forms.alert( "Launch the tool again to manage keynotes.", exitscript=True) except Exception as convex: logger.debug('Legacy conversion failed | %s' % convex) forms.alert("Conversion failed! %s" % convex, exitscript=True) elif res == "Select a different keynote file": self._change_kfile() elif res == "Give me more info": script.open_url(__helpurl__) #pylint: disable=undefined-variable script.exit() else: forms.alert("Keynote file is not yet converted.", exitscript=True) self._cache = [] self._allcat = kdb.RKeynote(key='', text='-- ALL CATEGORIES --', parent_key='', locked=False, owner='', children=None) self._needs_update = False self._config = script.get_config() self._used_keysdict = self.get_used_keynote_elements() self.load_config(reset_config) self.search_tb.Focus()
def get_source_sheets(): sheet_elements = forms.select_sheets(button_name='Select TitleBlocks') if not sheet_elements: script.exit() return sheet_elements
def _print_combined_sheets_in_order(self): print_mgr = revit.doc.PrintManager print_mgr.PrintRange = DB.PrintRange.Select viewsheet_settings = print_mgr.ViewSheetSetting sheet_set = DB.ViewSet() # add non-printable char in front of sheet Numbers # to push revit to sort them per user original_sheetnums = [] with revit.TransactionGroup('Print Sheets in Order') as tg: with revit.Transaction('Fix Sheet Numbers') as t: for idx, sheet in enumerate(self.sheets_lb.ItemsSource): sht = sheet.revit_sheet original_sheetnums.append(sht.SheetNumber) sht.SheetNumber = NPC * (idx + 1) + sht.SheetNumber sheet_set.Insert(sht) # Collect existing sheet sets cl = DB.FilteredElementCollector(revit.doc) viewsheetsets = cl.OfClass(framework.get_type(DB.ViewSheetSet))\ .WhereElementIsNotElementType()\ .ToElements() all_viewsheetsets = {vss.Name: vss for vss in viewsheetsets} sheetsetname = 'OrderedPrintSet' with revit.Transaction('Update Ordered Print Set') as t: # Delete existing matching sheet set if sheetsetname in all_viewsheetsets: viewsheet_settings.CurrentViewSheetSet = \ all_viewsheetsets[sheetsetname] viewsheet_settings.Delete() try: viewsheet_settings.CurrentViewSheetSet.Views = sheet_set except Exception as viewset_err: sheet_report = '' for sheet in sheet_set: sheet_report += '{} {}\n'.format( sheet.SheetNumber if isinstance( sheet, DB.ViewSheet) else '---', type(sheet)) logger.critical( 'Error setting sheet set on print mechanism. ' 'These items are included in the viewset ' 'object:\n{}'.format(sheet_report)) raise viewset_err viewsheet_settings.SaveAs(sheetsetname) print_mgr.PrintOrderReverse = self.reverse_print try: print_mgr.CombinedFile = True except Exception as e: forms.alert( str(e) + '\nSet printer correctly in Print settings.') script.exit() print_mgr.PrintToFile = True print_mgr.PrintToFileName = op.join(r'C:', 'Ordered Sheet Set.pdf') print_mgr.Apply() print_mgr.SubmitPrint() # now fix the sheet names with revit.Transaction('Restore Sheet Numbers') as t: for sheet, sheetnum in zip(self.sheets_lb.ItemsSource, original_sheetnums): sht = sheet.revit_sheet sht.SheetNumber = sheetnum
def __init__(self, xaml_file_name): forms.WPFWindow.__init__(self, xaml_file_name) # verify keynote file existence self._kfile = revit.query.get_keynote_file(doc=revit.doc) if not self._kfile or not op.exists(self._kfile): self._kfile = None forms.alert("Keynote file is not accessible. " "Please select a keynote file.") self._change_kfile() # if a keynote file is still not set, return if not self._kfile: raise Exception('Keynote file is not setup.') self._conn = None try: self._conn = kdb.connect(self._kfile) except System.TimeoutException as toutex: forms.alert(toutex.Message, exitscript=True) except Exception as ex: logger.debug('Connection failed | %s' % ex) res = forms.alert( "Existing keynote file needs to be converted to " "a format usable by this tool. The resulting keynote " "file is still readble by Revit and could be shared " "with other projects. Users should NOT be making changes to " "the existing keynote file during the conversion process.\n" "Are you sure you want to convert?", options=["Convert", "Give me more info"]) if res: if res == "Convert": try: self._convert_existing() forms.alert("Conversion completed!") if not self._conn: forms.alert( "Launch the tool again to manage keynotes.", exitscript=True) except Exception as convex: logger.debug('Legacy conversion failed | %s' % convex) forms.alert("Conversion failed! %s" % convex, exitscript=True) elif res == "Give me more info": script.open_url('https://eirannejad.github.io/pyRevit') script.exit() else: forms.alert("Keynote file is not yet converted.", exitscript=True) self._cache = [] self._allcat = kdb.RKeynote(key='', text='-- ALL CATEGORIES --', parent_key='', locked=False, owner='', children=None) self._config = script.get_config() self._used_keysdict = self.get_used_keynote_elements() self.load_config() self.search_tb.Focus()
def reload_links(ref_type=DB.ExternalFileReferenceType.RevitLink): """Reload links of selected type""" try: link_type = DB.RevitLinkType if ref_type == DB.ExternalFileReferenceType.CADLink: link_type = DB.CADLinkType links = DB.FilteredElementCollector(revit.doc) \ .OfClass(link_type)\ .ToElements() for link in links: logger.debug(link) if links: xrefs = [revit.db.ExternalRef(x, None) for x in links] linkcount = len(xrefs) if linkcount > 1: selected_xrefs = \ forms.SelectFromList.show( xrefs, title='Select Links to Reload', width=500, button_name='Reload', multiselect=True ) if not selected_xrefs: script.exit() elif linkcount == 1: selected_xrefs = xrefs if revit.doc.IsWorkshared\ and ref_type == DB.ExternalFileReferenceType.RevitLink: reload_locally = forms.alert( 'Do you want to reload links locally, without taking '\ 'ownership and without affecting other users?\n'\ 'Clicking "No" will reload for all users.', title='Reload locally?', yes=True, no=True) else: reload_locally = False for xref in selected_xrefs: print("Reloading \"{}\"".format(xref.name)) if ref_type == DB.ExternalFileReferenceType.RevitLink: if reload_locally: try: if not xref.link.LocallyUnloaded: xref.link.UnloadLocally(None) xref.link.RevertLocalUnloadStatus() except Exception as local_reload_err: logger.debug('Error while locally reloading ' 'linked model: %s' % local_reload_err) else: xref.reload() elif ref_type == DB.ExternalFileReferenceType.CADLink: with revit.Transaction('Reload CAD Links'): xref.reload() print("Reload Completed...") except Exception as reload_err: logger.error('Load error: %s' % reload_err)