ITK/Debug Visualizers for Visual Studio
Visual Studio 2008/2010
Visual studio has support for custom visualization of user types in debugger (watch window and mouse hover).
File C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\Packages\Debugger\autoexp.dat controls how different datatypes are displayed. The file itself contains instructions on how to modify it. Anyone can add custom definitions for their own classes. The file below contains definitions for some of the ITK's classes. The contents of itk_debug_visualizers.dat should be merged into autoexp.dat.
With VS2008 SP1 and newer you don't even have to modify autoexp.dat, you can add environment variable _vcee_autoexp which points to your own file which will then be combined with the system one on the fly by Visual Studio each time debugging session is started (F5 pressed).
Watch window displaying itk::Image using enhanced view:
itk::Image with underlying buffer expanded (limited to first million elements):
I have started building this file, but it only contains support for itk::Image, the classes image contains and basic iterator types. With distributed effort, anyone can contribute a visualizer for a class or two for everyone's benefit.
itk_debug_visualizers.dat
<source lang="lisp">
- InsightToolkit enhanced debugger visualizers for Visual Studio
- I used this
- http://www.virtualdub.org/blog/pivot/entry.php?id=120
- as the main guide. This too
- http://www.filetolink.com/17ad36ef
- using Notepad++ with LISP/Scheme syntax highlight is better than plain text
- Dženan Zukić
[ExecutionControl]
- syntax myfunctionname=NoStepInto
- do not step into any of the SmartPointer's methods
itk::SmartPointer::*=NoStepInto
[Visualizer]
- -----------------------------------Size-----------------------------------
itk::Size<*>{
children ( #( #array( expr : ($c.m_Size)[$i], size : $T1 ) ) )
preview ( #( "[", #array( expr : ($c.m_Size)[$i], size : $T1 ), "]" ) )
}
- -----------------------------------Index-----------------------------------
itk::Index<*>{
children ( #( #array( expr : ($c.m_Index)[$i], size : $T1 ) ) )
preview ( #( "[", #array( expr : ($c.m_Index)[$i], size : $T1 ), "]" ) )
}
- -----------------------------------FixedArray-----------------------------------
itk::FixedArray<double,*>{
children ( #( #array( expr : ($c.m_InternalArray)[$i], size : $T1 ) ) )
preview ( #( "[", #array( expr : ($c.m_InternalArray)[$i], size : $T1 ):[$e,g], "]" ) )
}
itk::FixedArray<*,*>{
children ( #( #array( expr : ($c.m_InternalArray)[$i], size : $T2 ) ) )
preview ( #( "[", #array( expr : ($c.m_InternalArray)[$i], size : $T2 ), "]" ) )
}
- -----------------------------------CovariantVector-----------------------------------
- covariant vector is exactly the same as fixed array, from which it is derived
- because CovariantVector does not introduce any new member variables
- specialization for double
- otherwise there are too many digits displayed in preview
itk::CovariantVector<double,*>{
children ( #( #array( expr : ($c.m_InternalArray)[$i], size : $T1 ) ) )
preview ( #( "[", #array( expr : ($c.m_InternalArray)[$i], size : $T1 ):[$e,g], "]" ) )
}
itk::CovariantVector<*,*>{
children ( #( #array( expr : ($c.m_InternalArray)[$i], size : $T2 ) ) )
preview ( #( "[", #array( expr : ($c.m_InternalArray)[$i], size : $T2 ), "]" ) )
}
- -----------------------------------Point-----------------------------------
- point is exactly the same as fixed array, from which it is derived
- because point does not introduce any new member variables
- specialization for double
- otherwise there are too many digits displayed in preview
itk::Point<double,*>{
children ( #( #array( expr : ($c.m_InternalArray)[$i], size : $T1 ) ) )
preview ( #( "[", #array( expr : ($c.m_InternalArray)[$i], size : $T1 ):[$e,g], "]" ) )
}
itk::Point<*,*>{
children ( #( #array( expr : ($c.m_InternalArray)[$i], size : $T2 ) ) )
preview ( #( "[", #array( expr : ($c.m_InternalArray)[$i], size : $T2 ), "]" ) )
}
- -----------------------------------Vector-----------------------------------
- same as point
itk::Vector<double,*>{
children ( #( #array( expr : ($c.m_InternalArray)[$i], size : $T1 ) ) )
preview ( #( "[", #array( expr : ($c.m_InternalArray)[$i], size : $T1 ):[$e,g], "]" ) )
}
itk::Vector<*,*>{
children ( #( #array( expr : ($c.m_InternalArray)[$i], size : $T2 ) ) )
preview ( #( "[", #array( expr : ($c.m_InternalArray)[$i], size : $T2 ), "]" ) )
}
- -----------------------------------ImportImageContainer-----------------------------------
itk::ImportImageContainer<*,*>{
children ( #( size: $c.m_Size, capacity: $c.m_Capacity, #(uglyAll: [$c,!]), #array( expr : ($c.m_ImportPointer)[$i], size : $c.m_Size ) ) )
preview ( #( "Alloc ", $c.m_Size, " of ", $c.m_Capacity ) )
}
- Note
- ImageRegion and/or ImageBase(Image) have a bugged preview
- I don't know whether this is a bug in VS or my code is wrong
- It does not impair function but it does look ugly
- -----------------------------------ImageRegion-----------------------------------
itk::ImageRegion<*>{
children ( #( size: $c.m_Size, index: $c.m_Index ) )
preview ( #( "R", $c.m_Size ) )
}
- -----------------------------------ImageBase-----------------------------------
itk::ImageBase<*>{
children ( #( size: $c.m_LargestPossibleRegion, origin: $c.m_Origin, spacing: $c.m_Spacing, #(allMembers: [$c,!]) ) )
preview ( #( $c.m_LargestPossibleRegion, "@", $c.m_Origin ) )
}
- -----------------------------------Image-----------------------------------
- derived from ImageBase + m_Buffer
- but it is dependent on one more template parameter
itk::Image<*,*>{
children ( #( size: $c.m_LargestPossibleRegion, origin: $c.m_Origin, spacing: $c.m_Spacing, buffer: $c.m_Buffer, #(allMembers: [$c,!]) ) )
preview ( #( $c.m_LargestPossibleRegion, "@", $c.m_Origin ) )
}
- for iterators, just define preview (which uses default children)
- for this purpose, we can use the same code for all the basic iterators
- -----------------------------------ImageConstIterator-----------------------------------
itk::ImageConstIterator<*>{
preview ( #( " [", $c.m_Offset, "] ", *($c.m_Buffer+$c.m_Offset) ) )
}
- -----------------------------------ImageIterator-----------------------------------
itk::ImageIterator<*>{
preview ( #( " [", $c.m_Offset, "] ", *($c.m_Buffer+$c.m_Offset) ) )
}
- -----------------------------------ImageRegionConstIterator-----------------------------------
itk::ImageRegionConstIterator<*>{
preview ( #( " [", $c.m_Offset, "] ", *($c.m_Buffer+$c.m_Offset) ) )
}
- -----------------------------------ImageRegionIterator-----------------------------------
itk::ImageRegionIterator<*>{
preview ( #( " [", $c.m_Offset, "] ", *($c.m_Buffer+$c.m_Offset) ) )
}
- the below visualizer for smart pointer is a worthless "improvement" over the deafult
- -----------------------------------SmartPointer-----------------------------------
- itk
- :SmartPointer<*>{
- children
- (
- #(
- ptr
- *($c.m_Pointer)
- )
- )
- preview
- (
- #(
- (void *)$c.m_Pointer,
- " ",
- *($c.m_Pointer)
- )
- )
- }
</source>
Visual Studio 2012
Visual Studio 2012 introduces a novel type visualization framework called natvis. A good natvis tutorial is hosted on MSDN. Natvis files are now defined per user and can be put in following folder: %USERPROFILE%/documents/visual studio 2012/visualizers
Support for the new style of debug visualizers is added in this patch.
Image Watch is a Visual Studio add-on which allows developers to display 2D images during debug sessions. In order to integrate support for the display of 2D ITK images, copy this natvis file into the 'visualizers' directory mentioned above.