<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>CAD Culture &#187; Uncategorised</title>
	<atom:link href="http://www.cadculture.com/category/uncategorised/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cadculture.com</link>
	<description>Learn something new</description>
	<lastBuildDate>Tue, 21 Nov 2017 05:53:54 +0000</lastBuildDate>
	<language>en-AU</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.2.38</generator>
	<item>
		<title>3D Data Visualization with Open Source Tools: A Tutorial Using VTK</title>
		<link>http://www.cadculture.com/3d-data-visualization-with-open-source-tools-a-tutorial-using-vtk/</link>
		<comments>http://www.cadculture.com/3d-data-visualization-with-open-source-tools-a-tutorial-using-vtk/#comments</comments>
		<pubDate>Tue, 03 May 2016 09:15:25 +0000</pubDate>
		<dc:creator><![CDATA[Cad Culture]]></dc:creator>
				<category><![CDATA[Uncategorised]]></category>

		<guid isPermaLink="false">http://www.cadculture.com/?p=862</guid>
		<description><![CDATA[<p>In this tutorial I will give a quick introduction to VTK and its pipeline architecture, and go on to discuss a real-life 3D visualization example using data from a simulated fluid in an impeller pump. Finally I’ll list the strong points of the library, as well as the weak spots I encountered.</p>
<p>The post <a rel="nofollow" href="http://www.cadculture.com/3d-data-visualization-with-open-source-tools-a-tutorial-using-vtk/">3D Data Visualization with Open Source Tools: A Tutorial Using VTK</a> appeared first on <a rel="nofollow" href="http://www.cadculture.com">CAD Culture</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>In his recent article on Toptal’s blog, skilled data scientist Charles Cook wrote about <a href="https://www.toptal.com/scientific-computing/scientific-computing-with-open-source-tools">scientific computing with open source tools</a>. His tutorial makes an important point about open source tools and the role they can play in easily processing data and acquiring results.</p>
<p>But as soon as we’ve solved all these complex differential equations another problems comes up. How do we understand and interpret the huge amounts of data coming out of these simulations? How do we visualize potential gigabytes of data, such as data with millions of grid points within a large simulation?</p>
<p><a href="http://www.cadculture.com/wp-content/uploads/2016/05/data-visualisation.png"><img src="http://www.cadculture.com/wp-content/uploads/2016/05/data-visualisation.png" alt="data visualisation" width="620" height="620" class="alignnone size-full wp-image-863" /></a></p>
<p>During my work on similar problems for my <a href="http://benjaminhopfer.com/2014/04/10/masters-thesis-technical/">Master’s Thesis</a>, I came into contact with the Visualization Toolkit, or VTK &#8211; a powerful graphics library specialized for data visualization.</p>
<p>In this tutorial I will give a quick introduction to VTK and its pipeline architecture, and go on to discuss a real-life 3D visualization example using data from a simulated fluid in an impeller pump. Finally I’ll list the strong points of the library, as well as the weak spots I encountered.</p>
<h2>Data Visualization and The VTK Pipeline</h2>
<p>The open source library <a href="http://www.vtk.org/">VTK</a> contains a solid processing and rendering pipeline with many sophisticated visualization algorithms. It’s capabilities, however, don’t stop there, as over time image and mesh processing algorithms have been added as well. In my current project with a dental research company, I’m utilizing VTK for mesh based processing tasks within a <a href="http://www.qt-project.org/">Qt-based</a>, CAD-like application. The <a href="http://www.vtk.org/VTK/project/casestudies.html">VTK case studies</a> show the wide range of suitable applications.</p>
<p>The architecture of VTK revolves around a powerful pipeline concept. The basic outline of this concept is shown here:</p>
<p><a href="http://www.cadculture.com/wp-content/uploads/2016/05/vtk-visualisation-pipeline.png"><img src="http://www.cadculture.com/wp-content/uploads/2016/05/vtk-visualisation-pipeline.png" alt="vtk visualisation pipeline" width="620" height="680" class="alignnone size-full wp-image-864" /></a></p>
<ul>
<li><strong>Sources</strong> are at the very beginning of the pipeline and create “something out of nothing”. For example, a vtkConeSource creates a 3D cone, and a vtkSTLReader reads *.stl 3D geometry files.</li>
<li><strong>Filters</strong> transform the output of either sources or other filters to something new. For example a vtkCutter cuts the output of the previous object in the algorithms using an implicit function, e.g., a plane. All the processing algrithms that come with VTK are implemented as filters and can be freely chained together.</li>
<li><strong>Mappers</strong> transform data into graphics primitives. For example, they can be used to specify a look-up table for coloring scientific data. They are an abstract way to specify what to display.</li>
<li><strong>Actors</strong> represent an object (geometry plus display properties) within the scene. Things like color, opacity, shading, or orientation are specified here.</li>
<li><strong>Renderers &#038; Windows</strong> finally describe the rendering onto the screen in a platform-independent way.</li>
</ul>
<p>A typical VTK rendering pipeline starts with one or more sources, processes them using various filters into several output objects, which are then rendered separately using mappers and actors. The power behind this concept is the update mechanism. If settings of filters or sources are changed, all dependent filters, mappers, actors and render windows are automatically updated. If, on the other hand, an object further down the pipeline needs information in order to perform its tasks, it can easily obtain it.</p>
<p>In addition, there is no need to deal with rendering systems like OpenGL directly. VTK encapsulates all the low level task in a platform- and (partially) rendering system-independent way; the developer works on a much higher level.</p>
<h2>Code Example with a Rotor Pump Dataset</h2>
<p>Let’s look at a data visualization example using <a href="http://sciviscontest.ieeevis.org/2011/dataset/dataset.html">this dataset of fluid flow in a rotating impeller pump</a> from the IEEE Visualization Contest 2011. The data itself is the result of a computational fluid dynamics simulation, much like the one described in Charles Cook’s article.</p>
<p>The zipped simulation data of the featured pump is over 30 GB in size. It contains multiple parts and multiple time steps, hence the large size. In this guide, we’ll play around with the rotor part of one of these timesteps, which has a compressed size of about 150 MB.</p>
<p>My language of choice for using VTK is C++, but there are mappings for several other languages like Tcl/Tk, Java, and Python. If the target is just the visualization of a single data-set, one doesn’t need to write code at all and can instead utilize <a href="http://www.paraview.org/">Paraview</a>, a graphical front-end for most of VTK’s functionality.</p>
<h2>The Dataset and Why 64-bit is Necessary</h2>
<p>I extracted the rotor dataset from the 30 GB dataset provided above, by opening one timestep in Paraview and extracting the rotor part into a separate file. It is an unstructured grid file, i.e., a 3D volume consisting of points and 3D cells, like hexahedra, tetrahedra, and so on. Each of the 3D points has associated values. Sometimes the cells have associated values as well, but not in this case. This training will concentrate on pressure and velocity at the points and try to visualize these in their 3D context.</p>
<p>The compressed file size is about 150 MB and the in-memory size is about 280 MB when loaded with VTK. However, by processing it in VTK, the dataset is cached multiple times within the VTK pipeline and we quickly reach the 2 GB memory limit for 32bit programs. There are ways to save memory when using VTK, but to keep it simple we’ll just compile and run the example in 64bit.</p>
<p><strong>Acknowledgements</strong>: The dataset is made available courtesy of the Institute of Applied Mechanics, Clausthal University, Germany (Dipl. Wirtsch.-Ing. Andreas Lucius).</p>
<h2>The Target</h2>
<p>What we will achieve using VTK as a tool is the visualization shown in the image below. As a 3D context the outline of the dataset is shown using a partially transparent wireframe rendering. The left part of the dataset is then used to display the pressure using simple color coding of the surfaces. (We’ll skip the more complex volume rendering for this example). In order to visualize the velocity field, the right part of the dataset is filled with <a href="https://en.wikipedia.org/wiki/Streamlines,_streaklines,_and_pathlines">streamlines</a>, which are color-coded by the magnitude of their velocity. This visualization choice is technically not ideal, but I wanted to keep the VTK code as simple as possible. In addition, there is a reason for this example to be part of a visualization challenge, i.e., lots of turbulence in the flow.</p>
<p><a href="http://www.cadculture.com/wp-content/uploads/2016/05/visualisation-toolkit.png"><img src="http://www.cadculture.com/wp-content/uploads/2016/05/visualisation-toolkit.png" alt="Visualisation Toolkit" width="700" height="761" class="alignnone size-full wp-image-865" /></a></p>
<h2>Step by Step</h2>
<p>I will discuss the VTK code step by step, showing how the rendering output would look at each stage. The full source code can be downloaded at the end of the training.</p>
<p>Let’s starts by including everything we need from VTK and open the main function.</p>
<p>#include <vtkActor.h><br />
#include <vtkArrayCalculator.h><br />
#include <vtkCamera.h><br />
#include <vtkClipDataSet.h><br />
#include <vtkCutter.h><br />
#include <vtkDataSetMapper.h><br />
#include <vtkInteractorStyleTrackballCamera.h><br />
#include <vtkLookupTable.h><br />
#include <vtkNew.h><br />
#include <vtkPlane.h><br />
#include <vtkPointData.h><br />
#include <vtkPointSource.h><br />
#include <vtkPolyDataMapper.h><br />
#include <vtkProperty.h><br />
#include <vtkRenderer.h><br />
#include <vtkRenderWindow.h><br />
#include <vtkRenderWindowInteractor.h><br />
#include <vtkRibbonFilter.h><br />
#include <vtkStreamTracer.h><br />
#include <vtkSmartPointer.h><br />
#include <vtkUnstructuredGrid.h><br />
#include <vtkXMLUnstructuredGridReader.h></p>
<p>int main(int argc, char** argv)<br />
{</p>
<p>Next, we setup the renderer and the render window in order to display our results. We set the background color and the render window size.</p>
<p> // Setup the renderer<br />
  vtkNew<vtkRenderer> renderer;<br />
  renderer->SetBackground(0.9, 0.9, 0.9);</p>
<p>  // Setup the render window<br />
  vtkNew<vtkRenderWindow> renWin;<br />
  renWin->AddRenderer(renderer.Get());<br />
  renWin->SetSize(500, 500);</p>
<p>With this code we could already display a static render window. Instead, we opt to add a vtkRenderWindowInteractor in order to interactively rotate, zoom and pan the scene.</p>
<p>// Setup the render window interactor<br />
  vtkNew<vtkRenderWindowInteractor> interact;<br />
  vtkNew<vtkInteractorStyleTrackballCamera> style;<br />
  interact->SetRenderWindow(renWin.Get());<br />
  interact->SetInteractorStyle(style.Get());</p>
<p>Now we have a running example showing a gray, empty render window.</p>
<p>Next, we load the dataset using one of the many readers that come with VTK.</p>
<p>// Read the file<br />
  vtkSmartPointer<vtkXMLUnstructuredGridReader> pumpReader = vtkSmartPointer<vtkXMLUnstructuredGridReader>::New();<br />
  pumpReader->SetFileName(&#8220;rotor.vtu&#8221;);</p>
<p><strong>Short excursion into VTK memory management:</strong> VTK uses a convenient automatic memory management concept revolving around reference counting. Different from most other implementations however, the reference count is kept within the VTK objects themselves, instead of the smart pointer class. This has the advantage that the reference count can be increased, even if the VTK object is passed around as a raw pointer. There are two major ways to create managed VTK objects. vtkNew<T> and vtkSmartPointer<T>::New(), with the main difference being that a vtkSmartPointer<T> is implicit cast-able to the raw pointer T*, and can be returned from a function. For instances of vtkNew<T> we’ll have to call .Get() to obtain a raw pointer and we can only return it by wrapping it into a vtkSmartPointer. Within our example, we never return from functions and all objects live the whole time, therefore we’ll use the short vtkNew, with only the above exception for demonstration purposes.</p>
<p>At this point, nothing has been read from the file yet. We or a filter further down the chain would have to call Update() for the file reading to actually happen. It is usually the best approach to let the VTK classes handle the updates themselves. However, sometimes we want to access the result of a filter directly, for example to get the range of pressures in this dataset. Then we need to call Update() manually. (We don’t lose performance by calling Update() multiple times, as the results are cached.)</p>
<p>  // Get the pressure range<br />
  pumpReader->Update();<br />
  double pressureRange[2];<br />
  pumpReader->GetOutput()->GetPointData()->GetArray(&#8220;Pressure&#8221;)->GetRange(pressureRange);<br />
Next, we need to extract the left half of the dataset, using vtkClipDataSet. To achieve this we first define a vtkPlane that defines the split. Then, we’ll see for the first time how the VTK pipeline is connected together: successor->SetInputConnection(predecessor->GetOutputPort()). Whenever we request an update from clipperLeft this connection will now ensure that all preceding filters are also up to date.</p>
<p>  // Clip the left part from the input<br />
  vtkNew<vtkPlane> planeLeft;<br />
  planeLeft->SetOrigin(0.0, 0.0, 0.0);<br />
  planeLeft->SetNormal(-1.0, 0.0, 0.0);</p>
<p>  vtkNew<vtkClipDataSet> clipperLeft;<br />
  clipperLeft->SetInputConnection(pumpReader->GetOutputPort());<br />
  clipperLeft->SetClipFunction(planeLeft.Get());<br />
Finally, we create our first actors and mappers to display the wireframe rendering of the left half. Notice, that the mapper is connected to its filter in exactly the same way as the filters to each other. Most of the time, the renderer itself is triggering the updates of all actors, mappers and the underlying filter chains!</p>
<p>The only line that is not self-explanatory is probably leftWireMapper->ScalarVisibilityOff(); &#8211; it prohibits the coloring of the wireframe by pressure values, which are set as the currently active array.</p>
<p>  // Create the wireframe representation for the left part<br />
  vtkNew<vtkDataSetMapper> leftWireMapper;<br />
  leftWireMapper->SetInputConnection(clipperLeft->GetOutputPort());<br />
  leftWireMapper->ScalarVisibilityOff();</p>
<p>  vtkNew<vtkActor> leftWireActor;<br />
  leftWireActor->SetMapper(leftWireMapper.Get());<br />
  leftWireActor->GetProperty()->SetRepresentationToWireframe();<br />
  leftWireActor->GetProperty()->SetColor(0.8, 0.8, 0.8);<br />
  leftWireActor->GetProperty()->SetLineWidth(0.5);<br />
  leftWireActor->GetProperty()->SetOpacity(0.8);<br />
  renderer->AddActor(leftWireActor.Get());<br />
At this point, the render window is finally showing something, i.e., the wireframe for the left part.</p>
<p><a href="http://www.cadculture.com/wp-content/uploads/2016/05/visualisation-render.png"><img src="http://www.cadculture.com/wp-content/uploads/2016/05/visualisation-render.png" alt="visualisation render" width="700" height="761" class="alignnone size-full wp-image-866" /></a></p>
<p>The wireframe rendering for the right part is created in a similar way, by switching the plane normal of a (newly created) vtkClipDataSet to the opposite direction and slightly changing the color and opacity of the (newly created) mapper and actor. Notice, that here our VTK pipeline splits into two directions (right and left) from the same input dataset.</p>
<p>  // Clip the right part from the input<br />
  vtkNew<vtkPlane> planeRight;<br />
  planeRight->SetOrigin(0.0, 0.0, 0.0);<br />
  planeRight->SetNormal(1.0, 0.0, 0.0);</p>
<p>  vtkNew<vtkClipDataSet> clipperRight;<br />
  clipperRight->SetInputConnection(pumpReader->GetOutputPort());<br />
  clipperRight->SetClipFunction(planeRight.Get());</p>
<p>  // Create the wireframe representation for the right part<br />
  vtkNew<vtkDataSetMapper> rightWireMapper;<br />
  rightWireMapper->SetInputConnection(clipperRight->GetOutputPort());<br />
  rightWireMapper->ScalarVisibilityOff();</p>
<p>  vtkNew<vtkActor> rightWireActor;<br />
  rightWireActor->SetMapper(rightWireMapper.Get());<br />
  rightWireActor->GetProperty()->SetRepresentationToWireframe();<br />
  rightWireActor->GetProperty()->SetColor(0.2, 0.2, 0.2);<br />
  rightWireActor->GetProperty()->SetLineWidth(0.5);<br />
  rightWireActor->GetProperty()->SetOpacity(0.1);<br />
  renderer->AddActor(rightWireActor.Get());<br />
The output window now shows both wireframe parts, as expected.</p>
<p><a href="http://www.cadculture.com/wp-content/uploads/2016/05/visualisation-render-wireframe.png"><img src="http://www.cadculture.com/wp-content/uploads/2016/05/visualisation-render-wireframe.png" alt="visualisation render wireframe" width="700" height="761" class="alignnone size-full wp-image-868" /></a></p>
<p>Now we are ready to visualize some useful data! For adding the pressure visualization to the left part, we don’t need to do much. We create a new mapper and connect it to clipperLeft as well, but this time we color by the pressure array. It is also here, that we finally utilize the pressureRange we have derived above.</p>
<p>  // Create the pressure representation for the left part<br />
  vtkNew<vtkDataSetMapper> pressureColorMapper;<br />
  pressureColorMapper->SetInputConnection(clipperLeft->GetOutputPort());<br />
  pressureColorMapper->SelectColorArray(&#8220;Pressure&#8221;);<br />
  pressureColorMapper->SetScalarRange(pressureRange);</p>
<p>  vtkNew<vtkActor> pressureColorActor;<br />
  pressureColorActor->SetMapper(pressureColorMapper.Get());<br />
  pressureColorActor->GetProperty()->SetOpacity(0.5);<br />
  renderer->AddActor(pressureColorActor.Get());<br />
The output now looks like the image shown below. The pressure at the middle is very low, sucking material into the pump. Then, this material is transported to the outside, rapidly gaining pressure. (Of course there should be a color map legend with the actual values, but I left it out to keep the example shorter.)</p>
<p><a href="http://www.cadculture.com/wp-content/uploads/2016/05/visualisation-render-wireframe-coloured.png"><img src="http://www.cadculture.com/wp-content/uploads/2016/05/visualisation-render-wireframe-coloured.png" alt="visualisation render wireframe coloured" width="700" height="761" class="alignnone size-full wp-image-869" /></a></p>
<p>Now the trickier part starts. We want to draw velocity streamlines in the right part. Streamlines are generated by integration within a vector field from source points. The vector field is already part of the dataset in the form of the “Velocities” vector-array. So we only need to generate the source points. vtkPointSource generates a sphere of random points. We’ll generate 1500 source points, because most of them won’t lie within the dataset anyways and will be ignored by the stream tracer.</p>
<p>  // Create the source points for the streamlines<br />
  vtkNew<vtkPointSource> pointSource;<br />
  pointSource->SetCenter(0.0, 0.0, 0.015);<br />
  pointSource->SetRadius(0.2);<br />
  pointSource->SetDistributionToUniform();<br />
  pointSource->SetNumberOfPoints(1500);<br />
Next we create the streamtracer and set its input connections. “Wait, multiple connections?”, you might say. Yes &#8211; this is the first VTK filter with multiple inputs we encounter. The normal input connection is used for the vector field, and the source connection is used for the seed points. Since “Velocities” is the “active” vector array in clipperRight, we don’t need to specify it here explicitly. Finally we specify that the integration should be performed to both directions from the seed points, and set the integration method to <a href="https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods">Runge-Kutta-4.5.</a></p>
<p>  vtkNew<vtkStreamTracer> tracer;<br />
  tracer->SetInputConnection(clipperRight->GetOutputPort());<br />
  tracer->SetSourceConnection(pointSource->GetOutputPort());<br />
  tracer->SetIntegrationDirectionToBoth();<br />
  tracer->SetIntegratorTypeToRungeKutta45();</p>
<p>Our next problem is coloring the streamlines by velocity magnitude. Since there is no array for the magnitudes of the vectors, we will simply compute the magnitudes into a new scalar array. As you have guessed, there is a VTK filter for this task as well: vtkArrayCalculator. It takes a dataset and outputs it unchanged, but adds exactly one array that is computed from one or more of the existing ones. We configure this array calculator to take the magnitude of the “Velocity” vector and output it as “MagVelocity”. Finally, we call Update() manually again, in order to derive the range of the new array.</p>
<p>  // Compute the velocity magnitudes and create the ribbons<br />
  vtkNew<vtkArrayCalculator> magCalc;<br />
  magCalc->SetInputConnection(tracer->GetOutputPort());<br />
  magCalc->AddVectorArrayName(&#8220;Velocity&#8221;);<br />
  magCalc->SetResultArrayName(&#8220;MagVelocity&#8221;);<br />
  magCalc->SetFunction(&#8220;mag(Velocity)&#8221;);</p>
<p>  magCalc->Update();<br />
  double magVelocityRange[2];<br />
  magCalc->GetOutput()->GetPointData()->GetArray(&#8220;MagVelocity&#8221;)->GetRange(magVelocityRange);<br />
vtkStreamTracer directly outputs polylines and vtkArrayCalculator passes them on unchanged. Therefore we could just display the output of magCalc directly using a new mapper and actor.</p>
<p>Instead, in this training we opt to make the output a little nicer, by displaying ribbons instead. vtkRibbonFilter generates 2D cells to display ribbons for all polylines of its input.</p>
<p>  // Create and render the ribbons<br />
  vtkNew<vtkRibbonFilter> ribbonFilter;<br />
  ribbonFilter->SetInputConnection(magCalc->GetOutputPort());<br />
  ribbonFilter->SetWidth(0.0005);</p>
<p>  vtkNew<vtkPolyDataMapper> streamlineMapper;<br />
  streamlineMapper->SetInputConnection(ribbonFilter->GetOutputPort());<br />
  streamlineMapper->SelectColorArray(&#8220;MagVelocity&#8221;);<br />
  streamlineMapper->SetScalarRange(magVelocityRange);</p>
<p>  vtkNew<vtkActor> streamlineActor;<br />
  streamlineActor->SetMapper(streamlineMapper.Get());<br />
  renderer->AddActor(streamlineActor.Get());<br />
What is now still missing, and is actually needed to produce the intermediate renderings as well, are the last five lines to actually render the scene and initialize the interactor.</p>
<p>  // Render and show interactive window<br />
  renWin->Render();<br />
  interact->Initialize();<br />
  interact->Start();<br />
  return 0;<br />
}<br />
Finally, we arrive at the finished visualization, which I will present once again here:</p>
<p><a href="http://www.cadculture.com/wp-content/uploads/2016/05/visualisation-toolkit.png"><img src="http://www.cadculture.com/wp-content/uploads/2016/05/visualisation-toolkit.png" alt="Visualisation Toolkit" width="700" height="761" class="alignnone size-full wp-image-865" /></a></p>
<p>The full source code for the above visualization can be found <a href="https://bitbucket.org/B3ret/publicsamples/src/c189095649bb59ba2771b3b24b8779ac91bc2b20/main.cxx?at=master">here</a></p>
<h2>The Good, the Bad, and the Ugly</h2>
<p>I will close this article with a list of my personal pros and cons of the VTK framework.</p>
<ul>
<li><strong>Pro</strong>: Active development: VTK is under active development from several contributors, mainly from within the research community. This means that some cutting-edge algorithms are available, many 3D-formats can be imported and exported, bugs are actively fixed, and problems usually have a ready-made solution in the discussion boards.</li>
<li><strong>Con</strong>: Reliability: Coupling many algorithms from different contributors with the open pipeline design of VTK however, can lead to problems with unusual filter combinations. I have had to go into the VTK source code a few times in order to figure out why my complex filter chain is not producing the desired results. I would strongly recommend setting up VTK in a way that permits debugging.</li>
<li><strong>Pro</strong>: Software Architecture: The pipeline design and general architecture of VTK seems well thought out and is a pleasure to work with. A few code lines can produce amazing results. The built-in data structures are easy to understand and use.</li>
<li><strong>Con</strong>: Micro Architecture: Some micro-architectural design decisions escape my understanding. Const-correctness is almost non-existent, arrays are passed around as inputs and outputs with no clear distinction. I alleviated this for my own algorithms by giving up some performance and using my own wrapper for vtkMath which utilizes custom 3D types like typedef std::array<double, 3> Pnt3d;.</li>
<li><strong>Pro</strong>: Micro Documentation: The Doxygen documentation of all classes and filters is extensive and usable, the examples and test cases on the wiki are also a great help to understand how filters are used.</li>
</li>
<p><strong>Con</strong>: Macro Documentation: There are several good tutorials for and introductions to VTK on the web. However as far as I know, there is no big reference documentation that explains how specific things are done. If you want to do something new, expect to search for how to do it for some time. In addition it is hard to find the specific filter for a task. Once you’ve found it however, the Doxygen documentation will usually suffice. A good way to explore the VTK framework is to download and experiment with Paraview.</li>
<li><strong>Pro</strong>: Implicit Parallelization Support: If your sources can be split into several parts that can be processed independently, parallelization is as simple as creating a separate filter chain within each thread that processes a single part. Most large visualization problems usually fall into this category.</li>
<li><strong>Con</strong>: No Explicit Parallelization Support: If you are not blessed with large, dividable problems, but you want to utilize multiple cores, you are on your own. You’ll have to figure out which classes are thread-safe, or even re-entrant by trial-and-error or by reading the source. I once tracked down a parallelization problem to a VTK filter that used a static global variable in order to call some C library.</li>
<li><strong>Pro</strong>: Buildsystem CMake: The multi-platform meta-build-system <a href="http://www.cmake.org/">CMake</a> is also developed by Kitware (the makers of VTK) and used in many projects outside of Kitware. It integrates very nicely with VTK and makes setting up a build system for multiple platforms much less painful.</li>
<li><strong>Pro</strong>: Platform Independence, License, and Longevity: VTK is platform independent out of the box, and is licensed under a <a href="http://www.vtk.org/licensing/">very permissive BSD-style license</a>. In addition, professional support is available for those important projects that require it. Kitware is backed by many research entities and other companies and will be around for some time.</li>
</ul>
<h2>Last Word</h2>
<p>Overall, VTK is the best data visualization tool for the kinds of problems I love. If you ever come across a project that requires visualization, mesh processing, image processing or similar tasks, try firing up Paraview with an input example and evaluate if VTK could be the tool for you.</p>
<p>For more information or to read the original article please <a href="https://www.toptal.com/data-science/3d-data-visualization-with-open-source-tools-an-example-using-vtk">click here</a></p>
<p>The post <a rel="nofollow" href="http://www.cadculture.com/3d-data-visualization-with-open-source-tools-a-tutorial-using-vtk/">3D Data Visualization with Open Source Tools: A Tutorial Using VTK</a> appeared first on <a rel="nofollow" href="http://www.cadculture.com">CAD Culture</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cadculture.com/3d-data-visualization-with-open-source-tools-a-tutorial-using-vtk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introduction to OpenGL: A 3D Text Rendering Tutorial</title>
		<link>http://www.cadculture.com/introduction-to-opengl-a-3d-text-rendering-tutorial/</link>
		<comments>http://www.cadculture.com/introduction-to-opengl-a-3d-text-rendering-tutorial/#comments</comments>
		<pubDate>Wed, 20 Apr 2016 10:18:20 +0000</pubDate>
		<dc:creator><![CDATA[Cad Culture]]></dc:creator>
				<category><![CDATA[Uncategorised]]></category>

		<guid isPermaLink="false">http://www.cadculture.com/?p=855</guid>
		<description><![CDATA[<p>With the availability of tools like DirectX and OpenGL, writing a desktop application that renders 3D elements is not very difficult nowadays. However, like many technologies, there are sometimes obstacles making it difficult for developers trying to enter into this niche. Over time, the race between DirectX and OpenGL has caused these technologies to become [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://www.cadculture.com/introduction-to-opengl-a-3d-text-rendering-tutorial/">Introduction to OpenGL: A 3D Text Rendering Tutorial</a> appeared first on <a rel="nofollow" href="http://www.cadculture.com">CAD Culture</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>With the availability of tools like DirectX and OpenGL, writing a desktop application that renders 3D elements is not very difficult nowadays. However, like many technologies, there are sometimes obstacles making it difficult for developers trying to enter into this niche. Over time, the race between DirectX and OpenGL has caused these technologies to become more accessible to developers, along with better documentation and an easier process of becoming a skilled DirectX or OpenGL developer.</p>
<p>DirectX, introduced and maintained by Microsoft, is a technology specific to the Windows platform. On the other hand, OpenGL is a cross-platform API for the 3D graphics arena whose specification is maintained by the Khronos Group.</p>
<p><a href="http://www.cadculture.com/wp-content/uploads/2016/04/open-gl-blog-image.png"><img src="http://www.cadculture.com/wp-content/uploads/2016/04/open-gl-blog-image.png" alt="Introduction to Open GL" width="620" height="620" class="alignnone size-full wp-image-856" /></a></p>
<p>In this introduction to OpenGL, I will explain how to write a very simple application to render 3D text models. We will be using Qt/Qt Creator to implement the UI, making it easy to compile and run this application on multiple platforms. The source code of the prototype built for this article is available on GitHub.</p>
<p>The goal of this simple application is to generate 3D models, save them to a file with a simple format, and to open and render them on screen. The 3D model in the rendered scene will be rotatable and zoomable, to give a better sense of depth and dimension.</p>
<h2>Prerequisites</h2>
<p>Before getting started, we will need to prepare our development environment with some useful tools for this project. The very first thing we need is the Qt framework and relevant utilities, which can be downloaded from www.qt.io. It may also be available through your operating system’s standard package manager; if that is the case, you might want to try with it first. This article requires some familiarity with the Qt framework. However, if you are not familiar with the framework, please do not feel discouraged to follow along, as the prototype relies on some fairly trivial features of the framework.</p>
<p>You can also use Microsoft Visual Studio 2013 on Windows. In that case, please make sure you are using the appropriate Qt Addin for Visual Studio.</p>
<p>At this point, you might want to clone the repository from GitHub and follow it as you read through this article.</p>
<h2>OpenGL Overview</h2>
<p>We will begin by creating a simple Qt application project with a single document widget. Since it is a bare-bones widget, compiling and running it will not produce anything useful. With Qt designer, we will add a “File” menu with four items: “New…”, “Open…”, “Close”, and “Exit”. You can find the code that binds these menu items to their corresponding actions in the repository.</p>
<p>Clicking on “New…” should popup a dialog that will look something like this:</p>
<p><a href="http://www.cadculture.com/wp-content/uploads/2016/04/open-gl-logo.jpg"><img src="http://www.cadculture.com/wp-content/uploads/2016/04/open-gl-logo.jpg" alt="open gl logo" width="700" height="577" class="alignnone size-full wp-image-857" /></a></p>
<p>Here, the user may enter some text, choose a font, tweak the resulting model height, and generate a 3D model. Clicking on “Create” should save the model, and should also open it if the user chooses the appropriate option from the lower-left corner. As you can tell, the goal here is to convert some user inputted text into a 3D model and render it on the display.</p>
<p>The project will have a simple structure, and the components will be broken down into a handful of C++ and header files:</p>
<p><a href="http://www.cadculture.com/wp-content/uploads/2016/04/open-gl-options.png"><img src="http://www.cadculture.com/wp-content/uploads/2016/04/open-gl-options.png" alt="open gl options" width="620" height="620" class="alignnone size-full wp-image-858" /></a></p>
<p><strong>createcharmodeldlg.h/cpp</strong></p>
<p>Files contain QDialog derived object. This implements the dialog widget which allows the user to type text, select font, and choose whether to save the result into a file and/or display it in 3D.</p>
<p><strong>gl_widget.h/cpp</strong></p>
<p>Contains implementation of QOpenGLWidget derived object. This widget is used to render the 3D scene.</p>
<p><strong>mainwindow.h/cpp</strong></p>
<p>Contains implementation of the main application widget. These files were left unchanged since they were created by Qt Creator wizard.</p>
<p><strong>main.cpp</strong></p>
<p>Contains the main(…) function, which creates the main application widget and shows it on screen.</p>
<p><strong>model2d_processing.h/cpp</strong></p>
<p>Contains functionality of creation of 2D scene.</p>
<p><strong>model3d.h/cpp</strong></p>
<p>Contains structures which store 3D model objects and allow operations to work on them (save, load etc.).</p>
<p><strong>model_creator.h/cpp</strong></p>
<p>Contains implementation of class which allows creation of 3D scene model object.</p>
<h2>OpenGL Implementation</h2>
<p>For brevity, we will skip the obvious details of implementing the user interface with Qt Designer, and the code defining the behaviors of the interactive elements. There are certainly some more interesting aspects of this prototype application, ones that are not only important but also relevant to 3D model encoding and rendering that we want to cover. For example, the first step of converting text to a 3D model in this prototype involves converting the text to a 2D monochrome image. Once this image is generated, it is possible to know which pixel of the image forms the text, and which ones are just “empty” space. There are some simpler ways of rendering basic text using OpenGL, but we are taking this approach in order to cover some nitty-gritty details of 3D rendering with OpenGL.</p>
<p>To generate this image, we instantiate a QImage object with the QImage::Format_Mono flag. Since all we need to know is which pixels are part of the text and which ones are not, a monochrome image should work just fine. When the user enters some text, we synchronously update this QImage object. Based on the font size and image width, we try our best to fit the text within the user defined height.</p>
<p>Next, we enumerate all the pixels which are part of the text &#8211; in this case, the black pixels. Each pixel here is treated as separate square-ish units. Based on this, we can generate a list of triangles, computing the coordinates of their vertices, and store them in our 3D model file.</p>
<p>Now that we have our own simple 3D model file format, we can start focusing on rendering it. For OpenGL based 3D rendering, Qt provides a widget called QOpenGLWidget. To use this widget, three functions may be overridden:</p>
<ul>
<li>initializeGl() &#8211; this is where the initialization code goes</li>
<li>paintGl() &#8211; this method is called everytime the widget is redrawn</li>
<li>resizeGl(int w, int h) &#8211; this method is called with the widget’s width and height every time it is resized</li>
</ul>
<p><a href="http://www.cadculture.com/wp-content/uploads/2016/04/open-gl-logo-2.jpg"><img src="http://www.cadculture.com/wp-content/uploads/2016/04/open-gl-logo-2.jpg" alt="open-gl-logo-2" width="700" height="577" class="alignnone size-full wp-image-859" /></a></p>
<p>We will initialize the widget by setting the appropriate shader configuration in the initializeGl method.</p>
<p><em>glEnable(GL_DEPTH_TEST);</em><br />
<em>glShadeModel(GL_FLAT);</em><br />
<em>glDisable(GL_CULL_FACE);</em></p>
<p>The first line makes the program show only those rendered pixels that are closer to us, rather than the ones that are behind other pixels and out of sight. The second line specifies the flat shading technique. The third line makes the program render triangles regardless of which direction their normals point to.</p>
<p>Once initialized, we render the model on the display every time paintGl is called. Before we override the paintGl method, we must prepare the buffer. To do that, we first create a buffer handle. We then bind the handle to one of the binding points, copy the source data into the buffer, and finally we tell the program to unbind the buffer:</p>
<p>// Get the Qt object which allows to operate with buffers<br />
QOpenGLFunctions funcs(QOpenGLContext::currentContext());<br />
// Create the buffer handle<br />
funcs.glGenBuffers(1, &#038;handle);<br />
// Select buffer by its handle (so we’ll use this buffer<br />
// further)<br />
funcs.glBindBuffer(GL_ARRAY_BUFFER, handle);<br />
// Copy data into the buffer. Being copied,<br />
// source data is not used any more and can be released<br />
funcs.glBufferData(GL_ARRAY_BUFFER,<br />
	size_in_bytes,<br />
	src_data,<br />
	GL_STATIC_DRAW);<br />
// Tell the program we’ve finished with the handle<br />
funcs.glBindBuffer(GL_ARRAY_BUFFER, 0);</p>
<p>Inside the overriding paintGl method, we use an array of vertices and an array of normal data to draw the triangles for each frame:</p>
<p>QOpenGLFunctions funcs(QOpenGLContext::currentContext());<br />
// Vertex data<br />
glEnableClientState(GL_VERTEX_ARRAY);// Work with VERTEX buffer<br />
funcs.glBindBuffer(GL_ARRAY_BUFFER, m_hVertexes);	// Use this one<br />
glVertexPointer(3, GL_FLOAT, 0, 0);		// Data format<br />
funcs.glVertexAttribPointer(m_coordVertex, 3, GL_FLOAT,<br />
	GL_FALSE, 0, 0);	// Provide into shader program</p>
<p>// Normal data<br />
glEnableClientState(GL_NORMAL_ARRAY);// Work with NORMAL buffer<br />
funcs.glBindBuffer(GL_ARRAY_BUFFER, m_hNormals);// Use this one<br />
glNormalPointer(GL_FLOAT, 0, 0);	// Data format<br />
funcs.glEnableVertexAttribArray(m_coordNormal);	// Shader attribute<br />
funcs.glVertexAttribPointer(m_coordNormal, 3, GL_FLOAT,<br />
	GL_FALSE, 0, 0);	// Provide into shader program</p>
<p>// Draw frame<br />
glDrawArrays(GL_TRIANGLES, 0, (3 * m_model.GetTriangleCount()));</p>
<p>// Rendering finished, buffers are not in use now<br />
funcs.glDisableVertexAttribArray(m_coordNormal);<br />
funcs.glBindBuffer(GL_ARRAY_BUFFER, 0);<br />
glDisableClientState(GL_VERTEX_ARRAY);<br />
glDisableClientState(GL_NORMAL_ARRAY);<br />
For improved performance, we used Vertex Buffer Object (VBO) in our prototype application. This lets us store data in video memory and use it directly for rendering. An alternate method to this involves providing the data (vertex coordinates, normals and colors) from the rendering code:</p>
<p>glBegin(GL_TRIANGLES);<br />
	// Provide coordinates of triangle #1<br />
	glVertex3f( x[0], y[0], z[0]);<br />
	glVertex3f( x[1], y[1], z[1]);<br />
	glVertex3f( x[2], y[2], z[2]);<br />
	// Provide coordinates of other triangles<br />
	&#8230;<br />
glEnd();<br />
This may seem like a simpler solution; however, it has serious performance implications, as this requires the data to travel through the video memory bus &#8211; a relatively slower process. After implementing the paintGl method, we must pay attention to shaders:</p>
<p>m_shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex,<br />
    	QString::fromUtf8(<br />
        	&#8220;#version 400\r\n&#8221;<br />
        	&#8220;\r\n&#8221;<br />
        	&#8220;layout (location = 0) in vec3 coordVertexes;\r\n&#8221;<br />
        	&#8220;layout (location = 1) in vec3 coordNormals;\r\n&#8221;<br />
        	&#8220;flat out float lightIntensity;\r\n&#8221;<br />
        	&#8220;\r\n&#8221;<br />
        	&#8220;uniform mat4 matrixVertex;\r\n&#8221;<br />
        	&#8220;uniform mat4 matrixNormal;\r\n&#8221;<br />
        	&#8220;\r\n&#8221;<br />
        	&#8220;void main()\r\n&#8221;<br />
 	       	&#8220;{\r\n&#8221;<br />
        	&#8221;   gl_Position = matrixVertex * vec4(coordVertexes, 1.0);\r\n&#8221;<br />
        	&#8221;   lightIntensity = abs((matrixNormal * vec4(coordNormals, 1.0)).z);\r\n&#8221;<br />
        	&#8220;}&#8221;));<br />
m_shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment,<br />
    	QString::fromUtf8(<br />
        	&#8220;#version 400\r\n&#8221;<br />
        	&#8220;\r\n&#8221;<br />
        	&#8220;flat in float lightIntensity;\r\n&#8221;<br />
        	&#8220;\r\n&#8221;<br />
        	&#8220;layout (location = 0) out vec4 FragColor;\r\n&#8221;<br />
        	&#8220;uniform vec3 fragmentColor;\r\n&#8221;<br />
        	&#8220;\r\n&#8221;<br />
        	&#8220;void main()\r\n&#8221;<br />
        	&#8220;{\r\n&#8221;<br />
        	&#8221;	FragColor = vec4(fragmentColor * lightIntensity, 1.0);\r\n&#8221;<br />
        	&#8220;}&#8221;));<br />
	m_shaderProgram.link();<br />
	m_shaderProgram.bind();</p>
<p>	m_coordVertex =<br />
		m_shaderProgram.attributeLocation(QString::fromUtf8(&#8220;coordVertexes&#8221;));<br />
	m_coordNormal =<br />
		m_shaderProgram.attributeLocation(QString::fromUtf8(&#8220;coordNormals&#8221;));<br />
	m_matrixVertex =<br />
		m_shaderProgram.uniformLocation(QString::fromUtf8(&#8220;matrixVertex&#8221;));<br />
	m_matrixNormal =<br />
		m_shaderProgram.uniformLocation(QString::fromUtf8(&#8220;matrixNormal&#8221;));<br />
	m_colorFragment =<br />
		m_shaderProgram.uniformLocation(QString::fromUtf8(&#8220;fragmentColor&#8221;));<br />
With OpenGL, shaders are implemented using a language known as GLSL. The language is designed to make it easy to manipulate 3D data before it is rendered. Here, we will need two shaders: vertex shader and fragment shader. In vertex shader, we will transform the coordinates with the transformation matrix to apply rotation and zoom, and to calculate color. In fragment shader, we will assign color to the fragment. These shader programs must then be compiled and linked with the context. OpenGL provides simple ways of bridging the two environments so that parameters inside the program may be accessed or assigned from outside:</p>
<p>// Get model transformation matrix<br />
QMatrix4x4 matrixVertex;<br />
&#8230; // Calculate the matrix here<br />
// Set Shader Program object&#8217; parameters<br />
m_shaderProgram.setUniformValue(m_matrixVertex, matrixVertex);<br />
In the vertex shader code, we calculate the new vertex position by applying the transformation matrix on the original vertices:</p>
<p>gl_Position = matrixVertex * vec4(coordVertexes, 1.0);<br />
To compute this transformation matrix, we compute a few separate matrices: screen scale, translate scene, scale, rotate, and center. We then find the product of these matrices in order to compute the final transformation matrix. Start by translating the model center to the origin (0, 0, 0), which is the center of the screen as well. Rotation is determined by the user’s interaction with the scene using some pointing device. The user can click on the scene and drag around to rotate. When the user clicks, we store the cursor position, and after a movement we have the second cursor position. Using these two coordinates, along with the scene center, we form a triangle. Following some simple calculations we can determine the rotation angle, and we can update our rotation matrix to reflect this change. For scaling, we simply rely on the mouse wheel to modify the scaling factor of the X and Y axes of the OpenGL widget. The model is translated back by 0.5 to keep it behind the plane from which the scene is rendered. Finally, to maintain the natural aspect ratio we need to adjust the decrease of the model expansion along the longer side (unlike the OpenGL scene, the widget where it is rendered may have different physical dimensions along either axes). Combining all these, we calculate the final transformation matrix as follows:</p>
<p>void GlWidget::GetMatrixTransform(QMatrix4x4&#038; matrixVertex,<br />
                                 const Model3DEx&#038; model)<br />
{<br />
   matrixVertex.setToIdentity();</p>
<p>   QMatrix4x4 matrixScaleScreen;<br />
   double dimMin = static_cast<double>(qMin(width(), height()));<br />
   float scaleScreenVert = static_cast<float>(dimMin /<br />
       static_cast<double>(height()));<br />
   float scaleScreenHorz = static_cast<float>(dimMin /<br />
       static_cast<double>(width()));<br />
   matrixScaleScreen.scale(scaleScreenHorz, scaleScreenVert, 1.0f);</p>
<p>   QMatrix4x4 matrixCenter;<br />
   float centerX, centerY, centerZ;<br />
   model.GetCenter(centerX, centerY, centerZ);<br />
   matrixCenter.translate(-centerX, -centerY, -centerZ);</p>
<p>   QMatrix4x4 matrixScale;<br />
   float radius = 1.0;<br />
   model.GetRadius(radius);<br />
   float scale = static_cast<float>(m_scaleCoeff / radius);<br />
   matrixScale.scale(scale, scale, 0.5f / radius);</p>
<p>   QMatrix4x4 matrixTranslateScene;<br />
   matrixTranslateScene.translate(0.0f, 0.0f, -0.5f);</p>
<p>   matrixVertex = matrixScaleScreen * matrixTranslateScene * matrixScale * m_matrixRotate * matrixCenter;<br />
}</p>
<h2>Conclusion</h2>
<p>In this introduction to OpenGL 3D rendering, we explored one of the technologies that allow ud to utilize our video card to render a 3D model. This is much more efficient than using CPU cycles for the same purpose. We used a very simple shading technique, and made the scene interactive through the handling of user inputs from the mouse. We avoided using the video memory bus to pass data back-and-forth between the video memory and the program. Even though we just rendered a single line of text in 3D, more complicated scenes can be rendered in very similar ways.</p>
<p>To be fair, this tutorial has barely scratched the surface of 3D modeling and rendering. This is a vast topic, and this OpenGL tutorial can’t claim this is all you need to know to be able to build 3D games or modeling softwares. However, the purpose of this article is to give you a peek into this realm, and show how easily you can get started with OpenGL to build 3D applications.</p>
<p>View the original article here <a href="https://www.toptal.com/opengl/introduction-to-opengl-a-quick-tutorial">https://www.toptal.com/opengl/introduction-to-opengl-a-quick-tutorial</a></p>
<p>The post <a rel="nofollow" href="http://www.cadculture.com/introduction-to-opengl-a-3d-text-rendering-tutorial/">Introduction to OpenGL: A 3D Text Rendering Tutorial</a> appeared first on <a rel="nofollow" href="http://www.cadculture.com">CAD Culture</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cadculture.com/introduction-to-opengl-a-3d-text-rendering-tutorial/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>3d Printing for Designers and Developers</title>
		<link>http://www.cadculture.com/3d-printing-for-designers-and-developers/</link>
		<comments>http://www.cadculture.com/3d-printing-for-designers-and-developers/#comments</comments>
		<pubDate>Tue, 05 Apr 2016 09:33:01 +0000</pubDate>
		<dc:creator><![CDATA[Cad Culture]]></dc:creator>
				<category><![CDATA[Uncategorised]]></category>

		<guid isPermaLink="false">http://www.cadculture.com/?p=849</guid>
		<description><![CDATA[<p>3D printing is not a new technology, but recent advances in several fields have made it more accessible to hobbyists and businesses. Compared to other tech sectors, it’s still a small industry, but most analysts agree it has a lot of potential. But where is the potential for freelance designers and software engineers? A fellow [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://www.cadculture.com/3d-printing-for-designers-and-developers/">3d Printing for Designers and Developers</a> appeared first on <a rel="nofollow" href="http://www.cadculture.com">CAD Culture</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>3D printing is not a new technology, but recent advances in several fields have made it more accessible to hobbyists and businesses. Compared to other tech sectors, it’s still a small industry, but most analysts agree it has a lot of potential. But where is the potential for freelance designers and software engineers?</p>
<p>A fellow Toptaler asked me this a couple of weeks ago, because I used to cover 3D printing for a couple of publications. I had no clear answer. I couldn’t just list business opportunities because this is a niche industry with a limited upside and mass market appeal. What’s more, 3D printing is still not a mature technology, which means there is not a lot in the way of standardisation and online resources for designers and developers willing to take the plunge.</p>
<p>However, this does not mean there are no business opportunities; they’re out there, but they are limited. In this post, I will try to explain what makes the 3D printing industry different, and what freelancers can expect moving forward.</p>
<p>3D Printing For Hobbyists And Businesses</p>
<p>First of all, I think we need to distinguish between two very different niches in the 3D printing, or additive manufacturing industry.</p>
<p>On one end of the spectrum, you have countless hardware enthusiasts, software developers and designers working on open-source projects. The RepRap project embodies this lean and open approach better than any similar initiative in the industry. RepRap stands for Replicating Rapid Prototyper and it’s basically an initiative to develop inexpensive printers based on fused filament fabrication (FFF) technology. Essentially, that is Fused Deposition Modelling (FDM) technology, but RepRap can’t use that name because it was commercialised by Stratasys. When the company’s patent on FDM expired, FDM was embraced by the open-source community, albeit under a different name.</p>
<p><a href="http://www.cadculture.com/wp-content/uploads/2016/04/3d-printing.jpg"><img src="http://www.cadculture.com/wp-content/uploads/2016/04/3d-printing.jpg" alt="3d-printing" width="640" height="640" class="alignnone size-full wp-image-850" /></a></p>
<p>3D printing is not a new technology, but recent advances in several fields have made it more accessible to hobbyists and businesses.</p>
<p>RepRap turned ten this year, with the first printers showing up a few years after launch. By 2010, the RepRap project was on its third generation design, and the RepRap community saw a lot of growth over the next few years.</p>
<p>One noteworthy feature to come out of the RepRap initiative is self-replication; the ultimate goal of the project is to create a 3D printer that will eventually replicate itself. We are not there yet, but some RepRap designs allow users to print three quarters of the printer. You still can’t print extruders and electric servos, but it’s a start.</p>
<p>However, RepRap was never supposed to be a commercial success. It was created as a tech-first initiative, so it was never consumer-centric. It was all about pioneering various technologies and bringing them to the hobbyist market at low cost. RepRap was never supposed to be a cash cow.</p>
<p>So what about big business? A number of industry pioneers have already become 3D printing heavyweights. These include Stratasys, 3D Systems, Ultimaker and Printbot. RepRap printers still command a big market share, and they’re not being squeezed out by proprietary platforms. In fact, most vendors have no choice but to embrace some RepRap standards in order to guarantee compatibility.</p>
<p>However, simply listing 3D printing companies and their respective market share does not paint the full picture. For example, RepRap is limited to FFF technology, which is the most widespread 3D printing technology today. The problem is that FFF printers have a lot of limitations, which means they cannot be used in many industries.</p>
<h2>Different Technologies For Different Applications</h2>
<p>To get a better idea of what’s out there, we need to take a look at currently available 3D printing technologies. This might not seem interesting if you’re not a hardware geek, but it’s important to understand the difference between various printing technologies (and I will try to keep this section as brief as possible).</p>
<p><a href="http://www.cadculture.com/wp-content/uploads/2016/04/fff-fdm-sla-sls-3d-printers.jpg"><img src="http://www.cadculture.com/wp-content/uploads/2016/04/fff-fdm-sla-sls-3d-printers.jpg" alt="fff-fdm-sla-sls-3d-printers" width="640" height="640" class="alignnone size-full wp-image-851" /></a></p>
<p>Although hobbyist FFF printers are relatively inexpensive, certain types of professional 3D printers can cost as much as your home.</p>
<ul>
<li>FFF/FDM usually relies on thermoplastic “filament” heated by the printer extruder prior to being deposited on the print bed. Most FFF printers rely on ABS and PLA plastic filament, but the latest models also use polycarbonate (PC), high-density polyethylene (HDPE), high-impact polystyrene (HIPS) filament. Some even use metal wire instead of plastic, while others use sawdust to create quasi-wood objects. Some can even print food, chocolate, pasta and so on.
<li>
<li>Granular printers are different beasts since their material is not filament but, usually, powdered metal. These printers tend to be based on laser technology (although they don’t have much in common with your office laser printer). They use a powerful laser to selectively fuse granular materials. There are several ways of doing this: Selective laser sintering (SLS) printers fuse small metal particles by the process of “sintering,” while selective laser melting (SLM) printers melt the powder. Electron beam melting (EBM) printers hits metal powder with an electron beam in a vacuum environment</li>
<li>Stereolithography (SLA) printers transform liquid raw material into solids using light. These printers have a number of advantages, in terms of accuracy and the ability to produce complex objects in a single pass, because SLA prints don’t require struts or supports, in most cases. The downside is that the choice of materials is very limited. They are usually exotic liquid polymers, and can’t be used to print metal or chocolate.
<li>
</ul>
<p>There are a few more 3D printing technologies out there, but I see no point in covering all of them for the purposes of this blog post.</p>
<h2>The Challenge</h2>
<p>So why aren’t we all playing around with 3D printers in our homes and offices? Why can’t we print objects the same way we print invoices, sheets and emails? 3D printing is not going mainstream any time soon, and here are some challenges and issues that need to be addressed first.</p>
<ul>
<li>Prohibitively expensive hardware</li>
<li>Limited user base (compared to traditional printers)</li>
<li>Immature technology</li>
<li>Speed</li>
<li>Price/performance, ROI</li>
<li>Running costs</li>
<li>Energy efficiency</li>
</ul>
<p>With each new generation, entry-level 3D printers become a bit cheaper, but they are still too expensive for most potential users. It’s one thing to buy a $200 printer for your home or office, you’ll probably end up using it a lot, but the same isn’t necessarily true of 3D printers. How many people need to print documents, and how many need to print 3D objects?</p>
<p>Technology is improving, but serious limitations persist. 3D printers are still slow, are sensitive to all sorts of adverse conditions, their “printbeds” tend to be small (especially on inexpensive models), the choice of materials is limited and filament can be expensive.</p>
<p>The reason why businesses aren’t lining up to buy 3D printers is simple: ROI. 3D printers still can’t come close to traditional manufacturing methods in terms of speed, cost and energy efficiency. This does not mean industry isn’t going to shift to 3D printing in the future; we are already seeing some pioneering developments, but 3D printers won’t render traditional manufacturing techniques obsolete soon.</p>
<p>Still, there are some noteworthy exceptions. A couple of years ago, General Electric set out to design and build a new fuel injection nozzle for its next generation CFM LEAP turbofan engine, which is bound to end up in hundreds of airliners. GE eventually settled on <a href="http://www.geglobalresearch.com/innovation/3d-printing-creates-new-parts-aircraft-engines">3D-printed titanium nozzles</a>. The reason? The new 3D printed nozzle ended up 25 percent lighter than the previous design and consisted of a single part instead of 18 on the old nozzle. Durability is expected to be five times better. These nozzles will be used in engines manufactured in 2016 and beyond. GE hopes to produce more than 100,000 3D-printed parts by the end of the decade.</p>
<p>A team of GE engineers decided to <a href="http://www.ge.com/stories/advanced-manufacturing">create a working replica</a> of one of the company’s engines, using a new granular printing technique dubbed “metal laser melting.”</p>
<p>Long story short, no, you won’t buy 3D-printed toys for $2 anytime soon, but you will fly on airliners powered by more efficient and reliable engines, made possible by 3D printing. There won’t be any 3D-printed chocolate in your local mall, at least not yet, but your dentist will tell you it’s probably not a good idea to eat chocolate anyway, right after you get your 3D-printed prosthetic.</p>
<h2>There Is Another Way: 3D Printing Fulfilment Services</h2>
<p>So, you have a great idea for a product, but first you need a small series of prototypes. Who do you call? Do you buy a bunch of 3D printers? Or do you simply send the design to a fulfilment service that will ship you the completed models in a matter of days?</p>
<p><a href="http://www.cadculture.com/wp-content/uploads/2016/04/fullfillment-services-3d-printing.jpg"><img src="http://www.cadculture.com/wp-content/uploads/2016/04/fullfillment-services-3d-printing.jpg" alt="fullfillment-services-3d-printing" width="640" height="640" class="alignnone size-full wp-image-852" /></a></p>
<p>Fulfilment services allow consumers and small businesses to take advantage of sophisticated 3D printing infrastructure without burning capital.</p>
<p>A 3D printing fulfilment service seems like a hassle-free choice, and that’s the direction the industry seems to be taking. Many 3D printing outfits have launched similar services and are collaborating with other industry leaders. One example of this symbiotic relationship is <a href="http://pages.stratasysdirect.com/adobe.html">Stratasys Direct Express</a>, which recently partnered with Adobe and enabled Photoshop CC integration, offering colour 3D printing for professional designers.</p>
<p>Google and Motorola didn’t invest billions in their own 3D printing facilities when they unveiled the Ara modular smartphone concept. They outsourced module manufacturing to 3D Systems. This example also underscores the potential flexibility of additive manufacturing: Ara is based around an alloy exoskeleton filled with various standardised modules that could be 3D printed. Since the modules have to connect to the exoskeleton, 3D Systems developed a new technique of depositing conductive materials within the printed components, which is a far cry from traditional 3D printer prototyping.</p>
<p>3D fulfilment services usually offer several different printing technologies, cutting-edge hardware and support. Why bother getting a $2,000 printer when you can simply send your designs to professionals and use any of a variety of professional printers, some of which cost more than your home? And let’s not forget about economy of scale; big services can and should offer a superior price/performance ratio compared to in-house printing.</p>
<p>In my opinion, this is the way to go. This straightforward business model has a lot going for it, and it’s hard to see how individuals and small businesses could compete on an even playing field. In terms of price, size and energy consumption, a professional 3D printer has more in common with a printing press than your LaserJet, and how many people need a printing press in their home or office?</p>
<p>(One of my pet peeves is the name itself. When you mention a “printer” in conversation, most people think of their home inkjet printer, or office printer. While it’s true that 3D printers are printers, they don’t have much in common with traditional printers, and this distinction is often lost on laymen. If we just kept calling them additive manufacturing machines, this wouldn’t be an issue.)</p>
<p>Article Courtesy of BY NERMIN HAJDARBEGOVIC &#8211; TECHNICAL EDITOR @ TOPTAL<br />
view the original article here <a href="https://www.toptal.com/designers/print/3d-printing-for-developers">https://www.toptal.com/designers/print/3d-printing-for-developers</a></p>
<p>The post <a rel="nofollow" href="http://www.cadculture.com/3d-printing-for-designers-and-developers/">3d Printing for Designers and Developers</a> appeared first on <a rel="nofollow" href="http://www.cadculture.com">CAD Culture</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cadculture.com/3d-printing-for-designers-and-developers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
