<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> <meta http-equiv="X-UA-Compatible" content="IE=9"/> <meta name="generator" content="Doxygen 1.9.1"/> <meta name="viewport" content="width=device-width, initial-scale=1"/> <title>DGtal: Display3D: a stream mechanism for displaying 3D DGtal objects</title> <link href="tabs.css" rel="stylesheet" type="text/css"/> <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript" src="dynsections.js"></script> <link href="navtree.css" rel="stylesheet" type="text/css"/> <script type="text/javascript" src="resize.js"></script> <script type="text/javascript" src="navtreedata.js"></script> <script type="text/javascript" src="navtree.js"></script> <link href="search/search.css" rel="stylesheet" type="text/css"/> <script type="text/javascript" src="search/searchdata.js"></script> <script type="text/javascript" src="search/search.js"></script> <script type="text/x-mathjax-config"> MathJax.Hub.Config({ extensions: ["tex2jax.js", "TeX/AMSmath.js", "TeX/AMSsymbols.js"], jax: ["input/TeX","output/HTML-CSS"], }); </script> <script type="text/javascript" async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/MathJax.js?config=TeX-MML-AM_CHTML/MathJax.js"></script> <link href="doxygen.css" rel="stylesheet" type="text/css" /> <link href="doxygen-awesome.css" rel="stylesheet" type="text/css"/> </head> <body> <div id="top"><!-- do not remove this div, it is closed by doxygen! --> <div id="titlearea"> <table cellspacing="0" cellpadding="0"> <tbody> <tr style="height: 56px;"> <td id="projectalign" style="padding-left: 0.5em;"> <div id="projectname">DGtal  <span id="projectnumber">1.4.2</span> </div> </td> </tr> </tbody> </table> </div> <!-- end header part --> <!-- Generated by Doxygen 1.9.1 --> <script type="text/javascript"> /* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */ var searchBox = new SearchBox("searchBox", "search",false,'Search','.html'); /* @license-end */ </script> <script type="text/javascript" src="menudata.js"></script> <script type="text/javascript" src="menu.js"></script> <script type="text/javascript"> /* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */ $(function() { initMenu('',true,false,'search.php','Search'); $(document).ready(function() { init_search(); }); }); /* @license-end */</script> <div id="main-nav"></div> </div><!-- top --> <div id="side-nav" class="ui-resizable side-nav-resizable"> <div id="nav-tree"> <div id="nav-tree-contents"> <div id="nav-sync" class="sync"></div> </div> </div> <div id="splitbar" style="-moz-user-select:none;" class="ui-resizable-handle"> </div> </div> <script type="text/javascript"> /* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */ $(document).ready(function(){initNavTree('moduleDisplay3D.html',''); initResizable(); }); /* @license-end */ </script> <div id="doc-content"> <!-- window showing the filter options --> <div id="MSearchSelectWindow" onmouseover="return searchBox.OnSearchSelectShow()" onmouseout="return searchBox.OnSearchSelectHide()" onkeydown="return searchBox.OnSearchSelectKey(event)"> </div> <!-- iframe showing the search results (closed by default) --> <div id="MSearchResultsWindow"> <iframe src="javascript:void(0)" frameborder="0" name="MSearchResults" id="MSearchResults"> </iframe> </div> <div class="PageDoc"><div class="header"> <div class="headertitle"> <div class="title"><a class="el" href="classDGtal_1_1Display3D.html" title="Aim: This semi abstract class defines the stream mechanism to display 3d primitive (like BallVector,...">Display3D</a>: a stream mechanism for displaying 3D <a class="el" href="namespaceDGtal.html" title="DGtal is the top-level namespace which contains all DGtal functions and types.">DGtal</a> objects </div> </div> </div><!--header--> <div class="contents"> <div class="toc"><h3>Table of Contents</h3> <ul><li class="level1"><a href="#DGtalGLV_Display3D">Display3D: a stream mechanism from abstract class Display3D</a></li> <li class="level1"><a href="#DGtalGLV_Viewer3D">Interactive visualization from Viewer3D</a><ul><li class="level2"><a href="#DGtalGLV_Viewer3D_Rendering">Interactive change of rendering mode <br></a></li> <li class="level2"><a href="#DGtalGLV_Viewer3D_Light">Light source position modes</a></li> <li class="level2"><a href="#DGtalGLV_Viewer3D_Ball">Ball display modes</a></li> </ul> </li> <li class="level1"><a href="#DGtalGLV_Boas3DTo2D">Alternative visualization without QGLViewer dependency</a><ul><li class="level2"><a href="#DGtalGLV_StaticDisplay">Static display</a></li> <li class="level2"><a href="#DGtalGLV_OBJExport">Export objects with Board3D</a></li> </ul> </li> <li class="level1"><a href="#DGtalGLV_VisualizationDigitalSet">Visualization of DigitalSet and digital objects</a></li> <li class="level1"><a href="#DGtalGLV_ModeEx">Mode selection: the example of digital objects in 3D</a></li> <li class="level1"><a href="#DGtalGLV_Mode">Useful modes for several 3D drawable elements</a><ul><li class="level2"><a href="#DGtalGLV_ModeListing">Listing of different modes</a></li> <li class="level2"><a href="#DGtalGLV_ModeExamplesDomain">Examples with Objet modes</a></li> <li class="level2"><a href="#DGtalGLV_ModeOtherExamples">Illustrating KhalimskyCell with the "Illustration" mode</a></li> </ul> </li> <li class="level1"><a href="#DGtalGLV_Custom">Changing the style for displaying drawable elements.</a></li> <li class="level1"><a href="#DGtalGLV_CLipping">Adding clipping planes</a></li> <li class="level1"><a href="#DGtalGLV_Images">Adding 2D image visualization in 3D</a><ul><li class="level2"><a href="#DGtalGLV_ImagesSlices">Adding 2D slice images</a></li> <li class="level2"><a href="#DGtalGLV_ImagesEmbedded">Adding 2D images (from any embedding)</a></li> </ul> </li> <li class="level1"><a href="#DGtalGLV_Images3D">Adding 3D image visualization</a></li> <li class="level1"><a href="#DGtalGLV_Images3Dcustom">Customizing Slice Image visualization</a></li> </ul> </div> <div class="textblock"><p>This part of the manual describes how to visualize 3D objects and how to import them from binary file (.obj or pgm3d)</p> <dl class="section author"><dt>Author</dt><dd>Bertrand Kerautret, Martial Tola, Aline Martin, David Coeurjolly</dd></dl> <h1><a class="anchor" id="DGtalGLV_Display3D"></a> Display3D: a stream mechanism from abstract class Display3D</h1> <p>The semi abstract template class <a class="el" href="classDGtal_1_1Display3D.html" title="Aim: This semi abstract class defines the stream mechanism to display 3d primitive (like BallVector,...">Display3D</a> defines the stream mechanism to display 3d primitive (like <a class="el" href="classDGtal_1_1PointVector.html" title="Aim: Implements basic operations that will be used in Point and Vector classes.">PointVector</a>, <a class="el" href="classDGtal_1_1DigitalSetBySTLSet.html" title="Aim: A container class for storing sets of digital points within some given domain.">DigitalSetBySTLSet</a>, <a class="el" href="classDGtal_1_1Object.html" title="Aim: An object (or digital object) represents a set in some digital space associated with a digital t...">Object</a> ...). The class <a class="el" href="classDGtal_1_1Viewer3D.html">Viewer3D</a>, <a class="el" href="classDGtal_1_1Board3D.html" title="The class Board3D is a type of Display3D which export the figures in the format OBJ/MTL when calling ...">Board3D</a> and <a class="el" href="classDGtal_1_1Board3DTo2D.html" title="Class for PDF, PNG, PS, EPS, SVG export drawings with Cairo with 3D->2D projection.">Board3DTo2D</a> implement two different ways to display 3D objects. The first one (<a class="el" href="classDGtal_1_1Viewer3D.html">Viewer3D</a>), permits an interactive visualization (based on OpenGL). The second (<a class="el" href="classDGtal_1_1Board3D.html" title="The class Board3D is a type of Display3D which export the figures in the format OBJ/MTL when calling ...">Board3D</a>) provides mechanism to export the 3D objects to and Wavefront OBJ format. The last one (<a class="el" href="classDGtal_1_1Board3DTo2D.html" title="Class for PDF, PNG, PS, EPS, SVG export drawings with Cairo with 3D->2D projection.">Board3DTo2D</a>) provides 3D visualization to 2D vector format (using a projection mechanism based on the CAIRO library).</p> <p><a class="el" href="classDGtal_1_1Display3D.html" title="Aim: This semi abstract class defines the stream mechanism to display 3d primitive (like BallVector,...">Display3D</a> have two template parameters which correspond to the digital space and the Khalimsky space used to put the figures. From the Digital Space and Khalimsky Space, we use the associated embedding mechanism to convert digital objects to structures in \( \mathbb{R}^n\).</p> <p><a class="el" href="classDGtal_1_1Viewer3D.html">Viewer3D</a> and <a class="el" href="classDGtal_1_1Board3DTo2D.html" title="Class for PDF, PNG, PS, EPS, SVG export drawings with Cairo with 3D->2D projection.">Board3DTo2D</a> allow to set and change the camera point of view for the visualization.</p> <h1><a class="anchor" id="DGtalGLV_Viewer3D"></a> Interactive visualization from Viewer3D</h1> <p>The class <a class="el" href="classDGtal_1_1Viewer3D.html">Viewer3D</a> inherits from the base class QGLViewer (which is based on QGLwidget). It permits to display simple 3D shapes. LibQGLViewer ( <a href="http://www.libqglviewer.com">http://www.libqglviewer.com</a> ) is a C++ library based on QT allowing to access to simple 3D features like camera moving, mouse, keyboard interaction, clipping plane .... etc.</p> <p>It possess the additional functionality to display 2D slice image from a volume one.</p> <p>First to use the <a class="el" href="classDGtal_1_1Viewer3D.html">Viewer3D</a> stream, you need to include the following headers:</p> <div class="fragment"><div class="line"><span class="preprocessor">#include "DGtal/io/3dViewers/Viewer3D.h"</span></div> </div><!-- fragment --><p>The following code snippet defines three points and a rectangular domain in Z3. It then displays them in a <a class="el" href="classDGtal_1_1Viewer3D.html">Viewer3D</a> object. The full code is in <a href="io_2viewers_2viewer3D-1-points_8cpp-example.html">viewer3D-1-points.cpp</a>.</p> <p>The first step to visualize 3D object with <a class="el" href="classDGtal_1_1Viewer3D.html">Viewer3D</a> is to create a QApplication from the <a class="el" href="testArithmeticDSS-benchmark_8cpp.html#a3c04138a5bfe5d72780bb7e82a18e627">main()</a>: </p><div class="fragment"><div class="line"><span class="keyword">using namespace </span><a class="code" href="namespaceDGtal.html">DGtal</a>;</div> <div class="line"><span class="keyword">using namespace </span>Z3i;</div> <div class="line"> </div> <div class="line">QApplication application(argc,argv);</div> <div class="line">Viewer3D<> viewer;</div> <div class="line">viewer.show();</div> <div class="ttc" id="anamespaceDGtal_html"><div class="ttname"><a href="namespaceDGtal.html">DGtal</a></div><div class="ttdoc">DGtal is the top-level namespace which contains all DGtal functions and types.</div></div> </div><!-- fragment --><p>Then we can display some 3D primitives: </p><div class="fragment"><div class="line"><a class="code" href="testClone2_8cpp.html#a15e9592ccc512dc691b46185e6814758">Point</a> p1( 0, 0, 0 );</div> <div class="line"><a class="code" href="testClone2_8cpp.html#a15e9592ccc512dc691b46185e6814758">Point</a> p2( 5, 5 ,5 );</div> <div class="line"><a class="code" href="testClone2_8cpp.html#a15e9592ccc512dc691b46185e6814758">Point</a> p3( 2, 3, 4 );</div> <div class="line"><a class="code" href="testSimpleRandomAccessRangeFromPoint_8cpp.html#acd532b318489cd93df57e0b3d136d050">Domain</a> <a class="code" href="testProjection_8cpp.html#a1f1a69f8d8b037b72c2160ed12b3ef51">domain</a>( p1, p2 );</div> <div class="line"> </div> <div class="line">viewer << <a class="code" href="testProjection_8cpp.html#a1f1a69f8d8b037b72c2160ed12b3ef51">domain</a>;</div> <div class="line">viewer << p1 << p2 << p3;</div> <div class="line">viewer << Viewer3D<>::updateDisplay;</div> <div class="ttc" id="atestClone2_8cpp_html_a15e9592ccc512dc691b46185e6814758"><div class="ttname"><a href="testClone2_8cpp.html#a15e9592ccc512dc691b46185e6814758">Point</a></div><div class="ttdeci">MyPointD Point</div><div class="ttdef"><b>Definition:</b> <a href="testClone2_8cpp_source.html#l00383">testClone2.cpp:383</a></div></div> <div class="ttc" id="atestProjection_8cpp_html_a1f1a69f8d8b037b72c2160ed12b3ef51"><div class="ttname"><a href="testProjection_8cpp.html#a1f1a69f8d8b037b72c2160ed12b3ef51">domain</a></div><div class="ttdeci">Domain domain</div><div class="ttdef"><b>Definition:</b> <a href="testProjection_8cpp_source.html#l00088">testProjection.cpp:88</a></div></div> <div class="ttc" id="atestSimpleRandomAccessRangeFromPoint_8cpp_html_acd532b318489cd93df57e0b3d136d050"><div class="ttname"><a href="testSimpleRandomAccessRangeFromPoint_8cpp.html#acd532b318489cd93df57e0b3d136d050">Domain</a></div><div class="ttdeci">HyperRectDomain< Space > Domain</div><div class="ttdef"><b>Definition:</b> <a href="testSimpleRandomAccessRangeFromPoint_8cpp_source.html#l00044">testSimpleRandomAccessRangeFromPoint.cpp:44</a></div></div> </div><!-- fragment --><p>You should obtain the following visualization:</p> <div class="image"> <img src="simple3dVisu1.png" alt=""/> <div class="caption"> Digital point visualization with Viewer3D.</div></div> <h2><a class="anchor" id="DGtalGLV_Viewer3D_Rendering"></a> Interactive change of rendering mode <br></h2> <p>By default the rendering mode of the <a class="el" href="classDGtal_1_1Viewer3D.html">Viewer3D</a> is defined by melange of diffuse (Lambertian) and specular parts. The user can swith to the following mode by using the key P :</p> <table class="markdownTable"> <tr class="markdownTableHead"> <th class="markdownTableHeadCenter">type </th><th class="markdownTableHeadCenter">default mixte </th><th class="markdownTableHeadCenter">metallic </th><th class="markdownTableHeadCenter">plastic </th><th class="markdownTableHeadCenter">lambertian </th></tr> <tr class="markdownTableRowOdd"> <td class="markdownTableBodyCenter">mode </td><td class="markdownTableBodyCenter">0 </td><td class="markdownTableBodyCenter">1 </td><td class="markdownTableBodyCenter">2 </td><td class="markdownTableBodyCenter">3 </td></tr> <tr class="markdownTableRowEven"> <td class="markdownTableBodyCenter">Ex: </td><td class="markdownTableBodyCenter"><img src="defaultRenderingViewer3Dmode0.png" alt="" class="inline"/> </td><td class="markdownTableBodyCenter"><img src="metallicRenderingViewer3Dmode1.png" alt="" class="inline"/> </td><td class="markdownTableBodyCenter"><img src="plasticRenderingViewer3Dmode2.png" alt="" class="inline"/> </td><td class="markdownTableBodyCenter"><img src="lambertianRenderingViewer3Dmode3.png" alt="" class="inline"/> </td></tr> </table> <h2><a class="anchor" id="DGtalGLV_Viewer3D_Light"></a> Light source position modes</h2> <p>The light source position is by default defined according to the camera position and its position will not change even after camera moves (default mode). By this way, if you move the camera, the object will be always illuminated (see images of mode 0 of the following tabular). This default light position could be changed interactively by a mouse move in the <a class="el" href="classDGtal_1_1Viewer3D.html">Viewer3D</a> (with the key SHIFT+CTRL (SHIFT+CMD on mac)).</p> <p>There exists a second mode where the light source position will be fixed according the main scene axis. In this case, even if the camera move, the light source will have the same position towards the object of the scene (see for instance images of mode 1 of the following tabular). As for the previous mode, the default light position could be changed interactively by a mouse move in the <a class="el" href="classDGtal_1_1Viewer3D.html">Viewer3D</a> (with the key SHIFT+CTRL (SHIFT+CMD on mac)).</p> <p><b>To change between the two light position mode you can use the Key P in the viewer3D.</b></p> <table class="markdownTable"> <tr class="markdownTableHead"> <th class="markdownTableHeadCenter">Light position mode </th><th class="markdownTableHeadCenter">default position </th><th class="markdownTableHeadCenter">after camera move </th></tr> <tr class="markdownTableRowOdd"> <td class="markdownTableBodyCenter">0 </td><td class="markdownTableBodyCenter"><img src="lightPositionRef.png" alt="" class="inline"/> </td><td class="markdownTableBodyCenter"><img src="lightPositionMode0.png" alt="" class="inline"/> </td></tr> <tr class="markdownTableRowEven"> <td class="markdownTableBodyCenter">1 </td><td class="markdownTableBodyCenter"><img src="lightPositionRef.png" alt="" class="inline"/> </td><td class="markdownTableBodyCenter"><img src="lightPositionMode1.png" alt="" class="inline"/> </td></tr> </table> <dl class="section note"><dt>Note</dt><dd>Note that you can display the camera settings in the console (key C) which can be used in Board2Dto3D described in the following.</dd></dl> <h2><a class="anchor" id="DGtalGLV_Viewer3D_Ball"></a> Ball display modes</h2> <p>The <a class="el" href="classDGtal_1_1Viewer3D.html">Viewer3D</a> class has a special mode to display balls (added from the <a class="el" href="classDGtal_1_1Display3D.html" title="Aim: This semi abstract class defines the stream mechanism to display 3d primitive (like BallVector,...">Display3D</a> method <code>addBall()</code> ). By default, the balls are constructed with OpenGl quadrangulated sphere which can be slow if the number of ball is huge. In the latter case, it is possible to use OpenGL points to increase display performance. To use this mode, you have just to activate it with the method <code>setUseGLPointForBalls()</code> when needed:</p> <div class="fragment"><div class="line">viewer.setUseGLPointForBalls(<span class="keyword">true</span>);</div> <div class="line">viewer.addBall(<a class="code" href="namespaceDGtal_1_1Z3i.html#a5f087066515ecd33cefd7bd080ef8114">Z3i::RealPoint</a>(10.3, 11.3, 4.0);</div> <div class="ttc" id="anamespaceDGtal_1_1Z3i_html_a5f087066515ecd33cefd7bd080ef8114"><div class="ttname"><a href="namespaceDGtal_1_1Z3i.html#a5f087066515ecd33cefd7bd080ef8114">DGtal::Z3i::RealPoint</a></div><div class="ttdeci">Space::RealPoint RealPoint</div><div class="ttdef"><b>Definition:</b> <a href="StdDefs_8h_source.html#l00170">StdDefs.h:170</a></div></div> </div><!-- fragment --><p>By changing the mode you will obtain such display:</p> <table class="markdownTable"> <tr class="markdownTableHead"> <th class="markdownTableHeadCenter">ball display default mode </th><th class="markdownTableHeadCenter">ball display with OpenGL point mode </th></tr> <tr class="markdownTableRowOdd"> <td class="markdownTableBodyCenter"><img src="viewer3DBallDefaultQuads.png" alt="" class="inline"/> </td><td class="markdownTableBodyCenter"><img src="viewer3DBallPtOpenGL.png" alt="" class="inline"/> </td></tr> </table> <p>You can also change the ball display mode interactively by using the key O.</p> <h1><a class="anchor" id="DGtalGLV_Boas3DTo2D"></a> Alternative visualization without QGLViewer dependency</h1> <p>There are two ways to obtain an alternative visualization without the dependency of the 3D interactive viewer:</p><ul> <li>Static display by using Board2Dto3D.</li> <li>Export the 3d objects into 3d files (OBJ format) with <a class="el" href="classDGtal_1_1Board3D.html" title="The class Board3D is a type of Display3D which export the figures in the format OBJ/MTL when calling ...">Board3D</a>.</li> </ul> <h2><a class="anchor" id="DGtalGLV_StaticDisplay"></a> Static display</h2> <p>The same visualization can be obtain with the Board2Dto3D class. You just need to adapt the camera settings (see example <a class="el" href="dgtalBoard3DTo2D-1-points_8cpp_source.html">io/boards/dgtalBoard3DTo2D-1-points.cpp</a>).</p> <div class="fragment"><div class="line"> Board3DTo2D<Space, KSpace> board;</div> <div class="line"> board << <a class="code" href="testProjection_8cpp.html#a1f1a69f8d8b037b72c2160ed12b3ef51">domain</a>; </div> <div class="line"> board << p1 << p2 << p3;</div> <div class="line"> </div> <div class="line"> board << CameraPosition(2.500000, 2.500000, 16.078199)</div> <div class="line"> << CameraDirection(0.000000, 0.000000, -1.000000)</div> <div class="line"> << CameraUpVector(0.000000, 1.000000, 0.000000);</div> <div class="line"> board << CameraZNearFar(4.578200, 22.578199);</div> <div class="line"> </div> <div class="line"> board << SetMode3D(board.className(), <span class="stringliteral">"WireFrameMode"</span>);</div> <div class="line"> board.saveCairo(<span class="stringliteral">"dgtalBoard3DTo2D-1-points.png"</span>, <a class="code" href="classDGtal_1_1Board3DTo2D.html#a9eb212d147ee076abd4de9ab5f30812ba2432560ac427b13c428207dd27b0b41d">Board3DTo2D<Space, KSpace>::CairoPNG</a>, 600*2, 400*2);</div> <div class="ttc" id="aclassDGtal_1_1Board3DTo2D_html_a9eb212d147ee076abd4de9ab5f30812ba2432560ac427b13c428207dd27b0b41d"><div class="ttname"><a href="classDGtal_1_1Board3DTo2D.html#a9eb212d147ee076abd4de9ab5f30812ba2432560ac427b13c428207dd27b0b41d">DGtal::Board3DTo2D::CairoPNG</a></div><div class="ttdeci">@ CairoPNG</div><div class="ttdef"><b>Definition:</b> <a href="Board3DTo2D_8h_source.html#l00082">Board3DTo2D.h:82</a></div></div> </div><!-- fragment --><p> This example should provides a comparable visualization.</p> <h2><a class="anchor" id="DGtalGLV_OBJExport"></a> Export objects with Board3D</h2> <p>To export 3d objects into OBJ format you need simply to use the <a class="el" href="classDGtal_1_1Board3D.html" title="The class Board3D is a type of Display3D which export the figures in the format OBJ/MTL when calling ...">Board3D</a> class which inherits to the <a class="el" href="classDGtal_1_1Display3D.html" title="Aim: This semi abstract class defines the stream mechanism to display 3d primitive (like BallVector,...">Display3D</a> class. You can for instance follow these steps:</p> <div class="fragment"><div class="line"> Board3D<> board;</div> <div class="line"> board << SetMode3D(<a class="code" href="testProjection_8cpp.html#a1f1a69f8d8b037b72c2160ed12b3ef51">domain</a>.className(), <span class="stringliteral">"Paving"</span>);</div> <div class="line"> board << p1 << p2 << p3;</div> <div class="line"> board << shape_set;</div> <div class="line"> board.saveOBJ(<span class="stringliteral">"dgtalBoard3D-1-points.obj"</span>);</div> </div><!-- fragment --><p> And then visualize the resulting obj and mtl file by using for instance blender:</p> <div class="image"> <img src="dgtalBoard3D-1-points.png" alt=""/> <div class="caption"> Visualisation of exported OBJ file with blender.</div></div> <dl class="section user"><dt>Advanced: </dt><dd>By setting a second parameter to true when calling the saveOBJ, the geometrical objects will be scaled so that they fit in a [-1/2, 1/2]^3 domain.</dd></dl> <dl class="section note"><dt>Note</dt><dd>You do not need a <a class="el" href="classDGtal_1_1Board3D.html" title="The class Board3D is a type of Display3D which export the figures in the format OBJ/MTL when calling ...">Board3D</a> to export an OBJ file. There are custom methods to export OBJ files for some classes:<ul> <li><a class="el" href="classDGtal_1_1Mesh.html" title="Aim: This class is defined to represent a surface mesh through a set of vertices and faces....">Mesh</a>: use <a class="el" href="structDGtal_1_1MeshWriter.html#a6b9077bccc94a91299e7eaf55d076028">MeshWriter::export2OBJ</a></li> <li><a class="el" href="classDGtal_1_1TriangulatedSurface.html" title="Aim: Represents a triangulated surface. The topology is stored with a half-edge data structure....">TriangulatedSurface</a>: use <a class="el" href="classDGtal_1_1MeshHelpers.html#a039386aa1c2b460e0a33ff6d15a6f53e">MeshHelpers::exportOBJ</a>, and <a class="el" href="classDGtal_1_1MeshHelpers.html#aa687e35fc678eeed1d39c816c8d43880">MeshHelpers::exportOBJwithFaceNormalAndColor</a></li> <li><a class="el" href="classDGtal_1_1PolygonalSurface.html" title="Aim: Represents a polygon mesh, i.e. a 2-dimensional combinatorial surface whose faces are (topologic...">PolygonalSurface</a>: use <a class="el" href="classDGtal_1_1MeshHelpers.html#a039386aa1c2b460e0a33ff6d15a6f53e">MeshHelpers::exportOBJ</a>, and <a class="el" href="classDGtal_1_1MeshHelpers.html#aa687e35fc678eeed1d39c816c8d43880">MeshHelpers::exportOBJwithFaceNormalAndColor</a></li> <li>you may also use class <a class="el" href="classDGtal_1_1Shortcuts.html">Shortcuts</a>, see <a class="el" href="moduleShortcuts.html">Shortcuts (for the impatient developper)</a></li> </ul> </dd></dl> <h1><a class="anchor" id="DGtalGLV_VisualizationDigitalSet"></a> Visualization of DigitalSet and digital objects</h1> <p>The <a class="el" href="classDGtal_1_1Viewer3D.html">Viewer3D</a> class allows also to display directly a <code>DigitalSet</code>. The first step is to create a <code>DigitalSet</code> for example from the Shape class.</p> <div class="fragment"><div class="line"> QApplication application(argc,argv);</div> <div class="line"> <span class="keyword">typedef</span> Viewer3D<> MyViewer;</div> <div class="line"> MyViewer viewer;</div> <div class="line"> viewer.show();</div> <div class="line"> </div> <div class="line"> <a class="code" href="testClone2_8cpp.html#a15e9592ccc512dc691b46185e6814758">Point</a> p1( 0, 0, 0 );</div> <div class="line"> <a class="code" href="testClone2_8cpp.html#a15e9592ccc512dc691b46185e6814758">Point</a> p2( 10, 10 , 10 );</div> <div class="line"> <a class="code" href="testSimpleRandomAccessRangeFromPoint_8cpp.html#acd532b318489cd93df57e0b3d136d050">Domain</a> <a class="code" href="testProjection_8cpp.html#a1f1a69f8d8b037b72c2160ed12b3ef51">domain</a>( p1, p2 );</div> <div class="line"> viewer << <a class="code" href="testProjection_8cpp.html#a1f1a69f8d8b037b72c2160ed12b3ef51">domain</a>;</div> <div class="line"> </div> <div class="line"> <a class="code" href="testVoronoiMapComplete_8cpp.html#ac14360761d68859fc57ca37aea0b5c93">DigitalSet</a> shape_set( <a class="code" href="testProjection_8cpp.html#a1f1a69f8d8b037b72c2160ed12b3ef51">domain</a> );</div> <div class="line"> <a class="code" href="classDGtal_1_1Shapes.html#a2fffed9fe9a9a460dcd8e2902030e881">Shapes<Domain>::addNorm1Ball</a>( shape_set, <a class="code" href="testClone2_8cpp.html#a15e9592ccc512dc691b46185e6814758">Point</a>( 5, 5, 5 ), 2 );</div> <div class="line"> <a class="code" href="classDGtal_1_1Shapes.html#acde0e74411f8d24da89c93f6df58a84f">Shapes<Domain>::addNorm2Ball</a>( shape_set, <a class="code" href="testClone2_8cpp.html#a15e9592ccc512dc691b46185e6814758">Point</a>( 3, 3, 3 ), 2 );</div> <div class="line"> </div> <div class="line"> shape_set.erase(<a class="code" href="testClone2_8cpp.html#a15e9592ccc512dc691b46185e6814758">Point</a>(3,3,3));</div> <div class="line"> shape_set.erase(<a class="code" href="testClone2_8cpp.html#a15e9592ccc512dc691b46185e6814758">Point</a>(6,6,6));</div> <div class="line"> viewer << shape_set << MyViewer::updateDisplay;</div> <div class="ttc" id="aclassDGtal_1_1Shapes_html_a2fffed9fe9a9a460dcd8e2902030e881"><div class="ttname"><a href="classDGtal_1_1Shapes.html#a2fffed9fe9a9a460dcd8e2902030e881">DGtal::Shapes::addNorm1Ball</a></div><div class="ttdeci">static void addNorm1Ball(TDigitalSet &aSet, const Point &aCenter, UnsignedInteger aRadius)</div></div> <div class="ttc" id="aclassDGtal_1_1Shapes_html_acde0e74411f8d24da89c93f6df58a84f"><div class="ttname"><a href="classDGtal_1_1Shapes.html#acde0e74411f8d24da89c93f6df58a84f">DGtal::Shapes::addNorm2Ball</a></div><div class="ttdeci">static void addNorm2Ball(TDigitalSet &aSet, const Point &aCenter, UnsignedInteger aRadius)</div></div> <div class="ttc" id="atestVoronoiMapComplete_8cpp_html_ac14360761d68859fc57ca37aea0b5c93"><div class="ttname"><a href="testVoronoiMapComplete_8cpp.html#ac14360761d68859fc57ca37aea0b5c93">DigitalSet</a></div><div class="ttdeci">Z2i::DigitalSet DigitalSet</div><div class="ttdef"><b>Definition:</b> <a href="testVoronoiMapComplete_8cpp_source.html#l00040">testVoronoiMapComplete.cpp:40</a></div></div> </div><!-- fragment --><p>You should obtain the following visualization (see example: <a href="io_2viewers_2viewer3D-2-sets_8cpp-example.html">viewer3D-2-sets.cpp </a>):</p> <div class="image"> <img src="simple3dVisu2.png" alt=""/> <div class="caption"> Digital point visualization with Viewer3D.</div></div> <h1><a class="anchor" id="DGtalGLV_ModeEx"></a> Mode selection: the example of digital objects in 3D</h1> <p>As for <a class="el" href="classDGtal_1_1Board2D.html" title="Aim: This class specializes a 'Board' class so as to display DGtal objects more naturally (with <<)....">Board2D</a>, a mode can be choosen to display elements (<code><a class="el" href="structDGtal_1_1SetMode3D.html" title="Modifier class in a Display3D stream. Useful to choose your own mode for a given class....">SetMode3D</a></code>). You just have to specify the classname (the easiest way is to call the method <code>className()</code> on an instance of the correct type and the desired mode (a string).</p> <div class="fragment"><div class="line"><a class="code" href="namespaceDGtal_1_1Z3i.html#a8e4960d296e39e7e624b24d9d70e9ee6">Object6_18</a> shape( dt6_18, shape_set );</div> <div class="line">viewer << SetMode3D( shape.className(), <span class="stringliteral">"DrawAdjacencies"</span> );</div> <div class="line">viewer << shape;</div> <div class="ttc" id="anamespaceDGtal_1_1Z3i_html_a8e4960d296e39e7e624b24d9d70e9ee6"><div class="ttname"><a href="namespaceDGtal_1_1Z3i.html#a8e4960d296e39e7e624b24d9d70e9ee6">DGtal::Z3i::Object6_18</a></div><div class="ttdeci">Object< DT6_18, DigitalSet > Object6_18</div><div class="ttdef"><b>Definition:</b> <a href="StdDefs_8h_source.html#l00174">StdDefs.h:174</a></div></div> </div><!-- fragment --><p>or change the couple of adjacency</p> <div class="fragment"><div class="line"><a class="code" href="namespaceDGtal_1_1Z3i.html#ad3c59f1acd81dabcd6bda393aa940480">Object18_6</a> shape2( dt18_6, shape_set );</div> <div class="line">viewer << SetMode3D( shape2.className(), <span class="stringliteral">"DrawAdjacencies"</span> );</div> <div class="line">viewer << shape2;</div> <div class="ttc" id="anamespaceDGtal_1_1Z3i_html_ad3c59f1acd81dabcd6bda393aa940480"><div class="ttname"><a href="namespaceDGtal_1_1Z3i.html#ad3c59f1acd81dabcd6bda393aa940480">DGtal::Z3i::Object18_6</a></div><div class="ttdeci">Object< DT18_6, DigitalSet > Object18_6</div><div class="ttdef"><b>Definition:</b> <a href="StdDefs_8h_source.html#l00178">StdDefs.h:178</a></div></div> </div><!-- fragment --><p>You should obtain the two following visualizations (see example: <a href="io_2viewers_2viewer3D-3-objects_8cpp-example.html">viewer3D-3-objects.cpp </a>):</p> <div class="image"> <img src="visu6-18Adj.png" alt=""/> <div class="caption"> 6-18 digital Adjacencies visualization with Viewer3D.</div></div> <div class="image"> <img src="visu18-6Adj.png" alt=""/> <div class="caption"> 18-6 digital Adjacencies visualization with Viewer3D.</div></div> <p>Note that digital set was displayed with transparency by setting a custom colors.</p> <h1><a class="anchor" id="DGtalGLV_Mode"></a> Useful modes for several 3D drawable elements</h1> <h2><a class="anchor" id="DGtalGLV_ModeListing"></a> Listing of different modes</h2> <p>As for <code><a class="el" href="classDGtal_1_1Board2D.html" title="Aim: This class specializes a 'Board' class so as to display DGtal objects more naturally (with <<)....">Board2D</a></code> the object can be displayed with different possible mode:</p> <ul> <li>class <a class="el" href="classDGtal_1_1PointVector.html" title="Aim: Implements basic operations that will be used in Point and Vector classes.">PointVector</a>, modes: "" / "Both", "Paving" (default), "Grid"</li> <li>class <a class="el" href="classDGtal_1_1DigitalSetBySTLSet.html" title="Aim: A container class for storing sets of digital points within some given domain.">DigitalSetBySTLSet</a> and <a class="el" href="classDGtal_1_1DigitalSetBySTLVector.html" title="Aim: Realizes the concept CDigitalSet by using the STL container std::vector.">DigitalSetBySTLVector</a> : "", "" / "Both", "Paving" (default), "PavingTransp", "Grid".</li> <li>class <a class="el" href="classDGtal_1_1Object.html" title="Aim: An object (or digital object) represents a set in some digital space associated with a digital t...">Object</a>, modes: "" /"Basic" (default), "DrawAdjacencies", "PavingTransp".</li> <li>class <a class="el" href="classDGtal_1_1HyperRectDomain.html" title="Aim: Parallelepidec region of a digital space, model of a 'CDomain'.">HyperRectDomain</a> 3D, modes: "" / "Grid" (default), "Paving", "PavingPoints", "PavingGrids", "BoundingBox".</li> <li>class <a class="el" href="classDGtal_1_1HyperRectDomain.html" title="Aim: Parallelepidec region of a digital space, model of a 'CDomain'.">HyperRectDomain</a> 2D, modes: "" / "BoundingBox" (default), "Grid", "InterGrid" **.</li> <li>class <a class="el" href="structDGtal_1_1KhalimskyCell.html" title="Represents an (unsigned) cell in a cellular grid space by its Khalimsky coordinates.">KhalimskyCell</a> , modes: ""(default) / "Highlighted" , "Transparent", "Basic", "Illustration", "IllustrationCustomColor".</li> <li>class <a class="el" href="structDGtal_1_1SignedKhalimskyCell.html" title="Represents a signed cell in a cellular grid space by its Khalimsky coordinates and a boolean value.">SignedKhalimskyCell</a> , modes: "" (default) / "Highlighted" , "Basic", "Transparent", "Illustration", "IllustrationCustomColor".</li> <li>class <a class="el" href="classDGtal_1_1StandardDSS6Computer.html" title="Aim: Dynamic recognition of a 3d-digital straight segment (DSS)">StandardDSS6Computer</a> , modes: "" (default) / "Points", "BoundingBox *".</li> <li>class <a class="el" href="classDGtal_1_1Mesh.html" title="Aim: This class is defined to represent a surface mesh through a set of vertices and faces....">Mesh</a>, modes: "" (default) / "Faces *".</li> <li>class <a class="el" href="classDGtal_1_1ImageContainerBySTLVector.html">ImageContainerBySTLVector</a>, <a class="el" href="classDGtal_1_1ImageContainerBySTLMap.html">ImageContainerBySTLMap</a> 2D/3D modes: "", (default), "BoundingBox", "Grid", "InterGrid" . **</li> <li>class <a class="el" href="classDGtal_1_1ImageAdapter.html" title="Aim: implements an image adapter with a given domain (i.e. a subdomain) and 3 functors : g for domain...">ImageAdapter</a>, <a class="el" href="classDGtal_1_1ConstImageAdapter.html" title="Aim: implements a const image adapter with a given domain (i.e. a subdomain) and 2 functors : g for d...">ConstImageAdapter</a> 2D/3D modes: "", (default), "BoundingBox", "Grid", "InterGrid" . **</li> </ul> <p>Note that for <a class="el" href="structDGtal_1_1KhalimskyCell.html" title="Represents an (unsigned) cell in a cellular grid space by its Khalimsky coordinates.">KhalimskyCell</a> and <a class="el" href="structDGtal_1_1SignedKhalimskyCell.html" title="Represents a signed cell in a cellular grid space by its Khalimsky coordinates and a boolean value.">SignedKhalimskyCell</a> the default colors (with <a class="el" href="structDGtal_1_1CustomColors3D.html">CustomColors3D</a> objects) can be changed only with the empty mode ("") and the "IllustrationCustomColor" mode.</p> <p>"*": partially for (<a class="el" href="classDGtal_1_1Board3DTo2D.html" title="Class for PDF, PNG, PS, EPS, SVG export drawings with Cairo with 3D->2D projection.">Board3DTo2D</a>), see issue <a href="https://github.com/DGtal-team/DGtal/issues/582">582</a>. "**": only for <a class="el" href="classDGtal_1_1Viewer3D.html">Viewer3D</a>.</p> <h2><a class="anchor" id="DGtalGLV_ModeExamplesDomain"></a> Examples with Objet modes</h2> <p>The file <a href="io_2viewers_2viewer3D-4-modes_8cpp-example.html">viewer3D-4-modes.cpp </a> illustrates several possible modes to display these objects:</p> <p>We can display the set of point and the domain</p> <div class="fragment"><div class="line"><a class="code" href="testClone2_8cpp.html#a15e9592ccc512dc691b46185e6814758">Point</a> p1( -1, -1, -2 );</div> <div class="line"><a class="code" href="testClone2_8cpp.html#a15e9592ccc512dc691b46185e6814758">Point</a> p2( 2, 2, 3 );</div> <div class="line"><a class="code" href="testSimpleRandomAccessRangeFromPoint_8cpp.html#acd532b318489cd93df57e0b3d136d050">Domain</a> <a class="code" href="testProjection_8cpp.html#a1f1a69f8d8b037b72c2160ed12b3ef51">domain</a>( p1, p2 );</div> <div class="line"><a class="code" href="testClone2_8cpp.html#a15e9592ccc512dc691b46185e6814758">Point</a> p3( 1, 1, 1 );</div> <div class="line"><a class="code" href="testClone2_8cpp.html#a15e9592ccc512dc691b46185e6814758">Point</a> p4( 2, -1, 3 );</div> <div class="line"><a class="code" href="testClone2_8cpp.html#a15e9592ccc512dc691b46185e6814758">Point</a> p5( -1, 2, 3 );</div> <div class="line"><a class="code" href="testClone2_8cpp.html#a15e9592ccc512dc691b46185e6814758">Point</a> p6( 0, 0, 0 );</div> <div class="line"><a class="code" href="testClone2_8cpp.html#a15e9592ccc512dc691b46185e6814758">Point</a> p0( 0, 2, 1 );</div> </div><!-- fragment --><p>without mode change (see image (a)): </p><div class="fragment"><div class="line">viewer << p1 << p2 << p3<< p4<< p5 << p6 << p0;</div> <div class="line">viewer << <a class="code" href="testProjection_8cpp.html#a1f1a69f8d8b037b72c2160ed12b3ef51">domain</a>;</div> </div><!-- fragment --><p>We can change the mode for displaying the domain (see image (b)): </p><div class="fragment"><div class="line">viewer << p1 << p2 << p3<< p4<< p5 << p6 << p0;</div> <div class="line">viewer << SetMode3D(<a class="code" href="testProjection_8cpp.html#a1f1a69f8d8b037b72c2160ed12b3ef51">domain</a>.className(), <span class="stringliteral">"PavingGrids"</span>);</div> <div class="line">viewer << <a class="code" href="testProjection_8cpp.html#a1f1a69f8d8b037b72c2160ed12b3ef51">domain</a>;</div> </div><!-- fragment --><p> (Note that to avoid transparency displaying artifacts, we need to display the domain after the voxel elements included in the domain) <br /> </p> <p>It is also possible to change the mode for displaying the voxels: (see image (c)) </p><div class="fragment"><div class="line">viewer << <a class="code" href="testProjection_8cpp.html#a1f1a69f8d8b037b72c2160ed12b3ef51">domain</a>;</div> <div class="line">viewer << SetMode3D( p1.className(), <span class="stringliteral">"Grid"</span> );</div> <div class="line">viewer << p1 << p2 << p3<< p4<< p5 << p6 << p0;</div> </div><!-- fragment --><p>we obtain the following visualizations:</p> <div class="image"> <img src="visuModeDefault.png" alt=""/> <div class="caption"> (a) Default visualization of a digital point sets with the associated domain </div></div> <div class="image"> <img src="visuModePavingGridsDomain.png" alt=""/> <div class="caption"> (b) visualization using Paving mode for the domain.</div></div> <div class="image"> <img src="visuModeGridVoxel.png" alt=""/> <div class="caption"> (c) visualization using Paving mode for the voxels.</div></div> <h2><a class="anchor" id="DGtalGLV_ModeOtherExamples"></a> Illustrating KhalimskyCell with the "Illustration" mode</h2> <p>The "Illustration" mode is defined to construct illustrations composed of <a class="el" href="structDGtal_1_1KhalimskyCell.html" title="Represents an (unsigned) cell in a cellular grid space by its Khalimsky coordinates.">KhalimskyCell</a>. In particular it permits to increase the space between cells and improve the display visibility. It can be used typically as follows: First you need to add the following header:</p> <div class="fragment"><div class="line"><span class="preprocessor">#include "DGtal/io/DrawWithDisplay3DModifier.h"</span></div> </div><!-- fragment --><p>From a <a class="el" href="structDGtal_1_1SignedKhalimskyCell.html" title="Represents a signed cell in a cellular grid space by its Khalimsky coordinates and a boolean value.">SignedKhalimskyCell</a> (SCell in <a class="el" href="namespaceDGtal_1_1Z3i.html" title="Z3i this namespace gathers the standard of types for 3D imagery.">DGtal::Z3i</a>) you have to select the "Illustration" mode :</p> <div class="fragment"><div class="line"> <a class="code" href="digitalPolyhedronBuilder3D_8cpp.html#a6c4dc4f5610ba8c9b7ee6e83ecea8d24">SCell</a> v = <a class="code" href="testCubicalComplex_8cpp.html#a2b87ed989d2519d025bd5d4fbcbac062">K</a>.sSpel( <a class="code" href="testClone2_8cpp.html#a15e9592ccc512dc691b46185e6814758">Point</a>( 0, 0, 0 ), KSpace::POS ); <span class="comment">// +v</span></div> <div class="line"> viewer << SetMode3D( v.className(), <span class="stringliteral">"Illustration"</span> );</div> <div class="ttc" id="adigitalPolyhedronBuilder3D_8cpp_html_a6c4dc4f5610ba8c9b7ee6e83ecea8d24"><div class="ttname"><a href="digitalPolyhedronBuilder3D_8cpp.html#a6c4dc4f5610ba8c9b7ee6e83ecea8d24">SCell</a></div><div class="ttdeci">Z3i::SCell SCell</div><div class="ttdef"><b>Definition:</b> <a href="digitalPolyhedronBuilder3D_8cpp_source.html#l00079">digitalPolyhedronBuilder3D.cpp:79</a></div></div> <div class="ttc" id="atestCubicalComplex_8cpp_html_a2b87ed989d2519d025bd5d4fbcbac062"><div class="ttname"><a href="testCubicalComplex_8cpp.html#a2b87ed989d2519d025bd5d4fbcbac062">K</a></div><div class="ttdeci">KSpace K</div><div class="ttdef"><b>Definition:</b> <a href="testCubicalComplex_8cpp_source.html#l00062">testCubicalComplex.cpp:62</a></div></div> </div><!-- fragment --><p> Then, to display a surfel with its associated voxel, you need to transform the surfel by constructing a shifted and resized version (DGtal::TransformedKSSurfel) according to its associated voxel:</p> <div class="fragment"><div class="line"> <a class="code" href="digitalPolyhedronBuilder3D_8cpp.html#a6c4dc4f5610ba8c9b7ee6e83ecea8d24">SCell</a> sx = <a class="code" href="testCubicalComplex_8cpp.html#a2b87ed989d2519d025bd5d4fbcbac062">K</a>.sIncident( v, 0, <span class="keyword">true</span> ); <span class="comment">// surfel further along x</span></div> <div class="line"> <a class="code" href="structDGtal_1_1TransformedPrism.html">DGtal::TransformedPrism</a> tsx (sx, v);</div> <div class="ttc" id="astructDGtal_1_1TransformedPrism_html"><div class="ttname"><a href="structDGtal_1_1TransformedPrism.html">DGtal::TransformedPrism</a></div><div class="ttdoc">class to modify the position and scale to construct better illustration mode.</div><div class="ttdef"><b>Definition:</b> <a href="DrawWithDisplay3DModifier_8h_source.html#l00179">DrawWithDisplay3DModifier.h:180</a></div></div> </div><!-- fragment --><p>You will obtain such type of illustration (obtained from the example <a href="io_2viewers_2viewer3D-4bis-illustrationMode_8cpp-example.html">viewer3D-4bis-illustrationMode.cpp </a>).</p> <div class="image"> <img src="view3D-4bis-illustrationMode.png" alt=""/> <div class="caption"> Illustration of the "Illustration" KhalimskyCell mode.</div></div> <dl class="section user"><dt>Advanced: </dt><dd>There exists a specific method to display surfels (Khalimsky cells of dimension 2 in a space of dimension 3) as quadrilaterals where the user can prescribe a unitary normal vector. In <a class="el" href="classDGtal_1_1Viewer3D.html">Viewer3D</a>, the normal vector is used in the rendering process (useful to check the geometrical consistency of a normal vector field). Basic usage is:</dd></dl> <div class="fragment"><div class="line"><a class="code" href="structDGtal_1_1Display3DFactory.html#a91610f69591b1fa96e22732ad45cebdc">Display3DFactory<Space,KSpace>::drawOrientedSurfelWithNormal</a>( aViewer, aSurfel, theSurfelSign, aNormalVector);</div> <div class="ttc" id="astructDGtal_1_1Display3DFactory_html_a91610f69591b1fa96e22732ad45cebdc"><div class="ttname"><a href="structDGtal_1_1Display3DFactory.html#a91610f69591b1fa96e22732ad45cebdc">DGtal::Display3DFactory::drawOrientedSurfelWithNormal</a></div><div class="ttdeci">static void drawOrientedSurfelWithNormal(Display &display, const typename KSpace::SCell &aSignedCell, const RealVector &aNormal, const bool enableDoubleFace=false)</div></div> </div><!-- fragment --><p> or if the surfel is not oriented (unsigned khalimsky cell). </p><div class="fragment"><div class="line"><a class="code" href="structDGtal_1_1Display3DFactory.html#ad1b8288c63af35db95c5c5805eb28a93">Display3DFactory<Space,KSpace>::drawUnorientedSurfelWithNormal</a>( aViewer, aSurfel, aNormalVector);</div> <div class="ttc" id="astructDGtal_1_1Display3DFactory_html_ad1b8288c63af35db95c5c5805eb28a93"><div class="ttname"><a href="structDGtal_1_1Display3DFactory.html#ad1b8288c63af35db95c5c5805eb28a93">DGtal::Display3DFactory::drawUnorientedSurfelWithNormal</a></div><div class="ttdeci">static void drawUnorientedSurfelWithNormal(Display &display, const typename KSpace::Cell &anObject, const RealVector &aNormal, const bool enableDoubleFace=false)</div></div> </div><!-- fragment --><p>In the later case, the quadrilateral vertices are oriented such that the dot product between the normal vector and the quad canonical normal vector is positive. Finally, these two methods accept a last boolean parameter such that if true, the quad is geometrically duplicated with opposite normal vector (double-quad rendering).</p> <h1><a class="anchor" id="DGtalGLV_Custom"></a> Changing the style for displaying drawable elements.</h1> <p>As for <a class="el" href="classDGtal_1_1Board2D.html" title="Aim: This class specializes a 'Board' class so as to display DGtal objects more naturally (with <<)....">Board2D</a>, it is possible to custom the way to display 3D elements by using an instance of the following classes:</p> <ul> <li><a class="el" href="structDGtal_1_1CustomColors3D.html">CustomColors3D</a>: to change the color used to display surface primitive (GL_QUADS) and the pen color (LINE/POINTS) ;</li> </ul> <p>The custom color can be applied by an instance of the <a class="el" href="structDGtal_1_1CustomColors3D.html">CustomColors3D</a> as follow:</p> <div class="fragment"><div class="line">viewer << CustomColors3D(Color(250, 0,0),Color(250, 0,0));</div> <div class="line">viewer << p4 << p5 ;</div> </div><!-- fragment --><p>The example <a href="io_2viewers_2viewer3D-5-custom_8cpp-example.html">viewer3D-5-custom.cpp </a> illustrates some possible customs :</p> <div class="image"> <img src="visuModeCustom.png" alt="" width="5cm"/> <div class="caption"> Example of several custom display .</div></div> <h1><a class="anchor" id="DGtalGLV_CLipping"></a> Adding clipping planes</h1> <p>It also possible through the stream mechanism to add clipping plane with the object <code><a class="el" href="structDGtal_1_1ClippingPlane.html" title="Class for adding a Clipping plane through the Viewer3D stream. Realizes the concept CDrawableWithView...">ClippingPlane</a></code>. We just have to add the real plane equation and adding as for displaying an element. The file <a href="io_2viewers_2viewer3D-6-clipping_8cpp-example.html">viewer3D-6-clipping.cpp</a> gives a simple example.</p> <p>From displaying a digital set defined from a Norm2 ball, </p><div class="fragment"><div class="line"><a class="code" href="testClone2_8cpp.html#a15e9592ccc512dc691b46185e6814758">Point</a> p1( 0, 0, 0 );</div> <div class="line"><a class="code" href="testClone2_8cpp.html#a15e9592ccc512dc691b46185e6814758">Point</a> p2( 20, 20, 20 );</div> <div class="line"><a class="code" href="testSimpleRandomAccessRangeFromPoint_8cpp.html#acd532b318489cd93df57e0b3d136d050">Domain</a> <a class="code" href="testProjection_8cpp.html#a1f1a69f8d8b037b72c2160ed12b3ef51">domain</a>(p1, p2);</div> <div class="line"><a class="code" href="testVoronoiMapComplete_8cpp.html#ac14360761d68859fc57ca37aea0b5c93">DigitalSet</a> shape_set( <a class="code" href="testProjection_8cpp.html#a1f1a69f8d8b037b72c2160ed12b3ef51">domain</a> );</div> <div class="line"> </div> <div class="line"><a class="code" href="classDGtal_1_1Shapes.html#acde0e74411f8d24da89c93f6df58a84f">Shapes<Domain>::addNorm2Ball</a>( shape_set, <a class="code" href="testClone2_8cpp.html#a15e9592ccc512dc691b46185e6814758">Point</a>( 10, 10, 10 ), 7 );</div> <div class="line"> </div> <div class="line">viewer << SetMode3D( shape_set.className(), <span class="stringliteral">"Both"</span> );</div> <div class="line">viewer << shape_set;</div> <div class="line">viewer << CustomColors3D(Color(250, 200,0, 100),Color(250, 200,0, 20));</div> <div class="line">viewer << SetMode3D( p1.className(), <span class="stringliteral">"Paving"</span> );</div> </div><!-- fragment --><p>we can add for instance two differents clipping planes:</p> <div class="fragment"><div class="line">viewer << ClippingPlane(1,0,0,-4.9);</div> <div class="line">viewer << ClippingPlane(0,1,0.3,-10);</div> </div><!-- fragment --><div class="image"> <img src="visuClippingAll.png" alt="" width="5cm"/> <div class="caption"> (a) visualization of the initial set.</div></div> <div class="image"> <img src="visuClipping1.png" alt=""/> <div class="caption"> (b) visualization after adding the first clipping plane (0,1,0.3,-10).</div></div> <div class="image"> <img src="visuClipping2.png" alt=""/> <div class="caption"> (c) visualization after adding a second clipping plane (1,0,0,-4.9) .</div></div> <p>It also possible to remove the visualization of the transparent clipping plane by adding boolean option:</p> <div class="fragment"><div class="line">viewer << ClippingPlane(0,1,0.3,-10, <span class="keyword">false</span>);</div> </div><!-- fragment --><h1><a class="anchor" id="DGtalGLV_Images"></a> Adding 2D image visualization in 3D</h1> <h2><a class="anchor" id="DGtalGLV_ImagesSlices"></a> Adding 2D slice images</h2> <p>With the <a class="el" href="classDGtal_1_1Viewer3D.html">Viewer3D</a> class it is possible to display 2D slice image from a volume one. It can be done in few steps (see example of <a class="el" href="viewer3D-8-2DSliceImages_8cpp.html">io/viewers/viewer3D-8-2DSliceImages.cpp</a>) :</p> <div class="fragment"><div class="line"> <span class="comment">// Extracting the 2D images from the 3D one and from a given dimension.</span></div> <div class="line"> <span class="comment">// First image the teenth Z slice (dim=2)</span></div> <div class="line"> <span class="keyword">typedef</span> <a class="code" href="classDGtal_1_1ConstImageAdapter.html">DGtal::ConstImageAdapter<Image3D, DGtal::Z2i::Domain, DGtal::functors::Projector< DGtal::Z3i::Space></a>,</div> <div class="line"> <a class="code" href="testSimpleRandomAccessRangeFromPoint_8cpp.html#a566a00621638570a4186414035153a2e">Image3D::Value</a>, <a class="code" href="structDGtal_1_1functors_1_1Identity.html">DGtal::functors::Identity</a> > MySliceImageAdapter;</div> <div class="line"> </div> <div class="line"> <span class="comment">// Define the functor to recover a 2D domain from the 3D one in the Z direction (2):</span></div> <div class="line"> <a class="code" href="structDGtal_1_1functors_1_1Projector.html">DGtal::functors::Projector<DGtal::Z2i::Space></a> transTo2DdomainFunctorZ; transTo2DdomainFunctorZ.<a class="code" href="structDGtal_1_1functors_1_1Projector.html#a3c89c19e382da62a4cd43e15d57ae8b8">initRemoveOneDim</a>(2);</div> <div class="line"> <a class="code" href="classDGtal_1_1HyperRectDomain.html">DGtal::Z2i::Domain</a> domain2DZ(transTo2DdomainFunctorZ(imageVol.domain().lowerBound()),</div> <div class="line"> transTo2DdomainFunctorZ(imageVol.domain().upperBound()));</div> <div class="line"> </div> <div class="line"> <span class="comment">// Define the functor to associate 2D coordinates to the 3D one by giving the direction Z (2) and the slide numnber (10):</span></div> <div class="line"> <a class="code" href="structDGtal_1_1functors_1_1Projector.html">DGtal::functors::Projector<DGtal::Z3i::Space></a> aSliceFunctorZ(10); aSliceFunctorZ.initAddOneDim(2);</div> <div class="line"> </div> <div class="line"> <span class="comment">// We can now obtain the slice image (a ConstImageAdapter):</span></div> <div class="line"> <span class="keyword">const</span> <span class="keyword">auto</span> identityFunctor = <a class="code" href="structDGtal_1_1functors_1_1Identity.html">DGtal::functors::Identity</a>();</div> <div class="line"> MySliceImageAdapter aSliceImageZ(imageVol, domain2DZ, aSliceFunctorZ, identityFunctor );</div> <div class="line"> </div> <div class="line"> <span class="comment">// Second image the fiftieth Y slice (dim=1)</span></div> <div class="line"> <span class="comment">// Define the functor to recover a 2D domain from the 3D one in the Y direction (1):</span></div> <div class="line"> <a class="code" href="structDGtal_1_1functors_1_1Projector.html">DGtal::functors::Projector<DGtal::Z2i::Space></a> transTo2DdomainFunctorY; transTo2DdomainFunctorY.<a class="code" href="structDGtal_1_1functors_1_1Projector.html#a3c89c19e382da62a4cd43e15d57ae8b8">initRemoveOneDim</a>(1);</div> <div class="line"> <a class="code" href="classDGtal_1_1HyperRectDomain.html">DGtal::Z2i::Domain</a> domain2DY(transTo2DdomainFunctorY(imageVol.domain().lowerBound()),</div> <div class="line"> transTo2DdomainFunctorY(imageVol.domain().upperBound()));</div> <div class="line"> </div> <div class="line"> <span class="comment">// Define the functor to associate 2D coordinates to the 3D one by giving the direction Y (1) and the slide numnber (50):</span></div> <div class="line"> <a class="code" href="structDGtal_1_1functors_1_1Projector.html">DGtal::functors::Projector<DGtal::Z3i::Space></a> aSliceFunctorY(50); aSliceFunctorY.initAddOneDim(1);</div> <div class="line"> </div> <div class="line"> <span class="comment">// We can now obtain the slice image (a ConstImageAdapter):</span></div> <div class="line"> MySliceImageAdapter aSliceImageY(imageVol, domain2DY, aSliceFunctorY, identityFunctor );</div> <div class="ttc" id="aclassDGtal_1_1ConstImageAdapter_html"><div class="ttname"><a href="classDGtal_1_1ConstImageAdapter.html">DGtal::ConstImageAdapter</a></div><div class="ttdoc">Aim: implements a const image adapter with a given domain (i.e. a subdomain) and 2 functors : g for d...</div><div class="ttdef"><b>Definition:</b> <a href="ConstImageAdapter_8h_source.html#l00105">ConstImageAdapter.h:106</a></div></div> <div class="ttc" id="aclassDGtal_1_1HyperRectDomain_html"><div class="ttname"><a href="classDGtal_1_1HyperRectDomain.html">DGtal::HyperRectDomain< Space ></a></div></div> <div class="ttc" id="astructDGtal_1_1functors_1_1Identity_html"><div class="ttname"><a href="structDGtal_1_1functors_1_1Identity.html">DGtal::functors::Identity</a></div><div class="ttdoc">Aim: Define a simple default functor that just returns its argument.</div><div class="ttdef"><b>Definition:</b> <a href="BasicFunctors_8h_source.html#l00287">BasicFunctors.h:288</a></div></div> <div class="ttc" id="astructDGtal_1_1functors_1_1Projector_html"><div class="ttname"><a href="structDGtal_1_1functors_1_1Projector.html">DGtal::functors::Projector</a></div><div class="ttdoc">Aim: Functor that maps a point P of dimension i to a point Q of dimension j. The member myDims is an ...</div><div class="ttdef"><b>Definition:</b> <a href="BasicPointFunctors_8h_source.html#l00106">BasicPointFunctors.h:107</a></div></div> <div class="ttc" id="astructDGtal_1_1functors_1_1Projector_html_a3c89c19e382da62a4cd43e15d57ae8b8"><div class="ttname"><a href="structDGtal_1_1functors_1_1Projector.html#a3c89c19e382da62a4cd43e15d57ae8b8">DGtal::functors::Projector::initRemoveOneDim</a></div><div class="ttdeci">void initRemoveOneDim(const Dimension &dimRemoved)</div></div> <div class="ttc" id="atestSimpleRandomAccessRangeFromPoint_8cpp_html_a566a00621638570a4186414035153a2e"><div class="ttname"><a href="testSimpleRandomAccessRangeFromPoint_8cpp.html#a566a00621638570a4186414035153a2e">Value</a></div><div class="ttdeci">double Value</div><div class="ttdef"><b>Definition:</b> <a href="testSimpleRandomAccessRangeFromPoint_8cpp_source.html#l00041">testSimpleRandomAccessRangeFromPoint.cpp:38</a></div></div> </div><!-- fragment --><p> And the display them using the classic stream operator:</p> <div class="fragment"><div class="line"> viewer << aSliceImageZ;</div> <div class="line"> viewer << aSliceImageY;</div> </div><!-- fragment --><p> Finally you can adjust the image setting with the Display3DModifier <a class="el" href="structDGtal_1_1UpdateImagePosition.html" title="class to modify the position and orientation of an textured 2D image.">UpdateImagePosition</a> and <a class="el" href="structDGtal_1_1UpdateImageData.html" title="class to modify the data of an given image and also the possibility to translate it (optional).">UpdateImageData</a> object:</p> <div class="fragment"><div class="line"> viewer << DGtal::UpdateImagePosition<Z3i::Space, Z3i::KSpace>(1, MyViewer::yDirection, 0.0, 50.0, 0.0);</div> <div class="line"> viewer << DGtal::UpdateImageData<MySliceImageAdapter>(0, aSliceImageZ, 0, 0, 10);</div> <div class="line"> viewer << MyViewer::updateDisplay;</div> </div><!-- fragment --><p> You will obtain such a visualization: </p><div class="image"> <img src="viewer3D-8.png" alt="" width="5cm"/> <div class="caption"> Illustration of the 2D image slice visualization.</div></div> <p>You can also change the default mode by using: </p><div class="fragment"><div class="line"> viewer << SetMode3D(aSliceImageZ.className(), <span class="stringliteral">"BoundingBox"</span>);</div> <div class="line"> viewer << MyViewer::updateDisplay;</div> </div><!-- fragment --><p>and by changing the "BoundingBox" mode by "InterGrid" you will obtain the following visualization: </p><div class="image"> <img src="viewer3D-8InterGrid.png" alt="" width="5cm"/> <div class="caption"> Illustration of the 2D image slice visualization with InterGrid mode.</div></div> <p>See more details on this example <a class="el" href="viewer3D-8-2DSliceImages_8cpp.html">io/viewers/viewer3D-8-2DSliceImages.cpp</a> or from the DGtalTools repository with DGtalTools/visualization/3dImageViewer.cpp viewer.</p> <h2><a class="anchor" id="DGtalGLV_ImagesEmbedded"></a> Adding 2D images (from any embedding)</h2> <p>The slice images are not the only way to display 2D images in 3D. A 2D image can also be extracted and embedded in 3D by using a single embedding functor (Point2DEmbedderIn3D). The example <a class="el" href="viewer3D-8bis-2Dimages_8cpp.html">io/viewers/viewer3D-8bis-2Dimages.cpp</a> illustrates such a display.</p> <p>First we need to add the header file associated with the Point2DEmbedderIn3D: </p><div class="fragment"><div class="line"><span class="preprocessor">#include "DGtal/kernel/BasicPointFunctors.h"</span></div> </div><!-- fragment --><p> Then, the type definition of <a class="el" href="classDGtal_1_1ConstImageAdapter.html" title="Aim: implements a const image adapter with a given domain (i.e. a subdomain) and 2 functors : g for d...">ConstImageAdapter</a> is added: </p><div class="fragment"><div class="line"> <span class="keyword">typedef</span> <a class="code" href="classDGtal_1_1ConstImageAdapter.html">DGtal::ConstImageAdapter<Image3D, Z2i::Domain, DGtal::functors::Point2DEmbedderIn3D<DGtal::Z3i::Domain></a>,</div> <div class="line"> <a class="code" href="testSimpleRandomAccessRangeFromPoint_8cpp.html#a566a00621638570a4186414035153a2e">Image3D::Value</a>, <a class="code" href="structDGtal_1_1functors_1_1Identity.html">DGtal::functors::Identity</a> > ImageAdapterExtractor;</div> <div class="line"> </div> </div><!-- fragment --><p> The resulting 2D domain can be deduced from the width used in the functor: </p><div class="fragment"><div class="line"> <a class="code" href="classDGtal_1_1PointVector.html">DGtal::Z3i::Point</a> ptCenter(50, 62, 28);</div> <div class="line"> <span class="keyword">const</span> <span class="keywordtype">int</span> <a class="code" href="extract2DImagesFrom3D_8cpp.html#a696c5af853a544a9392523cb586f394e">IMAGE_PATCH_WIDTH</a> = 20;</div> <div class="line"> <span class="comment">// Setting the image domain of the resulting image to be displayed in 3D:</span></div> <div class="line"> <a class="code" href="classDGtal_1_1HyperRectDomain.html">DGtal::Z2i::Domain</a> domainImage2D (<a class="code" href="classDGtal_1_1PointVector.html">DGtal::Z2i::Point</a>(0,0),</div> <div class="line"> <a class="code" href="classDGtal_1_1PointVector.html">DGtal::Z2i::Point</a>(<a class="code" href="extract2DImagesFrom3D_8cpp.html#a696c5af853a544a9392523cb586f394e">IMAGE_PATCH_WIDTH</a>, <a class="code" href="extract2DImagesFrom3D_8cpp.html#a696c5af853a544a9392523cb586f394e">IMAGE_PATCH_WIDTH</a>));</div> <div class="ttc" id="aclassDGtal_1_1PointVector_html"><div class="ttname"><a href="classDGtal_1_1PointVector.html">DGtal::PointVector< dim, Integer ></a></div></div> <div class="ttc" id="aextract2DImagesFrom3D_8cpp_html_a696c5af853a544a9392523cb586f394e"><div class="ttname"><a href="extract2DImagesFrom3D_8cpp.html#a696c5af853a544a9392523cb586f394e">IMAGE_PATCH_WIDTH</a></div><div class="ttdeci">const int IMAGE_PATCH_WIDTH</div><div class="ttdef"><b>Definition:</b> <a href="extract2DImagesFrom3D_8cpp_source.html#l00059">extract2DImagesFrom3D.cpp:59</a></div></div> </div><!-- fragment --><p> The embedder then be used to extract the image: </p><div class="fragment"><div class="line"> <span class="comment">// Extracting images from 3D embeder</span></div> <div class="line"> <a class="code" href="classDGtal_1_1functors_1_1Point2DEmbedderIn3D.html">DGtal::functors::Point2DEmbedderIn3D<DGtal::Z3i::Domain ></a> embedder(imageVol.domain(),</div> <div class="line"> ptCenter+<a class="code" href="classDGtal_1_1PointVector.html">DGtal::Z3i::Point</a>(<span class="keyword">static_cast<</span><span class="keywordtype">int</span><span class="keyword">></span>(200.0*cos(alpha)),<span class="keyword">static_cast<</span><span class="keywordtype">int</span><span class="keyword">></span>(100.0*sin(alpha))),</div> <div class="line"> <a class="code" href="classDGtal_1_1PointVector.html">DGtal::Z3i::RealPoint</a>(cos(alpha),sin(alpha),cos(2.0*alpha)),</div> <div class="line"> <a class="code" href="extract2DImagesFrom3D_8cpp.html#a696c5af853a544a9392523cb586f394e">IMAGE_PATCH_WIDTH</a>);</div> <div class="line"> ImageAdapterExtractor extractedImage(imageVol, domainImage2D, embedder, idV);</div> <div class="ttc" id="aclassDGtal_1_1functors_1_1Point2DEmbedderIn3D_html"><div class="ttname"><a href="classDGtal_1_1functors_1_1Point2DEmbedderIn3D.html">DGtal::functors::Point2DEmbedderIn3D</a></div><div class="ttdoc">Aim: Functor that embeds a 2D point into a 3D space from two axis vectors and an origin point given i...</div><div class="ttdef"><b>Definition:</b> <a href="BasicPointFunctors_8h_source.html#l00372">BasicPointFunctors.h:373</a></div></div> </div><!-- fragment --><p> and used to display the image with the correct coordinates:</p> <div class="fragment"><div class="line"> <span class="comment">//Display image and update its position with embeder</span></div> <div class="line"> viewer << extractedImage;</div> <div class="line"> viewer << DGtal::UpdateImage3DEmbedding<Z3i::Space, Z3i::KSpace>(pos,</div> <div class="line"> embedder(<a class="code" href="namespaceDGtal_1_1Z2i.html#a858b8746eb7dc0280c8e12b37e56d9e3">Z2i::RealPoint</a>(0,0)),</div> <div class="line"> embedder(<a class="code" href="namespaceDGtal_1_1Z2i.html#a858b8746eb7dc0280c8e12b37e56d9e3">Z2i::RealPoint</a>(<a class="code" href="extract2DImagesFrom3D_8cpp.html#a696c5af853a544a9392523cb586f394e">IMAGE_PATCH_WIDTH</a>,0)),</div> <div class="line"> embedder(domainImage2D.upperBound()),</div> <div class="line"> embedder(<a class="code" href="namespaceDGtal_1_1Z2i.html#a858b8746eb7dc0280c8e12b37e56d9e3">Z2i::RealPoint</a>(0, <a class="code" href="extract2DImagesFrom3D_8cpp.html#a696c5af853a544a9392523cb586f394e">IMAGE_PATCH_WIDTH</a>)));</div> <div class="ttc" id="anamespaceDGtal_1_1Z2i_html_a858b8746eb7dc0280c8e12b37e56d9e3"><div class="ttname"><a href="namespaceDGtal_1_1Z2i.html#a858b8746eb7dc0280c8e12b37e56d9e3">DGtal::Z2i::RealPoint</a></div><div class="ttdeci">Space::RealPoint RealPoint</div><div class="ttdef"><b>Definition:</b> <a href="StdDefs_8h_source.html#l00097">StdDefs.h:97</a></div></div> </div><!-- fragment --><p>This example will produce such a visualization: </p><div class="image"> <img src="viewer3D-8bis.png" alt="" width="5cm"/> <div class="caption"> Illustration of the 2D image visualization.</div></div> <h1><a class="anchor" id="DGtalGLV_Images3D"></a> Adding 3D image visualization</h1> <p>In the same way a 3D image can be displayed. By following the same stream operator you will obtain such example of display: </p><div class="image"> <img src="viewer3D-9.png" alt="" width="5cm"/> <div class="caption"> Example of 3D image visualization with also digital sets.</div></div> <p>See more details in the example: <a class="el" href="viewer3D-9-3Dimages_8cpp.html">io/viewers/viewer3D-9-3Dimages.cpp</a></p> <h1><a class="anchor" id="DGtalGLV_Images3Dcustom"></a> Customizing Slice Image visualization</h1> <p>By default an image is displayed in gray scale levels from its scalar values. However it is possible to display color texture image by using the object <a class="el" href="structDGtal_1_1AddTextureImage2DWithFunctor.html" title="class to insert a custom 2D textured image by using a conversion functor and allows to change the def...">AddTextureImage2DWithFunctor</a> or <a class="el" href="structDGtal_1_1AddTextureImage3DWithFunctor.html" title="class to insert a custom 3D textured image by using a conversion functor and allows to change the def...">AddTextureImage3DWithFunctor</a> (of the <a class="el" href="structDGtal_1_1DrawWithDisplay3DModifier.html" title="Base class specifying the methods for classes which intend to modify a Viewer3D stream.">DrawWithDisplay3DModifier</a> class) with the RGBmode which allows to interpret the scalar as a color value. A color functor can also be specified to generate a given color.</p> <p>For instance the previous examples can easily displayed with color map:</p> <p>First we generate a color functor to generate unsigned integer interpreted as RGB color:</p><ul> <li>Adding the header to use hueShadeMap: <div class="fragment"><div class="line"><span class="preprocessor">#include "DGtal/io/DrawWithDisplay3DModifier.h"</span></div> <div class="line"><span class="preprocessor">#include "DGtal/io/viewers/DrawWithViewer3DModifier.h"</span></div> <div class="line"><span class="preprocessor">#include "DGtal/io/colormaps/HueShadeColorMap.h"</span></div> <div class="line"><span class="preprocessor">#include "DGtal/io/Color.h"</span></div> </div><!-- fragment --> with a functor to transform integer representing grayscale to integer representing color: <div class="fragment"><div class="line"><span class="keyword">struct </span>hueFct{</div> <div class="line"> <span class="keyword">inline</span></div> <div class="line"> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> operator() (<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> aVal)<span class="keyword"> const</span></div> <div class="line"><span class="keyword"> </span>{</div> <div class="line"> HueShadeColorMap<unsigned char> hueShade(0,255);</div> <div class="line"> Color col = hueShade((<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span>)aVal);</div> <div class="line"> <span class="keywordflow">return</span> (((<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>) col.red()) << 16)| (((<span class="keywordtype">unsigned</span> int) col.green()) << 8)|((<span class="keywordtype">unsigned</span> int) col.blue());</div> <div class="line"> }</div> <div class="line">};</div> </div><!-- fragment --></li> <li>Instead to use directly the image and the stream operator we add the <a class="el" href="structDGtal_1_1AddTextureImage2DWithFunctor.html" title="class to insert a custom 2D textured image by using a conversion functor and allows to change the def...">AddTextureImage2DWithFunctor</a> object: <div class="fragment"><div class="line"> viewer << AddTextureImage2DWithFunctor<MySliceImageAdapter, hueFct, Z3i::Space, Z3i::KSpace> (aSliceImageZ, hueFct(), <a class="code" href="classDGtal_1_1Viewer3D.html#a542350413b6cfa5ffae5cd6b21a81750a46bef3089f6f95256dddc1b38f56cc4b">Viewer3D<Z3i::Space, Z3i::KSpace>::RGBMode</a>);</div> <div class="line"> viewer << AddTextureImage2DWithFunctor<MySliceImageAdapter, hueFct, Z3i::Space, Z3i::KSpace> (aSliceImageY, hueFct(), <a class="code" href="classDGtal_1_1Viewer3D.html#a542350413b6cfa5ffae5cd6b21a81750a46bef3089f6f95256dddc1b38f56cc4b">Viewer3D<Z3i::Space, Z3i::KSpace>::RGBMode</a>);</div> <div class="ttc" id="aclassDGtal_1_1Viewer3D_html_a542350413b6cfa5ffae5cd6b21a81750a46bef3089f6f95256dddc1b38f56cc4b"><div class="ttname"><a href="classDGtal_1_1Viewer3D.html#a542350413b6cfa5ffae5cd6b21a81750a46bef3089f6f95256dddc1b38f56cc4b">DGtal::Viewer3D::RGBMode</a></div><div class="ttdeci">@ RGBMode</div><div class="ttdef"><b>Definition:</b> <a href="Viewer3D_8h_source.html#l00472">Viewer3D.h:472</a></div></div> </div><!-- fragment --></li> <li>Note that also can update the image position image data as in the previous example and we need to recall the functor function if we want to keep the same data interpretation : <div class="fragment"><div class="line"> viewer << DGtal::UpdateImagePosition<Z3i::Space, Z3i::KSpace>(3, MyViewer::yDirection, 500.0, 50.0, 0.0);</div> <div class="line"> viewer << DGtal::UpdateImageData<MySliceImageAdapter, hueFct>(2, aSliceImageZ, 500, 0, 10, 0.0, MyViewer::zDirection, hueFct());</div> <div class="line"> viewer << MyViewer::updateDisplay;</div> </div><!-- fragment --> You will obtain such a visualization: <div class="image"> <img src="viewer3D-8Color.png" alt="" width="5cm"/> <div class="caption"> Illustration of the 2D image slice visualization.</div></div> </li> </ul> </div></div><!-- contents --> </div><!-- PageDoc --> </div><!-- doc-content --> <!-- start footer part --> <div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> <ul> <li class="navelem"><a class="el" href="index.html">DGtal - Digital Geometry Tools and Algorithms Library.</a></li><li class="navelem"><a class="el" href="packageIO.html">IO package</a></li> <li class="footer">Generated on Mon Dec 23 2024 13:18:58 for DGtal by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li> </ul> </div> </body> </html>