I have many blocks
In each blocks , i would like to get center corrdinate x z
How can i that ?
Solved! Go to Solution.
I assume you are working with dynamic shapes, meaning blocks and lots that are automatically created by CityEngine in a street network. I assume you want CityEngine to automatically divide the blocks into lots. In this case, unfortunately, I can't think of a way in cga for each Lot to know the centroid or any information about the block it belongs to.
The only way I can think of is to start with the dynamically created blocks, do not subdivide them automatically (select blocks, set Subdivision Type = "No Subdivision" in Inspector), and subdivide them in your cga rule instead. Here is some code that calculates the block's centroid, places an invisible cube at the centroid, and subdivides the block into lots. Each lot queries its minimumDistance to the invisible cube at the centroid. If you don't need the exact centroid, it would be simpler to skip the centroid calculation and center the invisible cube in the block's scope instead. You can replace the SubdivideIntoLots rule with any algorithm you prefer. I know it's not ideal, but maybe this gives you some ideas of how to proceed.
const numBlockVertices = geometry.nVertices
const sumOfBlockVertices =
[ sum(comp(v) { all: convert(x, scope, world, pos, 0, 0, 0) }),
sum(comp(v) { all: convert(y, scope, world, pos, 0, 0, 0) }),
sum(comp(v) { all: convert(z, scope, world, pos, 0, 0, 0) }) ]
const centroidInWorld = sumOfBlockVertices./numBlockVertices
const cubeWidth = 1
const blockCentroidLabel = "BlockCentroid"
const splitDist = 30
const tallBuildingThres = 10
Block -->
BlockCenter
SubdivideIntoLots
BlockCenter
with(
centroidInScope := convert(world, scope, pos, centroidInWorld)
) -->
primitiveCube
s(cubeWidth, cubeWidth, cubeWidth)
t(centroidInScope[0]-0.5*cubeWidth, centroidInScope[1]-0.5*cubeWidth, centroidInScope[2]-0.5*cubeWidth)
label(blockCentroidLabel)
NIL
SubdivideIntoLots -->
splitAndSetbackPerimeter(0) { splitDist: splitDist: Lot }*
{ remainder: SubdivideIntoLots }
Lot
with(
distToCentroid := minimumDistance(intra, blockCentroidLabel)
) -->
case distToCentroid < tallBuildingThres:
TallBuilding
else:
House
Hi JeoCho,
If your intent is only to know the centre points, you can run the following python script on any selected block:
'''
Created on 10 Nov 2022
@author: Plfontes
'''
from scripting import *
# get a CityEngine instance
ce = CE()
@noUIupdate
def getBlockCentroid():
# get selected blocks
blocks = ce.getObjectsFrom(ce.selection(),ce.isBlock)
for block in blocks:
# get/print centroid
print(ce.getOID(block), ce.getPosition(block))
if __name__ == '__main__':
getBlockCentroid()
This will print to the console the block ID and its centroid (x, y, z) position.
Hope this helps.
Really thank you for reply
really sorry ,I have a other question
Example)
I would like to make this cga , but your code is python
If i have 3 block a , b ,c
Dist = The value of distance between a block center and lot
if dist < 1000 -> high building
If dist > 1000 -> residental house
I make this process
How can i make in cga?
I assume you are working with dynamic shapes, meaning blocks and lots that are automatically created by CityEngine in a street network. I assume you want CityEngine to automatically divide the blocks into lots. In this case, unfortunately, I can't think of a way in cga for each Lot to know the centroid or any information about the block it belongs to.
The only way I can think of is to start with the dynamically created blocks, do not subdivide them automatically (select blocks, set Subdivision Type = "No Subdivision" in Inspector), and subdivide them in your cga rule instead. Here is some code that calculates the block's centroid, places an invisible cube at the centroid, and subdivides the block into lots. Each lot queries its minimumDistance to the invisible cube at the centroid. If you don't need the exact centroid, it would be simpler to skip the centroid calculation and center the invisible cube in the block's scope instead. You can replace the SubdivideIntoLots rule with any algorithm you prefer. I know it's not ideal, but maybe this gives you some ideas of how to proceed.
const numBlockVertices = geometry.nVertices
const sumOfBlockVertices =
[ sum(comp(v) { all: convert(x, scope, world, pos, 0, 0, 0) }),
sum(comp(v) { all: convert(y, scope, world, pos, 0, 0, 0) }),
sum(comp(v) { all: convert(z, scope, world, pos, 0, 0, 0) }) ]
const centroidInWorld = sumOfBlockVertices./numBlockVertices
const cubeWidth = 1
const blockCentroidLabel = "BlockCentroid"
const splitDist = 30
const tallBuildingThres = 10
Block -->
BlockCenter
SubdivideIntoLots
BlockCenter
with(
centroidInScope := convert(world, scope, pos, centroidInWorld)
) -->
primitiveCube
s(cubeWidth, cubeWidth, cubeWidth)
t(centroidInScope[0]-0.5*cubeWidth, centroidInScope[1]-0.5*cubeWidth, centroidInScope[2]-0.5*cubeWidth)
label(blockCentroidLabel)
NIL
SubdivideIntoLots -->
splitAndSetbackPerimeter(0) { splitDist: splitDist: Lot }*
{ remainder: SubdivideIntoLots }
Lot
with(
distToCentroid := minimumDistance(intra, blockCentroidLabel)
) -->
case distToCentroid < tallBuildingThres:
TallBuilding
else:
House
Thank you
Thank you
This is what i was looking for
Really really thank you