Jump to content

Catmull–Clark subdivision surface/Tcl Test Code

From Rosetta Code

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>

Program Output


This figure shows the result of running the code on this page.

Cookies help us deliver our services. By using our services, you agree to our use of cookies.