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