Repository: fury-gl/fury

Issue:
Cylinder primitive generation
It would be good to have a function that generates the vertices and triangles of a cylinder. 

Primitives examples are available [here](https://github.com/fury-gl/fury/blob/master/fury/primitive.py).

Discussion:

Patch:
diff --git a/docs/source/posts/2020/2020-08-09-week-11-soham.rst b/docs/source/posts/2020/2020-08-09-week-11-soham.rst
deleted file mode 100644
index b202d9be..00000000
--- a/docs/source/posts/2020/2020-08-09-week-11-soham.rst
+++ /dev/null
@@ -1,41 +0,0 @@
-Chain Simulation, Scrollbar Refactor, Tutorial Update.
-======================================================
-
-.. post:: August 09 2020
-   :author: Soham Biswas
-   :tags: google
-   :category: gsoc
-
-Hello and welcome to my 11th weekly check-in. In this blog I will be discussing my progress with multiple topics related to physics and ui components. I was actively working on a couple of things, specifically Joint simulations in pyBullet and scrollbar UI component. I also took up the responsibility to complete an incomplete Pull Request which was pending for quite a while. The official repository of my sub-org can be found `here <https://github.com/fury-gl/fury/>`_.
-
-What did you do this week?
---------------------------
-The first thing that I did this week was to figure out joint simulations in pybullet. Due to lack of proper documentation I was not aware that Joints are kept stiff by default, hence I had no idea what was wrong with my simulations. Thankfully, while I was browsing pybullet forums, I found this `post <https://pybullet.org/Bullet/phpBB3/viewtopic.php?f=24&t=13035>`_ regarding rope simulations when I realized that I had to explicitly set the friction force to prevent stiffness among the Joints. Keeping this point in mind I was able to simulate the following Chain of hexagonal prisms:
-
-.. image:: https://user-images.githubusercontent.com/29832615/89737601-b7613100-da8f-11ea-947f-a96c66caefae.gif
-
-This week I was mainly supposed to  work on refactoring scrollbars as a standalone component. I have made some progress for now. I am able to render the scrollbars properly, with proper size, orientation and color but I am having some issues regarding its scrolling callbacks. I need to look further into it. Here's a brief glimpse:
-
-.. image:: https://user-images.githubusercontent.com/29832615/89738159-28a2e300-da94-11ea-9167-e825f82edf98.png
-
-This particular `PR <https://github.com/fury-gl/fury/pull/208>`_ by a fellow contributor was pending for quite a while, so I decided to look into it and complete it. The objective of the PR was to add examples for the ``CheckBox`` and ``RadioButton`` UI components, but the problem was that the objects were not rendered using FURY API in the tutorial, so I decided to complete that. It was already a well made tutorial. I only had to replace the appropriate functions with FURY's API calls.
-
-The ``CheckBox`` tutorial:
-
-.. image:: https://user-images.githubusercontent.com/29832615/89438967-20326b80-d767-11ea-8f47-e7711e900c9f.gif
-
-There's still some internal issues while updating the colors of the cube which is currently being worked on by my mentors.
-
-The ``RadioButton`` tutorial:
-
-.. image:: https://user-images.githubusercontent.com/29832615/89438999-2e808780-d767-11ea-8b08-2a36a05294bc.gif
-
-What is coming up next week?
-----------------------------
-Next week I will continue working on the scrollbar component and try to fix the issues that I am having with its callbacks. I will also try to work on the wrecking ball simulation.
-
-Did you get stuck anywhere?
----------------------------
-Apart from the scrollbar callbacks and stiff joints, I did not face any major issues.
-
-``Thank you for reading, see you next week!!``
diff --git a/docs/source/posts/2020/2020-08-16-week-12-soham.rst b/docs/source/posts/2020/2020-08-16-week-12-soham.rst
deleted file mode 100644
index 1cec7f84..00000000
--- a/docs/source/posts/2020/2020-08-16-week-12-soham.rst
+++ /dev/null
@@ -1,38 +0,0 @@
-Wrecking Ball Simulation, Scrollbars Update, Physics Tutorials.
-===============================================================
-
-.. post:: August 16 2020
-   :author: Soham Biswas
-   :tags: google
-   :category: gsoc
-
-Hello and welcome to my 12th weekly check-in. In this blog I will be discussing my progress with the wrecking ball simulation and my scrollbar separation work. Apart from this I have also finalized the physics simulation tutorials and have created a Pull Request to finally get it merged with the official repository. The official repository of my sub-org can be found `here <https://github.com/fury-gl/fury/>`_.
-
-What did you do this week?
---------------------------
-This week I was mainly focusing on the wrecking ball simulation. This simulation is basically the combination of chain simulation and brick wall simulation. A sphere attached to a chain smashes a "NxNxN" brick wall. The simulation is as follows:
-
-.. image :: https://user-images.githubusercontent.com/29832615/90336291-84232280-dff8-11ea-869b-21a99b203c31.gif
-
-There's a rendering bug with the cylinders because of which the chain segments look weird. My mentors confirmed that this bug originated from VTK's `cylinder source` method and they are currently working on it to fix it. The simulation will render correctly once that bug is fixed.
-
-Regarding the scrollbar separation task, I was able to fix those callback issues that I was facing. The mouse callbacks on the scrollbar now work correctly:
-
-.. image :: https://user-images.githubusercontent.com/29832615/90337280-1af2dd80-dfff-11ea-94c4-508121307583.gif
-
-I have also created a pull request to add the following physics simulations with proper documentation to the main repository:
-
-- Brick Wall Simulation
-- Ball Collision Simulation
-- Chain Simulation
-- Wrecking Ball Simulation
-
-What is coming up next week?
-----------------------------
-Currently I am a bit confused with the implementation of scrollbars with UI components. I had a meeting with my mentor and he decided to help me out with this. So most probably I will be working with the scrollbar component and its implementation. Next week will also be the final week for GSoC 2020 before the evaluations start so I would work on getting the final documentation and formalities ready.
-
-Did you get stuck anywhere?
----------------------------
-Apart from the scrollbar implementation idea, I did not face any major issues.
-
-``Thank you for reading, see you next week!!``
diff --git a/docs/source/posts/2020/2020-08-23-week-13-soham.rst b/docs/source/posts/2020/2020-08-23-week-13-soham.rst
deleted file mode 100644
index f7ac9b2b..00000000
--- a/docs/source/posts/2020/2020-08-23-week-13-soham.rst
+++ /dev/null
@@ -1,35 +0,0 @@
-Part of the Journey is the end unless its Open Source!
-======================================================
-
-.. post:: August 23 2020
-   :author: Soham Biswas
-   :tags: google
-   :category: gsoc
-
-Hello and welcome to my final weekly check-in. Today officially marks the end of  the coding period for GSoC 2020. I enjoyed every bit of it. This was a life-changing experience for me and now I observe and interpret everything from a different perspective altogether. I have grown into a better developer and a person since GSoC. I would like to thank all my mentors and especially Serge for his immense support and mentorship. I would love to contribute to fury even after GSoC is over but unfortunately my semester break is over so I wont be as active as I was during the summer.
-
-Now, regarding work I will be sharing my progress with the File Dialog UI component. The official repository of my sub-org can be found `here <https://github.com/fury-gl/fury/>`_.
-
-What did you do this week?
---------------------------
-This week I worked on the File Dialog UI component. Fury previously had a FileMenu component which could browse through the file system but we needed a dialog like implementation for it so that its easier for the users to read and write files during runtime. I tried implementing a simple design for it. It specifically has two modes, one for saving files and the other for writing files. The implementation can be demonstrated as follows:
-
-Open Dialog:
-^^^^^^^^^^^^
-
-.. image :: https://user-images.githubusercontent.com/29832615/90978632-df12c780-e56c-11ea-8517-6243ea06bdd2.gif
-
-Save Dialog:
-^^^^^^^^^^^^
-
-.. image :: https://user-images.githubusercontent.com/29832615/90978638-eafe8980-e56c-11ea-835a-3a82ccee2973.gif
-
-What is coming up next week?
-----------------------------
-Next week I will start with my final GSoC documentation and code submission. I will also try to implement the tests and tutorials for File Dialog or any further changes requested by my mentors. If I am not able to finish it within the next week, I will get it done after GSoC.
-
-Did you get stuck anywhere?
----------------------------
-I did not face any major issues this week.
-
-``Thank you all for your love and support. ❤️😄``
diff --git a/docs/source/posts/2020/2020-08-24-final-work-soham.rst b/docs/source/posts/2020/2020-08-24-final-work-soham.rst
deleted file mode 100644
index d6aee15b..00000000
--- a/docs/source/posts/2020/2020-08-24-final-work-soham.rst
+++ /dev/null
@@ -1,235 +0,0 @@
-.. image:: https://developers.google.com/open-source/gsoc/resources/downloads/GSoC-logo-horizontal.svg
-   :height: 50
-   :align: center
-   :target: https://summerofcode.withgoogle.com/projects/#6653942668197888
-
-.. image:: https://www.python.org/static/community_logos/python-logo.png
-   :width: 40%
-   :target: https://blogs.python-gsoc.org/en/nibba2018s-blog/
-
-.. image:: https://python-gsoc.org/logos/FURY.png
-   :width: 25%
-   :target: https://fury.gl/latest/community.html
-
-Google Summer of Code Final Work Product
-========================================
-
-.. post:: August 24 2020
-   :author: Soham Biswas
-   :tags: google
-   :category: gsoc
-
--  **Name:** Soham Biswas
--  **Organisation:** Python Software Foundation
--  **Sub-Organisation:** FURY
--  **Project:** `FURY - Create new UI Widgets & Physics Engine
-   Integration <https://github.com/fury-gl/fury/wiki/Google-Summer-of-Code-2020>`_
-
-Proposed Objectives
--------------------
-
--  ComboBox
--  Tab UI
--  File Dialog Improvements
-
-Modified Objectives
--------------------
-
--  Combobox
--  Tab UI
--  File Dialog Improvements
--  Double Click Callback
--  TextBlock2D Improvements
--  Scrollbars as a Standalone Component
--  Physics Engine Integration
-
-Objectives Completed
---------------------
-
--  **ComboBox2D UI Component**
-
-   A combobox is a commonly used graphical user interface widget.
-   Traditionally, it is a combination of a drop-down list or list box and a
-   single-line textbox, allowing the user to select a value from the list.
-   The term "combo box" is sometimes used to mean "drop-down list".
-   Respective components, tests and tutorials were created.
-
-   *Pull Requests:*
-
-   -  **Combobox UI component:** https://github.com/fury-gl/fury/pull/240
-   -  **Combobox UI Tutorial:** https://github.com/fury-gl/fury/pull/246
-
--  **Tab UI Component**
-
-   In interface design, a tabbed document interface or Tab is a graphical
-   control element that allows multiple documents or panels to be contained
-   within a single window, using tabs as a navigational widget for
-   switching between sets of documents. Respective components, tests and
-   tutorials were created.
-
-   *Pull Requests:*
-
-   -  **Tab UI component:** https://github.com/fury-gl/fury/pull/252
-   -  **Tab UI tutorial:** https://github.com/fury-gl/fury/pull/275
-
--  **Double Click Callback**
-
-   Double click callbacks aren't implemented in VTK by default so they need
-   to be implemented manually. With my mentor's help I was able to
-   implement double click callbacks for all the three mouse buttons
-   successfully.
-
-   *Pull Requests:*
-
-   -  **Adding Double Click Callback:**
-      https://github.com/fury-gl/fury/pull/231
-
--  **TextBlock2D Improvements**
-
-   The previous implementation of ``TextBlock2D`` was lacking a few
-   features such as size arguments and text overflow. There was no specific
-   way to create Texts occupying a said height or width area. Apart from
-   that UI components like ``ListBoxItem2D``, ``FileMenu2D`` etc had an
-   issue where text would overflow from their specified width. In order to
-   tackle these problems, a modification was done to ``TextBlock2D`` to
-   accept size as an argument and a new method was added to clip
-   overflowing text based on a specified width and to replace the
-   overflowing characters with ``...``.
-
-   *Pull Requests:*
-
-   -  **Setting Bounding Box for TextBlock2D:**
-      https://github.com/fury-gl/fury/pull/248
-   -  **Clip Text Overflow:** https://github.com/fury-gl/fury/pull/268
-
--  **Physics Engine Integration**
-
-   Optional support for Physics engine integration of Pybullet was added to
-   Fury. Pybullet's engine was used for the simulations and FURY was used
-   for rendering the said simulations. Exhaustive examples were added to
-   demonstrate various types of physics simulations possible using pybullet
-   and fury. The said examples are as follows:
-
-   -  Brick Wall Simulation
-
-      -  Explains how to render and simulate external forces, objects and
-         gravity.
-
-   -  Ball Collision Simulation
-
-      -  Explains how collisions work and how to detect said collisions.
-
-   -  Chain Simulation
-
-      -  Explains how to render and simulate joints.
-
-   -  Wrecking Ball Simulation
-
-      -  A more complicated simulation that combines concepts explained by
-         the other examples.
-
-   Apart from that, a document was created to explain the integration
-   process between pybullet and fury in detail.
-
-   *Pull Requests:*
-
-   -  **Physics Simulation Examples:**
-      https://github.com/fury-gl/fury/pull/287
-   -  **Fury-Pybullet Integration Docs:**
-      https://docs.google.com/document/d/1XJcG1TL5ZRJZDyi8V76leYZt_maxGp0kOB7OZIxKsTA/edit?usp=sharing
-
-Objectives in Progress
-----------------------
-
--  **Scrollbars as a standalone component**
-
-   The previous implementation of scrollbars were hard coded into
-   ``ListBox2D``. Therefore, it was not possible to use scrollbars with any
-   other UI component. Apart from that, scrollbars in terms of design were
-   limited. Creating a horizontal scrollbar was not possible. The objective
-   of this PR is to make scrollbars separate so that other UI elements can
-   also make use of it.
-
-   Currently, the skeletal and design aspects of the scrollbars are
-   implemented but the combination of scrollbars with other UI components
-   are still in progress.
-
-   *Pull Requests:*
-
-   -  **Scrollbars as a Standalone API:**
-      https://github.com/fury-gl/fury/pull/285
-
--  **File Dialog Improvements**
-
-   Currently, we have access to ``FileMenu2D`` which allows us to navigate
-   through the filesystem but it does not provide a user friendly Dialog to
-   read and write files in Fury. Hence the idea is to create a file dialog
-   which can easily open or save file at runtime. As of now, ``Open`` and
-   ``Save`` operations are implemented. Corresponding tests and tutorials
-   are in progress.
-
-   *Pull Requests:*
-
-   -  **File Dialog UI component:**
-      https://github.com/fury-gl/fury/pull/294
-
-Other Objectives
-----------------
-
--  **Radio Checkbox Tutorial using FURY API**
-
-   The objects for Radio button and Checkbox tutorial were rendered using
-   VTK's method by a fellow contributor so I decided to replace them with
-   native FURY API. The methods were rewritten keeping the previous commits
-   intact.
-
-   *Pull Requests:*
-
-   -  **Radio Checkbox tutorial using FURY API:**
-      https://github.com/fury-gl/fury/pull/281
-
--  **GSoC weekly Blogs**
-
-   Weekly blogs were added for FURY's Website.
-
-   *Pull Requests:*
-
-   -  **First & Second Evaluation:**
-      https://github.com/fury-gl/fury/pull/272
-   -  **Third Evaluation:** https://github.com/fury-gl/fury/pull/286
-
-Timeline
---------
-
-+-----------------------+------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+
-| Date                  | Description                                                      | Blog Link                                                                                          |
-+=======================+==================================================================+====================================================================================================+
-| Week 1(30-05-2020)    | Welcome to my GSoC Blog!!                                        | `Weekly Check-in #1 <https://blogs.python-gsoc.org/en/nibba2018s-blog/weekly-check-in-1-5/>`__     |
-+-----------------------+------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+
-| Week 2(07-06-2020)    | First Week of Coding!!                                           | `Weekly Check-in #2 <https://blogs.python-gsoc.org/en/nibba2018s-blog/weekly-check-in-2-3/>`__     |
-+-----------------------+------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+
-| Week 3(14-06-2020)    | ComboBox2D Progress!!                                            | `Weekly Check-in #3 <https://blogs.python-gsoc.org/en/nibba2018s-blog/weekly-check-in-3-4/>`__     |
-+-----------------------+------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+
-| Week 4(21-06-2020)    | TextBlock2D Progress!!                                           | `Weekly Check-in #4 <https://blogs.python-gsoc.org/en/nibba2018s-blog/weekly-check-in-4-4/>`__     |
-+-----------------------+------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+
-| Week 5(28-06-2020)    | May the Force be with you!!                                      | `Weekly Check-in #5 <https://blogs.python-gsoc.org/en/nibba2018s-blog/weekly-check-in-5-4/>`__     |
-+-----------------------+------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+
-| Week 6(05-07-2020)    | Translation, Reposition, Rotation.                               | `Weekly Check-in #6 <https://blogs.python-gsoc.org/en/nibba2018s-blog/weekly-check-in-6-7/>`__     |
-+-----------------------+------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+
-| Week 7(12-07-2020)    | Orientation, Sizing, Tab UI.                                     | `Weekly Check-in #7 <https://blogs.python-gsoc.org/en/nibba2018s-blog/weekly-check-in-7-4/>`__     |
-+-----------------------+------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+
-| Week 8(19-07-2020)    | ComboBox2D, TextBlock2D, ClippingOverflow.                       | `Weekly Check-in #8 <https://blogs.python-gsoc.org/en/nibba2018s-blog/weekly-check-in-8-2/>`__     |
-+-----------------------+------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+
-| Week 9(26-07-2020)    | Tab UI, TabPanel2D, Tab UI Tutorial.                             | `Weekly Check-in #9 <https://blogs.python-gsoc.org/en/nibba2018s-blog/weekly-check-in-9-4/>`__     |
-+-----------------------+------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+
-| Week 10(02-08-2020)   | Single Actor, Physics, Scrollbars.                               | `Weekly Check-in #10 <https://blogs.python-gsoc.org/en/nibba2018s-blog/weekly-check-in-10-2/>`__   |
-+-----------------------+------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+
-| Week 11(09-08-2020)   | Chain Simulation, Scrollbar Refactor,Tutorial Update.            | `Weekly Check-in #11 <https://blogs.python-gsoc.org/en/nibba2018s-blog/weekly-check-in-11-1/>`__   |
-+-----------------------+------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+
-| Week 12(16-08-2020)   | Wrecking Ball Simulation, ScrollbarsUpdate, Physics Tutorials.   | `Weekly Check-in #12 <https://blogs.python-gsoc.org/en/nibba2018s-blog/weekly-check-in-12/>`__     |
-+-----------------------+------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+
-| Week 13(23-08-2020)   | Part of the Journey is the end unless itsOpen Source!            | `Weekly Check-in #13 <https://blogs.python-gsoc.org/en/nibba2018s-blog/weekly-check-in-13/>`__     |
-+-----------------------+------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+
-
-Detailed weekly tasks and work done can be found
-`here <https://blogs.python-gsoc.org/en/nibba2018s-blog/>`__.
diff --git a/fury/primitive.py b/fury/primitive.py
index 922a6ca0..81b1aaf8 100644
--- a/fury/primitive.py
+++ b/fury/primitive.py
@@ -11,7 +11,6 @@ import math
 
 SCIPY_1_4_PLUS = LooseVersion(short_version) >= LooseVersion('1.4.0')
 
-
 SPHERE_FILES = {
     'symmetric362': pjoin(DATA_DIR, 'evenly_distributed_sphere_362.npz'),
     'symmetric642': pjoin(DATA_DIR, 'evenly_distributed_sphere_642.npz'),
@@ -182,7 +181,7 @@ def repeat_primitive(vertices, faces, centers, directions=None,
     directions = normalize_input(directions, 'directions')
     for pts, dirs in enumerate(directions):
         w = np.cos(0.5 * np.pi)
-        denom = np.linalg.norm(dirs/2.)
+        denom = np.linalg.norm(dirs / 2.)
         f = (np.sin(0.5 * np.pi) / denom) if denom else 0
         dirs = np.append((dirs / 2.) * f, w)
         rot = transform.Rotation.from_quat(dirs)
@@ -335,6 +334,7 @@ def prim_superquadric(roundness=(1, 1), sphere_name='symmetric362'):
     True
 
     """
+
     def _fexp(x, p):
         """Return a different kind of exponentiation."""
         return np.sign(x) * (np.abs(x) ** p)
@@ -609,22 +609,22 @@ def prim_octagonalprism():
     # to 7 decimal places
     two = float('{:.7f}'.format(math.sqrt(2)))
 
-    vertices = np.array([[-1, -(1+two), -1],
-                         [1, -(1+two), -1],
-                         [1, (1+two), -1],
-                         [-1, (1+two), -1],
-                         [-(1+two), -1, -1],
-                         [(1+two), -1, -1],
-                         [(1+two), 1, -1],
-                         [-(1+two), 1, -1],
-                         [-1, -(1+two), 1],
-                         [1, -(1+two), 1],
-                         [1, (1+two), 1],
-                         [-1, (1+two), 1],
-                         [-(1+two), -1, 1],
-                         [(1+two), -1, 1],
-                         [(1+two), 1, 1],
-                         [-(1+two), 1, 1]])
+    vertices = np.array([[-1, -(1 + two), -1],
+                         [1, -(1 + two), -1],
+                         [1, (1 + two), -1],
+                         [-1, (1 + two), -1],
+                         [-(1 + two), -1, -1],
+                         [(1 + two), -1, -1],
+                         [(1 + two), 1, -1],
+                         [-(1 + two), 1, -1],
+                         [-1, -(1 + two), 1],
+                         [1, -(1 + two), 1],
+                         [1, (1 + two), 1],
+                         [-1, (1 + two), 1],
+                         [-(1 + two), -1, 1],
+                         [(1 + two), -1, 1],
+                         [(1 + two), 1, 1],
+                         [-(1 + two), 1, 1]])
     triangles = np.array([[0, 8, 9],
                           [9, 1, 0],
                           [5, 13, 9],
@@ -670,25 +670,152 @@ def prim_frustum():
 
     """
     vertices = np.array([[-.5, -.5, .5],
-                        [.5, -.5, .5],
-                        [.5, .5, .5],
-                        [-.5, .5, .5],
-                        [-1, -1, -.5],
-                        [1, -1, -.5],
-                        [1, 1, -.5],
-                        [-1, 1, -.5]])
+                         [.5, -.5, .5],
+                         [.5, .5, .5],
+                         [-.5, .5, .5],
+                         [-1, -1, -.5],
+                         [1, -1, -.5],
+                         [1, 1, -.5],
+                         [-1, 1, -.5]])
     triangles = np.array([[4, 6, 5],
-                         [6, 4, 7],
-                         [0, 2, 1],
-                         [2, 0, 3],
-                         [4, 3, 0],
-                         [3, 4, 7],
-                         [7, 2, 3],
-                         [2, 7, 6],
-                         [6, 1, 2],
-                         [1, 6, 5],
-                         [5, 0, 1],
-                         [0, 5, 4]], dtype='u8')
+                          [6, 4, 7],
+                          [0, 2, 1],
+                          [2, 0, 3],
+                          [4, 3, 0],
+                          [3, 4, 7],
+                          [7, 2, 3],
+                          [2, 7, 6],
+                          [6, 1, 2],
+                          [1, 6, 5],
+                          [5, 0, 1],
+                          [0, 5, 4]], dtype='u8')
     vertices /= 2
     triangles = fix_winding_order(vertices, triangles, clockwise=True)
     return vertices, triangles
+
+
+def prim_cylinder(radius=0.5, height=1, sectors=36, capped=True):
+    """Return vertices and triangles for a cylinder.
+
+    Parameters
+    ----------
+    radius: float
+        Radius of the cylinder
+    height: float
+        Height of the cylinder
+    sectors: int
+        Sectors in the cylinder
+    capped: bool
+        Whether the cylinder is capped at both ends or open
+
+    Returns
+    -------
+    vertices: ndarray
+        vertices coords that compose our cylinder
+    triangles: ndarray
+        triangles that compose our cylinder
+    """
+
+    if not isinstance(sectors, int):
+        raise TypeError("Only integers are allowed for sectors parameter")
+    if not sectors > 7:
+        raise ValueError("Sectors parameter should be greater than 7")
+    sector_step = 2 * math.pi / sectors
+    unit_circle_vertices = []
+
+    # generate a unit circle on XY plane
+    for i in range(sectors + 1):
+        sector_angle = i * sector_step
+        unit_circle_vertices.append(math.cos(sector_angle))
+        unit_circle_vertices.append(0)
+        unit_circle_vertices.append(math.sin(sector_angle))
+
+    vertices = []
+    # generate vertices for a cylinder
+    for i in range(2):
+        h = -height / 2 + i * height
+        k = 0
+        for j in range(sectors + 1):
+            ux = unit_circle_vertices[k]
+            uz = unit_circle_vertices[k + 2]
+            # position vector
+            vertices.append(ux * radius)
+            vertices.append(h)
+            vertices.append(uz * radius)
+            k += 3
+
+    # base and top circle vertices
+    base_center_index = None
+    top_center_index = None
+
+    if capped:
+        base_center_index = int(len(vertices) / 3)
+        top_center_index = base_center_index + sectors + 1
+
+        for i in range(2):
+            h = -height / 2 + i * height
+            vertices.append(0)
+            vertices.append(h)
+            vertices.append(0)
+            k = 0
+            for j in range(sectors):
+                ux = unit_circle_vertices[k]
+                uz = unit_circle_vertices[k + 2]
+                # position vector
+                vertices.append(ux * radius)
+                vertices.append(h)
+                vertices.append(uz * radius)
+                k += 3
+
+    if capped:
+        vertices = (np.array(vertices).reshape(2 * (sectors + 1) + 2 * sectors + 2, 3))
+    else:
+        vertices = (np.array(vertices).reshape(2 * (sectors + 1), 3))
+
+    triangles = []
+    k1 = 0
+    k2 = sectors + 1
+
+    # triangles for the side surface
+    for i in range(sectors):
+        triangles.append(k1)
+        triangles.append(k2)
+        triangles.append(k1 + 1)
+
+        triangles.append(k2)
+        triangles.append(k2 + 1)
+        triangles.append(k1 + 1)
+        k1 += 1
+        k2 += 1
+
+    if capped:
+        k = base_center_index + 1
+        for i in range(sectors):
+            if i < sectors - 1:
+                triangles.append(base_center_index)
+                triangles.append(k)
+                triangles.append(k + 1)
+            else:
+                triangles.append(base_center_index)
+                triangles.append(k)
+                triangles.append(base_center_index + 1)
+            k += 1
+
+        k = top_center_index + 1
+        for i in range(sectors):
+            if i < sectors - 1:
+                triangles.append(top_center_index)
+                triangles.append(k + 1)
+                triangles.append(k)
+            else:
+                triangles.append(top_center_index)
+                triangles.append(top_center_index + 1)
+                triangles.append(k)
+            k += 1
+
+    if capped:
+        triangles = (np.array(triangles).reshape(4 * sectors, 3))
+    else:
+        triangles = (np.array(triangles).reshape(2 * sectors, 3))
+
+    return vertices, triangles


Test patch:
diff --git a/fury/tests/test_primitive.py b/fury/tests/test_primitive.py
index bc37e71c..bfae99ad 100644
--- a/fury/tests/test_primitive.py
+++ b/fury/tests/test_primitive.py
@@ -96,6 +96,28 @@ def test_superquadric_primitives():
     # TODO: We need to check some superquadrics shape
 
 
+def test_cylinder_primitive():
+    verts, faces = fp.prim_cylinder(radius=.5, height=1, sectors=10)
+    npt.assert_equal(verts.shape, (44, 3))
+    npt.assert_almost_equal(np.mean(verts), 0, decimal=1)
+    npt.assert_equal(verts.min(), -.5)
+    npt.assert_equal(verts.max(), .5)
+
+    # basic tests for triangle
+    npt.assert_equal(faces.shape, (40, 3))
+    npt.assert_equal(np.unique(np.concatenate(faces, axis=None)).tolist(),
+                     list(range(len(verts))))
+
+    verts, faces = fp.prim_cylinder(radius=.5, height=1, sectors=10, capped=False)
+    npt.assert_equal(verts.shape, (22, 3))
+    npt.assert_almost_equal(np.mean(verts), 0, decimal=1)
+    npt.assert_equal(verts.min(), -.5)
+    npt.assert_equal(verts.max(), .5)
+    npt.assert_equal(np.unique(np.concatenate(faces, axis=None)).tolist(),
+                     list(range(len(verts))))
+
+
+
 def test_repeat_primitive():
     # init variables
     verts, faces = fp.prim_square()