· 8 years ago · Feb 14, 2018, 01:22 PM
1/*
2abSymMesh v 1.91
3brendan ross 03.10.2004
4www.supercrumbly.com
5
6update -- 09.20.2004: "Select Moved Verts" button will select vertices that have been moved relative to the base mesh.
7update -- 3.21.2005: Added progress bar for "Select Moved Verts". I love progress bars.
8update -- 10.12.2006: Added popupMenu to "Revert Selected to Base" button to revert by a given percentage. Added $abSymProgBarThresh to adjust the number of verts included in an operation before a progress bar will be displayed (adjust higher for faster computers).
9update -- 10.25.2006: Added a slider to dynamically revert selected verts to base object. The slider only works on vertex selections, not on the object level (too slow). You can now specify alternate versions of the base mesh to revert to as well. Improved performance of revert.
10update -- 12.04.2006: It should now work in Maya 8.
11update -- 4.12.2008: Added operations menu. Allows you to copy, add and subtract blendshapes from one another.
12update -- 1.29.2009: Added limited ability to establish symmetry.
13update -- 9.19.2013: Added "Attempt To Restore Symmetry" to (new) "Tools" menu.
14update -- v. 1.91 datae: 10.28.2013: Added float field to the revert slider. Fixed issue with duplicate menu name preventing script from loading.
15
16use:
17
18A useful little script for building symmetrical and asymmetrical blendshapes. Check for symmetry, mirror
19and flip polygon geometry, and much more.
20
21(ok, not much more, but it is pretty useful)
22
23directions:
24
25It should be fairly self explanatory, but here goes.
26
27Select a mesh and click "Check Symmetry" to highlight asymmetric vertices.
28
29To use the selection mirror, mirror selected, flip, and revert functions, you must first select a symmetrical mesh
30and click "Select Base Geometry." You can now select a duplicate mesh with the same structure, and you should be
31able to use all of the functions on it. Revert, mirror, and flip work on both vertex (component) and object selections.
32
33Uncheck "Use Pivot as Origin" to evaluate your objects using the mirror axis world origin as
34your axis of symmetry.
35
36That's it. I hope you find it useful.
37*/
38
39global int $abSymProgBarThresh = 800; //number of verts in an operation beyond which a progress bar is shown (set higher for faster computers)
40global int $abSymTable[];
41
42global string $abSymRevVertTable[];
43global vector $abSymRevPosTable[];
44global vector $abSymRevBasePosTable[];
45global int $abSymSliderDragging = false; //used to flag when the mouse is dragging a slider
46
47global proc string[] abCheckSym(string $obj, int $axis, float $tol, int $bTable, int $usePiv) {
48 //$bTable is bool to use $obj to create and populate $abSymTable
49 //which goes a little like {obj.vtx[pos mAxis 1], obj.vtx[neg mAxis 1]}
50
51 global int $abSymTable[];
52 string $aNegVerts[];
53 string $aPosVerts[];
54 string $aNonSymVerts[];
55 string $aStr[];
56 string $vtx;
57 string $str;
58 int $aPosVertsInt[];
59 int $aNegVertsInt[];
60 int $aInt[];
61 int $totVtx;
62 int $i;
63 int $j;
64 int $mAxisInd = $axis - 1; //mirror axis index (for xform)
65 int $axis2Ind = ($mAxisInd + 1) % 3;
66 int $axis3Ind = ($mAxisInd + 2) % 3;
67 int $mod;
68 int $prog;
69 int $vertCounter = 0;
70 float $aNegVertTrans[];
71 float $aPosVertTrans[];
72 float $aVtxTrans[];
73 float $aVtx2Trans[];
74 float $bBox[];
75 float $mid;
76 float $midOffset;
77 float $posOffset;
78 float $negOffset;
79 float $flt;
80 float $progNum;
81 float $progDenom;
82 float $test1;
83 float $test2;
84
85 float $midOffsetTol = -.0000001;
86
87 if ($usePiv){
88 $aVtxTrans = `xform -q -ws -t $obj`;
89 $mid = $aVtxTrans[$mAxisInd];
90 }else{
91 if ($bTable){
92 $bBox = `xform -q -ws -boundingBox $obj`;
93 $mid = $bBox[$mAxisInd] + (($bBox[($mAxisInd+3)] - $bBox[$mAxisInd])/2);
94 }else{
95 $mid = 0; //if object isn't symmetrical, it's got to be at the origin to measure symmetry
96 }
97 }
98
99 if ($bTable) clear($abSymTable);
100
101 $aInt = `polyEvaluate -v $obj`;
102 $totVtx = $aInt[0];
103
104 waitCursor -state on;
105 progressWindow -title "Working" -progress 0 -status "Sorting";
106 $progDenom = $totVtx;
107 $flt = ceil($progDenom/50);
108 $mod = $flt;
109
110 for ($i=0;$i<$totVtx;$i++){
111
112 //prog win
113 if (($i % $mod) == 0){ //make the progress bar a bit less resource intensive
114 $progNum = $i;
115 $prog = ($progNum/$progDenom)*100.0;
116 progressWindow -e -progress $prog;
117 }
118 //end prog win
119
120 $vtx = $obj+".vtx["+$i+"]";
121 $aVtxTrans = `xform -q -ws -translation $vtx`;
122 $midOffset = $aVtxTrans[$mAxisInd] - $mid;
123 if ($midOffset >= $midOffsetTol){
124 $aPosVerts[size($aPosVerts)] = $vtx;
125 if ($bTable){$aPosVertsInt[size($aPosVertsInt)] = $i;}
126 $aPosVertTrans[size($aPosVertTrans)] = $aVtxTrans[$mAxisInd];
127 }else{
128 if ($midOffset < $midOffsetTol){
129 $aNegVerts[size($aNegVerts)] = $vtx;
130 if ($bTable){$aNegVertsInt[size($aNegVertsInt)] = $i;}
131 $aNegVertTrans[size($aNegVertTrans)] = $aVtxTrans[$mAxisInd];
132 }
133 }
134 }
135
136 if ($bTable){$str = "Building Symmetry Table";}else{$str = "Checking For Symmetry";}
137 progressWindow -e -progress 0 -status $str;
138 $progDenom = size($aPosVerts);
139 $flt = ceil($progDenom/50);
140 $mod = $flt;
141
142 //now find nonsymverts
143 for ($i=0;$i<size($aPosVerts);$i++){
144
145 //prog win
146 if (($i % $mod) == 0){ //make the progress bar a bit less resource intensive
147 $progNum = $i;
148 $prog = ($progNum/$progDenom)*100.0;
149 progressWindow -e -progress $prog;
150 }
151 //end prog win
152
153 $vtx = $aPosVerts[$i];
154 $posOffset = ($aPosVertTrans[$i] - $mid);
155 if ($posOffset < $tol){
156 $aPosVerts[$i] = "m";
157 $vertCounter ++;
158 continue;
159 }
160 for ($j=0;$j<size($aNegVerts);$j++){
161 if ($aNegVerts[$j] == "m") continue;
162 $negOffset = $mid - $aNegVertTrans[$j];
163 if ($negOffset < $tol){
164 $aNegVerts[$j] = "m";
165 $vertCounter ++;
166 continue;
167 }
168 if (abs($posOffset - $negOffset) <= $tol){
169 $aVtxTrans = `xform -q -ws -t $vtx`;
170 $aVtx2Trans = `xform -q -ws -t $aNegVerts[$j]`;
171 $test1 = $aVtxTrans[$axis2Ind] - $aVtx2Trans[$axis2Ind];
172 $test2 = $aVtxTrans[$axis3Ind] - $aVtx2Trans[$axis3Ind];
173 if (abs($test1) < $tol && abs($test2) < $tol){
174 //match
175 if ($bTable){
176 //use this info to build symmetry table
177 $abSymTable[size($abSymTable)] = $aPosVertsInt[$i];
178 $abSymTable[size($abSymTable)] = $aNegVertsInt[$j];
179 $vertCounter += 2;
180 }
181 $aPosVerts[$i] = $aNegVerts[$j] = "m"; //m is for match
182 break;
183 }
184 }
185 }
186 }
187 //now strip out "m" from $aPosVerts and $aNegVerts, and we'll have asymmetry
188 $aStr = {"m"};
189 $aPosVerts = stringArrayRemove($aStr, $aPosVerts);
190 $aNegVerts = stringArrayRemove($aStr, $aNegVerts);
191 $aNonSymVerts = stringArrayCatenate($aPosVerts, $aNegVerts);
192
193 if ($bTable){
194 $int = size($abSymTable) + $vertCounter;
195 if ($vertCounter != $totVtx){
196 //object is not symmetrical
197 warning "Base geometry is not symmetrical, not all vertices can be mirrored";
198 }else{
199 print "Base geometry is symmetrical";
200 }
201 }
202 progressWindow -endProgress;
203 waitCursor -state off;
204 return $aNonSymVerts;
205}
206
207
208global proc int abGetSymVtx(int $vtxInt){
209 //uses abSymTable, returns symmetrical vtx or -1 if failed
210 global int $abSymTable[];
211 int $mVtxInt = -1;
212 int $i;
213
214 for ($i=0;$i<size($abSymTable);$i++){
215 if ($vtxInt == $abSymTable[$i]){
216 //match
217 if (($i % 2) == 0){
218 //even number, match is record above (it's a positive vert)
219 $mVtxInt = $abSymTable[$i+1];
220 }else{
221 $mVtxInt = $abSymTable[$i-1];
222 }
223 break;
224 }
225 }
226 return $mVtxInt;
227}
228
229
230global proc abMirrorSel(string $obj, string $baseObj, string $aSelVerts[], int $axis, int $negToPos, int $flip, int $usePiv, float $tol){
231 //$axis is 1, 2, 3 -- $negToPos is bool -- true mirrors negative (axis) to positive (axis)
232 //$flip is bool -- if true, selVerts are flipped instead of mirrored
233 //$usePiv is bool to use pivot on $obj as origin
234 global int $abSymTable[];
235 global int $abSymProgBarThresh;
236
237 string $aStr[];
238 string $str;
239 string $vtx;
240 string $obj;
241 int $aPosVertsInt[];
242 int $aNegVertsInt[];
243 int $aZeroVertsInt[];
244 int $mAxisInd = $axis - 1; //mirror axis index (for xform)
245 int $axis2Ind = ($mAxisInd + 1) % 3;
246 int $axis3Ind = ($mAxisInd + 2) % 3;
247 int $vertNum;
248 int $i;
249 int $j;
250 int $prog;
251 int $mod;
252 int $showProg = false; //don't show the progress bar
253 float $bBox[];
254 float $baseMid;
255 float $baseMidOffset;
256 float $aVtxTrans[];
257 float $aFlpVtxTrans[];
258 float $mid; //mirror axis midpoint
259 float $progNum;
260 float $progDenom;
261 float $flt;
262
263 if ($usePiv){
264 $aVtxTrans = `xform -q -ws -t $obj`;
265 $mid = $aVtxTrans[$mAxisInd];
266 $aVtxTrans = `xform -q -ws -t $baseObj`;
267 $baseMid = $aVtxTrans[$mAxisInd];
268 }else{
269 $mid = 0;
270 $bBox = `xform -q -ws -boundingBox $baseObj`;
271 $baseMid = $bBox[$mAxisInd] + (($bBox[($mAxisInd+3)] - $bBox[$mAxisInd])/2);
272 }
273
274 waitCursor -state on;
275 if (size($aSelVerts) > $abSymProgBarThresh){ //show prog if more than this many verts being mirrored
276 $showProg = true;
277 $str = "Mirroring Vertices";
278 if ($flip){$str = "Flipping Vertices";}
279 progressWindow -title "Working" -progress 0 -status $str;
280 $progDenom = size($aSelVerts);
281 $flt = ceil($progDenom/50);
282 $mod = $flt;
283 }
284
285 //strip out Pos verts if $negToPos is true (and vice versa)
286 //aposverts (and anegverts) are int arrays in this proc to simplify matching
287 //get pos neg info from base mesh
288 for ($i=0;$i<size($aSelVerts);$i++){
289
290 //prog win
291 if ($showProg){
292 if (($i % $mod) == 0){ //make the progress bar a bit less resource intensive
293 $progNum = $i;
294 $prog = ($progNum/$progDenom)*50.0;
295 progressWindow -e -progress $prog;
296 }
297 }
298 //end prog win
299
300 $vtx = $aSelVerts[$i];
301 //$aVtxTrans = `xform -q -ws -translation $vtx`;
302 $vertNum = match("([0-9])+", (match ("([0-9])+\\]", $vtx)));
303 $aVtxTrans = `xform -q -ws -translation ($baseObj+".vtx["+$vertNum+"]")`;
304 $baseMidOffset = $aVtxTrans[$mAxisInd] - $baseMid;
305 if (abs($baseMidOffset) < $tol){
306 $aZeroVertsInt[size($aZeroVertsInt)] = $vertNum;
307 continue;
308 }
309 if ($baseMidOffset > 0){
310 $aPosVertsInt[size($aPosVertsInt)] = $vertNum;
311 continue;
312 }
313 if ($baseMidOffset < 0){
314 $aNegVertsInt[size($aNegVertsInt)] = $vertNum;
315 continue;
316 }
317 }
318
319 if ($negToPos){
320 $aPosVertsInt = $aNegVertsInt;
321 }
322
323 if ($showProg){
324 $progDenom = size($aPosVertsInt);
325 $flt = ceil($progDenom/50);
326 $mod = $flt;
327 }
328
329 for ($i=0;$i<size($aPosVertsInt);$i++){
330
331 //prog win
332 if ($showProg){
333 if (($i % $mod) == 0){ //make the progress bar a bit less resource intensive
334 $progNum = $i;
335 $prog = ($progNum/$progDenom)*50.0 + 50;
336 progressWindow -e -progress $prog;
337 }
338 }
339 //end prog win
340
341 $vertNum = abGetSymVtx($aPosVertsInt[$i]);
342 if ($vertNum != -1){
343 if (!$flip){ //mirror selected
344 $aVtxTrans = `xform -q -ws -t ($obj+".vtx["+$aPosVertsInt[$i]+"]")`;
345 $aVtxTrans[$mAxisInd] = 2*$mid - $aVtxTrans[$mAxisInd];
346 xform -ws -t $aVtxTrans[0] $aVtxTrans[1] $aVtxTrans[2] ($obj+".vtx["+$vertNum+"]");
347 }else{ //flip selected
348 $aVtxTrans = `xform -q -ws -t ($obj+".vtx["+$aPosVertsInt[$i]+"]")`;
349 $aVtxTrans[$mAxisInd] = 2*$mid - $aVtxTrans[$mAxisInd];
350 $aFlpVtxTrans = `xform -q -ws -t ($obj+".vtx["+$vertNum+"]")`;
351 $aFlpVtxTrans[$mAxisInd] = 2*$mid - $aFlpVtxTrans[$mAxisInd];
352 xform -ws -t $aVtxTrans[0] $aVtxTrans[1] $aVtxTrans[2] ($obj+".vtx["+$vertNum+"]");
353 xform -ws -t $aFlpVtxTrans[0] $aFlpVtxTrans[1] $aFlpVtxTrans[2] ($obj+".vtx["+$aPosVertsInt[$i]+"]");
354 }
355 }
356 }
357 for ($i=0;$i<size($aZeroVertsInt);$i++){ //flip middle verts too
358 if ($flip){
359 $aVtxTrans = `xform -q -ws -t ($obj+".vtx["+$aZeroVertsInt[$i]+"]")`;
360 $aVtxTrans[$mAxisInd] = 2*$mid - $aVtxTrans[$mAxisInd];
361 xform -ws -t $aVtxTrans[0] $aVtxTrans[1] $aVtxTrans[2] ($obj+".vtx["+$aZeroVertsInt[$i]+"]");
362 }else{
363 $aVtxTrans = `xform -q -ws -t ($obj+".vtx["+$aZeroVertsInt[$i]+"]")`;
364 $aVtxTrans[$mAxisInd] = $mid;
365 xform -ws -t $aVtxTrans[0] $aVtxTrans[1] $aVtxTrans[2] ($obj+".vtx["+$aZeroVertsInt[$i]+"]");
366 }
367 }
368 if ($showProg){progressWindow -endProgress;}
369 waitCursor -state off;
370}
371
372
373global proc abRevertSel(string $aSelVerts[], string $obj, string $baseObj, float $bias){
374 //reverts selected verts to base -os trans -- $bias is the percentage (0-1) to revert from current verts position to the base verts position, 100 taking on the base object's vert positions (original default behaviour)
375 global int $abSymProgBarThresh;
376
377 string $str;
378 string $vtx;
379 int $vertNum;
380 int $i;
381 int $prog;
382 int $mod;
383 int $showProg = false; //don't show the progress bar
384 float $aTrans[];
385 float $progNum;
386 float $progDenom;
387 float $flt;
388 float $tol = 0;
389 vector $vTol = <<$tol, $tol, $tol>>;
390 vector $vBaseTrans;
391 vector $vObjTrans;
392
393 if ($bias > 1){
394 $bias = 1;
395 }else if ($bias < 0){
396 $bias = 0;
397 }
398 $bias = 1 - $bias;
399 if ($bias < .01) $bias = 0;
400
401 if (size($aSelVerts) > $abSymProgBarThresh){ //show prog if more than this many verts being mirrored
402 $showProg = true;
403 progressWindow -title "Working" -progress 0 -status "Reverting Vertices";
404 $progDenom = size($aSelVerts);
405 $flt = ceil($progDenom/50);
406 $mod = $flt;
407 }
408
409 waitCursor -state on;
410 for ($i=0;$i<size($aSelVerts);$i++){
411 //prog win
412 if ($showProg){
413 if (($i % $mod) == 0){ //make the progress bar a bit less resource intensive
414 $progNum = $i;
415 $prog = ($progNum/$progDenom)*100;
416 progressWindow -e -progress $prog;
417 }
418 }
419 //end prog win
420 $vtx = $aSelVerts[$i];
421 $vertNum = match("([0-9])+", (match ("([0-9])+\\]", $vtx)));
422 $aTrans = `xform -q -os -t ($baseObj+".vtx["+$vertNum+"]")`;
423 $vBaseTrans = <<$aTrans[0], $aTrans[1], $aTrans[2]>>;
424
425 //bias stuff
426 $aTrans = `xform -q -os -t $vtx`;
427 $vObjTrans = <<$aTrans[0], $aTrans[1], $aTrans[2]>>;
428
429 if (abs($vObjTrans - $vBaseTrans) > $vTol) xform -os -t ($vBaseTrans.x+($vObjTrans.x-$vBaseTrans.x)*$bias) ($vBaseTrans.y+($vObjTrans.y-$vBaseTrans.y)*$bias) ($vBaseTrans.z+($vObjTrans.z-$vBaseTrans.z)*$bias) $vtx;
430 //done
431 }
432
433 if ($showProg){progressWindow -endProgress;}
434 waitCursor -state off;
435}
436
437
438global proc abSymInteractiveRevertToBase(){
439 //responds to revert to base slider movement
440
441 global string $abSymRevVertTable[];
442 global vector $abSymRevPosTable[];
443 global vector $abSymRevBasePosTable[];
444 global int $abSymSliderDragging;
445 global string $abAltSbg;
446 global string $abSbg;
447
448 int $i;
449 int $firstClick = false;
450
451 if ($abSymSliderDragging == false){
452 $abSymSliderDragging = true;
453
454 //check to see if selection is the same -- if it is, use the existing $abSymRevPosTable
455
456 string $aStr[], $selObj, $aSelVerts[], $aBaseVerts[];
457 int $buildNewTables = true;
458
459 $aStr = `filterExpand -sm 12`;
460 if (size($aStr) == 1){
461 $selObj = $aStr[0];
462 }else{
463 $aStr = `ls -hilite`;
464 if (size($aStr) == 1){
465 $selObj = $aStr[0];
466 }
467 }
468
469 $aSelVerts = `filterExpand -sm 31`;
470
471 if ($selObj != "" && size($aSelVerts) > 0){
472
473 if (size($aSelVerts) == size($abSymRevVertTable) && size($abSymRevVertTable) == size($abSymRevBasePosTable)){
474 $buildNewTables = false;
475 for ($i=0;$i<size($aSelVerts);$i++){
476 if ($aSelVerts[$i] != $abSymRevVertTable[$i]){
477 $buildNewTables = true;
478 break;
479 }
480 }
481 }
482
483 if ($buildNewTables){
484
485 abSymClearRevTables();
486
487 float $tol = .001;
488 float $aFlt[];
489 string $aBaseVerts[];
490 vector $vector1, $vector2;
491
492 string $baseObj = ($abAltSbg != "") ? $abAltSbg : $abSbg;
493
494 //make base verts array
495 for ($i=0;$i<size($aSelVerts);$i++){
496 $aBaseVerts[size($aBaseVerts)] = $baseObj+(`match "\\.vtx\\[([0-9])+]$" $aSelVerts[$i]`);
497 }
498
499 for ($i=0;$i<size($aSelVerts);$i++){
500
501 $aFlt = `xform -q -os -translation $aSelVerts[$i]`;
502 $vector1 = <<$aFlt[0], $aFlt[1], $aFlt[2]>>;
503 $aFlt = `xform -q -os -translation $aBaseVerts[$i]`;
504 $vector2 = <<$aFlt[0], $aFlt[1], $aFlt[2]>>;
505
506 if ((abs($vector1 - $vector2)) > <<$tol, $tol, $tol>>){
507
508 $abSymRevVertTable[size($abSymRevVertTable)] = $aSelVerts[$i];
509 $abSymRevPosTable[size($abSymRevPosTable)] = $vector1;
510 $abSymRevBasePosTable[size($abSymRevBasePosTable)] = $vector2;
511 }
512 }
513 }
514 }else{
515 abSymClearRevTables();
516 warning "Select vertices on one polygon object.";
517 }
518 $firstClick = true;
519 }
520
521 float $bias = `floatSlider -q -v rvrtFltSldr`;
522 float $aObjTrans[], $aBaseTrans[];
523 vector $vObjTrans, $vBaseTrans;
524
525 if (size($abSymRevVertTable) == size($abSymRevPosTable) && size($abSymRevPosTable) == size($abSymRevBasePosTable)){
526 for ($i=0;$i<size($abSymRevVertTable);$i++){
527
528 $vObjTrans = $abSymRevPosTable[$i];
529 $vBaseTrans = $abSymRevBasePosTable[$i];
530 xform -os -t ($vBaseTrans.x+($vObjTrans.x-$vBaseTrans.x)*$bias) ($vBaseTrans.y+($vObjTrans.y-$vBaseTrans.y)*$bias) ($vBaseTrans.z+($vObjTrans.z-$vBaseTrans.z)*$bias) $abSymRevVertTable[$i];
531 }
532 }
533
534 if ($firstClick) undoInfo -swf off;
535}
536
537
538global proc abSymEndDrag(){
539 //called when dragging is done
540
541 global int $abSymSliderDragging;
542
543 $abSymSliderDragging = false;
544 undoInfo -swf on;
545}
546
547
548global proc abSymClearRevTables(){
549 //clears out globals associated with dragging reversion slider
550
551 global string $abSymRevVertTable[];
552 global vector $abSymRevPosTable[];
553 global vector $abSymRevBasePosTable[];
554
555 clear $abSymRevVertTable;
556 clear $abSymRevPosTable;
557 clear $abSymRevBasePosTable;
558}
559
560
561global proc abSymUseAlternateBase(int $useAltBase){
562 //substitute alternate variation of this mesh as the base shape for revert commands -- $useAltBase is a boolean which determines whether to use the alternate base or to revert to original base object
563
564 global string $abAltSbg;
565 global string $abSbg;
566
567 string $aStr[];
568 int $aInt[], $totNewVtx, $totOrigVtx;
569
570
571 if ($useAltBase){
572 $aStr = `filterExpand -sm 12`;
573 if (size($aStr) == 1){
574
575 $aInt = `polyEvaluate -v $abSbg`;
576 $totOrigVtx = $aInt[0];
577 $aInt = `polyEvaluate -v $aStr[0]`;
578 $totNewVtx = $aInt[0];
579 if ($totOrigVtx = $totNewVtx){
580 //number of verts match up, so accept this mesh as a usable base
581
582 $abAltSbg = $aStr[0];
583 abSymClearRevTables();
584 menuItem -e -label ("Using "+$abAltSbg+" as Base") abSymCurBsMnIt;
585 menuItem -e -enable true abSymSlOrigRvtBsMnIt;
586 menuItem -e -enable true abSymSlAltMvVtsMnIt;
587
588 }else{
589 warning "The new base mesh must have the same number of vertices as the current base mesh.";
590 }
591 }else{
592 warning "Select a mesh to use as a base object.";
593 }
594 }else{
595 $abAltSbg = "";
596 abSymClearRevTables();
597 menuItem -e -label "Using Original Base" abSymCurBsMnIt;
598 menuItem -e -enable false abSymSlOrigRvtBsMnIt;
599 menuItem -e -enable false abSymSlAltMvVtsMnIt;
600
601 }
602}
603
604
605global proc string[] abSelMovedVerts(string $obj, string $baseObj, float $tol){
606 //select repositioned verts (as compared to the base mesh)
607 int $aInt[];
608 int $totVtx;
609 int $i;
610 int $j;
611 float $tFlt;
612 float $aVtxTrans[];
613 string $objStr = $obj+".vtx[";
614 string $baseObjStr = $baseObj+".vtx[";
615 string $aRetSel[];
616 string $vtx;
617
618 vector $vTrans1, $vTrans2;
619 vector $vTol = <<$tol, $tol, $tol>>;
620
621 $aInt = `polyEvaluate -v $obj`;
622 $totVtx = $aInt[0];
623
624 int $mod, $prog;
625 float $flt, $progNum, $progDenom;
626 float $progUpdate = 50.0;
627 waitCursor -state on;
628 progressWindow -title "Working" -progress 0 -status "Checking Verts";
629 $progDenom = $totVtx;
630 $flt = ceil($progDenom/$progUpdate);
631 $mod = $flt;
632
633 for ($i=0;$i<$totVtx;$i++){
634
635 //prog win
636 if (($i % $mod) == 0){ //make the progress bar a bit less resource intensive
637 $progNum = $i;
638 $prog = ($progNum/$progDenom)*100.0;
639 progressWindow -e -progress $prog;
640 }
641 //end prog win
642
643 $vtx = $objStr+$i+"]";
644 $aVtxTrans = `xform -q -os -t ($baseObjStr+$i+"]")`;
645 $vTrans1 = <<$aVtxTrans[0], $aVtxTrans[1], $aVtxTrans[2]>>;
646
647 $aVtxTrans = `xform -q -os -t $vtx`;
648 $vTrans2 = <<$aVtxTrans[0], $aVtxTrans[1], $aVtxTrans[2]>>;
649
650 if (abs($vTrans1 - $vTrans2) > $vTol) $aRetSel[size($aRetSel)] = $vtx;
651 }
652
653 progressWindow -endProgress;
654 waitCursor -state off;
655
656 return $aRetSel;
657}
658
659
660global proc abSMServiceAddSubtractCopy(int $operation){
661 // called by add, subtract and copy buttons in the menu -- if selection and basemesh are in order it calls abSMAddSubtractCopyMesh
662 // operation is passed to abSMAddSubtractCopyMesh
663
664 global string $abSbg;
665
666 if ($abSbg == ""){
667 warning "You must select a base mesh first.";
668 return;
669 }
670
671 string $aSel[] = `ls -sl`;
672
673 if (size($aSel) != 2){
674 warning "Select two mesh objects (source and target).";
675 return;
676 }
677
678 string $mesh, $aRel[];
679
680 int $aInt[] = `polyEvaluate -v $abSbg`;
681 int $baseVertNum = $aInt[0];
682
683 // make sure that both objects are meshes with the correct number of verts (same as base mesh) and neither is the basemesh
684 for ($mesh in $aSel){
685 // make sure neither mesh is the base mesh
686 if ($mesh == $abSbg){
687 warning "The basemesh cannot be used as a source or target. Try using revert instead.";
688 return;
689 }
690 $aRel = `listRelatives -type mesh`;
691 if (size($aRel) == 0){
692 warning ($mesh+" is not a mesh. Unable to proceed.");
693 return;
694 }else{
695 $aInt = `polyEvaluate -v $mesh`;
696 if ($aInt[0] != $baseVertNum){
697 warning ($mesh+" topology doesn't match the base object. Unable to proceed.");
698 return;
699 }
700 }
701 }
702
703 // ok, it's good to go
704 abSMAddSubtractCopyMesh($abSbg, $aSel[0], $aSel[1], $operation);
705
706}
707
708/*
709global proc abSMAddSubtractCopyMesh(string $baseMesh, string $source, string $target, int $operation){
710 // adds or subtracts one blend ($source) from another ($target) based on operation (0 == subtract, 1 == add, 2 == copy)
711
712 int $aInt[], $totVtx, $i;
713 float $aBaseVtxTrans[], $aSourceVtxTrans[], $aTargetVtxTrans[], $aSourceBaseOffset[];
714 string $baseMeshStr = $baseMesh+".vtx[";
715 string $sourceMeshStr = $source+".vtx[";
716 string $targetMeshStr = $target+".vtx[";
717
718
719 $aInt = `polyEvaluate -v $baseMesh`;
720 $totVtx = $aInt[0];
721
722 // get offset of source verts from baseMesh
723 for ($i=0;$i<$totVtx;$i++){
724
725 $aBaseVtxTrans = `xform -q -os -t ($baseMeshStr+$i+"]")`;
726 $aSourceVtxTrans = `xform -q -os -t ($sourceMeshStr+$i+"]")`;
727 $aTargetVtxTrans = `xform -q -os -t ($targetMeshStr+$i+"]")`;
728 $aSourceBaseOffset = {$aSourceVtxTrans[0]-$aBaseVtxTrans[0], $aSourceVtxTrans[1]-$aBaseVtxTrans[1], $aSourceVtxTrans[2]-$aBaseVtxTrans[2]};
729
730 if ($operation == 0){
731 // subtract
732 $aTargetVtxTrans = {$aTargetVtxTrans[0]-$aSourceBaseOffset[0], $aTargetVtxTrans[1]-$aSourceBaseOffset[1], $aTargetVtxTrans[2]-$aSourceBaseOffset[2]};
733 }else if ($operation == 1){
734 // add
735 $aTargetVtxTrans = {$aTargetVtxTrans[0]+$aSourceBaseOffset[0], $aTargetVtxTrans[1]+$aSourceBaseOffset[1], $aTargetVtxTrans[2]+$aSourceBaseOffset[2]};
736 }else if ($operation == 2){
737 // copy
738 $aTargetVtxTrans = $aSourceVtxTrans;
739 }
740
741 xform -os -t $aTargetVtxTrans[0] $aTargetVtxTrans[1] $aTargetVtxTrans[2] ($targetMeshStr+$i+"]");
742 }
743
744}
745*/
746
747
748global proc abSMAddSubtractCopyMesh(string $baseMesh, string $source, string $target, int $type){
749 // adds or subtracts one blend ($source) from another ($target) based on type (0 == subtract, 1 == add, 2 == copy)
750 // 3, 4, and 5 are mirror versions of 0, 1, and 2
751 // 6, and 7 are like 0 and 1 but use offset from the target instead of the base (7 is same as 2)
752 // 9 and 10 are mirror versions of 6 and 7
753
754 global int $abSymTable[];
755
756 int $aInt[], $totVtx, $i, $srcVtx, $trgVtx, $vtx, $aMSymTable[], $mirror, $operation, $offsetTableInd;
757 int $axisSel = (`radioButtonGrp -q -select saRbGrp`) - 1; // 0 == x, 1 == y, 2 == z
758 int $aSelAxis[] = {1, 1, 1};
759
760 float $aBaseVtxTrans[], $aSourceVtxTrans[], $aTargetVtxTrans[], $aSourceBaseOffset[], $aOffsetTable[];
761 string $mSource, $aStr[], $aSelVerts[], $baseMeshStr, $sourceMeshStr, $targetMeshStr, $baseMeshStr, $sourceMeshStr, $targetMeshStr;
762
763 if ($type == 7) $operation = 2;
764 else $operation = $type % 3;
765
766 $mirror = ($type == 3 || $type == 4 || $type == 5 || $type == 9 || $type == 10);
767
768 // use target for base for types 6 - 10
769 if ($type >= 6) $baseMesh = $target;
770
771 $baseMeshStr = $baseMesh+".vtx[";
772 $sourceMeshStr = $source+".vtx[";
773 $targetMeshStr = $target+".vtx[";
774
775 $totVtx = size($abSymTable);
776 string $aTest[];
777 for ($i=0;$i<$totVtx;$i++){
778
779 $vtx = $abSymTable[$i];
780
781 // if mirroring, get mirror vtx
782 if ($mirror) $aMSymTable[$i] = ($i%2 == 0) ? $abSymTable[$i+1] : $abSymTable[$i-1];
783
784 $aBaseVtxTrans = `xform -q -os -t ($baseMeshStr+$vtx+"]")`;
785 $aSourceVtxTrans = `xform -q -os -t ($sourceMeshStr+$vtx+"]")`;
786 $aTargetVtxTrans = `xform -q -os -t ($targetMeshStr+$vtx+"]")`;
787 $aSourceBaseOffset = {$aSourceVtxTrans[0]-$aBaseVtxTrans[0], $aSourceVtxTrans[1]-$aBaseVtxTrans[1], $aSourceVtxTrans[2]-$aBaseVtxTrans[2]};
788
789 if ($mirror){
790
791 $aOffsetTable[size($aOffsetTable)] = $aSourceBaseOffset[0];
792 $aOffsetTable[size($aOffsetTable)] = $aSourceBaseOffset[1];
793 $aOffsetTable[size($aOffsetTable)] = $aSourceBaseOffset[2];
794 continue;
795 }
796
797 if ($operation == 0){
798 // subtract
799 $aTargetVtxTrans = {$aTargetVtxTrans[0]-$aSourceBaseOffset[0], $aTargetVtxTrans[1]-$aSourceBaseOffset[1], $aTargetVtxTrans[2]-$aSourceBaseOffset[2]};
800
801 }else if ($operation == 1){
802 // add
803 $aTargetVtxTrans = {$aTargetVtxTrans[0]+$aSourceBaseOffset[0], $aTargetVtxTrans[1]+$aSourceBaseOffset[1], $aTargetVtxTrans[2]+$aSourceBaseOffset[2]};
804
805 }else if ($operation == 2){
806 // copy
807 $aTargetVtxTrans = $aSourceVtxTrans;
808 }
809
810 xform -os -t $aTargetVtxTrans[0] $aTargetVtxTrans[1] $aTargetVtxTrans[2] ($targetMeshStr+$vtx+"]");
811 }
812
813 if ($mirror){
814
815 if ($axisSel == 0) $aSelAxis[1] = -1;
816
817 // if mirroring, now we can apply the transforms to their matching verts
818 for ($i=0;$i<$totVtx;$i++){
819
820 $offsetTableInd = $i*3;
821 $vtx = $aMSymTable[$i];
822
823 $aTargetVtxTrans = `xform -q -os -t ($targetMeshStr+$vtx+"]")`;
824 $aSourceBaseOffset[0] = $aOffsetTable[$offsetTableInd]*$aSelAxis[0];
825 $aSourceBaseOffset[1] = $aOffsetTable[$offsetTableInd+1]*$aSelAxis[1];
826 $aSourceBaseOffset[2] = $aOffsetTable[$offsetTableInd+2]*$aSelAxis[2];
827
828 if ($operation == 1){
829 // add
830 $aTargetVtxTrans = {$aTargetVtxTrans[0]-$aSourceBaseOffset[0], $aTargetVtxTrans[1]-$aSourceBaseOffset[1], $aTargetVtxTrans[2]-$aSourceBaseOffset[2]};
831
832 }else if ($operation == 0){
833 // subtract
834 $aTargetVtxTrans = {$aTargetVtxTrans[0]+$aSourceBaseOffset[0], $aTargetVtxTrans[1]+$aSourceBaseOffset[1], $aTargetVtxTrans[2]+$aSourceBaseOffset[2]};
835
836 }else if ($operation == 2){
837 // copy
838 $aTargetVtxTrans = $aSourceVtxTrans;
839 }
840
841 xform -os -t $aTargetVtxTrans[0] $aTargetVtxTrans[1] $aTargetVtxTrans[2] ($targetMeshStr+$vtx+"]");
842
843 }
844 }
845
846}
847
848
849global proc string[] abSelSideVerts(string $obj, string $baseObj, int $mAxisInd, int $selNeg, int $usePiv, float $tol){
850 //selects a side of the object (located on origin) for faster mirroring (instead of having to find symmetrical verts)
851 //$selNeg true -- select Negative side of mesh, false -- select Pos side, 2 -- select all verts
852 int $aInt[];
853 int $totVtx;
854 int $i;
855 string $aRetSel[]; //return string of selected verts
856 string $vtxStr;
857 float $aVtxTrans[];
858 float $bBox[];
859 float $baseMid;
860 float $baseMidOffset;
861
862 $mAxisInd -= 1; //from (1 to 3) to (0 to 2)
863
864 $aInt = `polyEvaluate -v $obj`;
865 $totVtx = $aInt[0];
866
867 if ($selNeg == 2){ //return all verts
868 for ($i=0;$i<$totVtx;$i++){
869 $vtx = $obj+".vtx["+$i+"]";
870 $aRetSel[size($aRetSel)] = $vtx;
871 }
872 return $aRetSel;
873 }
874
875 if ($usePiv){
876 $aVtxTrans = `xform -q -ws -t $baseObj`;
877 $baseMid = $aVtxTrans[$mAxisInd];
878 }else{
879 $bBox = `xform -q -ws -boundingBox $baseObj`;
880 $baseMid = $bBox[$mAxisInd] + (($bBox[($mAxisInd+3)] - $bBox[$mAxisInd])/2);
881 }
882
883 for ($i=0;$i<$totVtx;$i++){
884 $vtxStr = ".vtx["+$i+"]";
885 $aVtxTrans = `xform -q -ws -translation ($baseObj+$vtxStr)`;
886 $baseMidOffset = $aVtxTrans[$mAxisInd] - $baseMid;
887 if (abs($baseMidOffset) < $tol){
888 $aRetSel[size($aRetSel)] = $obj+$vtxStr;
889 continue;
890 }
891 if ($baseMidOffset > 0 && !$selNeg){
892 $aRetSel[size($aRetSel)] = $obj+$vtxStr;
893 continue;
894 }
895 if ($baseMidOffset < 0 && $selNeg){
896 $aRetSel[size($aRetSel)] = $obj+$vtxStr;
897 continue;
898 }
899 }
900 return $aRetSel;
901}
902
903
904global proc string[] abSelMirror(string $obj, string $aSelVerts[]){
905 //mirror selection (not selected)
906 global int $abSymTable[];
907 string $aRetVerts[];
908 string $vtxStr;
909 int $i;
910 int $vertNum;
911 int $mVertNum;
912
913 if (size($abSymTable) == 0){
914 warning "No Base Geometry Selected";
915 return $aSelVerts;
916 }
917 waitCursor -state on;
918 $vtxStr = $obj+".vtx[";
919 for ($i=0;$i<size($aSelVerts);$i++){
920 $vertNum = match("([0-9])+", (match ("([0-9])+\\]", ($vtxStr+$aSelVerts[$i]+"]"))));
921 $mVertNum = abGetSymVtx($vertNum);
922 if ($mVertNum != -1){
923 $aRetVerts[size($aRetVerts)] = ($vtxStr+$mVertNum+"]");
924 }else{ //return non symverts too (zeros and others)
925 $aRetVerts[size($aRetVerts)] = ($vtxStr+$vertNum+"]");
926 }
927 }
928 waitCursor -state off;
929 return $aRetVerts;
930}
931
932
933global proc abClearSbg(){
934 //clears sbgFld and empties $abSymTable
935 global int $abSymTable[];
936 global string $abSbg;
937 global string $abAltSbg;
938
939 button -e -enable false smBn;
940 button -e -enable false smvBn;
941 button -e -enable false msBn;
942 button -e -enable false fsBn;
943 button -e -enable false rsBn;
944 clear($abSymTable);
945 $abSbg = $abAltSbg = "";
946 textField -e -text "" sbgFld;
947}
948
949
950global proc abSymCtl(string $action){
951
952 global int $abSymTable[];
953 global string $abSbg;
954 global string $abAltSbg;
955
956 string $sel[] = `ls -sl -fl`;
957 string $aStr[];
958 string $aSelVerts[];
959 string $aHiliteObj[];
960 string $baseObj = $abSbg;
961 string $revertBaseObj = ($abAltSbg != "") ? $abAltSbg : $abSbg;
962 string $str;
963 string $selMesh;
964 float $tol = `floatField -q -value tolFltFld`;
965 int $axisSel = `radioButtonGrp -q -select saRbGrp`;
966 int $negToPos = `checkBox -q -value maChkBx`;
967 int $usePiv = `checkBox -q -value upoChkBx`;
968 int $warned = false; //set if warning has already been passed
969 float $revertBias = 1;
970
971 if ($action == "rsPrBn"){
972 $revertBias = `floatField -q -value rsPrFltFld`;
973 $action = "rsBn";
974 }
975
976 //get selection info
977
978 $aStr = `filterExpand -sm 12 $sel`;
979 if (size($aStr) > 1){
980 warning "Select one polygon object";
981 $warned = true;
982 }else{
983 $selMesh = $aStr[0]; //if an object is selected
984 }
985
986 //make sure selected components are on only one mesh
987 if ($selMesh == ""){
988 $aHiliteObj = `ls -hilite`;
989 if (size($aHiliteObj) == 1){
990 $selMesh = $aHiliteObj[0];
991 $aSelVerts = `filterExpand -sm 31 $sel`;
992 }else{
993 if (size($aHiliteObj) > 1){
994 clear($aSelVerts);
995 warning "Only one object can be hilited in component mode";
996 $warned = true;
997 }
998 }
999 }else{
1000 select $selMesh; //if two objects are selected
1001 }
1002
1003 switch ($action){
1004
1005 case "sbgBn":
1006 if ($selMesh != ""){
1007 abCheckSym($selMesh, $axisSel, $tol, true, $usePiv);
1008 $abSbg = $selMesh;
1009 textField -e -text $selMesh sbgFld;
1010 button -e -enable true smBn;
1011 button -e -enable true smvBn;
1012 button -e -enable true msBn;
1013 button -e -enable true fsBn;
1014 button -e -enable true rsBn;
1015 }else{
1016 abClearSbg();
1017 }
1018 break;
1019
1020 case "favBn":
1021 if ($selMesh != ""){
1022 $aSelVerts = abCheckSym($selMesh, $axisSel, $tol, false, $usePiv);
1023 if (size($aSelVerts) > 0){
1024 selectMode -component;
1025 select $aSelVerts;
1026 print (size($aSelVerts)+" asymmetric vert(s)");
1027 }else{
1028 select $selMesh;
1029 print ($selMesh+" is symmetrical");
1030 }
1031 }
1032 break;
1033
1034 case "smBn":
1035 if (size($aSelVerts) > 0){
1036 $aSelVerts = abSelMirror ($selMesh, $aSelVerts);
1037 select $aSelVerts;
1038 }
1039 break;
1040
1041 case "smvBn":
1042 if ($selMesh != ""){
1043 $aSelVerts = abSelMovedVerts($selMesh, $baseObj, $tol);
1044 select $aSelVerts;
1045 }
1046 break;
1047
1048 case "smvAltBn":
1049 if ($selMesh != ""){
1050 $aSelVerts = abSelMovedVerts($selMesh, $revertBaseObj, $tol);
1051 select $aSelVerts;
1052 }
1053 break;
1054
1055 case "msBn":
1056 if (size($aSelVerts) > 0){
1057 abMirrorSel($selMesh, $baseObj, $aSelVerts, $axisSel, $negToPos, false, $usePiv, $tol);
1058 }else{
1059 if ($selMesh != ""){ //if object is selected, select half side verts then pass that as $aSelVerts
1060 $aSelVerts = abSelSideVerts ($selMesh, $baseObj, $axisSel, $negToPos, $usePiv, $tol);
1061 abMirrorSel($selMesh, $baseObj, $aSelVerts, $axisSel, $negToPos, false, $usePiv, $tol);
1062 }
1063 }
1064 break;
1065
1066 case "fsBn":
1067 if (size($aSelVerts) > 0){
1068 abMirrorSel($selMesh, $baseObj, $aSelVerts, $axisSel, $negToPos, true, $usePiv, $tol);
1069 }else{
1070 if ($selMesh != ""){ //if object is selected, select half side verts then pass that as $aSelVerts
1071 $aSelVerts = abSelSideVerts ($selMesh, $baseObj, $axisSel, $negToPos, $usePiv, $tol);
1072 abMirrorSel($selMesh, $baseObj, $aSelVerts, $axisSel, $negToPos, true, $usePiv, $tol);
1073 }
1074 }
1075 break;
1076
1077 case "rsBn":
1078
1079 if (size($aSelVerts) > 0){
1080 abRevertSel($aSelVerts, $selMesh, $revertBaseObj, $revertBias);
1081 }else{
1082 if ($selMesh != ""){ //if object is selected, select half side verts then pass that as $aSelVerts
1083 $aSelVerts = abSelSideVerts ($selMesh, $baseObj, $axisSel, 2, $usePiv, $tol); //2 returns all verts
1084 abRevertSel($aSelVerts, $selMesh, $revertBaseObj, $revertBias);
1085 }
1086 }
1087 break;
1088
1089 case "cBn":
1090 abClearSbg();
1091 abSymClearRevTables();
1092 deleteUI -window abSymWin;
1093 break;
1094
1095 case "saRbGrp":
1096 abClearSbg();
1097 switch ($axisSel){
1098 case 1:
1099 $str = "X";
1100 break;
1101 case 2:
1102 $str = "Y";
1103 break;
1104 case 3:
1105 $str = "Z";
1106 break;
1107
1108 }
1109 $str = "Operate -"+$str+" to +"+$str;
1110 checkBox -e -l $str maChkBx;
1111 }
1112 setFocus "modelPanel1";
1113}
1114
1115
1116global proc abSymMesh(){
1117
1118 global int $abSymTable[];
1119 global string $abSbg;
1120 global string $abAltSbg;
1121 global int $abSymSliderDragging;
1122
1123 $abSymSliderDragging = false;
1124
1125 abSymClearRevTables();
1126
1127 float $aRevertPopupVals[] = {1,2,3,4,5,1111,10,20,30,40,50,60,70,80,90}; //values that will appear in the revert popup menu (1111 is a divider bar)
1128
1129 int $sbgBnsEn = false; //bool for enabled state of sbg dependent buttons
1130 string $selBaseGeo;
1131
1132 if (size($abSymTable) > 0 && `objExists $abSbg`){ //reselect object whose data is in symTable
1133 $selBaseGeo = $abSbg;
1134 $sbgBnsEn = true;
1135 }else{
1136 clear($abSymTable);
1137 $abSbg = $abAltSbg = "";
1138 }
1139
1140 if (`window -exists abSymWin`){
1141 deleteUI -window abSymWin;
1142 }
1143
1144 window -t "abSymMesh" -w 180 -h 474 -menuBar true abSymWin;
1145
1146 // add menu
1147 menu -label "Operations" -postMenuCommand "global string $abSbg;string $aStr[], $str;$aStr = {\"abSMOpCopyMnIt\",\"abSMOpAddMnIt\",\"abSMOpSubtractMnIt\",\"abSMOpMirrCopyMnIt\",\"abSMOpMirrAddMnIt\",\"abSMOpMirrSubtractMnIt\",\"abSMOpBBaseAddMnIt\",\"abSMOpBBaseSubtractMnIt\",\"abSMOpBBaseMirrAddMnIt\",\"abSMOpBBaseMirrSubtractMnIt\"};for ($str in $aStr) menuItem -e -en ($abSbg != \"\" && `radioButtonGrp -q -select saRbGrp` == 1) $str;";
1148 menuItem -label "Copy A to B" -command "abSMServiceAddSubtractCopy(2);" abSMOpCopyMnIt;
1149 menuItem -label "Add A to B" -command "abSMServiceAddSubtractCopy(1);" abSMOpAddMnIt;
1150 menuItem -label "Subtract A from B" -command "abSMServiceAddSubtractCopy(0);" abSMOpSubtractMnIt;
1151 menuItem -divider true;
1152 menuItem -label "Copy Mirror A to B" -command "abSMServiceAddSubtractCopy(5);" abSMOpMirrCopyMnIt;
1153 menuItem -label "Add Mirror A to B" -command "abSMServiceAddSubtractCopy(4);" abSMOpMirrAddMnIt;
1154 menuItem -label "Subtract Mirror A from B" -command "abSMServiceAddSubtractCopy(3);" abSMOpMirrSubtractMnIt;
1155 menuItem -divider true;
1156 menuItem -label "Add A to B (Use B as Base)" -command "abSMServiceAddSubtractCopy(7);" abSMOpBBaseAddMnIt;
1157 menuItem -label "Subtract A from B (Use B as Base)" -command "abSMServiceAddSubtractCopy(6);" abSMOpBBaseSubtractMnIt;
1158 menuItem -divider true;
1159 menuItem -label "Add Mirror A to B (Use B as Base)" -command "abSMServiceAddSubtractCopy(10);" abSMOpBBaseMirrAddMnIt;
1160 menuItem -label "Subtract Mirror A from B (Use B as Base)" -command "abSMServiceAddSubtractCopy(9);" abSMOpBBaseMirrSubtractMnIt;
1161
1162
1163 menu -label "Tools";
1164 menuItem -label "Attempt To Restore Symmetry" -ann "Attempt to restore X axis symmetry by matching vertices while iterating through a series of increasing radii." -command "abSymmetrizeVertsUI();";
1165
1166 // continue with layout
1167 formLayout -numberOfDivisions 100 abSymForm;
1168
1169 radioButtonGrp -numberOfRadioButtons 3 -l1 "YZ" -l2 "XZ" -l3 "XY"
1170 -select 1 -columnWidth3 52 52 52 -onCommand "abSymCtl(\"saRbGrp\")" saRbGrp;
1171 separator sep1;
1172 text -l "Global Tolerance" tolTxt;
1173
1174 floatField -min 0 -max 1 -value .001 tolFltFld;
1175 separator sep2;
1176 button -l "Select Base Geometry" -command "abSymCtl(\"sbgBn\")" sbgBn;
1177 textField -editable false -text $selBaseGeo sbgFld;
1178 separator sep3;
1179 button -l "Check Symmetry" -command "abSymCtl(\"favBn\")" csBn;
1180 button -l "Selection Mirror" -enable $sbgBnsEn -command "abSymCtl(\"smBn\")" smBn;
1181 button -l "Select Moved Verts" -enable $sbgBnsEn -command "abSymCtl(\"smvBn\")" smvBn;
1182 separator sep4;
1183 button -l "Mirror Selected" -enable $sbgBnsEn -command "abSymCtl(\"msBn\")" msBn;
1184 button -l "Flip Selected" -enable $sbgBnsEn -command "abSymCtl(\"fsBn\")" fsBn;
1185 button -l "Revert Selected to Base" -enable $sbgBnsEn -command "abSymCtl(\"rsBn\")" rsBn;
1186
1187 string $tCmdStr = "floatField -e -value ((`floatField -q -v rvrtFltValFltFld`)/100.0) rsPrFltFld;abSymCtl(\"rsPrBn\");";
1188
1189 floatField -value 0 -pre 2 -min 0 -max 100 -cc $tCmdStr -ec $tCmdStr rvrtFltValFltFld;
1190 floatSlider -value 1 -minValue 0 -maxValue 1 -dragCommand "abSymInteractiveRevertToBase();" -changeCommand "abSymEndDrag();" rvrtFltSldr;
1191
1192 popupMenu -button 3 -p rvrtFltSldr rsPpUpMn;
1193 menuItem -label "Commit Changes" -command "abSymClearRevTables();";
1194 separator sep5;
1195 checkBox -l "Operate -X to +X" -value false maChkBx;
1196 checkBox -l "Use Pivot as Origin" -value true upoChkBx;
1197 button -l "Close" -height 24 -command "abSymCtl(\"cBn\")" cBn;
1198
1199 //hidden var field
1200 floatField -value 1 -min 0 -max 1 -pre 2 -manage 0 rsPrFltFld;
1201
1202 //revert button popup menus
1203
1204 popupMenu -button 3 -p rsBn rsPpUpMn;
1205
1206 if (size($aRevertPopupVals) > 0){
1207
1208 int $i;
1209 string $cmdStr;
1210 float $flt;
1211
1212 for ($i=0;$i<size($aRevertPopupVals);$i++){
1213
1214 if ($aRevertPopupVals[$i] == 1111){
1215 $cmdStr += "menuItem -divider true;";
1216 continue;
1217 }
1218
1219 $flt = $aRevertPopupVals[$i]/100;
1220 $cmdStr += "menuItem -label \""+$aRevertPopupVals[$i]+"%\" -command \"floatField -e -value "+$flt+" rsPrFltFld;abSymCtl(\\\"rsPrBn\\\");\";";
1221 }
1222
1223 $cmdStr += "menuItem -divider true;";
1224 eval($cmdStr);
1225 }
1226
1227 setParent -m rsPpUpMn;
1228
1229 string $baseStr;
1230 int $enableOrigRecall = false;
1231
1232 if ($abAltSbg != "" && `objExists $abAltSbg`){
1233 $baseStr = "Using "+$abAltSbg+" as Base";
1234 $enableOrigRecall = true;
1235 }else{
1236 $baseStr = "Using Original Base";
1237 }
1238
1239 menuItem -label $baseStr abSymCurBsMnIt;
1240 menuItem -divider true;
1241 menuItem -label "Use Selected as Base" -command "abSymUseAlternateBase(1);" abSymSlRvtBsMnIt;
1242 menuItem -label "Use Original Base" -enable $enableOrigRecall -command "abSymUseAlternateBase(0);" abSymSlOrigRvtBsMnIt;
1243 menuItem -label "Select Moved from Revert Base" -enable $enableOrigRecall -command "abSymCtl(\"smvAltBn\");" abSymSlAltMvVtsMnIt;
1244 menuItem -divider true;
1245 menuItem -label "Use Overshoot" -checkBox 0 -command "float $min,$max;if (`menuItem -q -c abSymOvrShtMnIt`){$min=-.5;$max=1.5;}else{$min=0;$max=1;}floatSlider -e -min $min -max $max rvrtFltSldr;" abSymOvrShtMnIt;
1246 setParent ..;
1247
1248 int $tMarg = 7;
1249 int $lMarg = 5;
1250 int $rMarg = 5;
1251 int $ctSpc = 5; //control top space
1252 int $cbSpc = 20;
1253
1254 formLayout -e
1255
1256 -af saRbGrp "top" $tMarg
1257 -af saRbGrp "left" 18
1258
1259 -af sep1 "left" $lMarg
1260 -ac sep1 "top" $ctSpc saRbGrp
1261 -af sep1 "right" $rMarg
1262
1263 -af tolTxt "left" $lMarg
1264 -ac tolTxt "top" ($ctSpc+2) sep1
1265 -ac tolFltFld "left" $ctSpc tolTxt
1266 -ac tolFltFld "top" $ctSpc sep1
1267 -af tolFltFld "right" $rMarg
1268
1269 -af sep2 "left" $lMarg
1270 -ac sep2 "top" $ctSpc tolFltFld
1271 -af sep2 "right" $rMarg
1272
1273 -af sbgBn "left" $lMarg
1274 -ac sbgBn "top" $ctSpc sep2
1275 -af sbgBn "right" $rMarg
1276
1277 -af sbgFld "left" $lMarg
1278 -ac sbgFld "top" $ctSpc sbgBn
1279 -af sbgFld "right" $rMarg
1280
1281 -af sep3 "left" $lMarg
1282 -ac sep3 "top" $ctSpc sbgFld
1283 -af sep3 "right" $rMarg
1284
1285 -af csBn "left" $lMarg
1286 -ac csBn "top" $ctSpc sep3
1287 -af csBn "right" $rMarg
1288
1289 -af smBn "left" $lMarg
1290 -ac smBn "top" $ctSpc csBn
1291 -af smBn "right" $rMarg
1292
1293 -af smvBn "left" $lMarg
1294 -ac smvBn "top" $ctSpc smBn
1295 -af smvBn "right" $rMarg
1296
1297 -af sep4 "left" $lMarg
1298 -ac sep4 "top" $ctSpc smvBn
1299 -af sep4 "right" $rMarg
1300
1301 -af msBn "left" $lMarg
1302 -ac msBn "top" $ctSpc sep4
1303 -af msBn "right" $rMarg
1304
1305 -af fsBn "left" $lMarg
1306 -ac fsBn "top" $ctSpc msBn
1307 -af fsBn "right" $rMarg
1308
1309 -af sep5 "left" $lMarg
1310 -ac sep5 "top" $ctSpc fsBn
1311 -af sep5 "right" $rMarg
1312
1313 -af rsBn "left" $lMarg
1314 -ac rsBn "top" $ctSpc sep5
1315 -af rsBn "right" $rMarg
1316
1317 -af rvrtFltSldr "left" $lMarg
1318 -ac rvrtFltSldr "top" ($ctSpc+4) rsBn
1319 -ap rvrtFltSldr "right" $rMarg 78
1320
1321 -ac rvrtFltValFltFld "left" $lMarg rvrtFltSldr
1322 -ac rvrtFltValFltFld "top" $ctSpc rsBn
1323 -af rvrtFltValFltFld "right" $rMarg
1324
1325 -af maChkBx "left" $lMarg
1326 -ac maChkBx "top" ($ctSpc+4) rvrtFltSldr
1327
1328 -af upoChkBx "left" $lMarg
1329 -ac upoChkBx "top" $ctSpc maChkBx
1330
1331 -af cBn "left" $lMarg
1332 -ac cBn "top" $cbSpc upoChkBx
1333 -af cBn "right" $rMarg
1334
1335 abSymForm
1336 ;
1337
1338 showWindow abSymWin;
1339}
1340
1341
1342global proc abSymmetrizeVertsUI(){
1343
1344 int $lmargin = 3;
1345 int $rmargin = 3;
1346 int $tmargin = 5;
1347
1348 if (`window -exists abSymmetrizeVertsWin`)
1349 deleteUI -window abSymmetrizeVertsWin;
1350
1351 window -t "Symmetrize Verts" -w 164 -h 114 -menuBar false -minimizeButton false -maximizeButton false abSymmetrizeVertsWin;
1352
1353 formLayout -numberOfDivisions 100 abSymmetrizeVertsForm;
1354
1355 text -l "Iterations:" abSymVtIterationsTxt;
1356 intField -min 10 -v 200 abSymVtIterationsIntFld;
1357
1358 text -l "Start Radius:" abSymVtStRadTxt;
1359 floatField -precision 6 -min .00000001 -v .000001 abSymVtStRadFltFld;
1360
1361 text -l "End Radius:" abSymVtEndRadTxt;
1362 floatField -precision 6 -min .001 -v 1 abSymVtEndRadFltFld;
1363
1364 button -h 28 -l "Symmetrize Selected Verts" -c "abSymmetrizeVerts(`floatField -q -v abSymVtStRadFltFld`, `floatField -q -v abSymVtEndRadFltFld`, `intField -q -v abSymVtIterationsIntFld`);" abSymVtGoBn;
1365
1366 formLayout -e
1367
1368 -af abSymVtIterationsTxt "top" $tmargin
1369 -af abSymVtIterationsTxt "left" $lmargin
1370
1371 -af abSymVtIterationsIntFld "top" $tmargin
1372 -ac abSymVtIterationsIntFld "left" $lmargin abSymVtIterationsTxt
1373 -af abSymVtIterationsIntFld "right" $rmargin
1374
1375 -ac abSymVtStRadTxt "top" $tmargin abSymVtIterationsIntFld
1376 -af abSymVtStRadTxt "left" $lmargin
1377
1378 -ac abSymVtStRadFltFld "top" $tmargin abSymVtIterationsIntFld
1379 -ac abSymVtStRadFltFld "left" $lmargin abSymVtStRadTxt
1380 -af abSymVtStRadFltFld "right" $rmargin
1381
1382 -ac abSymVtEndRadTxt "top" $tmargin abSymVtStRadFltFld
1383 -af abSymVtEndRadTxt "left" $lmargin
1384
1385 -ac abSymVtEndRadFltFld "top" $tmargin abSymVtStRadFltFld
1386 -ac abSymVtEndRadFltFld "left" $lmargin abSymVtEndRadTxt
1387 -af abSymVtEndRadFltFld "right" $rmargin
1388
1389 -ac abSymVtGoBn "top" $tmargin abSymVtEndRadFltFld
1390 -af abSymVtGoBn "left" $lmargin
1391 -af abSymVtGoBn "right" $rmargin
1392
1393 abSymmetrizeVertsForm
1394 ;
1395
1396 showWindow abSymmetrizeVertsWin;
1397
1398}
1399
1400
1401global proc abSymmetrizeVerts(float $startTol, float $endTol, int $iterations){
1402 // select src, targ, src, targ and this funtion will symmetrize them across the yz axis
1403
1404 string $aSel[], $aSelObj[], $obj, $aLfVts[], $aRtVts[], $aOriginVts[], $aTempLfVts[], $aTempRtVts[], $plural;
1405 float $aTrans[], $aSrcTrans[], $aDestTrans[], $tol, $t, $aOffset[];
1406 int $i, $k, $it, $match, $matchCounter;
1407
1408 $matchCounter = 0;
1409
1410 if ($startTol > $endTol){
1411 warning "Start radius must be less than end tolerance. Try again.";
1412 return;
1413 }
1414
1415 $aSel = `filterExpand -sm 31`;
1416
1417 $aSelObj = `ls -hilite`;
1418
1419 if (size($aSelObj) != 1){
1420 warning "Select asymmetrical verts on a single object and try again.";
1421 return;
1422 }
1423
1424 $obj = $aSelObj[0];
1425
1426 // sort verts
1427 for ($i=0;$i<size($aSel);$i++){
1428
1429 $aTrans = `xform -q -os -t $aSel[$i]`;
1430
1431 if ($aTrans[0] > $startTol){
1432
1433 $aLfVts[size($aLfVts)] = $aSel[$i];
1434
1435 }else if ($aTrans[0] < (-1.0*$startTol)){
1436
1437 $aRtVts[size($aRtVts)] = $aSel[$i];
1438
1439 }else{
1440 $aOriginVts[size($aOriginVts)] = $aSel[$i];
1441 }
1442 }
1443
1444 float $prog, $progDenom;
1445 int $numLfVts;
1446
1447 $numLfVts = size($aLfVts);
1448 waitCursor -state on;
1449 progressWindow -title "Working" -progress 0 -status "Matched 0 Vertices";
1450 $progDenom = float($numLfVts);
1451
1452
1453 // now go through verts in ever increasing tolerance
1454 for ($it=0;$it<$iterations;$it++){
1455
1456 //prog win
1457 $prog = ((float($numLfVts-(size($aLfVts))))/$progDenom)*100.0;
1458 progressWindow -e -progress (int($prog));
1459 //end prog win
1460
1461
1462 clear($aTempLfVts);
1463
1464 $t = float($it)/float($iterations-1);
1465 $tol = $endTol*(float($t))*(float($t)) + $startTol;
1466
1467 for ($i=0;$i<size($aLfVts);$i++){
1468
1469 clear($aTempRtVts);
1470 $match = false;
1471
1472 $aSrcTrans = `xform -q -os -t $aLfVts[$i]`;
1473 $aDestTrans = $aSrcTrans;
1474 $aDestTrans[0] *= -1.0;
1475
1476 for ($k=0;$k<size($aRtVts);$k++){
1477
1478 $aTrans = `xform -q -os -t $aRtVts[$k]`;
1479
1480 $aOffset[0] = abs($aDestTrans[0] - $aTrans[0]);
1481 $aOffset[1] = abs($aDestTrans[1] - $aTrans[1]);
1482 $aOffset[2] = abs($aDestTrans[2] - $aTrans[2]);
1483
1484 if (!$match && ($aOffset[0] < $tol && $aOffset[1] < $tol && $aOffset[2] < $tol)){
1485
1486 // match
1487 $match = true;
1488 $matchCounter++;
1489
1490 xform -os -t $aDestTrans[0] $aDestTrans[1] $aDestTrans[2] $aRtVts[$k];
1491
1492 select -tgl $aLfVts[$i] $aRtVts[$k] ;
1493
1494 $plural = ($matchCounter == 1) ? "vertex" : "vertices";
1495 progressWindow -e -status ("Matched "+$matchCounter+" "+$plural);
1496
1497 }else{
1498 $aTempRtVts[size($aTempRtVts)] = $aRtVts[$k];
1499 }
1500 }
1501
1502 if (!$match)
1503 $aTempLfVts[size($aTempLfVts)] = $aLfVts[$i];
1504
1505 $aRtVts = $aTempRtVts;
1506 }
1507
1508 $aLfVts = $aTempLfVts;
1509
1510 if (size($aLfVts) == 0 && size($aRtVts) == 0)
1511 break;
1512 }
1513
1514 progressWindow -endProgress;
1515 waitCursor -state off;
1516
1517 //print ("\nfinal tolerance was: "+$tol);
1518
1519 if ($matchCounter > 0)
1520 print ("\n\nSymmetrized "+$matchCounter+" "+$plural+".");
1521
1522}