diff --git a/.clang-format b/.clang-format index 684ae7af..e4541757 100644 --- a/.clang-format +++ b/.clang-format @@ -4,7 +4,7 @@ AccessModifierOffset: 0 AlignAfterOpenBracket: Align AlignEscapedNewlines: 'Left' AlignOperands: 'true' -AlignTrailingComments: 'true' +AlignTrailingComments: 'false' AllowAllArgumentsOnNextLine: 'false' AllowAllParametersOfDeclarationOnNextLine: 'false' AllowShortFunctionsOnASingleLine: Empty @@ -29,7 +29,7 @@ SpaceAfterTemplateKeyword: 'false' SpaceBeforeParens: ControlStatements SpacesInAngles: 'false' SpaceInEmptyParentheses: false -Standard: Cpp11 +Standard: c++14 TabWidth: '4' UseTab: Never diff --git a/.clang-format-ignore b/.clang-format-ignore deleted file mode 100644 index dc369351..00000000 --- a/.clang-format-ignore +++ /dev/null @@ -1 +0,0 @@ -**/extern/* diff --git a/.github/workflows/make-changelog-md.sh b/.github/workflows/make-changelog-md.sh index 4c766887..b3e85bf3 100755 --- a/.github/workflows/make-changelog-md.sh +++ b/.github/workflows/make-changelog-md.sh @@ -7,4 +7,3 @@ pcregrep -M "^${tag}.*\n\^\^\^\^+.*\n(.*\n)+?(\^\^\^\^+|^---+)$" CHANGELOG.rst \ | tail -n +3 \ | head -n -2 \ | pandoc --from=rst --to=markdown - diff --git a/.github/workflows/style_check.yml b/.github/workflows/style_check.yml index c325dee7..97b5056d 100644 --- a/.github/workflows/style_check.yml +++ b/.github/workflows/style_check.yml @@ -2,47 +2,32 @@ name: Style check concurrency: group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true on: # Trigger on pull requests. pull_request: - # Trigger on pushes to the mainline branches and version tags. This prevents building commits + # Trigger on pushes to the mainline branches. This prevents building commits # twice when the pull request source branch is in the same repository. push: branches: - "master" - # Trigger on request. - workflow_dispatch: - jobs: - style_checks: - name: Run ${{ matrix.name }} + pre-commit: + name: Run pre-commit runs-on: ubuntu-latest - container: - image: glotzerlab/ci:2021.05-clang10_py38 - options: -u 0 - strategy: - matrix: - include: - - name: clang_format - command: ./run-clang-format.py -r . - - name: flake8 - command: flake8 - - name: yapf - command: yapf -d -r . - steps: - - uses: actions/checkout@v2.3.4 - - name: Execute ${{ matrix.name }} - run: ${{ matrix.command }} + - uses: actions/checkout@v2.3.4 + - uses: actions/setup-python@v2.2.2 + - uses: pre-commit/action@v2.0.2 + with: + extra_args: --all-files --hook-stage manual clang-format # This job is used to provide a single requirement for branch merge conditions. checks_complete: name: Style check - needs: [style_checks] + needs: [pre-commit] runs-on: ubuntu-latest steps: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..ebe024f9 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,34 @@ +ci: + skip: [clang-format] + +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: 'v3.4.0' + hooks: + - id: end-of-file-fixer + exclude_types: [svg] + - id: trailing-whitespace + exclude_types: [svg] + - id: check-json + - id: check-yaml + - id: check-case-conflict +- repo: https://github.com/google/yapf + rev: 'v0.31.0' + hooks: + - id: yapf +- repo: https://gitlab.com/pycqa/flake8 + rev: '3.9.1' + hooks: + - id: flake8 + args: + - --show-source + additional_dependencies: + - pep8-naming + - flake8-docstrings + - flake8-rst-docstrings +- repo: https://github.com/glotzerlab/pre-commit-clang-format + rev: v1.0.0 + hooks: + - id: clang-format + stages: [manual] + exclude: (?:^extern/) diff --git a/.vscode/settings.json b/.vscode/settings.json index fbf65a73..71bf41a8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -38,7 +38,7 @@ "dist": true, "doc/build": true, "doc/_build": true, - "*.sublime-workspace": true, + "*.sublime-workspace": true }, "cSpell.enableFiletypes": [ "cuda" @@ -86,5 +86,5 @@ "unmap", "verts", "yapf" - ], + ] } diff --git a/ContributorAgreement.md b/ContributorAgreement.md index 04944131..2061414d 100644 --- a/ContributorAgreement.md +++ b/ContributorAgreement.md @@ -26,4 +26,3 @@ you are authorized to sign this contract on behalf of your company (if identifie Based on the Sun Contributor Agreement - version 1.5. This document is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License http://creativecommons.org/licenses/by-sa/3.0/ - diff --git a/Doxyfile b/Doxyfile index 6748703c..8cdd07eb 100644 --- a/Doxyfile +++ b/Doxyfile @@ -51,7 +51,7 @@ PROJECT_BRIEF = "Python library for production quality ray tracing in r # pixels and the maximum width should not exceed 200 pixels. Doxygen will copy # the logo to the output directory. -PROJECT_LOGO = +PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is @@ -162,7 +162,7 @@ FULL_PATH_NAMES = YES # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. -STRIP_FROM_PATH = +STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # path mentioned in the documentation of a class, which tells the reader which @@ -171,7 +171,7 @@ STRIP_FROM_PATH = # specify the list of include paths that are normally passed to the compiler # using the -I flag. -STRIP_FROM_INC_PATH = +STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but # less readable) file names. This can be useful is your file systems doesn't @@ -238,13 +238,13 @@ TAB_SIZE = 4 # "Side Effects:". You can put \n's in the value part of an alias to insert # newlines. -ALIASES = +ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding "class=itcl::class" # will allow you to use the command class in the itcl::class meaning. -TCL_SUBST = +TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For @@ -291,7 +291,7 @@ OPTIMIZE_OUTPUT_VHDL = NO # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. -EXTENSION_MAPPING = +EXTENSION_MAPPING = # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable @@ -639,7 +639,7 @@ GENERATE_DEPRECATEDLIST= YES # sections, marked by \if ... \endif and \cond # ... \endcond blocks. -ENABLED_SECTIONS = +ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the # initial value of a variable or macro / define can have for it to appear in the @@ -681,7 +681,7 @@ SHOW_NAMESPACES = YES # by doxygen. Whatever the program writes to standard output is used as the file # version. For an example see the documentation. -FILE_VERSION_FILTER = +FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated @@ -694,7 +694,7 @@ FILE_VERSION_FILTER = # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE # tag is left empty. -LAYOUT_FILE = +LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib @@ -704,7 +704,7 @@ LAYOUT_FILE = # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # search path. See also \cite for info how to create references. -CITE_BIB_FILES = +CITE_BIB_FILES = #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages @@ -769,7 +769,7 @@ WARN_FORMAT = "$file:$line: $text" # messages should be written. If left blank the output is written to standard # error (stderr). -WARN_LOGFILE = +WARN_LOGFILE = #--------------------------------------------------------------------------- # Configuration options related to the input files @@ -861,7 +861,7 @@ RECURSIVE = YES # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = +EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded @@ -877,7 +877,7 @@ EXCLUDE_SYMLINKS = NO # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* -EXCLUDE_PATTERNS = +EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the @@ -888,13 +888,13 @@ EXCLUDE_PATTERNS = # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* -EXCLUDE_SYMBOLS = +EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include # command). -EXAMPLE_PATH = +EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and @@ -914,7 +914,7 @@ EXAMPLE_RECURSIVE = NO # that contain images that are to be included in the documentation (see the # \image command). -IMAGE_PATH = +IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program @@ -935,7 +935,7 @@ IMAGE_PATH = # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. -INPUT_FILTER = +INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the @@ -948,7 +948,7 @@ INPUT_FILTER = # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. -FILTER_PATTERNS = +FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will also be used to filter the input files that are used for @@ -963,14 +963,14 @@ FILTER_SOURCE_FILES = NO # *.ext= (so without naming a filter). # This tag requires that the tag FILTER_SOURCE_FILES is set to YES. -FILTER_SOURCE_PATTERNS = +FILTER_SOURCE_PATTERNS = # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. -USE_MDFILE_AS_MAINPAGE = +USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # Configuration options related to source browsing @@ -1082,7 +1082,7 @@ COLS_IN_ALPHA_INDEX = 5 # while generating the index headers. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. -IGNORE_PREFIX = +IGNORE_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the HTML output @@ -1126,7 +1126,7 @@ HTML_FILE_EXTENSION = .html # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_HEADER = +HTML_HEADER = # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard @@ -1136,7 +1136,7 @@ HTML_HEADER = # that doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_FOOTER = +HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style # sheet that is used by each HTML page. It can be used to fine-tune the look of @@ -1148,7 +1148,7 @@ HTML_FOOTER = # obsolete. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_STYLESHEET = +HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined # cascading style sheets that are included after the standard style sheets @@ -1161,7 +1161,7 @@ HTML_STYLESHEET = # list). For an example see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_EXTRA_STYLESHEET = +HTML_EXTRA_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note @@ -1171,7 +1171,7 @@ HTML_EXTRA_STYLESHEET = # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_EXTRA_FILES = +HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to @@ -1300,7 +1300,7 @@ GENERATE_HTMLHELP = NO # written to the html output directory. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. -CHM_FILE = +CHM_FILE = # The HHC_LOCATION tag can be used to specify the location (absolute path # including file name) of the HTML help compiler (hhc.exe). If non-empty, @@ -1308,7 +1308,7 @@ CHM_FILE = # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. -HHC_LOCATION = +HHC_LOCATION = # The GENERATE_CHI flag controls if a separate .chi index file is generated # (YES) or that it should be included in the master .chm file (NO). @@ -1321,7 +1321,7 @@ GENERATE_CHI = NO # and project file content. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. -CHM_INDEX_ENCODING = +CHM_INDEX_ENCODING = # The BINARY_TOC flag controls whether a binary table of contents is generated # (YES) or a normal table of contents (NO) in the .chm file. Furthermore it @@ -1352,7 +1352,7 @@ GENERATE_QHP = NO # the HTML output folder. # This tag requires that the tag GENERATE_QHP is set to YES. -QCH_FILE = +QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace @@ -1377,7 +1377,7 @@ QHP_VIRTUAL_FOLDER = doc # filters). # This tag requires that the tag GENERATE_QHP is set to YES. -QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom @@ -1385,21 +1385,21 @@ QHP_CUST_FILTER_NAME = # filters). # This tag requires that the tag GENERATE_QHP is set to YES. -QHP_CUST_FILTER_ATTRS = +QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: # http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. -QHP_SECT_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = # The QHG_LOCATION tag can be used to specify the location of Qt's # qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the # generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. -QHG_LOCATION = +QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be # generated, together with the HTML files, they form an Eclipse help plugin. To @@ -1532,7 +1532,7 @@ MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols # This tag requires that the tag USE_MATHJAX is set to YES. -MATHJAX_EXTENSIONS = +MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site @@ -1540,7 +1540,7 @@ MATHJAX_EXTENSIONS = # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. -MATHJAX_CODEFILE = +MATHJAX_CODEFILE = # When the SEARCHENGINE tag is enabled doxygen will generate a search box for # the HTML output. The underlying search engine uses javascript and DHTML and @@ -1600,7 +1600,7 @@ EXTERNAL_SEARCH = NO # Searching" for details. # This tag requires that the tag SEARCHENGINE is set to YES. -SEARCHENGINE_URL = +SEARCHENGINE_URL = # When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed # search data is written to a file for indexing by an external tool. With the @@ -1616,7 +1616,7 @@ SEARCHDATA_FILE = searchdata.xml # projects and redirect the results back to the right project. # This tag requires that the tag SEARCHENGINE is set to YES. -EXTERNAL_SEARCH_ID = +EXTERNAL_SEARCH_ID = # The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen # projects other than the one defined by this configuration file, but that are @@ -1626,7 +1626,7 @@ EXTERNAL_SEARCH_ID = # EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... # This tag requires that the tag SEARCHENGINE is set to YES. -EXTRA_SEARCH_MAPPINGS = +EXTRA_SEARCH_MAPPINGS = #--------------------------------------------------------------------------- # Configuration options related to the LaTeX output @@ -1690,7 +1690,7 @@ PAPER_TYPE = a4 # If left blank no extra packages will be included. # This tag requires that the tag GENERATE_LATEX is set to YES. -EXTRA_PACKAGES = +EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for the # generated LaTeX document. The header should contain everything until the first @@ -1706,7 +1706,7 @@ EXTRA_PACKAGES = # to HTML_HEADER. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_HEADER = +LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the # generated LaTeX document. The footer should contain everything after the last @@ -1717,7 +1717,7 @@ LATEX_HEADER = # Note: Only use a user-defined footer if you know what you are doing! # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_FOOTER = +LATEX_FOOTER = # The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined # LaTeX style sheets that are included after the standard style sheets created @@ -1728,7 +1728,7 @@ LATEX_FOOTER = # list). # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_EXTRA_STYLESHEET = +LATEX_EXTRA_STYLESHEET = # The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the LATEX_OUTPUT output @@ -1736,7 +1736,7 @@ LATEX_EXTRA_STYLESHEET = # markers available. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_EXTRA_FILES = +LATEX_EXTRA_FILES = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is # prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will @@ -1844,14 +1844,14 @@ RTF_HYPERLINKS = NO # default style sheet that doxygen normally uses. # This tag requires that the tag GENERATE_RTF is set to YES. -RTF_STYLESHEET_FILE = +RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an RTF document. Syntax is # similar to doxygen's config file. A template extensions file can be generated # using doxygen -e rtf extensionFile. # This tag requires that the tag GENERATE_RTF is set to YES. -RTF_EXTENSIONS_FILE = +RTF_EXTENSIONS_FILE = # If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code # with syntax highlighting in the RTF output. @@ -1896,7 +1896,7 @@ MAN_EXTENSION = .3 # MAN_EXTENSION with the initial . removed. # This tag requires that the tag GENERATE_MAN is set to YES. -MAN_SUBDIR = +MAN_SUBDIR = # If the MAN_LINKS tag is set to YES and doxygen generates man output, then it # will generate one additional man file for each entity documented in the real @@ -2009,7 +2009,7 @@ PERLMOD_PRETTY = YES # overwrite each other's variables. # This tag requires that the tag GENERATE_PERLMOD is set to YES. -PERLMOD_MAKEVAR_PREFIX = +PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor @@ -2050,7 +2050,7 @@ SEARCH_INCLUDES = YES # preprocessor. # This tag requires that the tag SEARCH_INCLUDES is set to YES. -INCLUDE_PATH = +INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the @@ -2058,7 +2058,7 @@ INCLUDE_PATH = # used. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -INCLUDE_FILE_PATTERNS = +INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that are # defined before the preprocessor is started (similar to the -D option of e.g. @@ -2068,7 +2068,7 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = +PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The @@ -2077,7 +2077,7 @@ PREDEFINED = # definition found in the source code. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -EXPAND_AS_DEFINED = +EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will # remove all references to function-like macros that are alone on a line, have @@ -2106,13 +2106,13 @@ SKIP_FUNCTION_MACROS = YES # the path). If a tag file is not located in the directory in which doxygen is # run, you must also specify the path to the tagfile here. -TAGFILES = +TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create a # tag file that is based on the input files it reads. See section "Linking to # external documentation" for more information about the usage of tag files. -GENERATE_TAGFILE = +GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES, all external class will be listed in # the class index. If set to NO, only the inherited external classes will be @@ -2161,14 +2161,14 @@ CLASS_DIAGRAMS = NO # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. -MSCGEN_PATH = +MSCGEN_PATH = # You can include diagrams made with dia in doxygen documentation. Doxygen will # then run dia to produce the diagram and insert it in the documentation. The # DIA_PATH tag allows you to specify the directory where the dia binary resides. # If left empty dia is assumed to be found in the default search path. -DIA_PATH = +DIA_PATH = # If set to YES the inheritance and collaboration graphs will hide inheritance # and usage relations if the target is undocumented or is not a class. @@ -2217,7 +2217,7 @@ DOT_FONTSIZE = 10 # the path where dot can find it using this tag. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_FONTPATH = +DOT_FONTPATH = # If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for # each documented class showing the direct and indirect inheritance relations. @@ -2361,26 +2361,26 @@ INTERACTIVE_SVG = NO # found. If left blank, it is assumed the dot tool can be found in the path. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_PATH = +DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the \dotfile # command). # This tag requires that the tag HAVE_DOT is set to YES. -DOTFILE_DIRS = +DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the \mscfile # command). -MSCFILE_DIRS = +MSCFILE_DIRS = # The DIAFILE_DIRS tag can be used to specify one or more directories that # contain dia files that are included in the documentation (see the \diafile # command). -DIAFILE_DIRS = +DIAFILE_DIRS = # When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the # path where java can find the plantuml.jar file. If left blank, it is assumed @@ -2388,12 +2388,12 @@ DIAFILE_DIRS = # generate a warning when it encounters a \startuml command in this case and # will not generate output for the diagram. -PLANTUML_JAR_PATH = +PLANTUML_JAR_PATH = # When using plantuml, the specified paths are searched for files specified by # the !include statement in a plantuml block. -PLANTUML_INCLUDE_PATH = +PLANTUML_INCLUDE_PATH = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes # that will be shown in the graph. If the number of nodes in a graph becomes diff --git a/doc/community.rst b/doc/community.rst index 47f447df..2fb00820 100644 --- a/doc/community.rst +++ b/doc/community.rst @@ -22,4 +22,3 @@ Contribute **fresnel** is an open source project. Contributions are accepted via pull request to `fresnel's github repository `_. Please review ``CONTRIBUTING.MD`` in the repository before starting development. You are encouraged to discuss your proposed contribution with the **fresnel** user and developer community who can help you design your contribution to fit smoothly into the existing ecosystem. - diff --git a/doc/indices.rst b/doc/indices.rst index 55eb7ccc..c98b14c3 100644 --- a/doc/indices.rst +++ b/doc/indices.rst @@ -7,4 +7,3 @@ Index * :ref:`genindex` * :ref:`modindex` - diff --git a/doc/module-camera.rst b/doc/module-camera.rst index 8aba2c99..9bebad1b 100644 --- a/doc/module-camera.rst +++ b/doc/module-camera.rst @@ -22,4 +22,3 @@ fresnel.camera :synopsis: Cameras. :members: :show-inheritance: - diff --git a/doc/module-color.rst b/doc/module-color.rst index 9ecd3c49..a07a7f26 100644 --- a/doc/module-color.rst +++ b/doc/module-color.rst @@ -19,4 +19,3 @@ fresnel.color .. automodule:: fresnel.color :synopsis: Color utilities. :members: - diff --git a/doc/module-geometry.rst b/doc/module-geometry.rst index 493720e4..4f48e1c1 100644 --- a/doc/module-geometry.rst +++ b/doc/module-geometry.rst @@ -26,4 +26,3 @@ fresnel.geometry :synopsis: Geometric primitives. :members: :show-inheritance: - diff --git a/doc/module-interact.rst b/doc/module-interact.rst index 0c9fc007..7849432e 100644 --- a/doc/module-interact.rst +++ b/doc/module-interact.rst @@ -19,4 +19,3 @@ fresnel.interact .. automodule:: fresnel.interact :synopsis: Interactive Qt widgets. :members: - diff --git a/doc/module-light.rst b/doc/module-light.rst index 24f8946f..e4d13402 100644 --- a/doc/module-light.rst +++ b/doc/module-light.rst @@ -25,4 +25,3 @@ fresnel.light .. automodule:: fresnel.light :synopsis: Lights. :members: - diff --git a/doc/module-material.rst b/doc/module-material.rst index bfebac1f..e274e12f 100644 --- a/doc/module-material.rst +++ b/doc/module-material.rst @@ -19,4 +19,3 @@ fresnel.material .. automodule:: fresnel.material :synopsis: Materials. :members: - diff --git a/doc/module-tracer.rst b/doc/module-tracer.rst index 338af7aa..7a061c6a 100644 --- a/doc/module-tracer.rst +++ b/doc/module-tracer.rst @@ -22,4 +22,3 @@ fresnel.tracer :synopsis: Ray tracers. :show-inheritance: :members: - diff --git a/doc/module-util.rst b/doc/module-util.rst index 0b8d3d39..19684966 100644 --- a/doc/module-util.rst +++ b/doc/module-util.rst @@ -22,4 +22,3 @@ fresnel.util :synopsis: Utility classes. :members: :show-inheritance: - diff --git a/doc/style.rst b/doc/style.rst index e308531d..447b0f4f 100644 --- a/doc/style.rst +++ b/doc/style.rst @@ -5,17 +5,27 @@ Code style ========== -All code in fresnel must follow a consistent style to ensure readability. -We provide configuration files for linters (specified below) so that developers -can automatically validate and format files. +All code in fresnel must follow a consistent style to ensure readability. We +provide configuration files for linters and autoformatters (specified below) so +that developers can automatically validate and format files. + +These tools are configured for use with `pre-commit`_ in +``.pre-commit-config.yaml``. You can install pre-commit hooks to validate your +code. Checks will run on pull requests. Run checks manually with:: + + pre-commit run --all-files + +.. _pre-commit: https://pre-commit.com/ Python ------ -Python code in GSD should follow `PEP8 -`_ with the formatting performed by -`yapf `_ (configuration in ``setup.cfg``). -Code should pass all **flake8** tests and formatted by **yapf**. +Python code in GSD should follow `PEP8`_ with the formatting performed by +`yapf`_ (configuration in ``setup.cfg``). Code should pass all **flake8** tests +and formatted by **yapf**. + +.. _PEP8: https://www.python.org/dev/peps/pep-0008 +.. _yapf: https://github.com/google/yapf Tools ^^^^^ @@ -28,27 +38,27 @@ Tools * `flake8-docstrings `_ * `flake8-rst-docstrings `_ - * Run: ``flake8`` to see a list of linter violations. + * Configure flake8 in your editor to see violations on save. * Autoformatter: `yapf `_ - * Run: ``yapf -d -r .`` to see needed style changes. - * Run: ``yapf -i file.py`` to apply style changes to a whole file, or use - your IDE to apply **yapf** to a selection. + * Run: ``pre-commit run --all-files`` to apply style changes to the whole + repository. Documentation ^^^^^^^^^^^^^ Python code should be documented with docstrings and added to the Sphinx -documentation index in ``doc/``. Docstrings should follow `Google style -`_ -formatting for use in `Napoleon -`_. +documentation index in ``doc/``. Docstrings should follow `Google style`_ +formatting for use in `Napoleon`_. + +.. _Google Style: https://www.sphinx-doc.org/en/master/usage/extensions/example_google.html#example-google +.. _Napoleon: https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html C++/CUDA -------- -* Style is set by clang-format >= 10 +* Style is set by clang-format-10 * Whitesmith's indentation style. * 100 character line width. @@ -72,8 +82,9 @@ Tools * Autoformatter: `clang-format `_. - * Run: ``./run-clang-format.py -r .`` to see needed changes. - * Run: ``clang-format -i file.c`` to apply the changes. + * Run: ``pre-commit run --all-files --hook-stage manual`` to apply changes to + the whole repository. You must have a ``conda`` installation in your + ``PATH`` to run this. Documentation ^^^^^^^^^^^^^ diff --git a/fresnel/common/IntersectCylinder.h b/fresnel/common/IntersectCylinder.h index 92dd2be5..3a5832fa 100644 --- a/fresnel/common/IntersectCylinder.h +++ b/fresnel/common/IntersectCylinder.h @@ -200,7 +200,7 @@ DEVICE inline bool intersect_ray_spherocylinder(float& t, // determine d_edge // project C and Oa into the view plane perpendicular to the view direction - const vec3 C_vp = C - dot(C, d) * d; // vector rejection assuming view is normalized + const vec3 C_vp = C - dot(C, d) * d; // vector rejection assuming view is normalized const vec3 Oa_vp = Oa - dot(Oa, d) * d; // vector rejection assuming view is normalized // d_edge is r - (the distance from Oa_vp to the line segment (0,0,0) - Oa_vp) diff --git a/fresnel/common/Light.h b/fresnel/common/Light.h index cb96e12c..6570612e 100644 --- a/fresnel/common/Light.h +++ b/fresnel/common/Light.h @@ -36,9 +36,9 @@ namespace fresnel struct Lights { vec3 direction[4]; //!< Light directions - RGB color[4]; //!< Color of each light (linearized sRGB color space) - float theta[4]; //!< Half angle of the area light - unsigned int N; //!< Number of lights + RGB color[4]; //!< Color of each light (linearized sRGB color space) + float theta[4]; //!< Half angle of the area light + unsigned int N; //!< Number of lights //! Default constructor leaves memory uninitialized to support OptiX variables Lights() { } diff --git a/fresnel/common/Material.h b/fresnel/common/Material.h index 01646f44..3c64203d 100644 --- a/fresnel/common/Material.h +++ b/fresnel/common/Material.h @@ -46,13 +46,13 @@ DEVICE inline float schlick(float x) */ struct Material { - float solid; //!< Set to 1 to pass through solid color - RGB color; //!< Color of the material + float solid; //!< Set to 1 to pass through solid color + RGB color; //!< Color of the material float primitive_color_mix; //!< Set to 0 to force material color, 1 to use geometry color - float roughness; //!< Set to 0 for a smooth material, non-zero for a rough material - float specular; //!< Set to 0 for no specular highlights, 1 for strong highlights - float metal; //!< Set to 0 for dielectric materials, set to 1 for metals - float spec_trans; //!< Set to 0 for solid materials, 1 for fully transmissive + float roughness; //!< Set to 0 for a smooth material, non-zero for a rough material + float specular; //!< Set to 0 for no specular highlights, 1 for strong highlights + float metal; //!< Set to 0 for dielectric materials, set to 1 for metals + float spec_trans; //!< Set to 0 for solid materials, 1 for fully transmissive //! Default constructor gives uninitialized material DEVICE Material() { } diff --git a/fresnel/common/RayGen.h b/fresnel/common/RayGen.h index ab556f1f..bbd32e7f 100644 --- a/fresnel/common/RayGen.h +++ b/fresnel/common/RayGen.h @@ -186,11 +186,11 @@ class RayGen } protected: - unsigned int m_width; //!< Width of the output image (in pixels) - unsigned int m_height; //!< Height of the output image (in pixels) + unsigned int m_width; //!< Width of the output image (in pixels) + unsigned int m_height; //!< Height of the output image (in pixels) r123::Philox4x32::key_type m_rng_key; //!< Key for the random number generator - unsigned int m_i; //!< i coordinate of the pixel - unsigned int m_j; //!< j coordinate of the pixel + unsigned int m_i; //!< i coordinate of the pixel + unsigned int m_j; //!< j coordinate of the pixel }; } // namespace fresnel diff --git a/fresnel/common/VectorMath.h b/fresnel/common/VectorMath.h index 8f477b26..e58b0d07 100644 --- a/fresnel/common/VectorMath.h +++ b/fresnel/common/VectorMath.h @@ -918,7 +918,7 @@ template struct quat return q; } - Real s; //!< scalar component + Real s; //!< scalar component vec3 v; //!< vector component }; diff --git a/fresnel/common/module-common.cc b/fresnel/common/module-common.cc index 6d1d8df0..51811037 100644 --- a/fresnel/common/module-common.cc +++ b/fresnel/common/module-common.cc @@ -55,28 +55,32 @@ PYBIND11_MODULE(_common, m) .def_readwrite("spec_trans", &Material::spec_trans) .def_readwrite("metal", &Material::metal) .def_readwrite("color", &Material::color) - .def("__repr__", [](const Material& a) { - ostringstream s; - s << ""; + .def("__repr__", + [](const Material& a) + { + ostringstream s; + s << ""; - return s.str(); - }); + return s.str(); + }); pybind11::class_>(m, "vec3f") .def(pybind11::init()) .def_readwrite("x", &vec3::x) .def_readwrite("y", &vec3::y) .def_readwrite("z", &vec3::z) - .def("__repr__", [](const vec3& a) { - ostringstream s; - s << ""; - return s.str(); - }); + .def("__repr__", + [](const vec3& a) + { + ostringstream s; + s << ""; + return s.str(); + }); pybind11::class_(m, "UserCamera") .def(pybind11::init<>()) diff --git a/fresnel/cpu/Array.cc b/fresnel/cpu/Array.cc index 38b98504..57be0260 100644 --- a/fresnel/cpu/Array.cc +++ b/fresnel/cpu/Array.cc @@ -21,8 +21,8 @@ void export_Array(pybind11::module& m) m, "ArrayRGBAc", pybind11::buffer_protocol()) - .def_buffer( - [](Array>& t) -> pybind11::buffer_info { return t.getBuffer(); }) + .def_buffer([](Array>& t) -> pybind11::buffer_info + { return t.getBuffer(); }) .def("map", &Array>::map_py) .def("unmap", &Array>::unmap); @@ -38,8 +38,8 @@ void export_Array(pybind11::module& m) m, "ArrayRGBc", pybind11::buffer_protocol()) - .def_buffer( - [](Array>& t) -> pybind11::buffer_info { return t.getBuffer(); }) + .def_buffer([](Array>& t) -> pybind11::buffer_info + { return t.getBuffer(); }) .def("map", &Array>::map_py) .def("unmap", &Array>::unmap); diff --git a/fresnel/cpu/Array.h b/fresnel/cpu/Array.h index 50abcd96..d9a4f9c2 100644 --- a/fresnel/cpu/Array.h +++ b/fresnel/cpu/Array.h @@ -223,9 +223,9 @@ template class Array protected: std::vector m_data; //!< Stored data - size_t m_w; //!< Width of data array - size_t m_h; //!< Height of data array - unsigned int m_ndim; //!< Number of dimensions in the data array + size_t m_w; //!< Width of data array + size_t m_h; //!< Height of data array + unsigned int m_ndim; //!< Number of dimensions in the data array }; //! Export Array instantiations to python diff --git a/fresnel/cpu/Device.h b/fresnel/cpu/Device.h index 0c60ba82..f598ec59 100644 --- a/fresnel/cpu/Device.h +++ b/fresnel/cpu/Device.h @@ -74,7 +74,7 @@ class Device throw std::runtime_error("Embree: The operation got cancelled by an Memory Monitor " "Callback or Progress Monitor Callback function."); break; - default: + default: throw std::runtime_error("Embree: An invalid error has occurred."); break; } @@ -89,9 +89,9 @@ class Device } private: - RTCDevice m_device; //!< Store the embree device + RTCDevice m_device; //!< Store the embree device std::shared_ptr m_arena; //!< TBB task arena - int m_limit; //!< Cached limit for reporting to users + int m_limit; //!< Cached limit for reporting to users }; //! Export Device to python diff --git a/fresnel/cpu/Geometry.h b/fresnel/cpu/Geometry.h index eedc2e9b..798e8c40 100644 --- a/fresnel/cpu/Geometry.h +++ b/fresnel/cpu/Geometry.h @@ -94,11 +94,11 @@ class Geometry } protected: - unsigned int m_geom_id; //!< Associated geometry id - bool m_valid = false; //!< true when the geometry is valid and attached to the Scene - std::shared_ptr m_scene; //!< The scene the geometry is attached to + unsigned int m_geom_id; //!< Associated geometry id + bool m_valid = false; //!< true when the geometry is valid and attached to the Scene + std::shared_ptr m_scene; //!< The scene the geometry is attached to std::shared_ptr m_device; //!< The device the Scene is attached to - RTCGeometry m_geometry; //!< The embree geometry object + RTCGeometry m_geometry; //!< The embree geometry object }; //! Export Geometry to python diff --git a/fresnel/cpu/GeometryConvexPolyhedron.h b/fresnel/cpu/GeometryConvexPolyhedron.h index cf1ac1a4..223cadb4 100644 --- a/fresnel/cpu/GeometryConvexPolyhedron.h +++ b/fresnel/cpu/GeometryConvexPolyhedron.h @@ -74,13 +74,13 @@ class GeometryConvexPolyhedron : public Geometry protected: std::vector> m_plane_origin; //!< Origins of all the planes in the convex polyhedron std::vector> m_plane_normal; //!< Normals of all the planes in the convex polyhedron - std::vector> m_plane_color; //!< Colors assigned to the polyhedron planes + std::vector> m_plane_color; //!< Colors assigned to the polyhedron planes - std::shared_ptr>> m_position; //!< Position of each polyhedron + std::shared_ptr>> m_position; //!< Position of each polyhedron std::shared_ptr>> m_orientation; //!< Orientation of each polyhedron - std::shared_ptr>> m_color; //!< Per-particle color + std::shared_ptr>> m_color; //!< Per-particle color - float m_radius = 0; //!< Precomputed radius + float m_radius = 0; //!< Precomputed radius float m_color_by_face = 0.0f; //!< Flag that mixes per particle color with per face color //! Embree bounding function diff --git a/fresnel/cpu/GeometryCylinder.h b/fresnel/cpu/GeometryCylinder.h index d4857486..5e51d9d0 100644 --- a/fresnel/cpu/GeometryCylinder.h +++ b/fresnel/cpu/GeometryCylinder.h @@ -57,8 +57,8 @@ class GeometryCylinder : public Geometry protected: std::shared_ptr>> m_points; //!< Position the start and end of each cylinder - std::shared_ptr> m_radius; //!< Per-particle radii - std::shared_ptr>> m_color; //!< Color for each start and end point + std::shared_ptr> m_radius; //!< Per-particle radii + std::shared_ptr>> m_color; //!< Color for each start and end point //! Embree bounding function static void bounds(const struct RTCBoundsFunctionArguments* args); diff --git a/fresnel/cpu/GeometryMesh.h b/fresnel/cpu/GeometryMesh.h index d74aeedf..84a2471c 100644 --- a/fresnel/cpu/GeometryMesh.h +++ b/fresnel/cpu/GeometryMesh.h @@ -60,7 +60,7 @@ class GeometryMesh : public Geometry m_vertices; //!< Holds the vertex coordinates in ccw order for each face std::shared_ptr>> m_color; //!< Color for each vertex point - std::shared_ptr>> m_position; //!< Position of each polyhedron + std::shared_ptr>> m_position; //!< Position of each polyhedron std::shared_ptr>> m_orientation; //!< Orientation of each polyhedron unsigned int m_N; //!< Number of polyhedra diff --git a/fresnel/cpu/GeometryPolygon.h b/fresnel/cpu/GeometryPolygon.h index 00b5ad2e..fb4ef830 100644 --- a/fresnel/cpu/GeometryPolygon.h +++ b/fresnel/cpu/GeometryPolygon.h @@ -60,11 +60,11 @@ class GeometryPolygon : public Geometry protected: std::vector> m_vertices; //!< Polygon vertices - float m_rounding_radius; //!< Spheropolygon rounding radius + float m_rounding_radius; //!< Spheropolygon rounding radius std::shared_ptr>> m_position; //!< Position of each polygon - std::shared_ptr> m_angle; //!< Orientation of each polygon - std::shared_ptr>> m_color; //!< Per-particle color + std::shared_ptr> m_angle; //!< Orientation of each polygon + std::shared_ptr>> m_color; //!< Per-particle color float m_radius = 0; //!< Precomputed radius in the xy plane diff --git a/fresnel/cpu/GeometrySphere.h b/fresnel/cpu/GeometrySphere.h index da94980f..34f90294 100644 --- a/fresnel/cpu/GeometrySphere.h +++ b/fresnel/cpu/GeometrySphere.h @@ -54,8 +54,8 @@ class GeometrySphere : public Geometry protected: std::shared_ptr>> m_position; //!< Position for each sphere - std::shared_ptr> m_radius; //!< Per-particle radii - std::shared_ptr>> m_color; //!< Per-particle color + std::shared_ptr> m_radius; //!< Per-particle radii + std::shared_ptr>> m_color; //!< Per-particle color //! Embree bounding function static void bounds(const struct RTCBoundsFunctionArguments* args); diff --git a/fresnel/cpu/Scene.h b/fresnel/cpu/Scene.h index 42f02a6e..03e01c68 100644 --- a/fresnel/cpu/Scene.h +++ b/fresnel/cpu/Scene.h @@ -155,17 +155,17 @@ class Scene } private: - RTCScene m_scene; //!< Store the scene + RTCScene m_scene; //!< Store the scene std::shared_ptr m_device; //!< The device the scene is attached to - std::vector m_materials; //!< Materials associated with geometry ids + std::vector m_materials; //!< Materials associated with geometry ids std::vector m_outline_materials; //!< Materials associated with geometry ids - std::vector m_outline_widths; //!< Materials associated with geometry ids + std::vector m_outline_widths; //!< Materials associated with geometry ids RGB m_background_color; //!< The background color - float m_background_alpha; //!< Background alpha - UserCamera m_camera; //!< The camera - Lights m_lights; //!< The lights + float m_background_alpha; //!< Background alpha + UserCamera m_camera; //!< The camera + Lights m_lights; //!< The lights }; //! Export Scene to python diff --git a/fresnel/cpu/Tracer.h b/fresnel/cpu/Tracer.h index a7ad3473..775606c5 100644 --- a/fresnel/cpu/Tracer.h +++ b/fresnel/cpu/Tracer.h @@ -81,12 +81,12 @@ class Tracer } protected: - std::shared_ptr m_device; //!< The device the Scene is attached to - std::shared_ptr>> m_linear_out; //!< The output buffer (linear space) + std::shared_ptr m_device; //!< The device the Scene is attached to + std::shared_ptr>> m_linear_out; //!< The output buffer (linear space) std::shared_ptr>> m_srgb_out; //!< The output buffer (srgb space) bool m_highlight_warning; //!< Set to true to enable highlight warnings in sRGB output RGB m_highlight_warning_color; //!< The highlight warning color - unsigned int m_seed = 0; //!< Random number seed + unsigned int m_seed = 0; //!< Random number seed }; //! Export Tracer to python diff --git a/fresnel/cpu/TracerDirect.cc b/fresnel/cpu/TracerDirect.cc index 3611108d..b6b65fc6 100644 --- a/fresnel/cpu/TracerDirect.cc +++ b/fresnel/cpu/TracerDirect.cc @@ -26,7 +26,12 @@ TracerDirect::~TracerDirect() { } void TracerDirect::render(std::shared_ptr scene) { std::shared_ptr arena = scene->getDevice()->getTBBArena(); + Tracer::render(scene); + arena->execute([&] { renderImplementation(scene); }); + } +void TracerDirect::renderImplementation(std::shared_ptr scene) + { const RGB background_color = scene->getBackgroundColor(); const float background_alpha = scene->getBackgroundAlpha(); @@ -39,7 +44,6 @@ void TracerDirect::render(std::shared_ptr scene) const Camera cam(user_camera, m_linear_out->getW(), m_linear_out->getH(), m_seed, sample_aa); const Lights lights(scene->getLights(), cam); - Tracer::render(scene); // update Embree data structures rtcCommitScene(scene->getRTCScene()); @@ -57,163 +61,159 @@ void TracerDirect::render(std::shared_ptr scene) const unsigned int numTilesX = (width + TILE_SIZE_X - 1) / TILE_SIZE_X; const unsigned int numTilesY = (height + TILE_SIZE_Y - 1) / TILE_SIZE_Y; - arena->execute([&] { - parallel_for( - blocked_range(0, numTilesX * numTilesY), - [=](const blocked_range& r) { - for (size_t tile = r.begin(); tile != r.end(); ++tile) - { - const unsigned int tileY = tile / numTilesX; - const unsigned int tileX = tile - tileY * numTilesX; - const unsigned int x0 = tileX * TILE_SIZE_X; - const unsigned int x1 = std::min(x0 + TILE_SIZE_X, width); - const unsigned int y0 = tileY * TILE_SIZE_Y; - const unsigned int y1 = std::min(y0 + TILE_SIZE_Y, height); - - for (unsigned int j = y0; j < y1; j++) - for (unsigned int i = x0; i < x1; i++) + parallel_for( + blocked_range(0, numTilesX * numTilesY), + [=](const blocked_range& r) + { + for (size_t tile = r.begin(); tile != r.end(); ++tile) + { + const unsigned int tileY = tile / numTilesX; + const unsigned int tileX = tile - tileY * numTilesX; + const unsigned int x0 = tileX * TILE_SIZE_X; + const unsigned int x1 = std::min(x0 + TILE_SIZE_X, width); + const unsigned int y0 = tileY * TILE_SIZE_Y; + const unsigned int y1 = std::min(y0 + TILE_SIZE_Y, height); + + for (unsigned int j = y0; j < y1; j++) + for (unsigned int i = x0; i < x1; i++) + { + // create the ray generator for this pixel + RayGen ray_gen(i, j, width, height, m_seed); + + // loop over AA samples + RGBA output_avg(0, 0, 0, 0); + + for (unsigned int sample = 0; sample < m_aa_n * m_aa_n; sample++) { - // create the ray generator for this pixel - RayGen ray_gen(i, j, width, height, m_seed); - - // loop over AA samples - RGBA output_avg(0, 0, 0, 0); - - for (unsigned int sample = 0; sample < m_aa_n * m_aa_n; sample++) + // trace a ray into the scene + RTCRayHit ray_hit; + RTCRay& ray = ray_hit.ray; + vec3 org, dir; + cam.generateRay(org, dir, i, j, sample); + ray.org_x = org.x; + ray.org_y = org.y; + ray.org_z = org.z; + + ray.dir_x = dir.x; + ray.dir_y = dir.y; + ray.dir_z = dir.z; + + ray.tnear = 0.0f; + ray.tfar = std::numeric_limits::infinity(); + ray.time = 0.0f; + ray.flags = 0; + ray.mask = -1; + ray_hit.hit.geomID = RTC_INVALID_GEOMETRY_ID; + ray_hit.hit.instID[0] = RTC_INVALID_GEOMETRY_ID; + + FresnelRTCIntersectContext context; + rtcInitIntersectContext(&context.context); + + rtcIntersect1(scene->getRTCScene(), &context.context, &ray_hit); + + // determine the output pixel color + RGB c = background_color; + float a = background_alpha; + + if (ray_hit.hit.geomID != RTC_INVALID_GEOMETRY_ID) { - // trace a ray into the scene - RTCRayHit ray_hit; - RTCRay& ray = ray_hit.ray; - vec3 org, dir; - cam.generateRay(org, dir, i, j, sample); - ray.org_x = org.x; - ray.org_y = org.y; - ray.org_z = org.z; - - ray.dir_x = dir.x; - ray.dir_y = dir.y; - ray.dir_z = dir.z; - - ray.tnear = 0.0f; - ray.tfar = std::numeric_limits::infinity(); - ray.time = 0.0f; - ray.flags = 0; - ray.mask = -1; - ray_hit.hit.geomID = RTC_INVALID_GEOMETRY_ID; - ray_hit.hit.instID[0] = RTC_INVALID_GEOMETRY_ID; - - FresnelRTCIntersectContext context; - rtcInitIntersectContext(&context.context); - - rtcIntersect1(scene->getRTCScene(), &context.context, &ray_hit); - - // determine the output pixel color - RGB c = background_color; - float a = background_alpha; - - if (ray_hit.hit.geomID != RTC_INVALID_GEOMETRY_ID) + vec3 n(ray_hit.hit.Ng_x, ray_hit.hit.Ng_y, ray_hit.hit.Ng_z); + n /= std::sqrt(dot(n, n)); + vec3 v = -dir / std::sqrt(dot(dir, dir)); + Material m; + + // apply the material color or outline color depending on + // the distance to the edge + if (context.d >= scene->getOutlineWidth(ray_hit.hit.geomID)) + m = scene->getMaterial(ray_hit.hit.geomID); + else + m = scene->getOutlineMaterial(ray_hit.hit.geomID); + + if (m.isSolid()) { - vec3 n(ray_hit.hit.Ng_x, - ray_hit.hit.Ng_y, - ray_hit.hit.Ng_z); - n /= std::sqrt(dot(n, n)); - vec3 v = -dir / std::sqrt(dot(dir, dir)); - Material m; - - // apply the material color or outline color depending on - // the distance to the edge - if (context.d >= scene->getOutlineWidth(ray_hit.hit.geomID)) - m = scene->getMaterial(ray_hit.hit.geomID); - else - m = scene->getOutlineMaterial(ray_hit.hit.geomID); - - if (m.isSolid()) - { - c = m.getColor(context.shading_color); - } - else + c = m.getColor(context.shading_color); + } + else + { + c = RGB(0, 0, 0); + for (unsigned int light_id = 0; light_id < lights.N; light_id++) { - c = RGB(0, 0, 0); - for (unsigned int light_id = 0; light_id < lights.N; - light_id++) + vec3 l = lights.direction[light_id]; + + // find the representative point, a vector pointing + // to the a point on the area light with a smallest + // angle to the reflection vector + vec3 r = -v + (2.0f * n * dot(n, v)); + + // find the closest point on the area light + float half_angle = lights.theta[light_id]; + float cos_half_angle = cosf(half_angle); + float ldotr = dot(l, r); + if (ldotr < cos_half_angle) { - vec3 l = lights.direction[light_id]; - - // find the representative point, a vector pointing - // to the a point on the area light with a smallest - // angle to the reflection vector - vec3 r = -v + (2.0f * n * dot(n, v)); - - // find the closest point on the area light - float half_angle = lights.theta[light_id]; - float cos_half_angle = cosf(half_angle); - float ldotr = dot(l, r); - if (ldotr < cos_half_angle) - { - vec3 a = cross(l, r); - a = a / sqrtf(dot(a, a)); - - // miss the light, need to rotate r by the - // difference in the angles about l cross r - quat q = quat::fromAxisAngle( - a, - -acosf(ldotr) + half_angle); - r = rotate(q, r); - } - else - { - // hit the light, no modification necessary to r - } - - // only apply brdf when the light faces the surface - RGB f_d; - float ndotl = dot(n, l); - if (ndotl >= 0.0f) - f_d = m.brdf_diffuse(l, v, n, context.shading_color) - * ndotl; - else - f_d = RGB(0.0f, 0.0f, 0.0f); - - RGB f_s; - if (dot(n, r) >= 0.0f) - { - f_s = m.brdf_specular(r, - v, - n, - context.shading_color, - half_angle) - * dot(n, r); - } - else - f_s = RGB(0.0f, 0.0f, 0.0f); - - c += (f_d + f_s) * float(M_PI) * lights.color[light_id]; + vec3 a = cross(l, r); + a = a / sqrtf(dot(a, a)); + + // miss the light, need to rotate r by the + // difference in the angles about l cross r + quat q = quat::fromAxisAngle( + a, + -acosf(ldotr) + half_angle); + r = rotate(q, r); + } + else + { + // hit the light, no modification necessary to r } - } - a = 1.0; + // only apply brdf when the light faces the surface + RGB f_d; + float ndotl = dot(n, l); + if (ndotl >= 0.0f) + f_d = m.brdf_diffuse(l, v, n, context.shading_color) + * ndotl; + else + f_d = RGB(0.0f, 0.0f, 0.0f); + + RGB f_s; + if (dot(n, r) >= 0.0f) + { + f_s = m.brdf_specular(r, + v, + n, + context.shading_color, + half_angle) + * dot(n, r); + } + else + f_s = RGB(0.0f, 0.0f, 0.0f); + + c += (f_d + f_s) * float(M_PI) * lights.color[light_id]; + } } - // accumulate importance sampled average - output_avg += RGBA(c, a); - } // end loop over AA samples - - // write the output pixel - unsigned int pixel = j * width + i; - RGBA output_pixel = output_avg / float(m_aa_n * m_aa_n); - - linear_output[pixel] = output_pixel; - if (!m_highlight_warning - || (output_pixel.r <= 1.0f && output_pixel.g <= 1.0f - && output_pixel.b <= 1.0f)) - srgb_output[pixel] = sRGB(output_pixel); - else - srgb_output[pixel] - = sRGB(RGBA(m_highlight_warning_color, output_pixel.a)); - } // end loop over pixels in the tile - } // loop over tiles in this region - }); // end parallel loop over tiles - }); // end parallel arena + a = 1.0; + } + + // accumulate importance sampled average + output_avg += RGBA(c, a); + } // end loop over AA samples + + // write the output pixel + unsigned int pixel = j * width + i; + RGBA output_pixel = output_avg / float(m_aa_n * m_aa_n); + + linear_output[pixel] = output_pixel; + if (!m_highlight_warning + || (output_pixel.r <= 1.0f && output_pixel.g <= 1.0f + && output_pixel.b <= 1.0f)) + srgb_output[pixel] = sRGB(output_pixel); + else + srgb_output[pixel] + = sRGB(RGBA(m_highlight_warning_color, output_pixel.a)); + } // end loop over pixels in the tile + } // loop over tiles in this region + }); // end parallel loop over tiles m_linear_out->unmap(); m_srgb_out->unmap(); diff --git a/fresnel/cpu/TracerDirect.h b/fresnel/cpu/TracerDirect.h index 1932456f..edd39791 100644 --- a/fresnel/cpu/TracerDirect.h +++ b/fresnel/cpu/TracerDirect.h @@ -44,6 +44,9 @@ class TracerDirect : public Tracer protected: //! Number of AA samples in each direction unsigned int m_aa_n = 8; + + /// Implementation of the render loop + virtual void renderImplementation(std::shared_ptr scene); }; //! Export TracerDirect to python diff --git a/fresnel/cpu/TracerPath.cc b/fresnel/cpu/TracerPath.cc index e15a1539..36b682f9 100644 --- a/fresnel/cpu/TracerPath.cc +++ b/fresnel/cpu/TracerPath.cc @@ -48,14 +48,18 @@ void TracerPath::reset() void TracerPath::render(std::shared_ptr scene) { + Tracer::render(scene); std::shared_ptr arena = scene->getDevice()->getTBBArena(); + arena->execute([&] { renderImplementation(scene); }); + } +void TracerPath::renderImplementation(std::shared_ptr scene) + { const RGB background_color = scene->getBackgroundColor(); const float background_alpha = scene->getBackgroundAlpha(); const Camera cam(scene->getCamera(), m_linear_out->getW(), m_linear_out->getH(), m_seed); const Lights lights(scene->getLights(), cam); - Tracer::render(scene); // update Embree data structures rtcCommitScene(scene->getRTCScene()); @@ -76,171 +80,167 @@ void TracerPath::render(std::shared_ptr scene) const unsigned int numTilesX = (width + TILE_SIZE_X - 1) / TILE_SIZE_X; const unsigned int numTilesY = (height + TILE_SIZE_Y - 1) / TILE_SIZE_Y; - arena->execute([&] { - parallel_for( - blocked_range(0, numTilesX * numTilesY), - [=](const blocked_range& r) { - for (size_t tile = r.begin(); tile != r.end(); ++tile) - { - const unsigned int tileY = tile / numTilesX; - const unsigned int tileX = tile - tileY * numTilesX; - const unsigned int x0 = tileX * TILE_SIZE_X; - const unsigned int x1 = std::min(x0 + TILE_SIZE_X, width); - const unsigned int y0 = tileY * TILE_SIZE_Y; - const unsigned int y1 = std::min(y0 + TILE_SIZE_Y, height); - - for (unsigned int j = y0; j < y1; j++) - for (unsigned int i = x0; i < x1; i++) + parallel_for( + blocked_range(0, numTilesX * numTilesY), + [=](const blocked_range& r) + { + for (size_t tile = r.begin(); tile != r.end(); ++tile) + { + const unsigned int tileY = tile / numTilesX; + const unsigned int tileX = tile - tileY * numTilesX; + const unsigned int x0 = tileX * TILE_SIZE_X; + const unsigned int x1 = std::min(x0 + TILE_SIZE_X, width); + const unsigned int y0 = tileY * TILE_SIZE_Y; + const unsigned int y1 = std::min(y0 + TILE_SIZE_Y, height); + + for (unsigned int j = y0; j < y1; j++) + for (unsigned int i = x0; i < x1; i++) + { + // create the ray generator for this pixel + RayGen ray_gen(i, j, width, height, m_seed); + + // per ray data + PRDpath prd; + prd.result = RGB(0, 0, 0); + prd.a = 1.0f; + + // trace the first ray into the scene + RTCRayHit ray_hit_initial; + RTCRay& ray_initial = ray_hit_initial.ray; + + vec3 org, dir; + cam.generateRay(org, dir, i, j, m_n_samples); + ray_initial.org_x = org.x; + ray_initial.org_y = org.y; + ray_initial.org_z = org.z; + + ray_initial.dir_x = dir.x; + ray_initial.dir_y = dir.y; + ray_initial.dir_z = dir.z; + + ray_initial.tnear = 1e-3f; + ray_initial.tfar = std::numeric_limits::infinity(); + ray_initial.time = 0.0f; + ray_initial.mask = -1; + ray_initial.flags = 0; + ray_hit_initial.hit.geomID = RTC_INVALID_GEOMETRY_ID; + ray_hit_initial.hit.instID[0] = RTC_INVALID_GEOMETRY_ID; + + FresnelRTCIntersectContext context; + rtcInitIntersectContext(&context.context); + + rtcIntersect1(scene->getRTCScene(), &context.context, &ray_hit_initial); + + FresnelRTCIntersectContext context_initial = context; + + // trace a path from the hit point into the scene m_light_samples times + for (prd.light_sample = 0; prd.light_sample < m_light_samples; + prd.light_sample++) { - // create the ray generator for this pixel - RayGen ray_gen(i, j, width, height, m_seed); - - // per ray data - PRDpath prd; - prd.result = RGB(0, 0, 0); - prd.a = 1.0f; - - // trace the first ray into the scene - RTCRayHit ray_hit_initial; - RTCRay& ray_initial = ray_hit_initial.ray; - - vec3 org, dir; - cam.generateRay(org, dir, i, j, m_n_samples); - ray_initial.org_x = org.x; - ray_initial.org_y = org.y; - ray_initial.org_z = org.z; - - ray_initial.dir_x = dir.x; - ray_initial.dir_y = dir.y; - ray_initial.dir_z = dir.z; - - ray_initial.tnear = 1e-3f; - ray_initial.tfar = std::numeric_limits::infinity(); - ray_initial.time = 0.0f; - ray_initial.mask = -1; - ray_initial.flags = 0; - ray_hit_initial.hit.geomID = RTC_INVALID_GEOMETRY_ID; - ray_hit_initial.hit.instID[0] = RTC_INVALID_GEOMETRY_ID; - - FresnelRTCIntersectContext context; - rtcInitIntersectContext(&context.context); - - rtcIntersect1(scene->getRTCScene(), &context.context, &ray_hit_initial); - - FresnelRTCIntersectContext context_initial = context; - - // trace a path from the hit point into the scene m_light_samples times - for (prd.light_sample = 0; prd.light_sample < m_light_samples; - prd.light_sample++) - { - prd.attenuation = RGB(1.0f, 1.0f, 1.0f); - prd.done = false; + prd.attenuation = RGB(1.0f, 1.0f, 1.0f); + prd.done = false; - for (prd.depth = 0;; prd.depth++) + for (prd.depth = 0;; prd.depth++) + { + RTCRayHit ray_hit; + if (prd.depth == 0) + { + // the first hit is cached above + ray_hit = ray_hit_initial; + context = context_initial; + } + else + { + RTCRay& ray = ray_hit.ray; + ray.org_x = prd.origin.x; + ray.org_y = prd.origin.y; + ray.org_z = prd.origin.z; + + ray.dir_x = prd.direction.x; + ray.dir_y = prd.direction.y; + ray.dir_z = prd.direction.z; + + ray.tnear = 1e-3f; + ray.tfar = std::numeric_limits::infinity(); + ray.time = 0.0f; + ray.mask = -1; + ray.flags = 0; + ray_hit.hit.geomID = RTC_INVALID_GEOMETRY_ID; + ray_hit.hit.instID[0] = RTC_INVALID_GEOMETRY_ID; + + // subsequent depth steps need to trace + context = FresnelRTCIntersectContext(); + rtcInitIntersectContext(&context.context); + + rtcIntersect1(scene->getRTCScene(), &context.context, &ray_hit); + } + + if (ray_hit.hit.geomID != RTC_INVALID_GEOMETRY_ID) + { + // call hit program + path_tracer_hit(prd, + scene->getMaterial(ray_hit.hit.geomID), + scene->getOutlineMaterial(ray_hit.hit.geomID), + context.d, + scene->getOutlineWidth(ray_hit.hit.geomID), + context.shading_color, + vec3(ray_hit.hit.Ng_x, + ray_hit.hit.Ng_y, + ray_hit.hit.Ng_z), + vec3(ray_hit.ray.org_x, + ray_hit.ray.org_y, + ray_hit.ray.org_z), + vec3(ray_hit.ray.dir_x, + ray_hit.ray.dir_y, + ray_hit.ray.dir_z), + ray_hit.ray.tfar, + ray_gen, + m_n_samples, + m_light_samples); + } + else { - RTCRayHit ray_hit; - if (prd.depth == 0) - { - // the first hit is cached above - ray_hit = ray_hit_initial; - context = context_initial; - } - else - { - RTCRay& ray = ray_hit.ray; - ray.org_x = prd.origin.x; - ray.org_y = prd.origin.y; - ray.org_z = prd.origin.z; - - ray.dir_x = prd.direction.x; - ray.dir_y = prd.direction.y; - ray.dir_z = prd.direction.z; - - ray.tnear = 1e-3f; - ray.tfar = std::numeric_limits::infinity(); - ray.time = 0.0f; - ray.mask = -1; - ray.flags = 0; - ray_hit.hit.geomID = RTC_INVALID_GEOMETRY_ID; - ray_hit.hit.instID[0] = RTC_INVALID_GEOMETRY_ID; - - // subsequent depth steps need to trace - context = FresnelRTCIntersectContext(); - rtcInitIntersectContext(&context.context); - - rtcIntersect1(scene->getRTCScene(), - &context.context, - &ray_hit); - } - - if (ray_hit.hit.geomID != RTC_INVALID_GEOMETRY_ID) - { - // call hit program - path_tracer_hit( - prd, - scene->getMaterial(ray_hit.hit.geomID), - scene->getOutlineMaterial(ray_hit.hit.geomID), - context.d, - scene->getOutlineWidth(ray_hit.hit.geomID), - context.shading_color, - vec3(ray_hit.hit.Ng_x, - ray_hit.hit.Ng_y, - ray_hit.hit.Ng_z), - vec3(ray_hit.ray.org_x, - ray_hit.ray.org_y, - ray_hit.ray.org_z), - vec3(ray_hit.ray.dir_x, - ray_hit.ray.dir_y, - ray_hit.ray.dir_z), - ray_hit.ray.tfar, - ray_gen, - m_n_samples, - m_light_samples); - } - else - { - // call miss program - path_tracer_miss(prd, - background_color, - background_alpha, - m_light_samples, - lights, - vec3(ray_hit.ray.dir_x, - ray_hit.ray.dir_y, - ray_hit.ray.dir_z)); - } - - // break out of the loop when done - if (prd.done) - break; - } // end depth loop - } // end light samples loop - - // take the current sample and compute the average with the previous - // samples - RGBA output_sample(prd.result / float(m_light_samples), prd.a); - - // running average using Welford's method. Variance is not particularly - // useful to users, so don't compute that. - // (http://jonisalonen.com/2013/deriving-welfords-method-for-computing-variance/) - unsigned int pixel = j * width + i; - RGBA old_mean = linear_output[pixel]; - linear_output[pixel] - = old_mean + (output_sample - old_mean) / float(m_n_samples); - - // convert the current average output to sRGB - RGBA output_pixel = linear_output[pixel]; - if (!m_highlight_warning - || (output_pixel.r <= 1.0f && output_pixel.g <= 1.0f - && output_pixel.b <= 1.0f)) - srgb_output[pixel] = sRGB(output_pixel); - else - srgb_output[pixel] - = sRGB(RGBA(m_highlight_warning_color, output_pixel.a)); - } // end loop over pixels in a tile - } // end loop over tiles in this work unit - }); // end parallel loop over all tiles - }); // end arena limited execution + // call miss program + path_tracer_miss(prd, + background_color, + background_alpha, + m_light_samples, + lights, + vec3(ray_hit.ray.dir_x, + ray_hit.ray.dir_y, + ray_hit.ray.dir_z)); + } + + // break out of the loop when done + if (prd.done) + break; + } // end depth loop + } // end light samples loop + + // take the current sample and compute the average with the previous + // samples + RGBA output_sample(prd.result / float(m_light_samples), prd.a); + + // running average using Welford's method. Variance is not particularly + // useful to users, so don't compute that. + // (http://jonisalonen.com/2013/deriving-welfords-method-for-computing-variance/) + unsigned int pixel = j * width + i; + RGBA old_mean = linear_output[pixel]; + linear_output[pixel] + = old_mean + (output_sample - old_mean) / float(m_n_samples); + + // convert the current average output to sRGB + RGBA output_pixel = linear_output[pixel]; + if (!m_highlight_warning + || (output_pixel.r <= 1.0f && output_pixel.g <= 1.0f + && output_pixel.b <= 1.0f)) + srgb_output[pixel] = sRGB(output_pixel); + else + srgb_output[pixel] + = sRGB(RGBA(m_highlight_warning_color, output_pixel.a)); + } // end loop over pixels in a tile + } // end loop over tiles in this work unit + }); // end parallel loop over all tiles m_linear_out->unmap(); m_srgb_out->unmap(); diff --git a/fresnel/cpu/TracerPath.h b/fresnel/cpu/TracerPath.h index 7dad07f0..7e3203c6 100644 --- a/fresnel/cpu/TracerPath.h +++ b/fresnel/cpu/TracerPath.h @@ -65,8 +65,11 @@ class TracerPath : public Tracer } protected: - unsigned int m_n_samples; //!< Number of samples taken since the last reset + unsigned int m_n_samples; //!< Number of samples taken since the last reset unsigned int m_light_samples; //!< Number of light samples to take each render() + + /// Implementation of the render loop + virtual void renderImplementation(std::shared_ptr scene); }; //! Export TracerDirect to python diff --git a/fresnel/cpu/embree_platform.h b/fresnel/cpu/embree_platform.h index 42196e9c..6a46acdf 100644 --- a/fresnel/cpu/embree_platform.h +++ b/fresnel/cpu/embree_platform.h @@ -24,7 +24,7 @@ struct FresnelRTCIntersectContext RTCIntersectContext context; // ray extensions go here - float d; //!< Distance to the nearest edge + float d; //!< Distance to the nearest edge fresnel::RGB shading_color; //!< shading color determined by which primitive the ray hits //!< (or where on the primitive) }; diff --git a/fresnel/gpu/Array.cc b/fresnel/gpu/Array.cc index 21d5b9a9..aba38363 100644 --- a/fresnel/gpu/Array.cc +++ b/fresnel/gpu/Array.cc @@ -21,8 +21,8 @@ void export_Array(pybind11::module& m) m, "ArrayRGBAc", pybind11::buffer_protocol()) - .def_buffer( - [](Array>& t) -> pybind11::buffer_info { return t.getBuffer(); }) + .def_buffer([](Array>& t) -> pybind11::buffer_info + { return t.getBuffer(); }) .def("map", &Array>::map_py) .def("unmap", &Array>::unmap); @@ -38,8 +38,8 @@ void export_Array(pybind11::module& m) m, "ArrayRGBc", pybind11::buffer_protocol()) - .def_buffer( - [](Array>& t) -> pybind11::buffer_info { return t.getBuffer(); }) + .def_buffer([](Array>& t) -> pybind11::buffer_info + { return t.getBuffer(); }) .def("map", &Array>::map_py) .def("unmap", &Array>::unmap); diff --git a/fresnel/gpu/Array.h b/fresnel/gpu/Array.h index 6cb4c9fe..3c9328d4 100644 --- a/fresnel/gpu/Array.h +++ b/fresnel/gpu/Array.h @@ -215,11 +215,11 @@ template class Array } protected: - size_t m_w; //!< Width of data array - size_t m_h; //!< Height of data array - unsigned int m_ndim; //!< Number of dimensions in the data array + size_t m_w; //!< Width of data array + size_t m_h; //!< Height of data array + unsigned int m_ndim; //!< Number of dimensions in the data array optix::Buffer m_buffer; //!< OptiX buffer - void* m_tmp = nullptr; //!< Temporary storage of the data pointer + void* m_tmp = nullptr; //!< Temporary storage of the data pointer }; //! Export Array instantiations to python diff --git a/fresnel/gpu/Device.h b/fresnel/gpu/Device.h index aeacd28b..823a180c 100644 --- a/fresnel/gpu/Device.h +++ b/fresnel/gpu/Device.h @@ -81,8 +81,8 @@ class Device } private: - optix::Context m_context; //!< Store the context - std::string m_ptx_root; //!< Directory where PTX files are stored + optix::Context m_context; //!< Store the context + std::string m_ptx_root; //!< Directory where PTX files are stored optix::Material m_material; //!< Material for Direct ray tracer std::map, optix::Program> diff --git a/fresnel/gpu/Geometry.h b/fresnel/gpu/Geometry.h index 0b35555f..20b07217 100644 --- a/fresnel/gpu/Geometry.h +++ b/fresnel/gpu/Geometry.h @@ -90,16 +90,16 @@ class Geometry protected: optix::GeometryInstance m_instance; //!< The geometry instance object - optix::Geometry m_geometry; //!< The geometry object - bool m_valid = false; //!< true when the geometry instance is valid and attached to the Scene + optix::Geometry m_geometry; //!< The geometry object + bool m_valid = false; //!< true when the geometry instance is valid and attached to the Scene bool m_enabled = false; //!< true when the geometry instance is part of the Scene - std::shared_ptr m_scene; //!< The scene the geometry is attached to + std::shared_ptr m_scene; //!< The scene the geometry is attached to std::shared_ptr m_device; //!< The device the Scene is attached to - Material m_mat; //!< material assigned to this geometry + Material m_mat; //!< material assigned to this geometry Material m_outline_mat; //!< outline material assigned to this geometry - float m_outline_width; //!< outline width + float m_outline_width; //!< outline width //! Set up m_instance void setupInstance(); diff --git a/fresnel/gpu/GeometryConvexPolyhedron.h b/fresnel/gpu/GeometryConvexPolyhedron.h index c36a1341..d9c02955 100644 --- a/fresnel/gpu/GeometryConvexPolyhedron.h +++ b/fresnel/gpu/GeometryConvexPolyhedron.h @@ -72,11 +72,11 @@ class GeometryConvexPolyhedron : public Geometry protected: optix::Buffer m_plane_origin; //!< Buffer containing plane origins optix::Buffer m_plane_normal; //!< Buffer containing plane normals - optix::Buffer m_plane_color; //!< Buffer containing plane colors + optix::Buffer m_plane_color; //!< Buffer containing plane colors - std::shared_ptr>> m_position; //!< Position of each polyhedron + std::shared_ptr>> m_position; //!< Position of each polyhedron std::shared_ptr>> m_orientation; //!< Orientation of each polyhedron - std::shared_ptr>> m_color; //!< Per-particle color + std::shared_ptr>> m_color; //!< Per-particle color }; //! Export GeometryConvexPolyhedron to python diff --git a/fresnel/gpu/GeometryCylinder.h b/fresnel/gpu/GeometryCylinder.h index d9cd4710..05f281c9 100644 --- a/fresnel/gpu/GeometryCylinder.h +++ b/fresnel/gpu/GeometryCylinder.h @@ -51,8 +51,8 @@ class GeometryCylinder : public Geometry protected: std::shared_ptr>> m_points; //!< Position the start and end of each cylinder - std::shared_ptr> m_radius; //!< Per-particle radii - std::shared_ptr>> m_color; //!< Color for each start and end point + std::shared_ptr> m_radius; //!< Per-particle radii + std::shared_ptr>> m_color; //!< Color for each start and end point }; //! Export GeometryCylinder to python diff --git a/fresnel/gpu/GeometryMesh.h b/fresnel/gpu/GeometryMesh.h index bb778f5c..c1020c98 100644 --- a/fresnel/gpu/GeometryMesh.h +++ b/fresnel/gpu/GeometryMesh.h @@ -54,9 +54,9 @@ class GeometryMesh : public Geometry protected: optix::Buffer m_vertices; //!< Buffer containing mesh vertices - std::shared_ptr>> m_position; //!< Position of each polyhedron + std::shared_ptr>> m_position; //!< Position of each polyhedron std::shared_ptr>> m_orientation; //!< Orientation of each polyhedron - std::shared_ptr>> m_color; //!< Per-vertex color + std::shared_ptr>> m_color; //!< Per-vertex color }; //! Export GeometryMesh to python diff --git a/fresnel/gpu/GeometryPolygon.h b/fresnel/gpu/GeometryPolygon.h index 2555872a..5793023d 100644 --- a/fresnel/gpu/GeometryPolygon.h +++ b/fresnel/gpu/GeometryPolygon.h @@ -62,8 +62,8 @@ class GeometryPolygon : public Geometry optix::Buffer m_vertices; //!< Buffer containing polygon vertices std::shared_ptr>> m_position; //!< Position of each polygon - std::shared_ptr> m_angle; //!< Orientation of each polygon - std::shared_ptr>> m_color; //!< Per-particle color + std::shared_ptr> m_angle; //!< Orientation of each polygon + std::shared_ptr>> m_color; //!< Per-particle color float m_radius = 0; //!< Precomputed radius in the xy plane }; diff --git a/fresnel/gpu/GeometrySphere.h b/fresnel/gpu/GeometrySphere.h index 6d7fc0a3..b5963dd1 100644 --- a/fresnel/gpu/GeometrySphere.h +++ b/fresnel/gpu/GeometrySphere.h @@ -51,8 +51,8 @@ class GeometrySphere : public Geometry protected: std::shared_ptr>> m_position; //!< Position for each sphere - std::shared_ptr> m_radius; //!< Per-particle radii - std::shared_ptr>> m_color; //!< Per-particle color + std::shared_ptr> m_radius; //!< Per-particle radii + std::shared_ptr>> m_color; //!< Per-particle color }; //! Export GeometrySphere to python diff --git a/fresnel/gpu/Scene.h b/fresnel/gpu/Scene.h index 2c2e09a4..1a97019c 100644 --- a/fresnel/gpu/Scene.h +++ b/fresnel/gpu/Scene.h @@ -131,14 +131,14 @@ class Scene } private: - optix::GeometryGroup m_root; //!< Store the scene root object - optix::Acceleration m_accel; //!< Store the acceleration structure + optix::GeometryGroup m_root; //!< Store the scene root object + optix::Acceleration m_accel; //!< Store the acceleration structure std::shared_ptr m_device; //!< The device the scene is attached to RGB m_background_color; //!< The background color - float m_background_alpha; //!< Background alpha - UserCamera m_camera; //!< The camera - Lights m_lights; //!< The lights + float m_background_alpha; //!< Background alpha + UserCamera m_camera; //!< The camera + Lights m_lights; //!< The lights }; //! Export Scene to python diff --git a/fresnel/gpu/Tracer.h b/fresnel/gpu/Tracer.h index a3ab7390..0282559f 100644 --- a/fresnel/gpu/Tracer.h +++ b/fresnel/gpu/Tracer.h @@ -80,22 +80,22 @@ class Tracer protected: std::shared_ptr m_device; //!< The device the Scene is attached to - unsigned int m_w; //!< Width of the output buffer - unsigned int m_h; //!< Height of the output buffer - optix::Buffer m_linear_out_gpu; //!< The GPU linear output buffer - optix::Buffer m_srgb_out_gpu; //!< The GPU linear output buffer + unsigned int m_w; //!< Width of the output buffer + unsigned int m_h; //!< Height of the output buffer + optix::Buffer m_linear_out_gpu; //!< The GPU linear output buffer + optix::Buffer m_srgb_out_gpu; //!< The GPU linear output buffer std::shared_ptr>> m_linear_out_py; //!< The linear output buffer for python std::shared_ptr>> m_srgb_out_py; //!< The sRGB output buffer for python - optix::Program m_ray_gen; //!< Ray generation program + optix::Program m_ray_gen; //!< Ray generation program optix::Program m_exception_program; //!< Exception program - unsigned int m_ray_gen_entry; //!< Entry point of the ray generation program + unsigned int m_ray_gen_entry; //!< Entry point of the ray generation program bool m_highlight_warning; //!< Set to true to enable highlight warnings in sRGB output RGB m_highlight_warning_color; //!< The highlight warning color - unsigned int m_seed = 0; //!< Random number seed + unsigned int m_seed = 0; //!< Random number seed }; //! Export Tracer to python diff --git a/fresnel/gpu/TracerPath.h b/fresnel/gpu/TracerPath.h index a718be8f..fadd87d3 100644 --- a/fresnel/gpu/TracerPath.h +++ b/fresnel/gpu/TracerPath.h @@ -59,7 +59,7 @@ class TracerPath : public Tracer } protected: - unsigned int m_n_samples; //!< Number of samples taken since the last reset + unsigned int m_n_samples; //!< Number of samples taken since the last reset unsigned int m_light_samples; //!< Number of light samples to take each render() }; diff --git a/fresnel/gpu/path.cu b/fresnel/gpu/path.cu index ec6fc3c5..1a10da8b 100644 --- a/fresnel/gpu/path.cu +++ b/fresnel/gpu/path.cu @@ -97,7 +97,7 @@ RT_PROGRAM void path_ray_gen() if (prd.done) break; } // end depth loop - } // end light samples loop + } // end light samples loop RGBA output_sample(prd.result / float(light_samples), prd.a); diff --git a/run-clang-format.py b/run-clang-format.py deleted file mode 100755 index 186f66e1..00000000 --- a/run-clang-format.py +++ /dev/null @@ -1,379 +0,0 @@ -#!/usr/bin/env python -"""A wrapper script around clang-format, suitable for linting multiple files -and to use for continuous integration. - -This is an alternative API for the clang-format command line. -It runs over multiple files and directories in parallel. -A diff output is produced and a sensible exit code is returned. - -""" - -from __future__ import print_function, unicode_literals - -import argparse -import codecs -import difflib -import fnmatch -import io -import errno -import multiprocessing -import os -import signal -import subprocess -import sys -import traceback - -from functools import partial - -try: - from subprocess import DEVNULL # py3k -except ImportError: - DEVNULL = open(os.devnull, "wb") - - -DEFAULT_EXTENSIONS = 'c,h,C,H,cpp,hpp,cc,hh,c++,h++,cxx,hxx,cu,cuh' -DEFAULT_CLANG_FORMAT_IGNORE = '.clang-format-ignore' - - -class ExitStatus: - SUCCESS = 0 - DIFF = 1 - TROUBLE = 2 - -def excludes_from_file(ignore_file): - excludes = [] - try: - with io.open(ignore_file, 'r', encoding='utf-8') as f: - for line in f: - if line.startswith('#'): - # ignore comments - continue - pattern = line.rstrip() - if not pattern: - # allow empty lines - continue - excludes.append(pattern) - except EnvironmentError as e: - if e.errno != errno.ENOENT: - raise - return excludes; - -def list_files(files, recursive=False, extensions=None, exclude=None): - if extensions is None: - extensions = [] - if exclude is None: - exclude = [] - - out = [] - for file in files: - if recursive and os.path.isdir(file): - for dirpath, dnames, fnames in os.walk(file): - fpaths = [os.path.join(dirpath, fname) for fname in fnames] - for pattern in exclude: - # os.walk() supports trimming down the dnames list - # by modifying it in-place, - # to avoid unnecessary directory listings. - dnames[:] = [ - x for x in dnames - if - not fnmatch.fnmatch(os.path.join(dirpath, x), pattern) - ] - fpaths = [ - x for x in fpaths if not fnmatch.fnmatch(x, pattern) - ] - for f in fpaths: - ext = os.path.splitext(f)[1][1:] - if ext in extensions: - out.append(f) - else: - out.append(file) - return out - - -def make_diff(file, original, reformatted): - return list( - difflib.unified_diff( - original, - reformatted, - fromfile='{}\t(original)'.format(file), - tofile='{}\t(reformatted)'.format(file), - n=3)) - - -class DiffError(Exception): - def __init__(self, message, errs=None): - super(DiffError, self).__init__(message) - self.errs = errs or [] - - -class UnexpectedError(Exception): - def __init__(self, message, exc=None): - super(UnexpectedError, self).__init__(message) - self.formatted_traceback = traceback.format_exc() - self.exc = exc - - -def run_clang_format_diff_wrapper(args, file): - try: - ret = run_clang_format_diff(args, file) - return ret - except DiffError: - raise - except Exception as e: - raise UnexpectedError('{}: {}: {}'.format(file, e.__class__.__name__, - e), e) - - -def run_clang_format_diff(args, file): - try: - with io.open(file, 'r', encoding='utf-8') as f: - original = f.readlines() - except IOError as exc: - raise DiffError(str(exc)) - invocation = [args.clang_format_executable, file] - - # Use of utf-8 to decode the process output. - # - # Hopefully, this is the correct thing to do. - # - # It's done due to the following assumptions (which may be incorrect): - # - clang-format will returns the bytes read from the files as-is, - # without conversion, and it is already assumed that the files use utf-8. - # - if the diagnostics were internationalized, they would use utf-8: - # > Adding Translations to Clang - # > - # > Not possible yet! - # > Diagnostic strings should be written in UTF-8, - # > the client can translate to the relevant code page if needed. - # > Each translation completely replaces the format string - # > for the diagnostic. - # > -- http://clang.llvm.org/docs/InternalsManual.html#internals-diag-translation - # - # It's not pretty, due to Python 2 & 3 compatibility. - encoding_py3 = {} - if sys.version_info[0] >= 3: - encoding_py3['encoding'] = 'utf-8' - - try: - proc = subprocess.Popen( - invocation, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - universal_newlines=True, - **encoding_py3) - except OSError as exc: - raise DiffError( - "Command '{}' failed to start: {}".format( - subprocess.list2cmdline(invocation), exc - ) - ) - proc_stdout = proc.stdout - proc_stderr = proc.stderr - if sys.version_info[0] < 3: - # make the pipes compatible with Python 3, - # reading lines should output unicode - encoding = 'utf-8' - proc_stdout = codecs.getreader(encoding)(proc_stdout) - proc_stderr = codecs.getreader(encoding)(proc_stderr) - # hopefully the stderr pipe won't get full and block the process - outs = list(proc_stdout.readlines()) - errs = list(proc_stderr.readlines()) - proc.wait() - if proc.returncode: - raise DiffError( - "Command '{}' returned non-zero exit status {}".format( - subprocess.list2cmdline(invocation), proc.returncode - ), - errs, - ) - return make_diff(file, original, outs), errs - - -def bold_red(s): - return '\x1b[1m\x1b[31m' + s + '\x1b[0m' - - -def colorize(diff_lines): - def bold(s): - return '\x1b[1m' + s + '\x1b[0m' - - def cyan(s): - return '\x1b[36m' + s + '\x1b[0m' - - def green(s): - return '\x1b[32m' + s + '\x1b[0m' - - def red(s): - return '\x1b[31m' + s + '\x1b[0m' - - for line in diff_lines: - if line[:4] in ['--- ', '+++ ']: - yield bold(line) - elif line.startswith('@@ '): - yield cyan(line) - elif line.startswith('+'): - yield green(line) - elif line.startswith('-'): - yield red(line) - else: - yield line - - -def print_diff(diff_lines, use_color): - if use_color: - diff_lines = colorize(diff_lines) - if sys.version_info[0] < 3: - sys.stdout.writelines((l.encode('utf-8') for l in diff_lines)) - else: - sys.stdout.writelines(diff_lines) - - -def print_trouble(prog, message, use_colors): - error_text = 'error:' - if use_colors: - error_text = bold_red(error_text) - print("{}: {} {}".format(prog, error_text, message), file=sys.stderr) - - -def main(): - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument( - '--clang-format-executable', - metavar='EXECUTABLE', - help='path to the clang-format executable', - default='clang-format') - parser.add_argument( - '--extensions', - help='comma separated list of file extensions (default: {})'.format( - DEFAULT_EXTENSIONS), - default=DEFAULT_EXTENSIONS) - parser.add_argument( - '-r', - '--recursive', - action='store_true', - help='run recursively over directories') - parser.add_argument('files', metavar='file', nargs='+') - parser.add_argument( - '-q', - '--quiet', - action='store_true', - help="disable output, useful for the exit code") - parser.add_argument( - '-j', - metavar='N', - type=int, - default=0, - help='run N clang-format jobs in parallel' - ' (default number of cpus + 1)') - parser.add_argument( - '--color', - default='auto', - choices=['auto', 'always', 'never'], - help='show colored diff (default: auto)') - parser.add_argument( - '-e', - '--exclude', - metavar='PATTERN', - action='append', - default=[], - help='exclude paths matching the given glob-like pattern(s)' - ' from recursive search') - - args = parser.parse_args() - - # use default signal handling, like diff return SIGINT value on ^C - # https://bugs.python.org/issue14229#msg156446 - signal.signal(signal.SIGINT, signal.SIG_DFL) - try: - signal.SIGPIPE - except AttributeError: - # compatibility, SIGPIPE does not exist on Windows - pass - else: - signal.signal(signal.SIGPIPE, signal.SIG_DFL) - - colored_stdout = False - colored_stderr = False - if args.color == 'always': - colored_stdout = True - colored_stderr = True - elif args.color == 'auto': - colored_stdout = sys.stdout.isatty() - colored_stderr = sys.stderr.isatty() - - version_invocation = [args.clang_format_executable, str("--version")] - try: - subprocess.check_call(version_invocation, stdout=DEVNULL) - except subprocess.CalledProcessError as e: - print_trouble(parser.prog, str(e), use_colors=colored_stderr) - return ExitStatus.TROUBLE - except OSError as e: - print_trouble( - parser.prog, - "Command '{}' failed to start: {}".format( - subprocess.list2cmdline(version_invocation), e - ), - use_colors=colored_stderr, - ) - return ExitStatus.TROUBLE - - retcode = ExitStatus.SUCCESS - - excludes = excludes_from_file(DEFAULT_CLANG_FORMAT_IGNORE) - excludes.extend(args.exclude) - - files = list_files( - args.files, - recursive=args.recursive, - exclude=excludes, - extensions=args.extensions.split(',')) - - if not files: - return - - njobs = args.j - if njobs == 0: - njobs = multiprocessing.cpu_count() + 1 - njobs = min(len(files), njobs) - - if njobs == 1: - # execute directly instead of in a pool, - # less overhead, simpler stacktraces - it = (run_clang_format_diff_wrapper(args, file) for file in files) - pool = None - else: - pool = multiprocessing.Pool(njobs) - it = pool.imap_unordered( - partial(run_clang_format_diff_wrapper, args), files) - while True: - try: - outs, errs = next(it) - except StopIteration: - break - except DiffError as e: - print_trouble(parser.prog, str(e), use_colors=colored_stderr) - retcode = ExitStatus.TROUBLE - sys.stderr.writelines(e.errs) - except UnexpectedError as e: - print_trouble(parser.prog, str(e), use_colors=colored_stderr) - sys.stderr.write(e.formatted_traceback) - retcode = ExitStatus.TROUBLE - # stop at the first unexpected error, - # something could be very wrong, - # don't process all files unnecessarily - if pool: - pool.terminate() - break - else: - sys.stderr.writelines(errs) - if outs == []: - continue - if not args.quiet: - print_diff(outs, use_color=colored_stdout) - if retcode == ExitStatus.SUCCESS: - retcode = ExitStatus.DIFF - return retcode - - -if __name__ == '__main__': - sys.exit(main())