exp.wiki NEU
WICHTIG: Das exp.wiki wurde aktualisiert und ist ab sofort unter einer neuen Adresse zu erreichen: https://exparch-www.uibk.ac.at/testwiki
Bitte das Anlegen neuer Seiten oder die Änderungen bestehender ab sofort ausschließlich dort durchführen.
Bestehende Projektseiten wurden/werden migriert und sind auch auf der neuen Plattform vorhanden.

Voronoiturm

Aus exp.wiki

(Weitergeleitet von E3/E5 Projekt Wieser Rainer)
Wechseln zu: Navigation, Suche

Voronoiturm

Dieses Projekt beschäftigt sich mit parametrischer Modellierung zum Thema "´Strukturelle Morphologien - Packen". (siehe Analyse:Packen)

Bild:Packen-endresultat.jpg

Analoge Modelle

Modellversuche

Erste Script und Modellversuche

[Select all] [View all]

for ($xDir=0; $xDir<3; $xDir++) {
  for ($yDir=0; $yDir<3; $yDir++) {
    for ($zDir=0; $zDir<3; $zDir++) {
      polyCube -w 1 -d 1 -h 1 -n ("Wx"+$xDir+"y"+$yDir+"z"+$zDir);
      move -r $xDir $yDir $zDir;
      viewFit -all;
      refresh;
    }
  }
}

Modellversuche

Das script war schnell ausgereizt und die Ergebnisse recht eintönig. Man konnte zwar Körper mit konstanten Abständen aneinanderreihen und stapeln, jedoch wenig Variation erzeugen.

Voronoidiagramm

Um in der "Packstruktur" mehr Variation zu erzeugen bediente ich mich dem Voronoi-Diagramm (auch Thiessen-Polygone oder Dirichlet-Zerlegung genannt). Das Voronoi-Diagramm wurde nach Georgi Feodosjewitsch Woronoi benannt. Er war ein russischer Mathematiker ukrainischer Herkunft. Woronoi studierte an der Universität von Sankt Petersburg und lehrte dann an der Universität Warschau.

Bei der Konstruktion von Voronoi-Diagrammen wird eine Fläche bzw. ein Raum komplett mit Polygonen oder Polyedern gefüllt. Ein Voronoidiagramm kann man aus der Delaunay-Triangulation herleiten und umgekehrt. Man sagt auch die Delaunay-Triangulation verhält sich dual zum Voronoidiagramm. Man konstruiert die Verbindungsgerade zwischen zwei Punkten und darauf die Mittelsenkrechte. Die Schnittpunkte dieser Mittelsenkrechten schneiden sich an den Voronoi-Knoten und ergeben so das Voronoi-Diagramm. Räumlich funktioniert die Konstruktion gleich, nur dass die mittelsenkrechten Flächen sind und sich in einer Geraden schneiden.

Bild 1 zeigt links die beliebige Triangulation einer Punktmenge und rechts dieselbe Punktemenge mit der Delaunay-Triangulation.
Bild 2 zeigt die Konstruktion des Voronoi-Diagramms mit Hilfe der Delaunay-Triangulation
Bild 3 zeigt die Umkreismethode zur Bestimmung eines Delaunay-Dreiecks
Bild 4 zeigt das Voronoi-Diagramm und die Delaunay-Triangulation einer Punktmenge

Qhull

Qhull ist eine Applikation, die es ermöglicht, konvexe Hüllen, Delaunay-Triangulationen und Voronoi-Diagramme aus Punktmengen zu errechnen. Qhull kann in Verbindung mit anderen Applikationen wie Maya, Rhino etc. verwendet werden.

Anforderungen an das script

-Erzeugen einer Punktwolke
-Exportieren nach Qhull
-Importieren nach Maya

[Select all] [View all]

//Step 1: generate the points
 
//get Points from selection of Locators
global proc vector[] getPointsFromSelection(){
 
	vector $P[];
 
	string $list[] = `ls -sl`;
 
	for($item in $list){
 
		$vector = `pointPosition -w $item`;
		$P[size($P)] = $vector;
	}
 
	return $P;
 
}
 
//generates points randomly in 3D
global proc vector[] genPoints(int $quant, float $min, float $max)
{   
    // This generates 3D vectors in random space and returns as a list
    vector $points[];
    vector $P;
 
    string $myGroup = `group -em -n "Locators"`;
 
    for ($i=0; $i<$quant; $i++)
    {
        $P = <<(rand($min, $max)),(rand($min, $max)),(rand($min, $max))>>;
        $points[size($points)] = $P;
        $loc = `spaceLocator -p ($P.x) ($P.y) ($P.z)`; // make a locator to see points
        parent $loc[0] $myGroup;
 
    }
    return $points;
}
 
//generates points in 3D as grid
global proc vector[] genPointsGrid3D(float $min, float $max, int $quant)
{   
    // This generates 3D vectors in space and returns as a list
    vector $points[];
    vector $P;
 
    float $spac = (abs($min) + abs($max))/($quant - 1);
 
    print($spac + "\n");
 
    string $myGroup = `group -em -n "Locators"`;
 
    for ($x=0; $x<$quant; $x++)
    {
   	    for ($y=0; $y<$quant; $y++)
   		{
   	  	    for ($z=0; $z<$quant; $z++)
   			{
				$P = <<($min + ($x * $spac)), ($min + ($y * $spac)), ($min + ($z * $spac))>>;
				$points[size($points)] = $P;
				$loc = `spaceLocator -p ($P.x) ($P.y) ($P.z)`; // make a locator to see points
				parent $loc[0] $myGroup;
			}
        }
    }
    return $points;
}
 
//generates points randomly on surface
global proc vector[] genPoints2DFromSurf(int $quant)
{   
 
    string $obj[] = `ls -sl -tr`;
    print $obj; 
    vector $points[];
    vector $pointsUV[];
    vector $P;
	vector $UV;
 
    string $myGroup = `group -em -n "Locators"`;
 
    for ($i=0; $i<$quant; $i++)
    {
        int $sel = rand (size($obj)-1);
        string $O = $obj[$sel];
 
        float $U = `rand 1`;
        float $V = `rand 1`;
 
        $UV = <<$U, $V, 0>>;
        $pointsUV[size($pointsUV)] = $UV;
        $P = `pointOnSurface -top 1 -u $U -v $V -p $O`;
        $points[size($points)] = $P;
        $loc = `spaceLocator -p ($P.x) ($P.y) ($P.z)`; // make a locator to see points
		parent $loc[0] $myGroup;
 
    }
    return $pointsUV;
}
 
//generates points on surface in grid mode
global proc vector[] genPointGrid2DFromSurf(string $Type, int $numU, int $numV, float $expU, float $expV)
{   
 
	//USER VARIABLES
	string $expGrowth = "true";
	int $inc = 1;			//this value increments the number of points, if $expGrowth is set to 1;
 
	int $latTrans = 0;		//0 = no lateral translation, 1 = randomized, 2 = sine wave pattern
	float $range = 0.05;
 
	string $obj[] = `ls -sl -tr`;
    print $obj; 
    vector $points[];
    vector $pointsUV[];
    vector $P;
	vector $UV;
	float $U, $V;
 
	int	$incU = $numU;
 
    string $myGroup = `group -em -n "Locators"`;
 
		for ($i=0; $i<=$numV; $i++){
 
			if($expGrowth == "true"){
				$incU = ($numU + $inc * ($numV - $i));
			}
 
			for ($j=0; $j<=$incU; $j++){
 
				int $sel = rand (size($obj)-1);
				string $O = $obj[$sel];
 
				if ($latTrans == 1){
 
					float $randU = rand(-$range/2, $range/2);
					float $randV = rand(-$range/2, $range/2);
 
					$U = pow($j,$expU)/ pow(float($incU),$expU) + $randU;
					$V = pow($i,$expV)/ pow(float($numV),$expV) + $randV;
 
					if($j == $incU){
						$U = 1;
					}else if($j == 0){
						$U = 0;
					}else if($i == $numV){
						$V = 1;
					}else if($i == 0){
						$V = 0;
					}
 
				}else if ($latTrans == 2){
 
					//float $sinU = rand(-$range/2, $range/2);
					float $sinV = sin($j)*$range/2;
 
					$U = pow($j,$expU)/ pow(float($incU),$expU);
					$V = pow($i,$expV)/ pow(float($numV),$expV) + $sinV;
 
					if($j == $incU){
						$U = 1;
					}
					if($j == 0){
						$U = 0;
					}
					if($i == $numV){
						$V = 1;
					}
					if($i == 0){
						$V = 0;
					}
 
				}else{
					$U = pow($j,$expU)/ pow(float($incU),$expU);
					$V = pow($i,$expV)/ pow(float($numV),$expV);
				}
 
				$UV = <<$U, $V, 0>>;
				$pointsUV[size($pointsUV)] = $UV;
				$P = `pointOnSurface -top 1 -u $U -v $V -p $O`;
				$points[size($points)] = $P;
				$loc = `spaceLocator -p ($P.x) ($P.y) ($P.z)`; // make a locator to see points
				parent $loc[0] $myGroup;
 
			}
 
		}
    if ($Type == "convexhull"){	
    	return $points;
    }else{
    	return $pointsUV;
    }
}
 
global proc vector[] genPointsFromSurf(int $quant)
{   
 
    string $obj[] = `ls -sl -tr`;
    print $obj; 
    vector $points[];
    vector $P;
 
    string $myGroup = `group -em -n "Locators"`;
 
    for ($i=0; $i<$quant; $i++)
    {
        int $sel = rand (size($obj)-1);
        string $O = $obj[$sel];
 
        float $u = `getAttr ($O+".spansU")`+`getAttr ($O+".degreeU")`;
        float $v = `getAttr ($O+".spansV")`+`getAttr ($O+".degreeV")`;
        float $U = `rand $u`;
        float $V = `rand $v`;
 
        $P = `pointPosition ($O+".uv["+$U+"]["+$V+"]")`;
        $points[size($points)] = $P;
        $loc = `spaceLocator -p ($P.x) ($P.y) ($P.z)`; // make a locator to see points
        parent $loc[0] $myGroup;
    }
    return $points;
}
 
global proc vector[] genPointsFromFile(string $FileName)
{
    // This procedure will process points froma Qhull file
    // This is intended for the Qvoronoi setting
    // 
    vector $point;
    vector $points[];
 
    string $myGroup = `group -em -n "Locators"`;
 
    $fileId = `fopen $FileName "r"`;
    string $nextLine = `fgetline $fileId`;
    while ( size( $nextLine ) > 0 ) {
        if ( `size(strip($nextLine))` > 5 ){
            $point = `strip($nextLine)`; // Separate the digits into a list
            //$point = stringToStringArray(`strip($nextLine)`, " ");
            //$points[size($points)] = $point;
 
            //print($point.y + "\n");
            $loc = `spaceLocator -p ($point.x/1000) ($point.y/1000) ($point.z/1000)`; // make a locator to see points
            parent $loc[0] $myGroup;
            } // end if
        $nextLine = `fgetline $fileId`;
        } // end while
    fclose $fileId; 
return $points;    
}
 
//Step 2: send points to text file
 
global proc string PointsToFileForQhull(vector $Points[], string $Type,int $show)
{
    // Run through a list of vectors and write a file readable for Qhull
    //string $dir = "/Users/scottmaggart/Desktop/"; //enter the path to the work folder
    $dir = `internalVar -utd`;
    $FileName = ( $dir + "QtempIn" ); // Make a temp output file
    $fileId=`fopen $FileName "w"`; // open for writing
    string $output;
 
    if ($Type == "delaunay2D" || $Type == "delaunay2DFromSelection"){
		$output = "2\n"+size($Points)+"\n"; // First line (Qhull format)
 
		for ($p in $Points)
		{
			string $currLine = ($p.x + " " + $p.y + "\n"); // Points format
			$output = $output+$currLine; // This compound the entire string to one big string.
										 // The \n above causes the next line instead of <Enter>
		}
	}else if ($Type == "voronoi2D" || $Type == "voronoi2DFromSelection"){
		$output = "2\n"+size($Points)+"\n"; // First line (Qhull format)
 
		for ($p in $Points)
		{
			string $currLine = ($p.x + " " + $p.y + "\n"); // Points format
			$output = $output+$currLine; // This compound the entire string to one big string.
										 // The \n above causes the next line instead of <Enter>
		}
	}else{
    		$output = "3\n"+size($Points)+"\n"; // First line (Qhull format)
 
    		for ($p in $Points)
			{
				string $currLine = ($p.x + " " + $p.y + " " + $p.z+"\n"); // Points format
				$output = $output+$currLine; // This compound the entire string to one big string.
											 // The \n above causes the next line instead of <Enter>
			}
    }
 
    fwrite $fileId $output; // write the file
    fclose $fileId; // close the file... MUST DO THIS ALWAYS
    return $FileName; // so we can pass the exact location to the read-in proc
}
 
//Step 3: run qhull
 
global proc string[] runQhull(string $FileNameIN, string $Type, int $show)
{   
    // Send commands to Qhull through the system command prompt
    string $dir = `internalVar -utd`; 
    string $FileNameIndexes = ( $dir + $Type + "Indexes" );
    string $FileNamePoints = ( $dir + $Type + "Points" );
    string $FileNameRegions = ( $dir + $Type + "Regions" );
 
    if ($Type == "convexhull")
        {
        // For Delaunay, we only want an index list of how to assemble
        // $Points into facets
        //
        //for Mac
        //system("/applications/qhull/src/qhull i < "+$FileNameIN+" > "+$FileNameIndexes);                                 
        //
        //for PC
        system("C:/qhull/qhull i < "+$FileNameIN+" > "+$FileNameIndexes);                                 
 
        }
 
    else if ($Type == "delaunay2D" || $Type == "delaunay2DFromSelection")
        {
        // For Delaunay, we only want an index list of how to assemble
        // $Points into facets
        //
		//system("/applications/qhull/src/qdelaunay i < "+$FileNameIN+" > "+$FileNameIndexes);
		//
        //for Mac
        //system("/applications/qhull/src/qhull i d Qbb Qt < "+$FileNameIN+" > "+$FileNameIndexes);                                 
        //
        //for PC
        system("C:/qhull/qhull i d Qbb Qt < "+$FileNameIN+" > "+$FileNameIndexes);                                 
 
        }
 
     else if ($Type == "delaunay3D")
        {
        // For Delaunay, we only want an index list of how to assemble
        // $Points into facets
        //
		//system("/applications/qhull/src/qdelaunay i < "+$FileNameIN+" > "+$FileNameIndexes);
		//
        //for Mac
        //system("/applications/qhull/src/qhull i d Qbb Qt < "+$FileNameIN+" > "+$FileNameIndexes);                                 
        //
        //for PC
        system("C:/qhull/qhull i d Qbb Qt < "+$FileNameIN+" > "+$FileNameIndexes);                                 
 
        }
 
    else if ($Type == "voronoi2D")
        {
        // Voronoi requires a list of points and the indexing of those
        // points.  $Points will no longer be used
        //
        //for Mac
        //system("/applications/qhull/src/qvoronoi p < "+$FileNameIN+" > "+$FileNamePoints);                                  
        //system("/applications/qhull/src/qvoronoi Fv <  "+$FileNameIN+" > "+$FileNameIndexes);
        //
        //for PC
        system("C:/qhull/qvoronoi p < "+$FileNameIN+" > "+$FileNamePoints);
        system("C:/qhull/qvoronoi Fv < "+$FileNameIN+" > "+$FileNameIndexes);
        }
    else if ($Type == "voronoi3D" || $Type == "voronoi2DFromSelection")
        {
        // Voronoi requires a list of points and the indexing of those
        // points.  $Points will no longer be used
        //
        //for Mac
        //system("/applications/qhull/src/qvoronoi o < " + $FileNameIN + " > " + $FileNameRegions);
        //
        //for PC
        system("C:/qhull/qvoronoi o < " + $FileNameIN + " > " + $FileNameRegions);
        }
    else
    	{
    	error "Specify type!";
 
    	}
    if ($show == 1)
    {
        system("open "+ $FileNamePoints); 
        system("open "+ $FileNameIndexes); 
    }
    string $files[]={$FileNamePoints, $FileNameIndexes, $FileNameRegions};
    return $files;
}
 
//Step 4: process the result from qhull
 
global proc vector[] processQPointFile(string $FileName)
{
    // This procedure will process points froma Qhull file
    // This is intended for the Qvoronoi setting
    // 
    vector $point;
    vector $points[];
    $fileId = `fopen $FileName "r"`;
    string $nextLine = `fgetline $fileId`;
    while ( size( $nextLine ) > 0 ) {
        if ( `size(strip($nextLine))` > 5 ){
            $point = `strip($nextLine)`; // Separate the digits into a list
            //$point = stringToStringArray(`strip($nextLine)`, " ");
            $points[size($points)] = $point;
            } // end if
        $nextLine = `fgetline $fileId`;
        } // end while
    fclose $fileId; 
return $points;    
}
 
global proc string[] processQIndexFile(string $FileName)
{
    // This procedure will process points from a Qhull file
    // 
    string $ind;
    string $index[];
    $fileId = `fopen $FileName "r"`;
    string $nextLine = `fgetline $fileId`;
    while ( size( $nextLine ) > 0 ) 
        {
        if (size(stringToStringArray(`strip($nextLine)`, " ")) >= 3 )
            {
            $ind = `strip($nextLine)`; // Separate the digits into a list
            $index[size($index)] = $ind;
            } // end if
        $nextLine = `fgetline $fileId`;
        } // end while
    fclose $fileId;    
return $index;    
}
 
global proc vector[] processQFileVertex(string $FileName)
{
 
	string $dim, $ind, $num[], $vertex[];
	vector $V, $Vertexes[];
    string $index[];
 
    //open the file
    int $file = `fopen $FileName "r"`;
 
    //the first line contains the dimension
    string $nextLine = `fgetline $file`;
    $dim = `strip($nextLine)`;
 
    //read the second line to get the number of vertices and the number of input sites/voronoi regions
    string $nextLine = `fgetline $file`;
    $num = stringToStringArray(`strip($nextLine)`, " ");
    $numV = int($num[0]);		//number of vertices
    $numI = int($num[1]);		//number of input sites
 
    //the following $numV lines contain the coordinates of the n voronoi vertices
    for($i=0;$i<$numV;$i++){
    	string $nextLine = `fgetline $file`;
    	$vertex = stringToStringArray(`strip($nextLine)`, " ");
    	if(size($vertex)==2){
    		$V = <<float($vertex[0]), float($vertex[1]), 0>>;
    	}else{
    		$V = <<float($vertex[0]), float($vertex[1]), float($vertex[2])>>;
    	}
    	//$loc = `spaceLocator -p ($V.x) ($V.y) ($V.z)`;			//create a locator for each vertex
    	$Vertexes[size($Vertexes)] = $V;
    }
 
	//close the file
    fclose $file;
 
    return $Vertexes;   
 
}
 
global proc string[] processQFileRegion(string $FileName)
{
 
	string $dim, $ind, $num[], $vertex[];
    string $Regions[];
 
    //open the file
    int $file = `fopen $FileName "r"`;
 
    //the first line contains the dimension
    string $nextLine = `fgetline $file`;
    $dim = `strip($nextLine)`;
 
    //read the second line to get the number of vertices and the number of input sites/voronoi regions
    string $nextLine = `fgetline $file`;
    $num = stringToStringArray(`strip($nextLine)`, " ");
    $numV = int($num[0]);		//number of vertices
    $numI = int($num[1]);		//number of input sites
 
    //the following $numV lines contain the coordinates of the $numV voronoi vertices.
    //we already know them so we can skipt them
    for($i=0;$i<$numV;$i++){
    	string $nextLine = `fgetline $file`;
    }
 
    //each remaining line starts with the number of Voronoi vertices defining a Voronoi region,
    //followed by the vertices that define the region
    for($i=0;$i<$numI;$i++){
   		string $nextLine = `fgetline $file`;
   		string $region[] = stringToStringArray(`strip($nextLine)`, " ");
 
   		//check if region contains a point at infinity
		int $myInt = searchIntArray($region, "0");
 
		//if the region does not contain a vertex at infinity, assign the region to the list of regions
		//that we are going to use to build geometry
		if ($myInt != 1 && size($region)>3){
			//print($nextLine);
			$Regions[size($Regions)] = $nextLine;
		}		
    }
	//close the file
    fclose $file;
 
    return $Regions;   
 
}
 
global proc int searchIntArray(string $Array[], int $Num)
{
	int $Bln = 0;
	for($item in $Array){
		if($item == $Num){
			$Bln = 1;
			break;
		}
	}
	return $Bln;
}
 
//Step 5: generate geometry based on qhull result
 
global proc string makeFacets(vector $Points[], string $Index[], string $Type, string $outType)/*, vector $points[]) // $Points are global*/
{   
    vector $Points[];
    vector $tmpPoints1[] = $Points;
    vector $tmpPoints2[];
    string $index[];
    string $faces[];
 
    vector $p;
    vector $prevPoint;
    int $ci;
    string $ps;
 
    string $ResultType = "polygons";
 
    string $list[] = `ls -sl`;
    string $collectCurves[];
    string $myGroup = `group -em -n "Facets"`;
    for ($ind in $Index)
    {
        $index = stringToStringArray($ind, " ");
   		if($outType == "wire"){
			//create a curve that connects all the vertices of a region
			//get all the vertices that define the region
			$curve = "curve -d 1";
 
			for($j=0;$j<size($index);$j++){
				vector $p = $Points[int($index[$j])];
				$curve += " -p " + ($p.x) + " " + ($p.y) + " " + ($p.z);
			}
			//print ($facet + ";\n");
			string $newCurve = `eval($curve)`;
			closeCurve -ch 0 -ps 0 -rpo 1 -bb 0.5 -bki 0 -p 0.1 $newCurve;
 
			$faces[size($faces)] = $newCurve;
 
		}else if ($outType == "poly"){
            string $ps = "polyCreateFacet ";
            for ($i=0; $i<size($index);$i++) 
            {   
                int $ci = abs(  (int)$index[$i]  );
                vector $p = $Points[$ci];
                if ($Type == "delaunay2D"){
                	//get the world coordinates to the surface point first
                	vector $wc = `pointOnSurface -top 1 -u ($p.x) -v ($p.y) -p $list[0]`;
               		$ps = $ps +"-p (" +$wc.x+ ") ("+$wc.y+") ("+$wc.z+")";
	            }else{
	            	$ps = $ps +"-p (" +$p.x+ ") ("+$p.y+") ("+$p.z+")";
	            }
 
            }
            $ps = $ps+";"; 						// never forget your semicolon or there is HELL to pay!
            $name = eval ($ps); 				// this is how we launch the command 
            $faces[size($faces)] = $name[0];
 
        	//refresh; // Uncomment this for cinematics ;-)
		}else{
			error "specify output type!";
		}
 
    }
 
    parent $faces $myGroup;
 
    if ($outType == "poly"){
		//combine all the faces into one closed polygon
		$myResult = `polyUnite -ch off -n "polyResult" $faces`;
		polyMergeVertex  -d 0.01 -am 1 -ch 0 $myResult[0];
 
		//polySmooth  -mth 0 -dv 2 -c 1 -kb 0 -ksb 1 -khe 0 -kt 1 -kmb 2 -suv 1 -sl 1 -dpe 1 -ps 0.1 -ro 1 -ch 1 $myResult;
 
		return $myResult[0]; 
	}else{
		return $myGroup; 
	}
 
	select -cl;
 
 
}
 
global proc string[] makeRidges(vector $Points[], vector $voronoiVertices[], string $Index[], string $Type)/*, vector $points[]) // $Points are global*/
{   
    global vector $Points[];
    string $index[];
    $list = `ls -sl`;
 
    string $ridge;
	string $Ridges[];
 
	$group = `group -em -n "Ridges"`;
 
    for ($ind in $Index)
    {
        $index = stringToStringArray($ind, " ");
 
        //The first line is the number of ridges. Then each ridge is printed, one per line. 
        //The first number is the count of indices. The second pair of indices indicates a pair of input sites.
        //The remaining indices list the corresponding ridge of Voronoi vertices.
 
        int $num3 = abs(int($index[3]));
        int $num4 = abs(int($index[4]));
 
        //Vertex 0 is the vertex-at-infinity. It indicates an unbounded ray.
        //The unbounded ray is directed from the Voronoi vertices to infinity.
        //In order to build the ray we have to find the midpoint between the 2 inputPoints.
 
        if ($num3 == 0){	//we are dealing with a vertex at infinity
 
        	int $num1 = abs(int($index[1]));
        	int $num2 = abs(int($index[2]));
 
        	vector $iPt1 = $Points[$num1];
        	vector $iPt2 = $Points[$num2];
 
        	vector $midPt = ($iPt1 + $iPt2)/2;
 
        	vector $vertex1 = $midPt;
        	vector $vertex2 = $voronoiVertices[$num4-1];
 
        	if ($Type == "voronoi2D"){ 
 
				//get the world coordinates to the surface point first
				vector $wc1 = `pointOnSurface -top 1 -u ($vertex1.x) -v ($vertex1.y) -p $list[0]`;
				vector $wc2 = `pointOnSurface -top 1 -u ($vertex2.x) -v ($vertex2.y) -p $list[0]`;
 
				if (mag($wc1) < mag($wc2)){
					$ridge = `curve -d 1 -p ($wc1.x) ($wc1.y) ($wc1.z) -p ($wc2.x) ($wc2.y) ($wc2.z)`;
				}else{
					$ridge = `curve -d 1 -p ($wc2.x) ($wc2.y) ($wc2.z) -p ($wc1.x) ($wc1.y) ($wc1.z)`;
				}
 
			}else if ($Type == "voronoi2DFromSelection"){
 
				/*if (mag($vertex1) < mag($vertex2)){
					$ridge = `curve -d 1 -p ($vertex1.x) ($vertex1.y) ($vertex1.z) -p ($vertex2.x) ($vertex2.y) ($vertex2.z)`;
				}else{
					$ridge = `curve -d 1 -p ($vertex2.x) ($vertex2.y) ($vertex2.z) -p ($vertex1.x) ($vertex1.y) ($vertex1.z)`;
				}*/
 
				$ridge = `curve -d 1 -p ($vertex1.x) ($vertex1.y) ($vertex1.z) -p ($vertex2.x) ($vertex2.y) ($vertex2.z)`;
 
			}else{
				error "$Type should be voronoi2D or voronoi2DFromSelection!";
			}
 
        	//hide $ridge;
 
        }else{
 
    	    vector $vertex1 = $voronoiVertices[$num3-1];
	        vector $vertex2 = $voronoiVertices[$num4-1];
 
	        if ($Type == "voronoi2D"){ 
 
				//get the world coordinates to the surface point first
				vector $wc1 = `pointOnSurface -top 1 -u ($vertex1.x) -v ($vertex1.y) -p $list[0]`;
				vector $wc2 = `pointOnSurface -top 1 -u ($vertex2.x) -v ($vertex2.y) -p $list[0]`;
 
				$ridge = `curve -d 1 -p ($wc1.x) ($wc1.y) ($wc1.z) -p ($wc2.x) ($wc2.y) ($wc2.z)`;
 
        	}else if ($Type == "voronoi2DFromSelection"){
        		$ridge = `curve -d 1 -p ($vertex1.x) ($vertex1.y) ($vertex1.z) -p ($vertex2.x) ($vertex2.y) ($vertex2.z)`;
        	}else{
        		error "$Type should be voronoi2D or voronoi2DFromSelection!";
        	}
 
        }
 
        //refresh; // Uncomment this for cinematics ;-)
 
		parent $ridge $group;
 
		$Ridges[size($Ridges)] = $ridge;
    }
 
	return $Ridges;    
}
 
global proc string[] createRegions(vector $Vertexes[], string $Regions[], string $Type, string $outType)
{
 
	string $newRegions[];
 
	//$outType = "facet";
	for($line in $Regions){
   		//string $nextLine = `fgetline $file`;
   		string $region[] = stringToStringArray(`strip($line)`, " ");
   		if($Type != "voronoi3D" && $outType == "wire"){
			//create a curve that connects all the vertices of a region
			//get all the vertices that define the region
			$curve = "curve -d 1";
 
			for($j=1;$j<size($region);$j++){
				$V = $Vertexes[int($region[$j])];
				$curve += " -p " + ($V.x) + " " + ($V.y) + " " + ($V.z);
			}
			//print ($facet + ";\n");
			string $newCurve = `eval($curve)`;
			closeCurve -ch 0 -ps 0 -rpo 1 -bb 0.5 -bki 0 -p 0.1 $newCurve;
 
			$newRegions[size($newRegions)] = $newCurve;
 
		}else if($Type != "voronoi3D" && $outType == "poly"){
			//create a facet that connects all the vertices of a region
			string $facet = "polyCreateFacet";
 
			for($j=1;$j<size($region);$j++){
				$V = $Vertexes[int($region[$j])];
				$facet += " -p " + ($V.x) + " " + ($V.y) + " " + ($V.z);
			}
			//print ($facet + ";\n");
			string $newFacet[] = `eval($facet)`;
			polySmooth  -mth 0 -dv 2 -c 1 -kb 0 -ksb 1 -khe 0 -kt 1 -kmb 2 -suv 1 -sl 1 -dpe 1 -ps 0.1 -ro 1 -ch 1 $newFacet[0];
 
			$newRegions[size($newRegions)] = $newFacet[0];
 
		}else if($Type == "voronoi3D"){
			//create a convex hull of all the vertices of the region
			vector $currVertexes[];
 
			//Step 1: get the current vertices from the list in the region
			for($j=1;$j<size($region);$j++){
				$currVertexes[size($currVertexes)] = $Vertexes[int($region[$j])];
			}
 
			//Step 2: send the points to a text file
			string $mayaOut = PointsToFileForQhull($currVertexes, "convexhull", 0);
			//print("File created -> " + $mayaOut + "\n");
 
			//Step 3: run qhull
			string $mayaIn[] = runQhull($mayaOut, "convexhull", 0);
			//print("File created -> " + $mayaIn[1] + "\n");
 
			//Step 4: process qhull output file
			string $Indexes[] = processQIndexFile($mayaIn[1]);
			//print("Number of facets to be built -> " + size($Indexes) + "\n");
 
			//Step 5: create facets
			string $newFacet = makeFacets($currVertexes, $Indexes, "convexhull", $outType);
			//print("Number of facets created -> " + size($Facets) + "\n");
 
			$newRegions[size($newRegions)] = $newFacet;
 
			select -cl;
 
			clear($currVertexes);
 
		}else{
			error "specify output type!";
		}
		refresh;
	}
 
	return $newRegions;
 
}
 
 
 
 
/*
 
This script allows the creation of Delaunay triangulations and Voronoi Diagrams on a selection of points.
It works in conjunction with qhullFunctions.mel. Make sure you download the latest version of qhullFunctions.mel
from http://researchnodes.org/doku.php?id=digitalcities:qhullfunctions.mel.
 
Usage: select any number of points (locators) then run the script:
 
string $arrType[] = {"convexhull", "delaunay2DFromSelection", "delaunay3D", "voronoi2DFromSelection", "voronoi3D"};
qhullSelection($arrType[1]);
 
This example will create a 2-dimensional Delaunay trianglulation from the selected points. Remember that 
index 1 in an array corresponds to the second item in the list (index 0 is the first item).
 
Author: Tobias Schwinn - http://www.tobesch.de
 
Last modified: 27/06/2007
 
Change Log:
 
27/06/2007 - changed to allow for the creation of 3D voronoi diagrams, plus added wireframe ("wire") as output type
02/06/2007 - first release
 
*/
 
 
 
proc qhullSelection(string $Type){
 
	//user variables
	string $outType = "poly";			//"wire", "poly"
 
	string $Regions[], $Indexes[];
	vector $Vertices[];
 
	//Step 1: get the points from selection
	vector $Points[] = getPointsFromSelection();
	//print("Points selected -> " + size($Points) + "\n");
 
	//Step 2: send the points to a text file
	string $mayaOut = PointsToFileForQhull($Points, $Type, 0);
	//print("File created -> " + $mayaOut + "\n");
 
	//Step 3: run qhull
	string $mayaIn[] = runQhull($mayaOut, $Type, 0);
	//print("File created -> " + $mayaIn[1] + "\n");
 
	//Step 4: process qhull output file
	if ($Type == "voronoi2DFromSelection" || $Type == "voronoi3D"){
		$Vertices = processQFileVertex($mayaIn[2]);
		//print("Number of Voronoi vertices -> " + size($Vertices) + "\n");
		$Regions = processQFileRegion($mayaIn[2]);
		//print("Number of Voronoi regions to be built -> " + size($Regions) + "\n");
	}else{
		$Indexes = processQIndexFile($mayaIn[1]);
		//print("Number of facets to be built -> " + size($Indexes) + "\n");
	}
 
	//Step 5: create facets or ridges
	$myGroup = `group -em -n "Result"`;
	if ($Type == "voronoi2DFromSelection" || $Type == "voronoi3D"){
		string $myRegions[] = createRegions($Vertices, $Regions, $Type, $outType);
		//print("Number of Voronoi regions built -> " + size($myRegions) + "\n");
		parent $myRegions $myGroup;
	}else{
		string $newObj = makeFacets($Points, $Indexes, $Type, $outType);
		//print("New convex hull created -> " + $newObj + "\n");
		parent $newObj $myGroup;
	}
 
 
 
}
 
 
print("qhullFunctions.mel sourced...\n");
 
/*
 
This script allows the creation of Delaunay triangulations and Voronoi Diagrams on a selection of points.
It works in conjunction with qhullFunctions.mel. Make sure you download the latest version of qhullFunctions.mel
from http://researchnodes.org/doku.php?id=digitalcities:qhullfunctions.mel.
 
Usage: select any number of points (locators) then run the script:
 
string $arrType[] = {"convexhull", "delaunay2DFromSelection", "delaunay3D", "voronoi2DFromSelection", "voronoi3D"};
qhullSelection($arrType[1]);
 
This example will create a 2-dimensional Delaunay trianglulation from the selected points. Remember that 
index 1 in an array corresponds to the second item in the list (index 0 is the first item).
 
Author: Tobias Schwinn - http://www.tobesch.de
 
Last modified: 27/06/2007
 
Change Log:
 
27/06/2007 - changed to allow for the creation of 3D voronoi diagrams, plus added wireframe ("wire") as output type
02/06/2007 - first release
 
*/
 
proc qhullSelection(string $Type){
 
	//user variables
	string $outType = "poly";			//"wire", "poly"
 
	string $Regions[], $Indexes[];
	vector $Vertices[];
 
	//Step 1: get the points from selection
	vector $Points[] = getPointsFromSelection();
	//print("Points selected -> " + size($Points) + "\n");
 
	//Step 2: send the points to a text file
	string $mayaOut = PointsToFileForQhull($Points, $Type, 0);
	//print("File created -> " + $mayaOut + "\n");
 
	//Step 3: run qhull
	string $mayaIn[] = runQhull($mayaOut, $Type, 0);
	//print("File created -> " + $mayaIn[1] + "\n");
 
	//Step 4: process qhull output file
	if ($Type == "voronoi2DFromSelection" || $Type == "voronoi3D"){
		$Vertices = processQFileVertex($mayaIn[2]);
		//print("Number of Voronoi vertices -> " + size($Vertices) + "\n");
		$Regions = processQFileRegion($mayaIn[2]);
		//print("Number of Voronoi regions to be built -> " + size($Regions) + "\n");
	}else{
		$Indexes = processQIndexFile($mayaIn[1]);
		//print("Number of facets to be built -> " + size($Indexes) + "\n");
	}
 
	//Step 5: create facets or ridges
	$myGroup = `group -em -n "Result"`;
	if ($Type == "voronoi2DFromSelection" || $Type == "voronoi3D"){
		string $myRegions[] = createRegions($Vertices, $Regions, $Type, $outType);
		//print("Number of Voronoi regions built -> " + size($myRegions) + "\n");
		parent $myRegions $myGroup;
	}else{
		string $newObj = makeFacets($Points, $Indexes, $Type, $outType);
		//print("New convex hull created -> " + $newObj + "\n");
		parent $newObj $myGroup;
	}
 
 
 
}

Modellversuche

Endresultat

Quellenverzeichnis

http://www.learning-maya.com/69-0-mel--scripting-tutorials.html
http://de.wikipedia.org/wiki/Voronoi-Diagramm
http://www.researchnodes.org/doku.php?id=examples:qhull:qhullselection.mel&do=index
http://www.qhull.org/
http://iam.tugraz.at/


zurück zur Liste der Studentenprojekte

Attribute

Roland Rainer,Wieser Georg Schumacher Patrik Budig Michael,Neumayr Robert,Malin Markus | E5,E3 | E3/E5 Projekt Wieser Rainer | Strukturelle morphologien | 08SS Datei:Packen-endresultat.jpg

Fakten zu VoronoiturmRDF-Feed
BetreuerSchumacher Patrik  +, Budig Michael  +, Neumayr Robert  + und Malin Markus  +
ImagePacken-endresultat.jpg  +
LVE5  + und E3  +
Semester08SS  +
ThemaStrukturelle morphologien  +
TitelE3/E5 Projekt Wieser Rainer  +
VerfasserRoland Rainer  + und Wieser Georg  +
Persönliche Werkzeuge