CGTalk > Software > Autodesk Maya > Maya Programming
Login register
Thread Closed share thread « Previous Thread | Next Thread »  
Thread Tools Search this Thread Display Modes
Old 12-27-2007, 11:15 PM   #1
Matthias Buehler
Zurich, CH
Join Date: Feb 2007
Posts: 287
scripting with booleans ...

hey there.

i am currently scripting an «edge crusher» script with the boolean difference command.

but somehow the command cannot compute all results even though all the mesh pairs should be mathematically closed and ok. (history is off too !)

are there any known issues with the stability of the boolean commands ? any cv amount limitations ?


else, the script would be a little dream...
Old 12-28-2007, 03:01 AM   #2
Patrik Hadorn
Join Date: Apr 2005
Posts: 344
hey matthias
hmm..i already had some problems with the boolean command. but i can't tell you if this has something to do with your script.

maybe you could post the script or maybe a screenshot or whatever so we can better see your problem.

what do you try to do?

have a nice evening!
Old 12-28-2007, 04:45 PM   #3
Matthias Buehler
Zurich, CH
Join Date: Feb 2007
Posts: 287
aah, nice... night-active person !


i'll post the script now...

one minute...

* * *

let me make an other post for that ...
Old 12-28-2007, 04:46 PM   #4
Matthias Buehler
Zurich, CH
Join Date: Feb 2007
Posts: 287
if (`window -exists "edgeCrusherWindow"` == 1){deleteUI "edgeCrusherWindow";}

window -title "edgeCrusherWindow" -mnb 0 -mxb 0 edgeCrusherWindow;
columnLayout -adjustableColumn 1;
setParent ..;
setParent ..;

frameLayout -label "INFO AND USE" -cll true -collapse 1;
text -l "crushes poly edges for realism";
text -l "scripted by deadalvs, dec 07";
text -l "";
text -l "select edges before hitting the button";
text -l "";
text -l "";
text -l "uvs get ****ed up, just re-project them";
text -l "";
text -l "HAVE FUN !";

setParent ..;
setParent ..;

frameLayout -label "SETTINGS" -cll true;
text -l "";
text -l "approximative edge Radius";
floatField -v 0.035 edgeRadiusFloatField;
text -l "subdivisions per unit";
intField -v 16 subdivIntField;
text -l "roughness [%]";
floatField -v 25 roughnessFloatField;
text -l "crushing probability [%]";
floatField -v 25 crushingProbabilityFloatField;
checkBox -l "use secondary crushing subdivision" secondaryCrushingBox;
text -l "";
text -l "";
button -label "CRUSH !" -command "d_crushEdges();";
setParent ..;
setParent ..;
showWindow edgeCrusherWindow;

global proc d_crushEdges(){
global float $edgeRadius;
$edgeRadius = `floatField -q -v edgeRadiusFloatField`;
global float $subdiv;
$subdiv = `intField -q -v subdivIntField`;

string $selectedEdges[] = `ls -sl -fl`;

for ($eachSelectedEdge in $selectedEdges){
string $buffer[];
$numTokens = `tokenize $eachSelectedEdge "." $buffer`;
global string $meshToCrush;
$meshToCrush = $buffer[0];

string $pi[]=`polyInfo -edgeToVertex ($eachSelectedEdge )`;
string $piParts[];
tokenize $pi[0] $piParts;
//print ("#verts: "+(size($piParts)-2)+"\n");
int $CVNum_A = $piParts[2];
int $CVNum_B = $piParts[3];
vector $PosA = `pointPosition -w ($meshToCrush + ".vtx[" + ($CVNum_A) + "]")`;
vector $PosB = `pointPosition -w ($meshToCrush + ".vtx[" + ($CVNum_B) + "]")`;
//calc both vertex normals for the active edge
vector $VTXNormalA = `d_getPolyVertexNormal(($meshToCrush + ".vtx[" + ($CVNum_A) + "]"))`;
vector $VTXNormalB = `d_getPolyVertexNormal(($meshToCrush + ".vtx[" + ($CVNum_B) + "]"))`;
//calc "edge normal" by averaging the two vertex normals
vector $edgeNormal = unit ($VTXNormalA + $VTXNormalB);
//print ($eachSelectedEdge + "\n");
//print ($edgeNormal + "\n");
float $edgeLength = abs ($PosA - $PosB);
spaceLocator -n "EdgeVertex_A" -p 0 0 0;
move -a ($PosA.x) ($PosA.y) ($PosA.z);
spaceLocator -n "EdgeVertex_B" -p 0 0 0;
move -a ($PosB.x) ($PosB.y) ($PosB.z);
aimConstraint EdgeVertex_A EdgeVertex_B;
//getRotation !
float $rotBX = `getAttr EdgeVertex_B.rotateX`;
float $rotBY = `getAttr EdgeVertex_B.rotateY`;
float $rotBZ = `getAttr EdgeVertex_B.rotateZ`;
vector $edgeOrientation = <<$rotBX, $rotBY, $rotBZ>>;
select -r EdgeVertex_A;
select -add EdgeVertex_B;
polyCylinder -r 0.05 -h (($edgeLength) / $subdiv * ($subdiv + 2)) -sx 4 -sy ($edgeLength * $subdiv +2) -sz 1 -ax 1 0 0 -rcp 0 -cuv 3 -ch 1 -n "crushCylinder_1";
//deformation Process
string $lastCreatedCylinderArray[] = `ls - sl`;
string $lastCreatedCylinder = $lastCreatedCylinderArray[0];
//$lastCreatedCylinder = "pCylinder1";
select ($lastCreatedCylinder + ".vtx[0:1000000]");
string $selectedCVArray[] = `ls -sl -fl`;

vector $PosLastCV = `pointPosition -w ($selectedCVArray[(size ($selectedCVArray)-1)])`;
vector $PosSecondLastCV = `pointPosition -w ($selectedCVArray[(size ($selectedCVArray)-2)])`;

//scale end 2nd last
select -r $selectedCVArray[0];
select -add $selectedCVArray[1];
select -add $selectedCVArray[2];
select -add $selectedCVArray[3];
select -add $selectedCVArray[(size ($selectedCVArray)-2)];
scale -r -p ($PosSecondLastCV.x) ($PosSecondLastCV.y) ($PosSecondLastCV.z) .1 .1 .1 ;

//scale end last
select -r $selectedCVArray[(size ($selectedCVArray)-3)];
select -add $selectedCVArray[(size ($selectedCVArray)-4)];
select -add $selectedCVArray[(size ($selectedCVArray)-5)];
select -add $selectedCVArray[(size ($selectedCVArray)-6)];
select -add $selectedCVArray[(size ($selectedCVArray)-1)];
scale -r -p ($PosLastCV.x) ($PosLastCV.y) ($PosLastCV.z) .1 .1 .1 ;

//calc max travel dist for not corrupting the model with randomizing the cvs
// r !< small edge length of crushCylinder, then divided by 2
vector $PosDistCV_A = `pointPosition -w ($selectedCVArray[6])`;
vector $PosDistCV_B = `pointPosition -w ($selectedCVArray[10])`;
global float $edgeDist;
$edgeDist = abs (mag ($PosDistCV_A - $PosDistCV_B));
global float $maxMoveDistX;
$maxMoveDistX = $edgeDist;

// move all cvs a little
//but first create a new selection
select -r $selectedCVArray;
select -d $selectedCVArray[0];
select -d $selectedCVArray[1];
select -d $selectedCVArray[2];
select -d $selectedCVArray[3];
select -d $selectedCVArray[(size ($selectedCVArray)-2)];
select -d $selectedCVArray[(size ($selectedCVArray)-3)];
select -d $selectedCVArray[(size ($selectedCVArray)-4)];
select -d $selectedCVArray[(size ($selectedCVArray)-5)];
select -d $selectedCVArray[(size ($selectedCVArray)-6)];
select -d $selectedCVArray[(size ($selectedCVArray)-1)];

string $selectedInnerCVArray[] = `ls -sl -fl`;

for ($eachInnerCV in $selectedInnerCVArray){
global float $maxMoveDistX;
$maxMoveDistX = $maxMoveDistX * .9 * ((`floatField -q -v roughnessFloatField`) / 100);
global float $edgeRadius;
$edgeRadius = `floatField -q -v edgeRadiusFloatField`;
$edgeRadius = $edgeRadius * .5 * ((`floatField -q -v roughnessFloatField`) / 100);

select $eachInnerCV;
move -r (rand (-$maxMoveDistX, $maxMoveDistX)) (rand (-$edgeRadius, $edgeRadius)) (rand (-$edgeRadius, $edgeRadius));
if (`checkBox -q -v secondaryCrushingBox` == 1){

polySubdivideFacet -dv 1 -m 0 -ch 1 $lastCreatedCylinder ;
select -r $selectedInnerCVArray;

string $selectedSubdividedFacesArray[] = `ls -sl -fl`;
for ($eachSubdividedFace in $selectedSubdividedFacesArray){
global float $maxMoveDistX;
$maxMoveDistX = $maxMoveDistX * 0.08;
global float $edgeRadius;
$edgeRadius = `floatField -q -v edgeRadiusFloatField`;
$edgeRadius = $edgeRadius * .45;

select $eachSubdividedFace;
move -r (rand (-$maxMoveDistX, $maxMoveDistX)) (rand (-$edgeRadius, $edgeRadius)) (rand (-$edgeRadius, $edgeRadius));
//end if checkBox

select -r $lastCreatedCylinder;
move -r (($PosA.x + $PosB.x)/2) (($PosA.y + $PosB.y)/2) (($PosA.z + $PosB.z)/2);
rotate -r ($edgeOrientation.x) ($edgeOrientation.y) ($edgeOrientation.z);
// end eachEdgeLoop

select "crushCylinder_*";
select -d "*Shape*";
string $crushCylinderArray[] = `ls -sl -fl`;

for ($eachCylinder in $crushCylinderArray){

//$eachCylinder = "crushCylinder_1";
// print $eachCylinder;
global string $meshToCrush;
select -r $meshToCrush;
select -tgl $eachCylinder;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// deactivate booleans here by commenting out the polyBoolOp command !
polyBoolOp -op 2 -ch 0 -useThresholds 1;
pickWalk -d up;
rename ($meshToCrush);
select -cl;
//end booleanloop

//end d_crushEdges

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// d_getPolyVertexNormal script

//input string
//output vector
string $targetVertex = "pCube1.vtx[5]" ;


global proc vector d_getPolyVertexNormal(string $targetVertex){

select $targetVertex;
string $buffer[];
$numTokens = `tokenize $targetVertex "." $buffer`;
string $targetMesh = $buffer[0];

string $pi[] = `polyInfo -vertexToFace`;
string $piParts[];
tokenize $pi[0] $piParts;
int $i;
int $faceID;
vector $vNorm = 0;
vector $fNorm;
string $pi2[], $piParts2[];
for ($i = 2; $i< size($piParts); $i++){
$faceID = $piParts[$i];
$pi2 = `polyInfo -faceNormals ($targetMesh + ".f[" + $faceID + "]")`;
tokenize $pi2[0] $piParts2;
$fNorm = << float ($piParts2[2]),
float ($piParts2[3]),
float ($piParts2[4]) >>;
$vNorm += $fNorm;
$vNorm = `unit $vNorm`;

return $vNorm ;

//end d_getPolyVertexNormal

Old 12-28-2007, 04:56 PM   #5
Matthias Buehler
Zurich, CH
Join Date: Feb 2007
Posts: 287
i hope that text can be copy-pasted wo it works properly !

• just select an edge of a cube or whatever object and hit the crush button.
• when the object disappears with an error, the boolean command failes
• the input filed about probability is not yet built-in, so altering that value does nothing.
• important: the boolean command is not executed when commented out at the proper position in the script. there's a note with a lot of ///////// signs.

the idea of the script is first creating a lot of randomized cylinders for each selected object and then subtract these from the selected object to simulate crushed edges.
the mentioned probability input field would move the geomety away from the «edge normal» that i calculate from the two vertex normals by averaging.

the script has still a few issues, especially the mentioned failing boolean command and that the cylinder is not the perfect type of object to be place on the edges...


i guess i'll have to re-write the script because it lacks a little of everything... well..
Old 12-28-2007, 05:03 PM   #6
Patrik Hadorn
Join Date: Apr 2005
Posts: 344
phu... i think you have still a lot of things in the script which could be shorted.
could you explain what the steps you're doing to achieve this effect?

the error message you get means that the boolean operation deletes all geometry. so maybe one of the objects is too big.

i'm sorry i don't have enough time to read through it because i'm going out tonight with some friends. if i'm still ok when i return i'll take some time to work on your problem.

have a nice evening and "pfuus de guet" ;-D
Old 12-28-2007, 05:21 PM   #7
Matthias Buehler
Zurich, CH
Join Date: Feb 2007
Posts: 287
ah ... noooo problem...

this is more a hobby-project than a rational to-use script ...

i know ... it's a little long and could certainly be majorly shortened, but this was just the first approach...

* * *

the steps.

1) window

2) procedure that crushed the edge (directly called from the window)
2.1) get values from GUI
2.2) list all selected edges
2.3) for each edge loop:
2.4) calc the two vertex normals
2.5) calc the edge normal
2.6) calc the xyz rotation in [deg] for an object to look from one vertex to the other
2.7) create a cylinder, deform it, maybe subdivide it if checkBox ==1
(the deformations are based on the cv circles along the cylinder. this is why the cvs are directly called... self-intersecting geometry cannot be computed by the boolean command, this is why the cv randomizing must be controlled locally inside the smallest distance between the cvs, divided by 2)
2.8) move the cylinder to place
2.9) rotate the cylinder
2.10) end loop

3.1) select all cylinders
3.2) run thru each cylinder and boole it away.
3.3) rename the newly booled surface to the old name

* * *

don't bother ... a solution is not really needed... if the boolean command cannot trim meshes with many faces/subdivisions, the script itself is useless... !

have a nice evening !

greets !
Old 12-29-2007, 01:27 PM   #8
Patrik Hadorn
Join Date: Apr 2005
Posts: 344
your scripting style could still be improved :-D it was quite exhausting to read through.

what i can say about your script is that it's working. the problem is that your cylinder objects are heavily deformed and because of this you can't use them for boolean operations. well you can but the result is an object without geometry.

here you can see one of those overdeformed cylinders:

you can see that with this object you can't really calculate the boolean operation.

another problem with your script is that you get a lot of n-gons which could make some problems during the render process
Old 12-29-2007, 01:48 PM   #9
Matthias Buehler
Zurich, CH
Join Date: Feb 2007
Posts: 287
if i ever had learned scripting properly... :(
yes, i hate the looks of the script too... i've made better ones... way better ones .. ! hehe.

i know there are issues with over-deformed cylinders when going above 100% roughness... but even with very little deformation that normally should work, i have gotten proplems with the boolean command...

the n-gons certainly are an issue, but remapping the UVs helps a bit for the looks...

* * *

i guess the approach with booleans is a simplistic one... but thinking of a different way to do this sort of crushing effect... i could not find an other fast answer.
Old 12-29-2007, 01:48 PM   #10
CGTalk Moderation
CGTalk Forum Leader
Join Date: Sep 2003
Posts: 1,066,478
Thread automatically closed

This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.
CGTalk Policy/Legalities
Note that as CGTalk Members, you agree to the terms and conditions of using this website.
Thread Closed share thread

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Society of Digital Artists

Powered by vBulletin
Copyright ©2000 - 2006,
Jelsoft Enterprises Ltd.
Minimize Ads
Forum Jump

All times are GMT. The time now is 11:22 AM.

Powered by vBulletin
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.