Scale objects by volume centroid

Hey guys,

Is there a way to select multiple single objects and scale them all at the same time from their relative individual centres?

Cheers

Andy

Not sure if you can in Rhino alone but you can use the Grasshopper plugin to do that easily.

My Grasshopper experience is zero… Sadly

basically zero? or absolute zero?

because it really is a simple one to do in grasshopper.

in rhino alone, you’ll have to scale them one at a time since Scale accepts only a single origin point.

1 Like

Hi - you can use BoxEdit command with option to use individual bboxes and their centers. That should do it.

hth,

–jarek

BoxEdit? sounds neat…

i haven’t been able to try that one before :wink:

Hmmm… I’m working with surfaces so tried it with area:

It’s scaling the whole thing as it does with regular scale…

My mistake… It was joined.

Just trying to work out why when scaling in the negative the parts get bigger :smiley:

And now how to apply… I really should start using Grasshopper! :slightly_smiling:

to scale smaller, you’d set to something in between 0.0 & 0.999…

if you keep going in the negative direction past 0, it flips…

right-click on Scale and choose Bake.

Here’s a Python that might help-

import Rhino
import scriptcontext as sc
import rhinoscriptsyntax as rs

def ScaleEach():
    factor=2
    objrefs = []

    while True:
        if sc.sticky.has_key("SCALEFACTOR"):
            factor = sc.sticky["SCALEFACTOR"]
            
        go = Rhino.Input.Custom.GetObject()
        go.AcceptNumber(True, False)
        optFactor = Rhino.Input.Custom.OptionDouble(factor)
        go.AddOptionDouble("Scale",optFactor)
        
        get_rc = go.GetMultiple(1, 0)

        if go.CommandResult()!=Rhino.Commands.Result.Success:
            return go.CommandResult()
            
        if get_rc==Rhino.Input.GetResult.Object:
            objrefs =[go.Object(n) for n in range(go.ObjectCount)]
            break
            
        elif get_rc == Rhino.Input.GetResult.Number:
            factor = go.Number()
            sc.sticky["SCALEFACTOR"] = factor
            
        elif get_rc==Rhino.Input.GetResult.Option:
            factor = optFactor.CurrentValue
            sc.sticky["SCALEFACTOR"] = factor
            continue
            
    #factor = sc.sticky["SCALEFACTOR"]
    if len(objrefs) == 0: return
    
    rs.EnableRedraw(False)
    for objref in objrefs:
        Id = objref.ObjectId
        obj = sc.doc.Objects.Find(Id)
        bbCen = obj.Geometry.GetBoundingBox(True).Center
        rs.ScaleObject(Id,bbCen,[factor, factor, factor],False)
    rs.EnableRedraw(True)

if __name__ == '__main__':
    ScaleEach()

-Pascal

2 Likes

Thank you guys! So simple… When you know what you’re doing :slightly_smiling:

3 Likes

Hi Pascal,

Could you please upload the script file (rvb probably) or inform me on how to move froward from the text script?

Thank you

Hi Khaled - that script actually scales on the bounding box center, not quite the same thing as advertised, on the volume centroid - but here it is in case it helps

ScaleEachOnBBox.py (1.4 KB)

To use the Python script use RunPythonScript, or a macro:

_-RunPythonScript "Full path to py file inside double-quotes"

-Pascal

1 Like

Thanks Pascal for the immediate response.

I actually find the Boxedit tool to be very useful, since am working with SubDs and I wanted to modify edges together - the script seems to just work with objects -

Just discovering Boxedit capabilities now with local origins modifications. and the compatibilities with SubD is interesting! I suggest adding it’s icon to the right tool bar in the “SubD Tools” modeling interface, beside the cage edit and other UDTs

For ref, I managed to adjust those louvers to move apart, and then rotate them with a local angle relative to each louver’s center, all with boxedit. In one single real-time adjustment, similar to GH.
check block instance and play with min, cen, and max

Still discovering boxedit.
I am now making slabs and wanted them a little inset from the original contoured curves.
Again, boxedit worked neat in that, just when it came to some irregular slabs - the red boundaries, the center scaling didn’t do the job, I played again with different center pivot locations and types but don’t seem to figure it out.

Is there a way I can do that inset in rhino in a procedural way like boxedit?
and not by dupboarder, offset inside, trim

In V8 there is the Inset command, you can do all of your surfaces at once with the option set JoinOutput=No. You then will still have to select all the outside “slivers” and delete, but it’s much faster than doing one surface at a time with Offset.

I see, because now inset just works with subds and meshes, would be good to have it onto nurbs as well.
I am honestly so excited to start using V8

Cheers Helvetosaur!