Maya 2020 fundamentals - modelling the real world
Get halfway through a model and find it's an unworkable mess? Can't add edge loops where you need them? Can't subdivide a mesh properly? If any of this sounds familiar check this course out.
# 1 22-10-2013 , 10:04 PM
Subscriber
Join Date: Sep 2013
Posts: 3

Script for Boolean Operation not working?

Hey SimplyMaya,

I pretty new to this forum and I desperately need some help with a Python script that I came up with for a boolean operation.
Line 33 (highlighted in red) reports a runtime error: "Must have exactly 2 polygons selected."


Code:
import maya.cmds as mc
import maya.mel as mel
import random

random.seed(5)

### Varibale defining which boolean operation will be used:
### 1 = union, 2 = difference, 3 = intersection
booleanOp = 1


for i in range(20):
   name = "MyObject" + str(i)
   mc.polyCube(n=name, w=1, d=1, h=1)
   mc.move(random.uniform(-0.5,0.5), random.uniform(-0.5,0.5), random.uniform(-0.5,0.5))
   mc.scale(random.uniform(2.5,3.5), random.uniform(2.5,3.5), random.uniform(2.5,3.5))


mc.polyBoolOp("MyObject0", "MyObject1", op=booleanOp, n="MyResult1")


for next in range(2, 20):
    objNext = "MyObject" + str(next)
    
    previous = next - 1
    objPrevious = "MyObject" + str(previous)
    
    result = "MyResult" + str(next)

    mc.polyBoolOp(objPrevious, objNext, op=booleanOp, n=result)
    

mc.rename("MyResult19", "MyResult0")


for j in range(20):
    mc.polyCylinder(n="MyCylinder"+str(j), h=random.randrange(8, 9), r=random.uniform(0.05, 0.1))
    mc.move(random.randrange(-1, 1), random.randrange(-1, 1), random.randrange(-1, 1), )
    
    mel.eval('mc.polyBoolOp(op=2, n="MyResult") + str(j+1) + "MyResult" + str(j) + "MyCylinder" + str(j)')
objPrevious and objNext are defined variables that should provide the geometry for the boolean operation, but I still get the error. Any ideas?

Thanks

# 2 23-10-2013 , 05:34 AM
ctbram's Avatar
Moderator
Join Date: Jan 2004
Location: Michigan, USA
Posts: 2,998
In your script when you perform a boolean union on two objects those objects are consumed and produce a new object. For example consider the pseudo code union(MyObject0, MyObject1, MyResult1)

The result is a new object MyResult1 and although the shape nodes for MyObject0 and MyObject1 still exist you cannot use either in another union operation.

To show this create two objects in a scene and do a boolean union on them and then look in the outliner. You will see that the source objects now appear as a group with nothing but a transform node. You can select and transform the group and the original union will be updated but you cannot use either of the original objects as an argument to another union operation.


"If I have seen further it is by standing on the shoulders of giants." Sir Isaac Newton, 1675
# 3 23-10-2013 , 05:57 AM
ctbram's Avatar
Moderator
Join Date: Jan 2004
Location: Michigan, USA
Posts: 2,998
If your goal is to create a group of randomly transformed cubes and then union them into a single object this code will achieve that ...

I am not quite clear on what you are trying to do in the last for loop with the 20 cylinders.

Please note I am not really a Python guy and so there my be a better way to do this. I just googled stuff and cobbled this together based on bits of your original code.

Code:
import maya.cmds as mc
import maya.mel as mm
import random
import time

random.seed(time.clock())

boolOp = 1  # boolean union
count = 20 # number of cubes to create

# create <count> polycubes and randomly move and scale them
for i in range(count):
    name = "myObject" + str(i)
    mc.polyCube(n=name, w=1, d=1, h=1)
    mc.move(random.uniform(-0.5, 0.5), random.uniform(-0.5, 0.5), random.uniform(-0.5, 0.5))
    mc.scale(random.uniform(2.5, 3.5), random.uniform(2.5, 3.5), random.uniform(2.5, 3.5))
    
# combine the first pair of cubes with a boolean union and create the initial resulting object myResult0
mc.polyBoolOp("myObject0", "myObject1", op=boolOp, n="myResult0")

# perform a boolean union of all the remaining polycubes (2..19) 
for i in range(2,count):
    mc.polyBoolOp("myObject" + str(i), "myResult" + str(i-2), op=boolOp, n="myResult" + str(i-1))

# delete all the intermediate nodes created by the boolean unions
# leaving a single poly object myResult<count-2>
mc.DeleteAllHistory()


"If I have seen further it is by standing on the shoulders of giants." Sir Isaac Newton, 1675

Last edited by ctbram; 23-10-2013 at 06:57 AM.
# 4 23-10-2013 , 07:27 PM
Subscriber
Join Date: Sep 2013
Posts: 3
Wow, thanks for your help! user added image

To be a little more precise, the last part of my script should have generated a number of cylinders with random parameters and subtracted them from the cube formation of the previous boolean operation.

Thanks again.

# 5 23-10-2013 , 10:49 PM
ctbram's Avatar
Moderator
Join Date: Jan 2004
Location: Michigan, USA
Posts: 2,998
Ah I suspected that was the idea of the last loop but it seems to have a number of syntax errors and what appear to be logic errors so I could not quite figure out what your plan was.

1) the mc.move line has an extra "," and the end
2) random.randrange(8,9) picks an integer from the range [8,9-1] == [8]???
3) random.randrange(-1,1) picks an integer from the range [-1,0]
4) the entire eval() line appears to be syntactically incorrect


"If I have seen further it is by standing on the shoulders of giants." Sir Isaac Newton, 1675
Posting Rules Forum Rules
You may not post new threads | You may not post replies | You may not post attachments | You may not edit your posts | BB code is On | Smilies are On | [IMG] code is On | HTML code is Off

Similar Threads