<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
</head>
<body dir="ltr">
<div id="divtagdefaultwrapper" style="font-size:12pt;color:#000000;font-family:Calibri,Helvetica,sans-serif;" dir="ltr">
<p style="margin-top:0;margin-bottom:0"></p>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
Hi David,</div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
<br>
</div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
thanks again for your help.</div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
<br>
</div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
I added the method calls on the normalFilter as you have suggested but it didn't change the wrong voxelization of the Eiffel tower model. </div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
<br>
</div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
It did indead change the result to something different:</div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
<br>
</div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
<img size="54477" contenttype="image/png" id="291332_rs|3" style="user-select: none; height: 227.045px; width: 222px;" tabindex="0" width="222" height="227" data-outlook-trace="F:1|T:1" src="cid:ea753225-8561-4c0f-a7b0-2bb764dff664">    <img size="88782" contenttype="image/jpeg" id="368039_rs|3" style="user-select: none; width: 283px; height: 287.834px;" tabindex="0" data-outlook-trace="F:1|T:1" src="cid:a3cf6ebe-b37d-42ec-b0aa-fc502c405607"> 
             <img size="37648" contenttype="image/jpeg" id="385240_rs|3" style="user-select: none; height: 262.703px; width: 162px;" tabindex="0" data-outlook-trace="F:1|T:1" src="cid:4439e9e1-f381-4580-8b22-005d383ff492"><br>
<br>
 </div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
<div style="font-size: 16px; caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
<b>left image:      result with wrong orientation and without <span style="font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;">normalsFilter->AutoOrientNormalsOn()</span></b></div>
<div style="font-size: 16px; caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
<b>center image: mesh with wrong orientation and <span style="font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;">normalsFilter->AutoOrientNormalsOn()</span></b></div>
<div style="font-size: 16px; caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
<b><span style="font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;"></span>right image:   meshlab corrected version</b></div>
<br>
</div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
<br>
</div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
I attached both Eiffel tower models (with the wrong normals / polygon orientation and the corrected meshlab version) if you want to try it yourself.</div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
<br>
</div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
The vtkStripper is indead unecessary. I tried various meshes with and without using the vtkStripper filter step inbetween and it didn't make any difference. Since i took it from the Slicer3D source code Csaba pointed me to, i don't have any idea why the Slicer
 Guys use it there. Maybe they have some special kind of polydata where it is needed. For my general purpose meshes it does not seem to make a difference. The processing is, of course, faster without this additional step.</div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
<br>
</div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
The complete source code for voxelization and visualization and the CMakeList.txt is attached. </div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
<br>
</div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
<br>
</div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
The resulting code for the voxelization function:</div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
<br>
</div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>bool ConvertPolyDataToBinaryLabelMap(vtkSmartPointer<vtkPolyData> closedSurfacePolyData, </b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>                                     vtkSmartPointer<vtkImageData> binaryLabelMap)</b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>{</b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  <span style="color: rgb(0, 111, 201);">
<i>// Check for consistency</i></span></b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  if (closedSurfacePolyData->GetNumberOfPoints() < 2 || closedSurfacePolyData->GetNumberOfCells() < 2)</b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  {</b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>    std::cout <<
<span style="color: rgb(75, 165, 36);">"Convert: Cannot create binary labelmap from surface with number of points: "</span></b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>        << closedSurfacePolyData->GetNumberOfPoints() <<
<span style="color: rgb(75, 165, 36);">" and number of cells: "</span> </b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>        << closedSurfacePolyData->GetNumberOfCells() << std::endl;</b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>      </b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>      return false;</b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  }</b></span></div>
<div><b><br>
</b></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b><i><span style="color: rgb(0, 111, 201);">  // Compute polydata normals</span></i></b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b><span style="color: rgb(0, 111, 201);"><i>  //</i></span></b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b><span style="color: rgb(0, 111, 201);"><i>  // The purpose of the vtkPolyDataNormals filter here is to enforce a</i></span></b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b><span style="color: rgb(0, 111, 201);"><i>  // consistent orientation of the polygons (via the method ConsistencyOn)</i></span></b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b><span style="color: rgb(0, 111, 201);"><i>  // and to get an automatic determination of the correct orientation of the</i></span></b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b><span style="color: rgb(0, 111, 201);"><i>  // normals on the polydata surface (via the method AutoOrientNormalsOn).</i></span></b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b><span style="color: rgb(0, 111, 201);"><i>  //</i></span></b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b><span style="color: rgb(0, 111, 201);"><i>  // To increase the performance of the filter we turn off the splitting of </i></span></b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b><span style="color: rgb(0, 111, 201);"><i>  // sharp edges (via the method SplittingOff) since it is not necessary for</i></span></b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b><span style="color: rgb(0, 111, 201);"><i>  // getting a correct result here.</i></span></b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b><span style="color: rgb(0, 111, 201);"><i>  //</i></span></b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b><span style="color: rgb(0, 111, 201);"><i>  // The application of the filter on the polydata is purely optional if all </i></span></b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b><span style="color: rgb(0, 111, 201);"><i>  // the polygons are already correctly oriented.</i></span></b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  vtkNew<vtkPolyDataNormals> normalFilter;</b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  normalFilter->SetInputData(closedSurfacePolyData);</b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  normalFilter->ConsistencyOn();</b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  normalFilter->AutoOrientNormalsOn(); </b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  normalFilter->SplittingOff();</b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  </b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b><i><span style="color: rgb(0, 111, 201);">  // Make sure that we have a clean triangle polydata using the </span></i></b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b><span style="color: rgb(0, 111, 201);"><i>  // vtkTriangleFilter which generates triangles from input polygons.</i></span></b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b><i><span style="color: rgb(0, 111, 201);">  // Only needed if the input polygons are not flat.</span> </i></b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  vtkNew<vtkTriangleFilter> triangle;</b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  triangle->SetInputConnection(normalFilter->GetOutputPort());</b></span></div>
<div><b><br>
</b></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  <span style="color: rgb(0, 111, 201);">
<i>// Convert polydata to stencil</i></span></b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  vtkNew<vtkPolyDataToImageStencil> polyDataToImageStencil;</b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  polyDataToImageStencil->SetInputConnection(triangle->GetOutputPort());</b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  polyDataToImageStencil->SetOutputSpacing(binaryLabelMap->GetSpacing());</b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  polyDataToImageStencil->SetOutputOrigin(binaryLabelMap->GetOrigin());</b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  polyDataToImageStencil->SetOutputWholeExtent(binaryLabelMap->GetExtent());</b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  polyDataToImageStencil->Update();</b></span></div>
<div><b><br>
</b></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  <i>
<span style="color: rgb(0, 111, 201);">// Convert stencil to image</span></i></b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  vtkNew<vtkImageStencilToImage> imageStencilToImage;</b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  imageStencilToImage->SetInputConnection(polyDataToImageStencil->GetOutputPort());</b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  imageStencilToImage->SetOutsideValue(0);</b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  imageStencilToImage->SetInsideValue(1);</b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  imageStencilToImage->SetOutput(binaryLabelMap);</b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  imageStencilToImage->Update();</b></span></div>
<div><b><br>
</b></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>  return true;</b></span></div>
<div><span style="font-family: "Courier New", monospace; font-size: 9pt;"><b>}</b></span></div>
<div><br>
</div>
<br>
</div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
Thanks again for everything.</div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
<br>
</div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
Cheers,</div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
<br>
</div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
Berti</div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
<br>
</div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
<br>
</div>
<div style="caret-color: rgb(0, 0, 0); font-family: -webkit-standard; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.4);">
<br>
</div>
<br>
<p></p>
<br>
<br>
<div style="color: rgb(0, 0, 0);">
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>Von:</b> David Gobbi <david.gobbi@gmail.com><br>
<b>Gesendet:</b> Dienstag, 25. September 2018 10:20<br>
<b>An:</b> Berti Krüger<br>
<b>Cc:</b> Csaba Pinter; VTK Users; Bill Lorensen<br>
<b>Betreff:</b> Re: [vtkusers] Solid Voxelization with VTK</font>
<div> </div>
</div>
<meta content="text/html; charset=utf-8">
<div>
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">Hi Berti,
<div><br>
</div>
<div>Just a few extra comments about the three "preprocessing" steps that you apply in your sample code:</div>
<div><br>
</div>
<div>For vtkPolyDataNormals, you might want to add  normalsFilter->AutoOrientNormalsOn(), since this option is specifically designed to fix inside-out shapes like the Eiffel tower model.  And normalsFilter->SplittingOff() will make this filter work faster. 
 It would also be good if the comment mentioned that the purpose of the filter is to enforce consistent orientation of the polygons, and that the filter is optional if all the polygons are already correctly oriented.</div>
<div><br>
</div>
<div>The vtkStripper should be removed, unless you actually saw that it provides some benefit.  The vtkPolyDataToImageStencil class should give exactly the same results for triangles as for strips.  And vtkTriangleFilter is only needed if the input polygons
 are not flat.</div>
<div><br>
</div>
<div>Thanks again for the code,</div>
<div> - David</div>
<div><br>
</div>
<div><br>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>