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] {set d1 [expr {$d1 + [lindex $p 1]}]}
   foreach p [selectFrom $points $face2] {set d2 [expr {$d2 + [lindex $p 1]}]}
   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] foreach coord $polyCoords { lassign $coord x y z lappend c \ [expr {100 + 90*($x - 0.5*$y)}] \ [expr {100 + 90*(0.86*$y - $z)}] } $w create polygon $c -fill {} {*}$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]

  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}

}

  1. Try removing one of the faces to demonstrate holes.

set faces {

   {0 1 2 3}
   {0 3 7 4}
   {0 1 5 4}
   {3 2 6 7}
   {1 5 6 2}
   {4 7 6 5}

}

  1. Show the initial layout

visualizeNet .c $points $faces -outline black

  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
  1. lassign [CatmullClark $points2 $faces2] points2 faces2
  1. Visualize the new surface

visualizeNet .c $points2 $faces2 -outline green -fill green4</lang>