2023-12-08 02:27 PM - last edited on 2024-09-26 12:17 PM by Doreena Deng
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?