Showing posts with label melscript. Show all posts
Showing posts with label melscript. Show all posts

Sunday, December 29, 2013

Concave or convex angle? (Inside or Outside the Polygon)

Intro

So I needed this function for my building generator script, for the floor plans to rotate the walls to the correct angle. But it doesn't know whether its concave or convex. This script checks for the point P, on a polygon, to see if its inside or outside the polygon consisting of all points minus the point P.


Problem Breakdown

To find whether a point is inside or outside a polygon, I will need to use the Jordan Curve Theorem. To put it simply, for a point P, draw a line using its X axis, for each intersection with the polygon to the left or right of the point P, count it. If the count is even, then point P is outside, if its odd, it is inside. Imagine a pentagon. For its first point, pp0, I'd like to check if the angle0 is concave or convex. 

1. First I'll need to draw a line using the X axis through pp0. lineP

2. Secondly, I'll need to find the edges of the rectangle consisting of lines, line(pp4, pp1), line(pp1,pp2), line(pp2,pp3), line(pp3, pp4).

3. Use line-line intersection to see if line0, line1, line2, line3 intersects with lineP. If intersect, note if the intersection point is to the left or right of pp0 and add the count. 

4. If the count is even, pp0 is outside the rectange, which makes angle0 convex, if the count is odd, pp0 is inside the rectangle, and makes angle0 concave.


Source

global proc int checkInside(int $i) {//checks
    string $sel = "ngon";
    int $vtxSize[] = `polyEvaluate -v "ngon"`;
    int $a, $b, $c, $d, $e, $l_count, $r_count;
    float $a1, $a2, $b1, $b2, $c1, $c2;
    float $pp0[], $pp1[], $pp2[], $pointMax[], $pointXmin[];
    float $xx, $yy, $det;
    //this checks the immediate line AC from the point B. return should be boolean
     $a = $i - 1;
     $b = $i;
     $c = $i + 1;
     if($i == 0) {
         $a = $vtxSize[0] - 1;
         $b = 0;
     }//if

    float $pp0[] = pointPosition ($sel + ".vtx[" + $a + "]"); //coord of $a
    float $pp1[] = pointPosition ($sel + ".vtx[" + $b + "]"); //after checking the above, if none of the above, continue getting pp of next two vtx
    float $pp2[] = pointPosition ($sel + ".vtx[" + $c + "]"); //^
    float $min = min($pp0[2], $pp2[2]);
    float $max = max($pp0[2], $pp2[2]);
    
    $pointXmax = $pp1;
    $pointXmax[0] = $pointXmax[0] + 20;//arbitrary max, should be max x of the polygon
    $pointXmin = $pp1;
    $pointXmin[0] = $pointXmin[0] - 20;//lets only look at one side of the polygon            

    $a2 = $pointXmax[2] - $pointXmin[2];
    $b2 = $pointXmin[0] - $pointXmax[0];
    $c2 = ($a2 * $pointXmin[0] + $b2 * $pointXmin[2]);          
     
    if(($pp1[2] < $max) && ($pp1[2] > $min)) {    //if inside do check
        $a1 = $pp2[2] - $pp0[2];
        $b1 = $pp0[0] - $pp2[0];
        $c1 = ($a1 * $pp0[0]) + ($b1 * $pp0[2]);

        $det = ($a1 * $b2) - ($a2 * $b1);
        if($det != 0) {
            $xx = ($b2*$c1 - $b1*$c2)/$det;
            $yy = ($a1*$c2 - $a2*$c1)/$det;
        }
        else {
            print "det = 0";
        }

        if($xx > $pp1[0]) {
                $r_count = $r_count + 1;
        }
        else if($xx < $pp1[0]) {
                $l_count = $l_count + 1;
        }
        }//if

    //--------------------checks the imaginary line of prev and next point---end//
    //check every other edge in the polygon
    for($j = 0; $j < $vtxSize[0] - 2; $j++) {//every other edge
        $d = $j + $i + 1;
        $e = $d + 1;
        if($e >= $vtxSize[0]) {
            $e = $e - $vtxSize[0];
        }
        if($d >= $vtxSize[0]) {
            $d = $d - $vtxSize[0];
        }
        float $pp0[] = pointPosition ($sel + ".vtx[" + $d + "]"); //coord of $a
        float $pp2[] = pointPosition ($sel + ".vtx[" + $e + "]"); //^                
        float $min = min($pp0[2], $pp2[2]);
        float $max = max($pp0[2], $pp2[2]);    

        if(($pp1[2] < $max) && ($pp1[2] > $min)) {    //if inside do check
            $a1 = $pp2[2] - $pp0[2];
            $b1 = $pp0[0] - $pp2[0];
            $c1 = ($a1 * $pp0[0]) + ($b1 * $pp0[2]);
            
            $det = ($a1 * $b2) - ($a2 * $b1);
            if($det != 0) {
                $xx = ($b2*$c1 - $b1*$c2)/$det;
                $yy = ($a1*$c2 - $a2*$c1)/$det;
            }        

            if($xx > $pp1[0]) { //jordan curve theorem, simmple test to see inside or outside
                $r_count = $r_count + 1;
            }
            else if($xx < $pp1[0]) {
                $l_count = $l_count + 1;
            }
            //print ("rcount = " + $r_count + "\n");
            //print ("lcount = " + $l_count + "\n");                                  
        }//if inside
    } //for $j
    if($l_count % 2 == 0) {//even == outside
        return 0;
    } 
    else return 1;
}

Notes

Input: int $i, point $i on the polygon.
Output: boolean, 0 = outside, 1 = inside.

Tuesday, May 28, 2013

Export/Import Shading Group Set Members

On the off chance a scenes shaders needs to be exported and then imported to the same scene without shaders(happens in production...). Doesn't work with face components, will need to do that manually. fixed: copy pasted the import code in the export code.


Export

proc exportSG() {
    string $shadingGroup[];
    $shadingGroup = `ls -sl -type shadingEngine`;
    string $mesh[];
    string $shaders[];
    string $meshList = ("/home/julio/meshlist.txt" );
    int $fileId =`fopen $meshList "w"`;
    for($i = 0; $i < size($shadingGroup); $i++) {
        select -r -ne $shadingGroup[$i];
        $mesh = `listConnections -s 1 -d 0 -type mesh`;
        $face = `listConnections -s 1 -d 0`;
        $meshList = ("/home/julio/meshlist.txt" );
    
        for($j = 0; $j < size($mesh); $j++) {
            fprint $fileId ($shadingGroup[$i] + " " + $mesh[$j] + "\n");
            }
    }
        fclose $fileId;
    }
    
    exportSG;


Import

proc importSG() {
    int $fileId =`fopen "/home/julio/meshlist.txt" "r"`;
    string $buffer[];
    string $nextLine = `fgetline $fileId`;
    while ( size( $nextLine ) > 0 ) {
        tokenize $nextLine " " $buffer;
        select -r $buffer[1];
        sets -e -forceElement $buffer[0];    
        $nextLine = `fgetline $fileId`;
    }
    fclose $fileId;
}

importSG;

Monday, April 25, 2011

Architectural Visualization: Planks

Intro
Since I'll be working on a architectural visualization project, I will document the techniques I found interesting. The first notable one so far are the planks near a pool area.

For the planks, I found an 1kx1k tileable image. With some scripting and hypershade trickery, it is more than enough, even at closeups.

Goal
1. add transform noise to the planks
2. offset UV of individual planks
3. add different values to the planks

Friday, July 9, 2010

Invader Fractal


Invader Fractal in Mel version 1 Still some squares being left out, but all in all looking good. version 2 Complete, but need to add more size variations version 4 variation 1 Rewrote most of the space filling portion, and added frames etc. variation 2 variation 3 Based on Jared Tarbells Invader Fractal. except done in maya melscript. Below is the space filling portion of the script, using a main grid of 100x50 squares, we go through each one($j), if $j is white, j++, if not, search a random sized area for white squares, if a white square exists, we search random sized area - 1 for white squares and so on until random size = 1 and it must be black due to the first condition. If the random sized area have no white squares, we call the invader_plane()(not shown), which makes the invader plane at that area, and color that particular area white on the main_grid and continue(j++). There are two for loops within the main loop, L loop for going horizontal, which are increments of 50, and the K loop going vertical, which are increments of 1.
------------------------------------------------------------------------------------------------
global proc main_method() {
 undoInfo -state off;
 global int $i;
 int $j, $k, $l, $ex;
 float $vtxPos[];
 string $xyz[];

 for($j = 0; $j < 5000; $j++) {

  print("START----------------------------------------\n");
  $ex = 0;
  select -cl;
  //int $j = 6;
  int $random_size = rand(1,11);
  hilite main_grid;
  for($l = ($random_size - 1) * 50; $l  >= 0; $l = $l - 50){
   string $bah[0] = `listSets -o main_grid.f[$j]`;
   $xyz[0] = $bah[0];
   if ($xyz[0] == "whiteShaderSG") {
  //  print("stopped immediately!!\n");
    $ex = 1;
    continue;
   }   
   for ($k = $random_size - 1; $k >= 0; $k = $k - 1) {
    select -add ("main_grid.f[" + ($j+$k+$l) + "]"); 
    print("K LOOP  ");
    print("main_grid.f[" + ($j+$k+$l) + "]\n" + "$j=" + $j + " $k=" + $k + " $l=" + $l/50 + " size=" + $random_size + "\n");   
    string $bah[0] = `listSets -o main_grid.f[($j + $k + $l)]`;
    if($bah[0] == "whiteShaderSG") {
  //   print("coord " + "random_size="  + $random_size + " k=" + $k + " l/50=" + ($l/50) + "\n"); //coordinate for white square
     int $dif;
     if($k > ($l/50)) {
      print("k larger");
      int $dif;
      for($dif = 0;$dif <= ($random_size - $l/50); $dif++) {
  //     print("dif=" + $dif + " random_size=" + $random_size + " k=" + $k + "\n");
       select -d ("main_grid.f[" + ($j+$k+$l+($dif*50)) + ":" + ($j+$k+$l+$random_size+($dif*50)) + "]");
      }
      for($dif = 0;$dif <= ($random_size - $k); $dif++) {
  //     print("dif=" + $dif + " random_size=" + $random_size + " k=" + $k + "\n");
       select -d ("main_grid.f[" + ($j + ($random_size - $dif) * 50) + ":" + ($j + $random_size + ($random_size - $dif) * 50) + "]");
      }
      $random_size = $k;
     }
     else if($k < ($l/50)) {
      print("l larger");
      $k = 0;
      select -cl;
      $random_size = $l/50;
     }
     else {
      select -cl;
      print("K is equal to L\n\n");
      $random_size = $k;
      $k = 0;
      break;
     }
    }
   }
  print(`ls -sl`);
  print("L LOOP   ");
  print("main_grid.f[" + ($j+$k+$l) + "]\n" + "$j=" + $j + " $k=" + $k + " $l=" + $l/50 + " size=" + $random_size + "\n\n");   
  } 
 if ($ex == 1) {
  continue;
 }
 hilite main_grid;
 sets -e -forceElement whiteShaderSG;
 print(`ls -sl`);           
 polyChipOff -ch 0 -kft 1 -dup 1 -off 0 `ls -sl`;
 polySeparate -ch 0 -n temp main_gridShape;  
 CenterPivot;
 move -r (($random_size/2)*(-1)) ($random_size/2) ($random_size/2) temp1.scalePivot temp1.rotatePivot;     
 select temp temp1;   
 parent -w;   
 select -r main_grid;
 doDelete;
 rename "temp" "main_grid";
 float $vtxPos[3] = `xform -q -ws -t temp1.vtx[0]`;
 select -r temp1;
 doDelete;
 invader_plane;
 ls -sl;
 move -r $vtxPos[0] ($vtxPos[1]+1) $vtxPos[2];
 scale -r ($random_size) ($random_size) ($random_size);
 $i++;
 }
}

------------------------------------------------------------------------------------------------