=========
Cylinders
=========

In |HPSNOW|, cylinders, like spheres, are a type of primitive geometry. They have a smaller memory footprint and can be rendered more quickly than shells. These two features can create many advantages for developers who have models that lend themselves to cylindrical representations.

Cylinders are defined as two circles, known as end caps, connected to one another with edges to form a tube. To create a cylinder in the |HPSNOW| database, use ``HPS::SegmentKey::InsertCylinder``. This function accepts two points (indicating the center points of the end caps) a radius, and an enum. The enum is used to specify if either of the end caps will be rendered. The following sample code shows a cylinder with a 0.55 radius inserted into the database with end caps enabled.

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_cylinder.cpp
		   :start-after: //! [0211_a]
		   :end-before: //! [0211_a]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_cylinder.cs
		   :start-after: //! [0211_a]
		   :end-before: //! [0211_a]
		   
.. image:: images/cylinder.png

*A cylinder inserted using the code above*


Cones
=====

Note that if you wish to insert a cylinder with different size radii, you must use a ``HPS::CylinderKit``. One example of this is a cone. In |HPSNOW|, a cone is simply a cylinder in which one end is zero radius and the other is non-zero. In the example below, it is inserted using a ``HPS::CylinderKit``. Note that any cylinder that does not have equally sized radii **must** be inserted using the ``HPS::CylinderKit``.

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_cones.cpp
		   :start-after: //! [021101_a]
		   :end-before: //! [021101_a]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_cones.cs
		   :start-after: //! [021101_a]
		   :end-before: //! [021101_a]

.. image:: images/cone.png

*A cylinder rendered as a cone*


Notes on Cylinder Subentities
-----------------------------

Cylinders, like spheres, are dynamically constructed |HPSNOW| primitives. One result of this is that user interaction among subentities is limited. For instance, setting attributes or materials on individual faces, lines, or vertices is not supported nor is altering their position. Cylinder and sphere primitives cannot be textured.


Polycylinders
=============

Polycylinders are a sequence of connected cylinders defined by a collection of vertices and their associated radii. Polycylinders are useful in representing a variety of graphical items. For example, they could be used to depict pipework in a factory or plant, or color-interpolated heat/air/fluid-flow streamlines in CAE post-processing applications.

.. image:: images/polycylinders.png

*Three different types of models that can be created using polycylinders*

In addition to their flexibility as a geometric form, polycylinders have only a slightly larger memory footprint than cylinders and can still be rendered faster than shells. Polycylinder insertion is done similarly to normal cylinders - using ``HPS::SegmentKey::InsertCylinder``. The only difference is that you supply a series of points and radii instead of just the two points for the end caps.

The following code snippet shows how to create a torus using ``HPS::SegmentKey::InsertCylinder``. Here, each point of the polycylinder is computed in a circular pattern. |HPSNOW| connects them all to form the object - thus each segment of the torus is logically a single cylinder. Note that one of the last lines of code connects the last point to the first one.

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_polycylinders.cpp
		   :start-after: //! [021102_a]
		   :end-before: //! [021102_a]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_polycylinders.cs
		   :start-after: //! [021102_a]
		   :end-before: //! [021102_a]
		   
.. image:: images/torus.png

*A torus*

|HPSNOW| will sequentially assign the values from the radius array to each polycylinder point. If there are more points than radii, |HPSNOW| will start over with the radius array. Using this technique, interesting effects can be made to the surfaces of the polycylinder. Starting with the code from the previous example, simply change the radius array to include one more element:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_polycylinders.cpp
		   :start-after: //! [021102_b]
		   :end-before: //! [021102_b]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_polycylinders.cs
		   :start-after: //! [021102_b]
		   :end-before: //! [021102_b]
		   
.. image:: images/complex_torus.png

*A complex torus created by alternating the radius of each successive point along its path*


Tessellation
------------

Tessellation for cylinders is controlled at the segment level using ``SetTessellation``. Using a high tessellation value will result in a smoother rendering at the cost of memory and performance. Tessellating complicated polycylinders can result in a large amount of additional faces, so take care to use the smallest tessellation value that your scene allows.

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_polycylinders.cpp
		   :start-after: //! [021102_c]
		   :end-before: //! [021102_c]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_polycylinders.cs
		   :start-after: //! [021102_c]
		   :end-before: //! [021102_c]
		   
Setting the tessellation to a very low value results in primitive shapes that are not otherwise available in |HPSNOW|, such as extruded shapes and pyramids.

.. image:: images/low_tessellations.png

*Cylinders with low tessellations*


Polycylinder-Polyline Side-Effect
---------------------------------

An interesting side effect of polycylinders is that their ability to accept a color at each point can be used to draw polylines of multiple colors, which is not otherwise possible. By setting its radius to 0, a cylinder becomes a line. Setting a color for each point of the cylinder or polycylinder grants you the equivalent of color-interpolated polylines.

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_polycyl_polyline.cpp
		   :start-after: //! [021102_d]
		   :end-before: //! [021102_d]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_polycyl_polyline.cs
		   :start-after: //! [021102_d]
		   :end-before: //! [021102_d]
		   
.. image:: images/polycylinder_line.png

*A polycylinder rendered as a line (with increased edge weight for clarity)*


