We value your input!
Please participate in Archicad 28 Home Screen and Tooltips/Quick Tutorials survey

Archicad Python API
About automating tasks in Archicad using the Python API.

Python script for column numbering

GoranA
Participant

Is it possible to use a python script to set the ID of the columns, so that all columns of the same dimensions have a common ID.

 

I have edited zone script and that's working, but every column have unique ID, I need unique ID for column with same dimensions (width, hight, length).

 

 

 

from archicad import ACConnection
from typing import List, Tuple, Iterable
from itertools import cycle

conn = ACConnection.connect()
assert conn

acc = conn.commands
act = conn.types
acu = conn.utilities

propertyId = acu.GetBuiltInPropertyId('General_ElementID')

propertyValueStringPrefix = 'POS S'
elements = acc.GetElementsByType('Column')

ROW_GROUPING_LIMIT = 0.25
STORY_GROUPING_LIMIT = 1

def GeneratePropertyValueString(storyIndex: int, elemIndex: int) -> str:
    return f"{propertyValueStringPrefix}{storyIndex:1d}{elemIndex:02d}"

def generatePropertyValue(storyIndex: int, elemIndex: int) -> act.NormalStringPropertyValue:
    return act.NormalStringPropertyValue(GeneratePropertyValueString(storyIndex, elemIndex))

def createClusters(positions: Iterable[float], limit: float) -> List[Tuple[float, float]]:
    positions = sorted(positions)
    if len(positions) == 0:
        return []
    clusters = []
    posIter = iter(positions)
    firstPos = lastPos = next(posIter)

    for pos in posIter:
        if pos - lastPos <= limit:
            lastPos = pos
        else:
            clusters.append((firstPos, lastPos))
            firstPos = lastPos = pos
    clusters.append((firstPos, lastPos))
    return clusters

boundingBoxes = acc.Get3DBoundingBoxes(elements)
elementBoundingBoxes = list(zip(elements, boundingBoxes))
zClusters = createClusters((bb.boundingBox3D.zMin for bb in boundingBoxes), STORY_GROUPING_LIMIT)

storyIndex = 0
elemPropertyValues = []
for (zMin, zMax) in zClusters:
    elemIndex = 1
    elemsOnStory = [e for e in elementBoundingBoxes if zMin <= e[1].boundingBox3D.zMin <= zMax]
    yClusters = createClusters((e[1].boundingBox3D.yMin for e in elemsOnStory), ROW_GROUPING_LIMIT)

    for ((yMin, yMax), reverseOrder) in zip(yClusters, cycle([False, True])):
        elemsInRow = [e for e in elemsOnStory
                        if yMin <= e[1].boundingBox3D.yMin <= yMax]

        for (elem, bb) in sorted(elemsInRow, key=lambda e: e[1].boundingBox3D.xMin, reverse=reverseOrder):
            elemPropertyValues.append(act.ElementPropertyValue(
                elem.elementId, propertyId, generatePropertyValue(storyIndex, elemIndex)))
            elemIndex += 1
    storyIndex += 1

acc.SetPropertyValuesOfElements(elemPropertyValues)

newValues = acc.GetPropertyValuesOfElements(elements, [propertyId])
elemAndValuePairs = [(elements[i].elementId.guid, v.propertyValue.value) for i in range(len(newValues)) for v in newValues[i].propertyValues]
for elemAndValuePair in sorted(elemAndValuePairs, key=lambda p: p[1]):
    print(elemAndValuePair)

 

 

Can this script used for change column ID?

0 REPLIES 0