You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
453 lines
13 KiB
453 lines
13 KiB
2 years ago
|
#
|
||
|
# This example shows how to generate and manipulate texture coordinates.
|
||
|
# The user can interact with the vtkTransformTextureCoords object to
|
||
|
# modify the texture coordinates interactively. Different objects, textures
|
||
|
# and texture mappers can be selected.
|
||
|
#
|
||
|
|
||
|
#
|
||
|
# First we include the VTK Tcl packages which will make available
|
||
|
# all of the vtk commands to Tcl.
|
||
|
#
|
||
|
package require vtk
|
||
|
package require vtkinteraction
|
||
|
|
||
|
#
|
||
|
# These are the different choices made available to the user.
|
||
|
# They include: models, textures (relative to VTK_DATA_ROOT)
|
||
|
# and mapper types.
|
||
|
#
|
||
|
set models { \
|
||
|
"teapot.g" \
|
||
|
"Viewpoint/cow.g" \
|
||
|
"motor.g" \
|
||
|
}
|
||
|
|
||
|
set textures { \
|
||
|
"vtk.png" \
|
||
|
"masonry.bmp" \
|
||
|
"earth.ppm" \
|
||
|
"B.pgm" \
|
||
|
"beach.jpg" \
|
||
|
"fran_cut.png" \
|
||
|
}
|
||
|
|
||
|
set texture_mapper_types { \
|
||
|
vtkTextureMapToPlane \
|
||
|
vtkTextureMapToSphere \
|
||
|
vtkTextureMapToCylinder \
|
||
|
}
|
||
|
|
||
|
#
|
||
|
# A 3D model is loaded using an BYU reader.
|
||
|
# Compute normals, in case they are not provided with the model.
|
||
|
#
|
||
|
vtkBYUReader model_reader
|
||
|
model_reader SetGeometryFileName "$VTK_DATA_ROOT/Data/[lindex $models 0]"
|
||
|
|
||
|
vtkPolyDataNormals model_normals
|
||
|
model_normals SetInputConnection [model_reader GetOutputPort]
|
||
|
|
||
|
#
|
||
|
# Create all texture coordinates generators/mappers and use the first one
|
||
|
# for the current pipeline.
|
||
|
#
|
||
|
foreach texture_mapper_type $texture_mapper_types {
|
||
|
set texture_mapper \
|
||
|
[$texture_mapper_type [string tolower $texture_mapper_type]]
|
||
|
$texture_mapper SetInputConnection [model_normals GetOutputPort]
|
||
|
}
|
||
|
|
||
|
#
|
||
|
# Create a texture coordinate transformer, which can be used to
|
||
|
# translate, scale or flip the texture.
|
||
|
#
|
||
|
set texture_mapper_type [lindex $texture_mapper_types 0]
|
||
|
vtkTransformTextureCoords transform_texture
|
||
|
transform_texture SetInput [[string tolower $texture_mapper_type] GetOutput]
|
||
|
|
||
|
#
|
||
|
# Create polydata mapper.
|
||
|
#
|
||
|
vtkPolyDataMapper mapper
|
||
|
mapper SetInputConnection [transform_texture GetOutputPort]
|
||
|
|
||
|
#
|
||
|
# A texture is loaded using an image reader.
|
||
|
# Textures are simply images.
|
||
|
# The texture is eventually associated with an actor.
|
||
|
#
|
||
|
set filename "$VTK_DATA_ROOT/Data/[lindex $textures 0]"
|
||
|
vtkImageReader2Factory create_reader
|
||
|
set texture_reader [create_reader CreateImageReader2 $filename]
|
||
|
$texture_reader SetFileName $filename
|
||
|
|
||
|
vtkTexture texture
|
||
|
texture SetInputConnection [$texture_reader GetOutputPort]
|
||
|
texture InterpolateOn
|
||
|
|
||
|
vtkActor actor
|
||
|
actor SetMapper mapper
|
||
|
actor SetTexture texture
|
||
|
|
||
|
#
|
||
|
# Create a triangle filter that will feed the model geometry to
|
||
|
# the feature edge extractor. Create the corresponding mapper
|
||
|
# and actor.
|
||
|
#
|
||
|
vtkTriangleFilter triangle_filter
|
||
|
triangle_filter SetInputConnection [model_normals GetOutputPort]
|
||
|
|
||
|
vtkFeatureEdges edges_extractor
|
||
|
edges_extractor SetInputConnection [triangle_filter GetOutputPort]
|
||
|
edges_extractor ColoringOff
|
||
|
edges_extractor BoundaryEdgesOn
|
||
|
edges_extractor ManifoldEdgesOn
|
||
|
edges_extractor NonManifoldEdgesOn
|
||
|
|
||
|
vtkPolyDataMapper edges_mapper
|
||
|
edges_mapper SetInputConnection [edges_extractor GetOutputPort]
|
||
|
edges_mapper SetResolveCoincidentTopologyToPolygonOffset
|
||
|
|
||
|
vtkActor edges_actor
|
||
|
edges_actor SetMapper edges_mapper
|
||
|
eval [edges_actor GetProperty] SetColor 0 0 0
|
||
|
eval [edges_actor GetProperty] SetLineStipplePattern 4369
|
||
|
edges_actor VisibilityOff
|
||
|
|
||
|
#
|
||
|
# Create the standard rendering stuff.
|
||
|
#
|
||
|
vtkRenderer ren1
|
||
|
|
||
|
vtkRenderWindow renWin
|
||
|
renWin AddRenderer ren1
|
||
|
|
||
|
#
|
||
|
# Add the actors to the renderer, set the background
|
||
|
#
|
||
|
ren1 AddActor actor
|
||
|
ren1 AddActor edges_actor
|
||
|
ren1 SetBackground 1 1 1
|
||
|
|
||
|
#
|
||
|
# Create the Tk widget, associate it with the renderwindow.
|
||
|
#
|
||
|
set vtkw [vtkTkRenderWidget .ren \
|
||
|
-width 500 \
|
||
|
-height 400 \
|
||
|
-rw renWin]
|
||
|
|
||
|
#
|
||
|
# Pack the Tk widget.
|
||
|
#
|
||
|
pack $vtkw -side top -fill both -expand yes
|
||
|
|
||
|
#
|
||
|
# Sets event handlers
|
||
|
#
|
||
|
::vtk::bind_tk_render_widget $vtkw
|
||
|
|
||
|
#
|
||
|
# Create a menubar.
|
||
|
#
|
||
|
set menubar [menu .menubar]
|
||
|
. config -menu $menubar
|
||
|
|
||
|
#
|
||
|
# Create a "File" menu.
|
||
|
#
|
||
|
set file_menu [menu $menubar.file]
|
||
|
|
||
|
$file_menu add command \
|
||
|
-label "Quit" \
|
||
|
-command ::vtk::cb_exit
|
||
|
|
||
|
$menubar add cascade -label "File" -menu $file_menu
|
||
|
|
||
|
#
|
||
|
# Create a "Model" menu.
|
||
|
# Each model is a radio menu entry, associated to
|
||
|
# the load_model callback.
|
||
|
#
|
||
|
set model_menu [menu $menubar.model]
|
||
|
|
||
|
set gui_vars(model_reader,filename) \
|
||
|
[model_reader GetGeometryFileName]
|
||
|
|
||
|
foreach model $models {
|
||
|
set filename "$VTK_DATA_ROOT/Data/$model"
|
||
|
$model_menu add radio \
|
||
|
-label $model \
|
||
|
-command [list load_model $filename] \
|
||
|
-value $filename \
|
||
|
-variable gui_vars(model_reader,filename)
|
||
|
}
|
||
|
|
||
|
proc load_model {filename} {
|
||
|
model_reader SetGeometryFileName $filename
|
||
|
ren1 ResetCamera
|
||
|
renWin Render
|
||
|
}
|
||
|
|
||
|
$menubar add cascade -label "Model" -menu $model_menu
|
||
|
|
||
|
#
|
||
|
# Create a "Texture" menu.
|
||
|
# Each texture is a radio menu entry, associated to
|
||
|
# the load_texture callback.
|
||
|
#
|
||
|
set texture_menu [menu $menubar.texture]
|
||
|
|
||
|
set gui_vars(texture_reader,filename) \
|
||
|
[[[texture GetInputConnection 0 0] GetProducer] GetFileName]
|
||
|
|
||
|
foreach texture $textures {
|
||
|
set filename "$VTK_DATA_ROOT/Data/$texture"
|
||
|
$texture_menu add radio \
|
||
|
-label $texture \
|
||
|
-command [list load_texture $filename] \
|
||
|
-value $filename \
|
||
|
-variable gui_vars(texture_reader,filename)
|
||
|
}
|
||
|
|
||
|
proc load_texture {filename} {
|
||
|
set texture_reader [create_reader CreateImageReader2 $filename]
|
||
|
$texture_reader SetFileName $filename
|
||
|
texture SetInputConnection [$texture_reader GetOutputPort]
|
||
|
renWin Render
|
||
|
}
|
||
|
|
||
|
$menubar add cascade -label "Texture" -menu $texture_menu
|
||
|
|
||
|
#
|
||
|
# Create a "Mapper" menu.
|
||
|
# Each mapper type is a radio menu entry, associated to
|
||
|
# the use_texture_mapper_type callback.
|
||
|
#
|
||
|
set texture_mapper_type_menu [menu $menubar.texture_mapper_type]
|
||
|
|
||
|
set gui_vars(texture_mapper_type) \
|
||
|
[[[transform_texture GetInputConnection 0 0] GetProducer] GetClassName]
|
||
|
|
||
|
foreach texture_mapper_type $texture_mapper_types {
|
||
|
$texture_mapper_type_menu add radio \
|
||
|
-label $texture_mapper_type \
|
||
|
-command [list use_texture_mapper_type $texture_mapper_type] \
|
||
|
-value $texture_mapper_type \
|
||
|
-variable gui_vars(texture_mapper_type)
|
||
|
}
|
||
|
|
||
|
proc use_texture_mapper_type {texture_mapper_type} {
|
||
|
transform_texture SetInputConnection \
|
||
|
[[string tolower $texture_mapper_type] GetOutputPort]
|
||
|
renWin Render
|
||
|
}
|
||
|
|
||
|
$menubar add cascade -label "Mapper" -menu $texture_mapper_type_menu
|
||
|
|
||
|
#
|
||
|
# Create a "View" menu.
|
||
|
# It stores various properties.
|
||
|
#
|
||
|
set view_menu [menu $menubar.view]
|
||
|
|
||
|
set gui_vars(view,edges) [edges_actor GetVisibility]
|
||
|
|
||
|
$view_menu add radio \
|
||
|
-label "Edges" \
|
||
|
-command toggle_edges_visibility \
|
||
|
-value 1 \
|
||
|
-variable gui_vars(view,edges)
|
||
|
|
||
|
proc toggle_edges_visibility {} {
|
||
|
if {[edges_actor GetVisibility]} {
|
||
|
edges_actor VisibilityOff
|
||
|
} else {
|
||
|
edges_actor VisibilityOn
|
||
|
}
|
||
|
set gui_vars(view,edges) [edges_actor GetVisibility]
|
||
|
renWin Render
|
||
|
}
|
||
|
|
||
|
$menubar add cascade -label "View" -menu $view_menu
|
||
|
|
||
|
#
|
||
|
# Create the vtkTransformTextureCoords gui.
|
||
|
#
|
||
|
# Each entry in the following array describe a "control" in the GUI:
|
||
|
# - unique name of the control,
|
||
|
# - title for the control,
|
||
|
# - texture coordinates parametrized by that control,
|
||
|
# - name of the corresponding vtkTransformTextureCoords attribute,
|
||
|
# - start, end, increment value of each Tk scale widget in the control.
|
||
|
#
|
||
|
set transform_texture_coords_gui_controls \
|
||
|
{ \
|
||
|
position "Texture position" {r s} Position 0.0 2.0 0.01 \
|
||
|
scale "Texture scale" {r s} Scale 0.0 5.0 0.05 \
|
||
|
origin "Texture origin" {r s} Origin 0.0 1.0 0.01 \
|
||
|
}
|
||
|
|
||
|
proc create_transform_texture_coords_gui {parent obj} {
|
||
|
|
||
|
global gui_vars transform_texture_coords_gui_controls
|
||
|
|
||
|
#
|
||
|
# Create a main frame
|
||
|
#
|
||
|
if {$parent == "."} {
|
||
|
set main_frame [frame .main]
|
||
|
} else {
|
||
|
set main_frame [frame $parent.main]
|
||
|
}
|
||
|
|
||
|
set scale_width 9
|
||
|
set command [list update_transform_texture_from_gui_vars $obj]
|
||
|
|
||
|
#
|
||
|
# Loop over each "control" description
|
||
|
#
|
||
|
foreach {control label coords obj_method scale_from scale_to scale_res} \
|
||
|
$transform_texture_coords_gui_controls {
|
||
|
|
||
|
#
|
||
|
# Create a frame for the control, a label for its title, and a
|
||
|
# sub-frame that will hold all Tk scale widgets.
|
||
|
#
|
||
|
upvar ${control}_frame control_frame
|
||
|
set control_frame [frame $main_frame.$control -relief groove -border 2]
|
||
|
|
||
|
upvar ${control}_label control_label
|
||
|
set control_label [label $control_frame.label \
|
||
|
-text "$label:" -anchor w]
|
||
|
|
||
|
upvar ${control}_rst control_rst
|
||
|
set control_rst [frame $control_frame.rst]
|
||
|
|
||
|
#
|
||
|
# Add (r,s,t) texture coordinate widgets to the control.
|
||
|
# Each one is made of a label for the coordinate's name, a label
|
||
|
# for the coordinate's value and a Tk scale widget to control
|
||
|
# that value.
|
||
|
# All scale widgets are associated to the same callback:
|
||
|
# update_transform_texture_from_gui_vars
|
||
|
#
|
||
|
for {set i 0} {$i < [llength $coords]} {incr i} {
|
||
|
|
||
|
set coord [lindex $coords $i]
|
||
|
|
||
|
label $control_rst.${coord}_label \
|
||
|
-text "$coord:" -anchor w
|
||
|
|
||
|
set gui_vars($obj,$control,$coord) \
|
||
|
[lindex [$obj Get$obj_method] $i]
|
||
|
|
||
|
scale $control_rst.${coord}_scale \
|
||
|
-from $scale_from -to $scale_to -resolution $scale_res \
|
||
|
-orient horizontal \
|
||
|
-width $scale_width \
|
||
|
-showvalue false \
|
||
|
-var gui_vars($obj,$control,$coord) \
|
||
|
-command $command
|
||
|
|
||
|
label $control_rst.${coord}_value \
|
||
|
-textvariable gui_vars($obj,$control,$coord)
|
||
|
|
||
|
#
|
||
|
# For "origin", add flip checkbuttons.
|
||
|
# Pack the 3 (or 5) elements into a single row.
|
||
|
#
|
||
|
if {$control == "origin"} {
|
||
|
|
||
|
label $control_rst.${coord}_flip_label \
|
||
|
-text "Flip:" -anchor w
|
||
|
|
||
|
set get_flip "GetFlip[string toupper $coord]"
|
||
|
set gui_vars($obj,$control,${coord}_flip) [$obj $get_flip]
|
||
|
|
||
|
checkbutton $control_rst.${coord}_flip \
|
||
|
-variable gui_vars($obj,$control,${coord}_flip) \
|
||
|
-borderwidth 0 -padx 0 -pady 0 \
|
||
|
-command $command
|
||
|
|
||
|
grid $control_rst.${coord}_label \
|
||
|
$control_rst.${coord}_value \
|
||
|
$control_rst.${coord}_scale \
|
||
|
$control_rst.${coord}_flip_label \
|
||
|
$control_rst.${coord}_flip \
|
||
|
-sticky news
|
||
|
} else {
|
||
|
grid $control_rst.${coord}_label \
|
||
|
$control_rst.${coord}_value \
|
||
|
$control_rst.${coord}_scale \
|
||
|
-sticky news
|
||
|
}
|
||
|
|
||
|
#
|
||
|
# Allow the scale widgets to grow when the GUI is expanded.
|
||
|
#
|
||
|
grid columnconfigure $control_rst 2 -weight 1
|
||
|
}
|
||
|
|
||
|
#
|
||
|
# Pack everything
|
||
|
#
|
||
|
pack $control_frame \
|
||
|
-side top -fill x -expand true -padx 1 -pady 2
|
||
|
|
||
|
pack $control_label \
|
||
|
$control_rst \
|
||
|
-side top -fill x -expand true
|
||
|
}
|
||
|
|
||
|
return $main_frame
|
||
|
}
|
||
|
|
||
|
#
|
||
|
# This callback is used whenever the value of a Tk scale is changed.
|
||
|
# It recovers the gui values from the gui_vars global array, and
|
||
|
# change the corresponding vtkTransformTextureCoords attribute.
|
||
|
# The render window is re-rendered.
|
||
|
#
|
||
|
proc update_transform_texture_from_gui_vars {obj args} {
|
||
|
|
||
|
global gui_vars transform_texture_coords_gui_controls
|
||
|
|
||
|
foreach {control label coords obj_method scale_from scale_to scale_res} \
|
||
|
$transform_texture_coords_gui_controls {
|
||
|
set values [$obj Get$obj_method]
|
||
|
for {set i 0} {$i < [llength $coords]} {incr i} {
|
||
|
set coord [lindex $coords $i]
|
||
|
set values [lreplace $values $i $i $gui_vars($obj,$control,$coord)]
|
||
|
|
||
|
if {$control == "origin"} {
|
||
|
set flip_method "Flip[string toupper $coord]"
|
||
|
$obj Set$flip_method $gui_vars($obj,$control,${coord}_flip)
|
||
|
}
|
||
|
}
|
||
|
eval $obj Set$obj_method $values
|
||
|
}
|
||
|
renWin Render
|
||
|
}
|
||
|
|
||
|
#
|
||
|
# Create the gui and pack it.
|
||
|
#
|
||
|
set gui [create_transform_texture_coords_gui . transform_texture]
|
||
|
|
||
|
pack $gui -side top -anchor s -fill x -expand yes
|
||
|
|
||
|
#
|
||
|
# We set the window manager (wm command) so that it registers a
|
||
|
# command to handle the WM_DELETE_WINDOW protocal request..
|
||
|
#
|
||
|
wm title . "Texture mapper/transform demo"
|
||
|
wm protocol . WM_DELETE_WINDOW ::vtk::cb_exit
|
||
|
|
||
|
#
|
||
|
# You only need this line if you run this script from a Tcl shell
|
||
|
# (tclsh) instead of a Tk shell (wish)
|
||
|
#
|
||
|
tkwait window .
|