VolumeCentroid Won’t work with curves.
Is there a script or option to get it work based on bounding box. Thanks
VolumeCentroid Won’t work with curves.
Is there a script or option to get it work based on bounding box. Thanks
The Gumball center should be the bb center of selected curves… Or make a bounding box and use volume centroid on that.
Hi Mitch thank you for writing on this.
I mean a command that would create VolumeCentroids despite the object as with planar curves this approach would not work.
Just a Center/Centroid function for all — no concept of Area Centroid or Volume Centroid - just automatic based on context.
Thank you
The problem is that all of these are potentially different.
A closed surface/polysurface can have
All three of those can be different points.
An open surface/polysurface can have
Both of those can be different points.
An planar curve can have
All of those can be different points.
An arbitrary 3D curve can have
So you can see that the only one that is common to all of the above is the bounding box center - which is what Gumball uses. And for the objects that have multiple possibilities - practically all of the above - which method should Rhino choose?
Edit - if you want a simple script you can put on an alias to create a point at selected objects’ bounding box center, here you go:
import rhinoscriptsyntax as rs
obj_ids=rs.GetObjects("Select objects for bounding box centroid",preselect=True)
if obj_ids:
bb=rs.BoundingBox(obj_ids)
if bb: rs.AddPoint((bb[0]+bb[6])/2)
Mitch! So good, we have to mention for newbies to take the script data and paste them into a text file and name it ObjectCentroid.py and move it into the scripts folder and bind an Alias to it as OC
Thanks a lot for this works like a charm!
Well, there are a number of ways to install and run scripts:
https://wiki.mcneel.com/rhino/macroscriptsetup
Well, that might be a bit of a misnomer, as it doesn’t find the object centroid, it only finds the bounding box center (as mentioned above).
Hey Mitch, as always — sharp as a katana.
Hi everyone,
Does someone know why you can’t properly compute the Boundingbox’s center of a block or of an object if it is inside a block? Is this a new Rhino8 issue?
For example: below is a snapshot from a file with circles in blocks and outside of blocks. The centroids are incorrectly placed for the blocks and the objects inside blocks. You can see the 4 centroid (2 blocks + 2 circles in the blocks) floating near the World origin. The “free” circles have correct centroid dots.
Below is the script I used:
#! python 3
import rhinoscriptsyntax as rs
def loopBlock(block):
objectsInBlock = rs.BlockObjects(rs.BlockInstanceName(block))
for obj in objectsInBlock:
if rs.ObjectType(obj) != 4096:
action(obj)
else:
loopBlock(obj)
def action(object):
bb=rs.BoundingBox(object)
if bb: center = (bb[0]+bb[6])/2
rs.AddTextDot("Centroid!",center)
objs = rs.AllObjects(include_lights=False, include_grips=False)
if objs:
for obj in objs:
if rs.ObjectType(obj) == 4096: #block
loopBlock(obj)
else:
action(obj)
else:
print("No objects selectable.")
rs.Redraw()
The test file is attached.
testfile_centroid.3dm (2.6 MB)
I suspect because the centroids are calculated based on the positions of the original objects in the block, not of the individual instances - which may have been moved. For each instance you will probably need to transform the centroid points based on the block instance transformation.
Thanks for the hint, I had that in mind too. I managed to make it work by gradually adding all the block instances transformation data to the centroid of the bounding box. It’s a bit tedious, but it works.
Here’s the complete script, for future reference:
#! python 3
import rhinoscriptsyntax as rs
import Rhino
def dotIt(centroid):
rs.AddTextDot("Centroid!",centroid)
def getBlockOrigin(block):
irefObj = rs.coercerhinoobject(block)
idef = irefObj.InstanceDefinition
blockOrigin = irefObj.InsertionPoint
return blockOrigin
def getCentroid(obj): #cannot be directly applied to a block
bb=rs.BoundingBox(obj)
if bb:
centroid = ((bb[0]+bb[6])/2)
return centroid
def loopBlock(block, origin):
blockOrigin = getBlockOrigin(block) + origin
blockCentroid = origin + getCentroid(block)
dotIt(blockCentroid)
objectsInBlock = rs.BlockObjects(rs.BlockInstanceName(block))
for obj in objectsInBlock:
if rs.ObjectType(obj) != 4096: #is not a block
objCentroid = blockOrigin + getCentroid(obj)
dotIt(objCentroid)
else:
loopBlock(obj, blockOrigin)
objs = rs.AllObjects(include_lights=False, include_grips=False)
if objs:
for obj in objs:
if rs.ObjectType(obj) == 4096: #is a block
loopBlock(obj, Rhino.Geometry.Point3d.Origin)
else:
dotIt(getCentroid(obj))
else:
print("Could not select all objects.")
rs.Redraw()