Rhino Python: "Custom stonemap tool", measure block instances (gemstones)

script
blocks
jewelry
python

#1

Hello everyone,

I am writing a custom python script to write up a stone map for me.
Currently I iterate over all the block instances in the scene and assign them bounding boxes.
The only problem is the orientation of the gym interferes with the bounding box measurements. If the gem is rotated 90+ degrees it will measure its depth as width. I have been looking for a way to measure the gems. Any help would be much appreciated.
Here is a sample of the code:

def measureGems(gems):
    gemDict = {}
    for gem in range(0, len(gems)):
        box = rs.BoundingBox(gems[gem])
        if box:
            for i in range(0,len(box)):
                width = round(rs.Distance(box[0], box[1]),1)
                length = round(rs.Distance(box[0], box[3]),1)
                height = round(rs.Distance(box[0], box[4]),1)
            gemDict[ gems[gem] ] = (length, width)
    return gemDict

(Willem Derks) #2

Hi Maxx,

You can probably solve this by taking the boundingbox aligned with the Block plane:
You will need to construct the plane by transforming the block base aligned plane with the block instance transformation.
BoundingBox(objects, view_or_plane=None, in_world_coords=True)

Sorry for being rather brief, I’m short on time ATM.

-Willem


#3

I am interested it what you come up with as I ran into a similar issue in a different application. What I did was used blocks and had everything oriented inside those blocks along the x-y-z axis. The those blocks got translated around. In script when I run the bounding box command, on the geometry inside the block, it would give me dimension of bounding box as related to original block definition. So I would get the original x-y-z dimension. If that makes any sense.


#4

To be more specific, I am ordering the numbers on the bounding box and then using those as the X,Y,Z dimensions of the gemstone. If a gemstone is rotated 90 degrees it still gets numbered in the same order as other gems which throws off the x,y,z. I have attached a picture below.


#5

Hi Maxx,

below is a script based on the idea of @Willem, it uses the block aligned bounding box and adds the length and width to the dictionary.

import rhinoscriptsyntax as rs
    
def measureGems(gems):
    gemDict = {}
    for gem in gems:
        xform = rs.BlockInstanceXform(gem)
        plane = rs.PlaneTransform(rs.WorldXYPlane(), xform)
        box = rs.BoundingBox(gem, plane, True)
        if box:
            width  = round(rs.Distance(box[0], box[1]), 1)
            length = round(rs.Distance(box[0], box[3]), 1)
            height = round(rs.Distance(box[0], box[4]), 1)
            gemDict[gem] = (length, width)
    return gemDict
    
def DoSomething():
    blocks = rs.GetObjects("Select blocks", 4096, False, True, False)
    if blocks: 
        print measureGems(blocks)
    
DoSomething()

c.


#6

Thats exactly what i needed!
Thank you all for your help!
This seriously made my day!
:boom: