blog/
Про Python и ArchiCAD: удалить лишние слои
Рассказываю про скрипт, который выводит список (комбинацию слоёв) всех включенных слоёв ArchiCAD в файл. После сохранения, его можно просто импортировать в Архикад и у вас будет комбинация слоёв со всеми включенными слоями. Чтобы скрипт запустить, вам понадобится среда выполнения Pуthon с соотв. библиотеками, или просто Google Colab. Этот скрипт я написал c нуля, там могут быть ошибки и нелогичные моменты, потому что я только начал учить Python. Подробнее, и как пользоваться скриптом — в видео.
Все сказано в ролике, текст программы ниже и в Google Colab.
Ещё про питон — см. в рубрике программирование.
import sys
from lxml import etree
# import xml.etree.cElementTree as etree
import distutils
from distutils import util
url = 'xml/archicad_layer_comb_exported.xml' # HERE GOES THE SOURCE XML FILE URL
newFileURL = 'xml output/КОМБИНАЦИИ COLLECTED.xml' # HERE GOES THE DESTINATION XML FILE URL
try:
tree = etree.parse(url) # HERE I GET THE TREE
except:
print("Seems something's wrong with the source file URL.")
sys.exit()
root = tree.getroot()
layerCombList = root.findall('.//RegisteredAttributes/Attributes[@Type="Layer Combinations"]/LayerCombination')
if (layerCombList == []):
layerCombList = root.findall('.//RegisteredAttributes/Attributes[@Type="Комбинации Слоев"]/LayerCombination')
# print(layerCombList)
if (len(layerCombList) < 2):
print("There's only one damn layer combination in the xml.")
sys.exit()
mainLComb = layerCombList[0] # save the main combination!
layerStatusDict = {} # make a dictionary of lists
print("Number of combinations: ", len(layerCombList))
for layerComb in range(0, len(layerCombList)): # create a dictionary of LayerStatus/Hidden, groupped by layer combinations
layerStatusDict[layerComb] = layerCombList[layerComb].findall("LayerStatus/Hidden")
print("Number of indexes: ", len(layerStatusDict[1]), "\n")
print("The first combination (the reference one)\nis set to be the 0 combination.\n")
# iterate through layer dictionary, starting from the second element
for combination in range(1, len(layerStatusDict)):
print("Combination number: ", combination)
for status in range(0, len(layerStatusDict[combination])):
zeroTreeBool = bool(distutils.util.strtobool(layerStatusDict[0][status].text))
currentBool = bool(distutils.util.strtobool(layerStatusDict[combination][status].text))
# print(zeroTreeBool)
# set the algebraic boolean in zeroTreeBool to be false if any of the operands is false
# https://pyeda.readthedocs.io/en/latest/boolalg.html
zeroTreeBool = currentBool and zeroTreeBool
layerStatusDict[0][status].text = str(zeroTreeBool)
# print(layerStatusDict[0][status].text,"\n")
# print('Cob N', combination, ' status ', layerStatusDict[combination][status])
# layerStatusDict[0][status] = layerStatusDict[combination][status]
##################################################################
# HERE TO NAME THE NEW COMBINATION PROPERLY
# <LayerCombination Idx="233" Name="! 000 ПЛАНЫ ДЛЯ ПЕРЕВЫПУСКА">
layerCombList[0].attrib["Idx"] = "999"
layerCombList[0].attrib["Name"] = "! THE NEW COMBINATION !"
layerCombList[0].findall("Name")[0].text = layerCombList[0].attrib["Name"]
layerCombList[0].findall("Index")[0].text = layerCombList[0].attrib["Idx"]
##################################################################
# HERE TO REMOVE ALL OTHER COMBINATIONS
for combination in range(1, len(layerCombList)):
# layerCombList[combination].remove()
layerCombList[combination].getparent().remove(layerCombList[combination])
# SET ALL OTHER ATTRIBUTES OF THE COMBINATION TO DEFAULT
for element in layerCombList[0].findall("LayerStatus/Locked"):
element.text = "False"
for element in layerCombList[0].findall("LayerStatus/ForceToWire"):
element.text = "False"
for element in layerCombList[0].findall("LayerStatus/ConnectionClassId"):
element.text = "1"
##################################################################
# now that we have our XML modified, we have to save it to a file
print('Starting saving the tree to file ' + newFileURL)
print(tree)
original_stdout = sys.stdout # save the current output so to revert to it later
with open(newFileURL, "w+", encoding="utf-8") as f:
sys.stdout = f # Change the standard output to the file we created.
##############################################################
tree = tree.getroot()
xmlstr = etree.tostring(tree, encoding='utf-8', method='xml', xml_declaration=True).decode("utf-8")
print(xmlstr)
f.close() # close file
sys.stdout = original_stdout
print("Done.")
Может быть интересно:
- Распечатать дерево проекта в ArchiCAD 23 через Python
- Python в ArchiCAD 23
- Задаём свойства объектам в ArchiCAD 23 через Python
- Как скачать картинки с сайта с помощью Python
- Select all images urls and download them
▧