style-guidelines.html 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8"/>
  5. <title>libigl</title>
  6. <meta name="author" content="Alec Jacobson and Daniele Panozzo and others"/>
  7. <link type="text/css" rel="stylesheet" href="tutorial/style.css"/>
  8. <script type='text/javascript' src='http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'></script>
  9. <link rel='stylesheet' href='http://yandex.st/highlightjs/7.3/styles/default.min.css'>
  10. <script src='http://yandex.st/highlightjs/7.3/highlight.min.js'></script>
  11. <script>hljs.initHighlightingOnLoad();</script>
  12. </head>
  13. <body>
  14. <h1 id="libiglstyleguidelines">Libigl Style Guidelines</h1>
  15. <p>This library is shared by many people. This document highlights some style
  16. guidelines for <em>developers</em> of the library, but also act as best-practices for
  17. users.</p>
  18. <blockquote>
  19. <p>This is still a work in progress and will likely grow in the near future.</p>
  20. </blockquote>
  21. <h2 id="filefunction">One function, one .h/.cpp pair</h2>
  22. <p>The structure of libigl is very flat and function-based. For every
  23. function/sub-routine create a single .h and .cpp file. For example, if you have
  24. a function that determines connected components from a face list <code>F</code> you would
  25. create the header <code>connected_components.h</code> and <code>connected_components.cpp</code> and the only
  26. function defined should be <code>void connected_components(const ... F, ... C)</code>. If the
  27. implementation of <code>connected_components</code> requires a subroutine to compute an
  28. adjacency matrix then <em>create another pair</em> <code>adjacency_matrix.h</code> and
  29. <code>adjacency_matrix.cpp</code> with a single function <code>void adjacency_matrix(const ... F, ...
  30. A)</code>.</p>
  31. <h3 id="example">Example</h3>
  32. <p>Here is an example function that would be defined in
  33. <code>include/igl/example_fun.h</code> and implemented in <code>include/igl/example_fun.cpp</code>.</p>
  34. <h4 id="example_fun.h"><code>example_fun.h</code></h4>
  35. <pre><code class="cpp">// This file is part of libigl, a simple c++ geometry processing library.
  36. //
  37. // Copyright (C) 2015 [Your Name] [your email address]
  38. //
  39. // This Source Code Form is subject to the terms of the Mozilla Public License
  40. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  41. // obtain one at http://mozilla.org/MPL/2.0/
  42. #ifndef IGL_EXAMPLE_FUN_H
  43. #define IGL_EXAMPLE_FUN_H
  44. #include &quot;igl_inline.h&quot;
  45. namespace igl
  46. {
  47. // This is an example of a function, it takes a templated parameter and
  48. // shovels it into cout
  49. //
  50. // Templates:
  51. // T type that supports
  52. // Input:
  53. // input some input of a Printable type
  54. // Returns true for the sake of returning something
  55. template &lt;typename Printable&gt;
  56. IGL_INLINE bool example_fun(const Printable &amp; input);
  57. }
  58. #ifndef IGL_STATIC_LIBRARY
  59. # include &quot;example_fun.cpp&quot;
  60. #endif
  61. #endif
  62. </code></pre>
  63. <h4 id="example_fun.cpp"><code>example_fun.cpp</code></h4>
  64. <pre><code>// This file is part of libigl, a simple c++ geometry processing library.
  65. //
  66. // Copyright (C) 2015 [Your Name] [your email address]
  67. //
  68. // This Source Code Form is subject to the terms of the Mozilla Public License
  69. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  70. // obtain one at http://mozilla.org/MPL/2.0/
  71. #include &quot;igl/example_fun.h&quot;
  72. #include &lt;iostream&gt;
  73. template &lt;typename Printable&gt;
  74. IGL_INLINE bool igl::example_fun(const Printable &amp; input)
  75. {
  76. using namespace std;
  77. cout&lt;&lt;&quot;example_fun: &quot;&lt;&lt;input&lt;&lt;endl;
  78. return true;
  79. }
  80. #ifdef IGL_STATIC_LIBRARY
  81. template bool igl::example_fun&lt;double&gt;(const double&amp; input);
  82. template bool igl::example_fun&lt;int&gt;(const int&amp; input);
  83. #endif
  84. </code></pre>
  85. <h3 id="avoidstatichelperfunctions">Avoid static &#8220;helper&#8221; functions</h3>
  86. <p>Strive to encapsulate sub-functions that could possibly be useful outside of
  87. the implementation of your current function. This might mean abstracting the
  88. interface a bit. If it doesn&#8217;t dramatically effect performance then create a
  89. new pair of .h/.cpp files with this sub-function.</p>
  90. <h4 id="lambdafunctions">Lambda functions</h4>
  91. <p>If encapsulation in a separate file is not possible or does not make sense,
  92. then avoid crowding the namespace by creating lambda functions within the
  93. function implmentation.</p>
  94. <h3 id="avoidhelperclasses">Avoid &#8220;helper&#8221; classes</h3>
  95. <p>Libigl is built around the high-performance paradigm of &#8220;struct of arrays&#8221;
  96. rather than &#8220;array of structs&#8221;. The way we achieve this is to avoid classes and
  97. pass &#8220;basic types&#8221; directly. The price we pay is long function interfaces, but
  98. this increases code reuse dramatically. A &#8220;basic type&#8221; in our context is a
  99. Eigen type, stl type, or basic C type.</p>
  100. <h2 id="headerdocumentation">Header Documentation</h2>
  101. <p>Each function prototype should be well documented in its corresponding .h
  102. header file. A typical documentation consists of four parts:</p>
  103. <pre><code class="cpp">// [A human readable description of what the function does.]
  104. //
  105. // Inputs:
  106. // [variable name of first (const) input] [dimensions and
  107. // description of this input variable]
  108. // [variable name of second (const) input] [dimensions and
  109. // description of this input variable]
  110. // ...
  111. // Outputs:
  112. // [variable name of first output ] [dimensions and
  113. // description of this output variable]
  114. // [variable name of second output ] [dimensions and
  115. // description of this output variable]
  116. // ...
  117. // Returns [description of return value]
  118. </code></pre>
  119. <h3 id="example">Example</h3>
  120. <p>For example the header <code>barycenter.h</code></p>
  121. <pre><code>// Computes the barycenter of every simplex
  122. //
  123. // Inputs:
  124. // V #V x dim matrix of vertex coordinates
  125. // F #F x simplex_size matrix of indices of simplex corners into V
  126. // Output:
  127. // BC #F x dim matrix of 3d vertices
  128. //
  129. </code></pre>
  130. <h2 id="constinputs">Const inputs</h2>
  131. <p>All input parameters should be demarcated <code>const</code>. If an input is also an
  132. output than consider exposing two parameters (one <code>const</code>) or be sure to list
  133. the variable under both <code>// Inputs:</code> and <code>// Outputs:</code> in the header comments.</p>
  134. <h2 id="referenceparameters">Reference parameters</h2>
  135. <p>All but simple types should be passed by reference (e.g. <code>Matrix &amp; mat</code>) rather
  136. than pointers (e.g. <code>Matrix * mat</code>) or value (e.g. <code>Matrix mat</code>).</p>
  137. <h2 id="returnsvsoutputparameters">Returns vs output parameters</h2>
  138. <p>All functions should be implemented with at least one overload that has a
  139. <code>void</code> or simple return type (e.g. <code>bool</code> on success/failure). With this
  140. implementation its then possible to write an overload that returns a single
  141. output.</p>
  142. <p>For example:</p>
  143. <pre><code class="cpp">template &lt;typename Atype&gt;
  144. void adjacency_matrix(const ... &amp; F, Eigen::SparseMatrix&lt;AType&gt; &amp; A);
  145. template &lt;typename Atype&gt;
  146. Eigen::SparseMatrix&lt;Atype&gt; adjacency_matrix(const ... &amp; F);
  147. </code></pre>
  148. <h2 id="functionnamingconventions">Function naming conventions</h2>
  149. <p>Functions (and <a href="#filefunction">thus also files</a>) should have simple,
  150. descriptive names using lowercase letters and underscores between words. Avoid
  151. unnecessary prefaces. For example, instead of <code>compute_adjacency_matrix</code>,
  152. <code>construct_adjacency_matrix</code>, <code>extract_adjacency_matrix</code>,
  153. <code>get_adjacency_matrix</code>, or <code>set_adjacency_matrix</code> just call the function
  154. <code>adjacency_matrix</code>.</p>
  155. <h2 id="variablenamingconventions">Variable naming conventions</h2>
  156. <p>Libigl prefers short (even single character) variable names <em>with heavy
  157. documentation</em> in the comments in the header file or above the declaration of
  158. the function. When possible use <code>V</code> to mean a list of vertex positions and <code>F</code>
  159. to mean a list of faces/triangles.</p>
  160. <h2 id="classnamingconventions">Class naming conventions</h2>
  161. <p>Classes should be avoided. When naming a class use CamelCase (e.g.
  162. SortableRow.h).</p>
  163. <h2 id="enumnamingconvertion">Enum naming convertion</h2>
  164. <p>Enums types should be placed in the appropriate <code>igl::</code> namespace and should be
  165. named in CamelCase (e.g. <code>igl::SolverStatus</code>) and instances should be named in
  166. ALL_CAPS with underscores between words and prefaced with the name of the enum.
  167. For example:</p>
  168. <pre><code class="cpp">namespace igl
  169. {
  170. enum SolverStatus
  171. {
  172. // Good
  173. SOLVER_STATUS_CONVERGED = 0,
  174. // OK
  175. SOLVER_STATUS_MAX_ITER = 1,
  176. // Bad
  177. SOLVER_STATUS_ERROR = 2,
  178. NUM_SOLVER_STATUSES = 3,
  179. };
  180. };
  181. </code></pre>
  182. <h3 id="exceptionforfileio">Exception for file IO</h3>
  183. <p>For legacy reasons, file reading and writing functions use a different naming
  184. convention. A functions reading a <code>.xyz</code> file should be named <code>readXYZ</code> and a
  185. function writing <code>.xyz</code> files should be names <code>writeXYZ</code>.</p>
  186. <h2 id="usingnamespace...inglobalscope"><code>using namespace ...</code> in global scope</h2>
  187. <p>Writing <code>using namespace std;</code>, <code>using namespace Eigen;</code> etc. outside of a
  188. global scope is strictly forbidden. Place these lines at the top of each
  189. function instead.</p>
  190. <h2 id="namespacesandexternaldependencies">Namespaces and external dependencies</h2>
  191. <p>Functions in the main library (directly in <code>include/igl</code>) should only depend on
  192. Eigen and stl. These functions should have the <code>igl::</code> namespace.</p>
  193. <p>Functions with other dependencies should be placed into
  194. appropriate sub-directories (e.g. if <code>myfunction</code> depends on tetgen then create
  195. <code>igl/copyleft/tetgen/myfunction.h</code> and <code>igl/copyleft/tetgen/myfunction.cpp</code> and give the function
  196. the namespace <code>igl::copyleft::tetgen::myfunction</code>.</p>
  197. <h3 id="copyleftsubdirectorynamespace">copyleft subdirectory/namespace</h3>
  198. <p>Dependencies that require users of libigl to release their projects open source
  199. (e.g. GPL) are considered aggressively &#8220;copyleft&#8221; and should be placed in the
  200. <code>include/igl/copyleft/</code> sub-directory and <code>igl::copyleft::</code> namespace.</p>
  201. <h2 id="assertions">Assertions</h2>
  202. <p>Be generous with assertions and always identify the assertion with strings:</p>
  203. <pre><code class="cpp">assert(m &lt; n &amp;&amp; &quot;m must be less than n&quot;);
  204. </code></pre>
  205. <h2 id="ifndefincludeguard">ifndef include guard</h2>
  206. <p>Every header file should be wrapped in an <code>#ifndef</code> compiler directive. The
  207. name of the guard should be in direct correspondence with the path of the .h
  208. file. For example, <code>include/igl/copyleft/tetgen/tetrahedralize.h</code> should be</p>
  209. <pre><code class="cpp">#ifndef IGL_COPYLEFT_TETGEN_TETRAHEDRALIZE_H
  210. #define IGL_COPYLEFT_TETGEN_TETRAHEDRALIZE_H
  211. ...
  212. #endif
  213. </code></pre>
  214. <h2 id="spacesvs.tabsindentation">Spaces vs. tabs indentation</h2>
  215. <p>Do not use tabs. Use 2 spaces for each indentation level.</p>
  216. <h2 id="maxlinelength">Max line length</h2>
  217. <p>Limit lines to 80 characters. Break up long lines into many operations (this
  218. also helps performance).</p>
  219. <h2 id="includeorder">Include order</h2>
  220. <p><code>#include</code> directives at the top of a .h or .cpp file should be sorted
  221. according to a simple principle: place headers of files most likely to be
  222. edited by you first. This means for
  223. <code>include/igl/copyleft/tetgen/tetrahedralize.cpp</code> you might see</p>
  224. <pre><code class="cpp">// [Includes of headers in this directory]
  225. #include &quot;tetrahedralize.h&quot;
  226. #include &quot;mesh_to_tetgenio.h&quot;
  227. #include &quot;tetgenio_to_tetmesh.h&quot;
  228. // [Includes of headers in this project]
  229. #include &quot;../../matrix_to_list.h&quot;
  230. #include &quot;../../list_to_matrix.h&quot;
  231. #include &quot;../../boundary_facets.h&quot;
  232. // [Includes of headers of related projects]
  233. #include &lt;Eigen/Core&gt;
  234. // [Includes of headers of standard libraries]
  235. #include &lt;cassert&gt;
  236. #include &lt;iostream&gt;
  237. </code></pre>
  238. <h2 id="placementofincludes">Placement of includes</h2>
  239. <p>Whenever possible <code>#include</code> directives should be placed in the <code>.cpp</code>
  240. implementation file rather than the <code>.h</code> header file.</p>
  241. <h2 id="eigentemplates">Eigen templates</h2>
  242. </body>
  243. </html>