Catmull–Clark subdivision surface/Tcl Test Code: Difference between revisions

From Rosetta Code
Content added Content deleted
Line 42: Line 42:
(Using the utility functions from above, plus the code from the main solution page.)
(Using the utility functions from above, plus the code from the main solution page.)
<lang tcl># Make a display surface
<lang tcl># Make a display surface
pack [canvas .c]
pack [canvas .c -width 400 -height 400 -background #7f7f7f]

# Points to define the unit cube
# Points to define the unit cube
set points {
set points {
Line 55: Line 55:
{0.0 1.0 1.0}
{0.0 1.0 1.0}
}
}
foreach pt $points {
# Try removing one of the faces to demonstrate holes.
lassign $pt x y z
lappend points [list [expr {0.25 + 0.5*$x}] [expr {0.25 + 0.5*$y}] $z]
}
# Try removing {1 2 6 5} to demonstrate holes.
set faces {
set faces {
{0 1 2 3}
{0 8 9 1}
{0 3 7 4}
{1 9 10 2}
{2 10 11 3}
{3 11 8 0}
{0 1 5 4}
{0 1 5 4}
{3 2 6 7}
{1 2 6 5}
{1 5 6 2}
{2 3 7 6}
{4 7 6 5}
{3 0 4 7}
{4 5 13 12}
{5 6 14 13}
{6 7 15 14}
{7 4 12 15}
{8 9 13 12}
{9 10 14 13}
{10 11 15 14}
{11 8 12 15}
}
}

# Show the initial layout
# Show the initial layout
visualizeNet .c $points $faces -outline black
visualizeNet .c $points $faces -outline white -fill {}

# Apply the Catmull-Clark algorithm to generate a new surface
# Apply the Catmull-Clark algorithm to generate a new surface
lassign [CatmullClark $points $faces] points2 faces2
lassign [CatmullClark $points $faces] points2 faces2

## Uncomment the next line to get the second level of subdivision
## Uncomment the next line to get the second level of subdivision
#lassign [CatmullClark $points2 $faces2] points2 faces2
lassign [CatmullClark $points2 $faces2] points2 faces2
lassign [CatmullClark $points2 $faces2] points2 faces2

# Visualize the new surface
# Visualize the new surface
visualizeNet .c $points2 $faces2 -outline green -fill green4</lang>
visualizeNet .c $points2 $faces2 -outline #0000cc</lang>

Revision as of 01:26, 18 January 2010

This is the test code for the Tcl solution of the Catmull-Clark problem.

Library: Tk

Utility Functions

<lang tcl>package require Tk

  1. A simple-minded ordering function for faces

proc orderf {points face1 face2} {

   set d1 [set d2 0.0]
   foreach p [selectFrom $points $face1] {

lassign $p x y z set d1 [expr {$d1 + sqrt($x*$x + $y*$y + $z*$z)}]

   }
   foreach p [selectFrom $points $face2] {

lassign $p x y z set d2 [expr {$d2 + sqrt($x*$x + $y*$y + $z*$z)}]

   }
   expr {$d1<$d2 ? -1 : $d1>$d2 ? 1 : 0}

}

  1. Plots a net defined in points-and-faces fashion

proc visualizeNet {w points faces args} {

   foreach face [lsort -command [list orderf $points] $faces] {

set c {} set polyCoords [selectFrom $points $face] set sum {[list 0. 0. 0.]} set centroid [centroid $polyCoords] foreach coord $polyCoords { lassign $coord x y z lappend c \ [expr {200. + 190. * (0.867 * $x - 0.9396 * $y)}] \ [expr {200 + 190. * (0.5 * $x + 0.3402 * $y - $z)}] } lassign $centroid x y z set depth [expr {int(255*sqrt($x*$x + $y*$y + $z*$z) / sqrt(3.))}] set grey [format #%02x%02x%02x $depth $depth $depth] $w create polygon $c -fill $grey {*}$args

   }

}</lang>

Demonstration

(Using the utility functions from above, plus the code from the main solution page.) <lang tcl># Make a display surface pack [canvas .c -width 400 -height 400 -background #7f7f7f]

  1. Points to define the unit cube

set points {

   {0.0 0.0 0.0}
   {1.0 0.0 0.0}
   {1.0 1.0 0.0}
   {0.0 1.0 0.0}
   {0.0 0.0 1.0}
   {1.0 0.0 1.0}
   {1.0 1.0 1.0}
   {0.0 1.0 1.0}

} foreach pt $points {

   lassign $pt x y z
   lappend points [list [expr {0.25 + 0.5*$x}] [expr {0.25 + 0.5*$y}] $z]

}

  1. Try removing {1 2 6 5} to demonstrate holes.

set faces {

   {0 8 9 1}
   {1 9 10 2}
   {2 10 11 3}
   {3 11 8 0}
   {0 1 5 4}
   {1 2 6 5}
   {2 3 7 6}
   {3 0 4 7}
   {4 5 13 12}
   {5 6 14 13}
   {6 7 15 14}
   {7 4 12 15}
   {8 9 13 12}
   {9 10 14 13}
   {10 11 15 14}
   {11 8 12 15}

}

  1. Show the initial layout

visualizeNet .c $points $faces -outline white -fill {}

  1. Apply the Catmull-Clark algorithm to generate a new surface

lassign [CatmullClark $points $faces] points2 faces2

    1. Uncomment the next line to get the second level of subdivision

lassign [CatmullClark $points2 $faces2] points2 faces2 lassign [CatmullClark $points2 $faces2] points2 faces2

  1. Visualize the new surface

visualizeNet .c $points2 $faces2 -outline #0000cc</lang>