Про Python и ArchiCAD: удалить лишние слои

Ivan @ 03 / 12 / 2020 @ Blog / ArchiCAD / BIM и CAD / Медиа / Памятки / Программирование / Уроки
( / / )

Время чтения: ~ 9 мин.

Рассказываю про скрипт, который выводит список (комбинацию слоёв) всех включенных слоёв 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.")

 


Может быть интересно:


Подпишитесь на нас в социальных сетях!

Instagram
VK
Facebook
YouTube!
Telegram!

Подпишитесь на обновления



* нажимая на кнопку «Подписаться», вы даете согласие на обработку своих персональных данных