blog/
Задаём свойства объектам в ArchiCAD 23 через Python
Написал программу, задающую свойства объектов из списка (список хранится в excel, сохранённый из ArchiCAD, потому что Graphisoft не догадались сделать функцию в своём питоновском api, через которую можно было бы получить размеры библиотечного (очевидно, GDL) элемента).
Все сказано в ролике, текст программы ниже sort_and_rename_the_holes.py.
Ещё про питон — см. в рубрике программирование.
import os import sys import xlrd i=0 theStart=0 #these two params allow to limit the script so it could somehow run in AC: start from 0 index theEnd=150 excelFilePath = os.path.join (os.path.dirname (sys.argv[0]), "scheme.xls") #change scheme.xls with your file name if os.path.isfile (excelFilePath) is False: sys.exit ("File does not exist: {}".format (excelFilePath)) xl_workbook = xlrd.open_workbook(excelFilePath) xl_sheet = xl_workbook.sheet_by_index(0) class hole: # create a class of an object hole in which we will store the data to use later def __init__(self, the_id, width_height): self.the_id = the_id self.width_height = width_height holesList = [] sizesList = [] sizeDictionary = {} for row in range (i,xl_sheet.nrows): # create objects and put them into a dictionary, organized by objectSize objectWidth = (xl_sheet.cell_value(row, colx=0)) objectHeight = (xl_sheet.cell_value(row, colx=1)) objectGUID = (xl_sheet.cell_value(row, colx=2)) objectSize = str(int(objectWidth)) + "/" + str(int(objectHeight)) holesList.append(hole(str(objectGUID), objectSize)) if objectSize in sizeDictionary: sizeDictionary[objectSize].append(hole (str(objectGUID), objectSize)) else: sizeDictionary[objectSize]=[hole (str(objectGUID), objectSize)] print ("dictionary length:", len(sizeDictionary.keys()), str(sizeDictionary.keys())) #output the number of object sizes and their names cycleIterator = 0 # overall progress iterator for key in sizeDictionary.keys(): #cycle through the dictionary keys typeNumber = i+1 # add 1 to the type iterator as we need the mark star from 1, not 0 if (cycleIterator <= theEnd and cycleIterator >= theStart): #if we are in our set range, print the current size list print ('{:-^60}'.format (" "+str(typeNumber)+" : "+str(key)+" ")) for obj in sizeDictionary[key]: # cycle through the object list in the dictionary list of current object size cycleIterator += 1 elem = obj.the_id # put a link to the object id into the elem variable to use in the api calls if (cycleIterator <= theEnd and cycleIterator >= theStart): # if we are in the set range, go in and process the items for d in GetElementPropertyDefinitionDictionary (elem, API_PropertyDefinitionFilter_UserDefined).values(): # get the current object's definition dictionary (api call), and cycle through all its properties (which are Archicad API objects) if (d.canValueBeEditable and d.defaultValue.hasExpression == False): # if we have our value editable and not default (which is probably not needed), go on... p=GetElementProperty (elem, d.guid) # ...store the link to the object's property object in the p variable... if p.definition.name == "Марка отверстия": # ...if the name of the propery is the one we need, go on... #print (p.definition.name) theProperty = p # excessive line, but let it be #print (theProperty.value, typeNumber) if theProperty.value != typeNumber: #if the property value is not the one we need, change its properties. (theProperty is a link to the AC API object, we are checking) theProperty.isDefault = False # set it to be not default theProperty.value = str(typeNumber) # set the property value to be String of our number try: # to avoid the termination of the program, if the API call won't work, wrap it into try...except SetElementProperty (elem, theProperty) # call the API function to set the property (passing it the elem wich is the elemet object and theProperty as described earlier print (str(cycleIterator)+" of "+str(theEnd)+" > Set the number "+str(typeNumber)+" successfully ") # if we are ok, move on except: print (str(cycleIterator)+" of "+str(theEnd)+" > Couldn't set the "+str(typeNumber)+" number for "+str(obj.the_id)) # if not, tell us about it i += 1 # add 1 to the global iterator print ("{:-^60}".format ("DONE (from "+str(theStart)+" to "+str(theEnd)+")"))
Similar Posts:
- Script for choosing a winner on Instagram (JavaScript Instagram comment picker)
- Script for choosing a winner on Instagram (JavaScript Instagram comment picker)
- Про Python и ArchiCAD: удалить лишние слои
- Как разыграть бесплатные места на курсе вёрстки для архитекторов (JS+Instagram)
- Как проверить последовательность чисел в Питоне
▦