diff --git a/.gitignore b/.gitignore index 63b642bbc..0b7d1d975 100644 --- a/.gitignore +++ b/.gitignore @@ -28,9 +28,10 @@ input_* ### Executables and Libraries ### /spirit -spirit.js -spirit.js.mem -spirit.wasm +libSpirit.js +libSpirit.js.mem +libSpirit.wasm +libSpirit.wast ### Generated Files core/python/LICENSE.txt diff --git a/CMake/ChooseCompiler.cmake b/CMake/ChooseCompiler.cmake index 454eb5bb4..eed07b575 100644 --- a/CMake/ChooseCompiler.cmake +++ b/CMake/ChooseCompiler.cmake @@ -2,12 +2,12 @@ MESSAGE( STATUS ">> ------------------------------------------------------------ MESSAGE( STATUS ">> --------------------- ChooseCompiler.cmake ------------------------- <<" ) ######## UI Web - this means we need emcc ########################### if (SPIRIT_BUILD_FOR_JS) - ### + ### MESSAGE( STATUS ">> Choosing compiler: emcc" ) ### Set the path to emscripten - # SET(EMSCRIPTEN_ROOT_PATH "/usr/local/emsdk/emscripten/1.38.29/") + SET(EMSCRIPTEN_ROOT_PATH "/usr/local/emsdk/emscripten/1.38.29/") ### Use the Emscripten toolchain file - # SET(CMAKE_TOOLCHAIN_FILE /usr/local/emsdk/emscripten/1.38.13/cmake/Modules/Platform/Emscripten) + SET(CMAKE_TOOLCHAIN_FILE Emscripten) ###################################################################### diff --git a/CMakeLists.txt b/CMakeLists.txt index bb19af59f..b4ac50d18 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -213,6 +213,7 @@ endif( ) add_subdirectory( core ) ### Web UI if( SPIRIT_BUILD_FOR_JS ) + add_subdirectory( VFRendering ) add_subdirectory( ui-web ) ### CXX UI elseif( SPIRIT_BUILD_FOR_CXX ) diff --git a/VFRendering/CMakeLists.txt b/VFRendering/CMakeLists.txt index abb9410ad..4afede693 100755 --- a/VFRendering/CMakeLists.txt +++ b/VFRendering/CMakeLists.txt @@ -20,6 +20,7 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON) include(ExternalProject) ExternalProject_add(qhull GIT_REPOSITORY https://github.com/qhull/qhull.git + GIT_TAG v7.3.1 CMAKE_ARGS "-DCMAKE_INSTALL_PREFIX=${PROJECT_BINARY_DIR}/thirdparty-install;-DCMAKE_POSITION_INDEPENDENT_CODE=ON" PREFIX qhull-prefix ) @@ -56,11 +57,13 @@ endif() set(SOURCE_FILES src/ArrowRenderer.cxx src/BoundingBoxRenderer.cxx + src/ParallelepipedRenderer.cxx src/CombinedRenderer.cxx src/CoordinateSystemRenderer.cxx src/FPSCounter.cxx src/Geometry.cxx src/GlyphRenderer.cxx + src/DotRenderer.cxx src/IsosurfaceRenderer.cxx src/Options.cxx src/RendererBase.cxx @@ -79,10 +82,12 @@ set(HEADER_FILES include/VectorfieldIsosurface.hxx include/VFRendering/ArrowRenderer.hxx include/VFRendering/BoundingBoxRenderer.hxx + include/VFRendering/ParallelepipedRenderer.hxx include/VFRendering/CombinedRenderer.hxx include/VFRendering/CoordinateSystemRenderer.hxx include/VFRendering/FPSCounter.hxx include/VFRendering/GlyphRenderer.hxx + include/VFRendering/DotRenderer.hxx include/VFRendering/Geometry.hxx include/VFRendering/IsosurfaceRenderer.hxx include/VFRendering/Options.hxx @@ -95,6 +100,8 @@ set(HEADER_FILES include/VFRendering/VectorSphereRenderer.hxx include/VFRendering/View.hxx include/shaders + include/shaders/dot.frag.glsl.hxx + include/shaders/dot.vert.glsl.hxx include/shaders/glyphs.frag.glsl.hxx include/shaders/glyphs.vert.glsl.hxx include/shaders/boundingbox.frag.glsl.hxx diff --git a/VFRendering/Version.txt b/VFRendering/Version.txt old mode 100644 new mode 100755 index d9df1bbc0..a803cc227 --- a/VFRendering/Version.txt +++ b/VFRendering/Version.txt @@ -1 +1 @@ -0.11.0 +0.14.0 diff --git a/VFRendering/demo.py b/VFRendering/demo.py old mode 100644 new mode 100755 index ad3a4102f..18fb7bbb8 --- a/VFRendering/demo.py +++ b/VFRendering/demo.py @@ -21,7 +21,7 @@ from PyQt5.QtCore import pyqtSlot, QTimer from PyQt5.QtCore import Qt -import build.pyVFRendering as vfr +import pyVFRendering as vfr class MainWindow(QMainWindow): @@ -85,7 +85,7 @@ def initializeGL(self): renderer_cs.setNormalize(True) # Add renderers to view self.renderers = [ (renderer_arrows, [0.0, 0.0, 1.0, 1.0]), (renderer_boundingbox, [0.0, 0.0, 1.0, 1.0]), (renderer_cs, [0.0, 0.0, 0.2, 0.2]) ] - self.view.renderers(self.renderers) + self.view.renderers(self.renderers, True) # Options self.options = vfr.Options() diff --git a/VFRendering/include/VFRendering/BoundingBoxRenderer.hxx b/VFRendering/include/VFRendering/BoundingBoxRenderer.hxx index 1c0552375..b48752ebc 100755 --- a/VFRendering/include/VFRendering/BoundingBoxRenderer.hxx +++ b/VFRendering/include/VFRendering/BoundingBoxRenderer.hxx @@ -7,7 +7,9 @@ namespace VFRendering { class BoundingBoxRenderer : public RendererBase { public: enum Option { - COLOR = 600 + COLOR = 600, + LEVEL_OF_DETAIL, + LINE_WIDTH }; @@ -21,6 +23,7 @@ public: protected: virtual void update(bool keep_geometry) override; + void updateVertexData(); private: void initialize(); @@ -30,6 +33,7 @@ private: unsigned int m_vao = 0; unsigned int m_vbo = 0; unsigned int m_dash_vbo = 0; + unsigned int num_vertices = 0; std::vector m_vertices; std::vector m_dashing_values; }; @@ -39,6 +43,16 @@ template<> struct Options::Option{ glm::vec3 default_value = {1.0, 1.0, 1.0}; }; + +template<> +struct Options::Option{ + int default_value = 10; +}; + +template<> +struct Options::Option{ + float default_value = 0.0; +}; } } diff --git a/VFRendering/include/VFRendering/DotRenderer.hxx b/VFRendering/include/VFRendering/DotRenderer.hxx new file mode 100755 index 000000000..716ff41dd --- /dev/null +++ b/VFRendering/include/VFRendering/DotRenderer.hxx @@ -0,0 +1,62 @@ +#ifndef VFRENDERING_DOT_RENDERER_HXX +#define VFRENDERING_DOT_RENDERER_HXX + +#include + +namespace VFRendering { +class DotRenderer : public VectorFieldRenderer { +public: + + enum Option { + COLORMAP_IMPLEMENTATION = 140, + IS_VISIBLE_IMPLEMENTATION, + DOT_RADIUS, + DOT_STYLE + }; + + enum DotStyle { + CIRCLE, + SQUARE + }; + + DotRenderer(const View& view, const VectorField& vf); + virtual ~DotRenderer(); + virtual void update(bool keep_geometry) override; + virtual void draw(float aspect_ratio) override; + virtual void optionsHaveChanged(const std::vector& changed_options) override; + std::string getDotStyle(const DotStyle& dotstyle); + +private: + void updateShaderProgram(); + void updateVertexData(); + void initialize(); + + bool m_is_initialized = false; + + unsigned int m_program = 0; + unsigned int m_vao = 0; + + unsigned int m_instance_position_vbo = 0; + unsigned int m_instance_direction_vbo = 0; + + unsigned int m_num_instances = 0; +}; + +namespace Utilities { + +template<> +struct Options::Option { + float default_value = 1.f; +}; + +template<> +struct Options::Option { + DotRenderer::DotStyle default_value = DotRenderer::DotStyle::CIRCLE; +}; + +// COLORMAP_IMPLEMENTATION & IS_VISIBLE_IMPLEMENTATION define in View.hxx + +} + +} +#endif diff --git a/VFRendering/include/VFRendering/GlyphRenderer.hxx b/VFRendering/include/VFRendering/GlyphRenderer.hxx old mode 100644 new mode 100755 index 7e1b215ac..1bba5217c --- a/VFRendering/include/VFRendering/GlyphRenderer.hxx +++ b/VFRendering/include/VFRendering/GlyphRenderer.hxx @@ -6,6 +6,9 @@ namespace VFRendering { class GlyphRenderer : public VectorFieldRenderer { public: + enum Option { + ROTATE_GLYPHS = 1000 + }; GlyphRenderer(const View& view, const VectorField& vf); virtual ~GlyphRenderer(); @@ -33,6 +36,13 @@ private: unsigned int m_num_indices = 0; unsigned int m_num_instances = 0; }; + +namespace Utilities { +template<> +struct Options::Option { + bool default_value = true; +}; +} } #endif diff --git a/VFRendering/include/VFRendering/ParallelepipedRenderer.hxx b/VFRendering/include/VFRendering/ParallelepipedRenderer.hxx new file mode 100755 index 000000000..10dc21a4d --- /dev/null +++ b/VFRendering/include/VFRendering/ParallelepipedRenderer.hxx @@ -0,0 +1,41 @@ +#ifndef VFRENDERING_PARALLELEPIPED_RENDERER_HXX +#define VFRENDERING_PARALLELEPIPED_RENDERER_HXX + +#include + +namespace VFRendering { + +class ParallelepipedRenderer : public GlyphRenderer { +public: + enum Option { + LENGTH_A = 100, + LENGTH_B, + LENGTH_C + }; + + ParallelepipedRenderer(const View& view, const VectorField& vf); + virtual void optionsHaveChanged(const std::vector& changed_options) override; +}; + +namespace Utilities { + +template<> +struct Options::Option { + float default_value = 1.f; +}; + +template<> +struct Options::Option { + float default_value = 1.f; +}; + +template<> +struct Options::Option { + float default_value = 1.f; +}; + +} + +} + +#endif diff --git a/VFRendering/include/VFRendering/RendererBase.hxx b/VFRendering/include/VFRendering/RendererBase.hxx old mode 100644 new mode 100755 index 13c11b298..ab3f121ba --- a/VFRendering/include/VFRendering/RendererBase.hxx +++ b/VFRendering/include/VFRendering/RendererBase.hxx @@ -22,15 +22,14 @@ public: void setOption(const typename Options::Type::type& value); const Options& options() const; template - const typename Options::Type::type& getOption() const; + typename Options::Type::type getOption() const; virtual void optionsHaveChanged(const std::vector& changed_options); virtual void updateIfNecessary(); protected: virtual void options(const Options& options); - -private: const View& m_view; +private: Options m_options; }; @@ -40,8 +39,8 @@ void RendererBase::setOption(const typename Options::Type::type& value) { } template -const typename Options::Type::type& RendererBase::getOption() const { - return m_options.get();; +typename Options::Type::type RendererBase::getOption() const { + return m_options.get(); } } diff --git a/VFRendering/include/VFRendering/VectorField.hxx b/VFRendering/include/VFRendering/VectorField.hxx old mode 100644 new mode 100755 diff --git a/VFRendering/include/VFRendering/View.hxx b/VFRendering/include/VFRendering/View.hxx old mode 100644 new mode 100755 index 9b3908d64..8061c3e32 --- a/VFRendering/include/VFRendering/View.hxx +++ b/VFRendering/include/VFRendering/View.hxx @@ -43,6 +43,7 @@ public: void mouseScroll(const float& wheel_delta); void setFramebufferSize(float width, float height); float getFramerate() const; + glm::vec2 getFramebufferSize() const; void updateOptions(const Options& options); template @@ -50,7 +51,7 @@ public: void options(const Options& options); const Options& options() const; template - const typename Options::Type::type& getOption() const; + typename Options::Type::type getOption() const; void renderers(const std::vector, std::array>>& renderers, bool update_renderer_options=true); @@ -74,7 +75,7 @@ void View::setOption(const typename Options::Type::type& value) { } template -const typename Options::Type::type& View::getOption() const { +typename Options::Type::type View::getOption() const { return m_options.get(); } diff --git a/VFRendering/include/shaders/boundingbox.frag.glsl.hxx b/VFRendering/include/shaders/boundingbox.frag.glsl.hxx index a00f7baf9..1d279fe24 100755 --- a/VFRendering/include/shaders/boundingbox.frag.glsl.hxx +++ b/VFRendering/include/shaders/boundingbox.frag.glsl.hxx @@ -1,17 +1,16 @@ #ifndef BOUNDINGBOX_FRAG_GLSL_HXX #define BOUNDINGBOX_FRAG_GLSL_HXX -static const std::string BOUNDINGBOX_FRAG_GLSL = R"LITERAL( -#version 330 +#include "shader_header.hxx" + +static const std::string BOUNDINGBOX_FRAG_GLSL = FRAG_SHADER_HEADER + R"LITERAL( uniform vec3 uColor; in float vfDashingValue; -out vec4 fo_FragColor; - void main(void) { - if (int(floor(vfDashingValue)) % 2 != 0) { + if (mod(floor(vfDashingValue), 2.0) != 0.0) { discard; } fo_FragColor = vec4(uColor, 1.0); diff --git a/VFRendering/include/shaders/boundingbox.vert.glsl.hxx b/VFRendering/include/shaders/boundingbox.vert.glsl.hxx index cd1f8f6fb..9ecd4871c 100755 --- a/VFRendering/include/shaders/boundingbox.vert.glsl.hxx +++ b/VFRendering/include/shaders/boundingbox.vert.glsl.hxx @@ -1,8 +1,9 @@ #ifndef BOUNDINGBOX_VERT_GLSL_HXX #define BOUNDINGBOX_VERT_GLSL_HXX -static const std::string BOUNDINGBOX_VERT_GLSL = R"LITERAL( -#version 330 +#include "shader_header.hxx" + +static const std::string BOUNDINGBOX_VERT_GLSL = VERT_SHADER_HEADER + R"LITERAL( uniform mat4 uProjectionMatrix; uniform mat4 uModelviewMatrix; diff --git a/VFRendering/include/shaders/colormap.bluewhitered.glsl.hxx b/VFRendering/include/shaders/colormap.bluewhitered.glsl.hxx index e314886e0..ff47f47a5 100755 --- a/VFRendering/include/shaders/colormap.bluewhitered.glsl.hxx +++ b/VFRendering/include/shaders/colormap.bluewhitered.glsl.hxx @@ -3,10 +3,10 @@ static const std::string COLORMAP_BLUEWHITERED_GLSL = R"LITERAL( vec3 colormap(vec3 direction) { - if (direction.z < 0) { + if (direction.z < 0.0) { vec3 color_down = vec3(0.0, 0.0, 1.0); vec3 color_up = vec3(1.0, 1.0, 1.0); - return mix(color_down, color_up, normalize(direction).z+1); + return mix(color_down, color_up, normalize(direction).z+1.0); } else { vec3 color_down = vec3(1.0, 1.0, 1.0); vec3 color_up = vec3(1.0, 0.0, 0.0); diff --git a/VFRendering/include/shaders/coordinatesystem.frag.glsl.hxx b/VFRendering/include/shaders/coordinatesystem.frag.glsl.hxx index 182e07894..f7f10e9e2 100755 --- a/VFRendering/include/shaders/coordinatesystem.frag.glsl.hxx +++ b/VFRendering/include/shaders/coordinatesystem.frag.glsl.hxx @@ -1,12 +1,12 @@ #ifndef COORDINATESYSTEM_FRAG_GLSL_HXX #define COORDINATESYSTEM_FRAG_GLSL_HXX -static const std::string COORDINATESYSTEM_FRAG_GLSL = R"LITERAL( -#version 330 +#include "shader_header.hxx" + +static const std::string COORDINATESYSTEM_FRAG_GLSL = FRAG_SHADER_HEADER + R"LITERAL( in vec3 vfColor; in vec3 vfNormal; -out vec4 fo_FragColor; void main(void) { fo_FragColor = vec4(vfColor*abs(normalize(vfNormal).z), 1.0); diff --git a/VFRendering/include/shaders/coordinatesystem.vert.glsl.hxx b/VFRendering/include/shaders/coordinatesystem.vert.glsl.hxx index da91099be..39d43af06 100755 --- a/VFRendering/include/shaders/coordinatesystem.vert.glsl.hxx +++ b/VFRendering/include/shaders/coordinatesystem.vert.glsl.hxx @@ -1,8 +1,9 @@ #ifndef COORDINATESYSTEM_VERT_GLSL_HXX #define COORDINATESYSTEM_VERT_GLSL_HXX -static const std::string COORDINATESYSTEM_VERT_GLSL = R"LITERAL( -#version 330 +#include "shader_header.hxx" + +static const std::string COORDINATESYSTEM_VERT_GLSL = VERT_SHADER_HEADER + R"LITERAL( uniform mat4 uProjectionMatrix; uniform mat4 uModelviewMatrix; diff --git a/VFRendering/include/shaders/dots.vert.glsl.hxx b/VFRendering/include/shaders/dots.vert.glsl.hxx new file mode 100755 index 000000000..87f862f50 --- /dev/null +++ b/VFRendering/include/shaders/dots.vert.glsl.hxx @@ -0,0 +1,36 @@ +#ifndef DOTS_VERT_GLSL_HXX +#define DOTS_VERT_GLSL_HXX + +#include "shader_header.hxx" + +static const std::string DOT_VERT_GLSL = VERT_SHADER_HEADER + R"LITERAL( + +uniform mat4 uProjectionMatrix; +uniform mat4 uModelviewMatrix; +uniform float uDotRadius; + +in vec3 ivDotCoordinates; +in vec3 ivDotDirection; +out vec3 vfColor; + +vec3 colormap(vec3 direction); + +bool is_visible(vec3 position, vec3 direction); + +void main(void) { + float direction_length = length( ivDotDirection ); + + if ( is_visible( ivDotCoordinates, ivDotDirection ) && direction_length > 0.0) { + vfColor = colormap( normalize( ivDotDirection ) ); + vec3 vfPosition = ( uModelviewMatrix * vec4( ivDotCoordinates, 1.0 ) ).xyz; + gl_Position = uProjectionMatrix * vec4( vfPosition, 1.0 ); + } else { + gl_Position = vec4(2.0, 2.0, 2.0, 0.0); + } + + gl_PointSize = uDotRadius / gl_Position.z; + float point_size = gl_PointSize; +} +)LITERAL"; + +#endif diff --git a/VFRendering/include/shaders/dots_circle.frag.glsl.hxx b/VFRendering/include/shaders/dots_circle.frag.glsl.hxx new file mode 100755 index 000000000..c8b91a6a2 --- /dev/null +++ b/VFRendering/include/shaders/dots_circle.frag.glsl.hxx @@ -0,0 +1,19 @@ +#ifndef DOTS_CIRCLE_FRAG_GLSL_HXX +#define DOTS_CIRCLE_FRAG_GLSL_HXX + +#include "shader_header.hxx" + +static const std::string DOT_CIRCLE_FRAG_GLSL = FRAG_SHADER_HEADER + R"LITERAL( + +in vec3 vfColor; + +void main(void) { + if( dot( gl_PointCoord-0.5, gl_PointCoord-0.5 ) > 0.25 ) + discard; + else + fo_FragColor = vec4( vfColor, 1.0 ); +} +)LITERAL"; + +#endif + diff --git a/VFRendering/include/shaders/dots_square.frag.glsl.hxx b/VFRendering/include/shaders/dots_square.frag.glsl.hxx new file mode 100755 index 000000000..b3b0f2214 --- /dev/null +++ b/VFRendering/include/shaders/dots_square.frag.glsl.hxx @@ -0,0 +1,15 @@ +#ifndef DOTS_SQUARE_FRAG_GLSL_HXX +#define DOTS_SQUARE_FRAG_GLSL_HXX +#include "shader_header.hxx" + +static const std::string DOT_SQUARE_FRAG_GLSL = FRAG_SHADER_HEADER + R"LITERAL( + +in vec3 vfColor; + +void main(void) { + fo_FragColor = vec4( vfColor, 1.0 ); +} +)LITERAL"; + +#endif + diff --git a/VFRendering/include/shaders/glyphs.frag.glsl.hxx b/VFRendering/include/shaders/glyphs.frag.glsl.hxx old mode 100644 new mode 100755 index f5bc250b2..410191742 --- a/VFRendering/include/shaders/glyphs.frag.glsl.hxx +++ b/VFRendering/include/shaders/glyphs.frag.glsl.hxx @@ -1,13 +1,13 @@ -#ifndef ARROWS_FRAG_GLSL_HXX -#define ARROWS_FRAG_GLSL_HXX +#ifndef GLYPHS_FRAG_GLSL_HXX +#define GLYPHS_FRAG_GLSL_HXX -static const std::string ARROWS_FRAG_GLSL = R"LITERAL( -#version 330 +#include "shader_header.hxx" + +static const std::string GLYPHS_FRAG_GLSL = FRAG_SHADER_HEADER + R"LITERAL( uniform vec3 uLightPosition; in vec3 vfPosition; in vec3 vfNormal; in vec3 vfColor; -out vec4 fo_FragColor; void main(void) { vec3 cameraLocation = vec3(0, 0, 0); diff --git a/VFRendering/include/shaders/glyphs.vert.glsl.hxx b/VFRendering/include/shaders/glyphs.vert.glsl.hxx old mode 100644 new mode 100755 index b044148b6..e3efe75c0 --- a/VFRendering/include/shaders/glyphs.vert.glsl.hxx +++ b/VFRendering/include/shaders/glyphs.vert.glsl.hxx @@ -1,8 +1,9 @@ -#ifndef ARROWS_VERT_GLSL_HXX -#define ARROWS_VERT_GLSL_HXX +#ifndef GLYPHS_VERT_GLSL_HXX +#define GLYPHS_VERT_GLSL_HXX -static const std::string ARROWS_VERT_GLSL = R"LITERAL( -#version 330 +#include "shader_header.hxx" + +static const std::string GLYPHS_ROTATED_VERT_GLSL = VERT_SHADER_HEADER + R"LITERAL( uniform mat4 uProjectionMatrix; uniform mat4 uModelviewMatrix; uniform vec2 uZRange; @@ -41,7 +42,7 @@ bool is_visible(vec3 position, vec3 direction); void main(void) { float direction_length = length(ivInstanceDirection); - if (is_visible(ivInstanceOffset, ivInstanceDirection) && direction_length > 0) { + if (is_visible(ivInstanceOffset, ivInstanceDirection) && direction_length > 0.0) { vfColor = colormap(normalize(ivInstanceDirection)); mat3 instanceMatrix = direction_length * matrixFromDirection(ivInstanceDirection/direction_length); vfNormal = (uModelviewMatrix * vec4(instanceMatrix*ivNormal, 0.0)).xyz; @@ -53,5 +54,35 @@ void main(void) { } )LITERAL"; +static const std::string GLYPHS_UNROTATED_VERT_GLSL = VERT_SHADER_HEADER + R"LITERAL( +uniform mat4 uProjectionMatrix; +uniform mat4 uModelviewMatrix; +uniform vec2 uZRange; +in vec3 ivPosition; +in vec3 ivNormal; +in vec3 ivInstanceOffset; +in vec3 ivInstanceDirection; +out vec3 vfPosition; +out vec3 vfNormal; +out vec3 vfColor; + +vec3 colormap(vec3 direction); + +bool is_visible(vec3 position, vec3 direction); + +void main(void) { + float direction_length = length(ivInstanceDirection); + if (is_visible(ivInstanceOffset, ivInstanceDirection) && direction_length > 0.0) { + vfColor = colormap(normalize(ivInstanceDirection)); + mat3 instanceMatrix = mat3(direction_length); + vfNormal = (uModelviewMatrix * vec4(instanceMatrix*ivNormal, 0.0)).xyz; + vfPosition = (uModelviewMatrix * vec4(instanceMatrix*ivPosition+ivInstanceOffset, 1.0)).xyz; + gl_Position = uProjectionMatrix * vec4(vfPosition, 1.0); + } else { + gl_Position = vec4(2.0, 2.0, 2.0, 0.0); + } +} +)LITERAL"; + #endif diff --git a/VFRendering/include/shaders/isosurface.frag.glsl.hxx b/VFRendering/include/shaders/isosurface.frag.glsl.hxx index 3f6dd7a64..73995f629 100755 --- a/VFRendering/include/shaders/isosurface.frag.glsl.hxx +++ b/VFRendering/include/shaders/isosurface.frag.glsl.hxx @@ -1,13 +1,13 @@ #ifndef ISOSURFACE_FRAG_GLSL_HXX #define ISOSURFACE_FRAG_GLSL_HXX -static const std::string ISOSURFACE_FRAG_GLSL = R"LITERAL( -#version 330 +#include "shader_header.hxx" + +static const std::string ISOSURFACE_FRAG_GLSL = FRAG_SHADER_HEADER + R"LITERAL( in vec3 vfPosition; in vec3 vfDirection; in vec3 vfNormal; -out vec4 fo_FragColor; vec3 colormap(vec3 direction); bool is_visible(vec3 position, vec3 direction); diff --git a/VFRendering/include/shaders/isosurface.vert.glsl.hxx b/VFRendering/include/shaders/isosurface.vert.glsl.hxx index 0aded320c..4b0d6afdc 100755 --- a/VFRendering/include/shaders/isosurface.vert.glsl.hxx +++ b/VFRendering/include/shaders/isosurface.vert.glsl.hxx @@ -1,8 +1,9 @@ #ifndef ISOSURFACE_VERT_GLSL_HXX #define ISOSURFACE_VERT_GLSL_HXX -static const std::string ISOSURFACE_VERT_GLSL = R"LITERAL( -#version 330 +#include "shader_header.hxx" + +static const std::string ISOSURFACE_VERT_GLSL = VERT_SHADER_HEADER + R"LITERAL( uniform mat4 uProjectionMatrix; uniform mat4 uModelviewMatrix; diff --git a/VFRendering/include/shaders/shader_header.hxx b/VFRendering/include/shaders/shader_header.hxx new file mode 100755 index 000000000..1cf1ba78f --- /dev/null +++ b/VFRendering/include/shaders/shader_header.hxx @@ -0,0 +1,11 @@ +#ifndef SHADER_HEADER + +#ifdef __EMSCRIPTEN__ +#define VERT_SHADER_HEADER std::string("#version 100\nprecision highp float;\n#define in attribute\n#define out varying\n") +#define FRAG_SHADER_HEADER std::string("#version 100\nprecision highp float;\n#define in varying\n#define fo_FragColor gl_FragColor") +#else +#define VERT_SHADER_HEADER std::string("#version 330\n") +#define FRAG_SHADER_HEADER std::string("#version 330\nout vec4 fo_FragColor;\n") +#endif + +#endif \ No newline at end of file diff --git a/VFRendering/include/shaders/sphere_background.frag.glsl.hxx b/VFRendering/include/shaders/sphere_background.frag.glsl.hxx index 49ec16bb2..2c597ccd8 100755 --- a/VFRendering/include/shaders/sphere_background.frag.glsl.hxx +++ b/VFRendering/include/shaders/sphere_background.frag.glsl.hxx @@ -1,11 +1,11 @@ #ifndef SPHERE_BACKGROUND_FRAG_GLSL_HXX #define SPHERE_BACKGROUND_FRAG_GLSL_HXX -static const std::string SPHERE_BACKGROUND_FRAG_GLSL = R"LITERAL( -#version 330 +#include "shader_header.hxx" + +static const std::string SPHERE_BACKGROUND_FRAG_GLSL = FRAG_SHADER_HEADER + R"LITERAL( in vec3 vfPosition; -out vec4 fo_FragColor; void main(void) { float l = length(vfPosition); diff --git a/VFRendering/include/shaders/sphere_background.vert.glsl.hxx b/VFRendering/include/shaders/sphere_background.vert.glsl.hxx index 48b0f2586..3c6e3d18c 100755 --- a/VFRendering/include/shaders/sphere_background.vert.glsl.hxx +++ b/VFRendering/include/shaders/sphere_background.vert.glsl.hxx @@ -1,8 +1,9 @@ #ifndef SPHERE_BACKGROUND_VERT_GLSL_HXX #define SPHERE_BACKGROUND_VERT_GLSL_HXX -static const std::string SPHERE_BACKGROUND_VERT_GLSL = R"LITERAL( -#version 330 +#include "shader_header.hxx" + +static const std::string SPHERE_BACKGROUND_VERT_GLSL = VERT_SHADER_HEADER + R"LITERAL( uniform float uAspectRatio; uniform float uInnerSphereRadius; @@ -11,7 +12,7 @@ out vec3 vfPosition; void main(void) { vfPosition = ivPosition; - if (uAspectRatio > 1) { + if (uAspectRatio > 1.0) { gl_Position = vec4(vfPosition.xy*vec2(uInnerSphereRadius/uAspectRatio, uInnerSphereRadius), 0.0, 1.0); } else { gl_Position = vec4(vfPosition.xy*vec2(uInnerSphereRadius, uInnerSphereRadius*uAspectRatio), 0.0, 1.0); diff --git a/VFRendering/include/shaders/sphere_points.frag.glsl.hxx b/VFRendering/include/shaders/sphere_points.frag.glsl.hxx index 1940f9d29..6afca18a4 100755 --- a/VFRendering/include/shaders/sphere_points.frag.glsl.hxx +++ b/VFRendering/include/shaders/sphere_points.frag.glsl.hxx @@ -1,12 +1,12 @@ #ifndef SPHERE_POINTS_FRAG_GLSL_HXX #define SPHERE_POINTS_FRAG_GLSL_HXX -static const std::string SPHERE_POINTS_FRAG_GLSL = R"LITERAL( -#version 330 +#include "shader_header.hxx" + +static const std::string SPHERE_POINTS_FRAG_GLSL = FRAG_SHADER_HEADER + R"LITERAL( in vec3 vfPosition; in vec3 vfDirection; -out vec4 fo_FragColor; vec3 colormap(vec3 direction); diff --git a/VFRendering/include/shaders/sphere_points.vert.glsl.hxx b/VFRendering/include/shaders/sphere_points.vert.glsl.hxx index 7abfdad3f..a5e0c2732 100755 --- a/VFRendering/include/shaders/sphere_points.vert.glsl.hxx +++ b/VFRendering/include/shaders/sphere_points.vert.glsl.hxx @@ -1,8 +1,9 @@ #ifndef SPHERE_POINTS_VERT_GLSL_HXX #define SPHERE_POINTS_VERT_GLSL_HXX -static const std::string SPHERE_POINTS_VERT_GLSL = R"LITERAL( -#version 330 +#include "shader_header.hxx" + +static const std::string SPHERE_POINTS_VERT_GLSL = VERT_SHADER_HEADER + R"LITERAL( uniform mat4 uProjectionMatrix; uniform mat4 uModelviewMatrix; diff --git a/VFRendering/include/shaders/surface.frag.glsl.hxx b/VFRendering/include/shaders/surface.frag.glsl.hxx index 82c176980..c5c40898d 100755 --- a/VFRendering/include/shaders/surface.frag.glsl.hxx +++ b/VFRendering/include/shaders/surface.frag.glsl.hxx @@ -1,12 +1,12 @@ #ifndef SURFACE_FRAG_GLSL_HXX #define SURFACE_FRAG_GLSL_HXX -static const std::string SURFACE_FRAG_GLSL = R"LITERAL( -#version 330 +#include "shader_header.hxx" + +static const std::string SURFACE_FRAG_GLSL = FRAG_SHADER_HEADER + R"LITERAL( in vec3 vfPosition; in vec3 vfDirection; -out vec4 fo_FragColor; vec3 colormap(vec3 direction); bool is_visible(vec3 position, vec3 direction); diff --git a/VFRendering/include/shaders/surface.vert.glsl.hxx b/VFRendering/include/shaders/surface.vert.glsl.hxx index 39cbc4bb8..14887ae1b 100755 --- a/VFRendering/include/shaders/surface.vert.glsl.hxx +++ b/VFRendering/include/shaders/surface.vert.glsl.hxx @@ -1,8 +1,9 @@ #ifndef SURFACE_VERT_GLSL_HXX #define SURFACE_VERT_GLSL_HXX -static const std::string SURFACE_VERT_GLSL = R"LITERAL( -#version 330 +#include "shader_header.hxx" + +static const std::string SURFACE_VERT_GLSL = VERT_SHADER_HEADER + R"LITERAL( uniform mat4 uProjectionMatrix; uniform mat4 uModelviewMatrix; diff --git a/VFRendering/python/vfrendering_bindings.cpp b/VFRendering/python/vfrendering_bindings.cpp old mode 100644 new mode 100755 index d63bbfeac..f9bd31888 --- a/VFRendering/python/vfrendering_bindings.cpp +++ b/VFRendering/python/vfrendering_bindings.cpp @@ -9,7 +9,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -188,6 +190,13 @@ PYBIND11_MODULE(pyVFRendering, m) .value("translate", CameraMovementModes::TRANSLATE) .export_values(); + + // Styles of the dot drawn by the DotRenderer + py::enum_(m, "DotRendererStyle") + .value("circle", DotRenderer::DotStyle::CIRCLE) + .value("square", DotRenderer::DotStyle::SQUARE) + .export_values(); + // Renderer base class py::class_>(m, "RendererBase", "Renderer base class"); @@ -223,6 +232,17 @@ PYBIND11_MODULE(pyVFRendering, m) .def("setSphereRadius", &SphereRenderer::setOption, "Set the radius of a sphere"); + // ParallelepipedRenderer + py::class_>(m, "ParallelepipedRenderer", + "This class is used to draw parallelepiped at the positions of vectorfield, with colors corresponding to direction.") + .def(py::init()) + .def("setParallelepipedLengthA", &ParallelepipedRenderer::setOption, + "Set the length a of the parallelepiped") + .def("setParallelepipedLengthB", &ParallelepipedRenderer::setOption, + "Set the length b of the parallelepiped") + .def("setParallelepipedLengthC", &ParallelepipedRenderer::setOption, + "Set the length c of the parallelepiped"); + // BoundingBoxRenderer py::class_>(m, "BoundingBoxRenderer", "This Renderer draws a bounding box of the specified dimensions. It may include indicators for" @@ -264,4 +284,13 @@ PYBIND11_MODULE(pyVFRendering, m) .def("setPointSizeRange", &VectorSphereRenderer::setOption) .def("setInnerSphereRadius", &VectorSphereRenderer::setOption) .def("setUseSphereFakePerspective", &VectorSphereRenderer::setOption); + + // DotRenderer + py::class_>(m, "DotRenderer", + "This class is used to draw dots at the positions of vectorfield, with colors corresponding to direction.") + .def(py::init()) + .def("setDotRadius", &DotRenderer::setOption, + "Set the radius of a dot") + .def("setDotStyle", &DotRenderer::setOption, + "Set the style of a dot"); } diff --git a/VFRendering/setup.py b/VFRendering/setup.py old mode 100644 new mode 100755 index c3cb5390a..c8cdbfb44 --- a/VFRendering/setup.py +++ b/VFRendering/setup.py @@ -116,5 +116,6 @@ def finalize_options(self): description='VFRendering python bindings', long_description='', ext_modules=[CMakeExtension('pyVFRendering')], - cmdclass = {'build_ext': CMakeBuild, 'bdist_wheel': bdist_wheel}, + cmdclass={'build_ext': CMakeBuild, 'bdist_wheel': bdist_wheel}, + install_requires=['numpy'] ) \ No newline at end of file diff --git a/VFRendering/src/ArrowRenderer.cxx b/VFRendering/src/ArrowRenderer.cxx old mode 100644 new mode 100755 diff --git a/VFRendering/src/BoundingBoxRenderer.cxx b/VFRendering/src/BoundingBoxRenderer.cxx index 8a285d6c9..f632bcb90 100755 --- a/VFRendering/src/BoundingBoxRenderer.cxx +++ b/VFRendering/src/BoundingBoxRenderer.cxx @@ -1,6 +1,11 @@ #include "VFRendering/BoundingBoxRenderer.hxx" +#ifndef __EMSCRIPTEN__ #include +#else +#include +#endif + #include #include @@ -11,11 +16,11 @@ #include "shaders/boundingbox.frag.glsl.hxx" namespace VFRendering { - BoundingBoxRenderer::BoundingBoxRenderer(const View& view, const std::vector& vertices, const std::vector& dashing_values) : RendererBase(view), m_vertices(vertices), m_dashing_values(dashing_values) { - if (m_dashing_values.size() != m_vertices.size()) { - m_dashing_values.resize(m_vertices.size(), 0); - } +BoundingBoxRenderer::BoundingBoxRenderer(const View& view, const std::vector& vertices, const std::vector& dashing_values) : RendererBase(view), m_vertices(vertices), m_dashing_values(dashing_values) { + if (m_dashing_values.size() != m_vertices.size()) { + m_dashing_values.resize(m_vertices.size(), 0); } +} void BoundingBoxRenderer::initialize() { if (m_is_initialized) { @@ -25,17 +30,19 @@ void BoundingBoxRenderer::initialize() { glGenVertexArrays(1, &m_vao); glBindVertexArray(m_vao); + glGenBuffers(1, &m_vbo); glBindBuffer(GL_ARRAY_BUFFER, m_vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * m_vertices.size(), m_vertices.data(), GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, nullptr); glEnableVertexAttribArray(0); + glGenBuffers(1, &m_dash_vbo); glBindBuffer(GL_ARRAY_BUFFER, m_dash_vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(float) * m_dashing_values.size(), m_dashing_values.data(), GL_STATIC_DRAW); glVertexAttribPointer(1, 1, GL_FLOAT, false, 0, nullptr); glEnableVertexAttribArray(1); - + + updateVertexData(); + std::string vertex_shader_source = BOUNDINGBOX_VERT_GLSL; std::string fragment_shader_source = BOUNDINGBOX_FRAG_GLSL; m_program = Utilities::createProgram(vertex_shader_source, fragment_shader_source, {"ivPosition", "ivDashingValue"}); @@ -51,11 +58,108 @@ BoundingBoxRenderer::~BoundingBoxRenderer() { glDeleteProgram(m_program); } +void BoundingBoxRenderer::updateVertexData() { + float line_width = options().get(); + + if (line_width <= 0.0) { + glBindBuffer(GL_ARRAY_BUFFER, m_vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * m_vertices.size(), m_vertices.data(), GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, m_dash_vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * m_dashing_values.size(), m_dashing_values.data(), GL_STATIC_DRAW); + } else { + float radius = line_width * 0.5; + int level_of_detail = options().get(); + if (level_of_detail < 3) { + level_of_detail = 3; + } + + std::vector cylinder_vertices; + std::vector cylinder_dashing_values; + for (std::size_t i = 0; i + 1 < m_vertices.size(); i += 2) { + glm::vec3 start = m_vertices[i]; + glm::vec3 end = m_vertices[i + 1]; + glm::vec3 direction = end - start; + glm::vec3 ortho_x = glm::cross(direction, glm::vec3(1, 0, 0)); + glm::vec3 ortho_y = glm::cross(direction, glm::vec3(0, 1, 0)); + glm::vec3 ortho_z = glm::cross(direction, glm::vec3(0, 0, 1)); + float ortho_x_length = glm::length(ortho_x); + float ortho_y_length = glm::length(ortho_y); + float ortho_z_length = glm::length(ortho_z); + glm::vec3 normal; + if (ortho_x_length > ortho_y_length && ortho_x_length > ortho_z_length) { + normal = ortho_x; + } else if (ortho_y_length > ortho_z_length) { + normal = ortho_y; + } else { + normal = ortho_z; + } + normal = radius * glm::normalize(normal); + glm::vec3 binormal = radius * glm::normalize(glm::cross(direction, normal)); + + for (int j = 0; j < level_of_detail; j++) { + float start_angle = glm::radians(360.0 * j / level_of_detail); + float end_angle = glm::radians(360.0 * (j + 1) / level_of_detail); + + cylinder_vertices.push_back(start + normal * glm::cos(start_angle) + binormal * glm::sin(start_angle)); + cylinder_vertices.push_back(start + normal * glm::cos(end_angle) + binormal * glm::sin(end_angle)); + cylinder_vertices.push_back(end + normal * glm::cos(start_angle) + binormal * glm::sin(start_angle)); + cylinder_vertices.push_back(end + normal * glm::cos(start_angle) + binormal * glm::sin(start_angle)); + cylinder_vertices.push_back(start + normal * glm::cos(end_angle) + binormal * glm::sin(end_angle)); + cylinder_vertices.push_back(end + normal * glm::cos(end_angle) + binormal * glm::sin(end_angle)); + cylinder_dashing_values.push_back(m_dashing_values[i]); + cylinder_dashing_values.push_back(m_dashing_values[i]); + cylinder_dashing_values.push_back(m_dashing_values[i + 1]); + cylinder_dashing_values.push_back(m_dashing_values[i + 1]); + cylinder_dashing_values.push_back(m_dashing_values[i]); + cylinder_dashing_values.push_back(m_dashing_values[i + 1]); + + int first_dash = glm::floor(glm::min(m_dashing_values[i], m_dashing_values[i + 1])); + int last_dash = glm::ceil(glm::max(m_dashing_values[i], m_dashing_values[i + 1])); + for (int k = first_dash - 1; k < last_dash; k++) { + float d = k + 0.5; + if (glm::mod(glm::floor(d), 2.0f) != 0.0f) { + continue; + } + if (d < glm::min(m_dashing_values[i], m_dashing_values[i + 1]) || d > glm::max(m_dashing_values[i], m_dashing_values[i + 1])) { + continue; + } + float f = (d - m_dashing_values[i]) / (m_dashing_values[i + 1] - m_dashing_values[i]); + cylinder_vertices.push_back(start + direction * f); + cylinder_vertices.push_back(start + direction * f + normal * glm::cos(start_angle) + binormal * glm::sin(start_angle)); + cylinder_vertices.push_back(start + direction * f + normal * glm::cos(end_angle) + binormal * glm::sin(end_angle)); + cylinder_dashing_values.push_back(d); + cylinder_dashing_values.push_back(d); + cylinder_dashing_values.push_back(d); + } + } + } + + num_vertices = cylinder_vertices.size(); + + glBindBuffer(GL_ARRAY_BUFFER, m_vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * cylinder_vertices.size(), cylinder_vertices.data(), GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, m_dash_vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * cylinder_dashing_values.size(), cylinder_dashing_values.data(), GL_STATIC_DRAW); + } +} + void BoundingBoxRenderer::optionsHaveChanged(const std::vector& changed_options) { if (!m_is_initialized) { return; } - (void)changed_options; + + bool update_vertices = false; + for (auto option_index : changed_options) { + switch (option_index) { + case Option::LINE_WIDTH: + case Option::LEVEL_OF_DETAIL: + update_vertices = true; + break; + } + } + if (update_vertices) { + updateVertexData(); + } } void BoundingBoxRenderer::update(bool keep_geometry) { @@ -82,7 +186,15 @@ void BoundingBoxRenderer::draw(float aspect_ratio) { glUniform3f(glGetUniformLocation(m_program, "uColor"), color.r, color.g, color.b); glDisable(GL_CULL_FACE); - glDrawArrays(GL_LINES, 0, m_vertices.size()); + if (options().get() <= 0.0) { + glDrawArrays(GL_LINES, 0, m_vertices.size()); + } else { + int level_of_detail = options().get(); + if (level_of_detail < 3) { + level_of_detail = 3; + } + glDrawArrays(GL_TRIANGLES, 0, num_vertices); + } glEnable(GL_CULL_FACE); } diff --git a/VFRendering/src/CoordinateSystemRenderer.cxx b/VFRendering/src/CoordinateSystemRenderer.cxx old mode 100644 new mode 100755 index 7be519082..015cbf6d4 --- a/VFRendering/src/CoordinateSystemRenderer.cxx +++ b/VFRendering/src/CoordinateSystemRenderer.cxx @@ -1,6 +1,11 @@ #include "VFRendering/CoordinateSystemRenderer.hxx" +#ifndef __EMSCRIPTEN__ #include +#else +#include +#endif + #include #include #include diff --git a/VFRendering/src/DotRenderer.cxx b/VFRendering/src/DotRenderer.cxx new file mode 100755 index 000000000..d4a1beb07 --- /dev/null +++ b/VFRendering/src/DotRenderer.cxx @@ -0,0 +1,167 @@ +#include "VFRendering/DotRenderer.hxx" + +#ifndef __EMSCRIPTEN__ +#include +#else +#include +#endif + +#include +#include + +#include "VFRendering/Utilities.hxx" + +#include "shaders/dots.vert.glsl.hxx" +#include "shaders/dots_circle.frag.glsl.hxx" +#include "shaders/dots_square.frag.glsl.hxx" + +namespace VFRendering { + +DotRenderer::DotRenderer( const View& view, const VectorField& vf ) : + VectorFieldRenderer( view, vf ) { + } + +void DotRenderer::initialize() +{ + if ( m_is_initialized ) return; + + m_is_initialized = true; + + // VAO + glGenVertexArrays(1, &m_vao); + glBindVertexArray(m_vao); + + // Instance positions VBO + glGenBuffers(1, &m_instance_position_vbo); + glBindBuffer(GL_ARRAY_BUFFER, m_instance_position_vbo); + glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, nullptr); + glEnableVertexAttribArray(0); + + // Instance direction VBO + glGenBuffers(1, &m_instance_direction_vbo); + glBindBuffer(GL_ARRAY_BUFFER, m_instance_direction_vbo); + glVertexAttribPointer(1, 3, GL_FLOAT, false, 0, nullptr); + glEnableVertexAttribArray(1); + + m_num_instances = 0; + updateShaderProgram(); + + update( false ); +} + +DotRenderer::~DotRenderer() +{ + if ( !m_is_initialized ) return; + + glDeleteVertexArrays(1, &m_vao); + glDeleteBuffers(1, &m_instance_position_vbo); + glDeleteBuffers(1, &m_instance_direction_vbo); + glDeleteProgram(m_program); +} + +void DotRenderer::optionsHaveChanged( const std::vector& changed_options ) +{ + if ( !m_is_initialized ) return; + + bool update_shader = false; + for (auto option_index : changed_options) { + switch (option_index) { + case View::Option::COLORMAP_IMPLEMENTATION: + case View::Option::IS_VISIBLE_IMPLEMENTATION: + case DotRenderer::Option::DOT_STYLE: + update_shader = true; + break; + } + } + if (update_shader) { + updateShaderProgram(); + } +} + +void DotRenderer::update( bool keep_geometry ) +{ + if (!m_is_initialized) { + return; + } + glBindVertexArray( m_vao ); + + // If geometry is changed copy the new data into position's VBO + if ( !keep_geometry ) { + glBindBuffer( GL_ARRAY_BUFFER, m_instance_position_vbo ); + glBufferData( GL_ARRAY_BUFFER, sizeof(glm::vec3) * positions().size(), + positions().data(), GL_STREAM_DRAW ); + } + + // New data into direction's VBO + glBindBuffer( GL_ARRAY_BUFFER, m_instance_direction_vbo ); + glBufferData( GL_ARRAY_BUFFER, sizeof(glm::vec3) * directions().size(), + directions().data(), GL_STREAM_DRAW ); + + m_num_instances = std::min( positions().size(), directions().size() ); +} + +void DotRenderer::draw( float aspect_ratio ) +{ + initialize(); + if ( m_num_instances <= 0 ) return; + + glBindVertexArray( m_vao ); + glUseProgram( m_program ); + + auto matrices = Utilities::getMatrices( options(), aspect_ratio ); + auto model_view_matrix = matrices.first; + auto projection_matrix = matrices.second; + + float dot_radius = options().get(); + glm::vec2 frame_size = m_view.getFramebufferSize(); + dot_radius *= std::min( frame_size[0], frame_size[1] ) / 1000; + + // Set shader's uniforms + glUniformMatrix4fv( glGetUniformLocation( m_program, "uProjectionMatrix" ), + 1, false, glm::value_ptr(projection_matrix)); + glUniformMatrix4fv( glGetUniformLocation( m_program, "uModelviewMatrix" ), + 1, false, glm::value_ptr(model_view_matrix)); + glUniform1f( glGetUniformLocation( m_program, "uDotRadius" ), dot_radius); + + glDisable( GL_CULL_FACE ); +#ifndef __EMSCRIPTEN__ + glEnable( GL_PROGRAM_POINT_SIZE ); +#endif + glDrawArrays( GL_POINTS, 0, m_num_instances ); + glEnable( GL_CULL_FACE ); +} + +void DotRenderer::updateShaderProgram() +{ + if ( !m_is_initialized ) return; + + if ( m_program ) glDeleteProgram( m_program ); + + // Vertex shader options + std::string vertex_shader_source = DOT_VERT_GLSL; + vertex_shader_source += + options().get(); + vertex_shader_source += + options().get(); + + // Fragment shader options + std::string fragment_shader_source = getDotStyle(options().get()); + + // Compile & link shader Program. Pass uniforms. + m_program = Utilities::createProgram( vertex_shader_source, + fragment_shader_source, { "ivDotCoordinates", "ivDotDirection" } ); +} + +std::string DotRenderer::getDotStyle(const DotStyle& dotstyle) +{ + switch(dotstyle) { + case DotStyle::CIRCLE: + return DOT_CIRCLE_FRAG_GLSL; + case DotStyle::SQUARE: + return DOT_SQUARE_FRAG_GLSL; + default: + return DOT_CIRCLE_FRAG_GLSL; + } +} + +} // namespace VFRendering diff --git a/VFRendering/src/GlyphRenderer.cxx b/VFRendering/src/GlyphRenderer.cxx old mode 100644 new mode 100755 index 7a6a3368f..1edd6ecb0 --- a/VFRendering/src/GlyphRenderer.cxx +++ b/VFRendering/src/GlyphRenderer.cxx @@ -1,6 +1,11 @@ #include "VFRendering/GlyphRenderer.hxx" +#ifndef __EMSCRIPTEN__ #include +#else +#include +#endif + #include #include @@ -78,6 +83,7 @@ void GlyphRenderer::optionsHaveChanged(const std::vector& changed_options) switch (option_index) { case View::Option::COLORMAP_IMPLEMENTATION: case View::Option::IS_VISIBLE_IMPLEMENTATION: + case GlyphRenderer::Option::ROTATE_GLYPHS: update_shader = true; break; } @@ -132,10 +138,15 @@ void GlyphRenderer::updateShaderProgram() { if (m_program) { glDeleteProgram(m_program); } - std::string vertex_shader_source = ARROWS_VERT_GLSL; + std::string vertex_shader_source; + if (options().get()) { + vertex_shader_source = GLYPHS_ROTATED_VERT_GLSL; + } else { + vertex_shader_source = GLYPHS_UNROTATED_VERT_GLSL; + } vertex_shader_source += options().get(); vertex_shader_source += options().get(); - std::string fragment_shader_source = ARROWS_FRAG_GLSL; + std::string fragment_shader_source = GLYPHS_FRAG_GLSL; m_program = Utilities::createProgram(vertex_shader_source, fragment_shader_source, {"ivPosition", "ivNormal", "ivInstanceOffset", "ivInstanceDirection"}); } diff --git a/VFRendering/src/IsosurfaceRenderer.cxx b/VFRendering/src/IsosurfaceRenderer.cxx old mode 100644 new mode 100755 index f82aedc05..55e821e94 --- a/VFRendering/src/IsosurfaceRenderer.cxx +++ b/VFRendering/src/IsosurfaceRenderer.cxx @@ -1,6 +1,11 @@ #include "VFRendering/IsosurfaceRenderer.hxx" +#ifndef __EMSCRIPTEN__ #include +#else +#include +#endif + #include #include diff --git a/VFRendering/src/ParallelepipedRenderer.cxx b/VFRendering/src/ParallelepipedRenderer.cxx new file mode 100755 index 000000000..62de58133 --- /dev/null +++ b/VFRendering/src/ParallelepipedRenderer.cxx @@ -0,0 +1,82 @@ +#include "VFRendering/ParallelepipedRenderer.hxx" + +#include +#include + +namespace VFRendering { + +static void setParallelepipedMeshOptions(GlyphRenderer& renderer, const Options& options); + +ParallelepipedRenderer::ParallelepipedRenderer( const View& view, const VectorField& vf) + : GlyphRenderer(view, vf) +{ + setParallelepipedMeshOptions( *this, this->options() ); +} + +void ParallelepipedRenderer::optionsHaveChanged(const std::vector& changed_options) { + bool update_vertices = false; + for (auto option_index : changed_options) { + switch (option_index) { + case Option::LENGTH_A: + case Option::LENGTH_B: + case Option::LENGTH_C: + update_vertices = true; + break; + } + } + if (update_vertices) { + setParallelepipedMeshOptions(*this, options()); + } + GlyphRenderer::optionsHaveChanged(changed_options); +} + +static void setParallelepipedMeshOptions(GlyphRenderer& renderer, const Options& options) { + auto length_a = options.get(); + auto length_b = options.get(); + auto length_z = options.get(); + + // Enforce valid range + if (length_a < 0) length_a = 0; + if (length_b < 0) length_b = 0; + if (length_z < 0) length_z = 0; + + std::vector cube_indices = + {0,3,1,1,3,2, + 4,5,7,5,7,6, + 8,10,9,8,11,10, + 12,14,13,12,15,14, + 16,19,17,17,19,18, + 20,21,22,22,23,20}; + + std::vector cube_vertices = { + {-1,-1,-1}, {-1,-1, 1}, { 1,-1, 1}, { 1,-1,-1}, + { 1,-1,-1}, { 1,-1, 1}, { 1, 1, 1}, { 1, 1,-1}, + { 1, 1,-1}, { 1, 1, 1}, {-1, 1, 1}, {-1, 1,-1}, + {-1, 1,-1}, {-1, 1, 1}, {-1,-1, 1}, {-1,-1,-1}, + {-1,-1,-1}, { 1,-1,-1}, { 1, 1,-1}, {-1, 1,-1}, + { 1,-1, 1}, { 1, 1, 1}, {-1, 1, 1}, {-1,-1, 1} + }; + + for (auto& vertex : cube_vertices) { + vertex.x *= length_a; + vertex.y *= length_b; + vertex.z *= length_z; + } + + std::vector normals = { + {0,-1,0}, {0,-1,0}, {0,-1,0}, {0,-1,0}, + {1,0,0}, {1,0,0}, {1,0,0}, {1,0,0}, + {0,1,0}, {0,1,0}, {0,1,0}, {0,1,0}, + {-1,0,0}, {-1,0,0}, {-1,0,0}, {-1,0,0}, + {0,0,-1}, {0,0,-1}, {0,0,-1}, {0,0,-1}, + {0,0,1}, {0,0,1}, {0,0,1}, {0,0,1} + }; + + for (auto& normal : normals) { + normal = glm::normalize(normal); + } + + renderer.setGlyph(cube_vertices, normals, cube_indices); +} + +} diff --git a/VFRendering/src/SurfaceRenderer.cxx b/VFRendering/src/SurfaceRenderer.cxx old mode 100644 new mode 100755 index 0c04d3249..55aa88ff7 --- a/VFRendering/src/SurfaceRenderer.cxx +++ b/VFRendering/src/SurfaceRenderer.cxx @@ -1,6 +1,11 @@ #include "VFRendering/SurfaceRenderer.hxx" +#ifndef __EMSCRIPTEN__ #include +#else +#include +#endif + #include #include diff --git a/VFRendering/src/Utilities.cxx b/VFRendering/src/Utilities.cxx old mode 100644 new mode 100755 index d65c19749..923b6484b --- a/VFRendering/src/Utilities.cxx +++ b/VFRendering/src/Utilities.cxx @@ -1,7 +1,12 @@ #include "VFRendering/Utilities.hxx" #include +#ifndef __EMSCRIPTEN__ #include +#else +#include +#endif + #include #include "VFRendering/View.hxx" @@ -37,6 +42,9 @@ static GLuint createShader(GLenum shader_type, const std::string& shader_source) message += info_log; delete[] info_log; } +#ifdef __EMSCRIPTEN__ + std::cerr << message << std::endl; +#endif throw OpenGLException(message); } return shader; @@ -54,7 +62,9 @@ unsigned int createProgram(const std::string& vertex_shader_source, const std::s for (std::vector::size_type i = 0; i < attributes.size(); i++) { glBindAttribLocation(program, i, attributes[i].c_str()); } +#ifndef EMSCRIPTEN glBindFragDataLocation(program, 0, "fo_FragColor"); +#endif glLinkProgram(program); glDeleteShader(vertex_shader); glDeleteShader(fragment_shader); @@ -77,6 +87,9 @@ unsigned int createProgram(const std::string& vertex_shader_source, const std::s message += info_log; delete[] info_log; } +#ifdef __EMSCRIPTEN__ + std::cerr << message << std::endl; +#endif throw OpenGLException(message); } return program; diff --git a/VFRendering/src/VectorSphereRenderer.cxx b/VFRendering/src/VectorSphereRenderer.cxx old mode 100644 new mode 100755 index deba99404..13902238e --- a/VFRendering/src/VectorSphereRenderer.cxx +++ b/VFRendering/src/VectorSphereRenderer.cxx @@ -1,6 +1,11 @@ #include "VFRendering/VectorSphereRenderer.hxx" +#ifndef __EMSCRIPTEN__ #include +#else +#include +#endif + #include #include #include @@ -150,11 +155,15 @@ void VectorSphereRenderer::draw(float aspect_ratio) { glUniform1f(glGetUniformLocation(m_sphere_points_program, "uUseFakePerspective"), 0.0f); } +#ifndef __EMSCRIPTEN__ glEnable(GL_PROGRAM_POINT_SIZE); +#endif glDisable(GL_CULL_FACE); glDrawArrays(GL_POINTS, 0, m_num_instances); glEnable(GL_CULL_FACE); +#ifndef __EMSCRIPTEN__ glDisable(GL_PROGRAM_POINT_SIZE); +#endif } void VectorSphereRenderer::updateShaderProgram() { diff --git a/VFRendering/src/View.cxx b/VFRendering/src/View.cxx old mode 100644 new mode 100755 index f839d9a42..26a18f70e --- a/VFRendering/src/View.cxx +++ b/VFRendering/src/View.cxx @@ -3,7 +3,11 @@ #include #include +#ifndef __EMSCRIPTEN__ #include +#else +#include +#endif #include "VFRendering/RendererBase.hxx" #include "VFRendering/ArrowRenderer.hxx" @@ -23,10 +27,12 @@ void View::initialize() { } m_is_initialized = true; +#ifndef EMSCRIPTEN if (!gladLoadGL()) { std::cerr << "Failed to initialize glad" << std::endl; return; } +#endif // Reset any errors potentially caused by the extension loader glGetError(); glEnable(GL_DEPTH_TEST); @@ -142,6 +148,10 @@ void View::setFramebufferSize(float width, float height) { m_framebuffer_size = glm::vec2(width, height); } +glm::vec2 View::getFramebufferSize() const { + return m_framebuffer_size; +} + void View::setCamera(glm::vec3 camera_position, glm::vec3 center_position, glm::vec3 up_vector) { Options options; options.set(camera_position); diff --git a/VFRendering/thirdparty/pybind11/.gitignore b/VFRendering/thirdparty/pybind11/.gitignore deleted file mode 100644 index c444c17ed..000000000 --- a/VFRendering/thirdparty/pybind11/.gitignore +++ /dev/null @@ -1,37 +0,0 @@ -CMakeCache.txt -CMakeFiles -Makefile -cmake_install.cmake -.DS_Store -*.so -*.pyd -*.dll -*.sln -*.sdf -*.opensdf -*.vcxproj -*.filters -example.dir -Win32 -x64 -Release -Debug -.vs -CTestTestfile.cmake -Testing -autogen -MANIFEST -/.ninja_* -/*.ninja -/docs/.build -*.py[co] -*.egg-info -*~ -.DS_Store -/dist -/build -/cmake/ -.cache/ -sosize-*.txt -pybind11Config*.cmake -pybind11Targets.cmake diff --git a/VFRendering/thirdparty/pybind11/CMakeLists.txt b/VFRendering/thirdparty/pybind11/CMakeLists.txt deleted file mode 100644 index 4280ba742..000000000 --- a/VFRendering/thirdparty/pybind11/CMakeLists.txt +++ /dev/null @@ -1,155 +0,0 @@ -# CMakeLists.txt -- Build system for the pybind11 modules -# -# Copyright (c) 2015 Wenzel Jakob -# -# All rights reserved. Use of this source code is governed by a -# BSD-style license that can be found in the LICENSE file. - -cmake_minimum_required(VERSION 2.8.12) - -if (POLICY CMP0048) - # cmake warns if loaded from a min-3.0-required parent dir, so silence the warning: - cmake_policy(SET CMP0048 NEW) -endif() - -# CMake versions < 3.4.0 do not support try_compile/pthread checks without C as active language. -if(CMAKE_VERSION VERSION_LESS 3.4.0) - project(pybind11) -else() - project(pybind11 CXX) -endif() - -# Check if pybind11 is being used directly or via add_subdirectory -set(PYBIND11_MASTER_PROJECT OFF) -if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) - set(PYBIND11_MASTER_PROJECT ON) -endif() - -option(PYBIND11_INSTALL "Install pybind11 header files?" ${PYBIND11_MASTER_PROJECT}) -option(PYBIND11_TEST "Build pybind11 test suite?" ${PYBIND11_MASTER_PROJECT}) - -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/tools") - -include(pybind11Tools) - -# Cache variables so pybind11_add_module can be used in parent projects -set(PYBIND11_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}/include" CACHE INTERNAL "") -set(PYTHON_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS} CACHE INTERNAL "") -set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} CACHE INTERNAL "") -set(PYTHON_MODULE_PREFIX ${PYTHON_MODULE_PREFIX} CACHE INTERNAL "") -set(PYTHON_MODULE_EXTENSION ${PYTHON_MODULE_EXTENSION} CACHE INTERNAL "") - -# NB: when adding a header don't forget to also add it to setup.py -set(PYBIND11_HEADERS - include/pybind11/detail/class.h - include/pybind11/detail/common.h - include/pybind11/detail/descr.h - include/pybind11/detail/init.h - include/pybind11/detail/internals.h - include/pybind11/detail/typeid.h - include/pybind11/attr.h - include/pybind11/buffer_info.h - include/pybind11/cast.h - include/pybind11/chrono.h - include/pybind11/common.h - include/pybind11/complex.h - include/pybind11/options.h - include/pybind11/eigen.h - include/pybind11/embed.h - include/pybind11/eval.h - include/pybind11/functional.h - include/pybind11/numpy.h - include/pybind11/operators.h - include/pybind11/pybind11.h - include/pybind11/pytypes.h - include/pybind11/stl.h - include/pybind11/stl_bind.h -) -string(REPLACE "include/" "${CMAKE_CURRENT_SOURCE_DIR}/include/" - PYBIND11_HEADERS "${PYBIND11_HEADERS}") - -if (PYBIND11_TEST) - add_subdirectory(tests) -endif() - -include(GNUInstallDirs) -include(CMakePackageConfigHelpers) - -# extract project version from source -file(STRINGS "${PYBIND11_INCLUDE_DIR}/pybind11/detail/common.h" pybind11_version_defines - REGEX "#define PYBIND11_VERSION_(MAJOR|MINOR|PATCH) ") -foreach(ver ${pybind11_version_defines}) - if (ver MATCHES "#define PYBIND11_VERSION_(MAJOR|MINOR|PATCH) +([^ ]+)$") - set(PYBIND11_VERSION_${CMAKE_MATCH_1} "${CMAKE_MATCH_2}" CACHE INTERNAL "") - endif() -endforeach() -set(${PROJECT_NAME}_VERSION ${PYBIND11_VERSION_MAJOR}.${PYBIND11_VERSION_MINOR}.${PYBIND11_VERSION_PATCH}) -message(STATUS "pybind11 v${${PROJECT_NAME}_VERSION}") - -option (USE_PYTHON_INCLUDE_DIR "Install pybind11 headers in Python include directory instead of default installation prefix" OFF) -if (USE_PYTHON_INCLUDE_DIR) - file(RELATIVE_PATH CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX} ${PYTHON_INCLUDE_DIRS}) -endif() - -if(NOT (CMAKE_VERSION VERSION_LESS 3.0)) # CMake >= 3.0 - # Build an interface library target: - add_library(pybind11 INTERFACE) - add_library(pybind11::pybind11 ALIAS pybind11) # to match exported target - target_include_directories(pybind11 INTERFACE $ - $ - $) - target_compile_options(pybind11 INTERFACE $) - - add_library(module INTERFACE) - add_library(pybind11::module ALIAS module) - if(NOT MSVC) - target_compile_options(module INTERFACE -fvisibility=hidden) - endif() - target_link_libraries(module INTERFACE pybind11::pybind11) - if(WIN32 OR CYGWIN) - target_link_libraries(module INTERFACE $) - elseif(APPLE) - target_link_libraries(module INTERFACE "-undefined dynamic_lookup") - endif() - - add_library(embed INTERFACE) - add_library(pybind11::embed ALIAS embed) - target_link_libraries(embed INTERFACE pybind11::pybind11 $) -endif() - -if (PYBIND11_INSTALL) - install(DIRECTORY ${PYBIND11_INCLUDE_DIR}/pybind11 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) - # GNUInstallDirs "DATADIR" wrong here; CMake search path wants "share". - set(PYBIND11_CMAKECONFIG_INSTALL_DIR "share/cmake/${PROJECT_NAME}" CACHE STRING "install path for pybind11Config.cmake") - - configure_package_config_file(tools/${PROJECT_NAME}Config.cmake.in - "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" - INSTALL_DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR}) - # Remove CMAKE_SIZEOF_VOID_P from ConfigVersion.cmake since the library does - # not depend on architecture specific settings or libraries. - set(_PYBIND11_CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P}) - unset(CMAKE_SIZEOF_VOID_P) - write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake - VERSION ${${PROJECT_NAME}_VERSION} - COMPATIBILITY AnyNewerVersion) - set(CMAKE_SIZEOF_VOID_P ${_PYBIND11_CMAKE_SIZEOF_VOID_P}) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake - ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake - tools/FindPythonLibsNew.cmake - tools/pybind11Tools.cmake - DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR}) - - if(NOT (CMAKE_VERSION VERSION_LESS 3.0)) - if(NOT PYBIND11_EXPORT_NAME) - set(PYBIND11_EXPORT_NAME "${PROJECT_NAME}Targets") - endif() - - install(TARGETS pybind11 module embed - EXPORT "${PYBIND11_EXPORT_NAME}") - if(PYBIND11_MASTER_PROJECT) - install(EXPORT "${PYBIND11_EXPORT_NAME}" - NAMESPACE "${PROJECT_NAME}::" - DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR}) - endif() - endif() -endif() diff --git a/VFRendering/thirdparty/pybind11/CONTRIBUTING.md b/VFRendering/thirdparty/pybind11/CONTRIBUTING.md deleted file mode 100644 index 375735f6c..000000000 --- a/VFRendering/thirdparty/pybind11/CONTRIBUTING.md +++ /dev/null @@ -1,47 +0,0 @@ -Thank you for your interest in this project! Please refer to the following -sections on how to contribute code and bug reports. - -### Reporting bugs - -At the moment, this project is run in the spare time of a single person -([Wenzel Jakob](http://rgl.epfl.ch/people/wjakob)) with very limited resources -for issue tracker tickets. Thus, before submitting a question or bug report, -please take a moment of your time and ensure that your issue isn't already -discussed in the project documentation provided at -[http://pybind11.readthedocs.org/en/latest](http://pybind11.readthedocs.org/en/latest). - -Assuming that you have identified a previously unknown problem or an important -question, it's essential that you submit a self-contained and minimal piece of -code that reproduces the problem. In other words: no external dependencies, -isolate the function(s) that cause breakage, submit matched and complete C++ -and Python snippets that can be easily compiled and run on my end. - -## Pull requests -Contributions are submitted, reviewed, and accepted using Github pull requests. -Please refer to [this -article](https://help.github.com/articles/using-pull-requests) for details and -adhere to the following rules to make the process as smooth as possible: - -* Make a new branch for every feature you're working on. -* Make small and clean pull requests that are easy to review but make sure they - do add value by themselves. -* Add tests for any new functionality and run the test suite (``make pytest``) - to ensure that no existing features break. -* This project has a strong focus on providing general solutions using a - minimal amount of code, thus small pull requests are greatly preferred. - -### Licensing of contributions - -pybind11 is provided under a BSD-style license that can be found in the -``LICENSE`` file. By using, distributing, or contributing to this project, you -agree to the terms and conditions of this license. - -You are under no obligation whatsoever to provide any bug fixes, patches, or -upgrades to the features, functionality or performance of the source code -("Enhancements") to anyone; however, if you choose to make your Enhancements -available either publicly, or directly to the author of this software, without -imposing a separate written license agreement for such Enhancements, then you -hereby grant the following license: a non-exclusive, royalty-free perpetual -license to install, use, modify, prepare derivative works, incorporate into -other computer software, distribute, and sublicense such enhancements or -derivative works thereof, in binary and source code form. diff --git a/VFRendering/thirdparty/pybind11/LICENSE b/VFRendering/thirdparty/pybind11/LICENSE deleted file mode 100644 index 6f15578cc..000000000 --- a/VFRendering/thirdparty/pybind11/LICENSE +++ /dev/null @@ -1,29 +0,0 @@ -Copyright (c) 2016 Wenzel Jakob , All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -Please also refer to the file CONTRIBUTING.md, which clarifies licensing of -external contributions to this project including patches, pull requests, etc. diff --git a/VFRendering/thirdparty/pybind11/MANIFEST.in b/VFRendering/thirdparty/pybind11/MANIFEST.in deleted file mode 100644 index 6e57baeee..000000000 --- a/VFRendering/thirdparty/pybind11/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -recursive-include include/pybind11 *.h -include LICENSE README.md CONTRIBUTING.md diff --git a/VFRendering/thirdparty/pybind11/README.md b/VFRendering/thirdparty/pybind11/README.md deleted file mode 100644 index 04568aced..000000000 --- a/VFRendering/thirdparty/pybind11/README.md +++ /dev/null @@ -1,128 +0,0 @@ -![pybind11 logo](https://github.com/pybind/pybind11/raw/master/docs/pybind11-logo.png) - -# pybind11 — Seamless operability between C++11 and Python - -[![Documentation Status](https://readthedocs.org/projects/pybind11/badge/?version=master)](http://pybind11.readthedocs.org/en/master/?badge=master) -[![Documentation Status](https://readthedocs.org/projects/pybind11/badge/?version=stable)](http://pybind11.readthedocs.org/en/stable/?badge=stable) -[![Gitter chat](https://img.shields.io/gitter/room/gitterHQ/gitter.svg)](https://gitter.im/pybind/Lobby) -[![Build Status](https://travis-ci.org/pybind/pybind11.svg?branch=master)](https://travis-ci.org/pybind/pybind11) -[![Build status](https://ci.appveyor.com/api/projects/status/riaj54pn4h08xy40?svg=true)](https://ci.appveyor.com/project/wjakob/pybind11) - -**pybind11** is a lightweight header-only library that exposes C++ types in Python -and vice versa, mainly to create Python bindings of existing C++ code. Its -goals and syntax are similar to the excellent -[Boost.Python](http://www.boost.org/doc/libs/1_58_0/libs/python/doc/) library -by David Abrahams: to minimize boilerplate code in traditional extension -modules by inferring type information using compile-time introspection. - -The main issue with Boost.Python—and the reason for creating such a similar -project—is Boost. Boost is an enormously large and complex suite of utility -libraries that works with almost every C++ compiler in existence. This -compatibility has its cost: arcane template tricks and workarounds are -necessary to support the oldest and buggiest of compiler specimens. Now that -C++11-compatible compilers are widely available, this heavy machinery has -become an excessively large and unnecessary dependency. - -Think of this library as a tiny self-contained version of Boost.Python with -everything stripped away that isn't relevant for binding generation. Without -comments, the core header files only require ~4K lines of code and depend on -Python (2.7 or 3.x, or PyPy2.7 >= 5.7) and the C++ standard library. This -compact implementation was possible thanks to some of the new C++11 language -features (specifically: tuples, lambda functions and variadic templates). Since -its creation, this library has grown beyond Boost.Python in many ways, leading -to dramatically simpler binding code in many common situations. - -Tutorial and reference documentation is provided at -[http://pybind11.readthedocs.org/en/master](http://pybind11.readthedocs.org/en/master). -A PDF version of the manual is available -[here](https://media.readthedocs.org/pdf/pybind11/master/pybind11.pdf). - -## Core features -pybind11 can map the following core C++ features to Python - -- Functions accepting and returning custom data structures per value, reference, or pointer -- Instance methods and static methods -- Overloaded functions -- Instance attributes and static attributes -- Arbitrary exception types -- Enumerations -- Callbacks -- Iterators and ranges -- Custom operators -- Single and multiple inheritance -- STL data structures -- Iterators and ranges -- Smart pointers with reference counting like ``std::shared_ptr`` -- Internal references with correct reference counting -- C++ classes with virtual (and pure virtual) methods can be extended in Python - -## Goodies -In addition to the core functionality, pybind11 provides some extra goodies: - -- Python 2.7, 3.x, and PyPy (PyPy2.7 >= 5.7) are supported with an - implementation-agnostic interface. - -- It is possible to bind C++11 lambda functions with captured variables. The - lambda capture data is stored inside the resulting Python function object. - -- pybind11 uses C++11 move constructors and move assignment operators whenever - possible to efficiently transfer custom data types. - -- It's easy to expose the internal storage of custom data types through - Pythons' buffer protocols. This is handy e.g. for fast conversion between - C++ matrix classes like Eigen and NumPy without expensive copy operations. - -- pybind11 can automatically vectorize functions so that they are transparently - applied to all entries of one or more NumPy array arguments. - -- Python's slice-based access and assignment operations can be supported with - just a few lines of code. - -- Everything is contained in just a few header files; there is no need to link - against any additional libraries. - -- Binaries are generally smaller by a factor of at least 2 compared to - equivalent bindings generated by Boost.Python. A recent pybind11 conversion - of PyRosetta, an enormous Boost.Python binding project, - [reported](http://graylab.jhu.edu/RosettaCon2016/PyRosetta-4.pdf) a binary - size reduction of **5.4x** and compile time reduction by **5.8x**. - -- Function signatures are precomputed at compile time (using ``constexpr``), - leading to smaller binaries. - -- With little extra effort, C++ types can be pickled and unpickled similar to - regular Python objects. - -## Supported compilers - -1. Clang/LLVM 3.3 or newer (for Apple Xcode's clang, this is 5.0.0 or newer) -2. GCC 4.8 or newer -3. Microsoft Visual Studio 2015 Update 3 or newer -4. Intel C++ compiler 16 or newer (15 with a [workaround](https://github.com/pybind/pybind11/issues/276)) -5. Cygwin/GCC (tested on 2.5.1) - -## About - -This project was created by [Wenzel Jakob](http://rgl.epfl.ch/people/wjakob). -Significant features and/or improvements to the code were contributed by -Jonas Adler, -Sylvain Corlay, -Trent Houliston, -Axel Huebl, -@hulucc, -Sergey Lyskov -Johan Mabille, -Tomasz Miąsko, -Dean Moldovan, -Ben Pritchard, -Jason Rhinelander, -Boris Schäling, -Pim Schellart, -Ivan Smirnov, and -Patrick Stewart. - -### License - -pybind11 is provided under a BSD-style license that can be found in the -``LICENSE`` file. By using, distributing, or contributing to this project, -you agree to the terms and conditions of this license. diff --git a/VFRendering/thirdparty/pybind11/include/pybind11/attr.h b/VFRendering/thirdparty/pybind11/include/pybind11/attr.h deleted file mode 100644 index dce875a6b..000000000 --- a/VFRendering/thirdparty/pybind11/include/pybind11/attr.h +++ /dev/null @@ -1,489 +0,0 @@ -/* - pybind11/attr.h: Infrastructure for processing custom - type and function attributes - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "cast.h" - -NAMESPACE_BEGIN(PYBIND11_NAMESPACE) - -/// \addtogroup annotations -/// @{ - -/// Annotation for methods -struct is_method { handle class_; is_method(const handle &c) : class_(c) { } }; - -/// Annotation for operators -struct is_operator { }; - -/// Annotation for parent scope -struct scope { handle value; scope(const handle &s) : value(s) { } }; - -/// Annotation for documentation -struct doc { const char *value; doc(const char *value) : value(value) { } }; - -/// Annotation for function names -struct name { const char *value; name(const char *value) : value(value) { } }; - -/// Annotation indicating that a function is an overload associated with a given "sibling" -struct sibling { handle value; sibling(const handle &value) : value(value.ptr()) { } }; - -/// Annotation indicating that a class derives from another given type -template struct base { - PYBIND11_DEPRECATED("base() was deprecated in favor of specifying 'T' as a template argument to class_") - base() { } -}; - -/// Keep patient alive while nurse lives -template struct keep_alive { }; - -/// Annotation indicating that a class is involved in a multiple inheritance relationship -struct multiple_inheritance { }; - -/// Annotation which enables dynamic attributes, i.e. adds `__dict__` to a class -struct dynamic_attr { }; - -/// Annotation which enables the buffer protocol for a type -struct buffer_protocol { }; - -/// Annotation which requests that a special metaclass is created for a type -struct metaclass { - handle value; - - PYBIND11_DEPRECATED("py::metaclass() is no longer required. It's turned on by default now.") - metaclass() {} - - /// Override pybind11's default metaclass - explicit metaclass(handle value) : value(value) { } -}; - -/// Annotation that marks a class as local to the module: -struct module_local { const bool value; constexpr module_local(bool v = true) : value(v) { } }; - -/// Annotation to mark enums as an arithmetic type -struct arithmetic { }; - -/** \rst - A call policy which places one or more guard variables (``Ts...``) around the function call. - - For example, this definition: - - .. code-block:: cpp - - m.def("foo", foo, py::call_guard()); - - is equivalent to the following pseudocode: - - .. code-block:: cpp - - m.def("foo", [](args...) { - T scope_guard; - return foo(args...); // forwarded arguments - }); - \endrst */ -template struct call_guard; - -template <> struct call_guard<> { using type = detail::void_type; }; - -template -struct call_guard { - static_assert(std::is_default_constructible::value, - "The guard type must be default constructible"); - - using type = T; -}; - -template -struct call_guard { - struct type { - T guard{}; // Compose multiple guard types with left-to-right default-constructor order - typename call_guard::type next{}; - }; -}; - -/// @} annotations - -NAMESPACE_BEGIN(detail) -/* Forward declarations */ -enum op_id : int; -enum op_type : int; -struct undefined_t; -template struct op_; -inline void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret); - -/// Internal data structure which holds metadata about a keyword argument -struct argument_record { - const char *name; ///< Argument name - const char *descr; ///< Human-readable version of the argument value - handle value; ///< Associated Python object - bool convert : 1; ///< True if the argument is allowed to convert when loading - bool none : 1; ///< True if None is allowed when loading - - argument_record(const char *name, const char *descr, handle value, bool convert, bool none) - : name(name), descr(descr), value(value), convert(convert), none(none) { } -}; - -/// Internal data structure which holds metadata about a bound function (signature, overloads, etc.) -struct function_record { - function_record() - : is_constructor(false), is_new_style_constructor(false), is_stateless(false), - is_operator(false), has_args(false), has_kwargs(false), is_method(false) { } - - /// Function name - char *name = nullptr; /* why no C++ strings? They generate heavier code.. */ - - // User-specified documentation string - char *doc = nullptr; - - /// Human-readable version of the function signature - char *signature = nullptr; - - /// List of registered keyword arguments - std::vector args; - - /// Pointer to lambda function which converts arguments and performs the actual call - handle (*impl) (function_call &) = nullptr; - - /// Storage for the wrapped function pointer and captured data, if any - void *data[3] = { }; - - /// Pointer to custom destructor for 'data' (if needed) - void (*free_data) (function_record *ptr) = nullptr; - - /// Return value policy associated with this function - return_value_policy policy = return_value_policy::automatic; - - /// True if name == '__init__' - bool is_constructor : 1; - - /// True if this is a new-style `__init__` defined in `detail/init.h` - bool is_new_style_constructor : 1; - - /// True if this is a stateless function pointer - bool is_stateless : 1; - - /// True if this is an operator (__add__), etc. - bool is_operator : 1; - - /// True if the function has a '*args' argument - bool has_args : 1; - - /// True if the function has a '**kwargs' argument - bool has_kwargs : 1; - - /// True if this is a method - bool is_method : 1; - - /// Number of arguments (including py::args and/or py::kwargs, if present) - std::uint16_t nargs; - - /// Python method object - PyMethodDef *def = nullptr; - - /// Python handle to the parent scope (a class or a module) - handle scope; - - /// Python handle to the sibling function representing an overload chain - handle sibling; - - /// Pointer to next overload - function_record *next = nullptr; -}; - -/// Special data structure which (temporarily) holds metadata about a bound class -struct type_record { - PYBIND11_NOINLINE type_record() - : multiple_inheritance(false), dynamic_attr(false), buffer_protocol(false), module_local(false) { } - - /// Handle to the parent scope - handle scope; - - /// Name of the class - const char *name = nullptr; - - // Pointer to RTTI type_info data structure - const std::type_info *type = nullptr; - - /// How large is the underlying C++ type? - size_t type_size = 0; - - /// How large is the type's holder? - size_t holder_size = 0; - - /// The global operator new can be overridden with a class-specific variant - void *(*operator_new)(size_t) = ::operator new; - - /// Function pointer to class_<..>::init_instance - void (*init_instance)(instance *, const void *) = nullptr; - - /// Function pointer to class_<..>::dealloc - void (*dealloc)(detail::value_and_holder &) = nullptr; - - /// List of base classes of the newly created type - list bases; - - /// Optional docstring - const char *doc = nullptr; - - /// Custom metaclass (optional) - handle metaclass; - - /// Multiple inheritance marker - bool multiple_inheritance : 1; - - /// Does the class manage a __dict__? - bool dynamic_attr : 1; - - /// Does the class implement the buffer protocol? - bool buffer_protocol : 1; - - /// Is the default (unique_ptr) holder type used? - bool default_holder : 1; - - /// Is the class definition local to the module shared object? - bool module_local : 1; - - PYBIND11_NOINLINE void add_base(const std::type_info &base, void *(*caster)(void *)) { - auto base_info = detail::get_type_info(base, false); - if (!base_info) { - std::string tname(base.name()); - detail::clean_type_id(tname); - pybind11_fail("generic_type: type \"" + std::string(name) + - "\" referenced unknown base type \"" + tname + "\""); - } - - if (default_holder != base_info->default_holder) { - std::string tname(base.name()); - detail::clean_type_id(tname); - pybind11_fail("generic_type: type \"" + std::string(name) + "\" " + - (default_holder ? "does not have" : "has") + - " a non-default holder type while its base \"" + tname + "\" " + - (base_info->default_holder ? "does not" : "does")); - } - - bases.append((PyObject *) base_info->type); - - if (base_info->type->tp_dictoffset != 0) - dynamic_attr = true; - - if (caster) - base_info->implicit_casts.emplace_back(type, caster); - } -}; - -inline function_call::function_call(function_record &f, handle p) : - func(f), parent(p) { - args.reserve(f.nargs); - args_convert.reserve(f.nargs); -} - -/// Tag for a new-style `__init__` defined in `detail/init.h` -struct is_new_style_constructor { }; - -/** - * Partial template specializations to process custom attributes provided to - * cpp_function_ and class_. These are either used to initialize the respective - * fields in the type_record and function_record data structures or executed at - * runtime to deal with custom call policies (e.g. keep_alive). - */ -template struct process_attribute; - -template struct process_attribute_default { - /// Default implementation: do nothing - static void init(const T &, function_record *) { } - static void init(const T &, type_record *) { } - static void precall(function_call &) { } - static void postcall(function_call &, handle) { } -}; - -/// Process an attribute specifying the function's name -template <> struct process_attribute : process_attribute_default { - static void init(const name &n, function_record *r) { r->name = const_cast(n.value); } -}; - -/// Process an attribute specifying the function's docstring -template <> struct process_attribute : process_attribute_default { - static void init(const doc &n, function_record *r) { r->doc = const_cast(n.value); } -}; - -/// Process an attribute specifying the function's docstring (provided as a C-style string) -template <> struct process_attribute : process_attribute_default { - static void init(const char *d, function_record *r) { r->doc = const_cast(d); } - static void init(const char *d, type_record *r) { r->doc = const_cast(d); } -}; -template <> struct process_attribute : process_attribute { }; - -/// Process an attribute indicating the function's return value policy -template <> struct process_attribute : process_attribute_default { - static void init(const return_value_policy &p, function_record *r) { r->policy = p; } -}; - -/// Process an attribute which indicates that this is an overloaded function associated with a given sibling -template <> struct process_attribute : process_attribute_default { - static void init(const sibling &s, function_record *r) { r->sibling = s.value; } -}; - -/// Process an attribute which indicates that this function is a method -template <> struct process_attribute : process_attribute_default { - static void init(const is_method &s, function_record *r) { r->is_method = true; r->scope = s.class_; } -}; - -/// Process an attribute which indicates the parent scope of a method -template <> struct process_attribute : process_attribute_default { - static void init(const scope &s, function_record *r) { r->scope = s.value; } -}; - -/// Process an attribute which indicates that this function is an operator -template <> struct process_attribute : process_attribute_default { - static void init(const is_operator &, function_record *r) { r->is_operator = true; } -}; - -template <> struct process_attribute : process_attribute_default { - static void init(const is_new_style_constructor &, function_record *r) { r->is_new_style_constructor = true; } -}; - -/// Process a keyword argument attribute (*without* a default value) -template <> struct process_attribute : process_attribute_default { - static void init(const arg &a, function_record *r) { - if (r->is_method && r->args.empty()) - r->args.emplace_back("self", nullptr, handle(), true /*convert*/, false /*none not allowed*/); - r->args.emplace_back(a.name, nullptr, handle(), !a.flag_noconvert, a.flag_none); - } -}; - -/// Process a keyword argument attribute (*with* a default value) -template <> struct process_attribute : process_attribute_default { - static void init(const arg_v &a, function_record *r) { - if (r->is_method && r->args.empty()) - r->args.emplace_back("self", nullptr /*descr*/, handle() /*parent*/, true /*convert*/, false /*none not allowed*/); - - if (!a.value) { -#if !defined(NDEBUG) - std::string descr("'"); - if (a.name) descr += std::string(a.name) + ": "; - descr += a.type + "'"; - if (r->is_method) { - if (r->name) - descr += " in method '" + (std::string) str(r->scope) + "." + (std::string) r->name + "'"; - else - descr += " in method of '" + (std::string) str(r->scope) + "'"; - } else if (r->name) { - descr += " in function '" + (std::string) r->name + "'"; - } - pybind11_fail("arg(): could not convert default argument " - + descr + " into a Python object (type not registered yet?)"); -#else - pybind11_fail("arg(): could not convert default argument " - "into a Python object (type not registered yet?). " - "Compile in debug mode for more information."); -#endif - } - r->args.emplace_back(a.name, a.descr, a.value.inc_ref(), !a.flag_noconvert, a.flag_none); - } -}; - -/// Process a parent class attribute. Single inheritance only (class_ itself already guarantees that) -template -struct process_attribute::value>> : process_attribute_default { - static void init(const handle &h, type_record *r) { r->bases.append(h); } -}; - -/// Process a parent class attribute (deprecated, does not support multiple inheritance) -template -struct process_attribute> : process_attribute_default> { - static void init(const base &, type_record *r) { r->add_base(typeid(T), nullptr); } -}; - -/// Process a multiple inheritance attribute -template <> -struct process_attribute : process_attribute_default { - static void init(const multiple_inheritance &, type_record *r) { r->multiple_inheritance = true; } -}; - -template <> -struct process_attribute : process_attribute_default { - static void init(const dynamic_attr &, type_record *r) { r->dynamic_attr = true; } -}; - -template <> -struct process_attribute : process_attribute_default { - static void init(const buffer_protocol &, type_record *r) { r->buffer_protocol = true; } -}; - -template <> -struct process_attribute : process_attribute_default { - static void init(const metaclass &m, type_record *r) { r->metaclass = m.value; } -}; - -template <> -struct process_attribute : process_attribute_default { - static void init(const module_local &l, type_record *r) { r->module_local = l.value; } -}; - -/// Process an 'arithmetic' attribute for enums (does nothing here) -template <> -struct process_attribute : process_attribute_default {}; - -template -struct process_attribute> : process_attribute_default> { }; - -/** - * Process a keep_alive call policy -- invokes keep_alive_impl during the - * pre-call handler if both Nurse, Patient != 0 and use the post-call handler - * otherwise - */ -template struct process_attribute> : public process_attribute_default> { - template = 0> - static void precall(function_call &call) { keep_alive_impl(Nurse, Patient, call, handle()); } - template = 0> - static void postcall(function_call &, handle) { } - template = 0> - static void precall(function_call &) { } - template = 0> - static void postcall(function_call &call, handle ret) { keep_alive_impl(Nurse, Patient, call, ret); } -}; - -/// Recursively iterate over variadic template arguments -template struct process_attributes { - static void init(const Args&... args, function_record *r) { - int unused[] = { 0, (process_attribute::type>::init(args, r), 0) ... }; - ignore_unused(unused); - } - static void init(const Args&... args, type_record *r) { - int unused[] = { 0, (process_attribute::type>::init(args, r), 0) ... }; - ignore_unused(unused); - } - static void precall(function_call &call) { - int unused[] = { 0, (process_attribute::type>::precall(call), 0) ... }; - ignore_unused(unused); - } - static void postcall(function_call &call, handle fn_ret) { - int unused[] = { 0, (process_attribute::type>::postcall(call, fn_ret), 0) ... }; - ignore_unused(unused); - } -}; - -template -using is_call_guard = is_instantiation; - -/// Extract the ``type`` from the first `call_guard` in `Extras...` (or `void_type` if none found) -template -using extract_guard_t = typename exactly_one_t, Extra...>::type; - -/// Check the number of named arguments at compile time -template ::value...), - size_t self = constexpr_sum(std::is_same::value...)> -constexpr bool expected_num_args(size_t nargs, bool has_args, bool has_kwargs) { - return named == 0 || (self + named + has_args + has_kwargs) == nargs; -} - -NAMESPACE_END(detail) -NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/VFRendering/thirdparty/pybind11/include/pybind11/buffer_info.h b/VFRendering/thirdparty/pybind11/include/pybind11/buffer_info.h deleted file mode 100644 index 9f072fa73..000000000 --- a/VFRendering/thirdparty/pybind11/include/pybind11/buffer_info.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - pybind11/buffer_info.h: Python buffer object interface - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "detail/common.h" - -NAMESPACE_BEGIN(PYBIND11_NAMESPACE) - -/// Information record describing a Python buffer object -struct buffer_info { - void *ptr = nullptr; // Pointer to the underlying storage - ssize_t itemsize = 0; // Size of individual items in bytes - ssize_t size = 0; // Total number of entries - std::string format; // For homogeneous buffers, this should be set to format_descriptor::format() - ssize_t ndim = 0; // Number of dimensions - std::vector shape; // Shape of the tensor (1 entry per dimension) - std::vector strides; // Number of entries between adjacent entries (for each per dimension) - - buffer_info() { } - - buffer_info(void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim, - detail::any_container shape_in, detail::any_container strides_in) - : ptr(ptr), itemsize(itemsize), size(1), format(format), ndim(ndim), - shape(std::move(shape_in)), strides(std::move(strides_in)) { - if (ndim != (ssize_t) shape.size() || ndim != (ssize_t) strides.size()) - pybind11_fail("buffer_info: ndim doesn't match shape and/or strides length"); - for (size_t i = 0; i < (size_t) ndim; ++i) - size *= shape[i]; - } - - template - buffer_info(T *ptr, detail::any_container shape_in, detail::any_container strides_in) - : buffer_info(private_ctr_tag(), ptr, sizeof(T), format_descriptor::format(), static_cast(shape_in->size()), std::move(shape_in), std::move(strides_in)) { } - - buffer_info(void *ptr, ssize_t itemsize, const std::string &format, ssize_t size) - : buffer_info(ptr, itemsize, format, 1, {size}, {itemsize}) { } - - template - buffer_info(T *ptr, ssize_t size) - : buffer_info(ptr, sizeof(T), format_descriptor::format(), size) { } - - explicit buffer_info(Py_buffer *view, bool ownview = true) - : buffer_info(view->buf, view->itemsize, view->format, view->ndim, - {view->shape, view->shape + view->ndim}, {view->strides, view->strides + view->ndim}) { - this->view = view; - this->ownview = ownview; - } - - buffer_info(const buffer_info &) = delete; - buffer_info& operator=(const buffer_info &) = delete; - - buffer_info(buffer_info &&other) { - (*this) = std::move(other); - } - - buffer_info& operator=(buffer_info &&rhs) { - ptr = rhs.ptr; - itemsize = rhs.itemsize; - size = rhs.size; - format = std::move(rhs.format); - ndim = rhs.ndim; - shape = std::move(rhs.shape); - strides = std::move(rhs.strides); - std::swap(view, rhs.view); - std::swap(ownview, rhs.ownview); - return *this; - } - - ~buffer_info() { - if (view && ownview) { PyBuffer_Release(view); delete view; } - } - -private: - struct private_ctr_tag { }; - - buffer_info(private_ctr_tag, void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim, - detail::any_container &&shape_in, detail::any_container &&strides_in) - : buffer_info(ptr, itemsize, format, ndim, std::move(shape_in), std::move(strides_in)) { } - - Py_buffer *view = nullptr; - bool ownview = false; -}; - -NAMESPACE_BEGIN(detail) - -template struct compare_buffer_info { - static bool compare(const buffer_info& b) { - return b.format == format_descriptor::format() && b.itemsize == (ssize_t) sizeof(T); - } -}; - -template struct compare_buffer_info::value>> { - static bool compare(const buffer_info& b) { - return (size_t) b.itemsize == sizeof(T) && (b.format == format_descriptor::value || - ((sizeof(T) == sizeof(long)) && b.format == (std::is_unsigned::value ? "L" : "l")) || - ((sizeof(T) == sizeof(size_t)) && b.format == (std::is_unsigned::value ? "N" : "n"))); - } -}; - -NAMESPACE_END(detail) -NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/VFRendering/thirdparty/pybind11/include/pybind11/cast.h b/VFRendering/thirdparty/pybind11/include/pybind11/cast.h deleted file mode 100644 index 0aa632601..000000000 --- a/VFRendering/thirdparty/pybind11/include/pybind11/cast.h +++ /dev/null @@ -1,2059 +0,0 @@ -/* - pybind11/cast.h: Partial template specializations to cast between - C++ and Python types - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "pytypes.h" -#include "detail/typeid.h" -#include "detail/descr.h" -#include "detail/internals.h" -#include -#include -#include - -#if defined(PYBIND11_CPP17) -# if defined(__has_include) -# if __has_include() -# define PYBIND11_HAS_STRING_VIEW -# endif -# elif defined(_MSC_VER) -# define PYBIND11_HAS_STRING_VIEW -# endif -#endif -#ifdef PYBIND11_HAS_STRING_VIEW -#include -#endif - -NAMESPACE_BEGIN(PYBIND11_NAMESPACE) -NAMESPACE_BEGIN(detail) - -/// A life support system for temporary objects created by `type_caster::load()`. -/// Adding a patient will keep it alive up until the enclosing function returns. -class loader_life_support { -public: - /// A new patient frame is created when a function is entered - loader_life_support() { - get_internals().loader_patient_stack.push_back(nullptr); - } - - /// ... and destroyed after it returns - ~loader_life_support() { - auto &stack = get_internals().loader_patient_stack; - if (stack.empty()) - pybind11_fail("loader_life_support: internal error"); - - auto ptr = stack.back(); - stack.pop_back(); - Py_CLEAR(ptr); - - // A heuristic to reduce the stack's capacity (e.g. after long recursive calls) - if (stack.capacity() > 16 && stack.size() != 0 && stack.capacity() / stack.size() > 2) - stack.shrink_to_fit(); - } - - /// This can only be used inside a pybind11-bound function, either by `argument_loader` - /// at argument preparation time or by `py::cast()` at execution time. - PYBIND11_NOINLINE static void add_patient(handle h) { - auto &stack = get_internals().loader_patient_stack; - if (stack.empty()) - throw cast_error("When called outside a bound function, py::cast() cannot " - "do Python -> C++ conversions which require the creation " - "of temporary values"); - - auto &list_ptr = stack.back(); - if (list_ptr == nullptr) { - list_ptr = PyList_New(1); - if (!list_ptr) - pybind11_fail("loader_life_support: error allocating list"); - PyList_SET_ITEM(list_ptr, 0, h.inc_ref().ptr()); - } else { - auto result = PyList_Append(list_ptr, h.ptr()); - if (result == -1) - pybind11_fail("loader_life_support: error adding patient"); - } - } -}; - -// Gets the cache entry for the given type, creating it if necessary. The return value is the pair -// returned by emplace, i.e. an iterator for the entry and a bool set to `true` if the entry was -// just created. -inline std::pair all_type_info_get_cache(PyTypeObject *type); - -// Populates a just-created cache entry. -PYBIND11_NOINLINE inline void all_type_info_populate(PyTypeObject *t, std::vector &bases) { - std::vector check; - for (handle parent : reinterpret_borrow(t->tp_bases)) - check.push_back((PyTypeObject *) parent.ptr()); - - auto const &type_dict = get_internals().registered_types_py; - for (size_t i = 0; i < check.size(); i++) { - auto type = check[i]; - // Ignore Python2 old-style class super type: - if (!PyType_Check((PyObject *) type)) continue; - - // Check `type` in the current set of registered python types: - auto it = type_dict.find(type); - if (it != type_dict.end()) { - // We found a cache entry for it, so it's either pybind-registered or has pre-computed - // pybind bases, but we have to make sure we haven't already seen the type(s) before: we - // want to follow Python/virtual C++ rules that there should only be one instance of a - // common base. - for (auto *tinfo : it->second) { - // NB: Could use a second set here, rather than doing a linear search, but since - // having a large number of immediate pybind11-registered types seems fairly - // unlikely, that probably isn't worthwhile. - bool found = false; - for (auto *known : bases) { - if (known == tinfo) { found = true; break; } - } - if (!found) bases.push_back(tinfo); - } - } - else if (type->tp_bases) { - // It's some python type, so keep follow its bases classes to look for one or more - // registered types - if (i + 1 == check.size()) { - // When we're at the end, we can pop off the current element to avoid growing - // `check` when adding just one base (which is typical--i.e. when there is no - // multiple inheritance) - check.pop_back(); - i--; - } - for (handle parent : reinterpret_borrow(type->tp_bases)) - check.push_back((PyTypeObject *) parent.ptr()); - } - } -} - -/** - * Extracts vector of type_info pointers of pybind-registered roots of the given Python type. Will - * be just 1 pybind type for the Python type of a pybind-registered class, or for any Python-side - * derived class that uses single inheritance. Will contain as many types as required for a Python - * class that uses multiple inheritance to inherit (directly or indirectly) from multiple - * pybind-registered classes. Will be empty if neither the type nor any base classes are - * pybind-registered. - * - * The value is cached for the lifetime of the Python type. - */ -inline const std::vector &all_type_info(PyTypeObject *type) { - auto ins = all_type_info_get_cache(type); - if (ins.second) - // New cache entry: populate it - all_type_info_populate(type, ins.first->second); - - return ins.first->second; -} - -/** - * Gets a single pybind11 type info for a python type. Returns nullptr if neither the type nor any - * ancestors are pybind11-registered. Throws an exception if there are multiple bases--use - * `all_type_info` instead if you want to support multiple bases. - */ -PYBIND11_NOINLINE inline detail::type_info* get_type_info(PyTypeObject *type) { - auto &bases = all_type_info(type); - if (bases.size() == 0) - return nullptr; - if (bases.size() > 1) - pybind11_fail("pybind11::detail::get_type_info: type has multiple pybind11-registered bases"); - return bases.front(); -} - -inline detail::type_info *get_local_type_info(const std::type_index &tp) { - auto &locals = registered_local_types_cpp(); - auto it = locals.find(tp); - if (it != locals.end()) - return it->second; - return nullptr; -} - -inline detail::type_info *get_global_type_info(const std::type_index &tp) { - auto &types = get_internals().registered_types_cpp; - auto it = types.find(tp); - if (it != types.end()) - return it->second; - return nullptr; -} - -/// Return the type info for a given C++ type; on lookup failure can either throw or return nullptr. -PYBIND11_NOINLINE inline detail::type_info *get_type_info(const std::type_index &tp, - bool throw_if_missing = false) { - if (auto ltype = get_local_type_info(tp)) - return ltype; - if (auto gtype = get_global_type_info(tp)) - return gtype; - - if (throw_if_missing) { - std::string tname = tp.name(); - detail::clean_type_id(tname); - pybind11_fail("pybind11::detail::get_type_info: unable to find type info for \"" + tname + "\""); - } - return nullptr; -} - -PYBIND11_NOINLINE inline handle get_type_handle(const std::type_info &tp, bool throw_if_missing) { - detail::type_info *type_info = get_type_info(tp, throw_if_missing); - return handle(type_info ? ((PyObject *) type_info->type) : nullptr); -} - -struct value_and_holder { - instance *inst; - size_t index; - const detail::type_info *type; - void **vh; - - // Main constructor for a found value/holder: - value_and_holder(instance *i, const detail::type_info *type, size_t vpos, size_t index) : - inst{i}, index{index}, type{type}, - vh{inst->simple_layout ? inst->simple_value_holder : &inst->nonsimple.values_and_holders[vpos]} - {} - - // Default constructor (used to signal a value-and-holder not found by get_value_and_holder()) - value_and_holder() : inst{nullptr} {} - - // Used for past-the-end iterator - value_and_holder(size_t index) : index{index} {} - - template V *&value_ptr() const { - return reinterpret_cast(vh[0]); - } - // True if this `value_and_holder` has a non-null value pointer - explicit operator bool() const { return value_ptr(); } - - template H &holder() const { - return reinterpret_cast(vh[1]); - } - bool holder_constructed() const { - return inst->simple_layout - ? inst->simple_holder_constructed - : inst->nonsimple.status[index] & instance::status_holder_constructed; - } - void set_holder_constructed(bool v = true) { - if (inst->simple_layout) - inst->simple_holder_constructed = v; - else if (v) - inst->nonsimple.status[index] |= instance::status_holder_constructed; - else - inst->nonsimple.status[index] &= (uint8_t) ~instance::status_holder_constructed; - } - bool instance_registered() const { - return inst->simple_layout - ? inst->simple_instance_registered - : inst->nonsimple.status[index] & instance::status_instance_registered; - } - void set_instance_registered(bool v = true) { - if (inst->simple_layout) - inst->simple_instance_registered = v; - else if (v) - inst->nonsimple.status[index] |= instance::status_instance_registered; - else - inst->nonsimple.status[index] &= (uint8_t) ~instance::status_instance_registered; - } -}; - -// Container for accessing and iterating over an instance's values/holders -struct values_and_holders { -private: - instance *inst; - using type_vec = std::vector; - const type_vec &tinfo; - -public: - values_and_holders(instance *inst) : inst{inst}, tinfo(all_type_info(Py_TYPE(inst))) {} - - struct iterator { - private: - instance *inst; - const type_vec *types; - value_and_holder curr; - friend struct values_and_holders; - iterator(instance *inst, const type_vec *tinfo) - : inst{inst}, types{tinfo}, - curr(inst /* instance */, - types->empty() ? nullptr : (*types)[0] /* type info */, - 0, /* vpos: (non-simple types only): the first vptr comes first */ - 0 /* index */) - {} - // Past-the-end iterator: - iterator(size_t end) : curr(end) {} - public: - bool operator==(const iterator &other) { return curr.index == other.curr.index; } - bool operator!=(const iterator &other) { return curr.index != other.curr.index; } - iterator &operator++() { - if (!inst->simple_layout) - curr.vh += 1 + (*types)[curr.index]->holder_size_in_ptrs; - ++curr.index; - curr.type = curr.index < types->size() ? (*types)[curr.index] : nullptr; - return *this; - } - value_and_holder &operator*() { return curr; } - value_and_holder *operator->() { return &curr; } - }; - - iterator begin() { return iterator(inst, &tinfo); } - iterator end() { return iterator(tinfo.size()); } - - iterator find(const type_info *find_type) { - auto it = begin(), endit = end(); - while (it != endit && it->type != find_type) ++it; - return it; - } - - size_t size() { return tinfo.size(); } -}; - -/** - * Extracts C++ value and holder pointer references from an instance (which may contain multiple - * values/holders for python-side multiple inheritance) that match the given type. Throws an error - * if the given type (or ValueType, if omitted) is not a pybind11 base of the given instance. If - * `find_type` is omitted (or explicitly specified as nullptr) the first value/holder are returned, - * regardless of type (and the resulting .type will be nullptr). - * - * The returned object should be short-lived: in particular, it must not outlive the called-upon - * instance. - */ -PYBIND11_NOINLINE inline value_and_holder instance::get_value_and_holder(const type_info *find_type /*= nullptr default in common.h*/, bool throw_if_missing /*= true in common.h*/) { - // Optimize common case: - if (!find_type || Py_TYPE(this) == find_type->type) - return value_and_holder(this, find_type, 0, 0); - - detail::values_and_holders vhs(this); - auto it = vhs.find(find_type); - if (it != vhs.end()) - return *it; - - if (!throw_if_missing) - return value_and_holder(); - -#if defined(NDEBUG) - pybind11_fail("pybind11::detail::instance::get_value_and_holder: " - "type is not a pybind11 base of the given instance " - "(compile in debug mode for type details)"); -#else - pybind11_fail("pybind11::detail::instance::get_value_and_holder: `" + - std::string(find_type->type->tp_name) + "' is not a pybind11 base of the given `" + - std::string(Py_TYPE(this)->tp_name) + "' instance"); -#endif -} - -PYBIND11_NOINLINE inline void instance::allocate_layout() { - auto &tinfo = all_type_info(Py_TYPE(this)); - - const size_t n_types = tinfo.size(); - - if (n_types == 0) - pybind11_fail("instance allocation failed: new instance has no pybind11-registered base types"); - - simple_layout = - n_types == 1 && tinfo.front()->holder_size_in_ptrs <= instance_simple_holder_in_ptrs(); - - // Simple path: no python-side multiple inheritance, and a small-enough holder - if (simple_layout) { - simple_value_holder[0] = nullptr; - simple_holder_constructed = false; - simple_instance_registered = false; - } - else { // multiple base types or a too-large holder - // Allocate space to hold: [v1*][h1][v2*][h2]...[bb...] where [vN*] is a value pointer, - // [hN] is the (uninitialized) holder instance for value N, and [bb...] is a set of bool - // values that tracks whether each associated holder has been initialized. Each [block] is - // padded, if necessary, to an integer multiple of sizeof(void *). - size_t space = 0; - for (auto t : tinfo) { - space += 1; // value pointer - space += t->holder_size_in_ptrs; // holder instance - } - size_t flags_at = space; - space += size_in_ptrs(n_types); // status bytes (holder_constructed and instance_registered) - - // Allocate space for flags, values, and holders, and initialize it to 0 (flags and values, - // in particular, need to be 0). Use Python's memory allocation functions: in Python 3.6 - // they default to using pymalloc, which is designed to be efficient for small allocations - // like the one we're doing here; in earlier versions (and for larger allocations) they are - // just wrappers around malloc. -#if PY_VERSION_HEX >= 0x03050000 - nonsimple.values_and_holders = (void **) PyMem_Calloc(space, sizeof(void *)); - if (!nonsimple.values_and_holders) throw std::bad_alloc(); -#else - nonsimple.values_and_holders = (void **) PyMem_New(void *, space); - if (!nonsimple.values_and_holders) throw std::bad_alloc(); - std::memset(nonsimple.values_and_holders, 0, space * sizeof(void *)); -#endif - nonsimple.status = reinterpret_cast(&nonsimple.values_and_holders[flags_at]); - } - owned = true; -} - -PYBIND11_NOINLINE inline void instance::deallocate_layout() { - if (!simple_layout) - PyMem_Free(nonsimple.values_and_holders); -} - -PYBIND11_NOINLINE inline bool isinstance_generic(handle obj, const std::type_info &tp) { - handle type = detail::get_type_handle(tp, false); - if (!type) - return false; - return isinstance(obj, type); -} - -PYBIND11_NOINLINE inline std::string error_string() { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_RuntimeError, "Unknown internal error occurred"); - return "Unknown internal error occurred"; - } - - error_scope scope; // Preserve error state - - std::string errorString; - if (scope.type) { - errorString += handle(scope.type).attr("__name__").cast(); - errorString += ": "; - } - if (scope.value) - errorString += (std::string) str(scope.value); - - PyErr_NormalizeException(&scope.type, &scope.value, &scope.trace); - -#if PY_MAJOR_VERSION >= 3 - if (scope.trace != nullptr) - PyException_SetTraceback(scope.value, scope.trace); -#endif - -#if !defined(PYPY_VERSION) - if (scope.trace) { - PyTracebackObject *trace = (PyTracebackObject *) scope.trace; - - /* Get the deepest trace possible */ - while (trace->tb_next) - trace = trace->tb_next; - - PyFrameObject *frame = trace->tb_frame; - errorString += "\n\nAt:\n"; - while (frame) { - int lineno = PyFrame_GetLineNumber(frame); - errorString += - " " + handle(frame->f_code->co_filename).cast() + - "(" + std::to_string(lineno) + "): " + - handle(frame->f_code->co_name).cast() + "\n"; - frame = frame->f_back; - } - } -#endif - - return errorString; -} - -PYBIND11_NOINLINE inline handle get_object_handle(const void *ptr, const detail::type_info *type ) { - auto &instances = get_internals().registered_instances; - auto range = instances.equal_range(ptr); - for (auto it = range.first; it != range.second; ++it) { - for (auto vh : values_and_holders(it->second)) { - if (vh.type == type) - return handle((PyObject *) it->second); - } - } - return handle(); -} - -inline PyThreadState *get_thread_state_unchecked() { -#if defined(PYPY_VERSION) - return PyThreadState_GET(); -#elif PY_VERSION_HEX < 0x03000000 - return _PyThreadState_Current; -#elif PY_VERSION_HEX < 0x03050000 - return (PyThreadState*) _Py_atomic_load_relaxed(&_PyThreadState_Current); -#elif PY_VERSION_HEX < 0x03050200 - return (PyThreadState*) _PyThreadState_Current.value; -#else - return _PyThreadState_UncheckedGet(); -#endif -} - -// Forward declarations -inline void keep_alive_impl(handle nurse, handle patient); -inline PyObject *make_new_instance(PyTypeObject *type); - -class type_caster_generic { -public: - PYBIND11_NOINLINE type_caster_generic(const std::type_info &type_info) - : typeinfo(get_type_info(type_info)), cpptype(&type_info) { } - - type_caster_generic(const type_info *typeinfo) - : typeinfo(typeinfo), cpptype(typeinfo ? typeinfo->cpptype : nullptr) { } - - bool load(handle src, bool convert) { - return load_impl(src, convert); - } - - PYBIND11_NOINLINE static handle cast(const void *_src, return_value_policy policy, handle parent, - const detail::type_info *tinfo, - void *(*copy_constructor)(const void *), - void *(*move_constructor)(const void *), - const void *existing_holder = nullptr) { - if (!tinfo) // no type info: error will be set already - return handle(); - - void *src = const_cast(_src); - if (src == nullptr) - return none().release(); - - auto it_instances = get_internals().registered_instances.equal_range(src); - for (auto it_i = it_instances.first; it_i != it_instances.second; ++it_i) { - for (auto instance_type : detail::all_type_info(Py_TYPE(it_i->second))) { - if (instance_type && same_type(*instance_type->cpptype, *tinfo->cpptype)) - return handle((PyObject *) it_i->second).inc_ref(); - } - } - - auto inst = reinterpret_steal(make_new_instance(tinfo->type)); - auto wrapper = reinterpret_cast(inst.ptr()); - wrapper->owned = false; - void *&valueptr = values_and_holders(wrapper).begin()->value_ptr(); - - switch (policy) { - case return_value_policy::automatic: - case return_value_policy::take_ownership: - valueptr = src; - wrapper->owned = true; - break; - - case return_value_policy::automatic_reference: - case return_value_policy::reference: - valueptr = src; - wrapper->owned = false; - break; - - case return_value_policy::copy: - if (copy_constructor) - valueptr = copy_constructor(src); - else - throw cast_error("return_value_policy = copy, but the " - "object is non-copyable!"); - wrapper->owned = true; - break; - - case return_value_policy::move: - if (move_constructor) - valueptr = move_constructor(src); - else if (copy_constructor) - valueptr = copy_constructor(src); - else - throw cast_error("return_value_policy = move, but the " - "object is neither movable nor copyable!"); - wrapper->owned = true; - break; - - case return_value_policy::reference_internal: - valueptr = src; - wrapper->owned = false; - keep_alive_impl(inst, parent); - break; - - default: - throw cast_error("unhandled return_value_policy: should not happen!"); - } - - tinfo->init_instance(wrapper, existing_holder); - - return inst.release(); - } - - // Base methods for generic caster; there are overridden in copyable_holder_caster - void load_value(value_and_holder &&v_h) { - auto *&vptr = v_h.value_ptr(); - // Lazy allocation for unallocated values: - if (vptr == nullptr) { - auto *type = v_h.type ? v_h.type : typeinfo; - vptr = type->operator_new(type->type_size); - } - value = vptr; - } - bool try_implicit_casts(handle src, bool convert) { - for (auto &cast : typeinfo->implicit_casts) { - type_caster_generic sub_caster(*cast.first); - if (sub_caster.load(src, convert)) { - value = cast.second(sub_caster.value); - return true; - } - } - return false; - } - bool try_direct_conversions(handle src) { - for (auto &converter : *typeinfo->direct_conversions) { - if (converter(src.ptr(), value)) - return true; - } - return false; - } - void check_holder_compat() {} - - PYBIND11_NOINLINE static void *local_load(PyObject *src, const type_info *ti) { - auto caster = type_caster_generic(ti); - if (caster.load(src, false)) - return caster.value; - return nullptr; - } - - /// Try to load with foreign typeinfo, if available. Used when there is no - /// native typeinfo, or when the native one wasn't able to produce a value. - PYBIND11_NOINLINE bool try_load_foreign_module_local(handle src) { - constexpr auto *local_key = PYBIND11_MODULE_LOCAL_ID; - const auto pytype = src.get_type(); - if (!hasattr(pytype, local_key)) - return false; - - type_info *foreign_typeinfo = reinterpret_borrow(getattr(pytype, local_key)); - // Only consider this foreign loader if actually foreign and is a loader of the correct cpp type - if (foreign_typeinfo->module_local_load == &local_load - || (cpptype && !same_type(*cpptype, *foreign_typeinfo->cpptype))) - return false; - - if (auto result = foreign_typeinfo->module_local_load(src.ptr(), foreign_typeinfo)) { - value = result; - return true; - } - return false; - } - - // Implementation of `load`; this takes the type of `this` so that it can dispatch the relevant - // bits of code between here and copyable_holder_caster where the two classes need different - // logic (without having to resort to virtual inheritance). - template - PYBIND11_NOINLINE bool load_impl(handle src, bool convert) { - if (!src) return false; - if (!typeinfo) return try_load_foreign_module_local(src); - if (src.is_none()) { - // Defer accepting None to other overloads (if we aren't in convert mode): - if (!convert) return false; - value = nullptr; - return true; - } - - auto &this_ = static_cast(*this); - this_.check_holder_compat(); - - PyTypeObject *srctype = Py_TYPE(src.ptr()); - - // Case 1: If src is an exact type match for the target type then we can reinterpret_cast - // the instance's value pointer to the target type: - if (srctype == typeinfo->type) { - this_.load_value(reinterpret_cast(src.ptr())->get_value_and_holder()); - return true; - } - // Case 2: We have a derived class - else if (PyType_IsSubtype(srctype, typeinfo->type)) { - auto &bases = all_type_info(srctype); - bool no_cpp_mi = typeinfo->simple_type; - - // Case 2a: the python type is a Python-inherited derived class that inherits from just - // one simple (no MI) pybind11 class, or is an exact match, so the C++ instance is of - // the right type and we can use reinterpret_cast. - // (This is essentially the same as case 2b, but because not using multiple inheritance - // is extremely common, we handle it specially to avoid the loop iterator and type - // pointer lookup overhead) - if (bases.size() == 1 && (no_cpp_mi || bases.front()->type == typeinfo->type)) { - this_.load_value(reinterpret_cast(src.ptr())->get_value_and_holder()); - return true; - } - // Case 2b: the python type inherits from multiple C++ bases. Check the bases to see if - // we can find an exact match (or, for a simple C++ type, an inherited match); if so, we - // can safely reinterpret_cast to the relevant pointer. - else if (bases.size() > 1) { - for (auto base : bases) { - if (no_cpp_mi ? PyType_IsSubtype(base->type, typeinfo->type) : base->type == typeinfo->type) { - this_.load_value(reinterpret_cast(src.ptr())->get_value_and_holder(base)); - return true; - } - } - } - - // Case 2c: C++ multiple inheritance is involved and we couldn't find an exact type match - // in the registered bases, above, so try implicit casting (needed for proper C++ casting - // when MI is involved). - if (this_.try_implicit_casts(src, convert)) - return true; - } - - // Perform an implicit conversion - if (convert) { - for (auto &converter : typeinfo->implicit_conversions) { - auto temp = reinterpret_steal(converter(src.ptr(), typeinfo->type)); - if (load_impl(temp, false)) { - loader_life_support::add_patient(temp); - return true; - } - } - if (this_.try_direct_conversions(src)) - return true; - } - - // Failed to match local typeinfo. Try again with global. - if (typeinfo->module_local) { - if (auto gtype = get_global_type_info(*typeinfo->cpptype)) { - typeinfo = gtype; - return load(src, false); - } - } - - // Global typeinfo has precedence over foreign module_local - return try_load_foreign_module_local(src); - } - - - // Called to do type lookup and wrap the pointer and type in a pair when a dynamic_cast - // isn't needed or can't be used. If the type is unknown, sets the error and returns a pair - // with .second = nullptr. (p.first = nullptr is not an error: it becomes None). - PYBIND11_NOINLINE static std::pair src_and_type( - const void *src, const std::type_info &cast_type, const std::type_info *rtti_type = nullptr) { - if (auto *tpi = get_type_info(cast_type)) - return {src, const_cast(tpi)}; - - // Not found, set error: - std::string tname = rtti_type ? rtti_type->name() : cast_type.name(); - detail::clean_type_id(tname); - std::string msg = "Unregistered type : " + tname; - PyErr_SetString(PyExc_TypeError, msg.c_str()); - return {nullptr, nullptr}; - } - - const type_info *typeinfo = nullptr; - const std::type_info *cpptype = nullptr; - void *value = nullptr; -}; - -/** - * Determine suitable casting operator for pointer-or-lvalue-casting type casters. The type caster - * needs to provide `operator T*()` and `operator T&()` operators. - * - * If the type supports moving the value away via an `operator T&&() &&` method, it should use - * `movable_cast_op_type` instead. - */ -template -using cast_op_type = - conditional_t>::value, - typename std::add_pointer>::type, - typename std::add_lvalue_reference>::type>; - -/** - * Determine suitable casting operator for a type caster with a movable value. Such a type caster - * needs to provide `operator T*()`, `operator T&()`, and `operator T&&() &&`. The latter will be - * called in appropriate contexts where the value can be moved rather than copied. - * - * These operator are automatically provided when using the PYBIND11_TYPE_CASTER macro. - */ -template -using movable_cast_op_type = - conditional_t::type>::value, - typename std::add_pointer>::type, - conditional_t::value, - typename std::add_rvalue_reference>::type, - typename std::add_lvalue_reference>::type>>; - -// std::is_copy_constructible isn't quite enough: it lets std::vector (and similar) through when -// T is non-copyable, but code containing such a copy constructor fails to actually compile. -template struct is_copy_constructible : std::is_copy_constructible {}; - -// Specialization for types that appear to be copy constructible but also look like stl containers -// (we specifically check for: has `value_type` and `reference` with `reference = value_type&`): if -// so, copy constructability depends on whether the value_type is copy constructible. -template struct is_copy_constructible, - std::is_same - >::value>> : is_copy_constructible {}; - -#if !defined(PYBIND11_CPP17) -// Likewise for std::pair before C++17 (which mandates that the copy constructor not exist when the -// two types aren't themselves copy constructible). -template struct is_copy_constructible> - : all_of, is_copy_constructible> {}; -#endif - -/// Generic type caster for objects stored on the heap -template class type_caster_base : public type_caster_generic { - using itype = intrinsic_t; -public: - static constexpr auto name = _(); - - type_caster_base() : type_caster_base(typeid(type)) { } - explicit type_caster_base(const std::type_info &info) : type_caster_generic(info) { } - - static handle cast(const itype &src, return_value_policy policy, handle parent) { - if (policy == return_value_policy::automatic || policy == return_value_policy::automatic_reference) - policy = return_value_policy::copy; - return cast(&src, policy, parent); - } - - static handle cast(itype &&src, return_value_policy, handle parent) { - return cast(&src, return_value_policy::move, parent); - } - - // Returns a (pointer, type_info) pair taking care of necessary RTTI type lookup for a - // polymorphic type. If the instance isn't derived, returns the non-RTTI base version. - template ::value, int> = 0> - static std::pair src_and_type(const itype *src) { - const void *vsrc = src; - auto &cast_type = typeid(itype); - const std::type_info *instance_type = nullptr; - if (vsrc) { - instance_type = &typeid(*src); - if (!same_type(cast_type, *instance_type)) { - // This is a base pointer to a derived type; if it is a pybind11-registered type, we - // can get the correct derived pointer (which may be != base pointer) by a - // dynamic_cast to most derived type: - if (auto *tpi = get_type_info(*instance_type)) - return {dynamic_cast(src), const_cast(tpi)}; - } - } - // Otherwise we have either a nullptr, an `itype` pointer, or an unknown derived pointer, so - // don't do a cast - return type_caster_generic::src_and_type(vsrc, cast_type, instance_type); - } - - // Non-polymorphic type, so no dynamic casting; just call the generic version directly - template ::value, int> = 0> - static std::pair src_and_type(const itype *src) { - return type_caster_generic::src_and_type(src, typeid(itype)); - } - - static handle cast(const itype *src, return_value_policy policy, handle parent) { - auto st = src_and_type(src); - return type_caster_generic::cast( - st.first, policy, parent, st.second, - make_copy_constructor(src), make_move_constructor(src)); - } - - static handle cast_holder(const itype *src, const void *holder) { - auto st = src_and_type(src); - return type_caster_generic::cast( - st.first, return_value_policy::take_ownership, {}, st.second, - nullptr, nullptr, holder); - } - - template using cast_op_type = detail::cast_op_type; - - operator itype*() { return (type *) value; } - operator itype&() { if (!value) throw reference_cast_error(); return *((itype *) value); } - -protected: - using Constructor = void *(*)(const void *); - - /* Only enabled when the types are {copy,move}-constructible *and* when the type - does not have a private operator new implementation. */ - template ::value>> - static auto make_copy_constructor(const T *x) -> decltype(new T(*x), Constructor{}) { - return [](const void *arg) -> void * { - return new T(*reinterpret_cast(arg)); - }; - } - - template ::value>> - static auto make_move_constructor(const T *x) -> decltype(new T(std::move(*const_cast(x))), Constructor{}) { - return [](const void *arg) -> void * { - return new T(std::move(*const_cast(reinterpret_cast(arg)))); - }; - } - - static Constructor make_copy_constructor(...) { return nullptr; } - static Constructor make_move_constructor(...) { return nullptr; } -}; - -template class type_caster : public type_caster_base { }; -template using make_caster = type_caster>; - -// Shortcut for calling a caster's `cast_op_type` cast operator for casting a type_caster to a T -template typename make_caster::template cast_op_type cast_op(make_caster &caster) { - return caster.operator typename make_caster::template cast_op_type(); -} -template typename make_caster::template cast_op_type::type> -cast_op(make_caster &&caster) { - return std::move(caster).operator - typename make_caster::template cast_op_type::type>(); -} - -template class type_caster> { -private: - using caster_t = make_caster; - caster_t subcaster; - using subcaster_cast_op_type = typename caster_t::template cast_op_type; - static_assert(std::is_same::type &, subcaster_cast_op_type>::value, - "std::reference_wrapper caster requires T to have a caster with an `T &` operator"); -public: - bool load(handle src, bool convert) { return subcaster.load(src, convert); } - static constexpr auto name = caster_t::name; - static handle cast(const std::reference_wrapper &src, return_value_policy policy, handle parent) { - // It is definitely wrong to take ownership of this pointer, so mask that rvp - if (policy == return_value_policy::take_ownership || policy == return_value_policy::automatic) - policy = return_value_policy::automatic_reference; - return caster_t::cast(&src.get(), policy, parent); - } - template using cast_op_type = std::reference_wrapper; - operator std::reference_wrapper() { return subcaster.operator subcaster_cast_op_type&(); } -}; - -#define PYBIND11_TYPE_CASTER(type, py_name) \ - protected: \ - type value; \ - public: \ - static constexpr auto name = py_name; \ - template >::value, int> = 0> \ - static handle cast(T_ *src, return_value_policy policy, handle parent) { \ - if (!src) return none().release(); \ - if (policy == return_value_policy::take_ownership) { \ - auto h = cast(std::move(*src), policy, parent); delete src; return h; \ - } else { \ - return cast(*src, policy, parent); \ - } \ - } \ - operator type*() { return &value; } \ - operator type&() { return value; } \ - operator type&&() && { return std::move(value); } \ - template using cast_op_type = pybind11::detail::movable_cast_op_type - - -template using is_std_char_type = any_of< - std::is_same, /* std::string */ - std::is_same, /* std::u16string */ - std::is_same, /* std::u32string */ - std::is_same /* std::wstring */ ->; - -template -struct type_caster::value && !is_std_char_type::value>> { - using _py_type_0 = conditional_t; - using _py_type_1 = conditional_t::value, _py_type_0, typename std::make_unsigned<_py_type_0>::type>; - using py_type = conditional_t::value, double, _py_type_1>; -public: - - bool load(handle src, bool convert) { - py_type py_value; - - if (!src) - return false; - - if (std::is_floating_point::value) { - if (convert || PyFloat_Check(src.ptr())) - py_value = (py_type) PyFloat_AsDouble(src.ptr()); - else - return false; - } else if (PyFloat_Check(src.ptr())) { - return false; - } else if (std::is_unsigned::value) { - py_value = as_unsigned(src.ptr()); - } else { // signed integer: - py_value = sizeof(T) <= sizeof(long) - ? (py_type) PyLong_AsLong(src.ptr()) - : (py_type) PYBIND11_LONG_AS_LONGLONG(src.ptr()); - } - - bool py_err = py_value == (py_type) -1 && PyErr_Occurred(); - if (py_err || (std::is_integral::value && sizeof(py_type) != sizeof(T) && - (py_value < (py_type) std::numeric_limits::min() || - py_value > (py_type) std::numeric_limits::max()))) { - bool type_error = py_err && PyErr_ExceptionMatches( -#if PY_VERSION_HEX < 0x03000000 && !defined(PYPY_VERSION) - PyExc_SystemError -#else - PyExc_TypeError -#endif - ); - PyErr_Clear(); - if (type_error && convert && PyNumber_Check(src.ptr())) { - auto tmp = reinterpret_steal(std::is_floating_point::value - ? PyNumber_Float(src.ptr()) - : PyNumber_Long(src.ptr())); - PyErr_Clear(); - return load(tmp, false); - } - return false; - } - - value = (T) py_value; - return true; - } - - static handle cast(T src, return_value_policy /* policy */, handle /* parent */) { - if (std::is_floating_point::value) { - return PyFloat_FromDouble((double) src); - } else if (sizeof(T) <= sizeof(ssize_t)) { - // This returns a long automatically if needed - if (std::is_signed::value) - return PYBIND11_LONG_FROM_SIGNED(src); - else - return PYBIND11_LONG_FROM_UNSIGNED(src); - } else { - if (std::is_signed::value) - return PyLong_FromLongLong((long long) src); - else - return PyLong_FromUnsignedLongLong((unsigned long long) src); - } - } - - PYBIND11_TYPE_CASTER(T, _::value>("int", "float")); -}; - -template struct void_caster { -public: - bool load(handle src, bool) { - if (src && src.is_none()) - return true; - return false; - } - static handle cast(T, return_value_policy /* policy */, handle /* parent */) { - return none().inc_ref(); - } - PYBIND11_TYPE_CASTER(T, _("None")); -}; - -template <> class type_caster : public void_caster {}; - -template <> class type_caster : public type_caster { -public: - using type_caster::cast; - - bool load(handle h, bool) { - if (!h) { - return false; - } else if (h.is_none()) { - value = nullptr; - return true; - } - - /* Check if this is a capsule */ - if (isinstance(h)) { - value = reinterpret_borrow(h); - return true; - } - - /* Check if this is a C++ type */ - auto &bases = all_type_info((PyTypeObject *) h.get_type().ptr()); - if (bases.size() == 1) { // Only allowing loading from a single-value type - value = values_and_holders(reinterpret_cast(h.ptr())).begin()->value_ptr(); - return true; - } - - /* Fail */ - return false; - } - - static handle cast(const void *ptr, return_value_policy /* policy */, handle /* parent */) { - if (ptr) - return capsule(ptr).release(); - else - return none().inc_ref(); - } - - template using cast_op_type = void*&; - operator void *&() { return value; } - static constexpr auto name = _("capsule"); -private: - void *value = nullptr; -}; - -template <> class type_caster : public void_caster { }; - -template <> class type_caster { -public: - bool load(handle src, bool convert) { - if (!src) return false; - else if (src.ptr() == Py_True) { value = true; return true; } - else if (src.ptr() == Py_False) { value = false; return true; } - else if (convert || !strcmp("numpy.bool_", Py_TYPE(src.ptr())->tp_name)) { - // (allow non-implicit conversion for numpy booleans) - - Py_ssize_t res = -1; - if (src.is_none()) { - res = 0; // None is implicitly converted to False - } - #if defined(PYPY_VERSION) - // On PyPy, check that "__bool__" (or "__nonzero__" on Python 2.7) attr exists - else if (hasattr(src, PYBIND11_BOOL_ATTR)) { - res = PyObject_IsTrue(src.ptr()); - } - #else - // Alternate approach for CPython: this does the same as the above, but optimized - // using the CPython API so as to avoid an unneeded attribute lookup. - else if (auto tp_as_number = src.ptr()->ob_type->tp_as_number) { - if (PYBIND11_NB_BOOL(tp_as_number)) { - res = (*PYBIND11_NB_BOOL(tp_as_number))(src.ptr()); - } - } - #endif - if (res == 0 || res == 1) { - value = (bool) res; - return true; - } - } - return false; - } - static handle cast(bool src, return_value_policy /* policy */, handle /* parent */) { - return handle(src ? Py_True : Py_False).inc_ref(); - } - PYBIND11_TYPE_CASTER(bool, _("bool")); -}; - -// Helper class for UTF-{8,16,32} C++ stl strings: -template struct string_caster { - using CharT = typename StringType::value_type; - - // Simplify life by being able to assume standard char sizes (the standard only guarantees - // minimums, but Python requires exact sizes) - static_assert(!std::is_same::value || sizeof(CharT) == 1, "Unsupported char size != 1"); - static_assert(!std::is_same::value || sizeof(CharT) == 2, "Unsupported char16_t size != 2"); - static_assert(!std::is_same::value || sizeof(CharT) == 4, "Unsupported char32_t size != 4"); - // wchar_t can be either 16 bits (Windows) or 32 (everywhere else) - static_assert(!std::is_same::value || sizeof(CharT) == 2 || sizeof(CharT) == 4, - "Unsupported wchar_t size != 2/4"); - static constexpr size_t UTF_N = 8 * sizeof(CharT); - - bool load(handle src, bool) { -#if PY_MAJOR_VERSION < 3 - object temp; -#endif - handle load_src = src; - if (!src) { - return false; - } else if (!PyUnicode_Check(load_src.ptr())) { -#if PY_MAJOR_VERSION >= 3 - return load_bytes(load_src); -#else - if (sizeof(CharT) == 1) { - return load_bytes(load_src); - } - - // The below is a guaranteed failure in Python 3 when PyUnicode_Check returns false - if (!PYBIND11_BYTES_CHECK(load_src.ptr())) - return false; - - temp = reinterpret_steal(PyUnicode_FromObject(load_src.ptr())); - if (!temp) { PyErr_Clear(); return false; } - load_src = temp; -#endif - } - - object utfNbytes = reinterpret_steal(PyUnicode_AsEncodedString( - load_src.ptr(), UTF_N == 8 ? "utf-8" : UTF_N == 16 ? "utf-16" : "utf-32", nullptr)); - if (!utfNbytes) { PyErr_Clear(); return false; } - - const CharT *buffer = reinterpret_cast(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr())); - size_t length = (size_t) PYBIND11_BYTES_SIZE(utfNbytes.ptr()) / sizeof(CharT); - if (UTF_N > 8) { buffer++; length--; } // Skip BOM for UTF-16/32 - value = StringType(buffer, length); - - // If we're loading a string_view we need to keep the encoded Python object alive: - if (IsView) - loader_life_support::add_patient(utfNbytes); - - return true; - } - - static handle cast(const StringType &src, return_value_policy /* policy */, handle /* parent */) { - const char *buffer = reinterpret_cast(src.data()); - ssize_t nbytes = ssize_t(src.size() * sizeof(CharT)); - handle s = decode_utfN(buffer, nbytes); - if (!s) throw error_already_set(); - return s; - } - - PYBIND11_TYPE_CASTER(StringType, _(PYBIND11_STRING_NAME)); - -private: - static handle decode_utfN(const char *buffer, ssize_t nbytes) { -#if !defined(PYPY_VERSION) - return - UTF_N == 8 ? PyUnicode_DecodeUTF8(buffer, nbytes, nullptr) : - UTF_N == 16 ? PyUnicode_DecodeUTF16(buffer, nbytes, nullptr, nullptr) : - PyUnicode_DecodeUTF32(buffer, nbytes, nullptr, nullptr); -#else - // PyPy seems to have multiple problems related to PyUnicode_UTF*: the UTF8 version - // sometimes segfaults for unknown reasons, while the UTF16 and 32 versions require a - // non-const char * arguments, which is also a nuissance, so bypass the whole thing by just - // passing the encoding as a string value, which works properly: - return PyUnicode_Decode(buffer, nbytes, UTF_N == 8 ? "utf-8" : UTF_N == 16 ? "utf-16" : "utf-32", nullptr); -#endif - } - - // When loading into a std::string or char*, accept a bytes object as-is (i.e. - // without any encoding/decoding attempt). For other C++ char sizes this is a no-op. - // which supports loading a unicode from a str, doesn't take this path. - template - bool load_bytes(enable_if_t src) { - if (PYBIND11_BYTES_CHECK(src.ptr())) { - // We were passed a Python 3 raw bytes; accept it into a std::string or char* - // without any encoding attempt. - const char *bytes = PYBIND11_BYTES_AS_STRING(src.ptr()); - if (bytes) { - value = StringType(bytes, (size_t) PYBIND11_BYTES_SIZE(src.ptr())); - return true; - } - } - - return false; - } - - template - bool load_bytes(enable_if_t) { return false; } -}; - -template -struct type_caster, enable_if_t::value>> - : string_caster> {}; - -#ifdef PYBIND11_HAS_STRING_VIEW -template -struct type_caster, enable_if_t::value>> - : string_caster, true> {}; -#endif - -// Type caster for C-style strings. We basically use a std::string type caster, but also add the -// ability to use None as a nullptr char* (which the string caster doesn't allow). -template struct type_caster::value>> { - using StringType = std::basic_string; - using StringCaster = type_caster; - StringCaster str_caster; - bool none = false; - CharT one_char = 0; -public: - bool load(handle src, bool convert) { - if (!src) return false; - if (src.is_none()) { - // Defer accepting None to other overloads (if we aren't in convert mode): - if (!convert) return false; - none = true; - return true; - } - return str_caster.load(src, convert); - } - - static handle cast(const CharT *src, return_value_policy policy, handle parent) { - if (src == nullptr) return pybind11::none().inc_ref(); - return StringCaster::cast(StringType(src), policy, parent); - } - - static handle cast(CharT src, return_value_policy policy, handle parent) { - if (std::is_same::value) { - handle s = PyUnicode_DecodeLatin1((const char *) &src, 1, nullptr); - if (!s) throw error_already_set(); - return s; - } - return StringCaster::cast(StringType(1, src), policy, parent); - } - - operator CharT*() { return none ? nullptr : const_cast(static_cast(str_caster).c_str()); } - operator CharT&() { - if (none) - throw value_error("Cannot convert None to a character"); - - auto &value = static_cast(str_caster); - size_t str_len = value.size(); - if (str_len == 0) - throw value_error("Cannot convert empty string to a character"); - - // If we're in UTF-8 mode, we have two possible failures: one for a unicode character that - // is too high, and one for multiple unicode characters (caught later), so we need to figure - // out how long the first encoded character is in bytes to distinguish between these two - // errors. We also allow want to allow unicode characters U+0080 through U+00FF, as those - // can fit into a single char value. - if (StringCaster::UTF_N == 8 && str_len > 1 && str_len <= 4) { - unsigned char v0 = static_cast(value[0]); - size_t char0_bytes = !(v0 & 0x80) ? 1 : // low bits only: 0-127 - (v0 & 0xE0) == 0xC0 ? 2 : // 0b110xxxxx - start of 2-byte sequence - (v0 & 0xF0) == 0xE0 ? 3 : // 0b1110xxxx - start of 3-byte sequence - 4; // 0b11110xxx - start of 4-byte sequence - - if (char0_bytes == str_len) { - // If we have a 128-255 value, we can decode it into a single char: - if (char0_bytes == 2 && (v0 & 0xFC) == 0xC0) { // 0x110000xx 0x10xxxxxx - one_char = static_cast(((v0 & 3) << 6) + (static_cast(value[1]) & 0x3F)); - return one_char; - } - // Otherwise we have a single character, but it's > U+00FF - throw value_error("Character code point not in range(0x100)"); - } - } - - // UTF-16 is much easier: we can only have a surrogate pair for values above U+FFFF, thus a - // surrogate pair with total length 2 instantly indicates a range error (but not a "your - // string was too long" error). - else if (StringCaster::UTF_N == 16 && str_len == 2) { - one_char = static_cast(value[0]); - if (one_char >= 0xD800 && one_char < 0xE000) - throw value_error("Character code point not in range(0x10000)"); - } - - if (str_len != 1) - throw value_error("Expected a character, but multi-character string found"); - - one_char = value[0]; - return one_char; - } - - static constexpr auto name = _(PYBIND11_STRING_NAME); - template using cast_op_type = pybind11::detail::cast_op_type<_T>; -}; - -// Base implementation for std::tuple and std::pair -template class Tuple, typename... Ts> class tuple_caster { - using type = Tuple; - static constexpr auto size = sizeof...(Ts); - using indices = make_index_sequence; -public: - - bool load(handle src, bool convert) { - if (!isinstance(src)) - return false; - const auto seq = reinterpret_borrow(src); - if (seq.size() != size) - return false; - return load_impl(seq, convert, indices{}); - } - - template - static handle cast(T &&src, return_value_policy policy, handle parent) { - return cast_impl(std::forward(src), policy, parent, indices{}); - } - - static constexpr auto name = _("Tuple[") + concat(make_caster::name...) + _("]"); - - template using cast_op_type = type; - - operator type() & { return implicit_cast(indices{}); } - operator type() && { return std::move(*this).implicit_cast(indices{}); } - -protected: - template - type implicit_cast(index_sequence) & { return type(cast_op(std::get(subcasters))...); } - template - type implicit_cast(index_sequence) && { return type(cast_op(std::move(std::get(subcasters)))...); } - - static constexpr bool load_impl(const sequence &, bool, index_sequence<>) { return true; } - - template - bool load_impl(const sequence &seq, bool convert, index_sequence) { - for (bool r : {std::get(subcasters).load(seq[Is], convert)...}) - if (!r) - return false; - return true; - } - - /* Implementation: Convert a C++ tuple into a Python tuple */ - template - static handle cast_impl(T &&src, return_value_policy policy, handle parent, index_sequence) { - std::array entries{{ - reinterpret_steal(make_caster::cast(std::get(std::forward(src)), policy, parent))... - }}; - for (const auto &entry: entries) - if (!entry) - return handle(); - tuple result(size); - int counter = 0; - for (auto & entry: entries) - PyTuple_SET_ITEM(result.ptr(), counter++, entry.release().ptr()); - return result.release(); - } - - Tuple...> subcasters; -}; - -template class type_caster> - : public tuple_caster {}; - -template class type_caster> - : public tuple_caster {}; - -/// Helper class which abstracts away certain actions. Users can provide specializations for -/// custom holders, but it's only necessary if the type has a non-standard interface. -template -struct holder_helper { - static auto get(const T &p) -> decltype(p.get()) { return p.get(); } -}; - -/// Type caster for holder types like std::shared_ptr, etc. -template -struct copyable_holder_caster : public type_caster_base { -public: - using base = type_caster_base; - static_assert(std::is_base_of>::value, - "Holder classes are only supported for custom types"); - using base::base; - using base::cast; - using base::typeinfo; - using base::value; - - bool load(handle src, bool convert) { - return base::template load_impl>(src, convert); - } - - explicit operator type*() { return this->value; } - explicit operator type&() { return *(this->value); } - explicit operator holder_type*() { return &holder; } - - // Workaround for Intel compiler bug - // see pybind11 issue 94 - #if defined(__ICC) || defined(__INTEL_COMPILER) - operator holder_type&() { return holder; } - #else - explicit operator holder_type&() { return holder; } - #endif - - static handle cast(const holder_type &src, return_value_policy, handle) { - const auto *ptr = holder_helper::get(src); - return type_caster_base::cast_holder(ptr, &src); - } - -protected: - friend class type_caster_generic; - void check_holder_compat() { - if (typeinfo->default_holder) - throw cast_error("Unable to load a custom holder type from a default-holder instance"); - } - - bool load_value(value_and_holder &&v_h) { - if (v_h.holder_constructed()) { - value = v_h.value_ptr(); - holder = v_h.template holder(); - return true; - } else { - throw cast_error("Unable to cast from non-held to held instance (T& to Holder) " -#if defined(NDEBUG) - "(compile in debug mode for type information)"); -#else - "of type '" + type_id() + "''"); -#endif - } - } - - template ::value, int> = 0> - bool try_implicit_casts(handle, bool) { return false; } - - template ::value, int> = 0> - bool try_implicit_casts(handle src, bool convert) { - for (auto &cast : typeinfo->implicit_casts) { - copyable_holder_caster sub_caster(*cast.first); - if (sub_caster.load(src, convert)) { - value = cast.second(sub_caster.value); - holder = holder_type(sub_caster.holder, (type *) value); - return true; - } - } - return false; - } - - static bool try_direct_conversions(handle) { return false; } - - - holder_type holder; -}; - -/// Specialize for the common std::shared_ptr, so users don't need to -template -class type_caster> : public copyable_holder_caster> { }; - -template -struct move_only_holder_caster { - static_assert(std::is_base_of, type_caster>::value, - "Holder classes are only supported for custom types"); - - static handle cast(holder_type &&src, return_value_policy, handle) { - auto *ptr = holder_helper::get(src); - return type_caster_base::cast_holder(ptr, &src); - } - static constexpr auto name = type_caster_base::name; -}; - -template -class type_caster> - : public move_only_holder_caster> { }; - -template -using type_caster_holder = conditional_t::value, - copyable_holder_caster, - move_only_holder_caster>; - -template struct always_construct_holder { static constexpr bool value = Value; }; - -/// Create a specialization for custom holder types (silently ignores std::shared_ptr) -#define PYBIND11_DECLARE_HOLDER_TYPE(type, holder_type, ...) \ - namespace pybind11 { namespace detail { \ - template \ - struct always_construct_holder : always_construct_holder { }; \ - template \ - class type_caster::value>> \ - : public type_caster_holder { }; \ - }} - -// PYBIND11_DECLARE_HOLDER_TYPE holder types: -template struct is_holder_type : - std::is_base_of, detail::type_caster> {}; -// Specialization for always-supported unique_ptr holders: -template struct is_holder_type> : - std::true_type {}; - -template struct handle_type_name { static constexpr auto name = _(); }; -template <> struct handle_type_name { static constexpr auto name = _(PYBIND11_BYTES_NAME); }; -template <> struct handle_type_name { static constexpr auto name = _("*args"); }; -template <> struct handle_type_name { static constexpr auto name = _("**kwargs"); }; - -template -struct pyobject_caster { - template ::value, int> = 0> - bool load(handle src, bool /* convert */) { value = src; return static_cast(value); } - - template ::value, int> = 0> - bool load(handle src, bool /* convert */) { - if (!isinstance(src)) - return false; - value = reinterpret_borrow(src); - return true; - } - - static handle cast(const handle &src, return_value_policy /* policy */, handle /* parent */) { - return src.inc_ref(); - } - PYBIND11_TYPE_CASTER(type, handle_type_name::name); -}; - -template -class type_caster::value>> : public pyobject_caster { }; - -// Our conditions for enabling moving are quite restrictive: -// At compile time: -// - T needs to be a non-const, non-pointer, non-reference type -// - type_caster::operator T&() must exist -// - the type must be move constructible (obviously) -// At run-time: -// - if the type is non-copy-constructible, the object must be the sole owner of the type (i.e. it -// must have ref_count() == 1)h -// If any of the above are not satisfied, we fall back to copying. -template using move_is_plain_type = satisfies_none_of; -template struct move_always : std::false_type {}; -template struct move_always, - negation>, - std::is_move_constructible, - std::is_same>().operator T&()), T&> ->::value>> : std::true_type {}; -template struct move_if_unreferenced : std::false_type {}; -template struct move_if_unreferenced, - negation>, - std::is_move_constructible, - std::is_same>().operator T&()), T&> ->::value>> : std::true_type {}; -template using move_never = none_of, move_if_unreferenced>; - -// Detect whether returning a `type` from a cast on type's type_caster is going to result in a -// reference or pointer to a local variable of the type_caster. Basically, only -// non-reference/pointer `type`s and reference/pointers from a type_caster_generic are safe; -// everything else returns a reference/pointer to a local variable. -template using cast_is_temporary_value_reference = bool_constant< - (std::is_reference::value || std::is_pointer::value) && - !std::is_base_of>::value ->; - -// When a value returned from a C++ function is being cast back to Python, we almost always want to -// force `policy = move`, regardless of the return value policy the function/method was declared -// with. Some classes (most notably Eigen::Ref and related) need to avoid this, and so can do so by -// specializing this struct. -template struct return_value_policy_override { - static return_value_policy policy(return_value_policy p) { - return !std::is_lvalue_reference::value && !std::is_pointer::value - ? return_value_policy::move : p; - } -}; - -// Basic python -> C++ casting; throws if casting fails -template type_caster &load_type(type_caster &conv, const handle &handle) { - if (!conv.load(handle, true)) { -#if defined(NDEBUG) - throw cast_error("Unable to cast Python instance to C++ type (compile in debug mode for details)"); -#else - throw cast_error("Unable to cast Python instance of type " + - (std::string) str(handle.get_type()) + " to C++ type '" + type_id() + "'"); -#endif - } - return conv; -} -// Wrapper around the above that also constructs and returns a type_caster -template make_caster load_type(const handle &handle) { - make_caster conv; - load_type(conv, handle); - return conv; -} - -NAMESPACE_END(detail) - -// pytype -> C++ type -template ::value, int> = 0> -T cast(const handle &handle) { - using namespace detail; - static_assert(!cast_is_temporary_value_reference::value, - "Unable to cast type to reference: value is local to type caster"); - return cast_op(load_type(handle)); -} - -// pytype -> pytype (calls converting constructor) -template ::value, int> = 0> -T cast(const handle &handle) { return T(reinterpret_borrow(handle)); } - -// C++ type -> py::object -template ::value, int> = 0> -object cast(const T &value, return_value_policy policy = return_value_policy::automatic_reference, - handle parent = handle()) { - if (policy == return_value_policy::automatic) - policy = std::is_pointer::value ? return_value_policy::take_ownership : return_value_policy::copy; - else if (policy == return_value_policy::automatic_reference) - policy = std::is_pointer::value ? return_value_policy::reference : return_value_policy::copy; - return reinterpret_steal(detail::make_caster::cast(value, policy, parent)); -} - -template T handle::cast() const { return pybind11::cast(*this); } -template <> inline void handle::cast() const { return; } - -template -detail::enable_if_t::value, T> move(object &&obj) { - if (obj.ref_count() > 1) -#if defined(NDEBUG) - throw cast_error("Unable to cast Python instance to C++ rvalue: instance has multiple references" - " (compile in debug mode for details)"); -#else - throw cast_error("Unable to move from Python " + (std::string) str(obj.get_type()) + - " instance to C++ " + type_id() + " instance: instance has multiple references"); -#endif - - // Move into a temporary and return that, because the reference may be a local value of `conv` - T ret = std::move(detail::load_type(obj).operator T&()); - return ret; -} - -// Calling cast() on an rvalue calls pybind::cast with the object rvalue, which does: -// - If we have to move (because T has no copy constructor), do it. This will fail if the moved -// object has multiple references, but trying to copy will fail to compile. -// - If both movable and copyable, check ref count: if 1, move; otherwise copy -// - Otherwise (not movable), copy. -template detail::enable_if_t::value, T> cast(object &&object) { - return move(std::move(object)); -} -template detail::enable_if_t::value, T> cast(object &&object) { - if (object.ref_count() > 1) - return cast(object); - else - return move(std::move(object)); -} -template detail::enable_if_t::value, T> cast(object &&object) { - return cast(object); -} - -template T object::cast() const & { return pybind11::cast(*this); } -template T object::cast() && { return pybind11::cast(std::move(*this)); } -template <> inline void object::cast() const & { return; } -template <> inline void object::cast() && { return; } - -NAMESPACE_BEGIN(detail) - -// Declared in pytypes.h: -template ::value, int>> -object object_or_cast(T &&o) { return pybind11::cast(std::forward(o)); } - -struct overload_unused {}; // Placeholder type for the unneeded (and dead code) static variable in the OVERLOAD_INT macro -template using overload_caster_t = conditional_t< - cast_is_temporary_value_reference::value, make_caster, overload_unused>; - -// Trampoline use: for reference/pointer types to value-converted values, we do a value cast, then -// store the result in the given variable. For other types, this is a no-op. -template enable_if_t::value, T> cast_ref(object &&o, make_caster &caster) { - return cast_op(load_type(caster, o)); -} -template enable_if_t::value, T> cast_ref(object &&, overload_unused &) { - pybind11_fail("Internal error: cast_ref fallback invoked"); } - -// Trampoline use: Having a pybind11::cast with an invalid reference type is going to static_assert, even -// though if it's in dead code, so we provide a "trampoline" to pybind11::cast that only does anything in -// cases where pybind11::cast is valid. -template enable_if_t::value, T> cast_safe(object &&o) { - return pybind11::cast(std::move(o)); } -template enable_if_t::value, T> cast_safe(object &&) { - pybind11_fail("Internal error: cast_safe fallback invoked"); } -template <> inline void cast_safe(object &&) {} - -NAMESPACE_END(detail) - -template tuple make_tuple(Args&&... args_) { - constexpr size_t size = sizeof...(Args); - std::array args { - { reinterpret_steal(detail::make_caster::cast( - std::forward(args_), policy, nullptr))... } - }; - for (size_t i = 0; i < args.size(); i++) { - if (!args[i]) { -#if defined(NDEBUG) - throw cast_error("make_tuple(): unable to convert arguments to Python object (compile in debug mode for details)"); -#else - std::array argtypes { {type_id()...} }; - throw cast_error("make_tuple(): unable to convert argument of type '" + - argtypes[i] + "' to Python object"); -#endif - } - } - tuple result(size); - int counter = 0; - for (auto &arg_value : args) - PyTuple_SET_ITEM(result.ptr(), counter++, arg_value.release().ptr()); - return result; -} - -/// \ingroup annotations -/// Annotation for arguments -struct arg { - /// Constructs an argument with the name of the argument; if null or omitted, this is a positional argument. - constexpr explicit arg(const char *name = nullptr) : name(name), flag_noconvert(false), flag_none(true) { } - /// Assign a value to this argument - template arg_v operator=(T &&value) const; - /// Indicate that the type should not be converted in the type caster - arg &noconvert(bool flag = true) { flag_noconvert = flag; return *this; } - /// Indicates that the argument should/shouldn't allow None (e.g. for nullable pointer args) - arg &none(bool flag = true) { flag_none = flag; return *this; } - - const char *name; ///< If non-null, this is a named kwargs argument - bool flag_noconvert : 1; ///< If set, do not allow conversion (requires a supporting type caster!) - bool flag_none : 1; ///< If set (the default), allow None to be passed to this argument -}; - -/// \ingroup annotations -/// Annotation for arguments with values -struct arg_v : arg { -private: - template - arg_v(arg &&base, T &&x, const char *descr = nullptr) - : arg(base), - value(reinterpret_steal( - detail::make_caster::cast(x, return_value_policy::automatic, {}) - )), - descr(descr) -#if !defined(NDEBUG) - , type(type_id()) -#endif - { } - -public: - /// Direct construction with name, default, and description - template - arg_v(const char *name, T &&x, const char *descr = nullptr) - : arg_v(arg(name), std::forward(x), descr) { } - - /// Called internally when invoking `py::arg("a") = value` - template - arg_v(const arg &base, T &&x, const char *descr = nullptr) - : arg_v(arg(base), std::forward(x), descr) { } - - /// Same as `arg::noconvert()`, but returns *this as arg_v&, not arg& - arg_v &noconvert(bool flag = true) { arg::noconvert(flag); return *this; } - - /// Same as `arg::nonone()`, but returns *this as arg_v&, not arg& - arg_v &none(bool flag = true) { arg::none(flag); return *this; } - - /// The default value - object value; - /// The (optional) description of the default value - const char *descr; -#if !defined(NDEBUG) - /// The C++ type name of the default value (only available when compiled in debug mode) - std::string type; -#endif -}; - -template -arg_v arg::operator=(T &&value) const { return {std::move(*this), std::forward(value)}; } - -/// Alias for backward compatibility -- to be removed in version 2.0 -template using arg_t = arg_v; - -inline namespace literals { -/** \rst - String literal version of `arg` - \endrst */ -constexpr arg operator"" _a(const char *name, size_t) { return arg(name); } -} - -NAMESPACE_BEGIN(detail) - -// forward declaration (definition in attr.h) -struct function_record; - -/// Internal data associated with a single function call -struct function_call { - function_call(function_record &f, handle p); // Implementation in attr.h - - /// The function data: - const function_record &func; - - /// Arguments passed to the function: - std::vector args; - - /// The `convert` value the arguments should be loaded with - std::vector args_convert; - - /// Extra references for the optional `py::args` and/or `py::kwargs` arguments (which, if - /// present, are also in `args` but without a reference). - object args_ref, kwargs_ref; - - /// The parent, if any - handle parent; - - /// If this is a call to an initializer, this argument contains `self` - handle init_self; -}; - - -/// Helper class which loads arguments for C++ functions called from Python -template -class argument_loader { - using indices = make_index_sequence; - - template using argument_is_args = std::is_same, args>; - template using argument_is_kwargs = std::is_same, kwargs>; - // Get args/kwargs argument positions relative to the end of the argument list: - static constexpr auto args_pos = constexpr_first() - (int) sizeof...(Args), - kwargs_pos = constexpr_first() - (int) sizeof...(Args); - - static constexpr bool args_kwargs_are_last = kwargs_pos >= - 1 && args_pos >= kwargs_pos - 1; - - static_assert(args_kwargs_are_last, "py::args/py::kwargs are only permitted as the last argument(s) of a function"); - -public: - static constexpr bool has_kwargs = kwargs_pos < 0; - static constexpr bool has_args = args_pos < 0; - - static constexpr auto arg_names = concat(type_descr(make_caster::name)...); - - bool load_args(function_call &call) { - return load_impl_sequence(call, indices{}); - } - - template - enable_if_t::value, Return> call(Func &&f) && { - return std::move(*this).template call_impl(std::forward(f), indices{}, Guard{}); - } - - template - enable_if_t::value, void_type> call(Func &&f) && { - std::move(*this).template call_impl(std::forward(f), indices{}, Guard{}); - return void_type(); - } - -private: - - static bool load_impl_sequence(function_call &, index_sequence<>) { return true; } - - template - bool load_impl_sequence(function_call &call, index_sequence) { - for (bool r : {std::get(argcasters).load(call.args[Is], call.args_convert[Is])...}) - if (!r) - return false; - return true; - } - - template - Return call_impl(Func &&f, index_sequence, Guard &&) { - return std::forward(f)(cast_op(std::move(std::get(argcasters)))...); - } - - std::tuple...> argcasters; -}; - -/// Helper class which collects only positional arguments for a Python function call. -/// A fancier version below can collect any argument, but this one is optimal for simple calls. -template -class simple_collector { -public: - template - explicit simple_collector(Ts &&...values) - : m_args(pybind11::make_tuple(std::forward(values)...)) { } - - const tuple &args() const & { return m_args; } - dict kwargs() const { return {}; } - - tuple args() && { return std::move(m_args); } - - /// Call a Python function and pass the collected arguments - object call(PyObject *ptr) const { - PyObject *result = PyObject_CallObject(ptr, m_args.ptr()); - if (!result) - throw error_already_set(); - return reinterpret_steal(result); - } - -private: - tuple m_args; -}; - -/// Helper class which collects positional, keyword, * and ** arguments for a Python function call -template -class unpacking_collector { -public: - template - explicit unpacking_collector(Ts &&...values) { - // Tuples aren't (easily) resizable so a list is needed for collection, - // but the actual function call strictly requires a tuple. - auto args_list = list(); - int _[] = { 0, (process(args_list, std::forward(values)), 0)... }; - ignore_unused(_); - - m_args = std::move(args_list); - } - - const tuple &args() const & { return m_args; } - const dict &kwargs() const & { return m_kwargs; } - - tuple args() && { return std::move(m_args); } - dict kwargs() && { return std::move(m_kwargs); } - - /// Call a Python function and pass the collected arguments - object call(PyObject *ptr) const { - PyObject *result = PyObject_Call(ptr, m_args.ptr(), m_kwargs.ptr()); - if (!result) - throw error_already_set(); - return reinterpret_steal(result); - } - -private: - template - void process(list &args_list, T &&x) { - auto o = reinterpret_steal(detail::make_caster::cast(std::forward(x), policy, {})); - if (!o) { -#if defined(NDEBUG) - argument_cast_error(); -#else - argument_cast_error(std::to_string(args_list.size()), type_id()); -#endif - } - args_list.append(o); - } - - void process(list &args_list, detail::args_proxy ap) { - for (const auto &a : ap) - args_list.append(a); - } - - void process(list &/*args_list*/, arg_v a) { - if (!a.name) -#if defined(NDEBUG) - nameless_argument_error(); -#else - nameless_argument_error(a.type); -#endif - - if (m_kwargs.contains(a.name)) { -#if defined(NDEBUG) - multiple_values_error(); -#else - multiple_values_error(a.name); -#endif - } - if (!a.value) { -#if defined(NDEBUG) - argument_cast_error(); -#else - argument_cast_error(a.name, a.type); -#endif - } - m_kwargs[a.name] = a.value; - } - - void process(list &/*args_list*/, detail::kwargs_proxy kp) { - if (!kp) - return; - for (const auto &k : reinterpret_borrow(kp)) { - if (m_kwargs.contains(k.first)) { -#if defined(NDEBUG) - multiple_values_error(); -#else - multiple_values_error(str(k.first)); -#endif - } - m_kwargs[k.first] = k.second; - } - } - - [[noreturn]] static void nameless_argument_error() { - throw type_error("Got kwargs without a name; only named arguments " - "may be passed via py::arg() to a python function call. " - "(compile in debug mode for details)"); - } - [[noreturn]] static void nameless_argument_error(std::string type) { - throw type_error("Got kwargs without a name of type '" + type + "'; only named " - "arguments may be passed via py::arg() to a python function call. "); - } - [[noreturn]] static void multiple_values_error() { - throw type_error("Got multiple values for keyword argument " - "(compile in debug mode for details)"); - } - - [[noreturn]] static void multiple_values_error(std::string name) { - throw type_error("Got multiple values for keyword argument '" + name + "'"); - } - - [[noreturn]] static void argument_cast_error() { - throw cast_error("Unable to convert call argument to Python object " - "(compile in debug mode for details)"); - } - - [[noreturn]] static void argument_cast_error(std::string name, std::string type) { - throw cast_error("Unable to convert call argument '" + name - + "' of type '" + type + "' to Python object"); - } - -private: - tuple m_args; - dict m_kwargs; -}; - -/// Collect only positional arguments for a Python function call -template ...>::value>> -simple_collector collect_arguments(Args &&...args) { - return simple_collector(std::forward(args)...); -} - -/// Collect all arguments, including keywords and unpacking (only instantiated when needed) -template ...>::value>> -unpacking_collector collect_arguments(Args &&...args) { - // Following argument order rules for generalized unpacking according to PEP 448 - static_assert( - constexpr_last() < constexpr_first() - && constexpr_last() < constexpr_first(), - "Invalid function call: positional args must precede keywords and ** unpacking; " - "* unpacking must precede ** unpacking" - ); - return unpacking_collector(std::forward(args)...); -} - -template -template -object object_api::operator()(Args &&...args) const { - return detail::collect_arguments(std::forward(args)...).call(derived().ptr()); -} - -template -template -object object_api::call(Args &&...args) const { - return operator()(std::forward(args)...); -} - -NAMESPACE_END(detail) - -#define PYBIND11_MAKE_OPAQUE(Type) \ - namespace pybind11 { namespace detail { \ - template<> class type_caster : public type_caster_base { }; \ - }} - -NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/VFRendering/thirdparty/pybind11/include/pybind11/chrono.h b/VFRendering/thirdparty/pybind11/include/pybind11/chrono.h deleted file mode 100644 index 95ada76e0..000000000 --- a/VFRendering/thirdparty/pybind11/include/pybind11/chrono.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - pybind11/chrono.h: Transparent conversion between std::chrono and python's datetime - - Copyright (c) 2016 Trent Houliston and - Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "pybind11.h" -#include -#include -#include -#include - -// Backport the PyDateTime_DELTA functions from Python3.3 if required -#ifndef PyDateTime_DELTA_GET_DAYS -#define PyDateTime_DELTA_GET_DAYS(o) (((PyDateTime_Delta*)o)->days) -#endif -#ifndef PyDateTime_DELTA_GET_SECONDS -#define PyDateTime_DELTA_GET_SECONDS(o) (((PyDateTime_Delta*)o)->seconds) -#endif -#ifndef PyDateTime_DELTA_GET_MICROSECONDS -#define PyDateTime_DELTA_GET_MICROSECONDS(o) (((PyDateTime_Delta*)o)->microseconds) -#endif - -NAMESPACE_BEGIN(PYBIND11_NAMESPACE) -NAMESPACE_BEGIN(detail) - -template class duration_caster { -public: - typedef typename type::rep rep; - typedef typename type::period period; - - typedef std::chrono::duration> days; - - bool load(handle src, bool) { - using namespace std::chrono; - - // Lazy initialise the PyDateTime import - if (!PyDateTimeAPI) { PyDateTime_IMPORT; } - - if (!src) return false; - // If invoked with datetime.delta object - if (PyDelta_Check(src.ptr())) { - value = type(duration_cast>( - days(PyDateTime_DELTA_GET_DAYS(src.ptr())) - + seconds(PyDateTime_DELTA_GET_SECONDS(src.ptr())) - + microseconds(PyDateTime_DELTA_GET_MICROSECONDS(src.ptr())))); - return true; - } - // If invoked with a float we assume it is seconds and convert - else if (PyFloat_Check(src.ptr())) { - value = type(duration_cast>(duration(PyFloat_AsDouble(src.ptr())))); - return true; - } - else return false; - } - - // If this is a duration just return it back - static const std::chrono::duration& get_duration(const std::chrono::duration &src) { - return src; - } - - // If this is a time_point get the time_since_epoch - template static std::chrono::duration get_duration(const std::chrono::time_point> &src) { - return src.time_since_epoch(); - } - - static handle cast(const type &src, return_value_policy /* policy */, handle /* parent */) { - using namespace std::chrono; - - // Use overloaded function to get our duration from our source - // Works out if it is a duration or time_point and get the duration - auto d = get_duration(src); - - // Lazy initialise the PyDateTime import - if (!PyDateTimeAPI) { PyDateTime_IMPORT; } - - // Declare these special duration types so the conversions happen with the correct primitive types (int) - using dd_t = duration>; - using ss_t = duration>; - using us_t = duration; - - auto dd = duration_cast(d); - auto subd = d - dd; - auto ss = duration_cast(subd); - auto us = duration_cast(subd - ss); - return PyDelta_FromDSU(dd.count(), ss.count(), us.count()); - } - - PYBIND11_TYPE_CASTER(type, _("datetime.timedelta")); -}; - -// This is for casting times on the system clock into datetime.datetime instances -template class type_caster> { -public: - typedef std::chrono::time_point type; - bool load(handle src, bool) { - using namespace std::chrono; - - // Lazy initialise the PyDateTime import - if (!PyDateTimeAPI) { PyDateTime_IMPORT; } - - if (!src) return false; - if (PyDateTime_Check(src.ptr())) { - std::tm cal; - cal.tm_sec = PyDateTime_DATE_GET_SECOND(src.ptr()); - cal.tm_min = PyDateTime_DATE_GET_MINUTE(src.ptr()); - cal.tm_hour = PyDateTime_DATE_GET_HOUR(src.ptr()); - cal.tm_mday = PyDateTime_GET_DAY(src.ptr()); - cal.tm_mon = PyDateTime_GET_MONTH(src.ptr()) - 1; - cal.tm_year = PyDateTime_GET_YEAR(src.ptr()) - 1900; - cal.tm_isdst = -1; - - value = system_clock::from_time_t(std::mktime(&cal)) + microseconds(PyDateTime_DATE_GET_MICROSECOND(src.ptr())); - return true; - } - else return false; - } - - static handle cast(const std::chrono::time_point &src, return_value_policy /* policy */, handle /* parent */) { - using namespace std::chrono; - - // Lazy initialise the PyDateTime import - if (!PyDateTimeAPI) { PyDateTime_IMPORT; } - - std::time_t tt = system_clock::to_time_t(src); - // this function uses static memory so it's best to copy it out asap just in case - // otherwise other code that is using localtime may break this (not just python code) - std::tm localtime = *std::localtime(&tt); - - // Declare these special duration types so the conversions happen with the correct primitive types (int) - using us_t = duration; - - return PyDateTime_FromDateAndTime(localtime.tm_year + 1900, - localtime.tm_mon + 1, - localtime.tm_mday, - localtime.tm_hour, - localtime.tm_min, - localtime.tm_sec, - (duration_cast(src.time_since_epoch() % seconds(1))).count()); - } - PYBIND11_TYPE_CASTER(type, _("datetime.datetime")); -}; - -// Other clocks that are not the system clock are not measured as datetime.datetime objects -// since they are not measured on calendar time. So instead we just make them timedeltas -// Or if they have passed us a time as a float we convert that -template class type_caster> -: public duration_caster> { -}; - -template class type_caster> -: public duration_caster> { -}; - -NAMESPACE_END(detail) -NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/VFRendering/thirdparty/pybind11/include/pybind11/common.h b/VFRendering/thirdparty/pybind11/include/pybind11/common.h deleted file mode 100644 index 6c8a4f1e8..000000000 --- a/VFRendering/thirdparty/pybind11/include/pybind11/common.h +++ /dev/null @@ -1,2 +0,0 @@ -#include "detail/common.h" -#warning "Including 'common.h' is deprecated. It will be removed in v3.0. Use 'pybind11.h'." diff --git a/VFRendering/thirdparty/pybind11/include/pybind11/complex.h b/VFRendering/thirdparty/pybind11/include/pybind11/complex.h deleted file mode 100644 index 3f8963857..000000000 --- a/VFRendering/thirdparty/pybind11/include/pybind11/complex.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - pybind11/complex.h: Complex number support - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "pybind11.h" -#include - -/// glibc defines I as a macro which breaks things, e.g., boost template names -#ifdef I -# undef I -#endif - -NAMESPACE_BEGIN(PYBIND11_NAMESPACE) - -template struct format_descriptor, detail::enable_if_t::value>> { - static constexpr const char c = format_descriptor::c; - static constexpr const char value[3] = { 'Z', c, '\0' }; - static std::string format() { return std::string(value); } -}; - -#ifndef PYBIND11_CPP17 - -template constexpr const char format_descriptor< - std::complex, detail::enable_if_t::value>>::value[3]; - -#endif - -NAMESPACE_BEGIN(detail) - -template struct is_fmt_numeric, detail::enable_if_t::value>> { - static constexpr bool value = true; - static constexpr int index = is_fmt_numeric::index + 3; -}; - -template class type_caster> { -public: - bool load(handle src, bool convert) { - if (!src) - return false; - if (!convert && !PyComplex_Check(src.ptr())) - return false; - Py_complex result = PyComplex_AsCComplex(src.ptr()); - if (result.real == -1.0 && PyErr_Occurred()) { - PyErr_Clear(); - return false; - } - value = std::complex((T) result.real, (T) result.imag); - return true; - } - - static handle cast(const std::complex &src, return_value_policy /* policy */, handle /* parent */) { - return PyComplex_FromDoubles((double) src.real(), (double) src.imag()); - } - - PYBIND11_TYPE_CASTER(std::complex, _("complex")); -}; -NAMESPACE_END(detail) -NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/VFRendering/thirdparty/pybind11/include/pybind11/detail/class.h b/VFRendering/thirdparty/pybind11/include/pybind11/detail/class.h deleted file mode 100644 index 7a5dd0130..000000000 --- a/VFRendering/thirdparty/pybind11/include/pybind11/detail/class.h +++ /dev/null @@ -1,622 +0,0 @@ -/* - pybind11/detail/class.h: Python C API implementation details for py::class_ - - Copyright (c) 2017 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "../attr.h" - -NAMESPACE_BEGIN(PYBIND11_NAMESPACE) -NAMESPACE_BEGIN(detail) - -#if PY_VERSION_HEX >= 0x03030000 -# define PYBIND11_BUILTIN_QUALNAME -# define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj) -#else -// In pre-3.3 Python, we still set __qualname__ so that we can produce reliable function type -// signatures; in 3.3+ this macro expands to nothing: -# define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj) setattr((PyObject *) obj, "__qualname__", nameobj) -#endif - -inline PyTypeObject *type_incref(PyTypeObject *type) { - Py_INCREF(type); - return type; -} - -#if !defined(PYPY_VERSION) - -/// `pybind11_static_property.__get__()`: Always pass the class instead of the instance. -extern "C" inline PyObject *pybind11_static_get(PyObject *self, PyObject * /*ob*/, PyObject *cls) { - return PyProperty_Type.tp_descr_get(self, cls, cls); -} - -/// `pybind11_static_property.__set__()`: Just like the above `__get__()`. -extern "C" inline int pybind11_static_set(PyObject *self, PyObject *obj, PyObject *value) { - PyObject *cls = PyType_Check(obj) ? obj : (PyObject *) Py_TYPE(obj); - return PyProperty_Type.tp_descr_set(self, cls, value); -} - -/** A `static_property` is the same as a `property` but the `__get__()` and `__set__()` - methods are modified to always use the object type instead of a concrete instance. - Return value: New reference. */ -inline PyTypeObject *make_static_property_type() { - constexpr auto *name = "pybind11_static_property"; - auto name_obj = reinterpret_steal(PYBIND11_FROM_STRING(name)); - - /* Danger zone: from now (and until PyType_Ready), make sure to - issue no Python C API calls which could potentially invoke the - garbage collector (the GC will call type_traverse(), which will in - turn find the newly constructed type in an invalid state) */ - auto heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0); - if (!heap_type) - pybind11_fail("make_static_property_type(): error allocating type!"); - - heap_type->ht_name = name_obj.inc_ref().ptr(); -#ifdef PYBIND11_BUILTIN_QUALNAME - heap_type->ht_qualname = name_obj.inc_ref().ptr(); -#endif - - auto type = &heap_type->ht_type; - type->tp_name = name; - type->tp_base = type_incref(&PyProperty_Type); - type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE; - type->tp_descr_get = pybind11_static_get; - type->tp_descr_set = pybind11_static_set; - - if (PyType_Ready(type) < 0) - pybind11_fail("make_static_property_type(): failure in PyType_Ready()!"); - - setattr((PyObject *) type, "__module__", str("pybind11_builtins")); - PYBIND11_SET_OLDPY_QUALNAME(type, name_obj); - - return type; -} - -#else // PYPY - -/** PyPy has some issues with the above C API, so we evaluate Python code instead. - This function will only be called once so performance isn't really a concern. - Return value: New reference. */ -inline PyTypeObject *make_static_property_type() { - auto d = dict(); - PyObject *result = PyRun_String(R"(\ - class pybind11_static_property(property): - def __get__(self, obj, cls): - return property.__get__(self, cls, cls) - - def __set__(self, obj, value): - cls = obj if isinstance(obj, type) else type(obj) - property.__set__(self, cls, value) - )", Py_file_input, d.ptr(), d.ptr() - ); - if (result == nullptr) - throw error_already_set(); - Py_DECREF(result); - return (PyTypeObject *) d["pybind11_static_property"].cast().release().ptr(); -} - -#endif // PYPY - -/** Types with static properties need to handle `Type.static_prop = x` in a specific way. - By default, Python replaces the `static_property` itself, but for wrapped C++ types - we need to call `static_property.__set__()` in order to propagate the new value to - the underlying C++ data structure. */ -extern "C" inline int pybind11_meta_setattro(PyObject* obj, PyObject* name, PyObject* value) { - // Use `_PyType_Lookup()` instead of `PyObject_GetAttr()` in order to get the raw - // descriptor (`property`) instead of calling `tp_descr_get` (`property.__get__()`). - PyObject *descr = _PyType_Lookup((PyTypeObject *) obj, name); - - // The following assignment combinations are possible: - // 1. `Type.static_prop = value` --> descr_set: `Type.static_prop.__set__(value)` - // 2. `Type.static_prop = other_static_prop` --> setattro: replace existing `static_prop` - // 3. `Type.regular_attribute = value` --> setattro: regular attribute assignment - const auto static_prop = (PyObject *) get_internals().static_property_type; - const auto call_descr_set = descr && PyObject_IsInstance(descr, static_prop) - && !PyObject_IsInstance(value, static_prop); - if (call_descr_set) { - // Call `static_property.__set__()` instead of replacing the `static_property`. -#if !defined(PYPY_VERSION) - return Py_TYPE(descr)->tp_descr_set(descr, obj, value); -#else - if (PyObject *result = PyObject_CallMethod(descr, "__set__", "OO", obj, value)) { - Py_DECREF(result); - return 0; - } else { - return -1; - } -#endif - } else { - // Replace existing attribute. - return PyType_Type.tp_setattro(obj, name, value); - } -} - -#if PY_MAJOR_VERSION >= 3 -/** - * Python 3's PyInstanceMethod_Type hides itself via its tp_descr_get, which prevents aliasing - * methods via cls.attr("m2") = cls.attr("m1"): instead the tp_descr_get returns a plain function, - * when called on a class, or a PyMethod, when called on an instance. Override that behaviour here - * to do a special case bypass for PyInstanceMethod_Types. - */ -extern "C" inline PyObject *pybind11_meta_getattro(PyObject *obj, PyObject *name) { - PyObject *descr = _PyType_Lookup((PyTypeObject *) obj, name); - if (descr && PyInstanceMethod_Check(descr)) { - Py_INCREF(descr); - return descr; - } - else { - return PyType_Type.tp_getattro(obj, name); - } -} -#endif - -/** This metaclass is assigned by default to all pybind11 types and is required in order - for static properties to function correctly. Users may override this using `py::metaclass`. - Return value: New reference. */ -inline PyTypeObject* make_default_metaclass() { - constexpr auto *name = "pybind11_type"; - auto name_obj = reinterpret_steal(PYBIND11_FROM_STRING(name)); - - /* Danger zone: from now (and until PyType_Ready), make sure to - issue no Python C API calls which could potentially invoke the - garbage collector (the GC will call type_traverse(), which will in - turn find the newly constructed type in an invalid state) */ - auto heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0); - if (!heap_type) - pybind11_fail("make_default_metaclass(): error allocating metaclass!"); - - heap_type->ht_name = name_obj.inc_ref().ptr(); -#ifdef PYBIND11_BUILTIN_QUALNAME - heap_type->ht_qualname = name_obj.inc_ref().ptr(); -#endif - - auto type = &heap_type->ht_type; - type->tp_name = name; - type->tp_base = type_incref(&PyType_Type); - type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE; - - type->tp_setattro = pybind11_meta_setattro; -#if PY_MAJOR_VERSION >= 3 - type->tp_getattro = pybind11_meta_getattro; -#endif - - if (PyType_Ready(type) < 0) - pybind11_fail("make_default_metaclass(): failure in PyType_Ready()!"); - - setattr((PyObject *) type, "__module__", str("pybind11_builtins")); - PYBIND11_SET_OLDPY_QUALNAME(type, name_obj); - - return type; -} - -/// For multiple inheritance types we need to recursively register/deregister base pointers for any -/// base classes with pointers that are difference from the instance value pointer so that we can -/// correctly recognize an offset base class pointer. This calls a function with any offset base ptrs. -inline void traverse_offset_bases(void *valueptr, const detail::type_info *tinfo, instance *self, - bool (*f)(void * /*parentptr*/, instance * /*self*/)) { - for (handle h : reinterpret_borrow(tinfo->type->tp_bases)) { - if (auto parent_tinfo = get_type_info((PyTypeObject *) h.ptr())) { - for (auto &c : parent_tinfo->implicit_casts) { - if (c.first == tinfo->cpptype) { - auto *parentptr = c.second(valueptr); - if (parentptr != valueptr) - f(parentptr, self); - traverse_offset_bases(parentptr, parent_tinfo, self, f); - break; - } - } - } - } -} - -inline bool register_instance_impl(void *ptr, instance *self) { - get_internals().registered_instances.emplace(ptr, self); - return true; // unused, but gives the same signature as the deregister func -} -inline bool deregister_instance_impl(void *ptr, instance *self) { - auto ®istered_instances = get_internals().registered_instances; - auto range = registered_instances.equal_range(ptr); - for (auto it = range.first; it != range.second; ++it) { - if (Py_TYPE(self) == Py_TYPE(it->second)) { - registered_instances.erase(it); - return true; - } - } - return false; -} - -inline void register_instance(instance *self, void *valptr, const type_info *tinfo) { - register_instance_impl(valptr, self); - if (!tinfo->simple_ancestors) - traverse_offset_bases(valptr, tinfo, self, register_instance_impl); -} - -inline bool deregister_instance(instance *self, void *valptr, const type_info *tinfo) { - bool ret = deregister_instance_impl(valptr, self); - if (!tinfo->simple_ancestors) - traverse_offset_bases(valptr, tinfo, self, deregister_instance_impl); - return ret; -} - -/// Instance creation function for all pybind11 types. It allocates the internal instance layout for -/// holding C++ objects and holders. Allocation is done lazily (the first time the instance is cast -/// to a reference or pointer), and initialization is done by an `__init__` function. -inline PyObject *make_new_instance(PyTypeObject *type) { -#if defined(PYPY_VERSION) - // PyPy gets tp_basicsize wrong (issue 2482) under multiple inheritance when the first inherited - // object is a a plain Python type (i.e. not derived from an extension type). Fix it. - ssize_t instance_size = static_cast(sizeof(instance)); - if (type->tp_basicsize < instance_size) { - type->tp_basicsize = instance_size; - } -#endif - PyObject *self = type->tp_alloc(type, 0); - auto inst = reinterpret_cast(self); - // Allocate the value/holder internals: - inst->allocate_layout(); - - inst->owned = true; - - return self; -} - -/// Instance creation function for all pybind11 types. It only allocates space for the -/// C++ object, but doesn't call the constructor -- an `__init__` function must do that. -extern "C" inline PyObject *pybind11_object_new(PyTypeObject *type, PyObject *, PyObject *) { - return make_new_instance(type); -} - -/// An `__init__` function constructs the C++ object. Users should provide at least one -/// of these using `py::init` or directly with `.def(__init__, ...)`. Otherwise, the -/// following default function will be used which simply throws an exception. -extern "C" inline int pybind11_object_init(PyObject *self, PyObject *, PyObject *) { - PyTypeObject *type = Py_TYPE(self); - std::string msg; -#if defined(PYPY_VERSION) - msg += handle((PyObject *) type).attr("__module__").cast() + "."; -#endif - msg += type->tp_name; - msg += ": No constructor defined!"; - PyErr_SetString(PyExc_TypeError, msg.c_str()); - return -1; -} - -inline void add_patient(PyObject *nurse, PyObject *patient) { - auto &internals = get_internals(); - auto instance = reinterpret_cast(nurse); - instance->has_patients = true; - Py_INCREF(patient); - internals.patients[nurse].push_back(patient); -} - -inline void clear_patients(PyObject *self) { - auto instance = reinterpret_cast(self); - auto &internals = get_internals(); - auto pos = internals.patients.find(self); - assert(pos != internals.patients.end()); - // Clearing the patients can cause more Python code to run, which - // can invalidate the iterator. Extract the vector of patients - // from the unordered_map first. - auto patients = std::move(pos->second); - internals.patients.erase(pos); - instance->has_patients = false; - for (PyObject *&patient : patients) - Py_CLEAR(patient); -} - -/// Clears all internal data from the instance and removes it from registered instances in -/// preparation for deallocation. -inline void clear_instance(PyObject *self) { - auto instance = reinterpret_cast(self); - - // Deallocate any values/holders, if present: - for (auto &v_h : values_and_holders(instance)) { - if (v_h) { - - // We have to deregister before we call dealloc because, for virtual MI types, we still - // need to be able to get the parent pointers. - if (v_h.instance_registered() && !deregister_instance(instance, v_h.value_ptr(), v_h.type)) - pybind11_fail("pybind11_object_dealloc(): Tried to deallocate unregistered instance!"); - - if (instance->owned || v_h.holder_constructed()) - v_h.type->dealloc(v_h); - } - } - // Deallocate the value/holder layout internals: - instance->deallocate_layout(); - - if (instance->weakrefs) - PyObject_ClearWeakRefs(self); - - PyObject **dict_ptr = _PyObject_GetDictPtr(self); - if (dict_ptr) - Py_CLEAR(*dict_ptr); - - if (instance->has_patients) - clear_patients(self); -} - -/// Instance destructor function for all pybind11 types. It calls `type_info.dealloc` -/// to destroy the C++ object itself, while the rest is Python bookkeeping. -extern "C" inline void pybind11_object_dealloc(PyObject *self) { - clear_instance(self); - - auto type = Py_TYPE(self); - type->tp_free(self); - - // `type->tp_dealloc != pybind11_object_dealloc` means that we're being called - // as part of a derived type's dealloc, in which case we're not allowed to decref - // the type here. For cross-module compatibility, we shouldn't compare directly - // with `pybind11_object_dealloc`, but with the common one stashed in internals. - auto pybind11_object_type = (PyTypeObject *) get_internals().instance_base; - if (type->tp_dealloc == pybind11_object_type->tp_dealloc) - Py_DECREF(type); -} - -/** Create the type which can be used as a common base for all classes. This is - needed in order to satisfy Python's requirements for multiple inheritance. - Return value: New reference. */ -inline PyObject *make_object_base_type(PyTypeObject *metaclass) { - constexpr auto *name = "pybind11_object"; - auto name_obj = reinterpret_steal(PYBIND11_FROM_STRING(name)); - - /* Danger zone: from now (and until PyType_Ready), make sure to - issue no Python C API calls which could potentially invoke the - garbage collector (the GC will call type_traverse(), which will in - turn find the newly constructed type in an invalid state) */ - auto heap_type = (PyHeapTypeObject *) metaclass->tp_alloc(metaclass, 0); - if (!heap_type) - pybind11_fail("make_object_base_type(): error allocating type!"); - - heap_type->ht_name = name_obj.inc_ref().ptr(); -#ifdef PYBIND11_BUILTIN_QUALNAME - heap_type->ht_qualname = name_obj.inc_ref().ptr(); -#endif - - auto type = &heap_type->ht_type; - type->tp_name = name; - type->tp_base = type_incref(&PyBaseObject_Type); - type->tp_basicsize = static_cast(sizeof(instance)); - type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE; - - type->tp_new = pybind11_object_new; - type->tp_init = pybind11_object_init; - type->tp_dealloc = pybind11_object_dealloc; - - /* Support weak references (needed for the keep_alive feature) */ - type->tp_weaklistoffset = offsetof(instance, weakrefs); - - if (PyType_Ready(type) < 0) - pybind11_fail("PyType_Ready failed in make_object_base_type():" + error_string()); - - setattr((PyObject *) type, "__module__", str("pybind11_builtins")); - PYBIND11_SET_OLDPY_QUALNAME(type, name_obj); - - assert(!PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC)); - return (PyObject *) heap_type; -} - -/// dynamic_attr: Support for `d = instance.__dict__`. -extern "C" inline PyObject *pybind11_get_dict(PyObject *self, void *) { - PyObject *&dict = *_PyObject_GetDictPtr(self); - if (!dict) - dict = PyDict_New(); - Py_XINCREF(dict); - return dict; -} - -/// dynamic_attr: Support for `instance.__dict__ = dict()`. -extern "C" inline int pybind11_set_dict(PyObject *self, PyObject *new_dict, void *) { - if (!PyDict_Check(new_dict)) { - PyErr_Format(PyExc_TypeError, "__dict__ must be set to a dictionary, not a '%.200s'", - Py_TYPE(new_dict)->tp_name); - return -1; - } - PyObject *&dict = *_PyObject_GetDictPtr(self); - Py_INCREF(new_dict); - Py_CLEAR(dict); - dict = new_dict; - return 0; -} - -/// dynamic_attr: Allow the garbage collector to traverse the internal instance `__dict__`. -extern "C" inline int pybind11_traverse(PyObject *self, visitproc visit, void *arg) { - PyObject *&dict = *_PyObject_GetDictPtr(self); - Py_VISIT(dict); - return 0; -} - -/// dynamic_attr: Allow the GC to clear the dictionary. -extern "C" inline int pybind11_clear(PyObject *self) { - PyObject *&dict = *_PyObject_GetDictPtr(self); - Py_CLEAR(dict); - return 0; -} - -/// Give instances of this type a `__dict__` and opt into garbage collection. -inline void enable_dynamic_attributes(PyHeapTypeObject *heap_type) { - auto type = &heap_type->ht_type; -#if defined(PYPY_VERSION) - pybind11_fail(std::string(type->tp_name) + ": dynamic attributes are " - "currently not supported in " - "conjunction with PyPy!"); -#endif - type->tp_flags |= Py_TPFLAGS_HAVE_GC; - type->tp_dictoffset = type->tp_basicsize; // place dict at the end - type->tp_basicsize += (ssize_t)sizeof(PyObject *); // and allocate enough space for it - type->tp_traverse = pybind11_traverse; - type->tp_clear = pybind11_clear; - - static PyGetSetDef getset[] = { - {const_cast("__dict__"), pybind11_get_dict, pybind11_set_dict, nullptr, nullptr}, - {nullptr, nullptr, nullptr, nullptr, nullptr} - }; - type->tp_getset = getset; -} - -/// buffer_protocol: Fill in the view as specified by flags. -extern "C" inline int pybind11_getbuffer(PyObject *obj, Py_buffer *view, int flags) { - // Look for a `get_buffer` implementation in this type's info or any bases (following MRO). - type_info *tinfo = nullptr; - for (auto type : reinterpret_borrow(Py_TYPE(obj)->tp_mro)) { - tinfo = get_type_info((PyTypeObject *) type.ptr()); - if (tinfo && tinfo->get_buffer) - break; - } - if (view == nullptr || obj == nullptr || !tinfo || !tinfo->get_buffer) { - if (view) - view->obj = nullptr; - PyErr_SetString(PyExc_BufferError, "pybind11_getbuffer(): Internal error"); - return -1; - } - std::memset(view, 0, sizeof(Py_buffer)); - buffer_info *info = tinfo->get_buffer(obj, tinfo->get_buffer_data); - view->obj = obj; - view->ndim = 1; - view->internal = info; - view->buf = info->ptr; - view->itemsize = info->itemsize; - view->len = view->itemsize; - for (auto s : info->shape) - view->len *= s; - if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) - view->format = const_cast(info->format.c_str()); - if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) { - view->ndim = (int) info->ndim; - view->strides = &info->strides[0]; - view->shape = &info->shape[0]; - } - Py_INCREF(view->obj); - return 0; -} - -/// buffer_protocol: Release the resources of the buffer. -extern "C" inline void pybind11_releasebuffer(PyObject *, Py_buffer *view) { - delete (buffer_info *) view->internal; -} - -/// Give this type a buffer interface. -inline void enable_buffer_protocol(PyHeapTypeObject *heap_type) { - heap_type->ht_type.tp_as_buffer = &heap_type->as_buffer; -#if PY_MAJOR_VERSION < 3 - heap_type->ht_type.tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER; -#endif - - heap_type->as_buffer.bf_getbuffer = pybind11_getbuffer; - heap_type->as_buffer.bf_releasebuffer = pybind11_releasebuffer; -} - -/** Create a brand new Python type according to the `type_record` specification. - Return value: New reference. */ -inline PyObject* make_new_python_type(const type_record &rec) { - auto name = reinterpret_steal(PYBIND11_FROM_STRING(rec.name)); - - auto qualname = name; - if (rec.scope && !PyModule_Check(rec.scope.ptr()) && hasattr(rec.scope, "__qualname__")) { -#if PY_MAJOR_VERSION >= 3 - qualname = reinterpret_steal( - PyUnicode_FromFormat("%U.%U", rec.scope.attr("__qualname__").ptr(), name.ptr())); -#else - qualname = str(rec.scope.attr("__qualname__").cast() + "." + rec.name); -#endif - } - - object module; - if (rec.scope) { - if (hasattr(rec.scope, "__module__")) - module = rec.scope.attr("__module__"); - else if (hasattr(rec.scope, "__name__")) - module = rec.scope.attr("__name__"); - } - - auto full_name = c_str( -#if !defined(PYPY_VERSION) - module ? str(module).cast() + "." + rec.name : -#endif - rec.name); - - char *tp_doc = nullptr; - if (rec.doc && options::show_user_defined_docstrings()) { - /* Allocate memory for docstring (using PyObject_MALLOC, since - Python will free this later on) */ - size_t size = strlen(rec.doc) + 1; - tp_doc = (char *) PyObject_MALLOC(size); - memcpy((void *) tp_doc, rec.doc, size); - } - - auto &internals = get_internals(); - auto bases = tuple(rec.bases); - auto base = (bases.size() == 0) ? internals.instance_base - : bases[0].ptr(); - - /* Danger zone: from now (and until PyType_Ready), make sure to - issue no Python C API calls which could potentially invoke the - garbage collector (the GC will call type_traverse(), which will in - turn find the newly constructed type in an invalid state) */ - auto metaclass = rec.metaclass.ptr() ? (PyTypeObject *) rec.metaclass.ptr() - : internals.default_metaclass; - - auto heap_type = (PyHeapTypeObject *) metaclass->tp_alloc(metaclass, 0); - if (!heap_type) - pybind11_fail(std::string(rec.name) + ": Unable to create type object!"); - - heap_type->ht_name = name.release().ptr(); -#ifdef PYBIND11_BUILTIN_QUALNAME - heap_type->ht_qualname = qualname.inc_ref().ptr(); -#endif - - auto type = &heap_type->ht_type; - type->tp_name = full_name; - type->tp_doc = tp_doc; - type->tp_base = type_incref((PyTypeObject *)base); - type->tp_basicsize = static_cast(sizeof(instance)); - if (bases.size() > 0) - type->tp_bases = bases.release().ptr(); - - /* Don't inherit base __init__ */ - type->tp_init = pybind11_object_init; - - /* Supported protocols */ - type->tp_as_number = &heap_type->as_number; - type->tp_as_sequence = &heap_type->as_sequence; - type->tp_as_mapping = &heap_type->as_mapping; - - /* Flags */ - type->tp_flags |= Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE; -#if PY_MAJOR_VERSION < 3 - type->tp_flags |= Py_TPFLAGS_CHECKTYPES; -#endif - - if (rec.dynamic_attr) - enable_dynamic_attributes(heap_type); - - if (rec.buffer_protocol) - enable_buffer_protocol(heap_type); - - if (PyType_Ready(type) < 0) - pybind11_fail(std::string(rec.name) + ": PyType_Ready failed (" + error_string() + ")!"); - - assert(rec.dynamic_attr ? PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC) - : !PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC)); - - /* Register type with the parent scope */ - if (rec.scope) - setattr(rec.scope, rec.name, (PyObject *) type); - else - Py_INCREF(type); // Keep it alive forever (reference leak) - - if (module) // Needed by pydoc - setattr((PyObject *) type, "__module__", module); - - PYBIND11_SET_OLDPY_QUALNAME(type, qualname); - - return (PyObject *) type; -} - -NAMESPACE_END(detail) -NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/VFRendering/thirdparty/pybind11/include/pybind11/detail/common.h b/VFRendering/thirdparty/pybind11/include/pybind11/detail/common.h deleted file mode 100644 index 7d629c0ff..000000000 --- a/VFRendering/thirdparty/pybind11/include/pybind11/detail/common.h +++ /dev/null @@ -1,813 +0,0 @@ -/* - pybind11/detail/common.h -- Basic macros - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#if !defined(NAMESPACE_BEGIN) -# define NAMESPACE_BEGIN(name) namespace name { -#endif -#if !defined(NAMESPACE_END) -# define NAMESPACE_END(name) } -#endif - -// Robust support for some features and loading modules compiled against different pybind versions -// requires forcing hidden visibility on pybind code, so we enforce this by setting the attribute on -// the main `pybind11` namespace. -#if !defined(PYBIND11_NAMESPACE) -# ifdef __GNUG__ -# define PYBIND11_NAMESPACE pybind11 __attribute__((visibility("hidden"))) -# else -# define PYBIND11_NAMESPACE pybind11 -# endif -#endif - -#if !defined(_MSC_VER) && !defined(__INTEL_COMPILER) -# if __cplusplus >= 201402L -# define PYBIND11_CPP14 -# if __cplusplus > 201402L /* Temporary: should be updated to >= the final C++17 value once known */ -# define PYBIND11_CPP17 -# endif -# endif -#elif defined(_MSC_VER) -// MSVC sets _MSVC_LANG rather than __cplusplus (supposedly until the standard is fully implemented) -# if _MSVC_LANG >= 201402L -# define PYBIND11_CPP14 -# if _MSVC_LANG > 201402L && _MSC_VER >= 1910 -# define PYBIND11_CPP17 -# endif -# endif -#endif - -// Compiler version assertions -#if defined(__INTEL_COMPILER) -# if __INTEL_COMPILER < 1500 -# error pybind11 requires Intel C++ compiler v15 or newer -# endif -#elif defined(__clang__) && !defined(__apple_build_version__) -# if __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 3) -# error pybind11 requires clang 3.3 or newer -# endif -#elif defined(__clang__) -// Apple changes clang version macros to its Xcode version; the first Xcode release based on -// (upstream) clang 3.3 was Xcode 5: -# if __clang_major__ < 5 -# error pybind11 requires Xcode/clang 5.0 or newer -# endif -#elif defined(__GNUG__) -# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8) -# error pybind11 requires gcc 4.8 or newer -# endif -#elif defined(_MSC_VER) -// Pybind hits various compiler bugs in 2015u2 and earlier, and also makes use of some stl features -// (e.g. std::negation) added in 2015u3: -# if _MSC_FULL_VER < 190024210 -# error pybind11 requires MSVC 2015 update 3 or newer -# endif -#endif - -#if !defined(PYBIND11_EXPORT) -# if defined(WIN32) || defined(_WIN32) -# define PYBIND11_EXPORT __declspec(dllexport) -# else -# define PYBIND11_EXPORT __attribute__ ((visibility("default"))) -# endif -#endif - -#if defined(_MSC_VER) -# define PYBIND11_NOINLINE __declspec(noinline) -#else -# define PYBIND11_NOINLINE __attribute__ ((noinline)) -#endif - -#if defined(PYBIND11_CPP14) -# define PYBIND11_DEPRECATED(reason) [[deprecated(reason)]] -#else -# define PYBIND11_DEPRECATED(reason) __attribute__((deprecated(reason))) -#endif - -#define PYBIND11_VERSION_MAJOR 2 -#define PYBIND11_VERSION_MINOR 3 -#define PYBIND11_VERSION_PATCH dev0 - -/// Include Python header, disable linking to pythonX_d.lib on Windows in debug mode -#if defined(_MSC_VER) -# if (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 4) -# define HAVE_ROUND 1 -# endif -# pragma warning(push) -# pragma warning(disable: 4510 4610 4512 4005) -# if defined(_DEBUG) -# define PYBIND11_DEBUG_MARKER -# undef _DEBUG -# endif -#endif - -#include -#include -#include - -#if defined(_WIN32) && (defined(min) || defined(max)) -# error Macro clash with min and max -- define NOMINMAX when compiling your program on Windows -#endif - -#if defined(isalnum) -# undef isalnum -# undef isalpha -# undef islower -# undef isspace -# undef isupper -# undef tolower -# undef toupper -#endif - -#if defined(_MSC_VER) -# if defined(PYBIND11_DEBUG_MARKER) -# define _DEBUG -# undef PYBIND11_DEBUG_MARKER -# endif -# pragma warning(pop) -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if PY_MAJOR_VERSION >= 3 /// Compatibility macros for various Python versions -#define PYBIND11_INSTANCE_METHOD_NEW(ptr, class_) PyInstanceMethod_New(ptr) -#define PYBIND11_INSTANCE_METHOD_CHECK PyInstanceMethod_Check -#define PYBIND11_INSTANCE_METHOD_GET_FUNCTION PyInstanceMethod_GET_FUNCTION -#define PYBIND11_BYTES_CHECK PyBytes_Check -#define PYBIND11_BYTES_FROM_STRING PyBytes_FromString -#define PYBIND11_BYTES_FROM_STRING_AND_SIZE PyBytes_FromStringAndSize -#define PYBIND11_BYTES_AS_STRING_AND_SIZE PyBytes_AsStringAndSize -#define PYBIND11_BYTES_AS_STRING PyBytes_AsString -#define PYBIND11_BYTES_SIZE PyBytes_Size -#define PYBIND11_LONG_CHECK(o) PyLong_Check(o) -#define PYBIND11_LONG_AS_LONGLONG(o) PyLong_AsLongLong(o) -#define PYBIND11_LONG_FROM_SIGNED(o) PyLong_FromSsize_t((ssize_t) o) -#define PYBIND11_LONG_FROM_UNSIGNED(o) PyLong_FromSize_t((size_t) o) -#define PYBIND11_BYTES_NAME "bytes" -#define PYBIND11_STRING_NAME "str" -#define PYBIND11_SLICE_OBJECT PyObject -#define PYBIND11_FROM_STRING PyUnicode_FromString -#define PYBIND11_STR_TYPE ::pybind11::str -#define PYBIND11_BOOL_ATTR "__bool__" -#define PYBIND11_NB_BOOL(ptr) ((ptr)->nb_bool) -#define PYBIND11_PLUGIN_IMPL(name) \ - extern "C" PYBIND11_EXPORT PyObject *PyInit_##name() - -#else -#define PYBIND11_INSTANCE_METHOD_NEW(ptr, class_) PyMethod_New(ptr, nullptr, class_) -#define PYBIND11_INSTANCE_METHOD_CHECK PyMethod_Check -#define PYBIND11_INSTANCE_METHOD_GET_FUNCTION PyMethod_GET_FUNCTION -#define PYBIND11_BYTES_CHECK PyString_Check -#define PYBIND11_BYTES_FROM_STRING PyString_FromString -#define PYBIND11_BYTES_FROM_STRING_AND_SIZE PyString_FromStringAndSize -#define PYBIND11_BYTES_AS_STRING_AND_SIZE PyString_AsStringAndSize -#define PYBIND11_BYTES_AS_STRING PyString_AsString -#define PYBIND11_BYTES_SIZE PyString_Size -#define PYBIND11_LONG_CHECK(o) (PyInt_Check(o) || PyLong_Check(o)) -#define PYBIND11_LONG_AS_LONGLONG(o) (PyInt_Check(o) ? (long long) PyLong_AsLong(o) : PyLong_AsLongLong(o)) -#define PYBIND11_LONG_FROM_SIGNED(o) PyInt_FromSsize_t((ssize_t) o) // Returns long if needed. -#define PYBIND11_LONG_FROM_UNSIGNED(o) PyInt_FromSize_t((size_t) o) // Returns long if needed. -#define PYBIND11_BYTES_NAME "str" -#define PYBIND11_STRING_NAME "unicode" -#define PYBIND11_SLICE_OBJECT PySliceObject -#define PYBIND11_FROM_STRING PyString_FromString -#define PYBIND11_STR_TYPE ::pybind11::bytes -#define PYBIND11_BOOL_ATTR "__nonzero__" -#define PYBIND11_NB_BOOL(ptr) ((ptr)->nb_nonzero) -#define PYBIND11_PLUGIN_IMPL(name) \ - static PyObject *pybind11_init_wrapper(); \ - extern "C" PYBIND11_EXPORT void init##name() { \ - (void)pybind11_init_wrapper(); \ - } \ - PyObject *pybind11_init_wrapper() -#endif - -#if PY_VERSION_HEX >= 0x03050000 && PY_VERSION_HEX < 0x03050200 -extern "C" { - struct _Py_atomic_address { void *value; }; - PyAPI_DATA(_Py_atomic_address) _PyThreadState_Current; -} -#endif - -#define PYBIND11_TRY_NEXT_OVERLOAD ((PyObject *) 1) // special failure return code -#define PYBIND11_STRINGIFY(x) #x -#define PYBIND11_TOSTRING(x) PYBIND11_STRINGIFY(x) -#define PYBIND11_CONCAT(first, second) first##second - -/** \rst - ***Deprecated in favor of PYBIND11_MODULE*** - - This macro creates the entry point that will be invoked when the Python interpreter - imports a plugin library. Please create a `module` in the function body and return - the pointer to its underlying Python object at the end. - - .. code-block:: cpp - - PYBIND11_PLUGIN(example) { - pybind11::module m("example", "pybind11 example plugin"); - /// Set up bindings here - return m.ptr(); - } -\endrst */ -#define PYBIND11_PLUGIN(name) \ - PYBIND11_DEPRECATED("PYBIND11_PLUGIN is deprecated, use PYBIND11_MODULE") \ - static PyObject *pybind11_init(); \ - PYBIND11_PLUGIN_IMPL(name) { \ - int major, minor; \ - if (sscanf(Py_GetVersion(), "%i.%i", &major, &minor) != 2) { \ - PyErr_SetString(PyExc_ImportError, "Can't parse Python version."); \ - return nullptr; \ - } else if (major != PY_MAJOR_VERSION || minor != PY_MINOR_VERSION) { \ - PyErr_Format(PyExc_ImportError, \ - "Python version mismatch: module was compiled for " \ - "version %i.%i, while the interpreter is running " \ - "version %i.%i.", PY_MAJOR_VERSION, PY_MINOR_VERSION, \ - major, minor); \ - return nullptr; \ - } \ - try { \ - return pybind11_init(); \ - } catch (pybind11::error_already_set &e) { \ - PyErr_SetString(PyExc_ImportError, e.what()); \ - return nullptr; \ - } catch (const std::exception &e) { \ - PyErr_SetString(PyExc_ImportError, e.what()); \ - return nullptr; \ - } \ - } \ - PyObject *pybind11_init() - -/** \rst - This macro creates the entry point that will be invoked when the Python interpreter - imports an extension module. The module name is given as the fist argument and it - should not be in quotes. The second macro argument defines a variable of type - `py::module` which can be used to initialize the module. - - .. code-block:: cpp - - PYBIND11_MODULE(example, m) { - m.doc() = "pybind11 example module"; - - // Add bindings here - m.def("foo", []() { - return "Hello, World!"; - }); - } -\endrst */ -#define PYBIND11_MODULE(name, variable) \ - static void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &); \ - PYBIND11_PLUGIN_IMPL(name) { \ - int major, minor; \ - if (sscanf(Py_GetVersion(), "%i.%i", &major, &minor) != 2) { \ - PyErr_SetString(PyExc_ImportError, "Can't parse Python version."); \ - return nullptr; \ - } else if (major != PY_MAJOR_VERSION || minor != PY_MINOR_VERSION) { \ - PyErr_Format(PyExc_ImportError, \ - "Python version mismatch: module was compiled for " \ - "version %i.%i, while the interpreter is running " \ - "version %i.%i.", PY_MAJOR_VERSION, PY_MINOR_VERSION, \ - major, minor); \ - return nullptr; \ - } \ - auto m = pybind11::module(PYBIND11_TOSTRING(name)); \ - try { \ - PYBIND11_CONCAT(pybind11_init_, name)(m); \ - return m.ptr(); \ - } catch (pybind11::error_already_set &e) { \ - PyErr_SetString(PyExc_ImportError, e.what()); \ - return nullptr; \ - } catch (const std::exception &e) { \ - PyErr_SetString(PyExc_ImportError, e.what()); \ - return nullptr; \ - } \ - } \ - void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &variable) - - -NAMESPACE_BEGIN(PYBIND11_NAMESPACE) - -using ssize_t = Py_ssize_t; -using size_t = std::size_t; - -/// Approach used to cast a previously unknown C++ instance into a Python object -enum class return_value_policy : uint8_t { - /** This is the default return value policy, which falls back to the policy - return_value_policy::take_ownership when the return value is a pointer. - Otherwise, it uses return_value::move or return_value::copy for rvalue - and lvalue references, respectively. See below for a description of what - all of these different policies do. */ - automatic = 0, - - /** As above, but use policy return_value_policy::reference when the return - value is a pointer. This is the default conversion policy for function - arguments when calling Python functions manually from C++ code (i.e. via - handle::operator()). You probably won't need to use this. */ - automatic_reference, - - /** Reference an existing object (i.e. do not create a new copy) and take - ownership. Python will call the destructor and delete operator when the - object’s reference count reaches zero. Undefined behavior ensues when - the C++ side does the same.. */ - take_ownership, - - /** Create a new copy of the returned object, which will be owned by - Python. This policy is comparably safe because the lifetimes of the two - instances are decoupled. */ - copy, - - /** Use std::move to move the return value contents into a new instance - that will be owned by Python. This policy is comparably safe because the - lifetimes of the two instances (move source and destination) are - decoupled. */ - move, - - /** Reference an existing object, but do not take ownership. The C++ side - is responsible for managing the object’s lifetime and deallocating it - when it is no longer used. Warning: undefined behavior will ensue when - the C++ side deletes an object that is still referenced and used by - Python. */ - reference, - - /** This policy only applies to methods and properties. It references the - object without taking ownership similar to the above - return_value_policy::reference policy. In contrast to that policy, the - function or property’s implicit this argument (called the parent) is - considered to be the the owner of the return value (the child). - pybind11 then couples the lifetime of the parent to the child via a - reference relationship that ensures that the parent cannot be garbage - collected while Python is still using the child. More advanced - variations of this scheme are also possible using combinations of - return_value_policy::reference and the keep_alive call policy */ - reference_internal -}; - -NAMESPACE_BEGIN(detail) - -inline static constexpr int log2(size_t n, int k = 0) { return (n <= 1) ? k : log2(n >> 1, k + 1); } - -// Returns the size as a multiple of sizeof(void *), rounded up. -inline static constexpr size_t size_in_ptrs(size_t s) { return 1 + ((s - 1) >> log2(sizeof(void *))); } - -/** - * The space to allocate for simple layout instance holders (see below) in multiple of the size of - * a pointer (e.g. 2 means 16 bytes on 64-bit architectures). The default is the minimum required - * to holder either a std::unique_ptr or std::shared_ptr (which is almost always - * sizeof(std::shared_ptr)). - */ -constexpr size_t instance_simple_holder_in_ptrs() { - static_assert(sizeof(std::shared_ptr) >= sizeof(std::unique_ptr), - "pybind assumes std::shared_ptrs are at least as big as std::unique_ptrs"); - return size_in_ptrs(sizeof(std::shared_ptr)); -} - -// Forward declarations -struct type_info; -struct value_and_holder; - -/// The 'instance' type which needs to be standard layout (need to be able to use 'offsetof') -struct instance { - PyObject_HEAD - /// Storage for pointers and holder; see simple_layout, below, for a description - union { - void *simple_value_holder[1 + instance_simple_holder_in_ptrs()]; - struct { - void **values_and_holders; - uint8_t *status; - } nonsimple; - }; - /// Weak references - PyObject *weakrefs; - /// If true, the pointer is owned which means we're free to manage it with a holder. - bool owned : 1; - /** - * An instance has two possible value/holder layouts. - * - * Simple layout (when this flag is true), means the `simple_value_holder` is set with a pointer - * and the holder object governing that pointer, i.e. [val1*][holder]. This layout is applied - * whenever there is no python-side multiple inheritance of bound C++ types *and* the type's - * holder will fit in the default space (which is large enough to hold either a std::unique_ptr - * or std::shared_ptr). - * - * Non-simple layout applies when using custom holders that require more space than `shared_ptr` - * (which is typically the size of two pointers), or when multiple inheritance is used on the - * python side. Non-simple layout allocates the required amount of memory to have multiple - * bound C++ classes as parents. Under this layout, `nonsimple.values_and_holders` is set to a - * pointer to allocated space of the required space to hold a sequence of value pointers and - * holders followed `status`, a set of bit flags (1 byte each), i.e. - * [val1*][holder1][val2*][holder2]...[bb...] where each [block] is rounded up to a multiple of - * `sizeof(void *)`. `nonsimple.status` is, for convenience, a pointer to the - * beginning of the [bb...] block (but not independently allocated). - * - * Status bits indicate whether the associated holder is constructed (& - * status_holder_constructed) and whether the value pointer is registered (& - * status_instance_registered) in `registered_instances`. - */ - bool simple_layout : 1; - /// For simple layout, tracks whether the holder has been constructed - bool simple_holder_constructed : 1; - /// For simple layout, tracks whether the instance is registered in `registered_instances` - bool simple_instance_registered : 1; - /// If true, get_internals().patients has an entry for this object - bool has_patients : 1; - - /// Initializes all of the above type/values/holders data (but not the instance values themselves) - void allocate_layout(); - - /// Destroys/deallocates all of the above - void deallocate_layout(); - - /// Returns the value_and_holder wrapper for the given type (or the first, if `find_type` - /// omitted). Returns a default-constructed (with `.inst = nullptr`) object on failure if - /// `throw_if_missing` is false. - value_and_holder get_value_and_holder(const type_info *find_type = nullptr, bool throw_if_missing = true); - - /// Bit values for the non-simple status flags - static constexpr uint8_t status_holder_constructed = 1; - static constexpr uint8_t status_instance_registered = 2; -}; - -static_assert(std::is_standard_layout::value, "Internal error: `pybind11::detail::instance` is not standard layout!"); - -/// from __cpp_future__ import (convenient aliases from C++14/17) -#if defined(PYBIND11_CPP14) && (!defined(_MSC_VER) || _MSC_VER >= 1910) -using std::enable_if_t; -using std::conditional_t; -using std::remove_cv_t; -using std::remove_reference_t; -#else -template using enable_if_t = typename std::enable_if::type; -template using conditional_t = typename std::conditional::type; -template using remove_cv_t = typename std::remove_cv::type; -template using remove_reference_t = typename std::remove_reference::type; -#endif - -/// Index sequences -#if defined(PYBIND11_CPP14) -using std::index_sequence; -using std::make_index_sequence; -#else -template struct index_sequence { }; -template struct make_index_sequence_impl : make_index_sequence_impl { }; -template struct make_index_sequence_impl <0, S...> { typedef index_sequence type; }; -template using make_index_sequence = typename make_index_sequence_impl::type; -#endif - -/// Make an index sequence of the indices of true arguments -template struct select_indices_impl { using type = ISeq; }; -template struct select_indices_impl, I, B, Bs...> - : select_indices_impl, index_sequence>, I + 1, Bs...> {}; -template using select_indices = typename select_indices_impl, 0, Bs...>::type; - -/// Backports of std::bool_constant and std::negation to accommodate older compilers -template using bool_constant = std::integral_constant; -template struct negation : bool_constant { }; - -template struct void_t_impl { using type = void; }; -template using void_t = typename void_t_impl::type; - -/// Compile-time all/any/none of that check the boolean value of all template types -#ifdef __cpp_fold_expressions -template using all_of = bool_constant<(Ts::value && ...)>; -template using any_of = bool_constant<(Ts::value || ...)>; -#elif !defined(_MSC_VER) -template struct bools {}; -template using all_of = std::is_same< - bools, - bools>; -template using any_of = negation...>>; -#else -// MSVC has trouble with the above, but supports std::conjunction, which we can use instead (albeit -// at a slight loss of compilation efficiency). -template using all_of = std::conjunction; -template using any_of = std::disjunction; -#endif -template using none_of = negation>; - -template class... Predicates> using satisfies_all_of = all_of...>; -template class... Predicates> using satisfies_any_of = any_of...>; -template class... Predicates> using satisfies_none_of = none_of...>; - -/// Strip the class from a method type -template struct remove_class { }; -template struct remove_class { typedef R type(A...); }; -template struct remove_class { typedef R type(A...); }; - -/// Helper template to strip away type modifiers -template struct intrinsic_type { typedef T type; }; -template struct intrinsic_type { typedef typename intrinsic_type::type type; }; -template struct intrinsic_type { typedef typename intrinsic_type::type type; }; -template struct intrinsic_type { typedef typename intrinsic_type::type type; }; -template struct intrinsic_type { typedef typename intrinsic_type::type type; }; -template struct intrinsic_type { typedef typename intrinsic_type::type type; }; -template struct intrinsic_type { typedef typename intrinsic_type::type type; }; -template using intrinsic_t = typename intrinsic_type::type; - -/// Helper type to replace 'void' in some expressions -struct void_type { }; - -/// Helper template which holds a list of types -template struct type_list { }; - -/// Compile-time integer sum -#ifdef __cpp_fold_expressions -template constexpr size_t constexpr_sum(Ts... ns) { return (0 + ... + size_t{ns}); } -#else -constexpr size_t constexpr_sum() { return 0; } -template -constexpr size_t constexpr_sum(T n, Ts... ns) { return size_t{n} + constexpr_sum(ns...); } -#endif - -NAMESPACE_BEGIN(constexpr_impl) -/// Implementation details for constexpr functions -constexpr int first(int i) { return i; } -template -constexpr int first(int i, T v, Ts... vs) { return v ? i : first(i + 1, vs...); } - -constexpr int last(int /*i*/, int result) { return result; } -template -constexpr int last(int i, int result, T v, Ts... vs) { return last(i + 1, v ? i : result, vs...); } -NAMESPACE_END(constexpr_impl) - -/// Return the index of the first type in Ts which satisfies Predicate. Returns sizeof...(Ts) if -/// none match. -template class Predicate, typename... Ts> -constexpr int constexpr_first() { return constexpr_impl::first(0, Predicate::value...); } - -/// Return the index of the last type in Ts which satisfies Predicate, or -1 if none match. -template class Predicate, typename... Ts> -constexpr int constexpr_last() { return constexpr_impl::last(0, -1, Predicate::value...); } - -/// Return the Nth element from the parameter pack -template -struct pack_element { using type = typename pack_element::type; }; -template -struct pack_element<0, T, Ts...> { using type = T; }; - -/// Return the one and only type which matches the predicate, or Default if none match. -/// If more than one type matches the predicate, fail at compile-time. -template class Predicate, typename Default, typename... Ts> -struct exactly_one { - static constexpr auto found = constexpr_sum(Predicate::value...); - static_assert(found <= 1, "Found more than one type matching the predicate"); - - static constexpr auto index = found ? constexpr_first() : 0; - using type = conditional_t::type, Default>; -}; -template class P, typename Default> -struct exactly_one { using type = Default; }; - -template class Predicate, typename Default, typename... Ts> -using exactly_one_t = typename exactly_one::type; - -/// Defer the evaluation of type T until types Us are instantiated -template struct deferred_type { using type = T; }; -template using deferred_t = typename deferred_type::type; - -/// Like is_base_of, but requires a strict base (i.e. `is_strict_base_of::value == false`, -/// unlike `std::is_base_of`) -template using is_strict_base_of = bool_constant< - std::is_base_of::value && !std::is_same::value>; - -/// Like is_base_of, but also requires that the base type is accessible (i.e. that a Derived pointer -/// can be converted to a Base pointer) -template using is_accessible_base_of = bool_constant< - std::is_base_of::value && std::is_convertible::value>; - -template class Base> -struct is_template_base_of_impl { - template static std::true_type check(Base *); - static std::false_type check(...); -}; - -/// Check if a template is the base of a type. For example: -/// `is_template_base_of` is true if `struct T : Base {}` where U can be anything -template class Base, typename T> -#if !defined(_MSC_VER) -using is_template_base_of = decltype(is_template_base_of_impl::check((intrinsic_t*)nullptr)); -#else // MSVC2015 has trouble with decltype in template aliases -struct is_template_base_of : decltype(is_template_base_of_impl::check((intrinsic_t*)nullptr)) { }; -#endif - -/// Check if T is an instantiation of the template `Class`. For example: -/// `is_instantiation` is true if `T == shared_ptr` where U can be anything. -template class Class, typename T> -struct is_instantiation : std::false_type { }; -template class Class, typename... Us> -struct is_instantiation> : std::true_type { }; - -/// Check if T is std::shared_ptr where U can be anything -template using is_shared_ptr = is_instantiation; - -/// Check if T looks like an input iterator -template struct is_input_iterator : std::false_type {}; -template -struct is_input_iterator()), decltype(++std::declval())>> - : std::true_type {}; - -template using is_function_pointer = bool_constant< - std::is_pointer::value && std::is_function::type>::value>; - -template struct strip_function_object { - using type = typename remove_class::type; -}; - -// Extracts the function signature from a function, function pointer or lambda. -template > -using function_signature_t = conditional_t< - std::is_function::value, - F, - typename conditional_t< - std::is_pointer::value || std::is_member_pointer::value, - std::remove_pointer, - strip_function_object - >::type ->; - -/// Returns true if the type looks like a lambda: that is, isn't a function, pointer or member -/// pointer. Note that this can catch all sorts of other things, too; this is intended to be used -/// in a place where passing a lambda makes sense. -template using is_lambda = satisfies_none_of, - std::is_function, std::is_pointer, std::is_member_pointer>; - -/// Ignore that a variable is unused in compiler warnings -inline void ignore_unused(const int *) { } - -/// Apply a function over each element of a parameter pack -#ifdef __cpp_fold_expressions -#define PYBIND11_EXPAND_SIDE_EFFECTS(PATTERN) (((PATTERN), void()), ...) -#else -using expand_side_effects = bool[]; -#define PYBIND11_EXPAND_SIDE_EFFECTS(PATTERN) pybind11::detail::expand_side_effects{ ((PATTERN), void(), false)..., false } -#endif - -NAMESPACE_END(detail) - -/// C++ bindings of builtin Python exceptions -class builtin_exception : public std::runtime_error { -public: - using std::runtime_error::runtime_error; - /// Set the error using the Python C API - virtual void set_error() const = 0; -}; - -#define PYBIND11_RUNTIME_EXCEPTION(name, type) \ - class name : public builtin_exception { public: \ - using builtin_exception::builtin_exception; \ - name() : name("") { } \ - void set_error() const override { PyErr_SetString(type, what()); } \ - }; - -PYBIND11_RUNTIME_EXCEPTION(stop_iteration, PyExc_StopIteration) -PYBIND11_RUNTIME_EXCEPTION(index_error, PyExc_IndexError) -PYBIND11_RUNTIME_EXCEPTION(key_error, PyExc_KeyError) -PYBIND11_RUNTIME_EXCEPTION(value_error, PyExc_ValueError) -PYBIND11_RUNTIME_EXCEPTION(type_error, PyExc_TypeError) -PYBIND11_RUNTIME_EXCEPTION(cast_error, PyExc_RuntimeError) /// Thrown when pybind11::cast or handle::call fail due to a type casting error -PYBIND11_RUNTIME_EXCEPTION(reference_cast_error, PyExc_RuntimeError) /// Used internally - -[[noreturn]] PYBIND11_NOINLINE inline void pybind11_fail(const char *reason) { throw std::runtime_error(reason); } -[[noreturn]] PYBIND11_NOINLINE inline void pybind11_fail(const std::string &reason) { throw std::runtime_error(reason); } - -template struct format_descriptor { }; - -NAMESPACE_BEGIN(detail) -// Returns the index of the given type in the type char array below, and in the list in numpy.h -// The order here is: bool; 8 ints ((signed,unsigned)x(8,16,32,64)bits); float,double,long double; -// complex float,double,long double. Note that the long double types only participate when long -// double is actually longer than double (it isn't under MSVC). -// NB: not only the string below but also complex.h and numpy.h rely on this order. -template struct is_fmt_numeric { static constexpr bool value = false; }; -template struct is_fmt_numeric::value>> { - static constexpr bool value = true; - static constexpr int index = std::is_same::value ? 0 : 1 + ( - std::is_integral::value ? detail::log2(sizeof(T))*2 + std::is_unsigned::value : 8 + ( - std::is_same::value ? 1 : std::is_same::value ? 2 : 0)); -}; -NAMESPACE_END(detail) - -template struct format_descriptor::value>> { - static constexpr const char c = "?bBhHiIqQfdg"[detail::is_fmt_numeric::index]; - static constexpr const char value[2] = { c, '\0' }; - static std::string format() { return std::string(1, c); } -}; - -#if !defined(PYBIND11_CPP17) - -template constexpr const char format_descriptor< - T, detail::enable_if_t::value>>::value[2]; - -#endif - -/// RAII wrapper that temporarily clears any Python error state -struct error_scope { - PyObject *type, *value, *trace; - error_scope() { PyErr_Fetch(&type, &value, &trace); } - ~error_scope() { PyErr_Restore(type, value, trace); } -}; - -/// Dummy destructor wrapper that can be used to expose classes with a private destructor -struct nodelete { template void operator()(T*) { } }; - -// overload_cast requires variable templates: C++14 -#if defined(PYBIND11_CPP14) -#define PYBIND11_OVERLOAD_CAST 1 - -NAMESPACE_BEGIN(detail) -template -struct overload_cast_impl { - constexpr overload_cast_impl() {} // MSVC 2015 needs this - - template - constexpr auto operator()(Return (*pf)(Args...)) const noexcept - -> decltype(pf) { return pf; } - - template - constexpr auto operator()(Return (Class::*pmf)(Args...), std::false_type = {}) const noexcept - -> decltype(pmf) { return pmf; } - - template - constexpr auto operator()(Return (Class::*pmf)(Args...) const, std::true_type) const noexcept - -> decltype(pmf) { return pmf; } -}; -NAMESPACE_END(detail) - -/// Syntax sugar for resolving overloaded function pointers: -/// - regular: static_cast(&Class::func) -/// - sweet: overload_cast(&Class::func) -template -static constexpr detail::overload_cast_impl overload_cast = {}; -// MSVC 2015 only accepts this particular initialization syntax for this variable template. - -/// Const member function selector for overload_cast -/// - regular: static_cast(&Class::func) -/// - sweet: overload_cast(&Class::func, const_) -static constexpr auto const_ = std::true_type{}; - -#else // no overload_cast: providing something that static_assert-fails: -template struct overload_cast { - static_assert(detail::deferred_t::value, - "pybind11::overload_cast<...> requires compiling in C++14 mode"); -}; -#endif // overload_cast - -NAMESPACE_BEGIN(detail) - -// Adaptor for converting arbitrary container arguments into a vector; implicitly convertible from -// any standard container (or C-style array) supporting std::begin/std::end, any singleton -// arithmetic type (if T is arithmetic), or explicitly constructible from an iterator pair. -template -class any_container { - std::vector v; -public: - any_container() = default; - - // Can construct from a pair of iterators - template ::value>> - any_container(It first, It last) : v(first, last) { } - - // Implicit conversion constructor from any arbitrary container type with values convertible to T - template ())), T>::value>> - any_container(const Container &c) : any_container(std::begin(c), std::end(c)) { } - - // initializer_list's aren't deducible, so don't get matched by the above template; we need this - // to explicitly allow implicit conversion from one: - template ::value>> - any_container(const std::initializer_list &c) : any_container(c.begin(), c.end()) { } - - // Avoid copying if given an rvalue vector of the correct type. - any_container(std::vector &&v) : v(std::move(v)) { } - - // Moves the vector out of an rvalue any_container - operator std::vector &&() && { return std::move(v); } - - // Dereferencing obtains a reference to the underlying vector - std::vector &operator*() { return v; } - const std::vector &operator*() const { return v; } - - // -> lets you call methods on the underlying vector - std::vector *operator->() { return &v; } - const std::vector *operator->() const { return &v; } -}; - -NAMESPACE_END(detail) - - - -NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/VFRendering/thirdparty/pybind11/include/pybind11/detail/descr.h b/VFRendering/thirdparty/pybind11/include/pybind11/detail/descr.h deleted file mode 100644 index 8d404e534..000000000 --- a/VFRendering/thirdparty/pybind11/include/pybind11/detail/descr.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - pybind11/detail/descr.h: Helper type for concatenating type signatures at compile time - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "common.h" - -NAMESPACE_BEGIN(PYBIND11_NAMESPACE) -NAMESPACE_BEGIN(detail) - -#if !defined(_MSC_VER) -# define PYBIND11_DESCR_CONSTEXPR static constexpr -#else -# define PYBIND11_DESCR_CONSTEXPR const -#endif - -/* Concatenate type signatures at compile time */ -template -struct descr { - char text[N + 1]; - - constexpr descr() : text{'\0'} { } - constexpr descr(char const (&s)[N+1]) : descr(s, make_index_sequence()) { } - - template - constexpr descr(char const (&s)[N+1], index_sequence) : text{s[Is]..., '\0'} { } - - template - constexpr descr(char c, Chars... cs) : text{c, static_cast(cs)..., '\0'} { } - - static constexpr std::array types() { - return {{&typeid(Ts)..., nullptr}}; - } -}; - -template -constexpr descr plus_impl(const descr &a, const descr &b, - index_sequence, index_sequence) { - return {a.text[Is1]..., b.text[Is2]...}; -} - -template -constexpr descr operator+(const descr &a, const descr &b) { - return plus_impl(a, b, make_index_sequence(), make_index_sequence()); -} - -template -constexpr descr _(char const(&text)[N]) { return descr(text); } -constexpr descr<0> _(char const(&)[1]) { return {}; } - -template struct int_to_str : int_to_str { }; -template struct int_to_str<0, Digits...> { - static constexpr auto digits = descr(('0' + Digits)...); -}; - -// Ternary description (like std::conditional) -template -constexpr enable_if_t> _(char const(&text1)[N1], char const(&)[N2]) { - return _(text1); -} -template -constexpr enable_if_t> _(char const(&)[N1], char const(&text2)[N2]) { - return _(text2); -} - -template -constexpr enable_if_t _(const T1 &d, const T2 &) { return d; } -template -constexpr enable_if_t _(const T1 &, const T2 &d) { return d; } - -template auto constexpr _() -> decltype(int_to_str::digits) { - return int_to_str::digits; -} - -template constexpr descr<1, Type> _() { return {'%'}; } - -constexpr descr<0> concat() { return {}; } - -template -constexpr descr concat(const descr &descr) { return descr; } - -template -constexpr auto concat(const descr &d, const Args &...args) - -> decltype(std::declval>() + concat(args...)) { - return d + _(", ") + concat(args...); -} - -template -constexpr descr type_descr(const descr &descr) { - return _("{") + descr + _("}"); -} - -NAMESPACE_END(detail) -NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/VFRendering/thirdparty/pybind11/include/pybind11/detail/init.h b/VFRendering/thirdparty/pybind11/include/pybind11/detail/init.h deleted file mode 100644 index 3238256ce..000000000 --- a/VFRendering/thirdparty/pybind11/include/pybind11/detail/init.h +++ /dev/null @@ -1,325 +0,0 @@ -/* - pybind11/detail/init.h: init factory function implementation and support code. - - Copyright (c) 2017 Jason Rhinelander - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "class.h" - -NAMESPACE_BEGIN(PYBIND11_NAMESPACE) -NAMESPACE_BEGIN(detail) - -template <> -class type_caster { -public: - bool load(handle h, bool) { - value = reinterpret_cast(h.ptr()); - return true; - } - - template using cast_op_type = value_and_holder &; - operator value_and_holder &() { return *value; } - static constexpr auto name = _(); - -private: - value_and_holder *value = nullptr; -}; - -NAMESPACE_BEGIN(initimpl) - -inline void no_nullptr(void *ptr) { - if (!ptr) throw type_error("pybind11::init(): factory function returned nullptr"); -} - -// Implementing functions for all forms of py::init<...> and py::init(...) -template using Cpp = typename Class::type; -template using Alias = typename Class::type_alias; -template using Holder = typename Class::holder_type; - -template using is_alias_constructible = std::is_constructible, Cpp &&>; - -// Takes a Cpp pointer and returns true if it actually is a polymorphic Alias instance. -template = 0> -bool is_alias(Cpp *ptr) { - return dynamic_cast *>(ptr) != nullptr; -} -// Failing fallback version of the above for a no-alias class (always returns false) -template -constexpr bool is_alias(void *) { return false; } - -// Attempts to constructs an alias using a `Alias(Cpp &&)` constructor. This allows types with -// an alias to provide only a single Cpp factory function as long as the Alias can be -// constructed from an rvalue reference of the base Cpp type. This means that Alias classes -// can, when appropriate, simply define a `Alias(Cpp &&)` constructor rather than needing to -// inherit all the base class constructors. -template -void construct_alias_from_cpp(std::true_type /*is_alias_constructible*/, - value_and_holder &v_h, Cpp &&base) { - v_h.value_ptr() = new Alias(std::move(base)); -} -template -[[noreturn]] void construct_alias_from_cpp(std::false_type /*!is_alias_constructible*/, - value_and_holder &, Cpp &&) { - throw type_error("pybind11::init(): unable to convert returned instance to required " - "alias class: no `Alias(Class &&)` constructor available"); -} - -// Error-generating fallback for factories that don't match one of the below construction -// mechanisms. -template -void construct(...) { - static_assert(!std::is_same::value /* always false */, - "pybind11::init(): init function must return a compatible pointer, " - "holder, or value"); -} - -// Pointer return v1: the factory function returns a class pointer for a registered class. -// If we don't need an alias (because this class doesn't have one, or because the final type is -// inherited on the Python side) we can simply take over ownership. Otherwise we need to try to -// construct an Alias from the returned base instance. -template -void construct(value_and_holder &v_h, Cpp *ptr, bool need_alias) { - no_nullptr(ptr); - if (Class::has_alias && need_alias && !is_alias(ptr)) { - // We're going to try to construct an alias by moving the cpp type. Whether or not - // that succeeds, we still need to destroy the original cpp pointer (either the - // moved away leftover, if the alias construction works, or the value itself if we - // throw an error), but we can't just call `delete ptr`: it might have a special - // deleter, or might be shared_from_this. So we construct a holder around it as if - // it was a normal instance, then steal the holder away into a local variable; thus - // the holder and destruction happens when we leave the C++ scope, and the holder - // class gets to handle the destruction however it likes. - v_h.value_ptr() = ptr; - v_h.set_instance_registered(true); // To prevent init_instance from registering it - v_h.type->init_instance(v_h.inst, nullptr); // Set up the holder - Holder temp_holder(std::move(v_h.holder>())); // Steal the holder - v_h.type->dealloc(v_h); // Destroys the moved-out holder remains, resets value ptr to null - v_h.set_instance_registered(false); - - construct_alias_from_cpp(is_alias_constructible{}, v_h, std::move(*ptr)); - } else { - // Otherwise the type isn't inherited, so we don't need an Alias - v_h.value_ptr() = ptr; - } -} - -// Pointer return v2: a factory that always returns an alias instance ptr. We simply take over -// ownership of the pointer. -template = 0> -void construct(value_and_holder &v_h, Alias *alias_ptr, bool) { - no_nullptr(alias_ptr); - v_h.value_ptr() = static_cast *>(alias_ptr); -} - -// Holder return: copy its pointer, and move or copy the returned holder into the new instance's -// holder. This also handles types like std::shared_ptr and std::unique_ptr where T is a -// derived type (through those holder's implicit conversion from derived class holder constructors). -template -void construct(value_and_holder &v_h, Holder holder, bool need_alias) { - auto *ptr = holder_helper>::get(holder); - // If we need an alias, check that the held pointer is actually an alias instance - if (Class::has_alias && need_alias && !is_alias(ptr)) - throw type_error("pybind11::init(): construction failed: returned holder-wrapped instance " - "is not an alias instance"); - - v_h.value_ptr() = ptr; - v_h.type->init_instance(v_h.inst, &holder); -} - -// return-by-value version 1: returning a cpp class by value. If the class has an alias and an -// alias is required the alias must have an `Alias(Cpp &&)` constructor so that we can construct -// the alias from the base when needed (i.e. because of Python-side inheritance). When we don't -// need it, we simply move-construct the cpp value into a new instance. -template -void construct(value_and_holder &v_h, Cpp &&result, bool need_alias) { - static_assert(std::is_move_constructible>::value, - "pybind11::init() return-by-value factory function requires a movable class"); - if (Class::has_alias && need_alias) - construct_alias_from_cpp(is_alias_constructible{}, v_h, std::move(result)); - else - v_h.value_ptr() = new Cpp(std::move(result)); -} - -// return-by-value version 2: returning a value of the alias type itself. We move-construct an -// Alias instance (even if no the python-side inheritance is involved). The is intended for -// cases where Alias initialization is always desired. -template -void construct(value_and_holder &v_h, Alias &&result, bool) { - static_assert(std::is_move_constructible>::value, - "pybind11::init() return-by-alias-value factory function requires a movable alias class"); - v_h.value_ptr() = new Alias(std::move(result)); -} - -// Implementing class for py::init<...>() -template -struct constructor { - template = 0> - static void execute(Class &cl, const Extra&... extra) { - cl.def("__init__", [](value_and_holder &v_h, Args... args) { - v_h.value_ptr() = new Cpp{std::forward(args)...}; - }, is_new_style_constructor(), extra...); - } - - template , Args...>::value, int> = 0> - static void execute(Class &cl, const Extra&... extra) { - cl.def("__init__", [](value_and_holder &v_h, Args... args) { - if (Py_TYPE(v_h.inst) == v_h.type->type) - v_h.value_ptr() = new Cpp{std::forward(args)...}; - else - v_h.value_ptr() = new Alias{std::forward(args)...}; - }, is_new_style_constructor(), extra...); - } - - template , Args...>::value, int> = 0> - static void execute(Class &cl, const Extra&... extra) { - cl.def("__init__", [](value_and_holder &v_h, Args... args) { - v_h.value_ptr() = new Alias{std::forward(args)...}; - }, is_new_style_constructor(), extra...); - } -}; - -// Implementing class for py::init_alias<...>() -template struct alias_constructor { - template , Args...>::value, int> = 0> - static void execute(Class &cl, const Extra&... extra) { - cl.def("__init__", [](value_and_holder &v_h, Args... args) { - v_h.value_ptr() = new Alias{std::forward(args)...}; - }, is_new_style_constructor(), extra...); - } -}; - -// Implementation class for py::init(Func) and py::init(Func, AliasFunc) -template , typename = function_signature_t> -struct factory; - -// Specialization for py::init(Func) -template -struct factory { - remove_reference_t class_factory; - - factory(Func &&f) : class_factory(std::forward(f)) { } - - // The given class either has no alias or has no separate alias factory; - // this always constructs the class itself. If the class is registered with an alias - // type and an alias instance is needed (i.e. because the final type is a Python class - // inheriting from the C++ type) the returned value needs to either already be an alias - // instance, or the alias needs to be constructible from a `Class &&` argument. - template - void execute(Class &cl, const Extra &...extra) && { - #if defined(PYBIND11_CPP14) - cl.def("__init__", [func = std::move(class_factory)] - #else - auto &func = class_factory; - cl.def("__init__", [func] - #endif - (value_and_holder &v_h, Args... args) { - construct(v_h, func(std::forward(args)...), - Py_TYPE(v_h.inst) != v_h.type->type); - }, is_new_style_constructor(), extra...); - } -}; - -// Specialization for py::init(Func, AliasFunc) -template -struct factory { - static_assert(sizeof...(CArgs) == sizeof...(AArgs), - "pybind11::init(class_factory, alias_factory): class and alias factories " - "must have identical argument signatures"); - static_assert(all_of...>::value, - "pybind11::init(class_factory, alias_factory): class and alias factories " - "must have identical argument signatures"); - - remove_reference_t class_factory; - remove_reference_t alias_factory; - - factory(CFunc &&c, AFunc &&a) - : class_factory(std::forward(c)), alias_factory(std::forward(a)) { } - - // The class factory is called when the `self` type passed to `__init__` is the direct - // class (i.e. not inherited), the alias factory when `self` is a Python-side subtype. - template - void execute(Class &cl, const Extra&... extra) && { - static_assert(Class::has_alias, "The two-argument version of `py::init()` can " - "only be used if the class has an alias"); - #if defined(PYBIND11_CPP14) - cl.def("__init__", [class_func = std::move(class_factory), alias_func = std::move(alias_factory)] - #else - auto &class_func = class_factory; - auto &alias_func = alias_factory; - cl.def("__init__", [class_func, alias_func] - #endif - (value_and_holder &v_h, CArgs... args) { - if (Py_TYPE(v_h.inst) == v_h.type->type) - // If the instance type equals the registered type we don't have inheritance, so - // don't need the alias and can construct using the class function: - construct(v_h, class_func(std::forward(args)...), false); - else - construct(v_h, alias_func(std::forward(args)...), true); - }, is_new_style_constructor(), extra...); - } -}; - -/// Set just the C++ state. Same as `__init__`. -template -void setstate(value_and_holder &v_h, T &&result, bool need_alias) { - construct(v_h, std::forward(result), need_alias); -} - -/// Set both the C++ and Python states -template ::value, int> = 0> -void setstate(value_and_holder &v_h, std::pair &&result, bool need_alias) { - construct(v_h, std::move(result.first), need_alias); - setattr((PyObject *) v_h.inst, "__dict__", result.second); -} - -/// Implementation for py::pickle(GetState, SetState) -template , typename = function_signature_t> -struct pickle_factory; - -template -struct pickle_factory { - static_assert(std::is_same, intrinsic_t>::value, - "The type returned by `__getstate__` must be the same " - "as the argument accepted by `__setstate__`"); - - remove_reference_t get; - remove_reference_t set; - - pickle_factory(Get get, Set set) - : get(std::forward(get)), set(std::forward(set)) { } - - template - void execute(Class &cl, const Extra &...extra) && { - cl.def("__getstate__", std::move(get)); - -#if defined(PYBIND11_CPP14) - cl.def("__setstate__", [func = std::move(set)] -#else - auto &func = set; - cl.def("__setstate__", [func] -#endif - (value_and_holder &v_h, ArgState state) { - setstate(v_h, func(std::forward(state)), - Py_TYPE(v_h.inst) != v_h.type->type); - }, is_new_style_constructor(), extra...); - } -}; - -NAMESPACE_END(initimpl) -NAMESPACE_END(detail) -NAMESPACE_END(pybind11) diff --git a/VFRendering/thirdparty/pybind11/include/pybind11/detail/internals.h b/VFRendering/thirdparty/pybind11/include/pybind11/detail/internals.h deleted file mode 100644 index 213cbaeb2..000000000 --- a/VFRendering/thirdparty/pybind11/include/pybind11/detail/internals.h +++ /dev/null @@ -1,247 +0,0 @@ -/* - pybind11/detail/internals.h: Internal data structure and related functions - - Copyright (c) 2017 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "../pytypes.h" - -NAMESPACE_BEGIN(PYBIND11_NAMESPACE) -NAMESPACE_BEGIN(detail) -// Forward declarations -inline PyTypeObject *make_static_property_type(); -inline PyTypeObject *make_default_metaclass(); -inline PyObject *make_object_base_type(PyTypeObject *metaclass); - -// Python loads modules by default with dlopen with the RTLD_LOCAL flag; under libc++ and possibly -// other STLs, this means `typeid(A)` from one module won't equal `typeid(A)` from another module -// even when `A` is the same, non-hidden-visibility type (e.g. from a common include). Under -// libstdc++, this doesn't happen: equality and the type_index hash are based on the type name, -// which works. If not under a known-good stl, provide our own name-based hash and equality -// functions that use the type name. -#if defined(__GLIBCXX__) -inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { return lhs == rhs; } -using type_hash = std::hash; -using type_equal_to = std::equal_to; -#else -inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { - return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0; -} - -struct type_hash { - size_t operator()(const std::type_index &t) const { - size_t hash = 5381; - const char *ptr = t.name(); - while (auto c = static_cast(*ptr++)) - hash = (hash * 33) ^ c; - return hash; - } -}; - -struct type_equal_to { - bool operator()(const std::type_index &lhs, const std::type_index &rhs) const { - return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0; - } -}; -#endif - -template -using type_map = std::unordered_map; - -struct overload_hash { - inline size_t operator()(const std::pair& v) const { - size_t value = std::hash()(v.first); - value ^= std::hash()(v.second) + 0x9e3779b9 + (value<<6) + (value>>2); - return value; - } -}; - -/// Internal data structure used to track registered instances and types. -/// Whenever binary incompatible changes are made to this structure, -/// `PYBIND11_INTERNALS_VERSION` must be incremented. -struct internals { - type_map registered_types_cpp; // std::type_index -> pybind11's type information - std::unordered_map> registered_types_py; // PyTypeObject* -> base type_info(s) - std::unordered_multimap registered_instances; // void * -> instance* - std::unordered_set, overload_hash> inactive_overload_cache; - type_map> direct_conversions; - std::unordered_map> patients; - std::forward_list registered_exception_translators; - std::unordered_map shared_data; // Custom data to be shared across extensions - std::vector loader_patient_stack; // Used by `loader_life_support` - std::forward_list static_strings; // Stores the std::strings backing detail::c_str() - PyTypeObject *static_property_type; - PyTypeObject *default_metaclass; - PyObject *instance_base; -#if defined(WITH_THREAD) - decltype(PyThread_create_key()) tstate = 0; // Usually an int but a long on Cygwin64 with Python 3.x - PyInterpreterState *istate = nullptr; -#endif -}; - -/// Additional type information which does not fit into the PyTypeObject. -/// Changes to this struct also require bumping `PYBIND11_INTERNALS_VERSION`. -struct type_info { - PyTypeObject *type; - const std::type_info *cpptype; - size_t type_size, holder_size_in_ptrs; - void *(*operator_new)(size_t); - void (*init_instance)(instance *, const void *); - void (*dealloc)(value_and_holder &v_h); - std::vector implicit_conversions; - std::vector> implicit_casts; - std::vector *direct_conversions; - buffer_info *(*get_buffer)(PyObject *, void *) = nullptr; - void *get_buffer_data = nullptr; - void *(*module_local_load)(PyObject *, const type_info *) = nullptr; - /* A simple type never occurs as a (direct or indirect) parent - * of a class that makes use of multiple inheritance */ - bool simple_type : 1; - /* True if there is no multiple inheritance in this type's inheritance tree */ - bool simple_ancestors : 1; - /* for base vs derived holder_type checks */ - bool default_holder : 1; - /* true if this is a type registered with py::module_local */ - bool module_local : 1; -}; - -/// Tracks the `internals` and `type_info` ABI version independent of the main library version -#define PYBIND11_INTERNALS_VERSION 1 - -#if defined(WITH_THREAD) -# define PYBIND11_INTERNALS_KIND "" -#else -# define PYBIND11_INTERNALS_KIND "_without_thread" -#endif - -#define PYBIND11_INTERNALS_ID "__pybind11_internals_v" \ - PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION) PYBIND11_INTERNALS_KIND "__" - -#define PYBIND11_MODULE_LOCAL_ID "__pybind11_module_local_v" \ - PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION) PYBIND11_INTERNALS_KIND "__" - -/// Each module locally stores a pointer to the `internals` data. The data -/// itself is shared among modules with the same `PYBIND11_INTERNALS_ID`. -inline internals *&get_internals_ptr() { - static internals *internals_ptr = nullptr; - return internals_ptr; -} - -/// Return a reference to the current `internals` data -PYBIND11_NOINLINE inline internals &get_internals() { - auto *&internals_ptr = get_internals_ptr(); - if (internals_ptr) - return *internals_ptr; - - constexpr auto *id = PYBIND11_INTERNALS_ID; - auto builtins = handle(PyEval_GetBuiltins()); - if (builtins.contains(id) && isinstance(builtins[id])) { - internals_ptr = *static_cast(capsule(builtins[id])); - - // We loaded builtins through python's builtins, which means that our `error_already_set` - // and `builtin_exception` may be different local classes than the ones set up in the - // initial exception translator, below, so add another for our local exception classes. - // - // libstdc++ doesn't require this (types there are identified only by name) -#if !defined(__GLIBCXX__) - internals_ptr->registered_exception_translators.push_front( - [](std::exception_ptr p) -> void { - try { - if (p) std::rethrow_exception(p); - } catch (error_already_set &e) { e.restore(); return; - } catch (const builtin_exception &e) { e.set_error(); return; - } - } - ); -#endif - } else { - internals_ptr = new internals(); -#if defined(WITH_THREAD) - PyEval_InitThreads(); - PyThreadState *tstate = PyThreadState_Get(); - internals_ptr->tstate = PyThread_create_key(); - PyThread_set_key_value(internals_ptr->tstate, tstate); - internals_ptr->istate = tstate->interp; -#endif - builtins[id] = capsule(&internals_ptr); - internals_ptr->registered_exception_translators.push_front( - [](std::exception_ptr p) -> void { - try { - if (p) std::rethrow_exception(p); - } catch (error_already_set &e) { e.restore(); return; - } catch (const builtin_exception &e) { e.set_error(); return; - } catch (const std::bad_alloc &e) { PyErr_SetString(PyExc_MemoryError, e.what()); return; - } catch (const std::domain_error &e) { PyErr_SetString(PyExc_ValueError, e.what()); return; - } catch (const std::invalid_argument &e) { PyErr_SetString(PyExc_ValueError, e.what()); return; - } catch (const std::length_error &e) { PyErr_SetString(PyExc_ValueError, e.what()); return; - } catch (const std::out_of_range &e) { PyErr_SetString(PyExc_IndexError, e.what()); return; - } catch (const std::range_error &e) { PyErr_SetString(PyExc_ValueError, e.what()); return; - } catch (const std::exception &e) { PyErr_SetString(PyExc_RuntimeError, e.what()); return; - } catch (...) { - PyErr_SetString(PyExc_RuntimeError, "Caught an unknown exception!"); - return; - } - } - ); - internals_ptr->static_property_type = make_static_property_type(); - internals_ptr->default_metaclass = make_default_metaclass(); - internals_ptr->instance_base = make_object_base_type(internals_ptr->default_metaclass); - } - return *internals_ptr; -} - -/// Works like `internals.registered_types_cpp`, but for module-local registered types: -inline type_map ®istered_local_types_cpp() { - static type_map locals{}; - return locals; -} - -/// Constructs a std::string with the given arguments, stores it in `internals`, and returns its -/// `c_str()`. Such strings objects have a long storage duration -- the internal strings are only -/// cleared when the program exits or after interpreter shutdown (when embedding), and so are -/// suitable for c-style strings needed by Python internals (such as PyTypeObject's tp_name). -template -const char *c_str(Args &&...args) { - auto &strings = get_internals().static_strings; - strings.emplace_front(std::forward(args)...); - return strings.front().c_str(); -} - -NAMESPACE_END(detail) - -/// Returns a named pointer that is shared among all extension modules (using the same -/// pybind11 version) running in the current interpreter. Names starting with underscores -/// are reserved for internal usage. Returns `nullptr` if no matching entry was found. -inline PYBIND11_NOINLINE void *get_shared_data(const std::string &name) { - auto &internals = detail::get_internals(); - auto it = internals.shared_data.find(name); - return it != internals.shared_data.end() ? it->second : nullptr; -} - -/// Set the shared data that can be later recovered by `get_shared_data()`. -inline PYBIND11_NOINLINE void *set_shared_data(const std::string &name, void *data) { - detail::get_internals().shared_data[name] = data; - return data; -} - -/// Returns a typed reference to a shared data entry (by using `get_shared_data()`) if -/// such entry exists. Otherwise, a new object of default-constructible type `T` is -/// added to the shared data under the given name and a reference to it is returned. -template -T &get_or_create_shared_data(const std::string &name) { - auto &internals = detail::get_internals(); - auto it = internals.shared_data.find(name); - T *ptr = (T *) (it != internals.shared_data.end() ? it->second : nullptr); - if (!ptr) { - ptr = new T(); - internals.shared_data[name] = ptr; - } - return *ptr; -} - -NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/VFRendering/thirdparty/pybind11/include/pybind11/detail/typeid.h b/VFRendering/thirdparty/pybind11/include/pybind11/detail/typeid.h deleted file mode 100644 index 6f36aab75..000000000 --- a/VFRendering/thirdparty/pybind11/include/pybind11/detail/typeid.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - pybind11/detail/typeid.h: Compiler-independent access to type identifiers - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include -#include - -#if defined(__GNUG__) -#include -#endif - -NAMESPACE_BEGIN(PYBIND11_NAMESPACE) -NAMESPACE_BEGIN(detail) -/// Erase all occurrences of a substring -inline void erase_all(std::string &string, const std::string &search) { - for (size_t pos = 0;;) { - pos = string.find(search, pos); - if (pos == std::string::npos) break; - string.erase(pos, search.length()); - } -} - -PYBIND11_NOINLINE inline void clean_type_id(std::string &name) { -#if defined(__GNUG__) - int status = 0; - std::unique_ptr res { - abi::__cxa_demangle(name.c_str(), nullptr, nullptr, &status), std::free }; - if (status == 0) - name = res.get(); -#else - detail::erase_all(name, "class "); - detail::erase_all(name, "struct "); - detail::erase_all(name, "enum "); -#endif - detail::erase_all(name, "pybind11::"); -} -NAMESPACE_END(detail) - -/// Return a string representation of a C++ type -template static std::string type_id() { - std::string name(typeid(T).name()); - detail::clean_type_id(name); - return name; -} - -NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/VFRendering/thirdparty/pybind11/include/pybind11/eigen.h b/VFRendering/thirdparty/pybind11/include/pybind11/eigen.h deleted file mode 100644 index 531d0706a..000000000 --- a/VFRendering/thirdparty/pybind11/include/pybind11/eigen.h +++ /dev/null @@ -1,615 +0,0 @@ -/* - pybind11/eigen.h: Transparent conversion for dense and sparse Eigen matrices - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "numpy.h" - -#if defined(__INTEL_COMPILER) -# pragma warning(disable: 1682) // implicit conversion of a 64-bit integral type to a smaller integral type (potential portability problem) -#elif defined(__GNUG__) || defined(__clang__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wconversion" -# pragma GCC diagnostic ignored "-Wdeprecated-declarations" -# ifdef __clang__ -// Eigen generates a bunch of implicit-copy-constructor-is-deprecated warnings with -Wdeprecated -// under Clang, so disable that warning here: -# pragma GCC diagnostic ignored "-Wdeprecated" -# endif -# if __GNUC__ >= 7 -# pragma GCC diagnostic ignored "-Wint-in-bool-context" -# endif -#endif - -#if defined(_MSC_VER) -# pragma warning(push) -# pragma warning(disable: 4127) // warning C4127: Conditional expression is constant -# pragma warning(disable: 4996) // warning C4996: std::unary_negate is deprecated in C++17 -#endif - -#include -#include - -// Eigen prior to 3.2.7 doesn't have proper move constructors--but worse, some classes get implicit -// move constructors that break things. We could detect this an explicitly copy, but an extra copy -// of matrices seems highly undesirable. -static_assert(EIGEN_VERSION_AT_LEAST(3,2,7), "Eigen support in pybind11 requires Eigen >= 3.2.7"); - -NAMESPACE_BEGIN(PYBIND11_NAMESPACE) - -// Provide a convenience alias for easier pass-by-ref usage with fully dynamic strides: -using EigenDStride = Eigen::Stride; -template using EigenDRef = Eigen::Ref; -template using EigenDMap = Eigen::Map; - -NAMESPACE_BEGIN(detail) - -#if EIGEN_VERSION_AT_LEAST(3,3,0) -using EigenIndex = Eigen::Index; -#else -using EigenIndex = EIGEN_DEFAULT_DENSE_INDEX_TYPE; -#endif - -// Matches Eigen::Map, Eigen::Ref, blocks, etc: -template using is_eigen_dense_map = all_of, std::is_base_of, T>>; -template using is_eigen_mutable_map = std::is_base_of, T>; -template using is_eigen_dense_plain = all_of>, is_template_base_of>; -template using is_eigen_sparse = is_template_base_of; -// Test for objects inheriting from EigenBase that aren't captured by the above. This -// basically covers anything that can be assigned to a dense matrix but that don't have a typical -// matrix data layout that can be copied from their .data(). For example, DiagonalMatrix and -// SelfAdjointView fall into this category. -template using is_eigen_other = all_of< - is_template_base_of, - negation, is_eigen_dense_plain, is_eigen_sparse>> ->; - -// Captures numpy/eigen conformability status (returned by EigenProps::conformable()): -template struct EigenConformable { - bool conformable = false; - EigenIndex rows = 0, cols = 0; - EigenDStride stride{0, 0}; // Only valid if negativestrides is false! - bool negativestrides = false; // If true, do not use stride! - - EigenConformable(bool fits = false) : conformable{fits} {} - // Matrix type: - EigenConformable(EigenIndex r, EigenIndex c, - EigenIndex rstride, EigenIndex cstride) : - conformable{true}, rows{r}, cols{c} { - // TODO: when Eigen bug #747 is fixed, remove the tests for non-negativity. http://eigen.tuxfamily.org/bz/show_bug.cgi?id=747 - if (rstride < 0 || cstride < 0) { - negativestrides = true; - } else { - stride = {EigenRowMajor ? rstride : cstride /* outer stride */, - EigenRowMajor ? cstride : rstride /* inner stride */ }; - } - } - // Vector type: - EigenConformable(EigenIndex r, EigenIndex c, EigenIndex stride) - : EigenConformable(r, c, r == 1 ? c*stride : stride, c == 1 ? r : r*stride) {} - - template bool stride_compatible() const { - // To have compatible strides, we need (on both dimensions) one of fully dynamic strides, - // matching strides, or a dimension size of 1 (in which case the stride value is irrelevant) - return - !negativestrides && - (props::inner_stride == Eigen::Dynamic || props::inner_stride == stride.inner() || - (EigenRowMajor ? cols : rows) == 1) && - (props::outer_stride == Eigen::Dynamic || props::outer_stride == stride.outer() || - (EigenRowMajor ? rows : cols) == 1); - } - operator bool() const { return conformable; } -}; - -template struct eigen_extract_stride { using type = Type; }; -template -struct eigen_extract_stride> { using type = StrideType; }; -template -struct eigen_extract_stride> { using type = StrideType; }; - -// Helper struct for extracting information from an Eigen type -template struct EigenProps { - using Type = Type_; - using Scalar = typename Type::Scalar; - using StrideType = typename eigen_extract_stride::type; - static constexpr EigenIndex - rows = Type::RowsAtCompileTime, - cols = Type::ColsAtCompileTime, - size = Type::SizeAtCompileTime; - static constexpr bool - row_major = Type::IsRowMajor, - vector = Type::IsVectorAtCompileTime, // At least one dimension has fixed size 1 - fixed_rows = rows != Eigen::Dynamic, - fixed_cols = cols != Eigen::Dynamic, - fixed = size != Eigen::Dynamic, // Fully-fixed size - dynamic = !fixed_rows && !fixed_cols; // Fully-dynamic size - - template using if_zero = std::integral_constant; - static constexpr EigenIndex inner_stride = if_zero::value, - outer_stride = if_zero::value; - static constexpr bool dynamic_stride = inner_stride == Eigen::Dynamic && outer_stride == Eigen::Dynamic; - static constexpr bool requires_row_major = !dynamic_stride && !vector && (row_major ? inner_stride : outer_stride) == 1; - static constexpr bool requires_col_major = !dynamic_stride && !vector && (row_major ? outer_stride : inner_stride) == 1; - - // Takes an input array and determines whether we can make it fit into the Eigen type. If - // the array is a vector, we attempt to fit it into either an Eigen 1xN or Nx1 vector - // (preferring the latter if it will fit in either, i.e. for a fully dynamic matrix type). - static EigenConformable conformable(const array &a) { - const auto dims = a.ndim(); - if (dims < 1 || dims > 2) - return false; - - if (dims == 2) { // Matrix type: require exact match (or dynamic) - - EigenIndex - np_rows = a.shape(0), - np_cols = a.shape(1), - np_rstride = a.strides(0) / static_cast(sizeof(Scalar)), - np_cstride = a.strides(1) / static_cast(sizeof(Scalar)); - if ((fixed_rows && np_rows != rows) || (fixed_cols && np_cols != cols)) - return false; - - return {np_rows, np_cols, np_rstride, np_cstride}; - } - - // Otherwise we're storing an n-vector. Only one of the strides will be used, but whichever - // is used, we want the (single) numpy stride value. - const EigenIndex n = a.shape(0), - stride = a.strides(0) / static_cast(sizeof(Scalar)); - - if (vector) { // Eigen type is a compile-time vector - if (fixed && size != n) - return false; // Vector size mismatch - return {rows == 1 ? 1 : n, cols == 1 ? 1 : n, stride}; - } - else if (fixed) { - // The type has a fixed size, but is not a vector: abort - return false; - } - else if (fixed_cols) { - // Since this isn't a vector, cols must be != 1. We allow this only if it exactly - // equals the number of elements (rows is Dynamic, and so 1 row is allowed). - if (cols != n) return false; - return {1, n, stride}; - } - else { - // Otherwise it's either fully dynamic, or column dynamic; both become a column vector - if (fixed_rows && rows != n) return false; - return {n, 1, stride}; - } - } - - static constexpr bool show_writeable = is_eigen_dense_map::value && is_eigen_mutable_map::value; - static constexpr bool show_order = is_eigen_dense_map::value; - static constexpr bool show_c_contiguous = show_order && requires_row_major; - static constexpr bool show_f_contiguous = !show_c_contiguous && show_order && requires_col_major; - - static constexpr auto descriptor = - _("numpy.ndarray[") + npy_format_descriptor::name + - _("[") + _(_<(size_t) rows>(), _("m")) + - _(", ") + _(_<(size_t) cols>(), _("n")) + - _("]") + - // For a reference type (e.g. Ref) we have other constraints that might need to be - // satisfied: writeable=True (for a mutable reference), and, depending on the map's stride - // options, possibly f_contiguous or c_contiguous. We include them in the descriptor output - // to provide some hint as to why a TypeError is occurring (otherwise it can be confusing to - // see that a function accepts a 'numpy.ndarray[float64[3,2]]' and an error message that you - // *gave* a numpy.ndarray of the right type and dimensions. - _(", flags.writeable", "") + - _(", flags.c_contiguous", "") + - _(", flags.f_contiguous", "") + - _("]"); -}; - -// Casts an Eigen type to numpy array. If given a base, the numpy array references the src data, -// otherwise it'll make a copy. writeable lets you turn off the writeable flag for the array. -template handle eigen_array_cast(typename props::Type const &src, handle base = handle(), bool writeable = true) { - constexpr ssize_t elem_size = sizeof(typename props::Scalar); - array a; - if (props::vector) - a = array({ src.size() }, { elem_size * src.innerStride() }, src.data(), base); - else - a = array({ src.rows(), src.cols() }, { elem_size * src.rowStride(), elem_size * src.colStride() }, - src.data(), base); - - if (!writeable) - array_proxy(a.ptr())->flags &= ~detail::npy_api::NPY_ARRAY_WRITEABLE_; - - return a.release(); -} - -// Takes an lvalue ref to some Eigen type and a (python) base object, creating a numpy array that -// reference the Eigen object's data with `base` as the python-registered base class (if omitted, -// the base will be set to None, and lifetime management is up to the caller). The numpy array is -// non-writeable if the given type is const. -template -handle eigen_ref_array(Type &src, handle parent = none()) { - // none here is to get past array's should-we-copy detection, which currently always - // copies when there is no base. Setting the base to None should be harmless. - return eigen_array_cast(src, parent, !std::is_const::value); -} - -// Takes a pointer to some dense, plain Eigen type, builds a capsule around it, then returns a numpy -// array that references the encapsulated data with a python-side reference to the capsule to tie -// its destruction to that of any dependent python objects. Const-ness is determined by whether or -// not the Type of the pointer given is const. -template ::value>> -handle eigen_encapsulate(Type *src) { - capsule base(src, [](void *o) { delete static_cast(o); }); - return eigen_ref_array(*src, base); -} - -// Type caster for regular, dense matrix types (e.g. MatrixXd), but not maps/refs/etc. of dense -// types. -template -struct type_caster::value>> { - using Scalar = typename Type::Scalar; - using props = EigenProps; - - bool load(handle src, bool convert) { - // If we're in no-convert mode, only load if given an array of the correct type - if (!convert && !isinstance>(src)) - return false; - - // Coerce into an array, but don't do type conversion yet; the copy below handles it. - auto buf = array::ensure(src); - - if (!buf) - return false; - - auto dims = buf.ndim(); - if (dims < 1 || dims > 2) - return false; - - auto fits = props::conformable(buf); - if (!fits) - return false; - - // Allocate the new type, then build a numpy reference into it - value = Type(fits.rows, fits.cols); - auto ref = reinterpret_steal(eigen_ref_array(value)); - if (dims == 1) ref = ref.squeeze(); - else if (ref.ndim() == 1) buf = buf.squeeze(); - - int result = detail::npy_api::get().PyArray_CopyInto_(ref.ptr(), buf.ptr()); - - if (result < 0) { // Copy failed! - PyErr_Clear(); - return false; - } - - return true; - } - -private: - - // Cast implementation - template - static handle cast_impl(CType *src, return_value_policy policy, handle parent) { - switch (policy) { - case return_value_policy::take_ownership: - case return_value_policy::automatic: - return eigen_encapsulate(src); - case return_value_policy::move: - return eigen_encapsulate(new CType(std::move(*src))); - case return_value_policy::copy: - return eigen_array_cast(*src); - case return_value_policy::reference: - case return_value_policy::automatic_reference: - return eigen_ref_array(*src); - case return_value_policy::reference_internal: - return eigen_ref_array(*src, parent); - default: - throw cast_error("unhandled return_value_policy: should not happen!"); - }; - } - -public: - - // Normal returned non-reference, non-const value: - static handle cast(Type &&src, return_value_policy /* policy */, handle parent) { - return cast_impl(&src, return_value_policy::move, parent); - } - // If you return a non-reference const, we mark the numpy array readonly: - static handle cast(const Type &&src, return_value_policy /* policy */, handle parent) { - return cast_impl(&src, return_value_policy::move, parent); - } - // lvalue reference return; default (automatic) becomes copy - static handle cast(Type &src, return_value_policy policy, handle parent) { - if (policy == return_value_policy::automatic || policy == return_value_policy::automatic_reference) - policy = return_value_policy::copy; - return cast_impl(&src, policy, parent); - } - // const lvalue reference return; default (automatic) becomes copy - static handle cast(const Type &src, return_value_policy policy, handle parent) { - if (policy == return_value_policy::automatic || policy == return_value_policy::automatic_reference) - policy = return_value_policy::copy; - return cast(&src, policy, parent); - } - // non-const pointer return - static handle cast(Type *src, return_value_policy policy, handle parent) { - return cast_impl(src, policy, parent); - } - // const pointer return - static handle cast(const Type *src, return_value_policy policy, handle parent) { - return cast_impl(src, policy, parent); - } - - static constexpr auto name = props::descriptor; - - operator Type*() { return &value; } - operator Type&() { return value; } - operator Type&&() && { return std::move(value); } - template using cast_op_type = movable_cast_op_type; - -private: - Type value; -}; - -// Eigen Ref/Map classes have slightly different policy requirements, meaning we don't want to force -// `move` when a Ref/Map rvalue is returned; we treat Ref<> sort of like a pointer (we care about -// the underlying data, not the outer shell). -template -struct return_value_policy_override::value>> { - static return_value_policy policy(return_value_policy p) { return p; } -}; - -// Base class for casting reference/map/block/etc. objects back to python. -template struct eigen_map_caster { -private: - using props = EigenProps; - -public: - - // Directly referencing a ref/map's data is a bit dangerous (whatever the map/ref points to has - // to stay around), but we'll allow it under the assumption that you know what you're doing (and - // have an appropriate keep_alive in place). We return a numpy array pointing directly at the - // ref's data (The numpy array ends up read-only if the ref was to a const matrix type.) Note - // that this means you need to ensure you don't destroy the object in some other way (e.g. with - // an appropriate keep_alive, or with a reference to a statically allocated matrix). - static handle cast(const MapType &src, return_value_policy policy, handle parent) { - switch (policy) { - case return_value_policy::copy: - return eigen_array_cast(src); - case return_value_policy::reference_internal: - return eigen_array_cast(src, parent, is_eigen_mutable_map::value); - case return_value_policy::reference: - case return_value_policy::automatic: - case return_value_policy::automatic_reference: - return eigen_array_cast(src, none(), is_eigen_mutable_map::value); - default: - // move, take_ownership don't make any sense for a ref/map: - pybind11_fail("Invalid return_value_policy for Eigen Map/Ref/Block type"); - } - } - - static constexpr auto name = props::descriptor; - - // Explicitly delete these: support python -> C++ conversion on these (i.e. these can be return - // types but not bound arguments). We still provide them (with an explicitly delete) so that - // you end up here if you try anyway. - bool load(handle, bool) = delete; - operator MapType() = delete; - template using cast_op_type = MapType; -}; - -// We can return any map-like object (but can only load Refs, specialized next): -template struct type_caster::value>> - : eigen_map_caster {}; - -// Loader for Ref<...> arguments. See the documentation for info on how to make this work without -// copying (it requires some extra effort in many cases). -template -struct type_caster< - Eigen::Ref, - enable_if_t>::value> -> : public eigen_map_caster> { -private: - using Type = Eigen::Ref; - using props = EigenProps; - using Scalar = typename props::Scalar; - using MapType = Eigen::Map; - using Array = array_t; - static constexpr bool need_writeable = is_eigen_mutable_map::value; - // Delay construction (these have no default constructor) - std::unique_ptr map; - std::unique_ptr ref; - // Our array. When possible, this is just a numpy array pointing to the source data, but - // sometimes we can't avoid copying (e.g. input is not a numpy array at all, has an incompatible - // layout, or is an array of a type that needs to be converted). Using a numpy temporary - // (rather than an Eigen temporary) saves an extra copy when we need both type conversion and - // storage order conversion. (Note that we refuse to use this temporary copy when loading an - // argument for a Ref with M non-const, i.e. a read-write reference). - Array copy_or_ref; -public: - bool load(handle src, bool convert) { - // First check whether what we have is already an array of the right type. If not, we can't - // avoid a copy (because the copy is also going to do type conversion). - bool need_copy = !isinstance(src); - - EigenConformable fits; - if (!need_copy) { - // We don't need a converting copy, but we also need to check whether the strides are - // compatible with the Ref's stride requirements - Array aref = reinterpret_borrow(src); - - if (aref && (!need_writeable || aref.writeable())) { - fits = props::conformable(aref); - if (!fits) return false; // Incompatible dimensions - if (!fits.template stride_compatible()) - need_copy = true; - else - copy_or_ref = std::move(aref); - } - else { - need_copy = true; - } - } - - if (need_copy) { - // We need to copy: If we need a mutable reference, or we're not supposed to convert - // (either because we're in the no-convert overload pass, or because we're explicitly - // instructed not to copy (via `py::arg().noconvert()`) we have to fail loading. - if (!convert || need_writeable) return false; - - Array copy = Array::ensure(src); - if (!copy) return false; - fits = props::conformable(copy); - if (!fits || !fits.template stride_compatible()) - return false; - copy_or_ref = std::move(copy); - loader_life_support::add_patient(copy_or_ref); - } - - ref.reset(); - map.reset(new MapType(data(copy_or_ref), fits.rows, fits.cols, make_stride(fits.stride.outer(), fits.stride.inner()))); - ref.reset(new Type(*map)); - - return true; - } - - operator Type*() { return ref.get(); } - operator Type&() { return *ref; } - template using cast_op_type = pybind11::detail::cast_op_type<_T>; - -private: - template ::value, int> = 0> - Scalar *data(Array &a) { return a.mutable_data(); } - - template ::value, int> = 0> - const Scalar *data(Array &a) { return a.data(); } - - // Attempt to figure out a constructor of `Stride` that will work. - // If both strides are fixed, use a default constructor: - template using stride_ctor_default = bool_constant< - S::InnerStrideAtCompileTime != Eigen::Dynamic && S::OuterStrideAtCompileTime != Eigen::Dynamic && - std::is_default_constructible::value>; - // Otherwise, if there is a two-index constructor, assume it is (outer,inner) like - // Eigen::Stride, and use it: - template using stride_ctor_dual = bool_constant< - !stride_ctor_default::value && std::is_constructible::value>; - // Otherwise, if there is a one-index constructor, and just one of the strides is dynamic, use - // it (passing whichever stride is dynamic). - template using stride_ctor_outer = bool_constant< - !any_of, stride_ctor_dual>::value && - S::OuterStrideAtCompileTime == Eigen::Dynamic && S::InnerStrideAtCompileTime != Eigen::Dynamic && - std::is_constructible::value>; - template using stride_ctor_inner = bool_constant< - !any_of, stride_ctor_dual>::value && - S::InnerStrideAtCompileTime == Eigen::Dynamic && S::OuterStrideAtCompileTime != Eigen::Dynamic && - std::is_constructible::value>; - - template ::value, int> = 0> - static S make_stride(EigenIndex, EigenIndex) { return S(); } - template ::value, int> = 0> - static S make_stride(EigenIndex outer, EigenIndex inner) { return S(outer, inner); } - template ::value, int> = 0> - static S make_stride(EigenIndex outer, EigenIndex) { return S(outer); } - template ::value, int> = 0> - static S make_stride(EigenIndex, EigenIndex inner) { return S(inner); } - -}; - -// type_caster for special matrix types (e.g. DiagonalMatrix), which are EigenBase, but not -// EigenDense (i.e. they don't have a data(), at least not with the usual matrix layout). -// load() is not supported, but we can cast them into the python domain by first copying to a -// regular Eigen::Matrix, then casting that. -template -struct type_caster::value>> { -protected: - using Matrix = Eigen::Matrix; - using props = EigenProps; -public: - static handle cast(const Type &src, return_value_policy /* policy */, handle /* parent */) { - handle h = eigen_encapsulate(new Matrix(src)); - return h; - } - static handle cast(const Type *src, return_value_policy policy, handle parent) { return cast(*src, policy, parent); } - - static constexpr auto name = props::descriptor; - - // Explicitly delete these: support python -> C++ conversion on these (i.e. these can be return - // types but not bound arguments). We still provide them (with an explicitly delete) so that - // you end up here if you try anyway. - bool load(handle, bool) = delete; - operator Type() = delete; - template using cast_op_type = Type; -}; - -template -struct type_caster::value>> { - typedef typename Type::Scalar Scalar; - typedef remove_reference_t().outerIndexPtr())> StorageIndex; - typedef typename Type::Index Index; - static constexpr bool rowMajor = Type::IsRowMajor; - - bool load(handle src, bool) { - if (!src) - return false; - - auto obj = reinterpret_borrow(src); - object sparse_module = module::import("scipy.sparse"); - object matrix_type = sparse_module.attr( - rowMajor ? "csr_matrix" : "csc_matrix"); - - if (!obj.get_type().is(matrix_type)) { - try { - obj = matrix_type(obj); - } catch (const error_already_set &) { - return false; - } - } - - auto values = array_t((object) obj.attr("data")); - auto innerIndices = array_t((object) obj.attr("indices")); - auto outerIndices = array_t((object) obj.attr("indptr")); - auto shape = pybind11::tuple((pybind11::object) obj.attr("shape")); - auto nnz = obj.attr("nnz").cast(); - - if (!values || !innerIndices || !outerIndices) - return false; - - value = Eigen::MappedSparseMatrix( - shape[0].cast(), shape[1].cast(), nnz, - outerIndices.mutable_data(), innerIndices.mutable_data(), values.mutable_data()); - - return true; - } - - static handle cast(const Type &src, return_value_policy /* policy */, handle /* parent */) { - const_cast(src).makeCompressed(); - - object matrix_type = module::import("scipy.sparse").attr( - rowMajor ? "csr_matrix" : "csc_matrix"); - - array data(src.nonZeros(), src.valuePtr()); - array outerIndices((rowMajor ? src.rows() : src.cols()) + 1, src.outerIndexPtr()); - array innerIndices(src.nonZeros(), src.innerIndexPtr()); - - return matrix_type( - std::make_tuple(data, innerIndices, outerIndices), - std::make_pair(src.rows(), src.cols()) - ).release(); - } - - PYBIND11_TYPE_CASTER(Type, _<(Type::IsRowMajor) != 0>("scipy.sparse.csr_matrix[", "scipy.sparse.csc_matrix[") - + npy_format_descriptor::name + _("]")); -}; - -NAMESPACE_END(detail) -NAMESPACE_END(PYBIND11_NAMESPACE) - -#if defined(__GNUG__) || defined(__clang__) -# pragma GCC diagnostic pop -#elif defined(_MSC_VER) -# pragma warning(pop) -#endif diff --git a/VFRendering/thirdparty/pybind11/include/pybind11/embed.h b/VFRendering/thirdparty/pybind11/include/pybind11/embed.h deleted file mode 100644 index 6664967c1..000000000 --- a/VFRendering/thirdparty/pybind11/include/pybind11/embed.h +++ /dev/null @@ -1,194 +0,0 @@ -/* - pybind11/embed.h: Support for embedding the interpreter - - Copyright (c) 2017 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "pybind11.h" -#include "eval.h" - -#if defined(PYPY_VERSION) -# error Embedding the interpreter is not supported with PyPy -#endif - -#if PY_MAJOR_VERSION >= 3 -# define PYBIND11_EMBEDDED_MODULE_IMPL(name) \ - extern "C" PyObject *pybind11_init_impl_##name() { \ - return pybind11_init_wrapper_##name(); \ - } -#else -# define PYBIND11_EMBEDDED_MODULE_IMPL(name) \ - extern "C" void pybind11_init_impl_##name() { \ - pybind11_init_wrapper_##name(); \ - } -#endif - -/** \rst - Add a new module to the table of builtins for the interpreter. Must be - defined in global scope. The first macro parameter is the name of the - module (without quotes). The second parameter is the variable which will - be used as the interface to add functions and classes to the module. - - .. code-block:: cpp - - PYBIND11_EMBEDDED_MODULE(example, m) { - // ... initialize functions and classes here - m.def("foo", []() { - return "Hello, World!"; - }); - } - \endrst */ -#define PYBIND11_EMBEDDED_MODULE(name, variable) \ - static void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &); \ - static PyObject PYBIND11_CONCAT(*pybind11_init_wrapper_, name)() { \ - auto m = pybind11::module(PYBIND11_TOSTRING(name)); \ - try { \ - PYBIND11_CONCAT(pybind11_init_, name)(m); \ - return m.ptr(); \ - } catch (pybind11::error_already_set &e) { \ - PyErr_SetString(PyExc_ImportError, e.what()); \ - return nullptr; \ - } catch (const std::exception &e) { \ - PyErr_SetString(PyExc_ImportError, e.what()); \ - return nullptr; \ - } \ - } \ - PYBIND11_EMBEDDED_MODULE_IMPL(name) \ - pybind11::detail::embedded_module name(PYBIND11_TOSTRING(name), \ - PYBIND11_CONCAT(pybind11_init_impl_, name)); \ - void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &variable) - - -NAMESPACE_BEGIN(PYBIND11_NAMESPACE) -NAMESPACE_BEGIN(detail) - -/// Python 2.7/3.x compatible version of `PyImport_AppendInittab` and error checks. -struct embedded_module { -#if PY_MAJOR_VERSION >= 3 - using init_t = PyObject *(*)(); -#else - using init_t = void (*)(); -#endif - embedded_module(const char *name, init_t init) { - if (Py_IsInitialized()) - pybind11_fail("Can't add new modules after the interpreter has been initialized"); - - auto result = PyImport_AppendInittab(name, init); - if (result == -1) - pybind11_fail("Insufficient memory to add a new module"); - } -}; - -NAMESPACE_END(detail) - -/** \rst - Initialize the Python interpreter. No other pybind11 or CPython API functions can be - called before this is done; with the exception of `PYBIND11_EMBEDDED_MODULE`. The - optional parameter can be used to skip the registration of signal handlers (see the - Python documentation for details). Calling this function again after the interpreter - has already been initialized is a fatal error. - \endrst */ -inline void initialize_interpreter(bool init_signal_handlers = true) { - if (Py_IsInitialized()) - pybind11_fail("The interpreter is already running"); - - Py_InitializeEx(init_signal_handlers ? 1 : 0); - - // Make .py files in the working directory available by default - module::import("sys").attr("path").cast().append("."); -} - -/** \rst - Shut down the Python interpreter. No pybind11 or CPython API functions can be called - after this. In addition, pybind11 objects must not outlive the interpreter: - - .. code-block:: cpp - - { // BAD - py::initialize_interpreter(); - auto hello = py::str("Hello, World!"); - py::finalize_interpreter(); - } // <-- BOOM, hello's destructor is called after interpreter shutdown - - { // GOOD - py::initialize_interpreter(); - { // scoped - auto hello = py::str("Hello, World!"); - } // <-- OK, hello is cleaned up properly - py::finalize_interpreter(); - } - - { // BETTER - py::scoped_interpreter guard{}; - auto hello = py::str("Hello, World!"); - } - - .. warning:: - - The interpreter can be restarted by calling `initialize_interpreter` again. - Modules created using pybind11 can be safely re-initialized. However, Python - itself cannot completely unload binary extension modules and there are several - caveats with regard to interpreter restarting. All the details can be found - in the CPython documentation. In short, not all interpreter memory may be - freed, either due to reference cycles or user-created global data. - - \endrst */ -inline void finalize_interpreter() { - handle builtins(PyEval_GetBuiltins()); - const char *id = PYBIND11_INTERNALS_ID; - - // Get the internals pointer (without creating it if it doesn't exist). It's possible for the - // internals to be created during Py_Finalize() (e.g. if a py::capsule calls `get_internals()` - // during destruction), so we get the pointer-pointer here and check it after Py_Finalize(). - detail::internals **internals_ptr_ptr = &detail::get_internals_ptr(); - // It could also be stashed in builtins, so look there too: - if (builtins.contains(id) && isinstance(builtins[id])) - internals_ptr_ptr = capsule(builtins[id]); - - Py_Finalize(); - - if (internals_ptr_ptr) { - delete *internals_ptr_ptr; - *internals_ptr_ptr = nullptr; - } -} - -/** \rst - Scope guard version of `initialize_interpreter` and `finalize_interpreter`. - This a move-only guard and only a single instance can exist. - - .. code-block:: cpp - - #include - - int main() { - py::scoped_interpreter guard{}; - py::print(Hello, World!); - } // <-- interpreter shutdown - \endrst */ -class scoped_interpreter { -public: - scoped_interpreter(bool init_signal_handlers = true) { - initialize_interpreter(init_signal_handlers); - } - - scoped_interpreter(const scoped_interpreter &) = delete; - scoped_interpreter(scoped_interpreter &&other) noexcept { other.is_valid = false; } - scoped_interpreter &operator=(const scoped_interpreter &) = delete; - scoped_interpreter &operator=(scoped_interpreter &&) = delete; - - ~scoped_interpreter() { - if (is_valid) - finalize_interpreter(); - } - -private: - bool is_valid = true; -}; - -NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/VFRendering/thirdparty/pybind11/include/pybind11/eval.h b/VFRendering/thirdparty/pybind11/include/pybind11/eval.h deleted file mode 100644 index ea85ba1db..000000000 --- a/VFRendering/thirdparty/pybind11/include/pybind11/eval.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - pybind11/exec.h: Support for evaluating Python expressions and statements - from strings and files - - Copyright (c) 2016 Klemens Morgenstern and - Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "pybind11.h" - -NAMESPACE_BEGIN(PYBIND11_NAMESPACE) - -enum eval_mode { - /// Evaluate a string containing an isolated expression - eval_expr, - - /// Evaluate a string containing a single statement. Returns \c none - eval_single_statement, - - /// Evaluate a string containing a sequence of statement. Returns \c none - eval_statements -}; - -template -object eval(str expr, object global = globals(), object local = object()) { - if (!local) - local = global; - - /* PyRun_String does not accept a PyObject / encoding specifier, - this seems to be the only alternative */ - std::string buffer = "# -*- coding: utf-8 -*-\n" + (std::string) expr; - - int start; - switch (mode) { - case eval_expr: start = Py_eval_input; break; - case eval_single_statement: start = Py_single_input; break; - case eval_statements: start = Py_file_input; break; - default: pybind11_fail("invalid evaluation mode"); - } - - PyObject *result = PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr()); - if (!result) - throw error_already_set(); - return reinterpret_steal(result); -} - -template -object eval(const char (&s)[N], object global = globals(), object local = object()) { - /* Support raw string literals by removing common leading whitespace */ - auto expr = (s[0] == '\n') ? str(module::import("textwrap").attr("dedent")(s)) - : str(s); - return eval(expr, global, local); -} - -inline void exec(str expr, object global = globals(), object local = object()) { - eval(expr, global, local); -} - -template -void exec(const char (&s)[N], object global = globals(), object local = object()) { - eval(s, global, local); -} - -template -object eval_file(str fname, object global = globals(), object local = object()) { - if (!local) - local = global; - - int start; - switch (mode) { - case eval_expr: start = Py_eval_input; break; - case eval_single_statement: start = Py_single_input; break; - case eval_statements: start = Py_file_input; break; - default: pybind11_fail("invalid evaluation mode"); - } - - int closeFile = 1; - std::string fname_str = (std::string) fname; -#if PY_VERSION_HEX >= 0x03040000 - FILE *f = _Py_fopen_obj(fname.ptr(), "r"); -#elif PY_VERSION_HEX >= 0x03000000 - FILE *f = _Py_fopen(fname.ptr(), "r"); -#else - /* No unicode support in open() :( */ - auto fobj = reinterpret_steal(PyFile_FromString( - const_cast(fname_str.c_str()), - const_cast("r"))); - FILE *f = nullptr; - if (fobj) - f = PyFile_AsFile(fobj.ptr()); - closeFile = 0; -#endif - if (!f) { - PyErr_Clear(); - pybind11_fail("File \"" + fname_str + "\" could not be opened!"); - } - -#if PY_VERSION_HEX < 0x03000000 && defined(PYPY_VERSION) - PyObject *result = PyRun_File(f, fname_str.c_str(), start, global.ptr(), - local.ptr()); - (void) closeFile; -#else - PyObject *result = PyRun_FileEx(f, fname_str.c_str(), start, global.ptr(), - local.ptr(), closeFile); -#endif - - if (!result) - throw error_already_set(); - return reinterpret_steal(result); -} - -NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/VFRendering/thirdparty/pybind11/include/pybind11/functional.h b/VFRendering/thirdparty/pybind11/include/pybind11/functional.h deleted file mode 100644 index 9cdf21f7a..000000000 --- a/VFRendering/thirdparty/pybind11/include/pybind11/functional.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - pybind11/functional.h: std::function<> support - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "pybind11.h" -#include - -NAMESPACE_BEGIN(PYBIND11_NAMESPACE) -NAMESPACE_BEGIN(detail) - -template -struct type_caster> { - using type = std::function; - using retval_type = conditional_t::value, void_type, Return>; - using function_type = Return (*) (Args...); - -public: - bool load(handle src, bool convert) { - if (src.is_none()) { - // Defer accepting None to other overloads (if we aren't in convert mode): - if (!convert) return false; - return true; - } - - if (!isinstance(src)) - return false; - - auto func = reinterpret_borrow(src); - - /* - When passing a C++ function as an argument to another C++ - function via Python, every function call would normally involve - a full C++ -> Python -> C++ roundtrip, which can be prohibitive. - Here, we try to at least detect the case where the function is - stateless (i.e. function pointer or lambda function without - captured variables), in which case the roundtrip can be avoided. - */ - if (auto cfunc = func.cpp_function()) { - auto c = reinterpret_borrow(PyCFunction_GET_SELF(cfunc.ptr())); - auto rec = (function_record *) c; - - if (rec && rec->is_stateless && - same_type(typeid(function_type), *reinterpret_cast(rec->data[1]))) { - struct capture { function_type f; }; - value = ((capture *) &rec->data)->f; - return true; - } - } - - value = [func](Args... args) -> Return { - gil_scoped_acquire acq; - object retval(func(std::forward(args)...)); - /* Visual studio 2015 parser issue: need parentheses around this expression */ - return (retval.template cast()); - }; - return true; - } - - template - static handle cast(Func &&f_, return_value_policy policy, handle /* parent */) { - if (!f_) - return none().inc_ref(); - - auto result = f_.template target(); - if (result) - return cpp_function(*result, policy).release(); - else - return cpp_function(std::forward(f_), policy).release(); - } - - PYBIND11_TYPE_CASTER(type, _("Callable[[") + concat(make_caster::name...) + _("], ") - + make_caster::name + _("]")); -}; - -NAMESPACE_END(detail) -NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/VFRendering/thirdparty/pybind11/include/pybind11/iostream.h b/VFRendering/thirdparty/pybind11/include/pybind11/iostream.h deleted file mode 100644 index a9c27aac1..000000000 --- a/VFRendering/thirdparty/pybind11/include/pybind11/iostream.h +++ /dev/null @@ -1,200 +0,0 @@ -/* - pybind11/iostream.h -- Tools to assist with redirecting cout and cerr to Python - - Copyright (c) 2017 Henry F. Schreiner - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "pybind11.h" - -#include -#include -#include -#include -#include - -NAMESPACE_BEGIN(PYBIND11_NAMESPACE) -NAMESPACE_BEGIN(detail) - -// Buffer that writes to Python instead of C++ -class pythonbuf : public std::streambuf { -private: - using traits_type = std::streambuf::traits_type; - - char d_buffer[1024]; - object pywrite; - object pyflush; - - int overflow(int c) { - if (!traits_type::eq_int_type(c, traits_type::eof())) { - *pptr() = traits_type::to_char_type(c); - pbump(1); - } - return sync() ? traits_type::not_eof(c) : traits_type::eof(); - } - - int sync() { - if (pbase() != pptr()) { - // This subtraction cannot be negative, so dropping the sign - str line(pbase(), static_cast(pptr() - pbase())); - - pywrite(line); - pyflush(); - - setp(pbase(), epptr()); - } - return 0; - } - -public: - pythonbuf(object pyostream) - : pywrite(pyostream.attr("write")), - pyflush(pyostream.attr("flush")) { - setp(d_buffer, d_buffer + sizeof(d_buffer) - 1); - } - - /// Sync before destroy - ~pythonbuf() { - sync(); - } -}; - -NAMESPACE_END(detail) - - -/** \rst - This a move-only guard that redirects output. - - .. code-block:: cpp - - #include - - ... - - { - py::scoped_ostream_redirect output; - std::cout << "Hello, World!"; // Python stdout - } // <-- return std::cout to normal - - You can explicitly pass the c++ stream and the python object, - for example to guard stderr instead. - - .. code-block:: cpp - - { - py::scoped_ostream_redirect output{std::cerr, py::module::import("sys").attr("stderr")}; - std::cerr << "Hello, World!"; - } - \endrst */ -class scoped_ostream_redirect { -protected: - std::streambuf *old; - std::ostream &costream; - detail::pythonbuf buffer; - -public: - scoped_ostream_redirect( - std::ostream &costream = std::cout, - object pyostream = module::import("sys").attr("stdout")) - : costream(costream), buffer(pyostream) { - old = costream.rdbuf(&buffer); - } - - ~scoped_ostream_redirect() { - costream.rdbuf(old); - } - - scoped_ostream_redirect(const scoped_ostream_redirect &) = delete; - scoped_ostream_redirect(scoped_ostream_redirect &&other) = default; - scoped_ostream_redirect &operator=(const scoped_ostream_redirect &) = delete; - scoped_ostream_redirect &operator=(scoped_ostream_redirect &&) = delete; -}; - - -/** \rst - Like `scoped_ostream_redirect`, but redirects cerr by default. This class - is provided primary to make ``py::call_guard`` easier to make. - - .. code-block:: cpp - - m.def("noisy_func", &noisy_func, - py::call_guard()); - -\endrst */ -class scoped_estream_redirect : public scoped_ostream_redirect { -public: - scoped_estream_redirect( - std::ostream &costream = std::cerr, - object pyostream = module::import("sys").attr("stderr")) - : scoped_ostream_redirect(costream,pyostream) {} -}; - - -NAMESPACE_BEGIN(detail) - -// Class to redirect output as a context manager. C++ backend. -class OstreamRedirect { - bool do_stdout_; - bool do_stderr_; - std::unique_ptr redirect_stdout; - std::unique_ptr redirect_stderr; - -public: - OstreamRedirect(bool do_stdout = true, bool do_stderr = true) - : do_stdout_(do_stdout), do_stderr_(do_stderr) {} - - void enter() { - if (do_stdout_) - redirect_stdout.reset(new scoped_ostream_redirect()); - if (do_stderr_) - redirect_stderr.reset(new scoped_estream_redirect()); - } - - void exit() { - redirect_stdout.reset(); - redirect_stderr.reset(); - } -}; - -NAMESPACE_END(detail) - -/** \rst - This is a helper function to add a C++ redirect context manager to Python - instead of using a C++ guard. To use it, add the following to your binding code: - - .. code-block:: cpp - - #include - - ... - - py::add_ostream_redirect(m, "ostream_redirect"); - - You now have a Python context manager that redirects your output: - - .. code-block:: python - - with m.ostream_redirect(): - m.print_to_cout_function() - - This manager can optionally be told which streams to operate on: - - .. code-block:: python - - with m.ostream_redirect(stdout=true, stderr=true): - m.noisy_function_with_error_printing() - - \endrst */ -inline class_ add_ostream_redirect(module m, std::string name = "ostream_redirect") { - return class_(m, name.c_str(), module_local()) - .def(init(), arg("stdout")=true, arg("stderr")=true) - .def("__enter__", &detail::OstreamRedirect::enter) - .def("__exit__", [](detail::OstreamRedirect &self, args) { self.exit(); }); -} - -NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/VFRendering/thirdparty/pybind11/include/pybind11/numpy.h b/VFRendering/thirdparty/pybind11/include/pybind11/numpy.h deleted file mode 100644 index f64084e8f..000000000 --- a/VFRendering/thirdparty/pybind11/include/pybind11/numpy.h +++ /dev/null @@ -1,1606 +0,0 @@ -/* - pybind11/numpy.h: Basic NumPy support, vectorize() wrapper - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "pybind11.h" -#include "complex.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(_MSC_VER) -# pragma warning(push) -# pragma warning(disable: 4127) // warning C4127: Conditional expression is constant -#endif - -/* This will be true on all flat address space platforms and allows us to reduce the - whole npy_intp / ssize_t / Py_intptr_t business down to just ssize_t for all size - and dimension types (e.g. shape, strides, indexing), instead of inflicting this - upon the library user. */ -static_assert(sizeof(ssize_t) == sizeof(Py_intptr_t), "ssize_t != Py_intptr_t"); - -NAMESPACE_BEGIN(PYBIND11_NAMESPACE) - -class array; // Forward declaration - -NAMESPACE_BEGIN(detail) -template struct npy_format_descriptor; - -struct PyArrayDescr_Proxy { - PyObject_HEAD - PyObject *typeobj; - char kind; - char type; - char byteorder; - char flags; - int type_num; - int elsize; - int alignment; - char *subarray; - PyObject *fields; - PyObject *names; -}; - -struct PyArray_Proxy { - PyObject_HEAD - char *data; - int nd; - ssize_t *dimensions; - ssize_t *strides; - PyObject *base; - PyObject *descr; - int flags; -}; - -struct PyVoidScalarObject_Proxy { - PyObject_VAR_HEAD - char *obval; - PyArrayDescr_Proxy *descr; - int flags; - PyObject *base; -}; - -struct numpy_type_info { - PyObject* dtype_ptr; - std::string format_str; -}; - -struct numpy_internals { - std::unordered_map registered_dtypes; - - numpy_type_info *get_type_info(const std::type_info& tinfo, bool throw_if_missing = true) { - auto it = registered_dtypes.find(std::type_index(tinfo)); - if (it != registered_dtypes.end()) - return &(it->second); - if (throw_if_missing) - pybind11_fail(std::string("NumPy type info missing for ") + tinfo.name()); - return nullptr; - } - - template numpy_type_info *get_type_info(bool throw_if_missing = true) { - return get_type_info(typeid(typename std::remove_cv::type), throw_if_missing); - } -}; - -inline PYBIND11_NOINLINE void load_numpy_internals(numpy_internals* &ptr) { - ptr = &get_or_create_shared_data("_numpy_internals"); -} - -inline numpy_internals& get_numpy_internals() { - static numpy_internals* ptr = nullptr; - if (!ptr) - load_numpy_internals(ptr); - return *ptr; -} - -struct npy_api { - enum constants { - NPY_ARRAY_C_CONTIGUOUS_ = 0x0001, - NPY_ARRAY_F_CONTIGUOUS_ = 0x0002, - NPY_ARRAY_OWNDATA_ = 0x0004, - NPY_ARRAY_FORCECAST_ = 0x0010, - NPY_ARRAY_ENSUREARRAY_ = 0x0040, - NPY_ARRAY_ALIGNED_ = 0x0100, - NPY_ARRAY_WRITEABLE_ = 0x0400, - NPY_BOOL_ = 0, - NPY_BYTE_, NPY_UBYTE_, - NPY_SHORT_, NPY_USHORT_, - NPY_INT_, NPY_UINT_, - NPY_LONG_, NPY_ULONG_, - NPY_LONGLONG_, NPY_ULONGLONG_, - NPY_FLOAT_, NPY_DOUBLE_, NPY_LONGDOUBLE_, - NPY_CFLOAT_, NPY_CDOUBLE_, NPY_CLONGDOUBLE_, - NPY_OBJECT_ = 17, - NPY_STRING_, NPY_UNICODE_, NPY_VOID_ - }; - - typedef struct { - Py_intptr_t *ptr; - int len; - } PyArray_Dims; - - static npy_api& get() { - static npy_api api = lookup(); - return api; - } - - bool PyArray_Check_(PyObject *obj) const { - return (bool) PyObject_TypeCheck(obj, PyArray_Type_); - } - bool PyArrayDescr_Check_(PyObject *obj) const { - return (bool) PyObject_TypeCheck(obj, PyArrayDescr_Type_); - } - - unsigned int (*PyArray_GetNDArrayCFeatureVersion_)(); - PyObject *(*PyArray_DescrFromType_)(int); - PyObject *(*PyArray_NewFromDescr_) - (PyTypeObject *, PyObject *, int, Py_intptr_t *, - Py_intptr_t *, void *, int, PyObject *); - PyObject *(*PyArray_DescrNewFromType_)(int); - int (*PyArray_CopyInto_)(PyObject *, PyObject *); - PyObject *(*PyArray_NewCopy_)(PyObject *, int); - PyTypeObject *PyArray_Type_; - PyTypeObject *PyVoidArrType_Type_; - PyTypeObject *PyArrayDescr_Type_; - PyObject *(*PyArray_DescrFromScalar_)(PyObject *); - PyObject *(*PyArray_FromAny_) (PyObject *, PyObject *, int, int, int, PyObject *); - int (*PyArray_DescrConverter_) (PyObject *, PyObject **); - bool (*PyArray_EquivTypes_) (PyObject *, PyObject *); - int (*PyArray_GetArrayParamsFromObject_)(PyObject *, PyObject *, char, PyObject **, int *, - Py_ssize_t *, PyObject **, PyObject *); - PyObject *(*PyArray_Squeeze_)(PyObject *); - int (*PyArray_SetBaseObject_)(PyObject *, PyObject *); - PyObject* (*PyArray_Resize_)(PyObject*, PyArray_Dims*, int, int); -private: - enum functions { - API_PyArray_GetNDArrayCFeatureVersion = 211, - API_PyArray_Type = 2, - API_PyArrayDescr_Type = 3, - API_PyVoidArrType_Type = 39, - API_PyArray_DescrFromType = 45, - API_PyArray_DescrFromScalar = 57, - API_PyArray_FromAny = 69, - API_PyArray_Resize = 80, - API_PyArray_CopyInto = 82, - API_PyArray_NewCopy = 85, - API_PyArray_NewFromDescr = 94, - API_PyArray_DescrNewFromType = 9, - API_PyArray_DescrConverter = 174, - API_PyArray_EquivTypes = 182, - API_PyArray_GetArrayParamsFromObject = 278, - API_PyArray_Squeeze = 136, - API_PyArray_SetBaseObject = 282 - }; - - static npy_api lookup() { - module m = module::import("numpy.core.multiarray"); - auto c = m.attr("_ARRAY_API"); -#if PY_MAJOR_VERSION >= 3 - void **api_ptr = (void **) PyCapsule_GetPointer(c.ptr(), NULL); -#else - void **api_ptr = (void **) PyCObject_AsVoidPtr(c.ptr()); -#endif - npy_api api; -#define DECL_NPY_API(Func) api.Func##_ = (decltype(api.Func##_)) api_ptr[API_##Func]; - DECL_NPY_API(PyArray_GetNDArrayCFeatureVersion); - if (api.PyArray_GetNDArrayCFeatureVersion_() < 0x7) - pybind11_fail("pybind11 numpy support requires numpy >= 1.7.0"); - DECL_NPY_API(PyArray_Type); - DECL_NPY_API(PyVoidArrType_Type); - DECL_NPY_API(PyArrayDescr_Type); - DECL_NPY_API(PyArray_DescrFromType); - DECL_NPY_API(PyArray_DescrFromScalar); - DECL_NPY_API(PyArray_FromAny); - DECL_NPY_API(PyArray_Resize); - DECL_NPY_API(PyArray_CopyInto); - DECL_NPY_API(PyArray_NewCopy); - DECL_NPY_API(PyArray_NewFromDescr); - DECL_NPY_API(PyArray_DescrNewFromType); - DECL_NPY_API(PyArray_DescrConverter); - DECL_NPY_API(PyArray_EquivTypes); - DECL_NPY_API(PyArray_GetArrayParamsFromObject); - DECL_NPY_API(PyArray_Squeeze); - DECL_NPY_API(PyArray_SetBaseObject); -#undef DECL_NPY_API - return api; - } -}; - -inline PyArray_Proxy* array_proxy(void* ptr) { - return reinterpret_cast(ptr); -} - -inline const PyArray_Proxy* array_proxy(const void* ptr) { - return reinterpret_cast(ptr); -} - -inline PyArrayDescr_Proxy* array_descriptor_proxy(PyObject* ptr) { - return reinterpret_cast(ptr); -} - -inline const PyArrayDescr_Proxy* array_descriptor_proxy(const PyObject* ptr) { - return reinterpret_cast(ptr); -} - -inline bool check_flags(const void* ptr, int flag) { - return (flag == (array_proxy(ptr)->flags & flag)); -} - -template struct is_std_array : std::false_type { }; -template struct is_std_array> : std::true_type { }; -template struct is_complex : std::false_type { }; -template struct is_complex> : std::true_type { }; - -template struct array_info_scalar { - typedef T type; - static constexpr bool is_array = false; - static constexpr bool is_empty = false; - static constexpr auto extents = _(""); - static void append_extents(list& /* shape */) { } -}; -// Computes underlying type and a comma-separated list of extents for array -// types (any mix of std::array and built-in arrays). An array of char is -// treated as scalar because it gets special handling. -template struct array_info : array_info_scalar { }; -template struct array_info> { - using type = typename array_info::type; - static constexpr bool is_array = true; - static constexpr bool is_empty = (N == 0) || array_info::is_empty; - static constexpr size_t extent = N; - - // appends the extents to shape - static void append_extents(list& shape) { - shape.append(N); - array_info::append_extents(shape); - } - - static constexpr auto extents = _::is_array>( - concat(_(), array_info::extents), _() - ); -}; -// For numpy we have special handling for arrays of characters, so we don't include -// the size in the array extents. -template struct array_info : array_info_scalar { }; -template struct array_info> : array_info_scalar> { }; -template struct array_info : array_info> { }; -template using remove_all_extents_t = typename array_info::type; - -template using is_pod_struct = all_of< - std::is_standard_layout, // since we're accessing directly in memory we need a standard layout type -#if !defined(__GNUG__) || defined(_LIBCPP_VERSION) || defined(_GLIBCXX_USE_CXX11_ABI) - // _GLIBCXX_USE_CXX11_ABI indicates that we're using libstdc++ from GCC 5 or newer, independent - // of the actual compiler (Clang can also use libstdc++, but it always defines __GNUC__ == 4). - std::is_trivially_copyable, -#else - // GCC 4 doesn't implement is_trivially_copyable, so approximate it - std::is_trivially_destructible, - satisfies_any_of, -#endif - satisfies_none_of ->; - -template ssize_t byte_offset_unsafe(const Strides &) { return 0; } -template -ssize_t byte_offset_unsafe(const Strides &strides, ssize_t i, Ix... index) { - return i * strides[Dim] + byte_offset_unsafe(strides, index...); -} - -/** - * Proxy class providing unsafe, unchecked const access to array data. This is constructed through - * the `unchecked()` method of `array` or the `unchecked()` method of `array_t`. `Dims` - * will be -1 for dimensions determined at runtime. - */ -template -class unchecked_reference { -protected: - static constexpr bool Dynamic = Dims < 0; - const unsigned char *data_; - // Storing the shape & strides in local variables (i.e. these arrays) allows the compiler to - // make large performance gains on big, nested loops, but requires compile-time dimensions - conditional_t> - shape_, strides_; - const ssize_t dims_; - - friend class pybind11::array; - // Constructor for compile-time dimensions: - template - unchecked_reference(const void *data, const ssize_t *shape, const ssize_t *strides, enable_if_t) - : data_{reinterpret_cast(data)}, dims_{Dims} { - for (size_t i = 0; i < (size_t) dims_; i++) { - shape_[i] = shape[i]; - strides_[i] = strides[i]; - } - } - // Constructor for runtime dimensions: - template - unchecked_reference(const void *data, const ssize_t *shape, const ssize_t *strides, enable_if_t dims) - : data_{reinterpret_cast(data)}, shape_{shape}, strides_{strides}, dims_{dims} {} - -public: - /** - * Unchecked const reference access to data at the given indices. For a compile-time known - * number of dimensions, this requires the correct number of arguments; for run-time - * dimensionality, this is not checked (and so is up to the caller to use safely). - */ - template const T &operator()(Ix... index) const { - static_assert(ssize_t{sizeof...(Ix)} == Dims || Dynamic, - "Invalid number of indices for unchecked array reference"); - return *reinterpret_cast(data_ + byte_offset_unsafe(strides_, ssize_t(index)...)); - } - /** - * Unchecked const reference access to data; this operator only participates if the reference - * is to a 1-dimensional array. When present, this is exactly equivalent to `obj(index)`. - */ - template > - const T &operator[](ssize_t index) const { return operator()(index); } - - /// Pointer access to the data at the given indices. - template const T *data(Ix... ix) const { return &operator()(ssize_t(ix)...); } - - /// Returns the item size, i.e. sizeof(T) - constexpr static ssize_t itemsize() { return sizeof(T); } - - /// Returns the shape (i.e. size) of dimension `dim` - ssize_t shape(ssize_t dim) const { return shape_[(size_t) dim]; } - - /// Returns the number of dimensions of the array - ssize_t ndim() const { return dims_; } - - /// Returns the total number of elements in the referenced array, i.e. the product of the shapes - template - enable_if_t size() const { - return std::accumulate(shape_.begin(), shape_.end(), (ssize_t) 1, std::multiplies()); - } - template - enable_if_t size() const { - return std::accumulate(shape_, shape_ + ndim(), (ssize_t) 1, std::multiplies()); - } - - /// Returns the total number of bytes used by the referenced data. Note that the actual span in - /// memory may be larger if the referenced array has non-contiguous strides (e.g. for a slice). - ssize_t nbytes() const { - return size() * itemsize(); - } -}; - -template -class unchecked_mutable_reference : public unchecked_reference { - friend class pybind11::array; - using ConstBase = unchecked_reference; - using ConstBase::ConstBase; - using ConstBase::Dynamic; -public: - /// Mutable, unchecked access to data at the given indices. - template T& operator()(Ix... index) { - static_assert(ssize_t{sizeof...(Ix)} == Dims || Dynamic, - "Invalid number of indices for unchecked array reference"); - return const_cast(ConstBase::operator()(index...)); - } - /** - * Mutable, unchecked access data at the given index; this operator only participates if the - * reference is to a 1-dimensional array (or has runtime dimensions). When present, this is - * exactly equivalent to `obj(index)`. - */ - template > - T &operator[](ssize_t index) { return operator()(index); } - - /// Mutable pointer access to the data at the given indices. - template T *mutable_data(Ix... ix) { return &operator()(ssize_t(ix)...); } -}; - -template -struct type_caster> { - static_assert(Dim == 0 && Dim > 0 /* always fail */, "unchecked array proxy object is not castable"); -}; -template -struct type_caster> : type_caster> {}; - -NAMESPACE_END(detail) - -class dtype : public object { -public: - PYBIND11_OBJECT_DEFAULT(dtype, object, detail::npy_api::get().PyArrayDescr_Check_); - - explicit dtype(const buffer_info &info) { - dtype descr(_dtype_from_pep3118()(PYBIND11_STR_TYPE(info.format))); - // If info.itemsize == 0, use the value calculated from the format string - m_ptr = descr.strip_padding(info.itemsize ? info.itemsize : descr.itemsize()).release().ptr(); - } - - explicit dtype(const std::string &format) { - m_ptr = from_args(pybind11::str(format)).release().ptr(); - } - - dtype(const char *format) : dtype(std::string(format)) { } - - dtype(list names, list formats, list offsets, ssize_t itemsize) { - dict args; - args["names"] = names; - args["formats"] = formats; - args["offsets"] = offsets; - args["itemsize"] = pybind11::int_(itemsize); - m_ptr = from_args(args).release().ptr(); - } - - /// This is essentially the same as calling numpy.dtype(args) in Python. - static dtype from_args(object args) { - PyObject *ptr = nullptr; - if (!detail::npy_api::get().PyArray_DescrConverter_(args.ptr(), &ptr) || !ptr) - throw error_already_set(); - return reinterpret_steal(ptr); - } - - /// Return dtype associated with a C++ type. - template static dtype of() { - return detail::npy_format_descriptor::type>::dtype(); - } - - /// Size of the data type in bytes. - ssize_t itemsize() const { - return detail::array_descriptor_proxy(m_ptr)->elsize; - } - - /// Returns true for structured data types. - bool has_fields() const { - return detail::array_descriptor_proxy(m_ptr)->names != nullptr; - } - - /// Single-character type code. - char kind() const { - return detail::array_descriptor_proxy(m_ptr)->kind; - } - -private: - static object _dtype_from_pep3118() { - static PyObject *obj = module::import("numpy.core._internal") - .attr("_dtype_from_pep3118").cast().release().ptr(); - return reinterpret_borrow(obj); - } - - dtype strip_padding(ssize_t itemsize) { - // Recursively strip all void fields with empty names that are generated for - // padding fields (as of NumPy v1.11). - if (!has_fields()) - return *this; - - struct field_descr { PYBIND11_STR_TYPE name; object format; pybind11::int_ offset; }; - std::vector field_descriptors; - - for (auto field : attr("fields").attr("items")()) { - auto spec = field.cast(); - auto name = spec[0].cast(); - auto format = spec[1].cast()[0].cast(); - auto offset = spec[1].cast()[1].cast(); - if (!len(name) && format.kind() == 'V') - continue; - field_descriptors.push_back({(PYBIND11_STR_TYPE) name, format.strip_padding(format.itemsize()), offset}); - } - - std::sort(field_descriptors.begin(), field_descriptors.end(), - [](const field_descr& a, const field_descr& b) { - return a.offset.cast() < b.offset.cast(); - }); - - list names, formats, offsets; - for (auto& descr : field_descriptors) { - names.append(descr.name); - formats.append(descr.format); - offsets.append(descr.offset); - } - return dtype(names, formats, offsets, itemsize); - } -}; - -class array : public buffer { -public: - PYBIND11_OBJECT_CVT(array, buffer, detail::npy_api::get().PyArray_Check_, raw_array) - - enum { - c_style = detail::npy_api::NPY_ARRAY_C_CONTIGUOUS_, - f_style = detail::npy_api::NPY_ARRAY_F_CONTIGUOUS_, - forcecast = detail::npy_api::NPY_ARRAY_FORCECAST_ - }; - - array() : array({{0}}, static_cast(nullptr)) {} - - using ShapeContainer = detail::any_container; - using StridesContainer = detail::any_container; - - // Constructs an array taking shape/strides from arbitrary container types - array(const pybind11::dtype &dt, ShapeContainer shape, StridesContainer strides, - const void *ptr = nullptr, handle base = handle()) { - - if (strides->empty()) - *strides = c_strides(*shape, dt.itemsize()); - - auto ndim = shape->size(); - if (ndim != strides->size()) - pybind11_fail("NumPy: shape ndim doesn't match strides ndim"); - auto descr = dt; - - int flags = 0; - if (base && ptr) { - if (isinstance(base)) - /* Copy flags from base (except ownership bit) */ - flags = reinterpret_borrow(base).flags() & ~detail::npy_api::NPY_ARRAY_OWNDATA_; - else - /* Writable by default, easy to downgrade later on if needed */ - flags = detail::npy_api::NPY_ARRAY_WRITEABLE_; - } - - auto &api = detail::npy_api::get(); - auto tmp = reinterpret_steal(api.PyArray_NewFromDescr_( - api.PyArray_Type_, descr.release().ptr(), (int) ndim, shape->data(), strides->data(), - const_cast(ptr), flags, nullptr)); - if (!tmp) - throw error_already_set(); - if (ptr) { - if (base) { - api.PyArray_SetBaseObject_(tmp.ptr(), base.inc_ref().ptr()); - } else { - tmp = reinterpret_steal(api.PyArray_NewCopy_(tmp.ptr(), -1 /* any order */)); - } - } - m_ptr = tmp.release().ptr(); - } - - array(const pybind11::dtype &dt, ShapeContainer shape, const void *ptr = nullptr, handle base = handle()) - : array(dt, std::move(shape), {}, ptr, base) { } - - template ::value && !std::is_same::value>> - array(const pybind11::dtype &dt, T count, const void *ptr = nullptr, handle base = handle()) - : array(dt, {{count}}, ptr, base) { } - - template - array(ShapeContainer shape, StridesContainer strides, const T *ptr, handle base = handle()) - : array(pybind11::dtype::of(), std::move(shape), std::move(strides), ptr, base) { } - - template - array(ShapeContainer shape, const T *ptr, handle base = handle()) - : array(std::move(shape), {}, ptr, base) { } - - template - explicit array(ssize_t count, const T *ptr, handle base = handle()) : array({count}, {}, ptr, base) { } - - explicit array(const buffer_info &info) - : array(pybind11::dtype(info), info.shape, info.strides, info.ptr) { } - - /// Array descriptor (dtype) - pybind11::dtype dtype() const { - return reinterpret_borrow(detail::array_proxy(m_ptr)->descr); - } - - /// Total number of elements - ssize_t size() const { - return std::accumulate(shape(), shape() + ndim(), (ssize_t) 1, std::multiplies()); - } - - /// Byte size of a single element - ssize_t itemsize() const { - return detail::array_descriptor_proxy(detail::array_proxy(m_ptr)->descr)->elsize; - } - - /// Total number of bytes - ssize_t nbytes() const { - return size() * itemsize(); - } - - /// Number of dimensions - ssize_t ndim() const { - return detail::array_proxy(m_ptr)->nd; - } - - /// Base object - object base() const { - return reinterpret_borrow(detail::array_proxy(m_ptr)->base); - } - - /// Dimensions of the array - const ssize_t* shape() const { - return detail::array_proxy(m_ptr)->dimensions; - } - - /// Dimension along a given axis - ssize_t shape(ssize_t dim) const { - if (dim >= ndim()) - fail_dim_check(dim, "invalid axis"); - return shape()[dim]; - } - - /// Strides of the array - const ssize_t* strides() const { - return detail::array_proxy(m_ptr)->strides; - } - - /// Stride along a given axis - ssize_t strides(ssize_t dim) const { - if (dim >= ndim()) - fail_dim_check(dim, "invalid axis"); - return strides()[dim]; - } - - /// Return the NumPy array flags - int flags() const { - return detail::array_proxy(m_ptr)->flags; - } - - /// If set, the array is writeable (otherwise the buffer is read-only) - bool writeable() const { - return detail::check_flags(m_ptr, detail::npy_api::NPY_ARRAY_WRITEABLE_); - } - - /// If set, the array owns the data (will be freed when the array is deleted) - bool owndata() const { - return detail::check_flags(m_ptr, detail::npy_api::NPY_ARRAY_OWNDATA_); - } - - /// Pointer to the contained data. If index is not provided, points to the - /// beginning of the buffer. May throw if the index would lead to out of bounds access. - template const void* data(Ix... index) const { - return static_cast(detail::array_proxy(m_ptr)->data + offset_at(index...)); - } - - /// Mutable pointer to the contained data. If index is not provided, points to the - /// beginning of the buffer. May throw if the index would lead to out of bounds access. - /// May throw if the array is not writeable. - template void* mutable_data(Ix... index) { - check_writeable(); - return static_cast(detail::array_proxy(m_ptr)->data + offset_at(index...)); - } - - /// Byte offset from beginning of the array to a given index (full or partial). - /// May throw if the index would lead to out of bounds access. - template ssize_t offset_at(Ix... index) const { - if ((ssize_t) sizeof...(index) > ndim()) - fail_dim_check(sizeof...(index), "too many indices for an array"); - return byte_offset(ssize_t(index)...); - } - - ssize_t offset_at() const { return 0; } - - /// Item count from beginning of the array to a given index (full or partial). - /// May throw if the index would lead to out of bounds access. - template ssize_t index_at(Ix... index) const { - return offset_at(index...) / itemsize(); - } - - /** - * Returns a proxy object that provides access to the array's data without bounds or - * dimensionality checking. Will throw if the array is missing the `writeable` flag. Use with - * care: the array must not be destroyed or reshaped for the duration of the returned object, - * and the caller must take care not to access invalid dimensions or dimension indices. - */ - template detail::unchecked_mutable_reference mutable_unchecked() & { - if (Dims >= 0 && ndim() != Dims) - throw std::domain_error("array has incorrect number of dimensions: " + std::to_string(ndim()) + - "; expected " + std::to_string(Dims)); - return detail::unchecked_mutable_reference(mutable_data(), shape(), strides(), ndim()); - } - - /** - * Returns a proxy object that provides const access to the array's data without bounds or - * dimensionality checking. Unlike `mutable_unchecked()`, this does not require that the - * underlying array have the `writable` flag. Use with care: the array must not be destroyed or - * reshaped for the duration of the returned object, and the caller must take care not to access - * invalid dimensions or dimension indices. - */ - template detail::unchecked_reference unchecked() const & { - if (Dims >= 0 && ndim() != Dims) - throw std::domain_error("array has incorrect number of dimensions: " + std::to_string(ndim()) + - "; expected " + std::to_string(Dims)); - return detail::unchecked_reference(data(), shape(), strides(), ndim()); - } - - /// Return a new view with all of the dimensions of length 1 removed - array squeeze() { - auto& api = detail::npy_api::get(); - return reinterpret_steal(api.PyArray_Squeeze_(m_ptr)); - } - - /// Resize array to given shape - /// If refcheck is true and more that one reference exist to this array - /// then resize will succeed only if it makes a reshape, i.e. original size doesn't change - void resize(ShapeContainer new_shape, bool refcheck = true) { - detail::npy_api::PyArray_Dims d = { - new_shape->data(), int(new_shape->size()) - }; - // try to resize, set ordering param to -1 cause it's not used anyway - object new_array = reinterpret_steal( - detail::npy_api::get().PyArray_Resize_(m_ptr, &d, int(refcheck), -1) - ); - if (!new_array) throw error_already_set(); - if (isinstance(new_array)) { *this = std::move(new_array); } - } - - /// Ensure that the argument is a NumPy array - /// In case of an error, nullptr is returned and the Python error is cleared. - static array ensure(handle h, int ExtraFlags = 0) { - auto result = reinterpret_steal(raw_array(h.ptr(), ExtraFlags)); - if (!result) - PyErr_Clear(); - return result; - } - -protected: - template friend struct detail::npy_format_descriptor; - - void fail_dim_check(ssize_t dim, const std::string& msg) const { - throw index_error(msg + ": " + std::to_string(dim) + - " (ndim = " + std::to_string(ndim()) + ")"); - } - - template ssize_t byte_offset(Ix... index) const { - check_dimensions(index...); - return detail::byte_offset_unsafe(strides(), ssize_t(index)...); - } - - void check_writeable() const { - if (!writeable()) - throw std::domain_error("array is not writeable"); - } - - // Default, C-style strides - static std::vector c_strides(const std::vector &shape, ssize_t itemsize) { - auto ndim = shape.size(); - std::vector strides(ndim, itemsize); - for (size_t i = ndim - 1; i > 0; --i) - strides[i - 1] = strides[i] * shape[i]; - return strides; - } - - // F-style strides; default when constructing an array_t with `ExtraFlags & f_style` - static std::vector f_strides(const std::vector &shape, ssize_t itemsize) { - auto ndim = shape.size(); - std::vector strides(ndim, itemsize); - for (size_t i = 1; i < ndim; ++i) - strides[i] = strides[i - 1] * shape[i - 1]; - return strides; - } - - template void check_dimensions(Ix... index) const { - check_dimensions_impl(ssize_t(0), shape(), ssize_t(index)...); - } - - void check_dimensions_impl(ssize_t, const ssize_t*) const { } - - template void check_dimensions_impl(ssize_t axis, const ssize_t* shape, ssize_t i, Ix... index) const { - if (i >= *shape) { - throw index_error(std::string("index ") + std::to_string(i) + - " is out of bounds for axis " + std::to_string(axis) + - " with size " + std::to_string(*shape)); - } - check_dimensions_impl(axis + 1, shape + 1, index...); - } - - /// Create array from any object -- always returns a new reference - static PyObject *raw_array(PyObject *ptr, int ExtraFlags = 0) { - if (ptr == nullptr) { - PyErr_SetString(PyExc_ValueError, "cannot create a pybind11::array from a nullptr"); - return nullptr; - } - return detail::npy_api::get().PyArray_FromAny_( - ptr, nullptr, 0, 0, detail::npy_api::NPY_ARRAY_ENSUREARRAY_ | ExtraFlags, nullptr); - } -}; - -template class array_t : public array { -private: - struct private_ctor {}; - // Delegating constructor needed when both moving and accessing in the same constructor - array_t(private_ctor, ShapeContainer &&shape, StridesContainer &&strides, const T *ptr, handle base) - : array(std::move(shape), std::move(strides), ptr, base) {} -public: - static_assert(!detail::array_info::is_array, "Array types cannot be used with array_t"); - - using value_type = T; - - array_t() : array(0, static_cast(nullptr)) {} - array_t(handle h, borrowed_t) : array(h, borrowed_t{}) { } - array_t(handle h, stolen_t) : array(h, stolen_t{}) { } - - PYBIND11_DEPRECATED("Use array_t::ensure() instead") - array_t(handle h, bool is_borrowed) : array(raw_array_t(h.ptr()), stolen_t{}) { - if (!m_ptr) PyErr_Clear(); - if (!is_borrowed) Py_XDECREF(h.ptr()); - } - - array_t(const object &o) : array(raw_array_t(o.ptr()), stolen_t{}) { - if (!m_ptr) throw error_already_set(); - } - - explicit array_t(const buffer_info& info) : array(info) { } - - array_t(ShapeContainer shape, StridesContainer strides, const T *ptr = nullptr, handle base = handle()) - : array(std::move(shape), std::move(strides), ptr, base) { } - - explicit array_t(ShapeContainer shape, const T *ptr = nullptr, handle base = handle()) - : array_t(private_ctor{}, std::move(shape), - ExtraFlags & f_style ? f_strides(*shape, itemsize()) : c_strides(*shape, itemsize()), - ptr, base) { } - - explicit array_t(size_t count, const T *ptr = nullptr, handle base = handle()) - : array({count}, {}, ptr, base) { } - - constexpr ssize_t itemsize() const { - return sizeof(T); - } - - template ssize_t index_at(Ix... index) const { - return offset_at(index...) / itemsize(); - } - - template const T* data(Ix... index) const { - return static_cast(array::data(index...)); - } - - template T* mutable_data(Ix... index) { - return static_cast(array::mutable_data(index...)); - } - - // Reference to element at a given index - template const T& at(Ix... index) const { - if (sizeof...(index) != ndim()) - fail_dim_check(sizeof...(index), "index dimension mismatch"); - return *(static_cast(array::data()) + byte_offset(ssize_t(index)...) / itemsize()); - } - - // Mutable reference to element at a given index - template T& mutable_at(Ix... index) { - if (sizeof...(index) != ndim()) - fail_dim_check(sizeof...(index), "index dimension mismatch"); - return *(static_cast(array::mutable_data()) + byte_offset(ssize_t(index)...) / itemsize()); - } - - /** - * Returns a proxy object that provides access to the array's data without bounds or - * dimensionality checking. Will throw if the array is missing the `writeable` flag. Use with - * care: the array must not be destroyed or reshaped for the duration of the returned object, - * and the caller must take care not to access invalid dimensions or dimension indices. - */ - template detail::unchecked_mutable_reference mutable_unchecked() & { - return array::mutable_unchecked(); - } - - /** - * Returns a proxy object that provides const access to the array's data without bounds or - * dimensionality checking. Unlike `unchecked()`, this does not require that the underlying - * array have the `writable` flag. Use with care: the array must not be destroyed or reshaped - * for the duration of the returned object, and the caller must take care not to access invalid - * dimensions or dimension indices. - */ - template detail::unchecked_reference unchecked() const & { - return array::unchecked(); - } - - /// Ensure that the argument is a NumPy array of the correct dtype (and if not, try to convert - /// it). In case of an error, nullptr is returned and the Python error is cleared. - static array_t ensure(handle h) { - auto result = reinterpret_steal(raw_array_t(h.ptr())); - if (!result) - PyErr_Clear(); - return result; - } - - static bool check_(handle h) { - const auto &api = detail::npy_api::get(); - return api.PyArray_Check_(h.ptr()) - && api.PyArray_EquivTypes_(detail::array_proxy(h.ptr())->descr, dtype::of().ptr()); - } - -protected: - /// Create array from any object -- always returns a new reference - static PyObject *raw_array_t(PyObject *ptr) { - if (ptr == nullptr) { - PyErr_SetString(PyExc_ValueError, "cannot create a pybind11::array_t from a nullptr"); - return nullptr; - } - return detail::npy_api::get().PyArray_FromAny_( - ptr, dtype::of().release().ptr(), 0, 0, - detail::npy_api::NPY_ARRAY_ENSUREARRAY_ | ExtraFlags, nullptr); - } -}; - -template -struct format_descriptor::value>> { - static std::string format() { - return detail::npy_format_descriptor::type>::format(); - } -}; - -template struct format_descriptor { - static std::string format() { return std::to_string(N) + "s"; } -}; -template struct format_descriptor> { - static std::string format() { return std::to_string(N) + "s"; } -}; - -template -struct format_descriptor::value>> { - static std::string format() { - return format_descriptor< - typename std::remove_cv::type>::type>::format(); - } -}; - -template -struct format_descriptor::is_array>> { - static std::string format() { - using detail::_; - static constexpr auto extents = _("(") + detail::array_info::extents + _(")"); - return extents.text + format_descriptor>::format(); - } -}; - -NAMESPACE_BEGIN(detail) -template -struct pyobject_caster> { - using type = array_t; - - bool load(handle src, bool convert) { - if (!convert && !type::check_(src)) - return false; - value = type::ensure(src); - return static_cast(value); - } - - static handle cast(const handle &src, return_value_policy /* policy */, handle /* parent */) { - return src.inc_ref(); - } - PYBIND11_TYPE_CASTER(type, handle_type_name::name); -}; - -template -struct compare_buffer_info::value>> { - static bool compare(const buffer_info& b) { - return npy_api::get().PyArray_EquivTypes_(dtype::of().ptr(), dtype(b).ptr()); - } -}; - -template -struct npy_format_descriptor_name; - -template -struct npy_format_descriptor_name::value>> { - static constexpr auto name = _::value>( - _("bool"), _::value>("int", "uint") + _() - ); -}; - -template -struct npy_format_descriptor_name::value>> { - static constexpr auto name = _::value || std::is_same::value>( - _("float") + _(), _("longdouble") - ); -}; - -template -struct npy_format_descriptor_name::value>> { - static constexpr auto name = _::value - || std::is_same::value>( - _("complex") + _(), _("longcomplex") - ); -}; - -template -struct npy_format_descriptor::value>> - : npy_format_descriptor_name { -private: - // NB: the order here must match the one in common.h - constexpr static const int values[15] = { - npy_api::NPY_BOOL_, - npy_api::NPY_BYTE_, npy_api::NPY_UBYTE_, npy_api::NPY_SHORT_, npy_api::NPY_USHORT_, - npy_api::NPY_INT_, npy_api::NPY_UINT_, npy_api::NPY_LONGLONG_, npy_api::NPY_ULONGLONG_, - npy_api::NPY_FLOAT_, npy_api::NPY_DOUBLE_, npy_api::NPY_LONGDOUBLE_, - npy_api::NPY_CFLOAT_, npy_api::NPY_CDOUBLE_, npy_api::NPY_CLONGDOUBLE_ - }; - -public: - static constexpr int value = values[detail::is_fmt_numeric::index]; - - static pybind11::dtype dtype() { - if (auto ptr = npy_api::get().PyArray_DescrFromType_(value)) - return reinterpret_borrow(ptr); - pybind11_fail("Unsupported buffer format!"); - } -}; - -#define PYBIND11_DECL_CHAR_FMT \ - static constexpr auto name = _("S") + _(); \ - static pybind11::dtype dtype() { return pybind11::dtype(std::string("S") + std::to_string(N)); } -template struct npy_format_descriptor { PYBIND11_DECL_CHAR_FMT }; -template struct npy_format_descriptor> { PYBIND11_DECL_CHAR_FMT }; -#undef PYBIND11_DECL_CHAR_FMT - -template struct npy_format_descriptor::is_array>> { -private: - using base_descr = npy_format_descriptor::type>; -public: - static_assert(!array_info::is_empty, "Zero-sized arrays are not supported"); - - static constexpr auto name = _("(") + array_info::extents + _(")") + base_descr::name; - static pybind11::dtype dtype() { - list shape; - array_info::append_extents(shape); - return pybind11::dtype::from_args(pybind11::make_tuple(base_descr::dtype(), shape)); - } -}; - -template struct npy_format_descriptor::value>> { -private: - using base_descr = npy_format_descriptor::type>; -public: - static constexpr auto name = base_descr::name; - static pybind11::dtype dtype() { return base_descr::dtype(); } -}; - -struct field_descriptor { - const char *name; - ssize_t offset; - ssize_t size; - std::string format; - dtype descr; -}; - -inline PYBIND11_NOINLINE void register_structured_dtype( - any_container fields, - const std::type_info& tinfo, ssize_t itemsize, - bool (*direct_converter)(PyObject *, void *&)) { - - auto& numpy_internals = get_numpy_internals(); - if (numpy_internals.get_type_info(tinfo, false)) - pybind11_fail("NumPy: dtype is already registered"); - - list names, formats, offsets; - for (auto field : *fields) { - if (!field.descr) - pybind11_fail(std::string("NumPy: unsupported field dtype: `") + - field.name + "` @ " + tinfo.name()); - names.append(PYBIND11_STR_TYPE(field.name)); - formats.append(field.descr); - offsets.append(pybind11::int_(field.offset)); - } - auto dtype_ptr = pybind11::dtype(names, formats, offsets, itemsize).release().ptr(); - - // There is an existing bug in NumPy (as of v1.11): trailing bytes are - // not encoded explicitly into the format string. This will supposedly - // get fixed in v1.12; for further details, see these: - // - https://github.com/numpy/numpy/issues/7797 - // - https://github.com/numpy/numpy/pull/7798 - // Because of this, we won't use numpy's logic to generate buffer format - // strings and will just do it ourselves. - std::vector ordered_fields(std::move(fields)); - std::sort(ordered_fields.begin(), ordered_fields.end(), - [](const field_descriptor &a, const field_descriptor &b) { return a.offset < b.offset; }); - ssize_t offset = 0; - std::ostringstream oss; - // mark the structure as unaligned with '^', because numpy and C++ don't - // always agree about alignment (particularly for complex), and we're - // explicitly listing all our padding. This depends on none of the fields - // overriding the endianness. Putting the ^ in front of individual fields - // isn't guaranteed to work due to https://github.com/numpy/numpy/issues/9049 - oss << "^T{"; - for (auto& field : ordered_fields) { - if (field.offset > offset) - oss << (field.offset - offset) << 'x'; - oss << field.format << ':' << field.name << ':'; - offset = field.offset + field.size; - } - if (itemsize > offset) - oss << (itemsize - offset) << 'x'; - oss << '}'; - auto format_str = oss.str(); - - // Sanity check: verify that NumPy properly parses our buffer format string - auto& api = npy_api::get(); - auto arr = array(buffer_info(nullptr, itemsize, format_str, 1)); - if (!api.PyArray_EquivTypes_(dtype_ptr, arr.dtype().ptr())) - pybind11_fail("NumPy: invalid buffer descriptor!"); - - auto tindex = std::type_index(tinfo); - numpy_internals.registered_dtypes[tindex] = { dtype_ptr, format_str }; - get_internals().direct_conversions[tindex].push_back(direct_converter); -} - -template struct npy_format_descriptor { - static_assert(is_pod_struct::value, "Attempt to use a non-POD or unimplemented POD type as a numpy dtype"); - - static constexpr auto name = make_caster::name; - - static pybind11::dtype dtype() { - return reinterpret_borrow(dtype_ptr()); - } - - static std::string format() { - static auto format_str = get_numpy_internals().get_type_info(true)->format_str; - return format_str; - } - - static void register_dtype(any_container fields) { - register_structured_dtype(std::move(fields), typeid(typename std::remove_cv::type), - sizeof(T), &direct_converter); - } - -private: - static PyObject* dtype_ptr() { - static PyObject* ptr = get_numpy_internals().get_type_info(true)->dtype_ptr; - return ptr; - } - - static bool direct_converter(PyObject *obj, void*& value) { - auto& api = npy_api::get(); - if (!PyObject_TypeCheck(obj, api.PyVoidArrType_Type_)) - return false; - if (auto descr = reinterpret_steal(api.PyArray_DescrFromScalar_(obj))) { - if (api.PyArray_EquivTypes_(dtype_ptr(), descr.ptr())) { - value = ((PyVoidScalarObject_Proxy *) obj)->obval; - return true; - } - } - return false; - } -}; - -#ifdef __CLION_IDE__ // replace heavy macro with dummy code for the IDE (doesn't affect code) -# define PYBIND11_NUMPY_DTYPE(Type, ...) ((void)0) -# define PYBIND11_NUMPY_DTYPE_EX(Type, ...) ((void)0) -#else - -#define PYBIND11_FIELD_DESCRIPTOR_EX(T, Field, Name) \ - ::pybind11::detail::field_descriptor { \ - Name, offsetof(T, Field), sizeof(decltype(std::declval().Field)), \ - ::pybind11::format_descriptor().Field)>::format(), \ - ::pybind11::detail::npy_format_descriptor().Field)>::dtype() \ - } - -// Extract name, offset and format descriptor for a struct field -#define PYBIND11_FIELD_DESCRIPTOR(T, Field) PYBIND11_FIELD_DESCRIPTOR_EX(T, Field, #Field) - -// The main idea of this macro is borrowed from https://github.com/swansontec/map-macro -// (C) William Swanson, Paul Fultz -#define PYBIND11_EVAL0(...) __VA_ARGS__ -#define PYBIND11_EVAL1(...) PYBIND11_EVAL0 (PYBIND11_EVAL0 (PYBIND11_EVAL0 (__VA_ARGS__))) -#define PYBIND11_EVAL2(...) PYBIND11_EVAL1 (PYBIND11_EVAL1 (PYBIND11_EVAL1 (__VA_ARGS__))) -#define PYBIND11_EVAL3(...) PYBIND11_EVAL2 (PYBIND11_EVAL2 (PYBIND11_EVAL2 (__VA_ARGS__))) -#define PYBIND11_EVAL4(...) PYBIND11_EVAL3 (PYBIND11_EVAL3 (PYBIND11_EVAL3 (__VA_ARGS__))) -#define PYBIND11_EVAL(...) PYBIND11_EVAL4 (PYBIND11_EVAL4 (PYBIND11_EVAL4 (__VA_ARGS__))) -#define PYBIND11_MAP_END(...) -#define PYBIND11_MAP_OUT -#define PYBIND11_MAP_COMMA , -#define PYBIND11_MAP_GET_END() 0, PYBIND11_MAP_END -#define PYBIND11_MAP_NEXT0(test, next, ...) next PYBIND11_MAP_OUT -#define PYBIND11_MAP_NEXT1(test, next) PYBIND11_MAP_NEXT0 (test, next, 0) -#define PYBIND11_MAP_NEXT(test, next) PYBIND11_MAP_NEXT1 (PYBIND11_MAP_GET_END test, next) -#ifdef _MSC_VER // MSVC is not as eager to expand macros, hence this workaround -#define PYBIND11_MAP_LIST_NEXT1(test, next) \ - PYBIND11_EVAL0 (PYBIND11_MAP_NEXT0 (test, PYBIND11_MAP_COMMA next, 0)) -#else -#define PYBIND11_MAP_LIST_NEXT1(test, next) \ - PYBIND11_MAP_NEXT0 (test, PYBIND11_MAP_COMMA next, 0) -#endif -#define PYBIND11_MAP_LIST_NEXT(test, next) \ - PYBIND11_MAP_LIST_NEXT1 (PYBIND11_MAP_GET_END test, next) -#define PYBIND11_MAP_LIST0(f, t, x, peek, ...) \ - f(t, x) PYBIND11_MAP_LIST_NEXT (peek, PYBIND11_MAP_LIST1) (f, t, peek, __VA_ARGS__) -#define PYBIND11_MAP_LIST1(f, t, x, peek, ...) \ - f(t, x) PYBIND11_MAP_LIST_NEXT (peek, PYBIND11_MAP_LIST0) (f, t, peek, __VA_ARGS__) -// PYBIND11_MAP_LIST(f, t, a1, a2, ...) expands to f(t, a1), f(t, a2), ... -#define PYBIND11_MAP_LIST(f, t, ...) \ - PYBIND11_EVAL (PYBIND11_MAP_LIST1 (f, t, __VA_ARGS__, (), 0)) - -#define PYBIND11_NUMPY_DTYPE(Type, ...) \ - ::pybind11::detail::npy_format_descriptor::register_dtype \ - (::std::vector<::pybind11::detail::field_descriptor> \ - {PYBIND11_MAP_LIST (PYBIND11_FIELD_DESCRIPTOR, Type, __VA_ARGS__)}) - -#ifdef _MSC_VER -#define PYBIND11_MAP2_LIST_NEXT1(test, next) \ - PYBIND11_EVAL0 (PYBIND11_MAP_NEXT0 (test, PYBIND11_MAP_COMMA next, 0)) -#else -#define PYBIND11_MAP2_LIST_NEXT1(test, next) \ - PYBIND11_MAP_NEXT0 (test, PYBIND11_MAP_COMMA next, 0) -#endif -#define PYBIND11_MAP2_LIST_NEXT(test, next) \ - PYBIND11_MAP2_LIST_NEXT1 (PYBIND11_MAP_GET_END test, next) -#define PYBIND11_MAP2_LIST0(f, t, x1, x2, peek, ...) \ - f(t, x1, x2) PYBIND11_MAP2_LIST_NEXT (peek, PYBIND11_MAP2_LIST1) (f, t, peek, __VA_ARGS__) -#define PYBIND11_MAP2_LIST1(f, t, x1, x2, peek, ...) \ - f(t, x1, x2) PYBIND11_MAP2_LIST_NEXT (peek, PYBIND11_MAP2_LIST0) (f, t, peek, __VA_ARGS__) -// PYBIND11_MAP2_LIST(f, t, a1, a2, ...) expands to f(t, a1, a2), f(t, a3, a4), ... -#define PYBIND11_MAP2_LIST(f, t, ...) \ - PYBIND11_EVAL (PYBIND11_MAP2_LIST1 (f, t, __VA_ARGS__, (), 0)) - -#define PYBIND11_NUMPY_DTYPE_EX(Type, ...) \ - ::pybind11::detail::npy_format_descriptor::register_dtype \ - (::std::vector<::pybind11::detail::field_descriptor> \ - {PYBIND11_MAP2_LIST (PYBIND11_FIELD_DESCRIPTOR_EX, Type, __VA_ARGS__)}) - -#endif // __CLION_IDE__ - -template -using array_iterator = typename std::add_pointer::type; - -template -array_iterator array_begin(const buffer_info& buffer) { - return array_iterator(reinterpret_cast(buffer.ptr)); -} - -template -array_iterator array_end(const buffer_info& buffer) { - return array_iterator(reinterpret_cast(buffer.ptr) + buffer.size); -} - -class common_iterator { -public: - using container_type = std::vector; - using value_type = container_type::value_type; - using size_type = container_type::size_type; - - common_iterator() : p_ptr(0), m_strides() {} - - common_iterator(void* ptr, const container_type& strides, const container_type& shape) - : p_ptr(reinterpret_cast(ptr)), m_strides(strides.size()) { - m_strides.back() = static_cast(strides.back()); - for (size_type i = m_strides.size() - 1; i != 0; --i) { - size_type j = i - 1; - value_type s = static_cast(shape[i]); - m_strides[j] = strides[j] + m_strides[i] - strides[i] * s; - } - } - - void increment(size_type dim) { - p_ptr += m_strides[dim]; - } - - void* data() const { - return p_ptr; - } - -private: - char* p_ptr; - container_type m_strides; -}; - -template class multi_array_iterator { -public: - using container_type = std::vector; - - multi_array_iterator(const std::array &buffers, - const container_type &shape) - : m_shape(shape.size()), m_index(shape.size(), 0), - m_common_iterator() { - - // Manual copy to avoid conversion warning if using std::copy - for (size_t i = 0; i < shape.size(); ++i) - m_shape[i] = shape[i]; - - container_type strides(shape.size()); - for (size_t i = 0; i < N; ++i) - init_common_iterator(buffers[i], shape, m_common_iterator[i], strides); - } - - multi_array_iterator& operator++() { - for (size_t j = m_index.size(); j != 0; --j) { - size_t i = j - 1; - if (++m_index[i] != m_shape[i]) { - increment_common_iterator(i); - break; - } else { - m_index[i] = 0; - } - } - return *this; - } - - template T* data() const { - return reinterpret_cast(m_common_iterator[K].data()); - } - -private: - - using common_iter = common_iterator; - - void init_common_iterator(const buffer_info &buffer, - const container_type &shape, - common_iter &iterator, - container_type &strides) { - auto buffer_shape_iter = buffer.shape.rbegin(); - auto buffer_strides_iter = buffer.strides.rbegin(); - auto shape_iter = shape.rbegin(); - auto strides_iter = strides.rbegin(); - - while (buffer_shape_iter != buffer.shape.rend()) { - if (*shape_iter == *buffer_shape_iter) - *strides_iter = *buffer_strides_iter; - else - *strides_iter = 0; - - ++buffer_shape_iter; - ++buffer_strides_iter; - ++shape_iter; - ++strides_iter; - } - - std::fill(strides_iter, strides.rend(), 0); - iterator = common_iter(buffer.ptr, strides, shape); - } - - void increment_common_iterator(size_t dim) { - for (auto &iter : m_common_iterator) - iter.increment(dim); - } - - container_type m_shape; - container_type m_index; - std::array m_common_iterator; -}; - -enum class broadcast_trivial { non_trivial, c_trivial, f_trivial }; - -// Populates the shape and number of dimensions for the set of buffers. Returns a broadcast_trivial -// enum value indicating whether the broadcast is "trivial"--that is, has each buffer being either a -// singleton or a full-size, C-contiguous (`c_trivial`) or Fortran-contiguous (`f_trivial`) storage -// buffer; returns `non_trivial` otherwise. -template -broadcast_trivial broadcast(const std::array &buffers, ssize_t &ndim, std::vector &shape) { - ndim = std::accumulate(buffers.begin(), buffers.end(), ssize_t(0), [](ssize_t res, const buffer_info &buf) { - return std::max(res, buf.ndim); - }); - - shape.clear(); - shape.resize((size_t) ndim, 1); - - // Figure out the output size, and make sure all input arrays conform (i.e. are either size 1 or - // the full size). - for (size_t i = 0; i < N; ++i) { - auto res_iter = shape.rbegin(); - auto end = buffers[i].shape.rend(); - for (auto shape_iter = buffers[i].shape.rbegin(); shape_iter != end; ++shape_iter, ++res_iter) { - const auto &dim_size_in = *shape_iter; - auto &dim_size_out = *res_iter; - - // Each input dimension can either be 1 or `n`, but `n` values must match across buffers - if (dim_size_out == 1) - dim_size_out = dim_size_in; - else if (dim_size_in != 1 && dim_size_in != dim_size_out) - pybind11_fail("pybind11::vectorize: incompatible size/dimension of inputs!"); - } - } - - bool trivial_broadcast_c = true; - bool trivial_broadcast_f = true; - for (size_t i = 0; i < N && (trivial_broadcast_c || trivial_broadcast_f); ++i) { - if (buffers[i].size == 1) - continue; - - // Require the same number of dimensions: - if (buffers[i].ndim != ndim) - return broadcast_trivial::non_trivial; - - // Require all dimensions be full-size: - if (!std::equal(buffers[i].shape.cbegin(), buffers[i].shape.cend(), shape.cbegin())) - return broadcast_trivial::non_trivial; - - // Check for C contiguity (but only if previous inputs were also C contiguous) - if (trivial_broadcast_c) { - ssize_t expect_stride = buffers[i].itemsize; - auto end = buffers[i].shape.crend(); - for (auto shape_iter = buffers[i].shape.crbegin(), stride_iter = buffers[i].strides.crbegin(); - trivial_broadcast_c && shape_iter != end; ++shape_iter, ++stride_iter) { - if (expect_stride == *stride_iter) - expect_stride *= *shape_iter; - else - trivial_broadcast_c = false; - } - } - - // Check for Fortran contiguity (if previous inputs were also F contiguous) - if (trivial_broadcast_f) { - ssize_t expect_stride = buffers[i].itemsize; - auto end = buffers[i].shape.cend(); - for (auto shape_iter = buffers[i].shape.cbegin(), stride_iter = buffers[i].strides.cbegin(); - trivial_broadcast_f && shape_iter != end; ++shape_iter, ++stride_iter) { - if (expect_stride == *stride_iter) - expect_stride *= *shape_iter; - else - trivial_broadcast_f = false; - } - } - } - - return - trivial_broadcast_c ? broadcast_trivial::c_trivial : - trivial_broadcast_f ? broadcast_trivial::f_trivial : - broadcast_trivial::non_trivial; -} - -template -struct vectorize_arg { - static_assert(!std::is_rvalue_reference::value, "Functions with rvalue reference arguments cannot be vectorized"); - // The wrapped function gets called with this type: - using call_type = remove_reference_t; - // Is this a vectorized argument? - static constexpr bool vectorize = - satisfies_any_of::value && - satisfies_none_of::value && - (!std::is_reference::value || - (std::is_lvalue_reference::value && std::is_const::value)); - // Accept this type: an array for vectorized types, otherwise the type as-is: - using type = conditional_t, array::forcecast>, T>; -}; - -template -struct vectorize_helper { -private: - static constexpr size_t N = sizeof...(Args); - static constexpr size_t NVectorized = constexpr_sum(vectorize_arg::vectorize...); - static_assert(NVectorized >= 1, - "pybind11::vectorize(...) requires a function with at least one vectorizable argument"); - -public: - template - explicit vectorize_helper(T &&f) : f(std::forward(f)) { } - - object operator()(typename vectorize_arg::type... args) { - return run(args..., - make_index_sequence(), - select_indices::vectorize...>(), - make_index_sequence()); - } - -private: - remove_reference_t f; - - template using param_n_t = typename pack_element::call_type...>::type; - - // Runs a vectorized function given arguments tuple and three index sequences: - // - Index is the full set of 0 ... (N-1) argument indices; - // - VIndex is the subset of argument indices with vectorized parameters, letting us access - // vectorized arguments (anything not in this sequence is passed through) - // - BIndex is a incremental sequence (beginning at 0) of the same size as VIndex, so that - // we can store vectorized buffer_infos in an array (argument VIndex has its buffer at - // index BIndex in the array). - template object run( - typename vectorize_arg::type &...args, - index_sequence i_seq, index_sequence vi_seq, index_sequence bi_seq) { - - // Pointers to values the function was called with; the vectorized ones set here will start - // out as array_t pointers, but they will be changed them to T pointers before we make - // call the wrapped function. Non-vectorized pointers are left as-is. - std::array params{{ &args... }}; - - // The array of `buffer_info`s of vectorized arguments: - std::array buffers{{ reinterpret_cast(params[VIndex])->request()... }}; - - /* Determine dimensions parameters of output array */ - ssize_t nd = 0; - std::vector shape(0); - auto trivial = broadcast(buffers, nd, shape); - size_t ndim = (size_t) nd; - - size_t size = std::accumulate(shape.begin(), shape.end(), (size_t) 1, std::multiplies()); - - // If all arguments are 0-dimension arrays (i.e. single values) return a plain value (i.e. - // not wrapped in an array). - if (size == 1 && ndim == 0) { - PYBIND11_EXPAND_SIDE_EFFECTS(params[VIndex] = buffers[BIndex].ptr); - return cast(f(*reinterpret_cast *>(params[Index])...)); - } - - array_t result; - if (trivial == broadcast_trivial::f_trivial) result = array_t(shape); - else result = array_t(shape); - - if (size == 0) return result; - - /* Call the function */ - if (trivial == broadcast_trivial::non_trivial) - apply_broadcast(buffers, params, result, i_seq, vi_seq, bi_seq); - else - apply_trivial(buffers, params, result.mutable_data(), size, i_seq, vi_seq, bi_seq); - - return result; - } - - template - void apply_trivial(std::array &buffers, - std::array ¶ms, - Return *out, - size_t size, - index_sequence, index_sequence, index_sequence) { - - // Initialize an array of mutable byte references and sizes with references set to the - // appropriate pointer in `params`; as we iterate, we'll increment each pointer by its size - // (except for singletons, which get an increment of 0). - std::array, NVectorized> vecparams{{ - std::pair( - reinterpret_cast(params[VIndex] = buffers[BIndex].ptr), - buffers[BIndex].size == 1 ? 0 : sizeof(param_n_t) - )... - }}; - - for (size_t i = 0; i < size; ++i) { - out[i] = f(*reinterpret_cast *>(params[Index])...); - for (auto &x : vecparams) x.first += x.second; - } - } - - template - void apply_broadcast(std::array &buffers, - std::array ¶ms, - array_t &output_array, - index_sequence, index_sequence, index_sequence) { - - buffer_info output = output_array.request(); - multi_array_iterator input_iter(buffers, output.shape); - - for (array_iterator iter = array_begin(output), end = array_end(output); - iter != end; - ++iter, ++input_iter) { - PYBIND11_EXPAND_SIDE_EFFECTS(( - params[VIndex] = input_iter.template data() - )); - *iter = f(*reinterpret_cast *>(std::get(params))...); - } - } -}; - -template -vectorize_helper -vectorize_extractor(const Func &f, Return (*) (Args ...)) { - return detail::vectorize_helper(f); -} - -template struct handle_type_name> { - static constexpr auto name = _("numpy.ndarray[") + npy_format_descriptor::name + _("]"); -}; - -NAMESPACE_END(detail) - -// Vanilla pointer vectorizer: -template -detail::vectorize_helper -vectorize(Return (*f) (Args ...)) { - return detail::vectorize_helper(f); -} - -// lambda vectorizer: -template ::value, int> = 0> -auto vectorize(Func &&f) -> decltype( - detail::vectorize_extractor(std::forward(f), (detail::function_signature_t *) nullptr)) { - return detail::vectorize_extractor(std::forward(f), (detail::function_signature_t *) nullptr); -} - -// Vectorize a class method (non-const): -template ())), Return, Class *, Args...>> -Helper vectorize(Return (Class::*f)(Args...)) { - return Helper(std::mem_fn(f)); -} - -// Vectorize a class method (non-const): -template ())), Return, const Class *, Args...>> -Helper vectorize(Return (Class::*f)(Args...) const) { - return Helper(std::mem_fn(f)); -} - -NAMESPACE_END(PYBIND11_NAMESPACE) - -#if defined(_MSC_VER) -#pragma warning(pop) -#endif diff --git a/VFRendering/thirdparty/pybind11/include/pybind11/operators.h b/VFRendering/thirdparty/pybind11/include/pybind11/operators.h deleted file mode 100644 index b3dd62c3b..000000000 --- a/VFRendering/thirdparty/pybind11/include/pybind11/operators.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - pybind11/operator.h: Metatemplates for operator overloading - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "pybind11.h" - -#if defined(__clang__) && !defined(__INTEL_COMPILER) -# pragma clang diagnostic ignored "-Wunsequenced" // multiple unsequenced modifications to 'self' (when using def(py::self OP Type())) -#elif defined(_MSC_VER) -# pragma warning(push) -# pragma warning(disable: 4127) // warning C4127: Conditional expression is constant -#endif - -NAMESPACE_BEGIN(PYBIND11_NAMESPACE) -NAMESPACE_BEGIN(detail) - -/// Enumeration with all supported operator types -enum op_id : int { - op_add, op_sub, op_mul, op_div, op_mod, op_divmod, op_pow, op_lshift, - op_rshift, op_and, op_xor, op_or, op_neg, op_pos, op_abs, op_invert, - op_int, op_long, op_float, op_str, op_cmp, op_gt, op_ge, op_lt, op_le, - op_eq, op_ne, op_iadd, op_isub, op_imul, op_idiv, op_imod, op_ilshift, - op_irshift, op_iand, op_ixor, op_ior, op_complex, op_bool, op_nonzero, - op_repr, op_truediv, op_itruediv, op_hash -}; - -enum op_type : int { - op_l, /* base type on left */ - op_r, /* base type on right */ - op_u /* unary operator */ -}; - -struct self_t { }; -static const self_t self = self_t(); - -/// Type for an unused type slot -struct undefined_t { }; - -/// Don't warn about an unused variable -inline self_t __self() { return self; } - -/// base template of operator implementations -template struct op_impl { }; - -/// Operator implementation generator -template struct op_ { - template void execute(Class &cl, const Extra&... extra) const { - using Base = typename Class::type; - using L_type = conditional_t::value, Base, L>; - using R_type = conditional_t::value, Base, R>; - using op = op_impl; - cl.def(op::name(), &op::execute, is_operator(), extra...); - #if PY_MAJOR_VERSION < 3 - if (id == op_truediv || id == op_itruediv) - cl.def(id == op_itruediv ? "__idiv__" : ot == op_l ? "__div__" : "__rdiv__", - &op::execute, is_operator(), extra...); - #endif - } - template void execute_cast(Class &cl, const Extra&... extra) const { - using Base = typename Class::type; - using L_type = conditional_t::value, Base, L>; - using R_type = conditional_t::value, Base, R>; - using op = op_impl; - cl.def(op::name(), &op::execute_cast, is_operator(), extra...); - #if PY_MAJOR_VERSION < 3 - if (id == op_truediv || id == op_itruediv) - cl.def(id == op_itruediv ? "__idiv__" : ot == op_l ? "__div__" : "__rdiv__", - &op::execute, is_operator(), extra...); - #endif - } -}; - -#define PYBIND11_BINARY_OPERATOR(id, rid, op, expr) \ -template struct op_impl { \ - static char const* name() { return "__" #id "__"; } \ - static auto execute(const L &l, const R &r) -> decltype(expr) { return (expr); } \ - static B execute_cast(const L &l, const R &r) { return B(expr); } \ -}; \ -template struct op_impl { \ - static char const* name() { return "__" #rid "__"; } \ - static auto execute(const R &r, const L &l) -> decltype(expr) { return (expr); } \ - static B execute_cast(const R &r, const L &l) { return B(expr); } \ -}; \ -inline op_ op(const self_t &, const self_t &) { \ - return op_(); \ -} \ -template op_ op(const self_t &, const T &) { \ - return op_(); \ -} \ -template op_ op(const T &, const self_t &) { \ - return op_(); \ -} - -#define PYBIND11_INPLACE_OPERATOR(id, op, expr) \ -template struct op_impl { \ - static char const* name() { return "__" #id "__"; } \ - static auto execute(L &l, const R &r) -> decltype(expr) { return expr; } \ - static B execute_cast(L &l, const R &r) { return B(expr); } \ -}; \ -template op_ op(const self_t &, const T &) { \ - return op_(); \ -} - -#define PYBIND11_UNARY_OPERATOR(id, op, expr) \ -template struct op_impl { \ - static char const* name() { return "__" #id "__"; } \ - static auto execute(const L &l) -> decltype(expr) { return expr; } \ - static B execute_cast(const L &l) { return B(expr); } \ -}; \ -inline op_ op(const self_t &) { \ - return op_(); \ -} - -PYBIND11_BINARY_OPERATOR(sub, rsub, operator-, l - r) -PYBIND11_BINARY_OPERATOR(add, radd, operator+, l + r) -PYBIND11_BINARY_OPERATOR(mul, rmul, operator*, l * r) -PYBIND11_BINARY_OPERATOR(truediv, rtruediv, operator/, l / r) -PYBIND11_BINARY_OPERATOR(mod, rmod, operator%, l % r) -PYBIND11_BINARY_OPERATOR(lshift, rlshift, operator<<, l << r) -PYBIND11_BINARY_OPERATOR(rshift, rrshift, operator>>, l >> r) -PYBIND11_BINARY_OPERATOR(and, rand, operator&, l & r) -PYBIND11_BINARY_OPERATOR(xor, rxor, operator^, l ^ r) -PYBIND11_BINARY_OPERATOR(eq, eq, operator==, l == r) -PYBIND11_BINARY_OPERATOR(ne, ne, operator!=, l != r) -PYBIND11_BINARY_OPERATOR(or, ror, operator|, l | r) -PYBIND11_BINARY_OPERATOR(gt, lt, operator>, l > r) -PYBIND11_BINARY_OPERATOR(ge, le, operator>=, l >= r) -PYBIND11_BINARY_OPERATOR(lt, gt, operator<, l < r) -PYBIND11_BINARY_OPERATOR(le, ge, operator<=, l <= r) -//PYBIND11_BINARY_OPERATOR(pow, rpow, pow, std::pow(l, r)) -PYBIND11_INPLACE_OPERATOR(iadd, operator+=, l += r) -PYBIND11_INPLACE_OPERATOR(isub, operator-=, l -= r) -PYBIND11_INPLACE_OPERATOR(imul, operator*=, l *= r) -PYBIND11_INPLACE_OPERATOR(itruediv, operator/=, l /= r) -PYBIND11_INPLACE_OPERATOR(imod, operator%=, l %= r) -PYBIND11_INPLACE_OPERATOR(ilshift, operator<<=, l <<= r) -PYBIND11_INPLACE_OPERATOR(irshift, operator>>=, l >>= r) -PYBIND11_INPLACE_OPERATOR(iand, operator&=, l &= r) -PYBIND11_INPLACE_OPERATOR(ixor, operator^=, l ^= r) -PYBIND11_INPLACE_OPERATOR(ior, operator|=, l |= r) -PYBIND11_UNARY_OPERATOR(neg, operator-, -l) -PYBIND11_UNARY_OPERATOR(pos, operator+, +l) -PYBIND11_UNARY_OPERATOR(abs, abs, std::abs(l)) -PYBIND11_UNARY_OPERATOR(hash, hash, std::hash()(l)) -PYBIND11_UNARY_OPERATOR(invert, operator~, (~l)) -PYBIND11_UNARY_OPERATOR(bool, operator!, !!l) -PYBIND11_UNARY_OPERATOR(int, int_, (int) l) -PYBIND11_UNARY_OPERATOR(float, float_, (double) l) - -#undef PYBIND11_BINARY_OPERATOR -#undef PYBIND11_INPLACE_OPERATOR -#undef PYBIND11_UNARY_OPERATOR -NAMESPACE_END(detail) - -using detail::self; - -NAMESPACE_END(PYBIND11_NAMESPACE) - -#if defined(_MSC_VER) -# pragma warning(pop) -#endif diff --git a/VFRendering/thirdparty/pybind11/include/pybind11/options.h b/VFRendering/thirdparty/pybind11/include/pybind11/options.h deleted file mode 100644 index cc1e1f6f0..000000000 --- a/VFRendering/thirdparty/pybind11/include/pybind11/options.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - pybind11/options.h: global settings that are configurable at runtime. - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "detail/common.h" - -NAMESPACE_BEGIN(PYBIND11_NAMESPACE) - -class options { -public: - - // Default RAII constructor, which leaves settings as they currently are. - options() : previous_state(global_state()) {} - - // Class is non-copyable. - options(const options&) = delete; - options& operator=(const options&) = delete; - - // Destructor, which restores settings that were in effect before. - ~options() { - global_state() = previous_state; - } - - // Setter methods (affect the global state): - - options& disable_user_defined_docstrings() & { global_state().show_user_defined_docstrings = false; return *this; } - - options& enable_user_defined_docstrings() & { global_state().show_user_defined_docstrings = true; return *this; } - - options& disable_function_signatures() & { global_state().show_function_signatures = false; return *this; } - - options& enable_function_signatures() & { global_state().show_function_signatures = true; return *this; } - - // Getter methods (return the global state): - - static bool show_user_defined_docstrings() { return global_state().show_user_defined_docstrings; } - - static bool show_function_signatures() { return global_state().show_function_signatures; } - - // This type is not meant to be allocated on the heap. - void* operator new(size_t) = delete; - -private: - - struct state { - bool show_user_defined_docstrings = true; //< Include user-supplied texts in docstrings. - bool show_function_signatures = true; //< Include auto-generated function signatures in docstrings. - }; - - static state &global_state() { - static state instance; - return instance; - } - - state previous_state; -}; - -NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/VFRendering/thirdparty/pybind11/include/pybind11/pybind11.h b/VFRendering/thirdparty/pybind11/include/pybind11/pybind11.h deleted file mode 100644 index 82f8a481f..000000000 --- a/VFRendering/thirdparty/pybind11/include/pybind11/pybind11.h +++ /dev/null @@ -1,1982 +0,0 @@ -/* - pybind11/pybind11.h: Main header file of the C++11 python - binding generator library - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#if defined(_MSC_VER) -# pragma warning(push) -# pragma warning(disable: 4100) // warning C4100: Unreferenced formal parameter -# pragma warning(disable: 4127) // warning C4127: Conditional expression is constant -# pragma warning(disable: 4512) // warning C4512: Assignment operator was implicitly defined as deleted -# pragma warning(disable: 4800) // warning C4800: 'int': forcing value to bool 'true' or 'false' (performance warning) -# pragma warning(disable: 4996) // warning C4996: The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name -# pragma warning(disable: 4702) // warning C4702: unreachable code -# pragma warning(disable: 4522) // warning C4522: multiple assignment operators specified -#elif defined(__INTEL_COMPILER) -# pragma warning(push) -# pragma warning(disable: 68) // integer conversion resulted in a change of sign -# pragma warning(disable: 186) // pointless comparison of unsigned integer with zero -# pragma warning(disable: 878) // incompatible exception specifications -# pragma warning(disable: 1334) // the "template" keyword used for syntactic disambiguation may only be used within a template -# pragma warning(disable: 1682) // implicit conversion of a 64-bit integral type to a smaller integral type (potential portability problem) -# pragma warning(disable: 1875) // offsetof applied to non-POD (Plain Old Data) types is nonstandard -# pragma warning(disable: 2196) // warning #2196: routine is both "inline" and "noinline" -#elif defined(__GNUG__) && !defined(__clang__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wunused-but-set-parameter" -# pragma GCC diagnostic ignored "-Wunused-but-set-variable" -# pragma GCC diagnostic ignored "-Wmissing-field-initializers" -# pragma GCC diagnostic ignored "-Wstrict-aliasing" -# pragma GCC diagnostic ignored "-Wattributes" -# if __GNUC__ >= 7 -# pragma GCC diagnostic ignored "-Wnoexcept-type" -# endif -#endif - -#include "attr.h" -#include "options.h" -#include "detail/class.h" -#include "detail/init.h" - -NAMESPACE_BEGIN(PYBIND11_NAMESPACE) - -/// Wraps an arbitrary C++ function/method/lambda function/.. into a callable Python object -class cpp_function : public function { -public: - cpp_function() { } - cpp_function(std::nullptr_t) { } - - /// Construct a cpp_function from a vanilla function pointer - template - cpp_function(Return (*f)(Args...), const Extra&... extra) { - initialize(f, f, extra...); - } - - /// Construct a cpp_function from a lambda function (possibly with internal state) - template ::value>> - cpp_function(Func &&f, const Extra&... extra) { - initialize(std::forward(f), - (detail::function_signature_t *) nullptr, extra...); - } - - /// Construct a cpp_function from a class method (non-const) - template - cpp_function(Return (Class::*f)(Arg...), const Extra&... extra) { - initialize([f](Class *c, Arg... args) -> Return { return (c->*f)(args...); }, - (Return (*) (Class *, Arg...)) nullptr, extra...); - } - - /// Construct a cpp_function from a class method (const) - template - cpp_function(Return (Class::*f)(Arg...) const, const Extra&... extra) { - initialize([f](const Class *c, Arg... args) -> Return { return (c->*f)(args...); }, - (Return (*)(const Class *, Arg ...)) nullptr, extra...); - } - - /// Return the function name - object name() const { return attr("__name__"); } - -protected: - /// Space optimization: don't inline this frequently instantiated fragment - PYBIND11_NOINLINE detail::function_record *make_function_record() { - return new detail::function_record(); - } - - /// Special internal constructor for functors, lambda functions, etc. - template - void initialize(Func &&f, Return (*)(Args...), const Extra&... extra) { - using namespace detail; - struct capture { detail::remove_reference_t f; }; - - /* Store the function including any extra state it might have (e.g. a lambda capture object) */ - auto rec = make_function_record(); - - /* Store the capture object directly in the function record if there is enough space */ - if (sizeof(capture) <= sizeof(rec->data)) { - /* Without these pragmas, GCC warns that there might not be - enough space to use the placement new operator. However, the - 'if' statement above ensures that this is the case. */ -#if defined(__GNUG__) && !defined(__clang__) && __GNUC__ >= 6 -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wplacement-new" -#endif - new ((capture *) &rec->data) capture { std::forward(f) }; -#if defined(__GNUG__) && !defined(__clang__) && __GNUC__ >= 6 -# pragma GCC diagnostic pop -#endif - if (!std::is_trivially_destructible::value) - rec->free_data = [](detail::function_record *r) { ((capture *) &r->data)->~capture(); }; - } else { - rec->data[0] = new capture { std::forward(f) }; - rec->free_data = [](detail::function_record *r) { delete ((capture *) r->data[0]); }; - } - - /* Type casters for the function arguments and return value */ - using cast_in = detail::argument_loader; - using cast_out = detail::make_caster< - detail::conditional_t::value, detail::void_type, Return> - >; - - static_assert(detail::expected_num_args(sizeof...(Args), cast_in::has_args, cast_in::has_kwargs), - "The number of argument annotations does not match the number of function arguments"); - - /* Dispatch code which converts function arguments and performs the actual function call */ - rec->impl = [](detail::function_call &call) -> handle { - cast_in args_converter; - - /* Try to cast the function arguments into the C++ domain */ - if (!args_converter.load_args(call)) - return PYBIND11_TRY_NEXT_OVERLOAD; - - /* Invoke call policy pre-call hook */ - detail::process_attributes::precall(call); - - /* Get a pointer to the capture object */ - auto data = (sizeof(capture) <= sizeof(call.func.data) - ? &call.func.data : call.func.data[0]); - capture *cap = const_cast(reinterpret_cast(data)); - - /* Override policy for rvalues -- usually to enforce rvp::move on an rvalue */ - const auto policy = detail::return_value_policy_override::policy(call.func.policy); - - /* Function scope guard -- defaults to the compile-to-nothing `void_type` */ - using Guard = detail::extract_guard_t; - - /* Perform the function call */ - handle result = cast_out::cast( - std::move(args_converter).template call(cap->f), policy, call.parent); - - /* Invoke call policy post-call hook */ - detail::process_attributes::postcall(call, result); - - return result; - }; - - /* Process any user-provided function attributes */ - detail::process_attributes::init(extra..., rec); - - /* Generate a readable signature describing the function's arguments and return value types */ - static constexpr auto signature = _("(") + cast_in::arg_names + _(") -> ") + cast_out::name; - PYBIND11_DESCR_CONSTEXPR auto types = decltype(signature)::types(); - - /* Register the function with Python from generic (non-templated) code */ - initialize_generic(rec, signature.text, types.data(), sizeof...(Args)); - - if (cast_in::has_args) rec->has_args = true; - if (cast_in::has_kwargs) rec->has_kwargs = true; - - /* Stash some additional information used by an important optimization in 'functional.h' */ - using FunctionType = Return (*)(Args...); - constexpr bool is_function_ptr = - std::is_convertible::value && - sizeof(capture) == sizeof(void *); - if (is_function_ptr) { - rec->is_stateless = true; - rec->data[1] = const_cast(reinterpret_cast(&typeid(FunctionType))); - } - } - - /// Register a function call with Python (generic non-templated code goes here) - void initialize_generic(detail::function_record *rec, const char *text, - const std::type_info *const *types, size_t args) { - - /* Create copies of all referenced C-style strings */ - rec->name = strdup(rec->name ? rec->name : ""); - if (rec->doc) rec->doc = strdup(rec->doc); - for (auto &a: rec->args) { - if (a.name) - a.name = strdup(a.name); - if (a.descr) - a.descr = strdup(a.descr); - else if (a.value) - a.descr = strdup(a.value.attr("__repr__")().cast().c_str()); - } - - rec->is_constructor = !strcmp(rec->name, "__init__") || !strcmp(rec->name, "__setstate__"); - -#if !defined(NDEBUG) && !defined(PYBIND11_DISABLE_NEW_STYLE_INIT_WARNING) - if (rec->is_constructor && !rec->is_new_style_constructor) { - const auto class_name = std::string(((PyTypeObject *) rec->scope.ptr())->tp_name); - const auto func_name = std::string(rec->name); - PyErr_WarnEx( - PyExc_FutureWarning, - ("pybind11-bound class '" + class_name + "' is using an old-style " - "placement-new '" + func_name + "' which has been deprecated. See " - "the upgrade guide in pybind11's docs. This message is only visible " - "when compiled in debug mode.").c_str(), 0 - ); - } -#endif - - /* Generate a proper function signature */ - std::string signature; - size_t type_index = 0, arg_index = 0; - for (auto *pc = text; *pc != '\0'; ++pc) { - const auto c = *pc; - - if (c == '{') { - // Write arg name for everything except *args and **kwargs. - if (*(pc + 1) == '*') - continue; - - if (arg_index < rec->args.size() && rec->args[arg_index].name) { - signature += rec->args[arg_index].name; - } else if (arg_index == 0 && rec->is_method) { - signature += "self"; - } else { - signature += "arg" + std::to_string(arg_index - (rec->is_method ? 1 : 0)); - } - signature += ": "; - } else if (c == '}') { - // Write default value if available. - if (arg_index < rec->args.size() && rec->args[arg_index].descr) { - signature += " = "; - signature += rec->args[arg_index].descr; - } - arg_index++; - } else if (c == '%') { - const std::type_info *t = types[type_index++]; - if (!t) - pybind11_fail("Internal error while parsing type signature (1)"); - if (auto tinfo = detail::get_type_info(*t)) { - handle th((PyObject *) tinfo->type); - signature += - th.attr("__module__").cast() + "." + - th.attr("__qualname__").cast(); // Python 3.3+, but we backport it to earlier versions - } else if (rec->is_new_style_constructor && arg_index == 0) { - // A new-style `__init__` takes `self` as `value_and_holder`. - // Rewrite it to the proper class type. - signature += - rec->scope.attr("__module__").cast() + "." + - rec->scope.attr("__qualname__").cast(); - } else { - std::string tname(t->name()); - detail::clean_type_id(tname); - signature += tname; - } - } else { - signature += c; - } - } - if (arg_index != args || types[type_index] != nullptr) - pybind11_fail("Internal error while parsing type signature (2)"); - -#if PY_MAJOR_VERSION < 3 - if (strcmp(rec->name, "__next__") == 0) { - std::free(rec->name); - rec->name = strdup("next"); - } else if (strcmp(rec->name, "__bool__") == 0) { - std::free(rec->name); - rec->name = strdup("__nonzero__"); - } -#endif - rec->signature = strdup(signature.c_str()); - rec->args.shrink_to_fit(); - rec->nargs = (std::uint16_t) args; - - if (rec->sibling && PYBIND11_INSTANCE_METHOD_CHECK(rec->sibling.ptr())) - rec->sibling = PYBIND11_INSTANCE_METHOD_GET_FUNCTION(rec->sibling.ptr()); - - detail::function_record *chain = nullptr, *chain_start = rec; - if (rec->sibling) { - if (PyCFunction_Check(rec->sibling.ptr())) { - auto rec_capsule = reinterpret_borrow(PyCFunction_GET_SELF(rec->sibling.ptr())); - chain = (detail::function_record *) rec_capsule; - /* Never append a method to an overload chain of a parent class; - instead, hide the parent's overloads in this case */ - if (!chain->scope.is(rec->scope)) - chain = nullptr; - } - // Don't trigger for things like the default __init__, which are wrapper_descriptors that we are intentionally replacing - else if (!rec->sibling.is_none() && rec->name[0] != '_') - pybind11_fail("Cannot overload existing non-function object \"" + std::string(rec->name) + - "\" with a function of the same name"); - } - - if (!chain) { - /* No existing overload was found, create a new function object */ - rec->def = new PyMethodDef(); - std::memset(rec->def, 0, sizeof(PyMethodDef)); - rec->def->ml_name = rec->name; - rec->def->ml_meth = reinterpret_cast(*dispatcher); - rec->def->ml_flags = METH_VARARGS | METH_KEYWORDS; - - capsule rec_capsule(rec, [](void *ptr) { - destruct((detail::function_record *) ptr); - }); - - object scope_module; - if (rec->scope) { - if (hasattr(rec->scope, "__module__")) { - scope_module = rec->scope.attr("__module__"); - } else if (hasattr(rec->scope, "__name__")) { - scope_module = rec->scope.attr("__name__"); - } - } - - m_ptr = PyCFunction_NewEx(rec->def, rec_capsule.ptr(), scope_module.ptr()); - if (!m_ptr) - pybind11_fail("cpp_function::cpp_function(): Could not allocate function object"); - } else { - /* Append at the end of the overload chain */ - m_ptr = rec->sibling.ptr(); - inc_ref(); - chain_start = chain; - if (chain->is_method != rec->is_method) - pybind11_fail("overloading a method with both static and instance methods is not supported; " - #if defined(NDEBUG) - "compile in debug mode for more details" - #else - "error while attempting to bind " + std::string(rec->is_method ? "instance" : "static") + " method " + - std::string(pybind11::str(rec->scope.attr("__name__"))) + "." + std::string(rec->name) + signature - #endif - ); - while (chain->next) - chain = chain->next; - chain->next = rec; - } - - std::string signatures; - int index = 0; - /* Create a nice pydoc rec including all signatures and - docstrings of the functions in the overload chain */ - if (chain && options::show_function_signatures()) { - // First a generic signature - signatures += rec->name; - signatures += "(*args, **kwargs)\n"; - signatures += "Overloaded function.\n\n"; - } - // Then specific overload signatures - bool first_user_def = true; - for (auto it = chain_start; it != nullptr; it = it->next) { - if (options::show_function_signatures()) { - if (index > 0) signatures += "\n"; - if (chain) - signatures += std::to_string(++index) + ". "; - signatures += rec->name; - signatures += it->signature; - signatures += "\n"; - } - if (it->doc && strlen(it->doc) > 0 && options::show_user_defined_docstrings()) { - // If we're appending another docstring, and aren't printing function signatures, we - // need to append a newline first: - if (!options::show_function_signatures()) { - if (first_user_def) first_user_def = false; - else signatures += "\n"; - } - if (options::show_function_signatures()) signatures += "\n"; - signatures += it->doc; - if (options::show_function_signatures()) signatures += "\n"; - } - } - - /* Install docstring */ - PyCFunctionObject *func = (PyCFunctionObject *) m_ptr; - if (func->m_ml->ml_doc) - std::free(const_cast(func->m_ml->ml_doc)); - func->m_ml->ml_doc = strdup(signatures.c_str()); - - if (rec->is_method) { - m_ptr = PYBIND11_INSTANCE_METHOD_NEW(m_ptr, rec->scope.ptr()); - if (!m_ptr) - pybind11_fail("cpp_function::cpp_function(): Could not allocate instance method object"); - Py_DECREF(func); - } - } - - /// When a cpp_function is GCed, release any memory allocated by pybind11 - static void destruct(detail::function_record *rec) { - while (rec) { - detail::function_record *next = rec->next; - if (rec->free_data) - rec->free_data(rec); - std::free((char *) rec->name); - std::free((char *) rec->doc); - std::free((char *) rec->signature); - for (auto &arg: rec->args) { - std::free(const_cast(arg.name)); - std::free(const_cast(arg.descr)); - arg.value.dec_ref(); - } - if (rec->def) { - std::free(const_cast(rec->def->ml_doc)); - delete rec->def; - } - delete rec; - rec = next; - } - } - - /// Main dispatch logic for calls to functions bound using pybind11 - static PyObject *dispatcher(PyObject *self, PyObject *args_in, PyObject *kwargs_in) { - using namespace detail; - - /* Iterator over the list of potentially admissible overloads */ - function_record *overloads = (function_record *) PyCapsule_GetPointer(self, nullptr), - *it = overloads; - - /* Need to know how many arguments + keyword arguments there are to pick the right overload */ - const size_t n_args_in = (size_t) PyTuple_GET_SIZE(args_in); - - handle parent = n_args_in > 0 ? PyTuple_GET_ITEM(args_in, 0) : nullptr, - result = PYBIND11_TRY_NEXT_OVERLOAD; - - auto self_value_and_holder = value_and_holder(); - if (overloads->is_constructor) { - const auto tinfo = get_type_info((PyTypeObject *) overloads->scope.ptr()); - const auto pi = reinterpret_cast(parent.ptr()); - self_value_and_holder = pi->get_value_and_holder(tinfo, false); - - if (!self_value_and_holder.type || !self_value_and_holder.inst) { - PyErr_SetString(PyExc_TypeError, "__init__(self, ...) called with invalid `self` argument"); - return nullptr; - } - - // If this value is already registered it must mean __init__ is invoked multiple times; - // we really can't support that in C++, so just ignore the second __init__. - if (self_value_and_holder.instance_registered()) - return none().release().ptr(); - } - - try { - // We do this in two passes: in the first pass, we load arguments with `convert=false`; - // in the second, we allow conversion (except for arguments with an explicit - // py::arg().noconvert()). This lets us prefer calls without conversion, with - // conversion as a fallback. - std::vector second_pass; - - // However, if there are no overloads, we can just skip the no-convert pass entirely - const bool overloaded = it != nullptr && it->next != nullptr; - - for (; it != nullptr; it = it->next) { - - /* For each overload: - 1. Copy all positional arguments we were given, also checking to make sure that - named positional arguments weren't *also* specified via kwarg. - 2. If we weren't given enough, try to make up the omitted ones by checking - whether they were provided by a kwarg matching the `py::arg("name")` name. If - so, use it (and remove it from kwargs; if not, see if the function binding - provided a default that we can use. - 3. Ensure that either all keyword arguments were "consumed", or that the function - takes a kwargs argument to accept unconsumed kwargs. - 4. Any positional arguments still left get put into a tuple (for args), and any - leftover kwargs get put into a dict. - 5. Pack everything into a vector; if we have py::args or py::kwargs, they are an - extra tuple or dict at the end of the positional arguments. - 6. Call the function call dispatcher (function_record::impl) - - If one of these fail, move on to the next overload and keep trying until we get a - result other than PYBIND11_TRY_NEXT_OVERLOAD. - */ - - function_record &func = *it; - size_t pos_args = func.nargs; // Number of positional arguments that we need - if (func.has_args) --pos_args; // (but don't count py::args - if (func.has_kwargs) --pos_args; // or py::kwargs) - - if (!func.has_args && n_args_in > pos_args) - continue; // Too many arguments for this overload - - if (n_args_in < pos_args && func.args.size() < pos_args) - continue; // Not enough arguments given, and not enough defaults to fill in the blanks - - function_call call(func, parent); - - size_t args_to_copy = std::min(pos_args, n_args_in); - size_t args_copied = 0; - - // 0. Inject new-style `self` argument - if (func.is_new_style_constructor) { - // The `value` may have been preallocated by an old-style `__init__` - // if it was a preceding candidate for overload resolution. - if (self_value_and_holder) - self_value_and_holder.type->dealloc(self_value_and_holder); - - call.init_self = PyTuple_GET_ITEM(args_in, 0); - call.args.push_back(reinterpret_cast(&self_value_and_holder)); - call.args_convert.push_back(false); - ++args_copied; - } - - // 1. Copy any position arguments given. - bool bad_arg = false; - for (; args_copied < args_to_copy; ++args_copied) { - argument_record *arg_rec = args_copied < func.args.size() ? &func.args[args_copied] : nullptr; - if (kwargs_in && arg_rec && arg_rec->name && PyDict_GetItemString(kwargs_in, arg_rec->name)) { - bad_arg = true; - break; - } - - handle arg(PyTuple_GET_ITEM(args_in, args_copied)); - if (arg_rec && !arg_rec->none && arg.is_none()) { - bad_arg = true; - break; - } - call.args.push_back(arg); - call.args_convert.push_back(arg_rec ? arg_rec->convert : true); - } - if (bad_arg) - continue; // Maybe it was meant for another overload (issue #688) - - // We'll need to copy this if we steal some kwargs for defaults - dict kwargs = reinterpret_borrow(kwargs_in); - - // 2. Check kwargs and, failing that, defaults that may help complete the list - if (args_copied < pos_args) { - bool copied_kwargs = false; - - for (; args_copied < pos_args; ++args_copied) { - const auto &arg = func.args[args_copied]; - - handle value; - if (kwargs_in && arg.name) - value = PyDict_GetItemString(kwargs.ptr(), arg.name); - - if (value) { - // Consume a kwargs value - if (!copied_kwargs) { - kwargs = reinterpret_steal(PyDict_Copy(kwargs.ptr())); - copied_kwargs = true; - } - PyDict_DelItemString(kwargs.ptr(), arg.name); - } else if (arg.value) { - value = arg.value; - } - - if (value) { - call.args.push_back(value); - call.args_convert.push_back(arg.convert); - } - else - break; - } - - if (args_copied < pos_args) - continue; // Not enough arguments, defaults, or kwargs to fill the positional arguments - } - - // 3. Check everything was consumed (unless we have a kwargs arg) - if (kwargs && kwargs.size() > 0 && !func.has_kwargs) - continue; // Unconsumed kwargs, but no py::kwargs argument to accept them - - // 4a. If we have a py::args argument, create a new tuple with leftovers - if (func.has_args) { - tuple extra_args; - if (args_to_copy == 0) { - // We didn't copy out any position arguments from the args_in tuple, so we - // can reuse it directly without copying: - extra_args = reinterpret_borrow(args_in); - } else if (args_copied >= n_args_in) { - extra_args = tuple(0); - } else { - size_t args_size = n_args_in - args_copied; - extra_args = tuple(args_size); - for (size_t i = 0; i < args_size; ++i) { - extra_args[i] = PyTuple_GET_ITEM(args_in, args_copied + i); - } - } - call.args.push_back(extra_args); - call.args_convert.push_back(false); - call.args_ref = std::move(extra_args); - } - - // 4b. If we have a py::kwargs, pass on any remaining kwargs - if (func.has_kwargs) { - if (!kwargs.ptr()) - kwargs = dict(); // If we didn't get one, send an empty one - call.args.push_back(kwargs); - call.args_convert.push_back(false); - call.kwargs_ref = std::move(kwargs); - } - - // 5. Put everything in a vector. Not technically step 5, we've been building it - // in `call.args` all along. - #if !defined(NDEBUG) - if (call.args.size() != func.nargs || call.args_convert.size() != func.nargs) - pybind11_fail("Internal error: function call dispatcher inserted wrong number of arguments!"); - #endif - - std::vector second_pass_convert; - if (overloaded) { - // We're in the first no-convert pass, so swap out the conversion flags for a - // set of all-false flags. If the call fails, we'll swap the flags back in for - // the conversion-allowed call below. - second_pass_convert.resize(func.nargs, false); - call.args_convert.swap(second_pass_convert); - } - - // 6. Call the function. - try { - loader_life_support guard{}; - result = func.impl(call); - } catch (reference_cast_error &) { - result = PYBIND11_TRY_NEXT_OVERLOAD; - } - - if (result.ptr() != PYBIND11_TRY_NEXT_OVERLOAD) - break; - - if (overloaded) { - // The (overloaded) call failed; if the call has at least one argument that - // permits conversion (i.e. it hasn't been explicitly specified `.noconvert()`) - // then add this call to the list of second pass overloads to try. - for (size_t i = func.is_method ? 1 : 0; i < pos_args; i++) { - if (second_pass_convert[i]) { - // Found one: swap the converting flags back in and store the call for - // the second pass. - call.args_convert.swap(second_pass_convert); - second_pass.push_back(std::move(call)); - break; - } - } - } - } - - if (overloaded && !second_pass.empty() && result.ptr() == PYBIND11_TRY_NEXT_OVERLOAD) { - // The no-conversion pass finished without success, try again with conversion allowed - for (auto &call : second_pass) { - try { - loader_life_support guard{}; - result = call.func.impl(call); - } catch (reference_cast_error &) { - result = PYBIND11_TRY_NEXT_OVERLOAD; - } - - if (result.ptr() != PYBIND11_TRY_NEXT_OVERLOAD) - break; - } - } - } catch (error_already_set &e) { - e.restore(); - return nullptr; - } catch (...) { - /* When an exception is caught, give each registered exception - translator a chance to translate it to a Python exception - in reverse order of registration. - - A translator may choose to do one of the following: - - - catch the exception and call PyErr_SetString or PyErr_SetObject - to set a standard (or custom) Python exception, or - - do nothing and let the exception fall through to the next translator, or - - delegate translation to the next translator by throwing a new type of exception. */ - - auto last_exception = std::current_exception(); - auto ®istered_exception_translators = get_internals().registered_exception_translators; - for (auto& translator : registered_exception_translators) { - try { - translator(last_exception); - } catch (...) { - last_exception = std::current_exception(); - continue; - } - return nullptr; - } - PyErr_SetString(PyExc_SystemError, "Exception escaped from default exception translator!"); - return nullptr; - } - - auto append_note_if_missing_header_is_suspected = [](std::string &msg) { - if (msg.find("std::") != std::string::npos) { - msg += "\n\n" - "Did you forget to `#include `? Or ,\n" - ", , etc. Some automatic\n" - "conversions are optional and require extra headers to be included\n" - "when compiling your pybind11 module."; - } - }; - - if (result.ptr() == PYBIND11_TRY_NEXT_OVERLOAD) { - if (overloads->is_operator) - return handle(Py_NotImplemented).inc_ref().ptr(); - - std::string msg = std::string(overloads->name) + "(): incompatible " + - std::string(overloads->is_constructor ? "constructor" : "function") + - " arguments. The following argument types are supported:\n"; - - int ctr = 0; - for (function_record *it2 = overloads; it2 != nullptr; it2 = it2->next) { - msg += " "+ std::to_string(++ctr) + ". "; - - bool wrote_sig = false; - if (overloads->is_constructor) { - // For a constructor, rewrite `(self: Object, arg0, ...) -> NoneType` as `Object(arg0, ...)` - std::string sig = it2->signature; - size_t start = sig.find('(') + 7; // skip "(self: " - if (start < sig.size()) { - // End at the , for the next argument - size_t end = sig.find(", "), next = end + 2; - size_t ret = sig.rfind(" -> "); - // Or the ), if there is no comma: - if (end >= sig.size()) next = end = sig.find(')'); - if (start < end && next < sig.size()) { - msg.append(sig, start, end - start); - msg += '('; - msg.append(sig, next, ret - next); - wrote_sig = true; - } - } - } - if (!wrote_sig) msg += it2->signature; - - msg += "\n"; - } - msg += "\nInvoked with: "; - auto args_ = reinterpret_borrow(args_in); - bool some_args = false; - for (size_t ti = overloads->is_constructor ? 1 : 0; ti < args_.size(); ++ti) { - if (!some_args) some_args = true; - else msg += ", "; - msg += pybind11::repr(args_[ti]); - } - if (kwargs_in) { - auto kwargs = reinterpret_borrow(kwargs_in); - if (kwargs.size() > 0) { - if (some_args) msg += "; "; - msg += "kwargs: "; - bool first = true; - for (auto kwarg : kwargs) { - if (first) first = false; - else msg += ", "; - msg += pybind11::str("{}={!r}").format(kwarg.first, kwarg.second); - } - } - } - - append_note_if_missing_header_is_suspected(msg); - PyErr_SetString(PyExc_TypeError, msg.c_str()); - return nullptr; - } else if (!result) { - std::string msg = "Unable to convert function return value to a " - "Python type! The signature was\n\t"; - msg += it->signature; - append_note_if_missing_header_is_suspected(msg); - PyErr_SetString(PyExc_TypeError, msg.c_str()); - return nullptr; - } else { - if (overloads->is_constructor && !self_value_and_holder.holder_constructed()) { - auto *pi = reinterpret_cast(parent.ptr()); - self_value_and_holder.type->init_instance(pi, nullptr); - } - return result.ptr(); - } - } -}; - -/// Wrapper for Python extension modules -class module : public object { -public: - PYBIND11_OBJECT_DEFAULT(module, object, PyModule_Check) - - /// Create a new top-level Python module with the given name and docstring - explicit module(const char *name, const char *doc = nullptr) { - if (!options::show_user_defined_docstrings()) doc = nullptr; -#if PY_MAJOR_VERSION >= 3 - PyModuleDef *def = new PyModuleDef(); - std::memset(def, 0, sizeof(PyModuleDef)); - def->m_name = name; - def->m_doc = doc; - def->m_size = -1; - Py_INCREF(def); - m_ptr = PyModule_Create(def); -#else - m_ptr = Py_InitModule3(name, nullptr, doc); -#endif - if (m_ptr == nullptr) - pybind11_fail("Internal error in module::module()"); - inc_ref(); - } - - /** \rst - Create Python binding for a new function within the module scope. ``Func`` - can be a plain C++ function, a function pointer, or a lambda function. For - details on the ``Extra&& ... extra`` argument, see section :ref:`extras`. - \endrst */ - template - module &def(const char *name_, Func &&f, const Extra& ... extra) { - cpp_function func(std::forward(f), name(name_), scope(*this), - sibling(getattr(*this, name_, none())), extra...); - // NB: allow overwriting here because cpp_function sets up a chain with the intention of - // overwriting (and has already checked internally that it isn't overwriting non-functions). - add_object(name_, func, true /* overwrite */); - return *this; - } - - /** \rst - Create and return a new Python submodule with the given name and docstring. - This also works recursively, i.e. - - .. code-block:: cpp - - py::module m("example", "pybind11 example plugin"); - py::module m2 = m.def_submodule("sub", "A submodule of 'example'"); - py::module m3 = m2.def_submodule("subsub", "A submodule of 'example.sub'"); - \endrst */ - module def_submodule(const char *name, const char *doc = nullptr) { - std::string full_name = std::string(PyModule_GetName(m_ptr)) - + std::string(".") + std::string(name); - auto result = reinterpret_borrow(PyImport_AddModule(full_name.c_str())); - if (doc && options::show_user_defined_docstrings()) - result.attr("__doc__") = pybind11::str(doc); - attr(name) = result; - return result; - } - - /// Import and return a module or throws `error_already_set`. - static module import(const char *name) { - PyObject *obj = PyImport_ImportModule(name); - if (!obj) - throw error_already_set(); - return reinterpret_steal(obj); - } - - /// Reload the module or throws `error_already_set`. - void reload() { - PyObject *obj = PyImport_ReloadModule(ptr()); - if (!obj) - throw error_already_set(); - *this = reinterpret_steal(obj); - } - - // Adds an object to the module using the given name. Throws if an object with the given name - // already exists. - // - // overwrite should almost always be false: attempting to overwrite objects that pybind11 has - // established will, in most cases, break things. - PYBIND11_NOINLINE void add_object(const char *name, handle obj, bool overwrite = false) { - if (!overwrite && hasattr(*this, name)) - pybind11_fail("Error during initialization: multiple incompatible definitions with name \"" + - std::string(name) + "\""); - - PyModule_AddObject(ptr(), name, obj.inc_ref().ptr() /* steals a reference */); - } -}; - -/// \ingroup python_builtins -/// Return a dictionary representing the global variables in the current execution frame, -/// or ``__main__.__dict__`` if there is no frame (usually when the interpreter is embedded). -inline dict globals() { - PyObject *p = PyEval_GetGlobals(); - return reinterpret_borrow(p ? p : module::import("__main__").attr("__dict__").ptr()); -} - -NAMESPACE_BEGIN(detail) -/// Generic support for creating new Python heap types -class generic_type : public object { - template friend class class_; -public: - PYBIND11_OBJECT_DEFAULT(generic_type, object, PyType_Check) -protected: - void initialize(const type_record &rec) { - if (rec.scope && hasattr(rec.scope, rec.name)) - pybind11_fail("generic_type: cannot initialize type \"" + std::string(rec.name) + - "\": an object with that name is already defined"); - - if (rec.module_local ? get_local_type_info(*rec.type) : get_global_type_info(*rec.type)) - pybind11_fail("generic_type: type \"" + std::string(rec.name) + - "\" is already registered!"); - - m_ptr = make_new_python_type(rec); - - /* Register supplemental type information in C++ dict */ - auto *tinfo = new detail::type_info(); - tinfo->type = (PyTypeObject *) m_ptr; - tinfo->cpptype = rec.type; - tinfo->type_size = rec.type_size; - tinfo->operator_new = rec.operator_new; - tinfo->holder_size_in_ptrs = size_in_ptrs(rec.holder_size); - tinfo->init_instance = rec.init_instance; - tinfo->dealloc = rec.dealloc; - tinfo->simple_type = true; - tinfo->simple_ancestors = true; - tinfo->default_holder = rec.default_holder; - tinfo->module_local = rec.module_local; - - auto &internals = get_internals(); - auto tindex = std::type_index(*rec.type); - tinfo->direct_conversions = &internals.direct_conversions[tindex]; - if (rec.module_local) - registered_local_types_cpp()[tindex] = tinfo; - else - internals.registered_types_cpp[tindex] = tinfo; - internals.registered_types_py[(PyTypeObject *) m_ptr] = { tinfo }; - - if (rec.bases.size() > 1 || rec.multiple_inheritance) { - mark_parents_nonsimple(tinfo->type); - tinfo->simple_ancestors = false; - } - else if (rec.bases.size() == 1) { - auto parent_tinfo = get_type_info((PyTypeObject *) rec.bases[0].ptr()); - tinfo->simple_ancestors = parent_tinfo->simple_ancestors; - } - - if (rec.module_local) { - // Stash the local typeinfo and loader so that external modules can access it. - tinfo->module_local_load = &type_caster_generic::local_load; - setattr(m_ptr, PYBIND11_MODULE_LOCAL_ID, capsule(tinfo)); - } - } - - /// Helper function which tags all parents of a type using mult. inheritance - void mark_parents_nonsimple(PyTypeObject *value) { - auto t = reinterpret_borrow(value->tp_bases); - for (handle h : t) { - auto tinfo2 = get_type_info((PyTypeObject *) h.ptr()); - if (tinfo2) - tinfo2->simple_type = false; - mark_parents_nonsimple((PyTypeObject *) h.ptr()); - } - } - - void install_buffer_funcs( - buffer_info *(*get_buffer)(PyObject *, void *), - void *get_buffer_data) { - PyHeapTypeObject *type = (PyHeapTypeObject*) m_ptr; - auto tinfo = detail::get_type_info(&type->ht_type); - - if (!type->ht_type.tp_as_buffer) - pybind11_fail( - "To be able to register buffer protocol support for the type '" + - std::string(tinfo->type->tp_name) + - "' the associated class<>(..) invocation must " - "include the pybind11::buffer_protocol() annotation!"); - - tinfo->get_buffer = get_buffer; - tinfo->get_buffer_data = get_buffer_data; - } - - // rec_func must be set for either fget or fset. - void def_property_static_impl(const char *name, - handle fget, handle fset, - detail::function_record *rec_func) { - const auto is_static = rec_func && !(rec_func->is_method && rec_func->scope); - const auto has_doc = rec_func && rec_func->doc && pybind11::options::show_user_defined_docstrings(); - auto property = handle((PyObject *) (is_static ? get_internals().static_property_type - : &PyProperty_Type)); - attr(name) = property(fget.ptr() ? fget : none(), - fset.ptr() ? fset : none(), - /*deleter*/none(), - pybind11::str(has_doc ? rec_func->doc : "")); - } -}; - -/// Set the pointer to operator new if it exists. The cast is needed because it can be overloaded. -template (T::operator new))>> -void set_operator_new(type_record *r) { r->operator_new = &T::operator new; } - -template void set_operator_new(...) { } - -template struct has_operator_delete : std::false_type { }; -template struct has_operator_delete(T::operator delete))>> - : std::true_type { }; -template struct has_operator_delete_size : std::false_type { }; -template struct has_operator_delete_size(T::operator delete))>> - : std::true_type { }; -/// Call class-specific delete if it exists or global otherwise. Can also be an overload set. -template ::value, int> = 0> -void call_operator_delete(T *p, size_t) { T::operator delete(p); } -template ::value && has_operator_delete_size::value, int> = 0> -void call_operator_delete(T *p, size_t s) { T::operator delete(p, s); } - -inline void call_operator_delete(void *p, size_t) { ::operator delete(p); } - -NAMESPACE_END(detail) - -/// Given a pointer to a member function, cast it to its `Derived` version. -/// Forward everything else unchanged. -template -auto method_adaptor(F &&f) -> decltype(std::forward(f)) { return std::forward(f); } - -template -auto method_adaptor(Return (Class::*pmf)(Args...)) -> Return (Derived::*)(Args...) { - static_assert(detail::is_accessible_base_of::value, - "Cannot bind an inaccessible base class method; use a lambda definition instead"); - return pmf; -} - -template -auto method_adaptor(Return (Class::*pmf)(Args...) const) -> Return (Derived::*)(Args...) const { - static_assert(detail::is_accessible_base_of::value, - "Cannot bind an inaccessible base class method; use a lambda definition instead"); - return pmf; -} - -template -class class_ : public detail::generic_type { - template using is_holder = detail::is_holder_type; - template using is_subtype = detail::is_strict_base_of; - template using is_base = detail::is_strict_base_of; - // struct instead of using here to help MSVC: - template struct is_valid_class_option : - detail::any_of, is_subtype, is_base> {}; - -public: - using type = type_; - using type_alias = detail::exactly_one_t; - constexpr static bool has_alias = !std::is_void::value; - using holder_type = detail::exactly_one_t, options...>; - - static_assert(detail::all_of...>::value, - "Unknown/invalid class_ template parameters provided"); - - static_assert(!has_alias || std::is_polymorphic::value, - "Cannot use an alias class with a non-polymorphic type"); - - PYBIND11_OBJECT(class_, generic_type, PyType_Check) - - template - class_(handle scope, const char *name, const Extra &... extra) { - using namespace detail; - - // MI can only be specified via class_ template options, not constructor parameters - static_assert( - none_of...>::value || // no base class arguments, or: - ( constexpr_sum(is_pyobject::value...) == 1 && // Exactly one base - constexpr_sum(is_base::value...) == 0 && // no template option bases - none_of...>::value), // no multiple_inheritance attr - "Error: multiple inheritance bases must be specified via class_ template options"); - - type_record record; - record.scope = scope; - record.name = name; - record.type = &typeid(type); - record.type_size = sizeof(conditional_t); - record.holder_size = sizeof(holder_type); - record.init_instance = init_instance; - record.dealloc = dealloc; - record.default_holder = std::is_same>::value; - - set_operator_new(&record); - - /* Register base classes specified via template arguments to class_, if any */ - PYBIND11_EXPAND_SIDE_EFFECTS(add_base(record)); - - /* Process optional arguments, if any */ - process_attributes::init(extra..., &record); - - generic_type::initialize(record); - - if (has_alias) { - auto &instances = record.module_local ? registered_local_types_cpp() : get_internals().registered_types_cpp; - instances[std::type_index(typeid(type_alias))] = instances[std::type_index(typeid(type))]; - } - } - - template ::value, int> = 0> - static void add_base(detail::type_record &rec) { - rec.add_base(typeid(Base), [](void *src) -> void * { - return static_cast(reinterpret_cast(src)); - }); - } - - template ::value, int> = 0> - static void add_base(detail::type_record &) { } - - template - class_ &def(const char *name_, Func&& f, const Extra&... extra) { - cpp_function cf(method_adaptor(std::forward(f)), name(name_), is_method(*this), - sibling(getattr(*this, name_, none())), extra...); - attr(cf.name()) = cf; - return *this; - } - - template class_ & - def_static(const char *name_, Func &&f, const Extra&... extra) { - static_assert(!std::is_member_function_pointer::value, - "def_static(...) called with a non-static member function pointer"); - cpp_function cf(std::forward(f), name(name_), scope(*this), - sibling(getattr(*this, name_, none())), extra...); - attr(cf.name()) = cf; - return *this; - } - - template - class_ &def(const detail::op_ &op, const Extra&... extra) { - op.execute(*this, extra...); - return *this; - } - - template - class_ & def_cast(const detail::op_ &op, const Extra&... extra) { - op.execute_cast(*this, extra...); - return *this; - } - - template - class_ &def(const detail::initimpl::constructor &init, const Extra&... extra) { - init.execute(*this, extra...); - return *this; - } - - template - class_ &def(const detail::initimpl::alias_constructor &init, const Extra&... extra) { - init.execute(*this, extra...); - return *this; - } - - template - class_ &def(detail::initimpl::factory &&init, const Extra&... extra) { - std::move(init).execute(*this, extra...); - return *this; - } - - template - class_ &def(detail::initimpl::pickle_factory &&pf, const Extra &...extra) { - std::move(pf).execute(*this, extra...); - return *this; - } - - template class_& def_buffer(Func &&func) { - struct capture { Func func; }; - capture *ptr = new capture { std::forward(func) }; - install_buffer_funcs([](PyObject *obj, void *ptr) -> buffer_info* { - detail::make_caster caster; - if (!caster.load(obj, false)) - return nullptr; - return new buffer_info(((capture *) ptr)->func(caster)); - }, ptr); - return *this; - } - - template - class_ &def_buffer(Return (Class::*func)(Args...)) { - return def_buffer([func] (type &obj) { return (obj.*func)(); }); - } - - template - class_ &def_buffer(Return (Class::*func)(Args...) const) { - return def_buffer([func] (const type &obj) { return (obj.*func)(); }); - } - - template - class_ &def_readwrite(const char *name, D C::*pm, const Extra&... extra) { - static_assert(std::is_base_of::value, "def_readwrite() requires a class member (or base class member)"); - cpp_function fget([pm](const type &c) -> const D &{ return c.*pm; }, is_method(*this)), - fset([pm](type &c, const D &value) { c.*pm = value; }, is_method(*this)); - def_property(name, fget, fset, return_value_policy::reference_internal, extra...); - return *this; - } - - template - class_ &def_readonly(const char *name, const D C::*pm, const Extra& ...extra) { - static_assert(std::is_base_of::value, "def_readonly() requires a class member (or base class member)"); - cpp_function fget([pm](const type &c) -> const D &{ return c.*pm; }, is_method(*this)); - def_property_readonly(name, fget, return_value_policy::reference_internal, extra...); - return *this; - } - - template - class_ &def_readwrite_static(const char *name, D *pm, const Extra& ...extra) { - cpp_function fget([pm](object) -> const D &{ return *pm; }, scope(*this)), - fset([pm](object, const D &value) { *pm = value; }, scope(*this)); - def_property_static(name, fget, fset, return_value_policy::reference, extra...); - return *this; - } - - template - class_ &def_readonly_static(const char *name, const D *pm, const Extra& ...extra) { - cpp_function fget([pm](object) -> const D &{ return *pm; }, scope(*this)); - def_property_readonly_static(name, fget, return_value_policy::reference, extra...); - return *this; - } - - /// Uses return_value_policy::reference_internal by default - template - class_ &def_property_readonly(const char *name, const Getter &fget, const Extra& ...extra) { - return def_property_readonly(name, cpp_function(method_adaptor(fget)), - return_value_policy::reference_internal, extra...); - } - - /// Uses cpp_function's return_value_policy by default - template - class_ &def_property_readonly(const char *name, const cpp_function &fget, const Extra& ...extra) { - return def_property(name, fget, nullptr, extra...); - } - - /// Uses return_value_policy::reference by default - template - class_ &def_property_readonly_static(const char *name, const Getter &fget, const Extra& ...extra) { - return def_property_readonly_static(name, cpp_function(fget), return_value_policy::reference, extra...); - } - - /// Uses cpp_function's return_value_policy by default - template - class_ &def_property_readonly_static(const char *name, const cpp_function &fget, const Extra& ...extra) { - return def_property_static(name, fget, nullptr, extra...); - } - - /// Uses return_value_policy::reference_internal by default - template - class_ &def_property(const char *name, const Getter &fget, const Setter &fset, const Extra& ...extra) { - return def_property(name, fget, cpp_function(method_adaptor(fset)), extra...); - } - template - class_ &def_property(const char *name, const Getter &fget, const cpp_function &fset, const Extra& ...extra) { - return def_property(name, cpp_function(method_adaptor(fget)), fset, - return_value_policy::reference_internal, extra...); - } - - /// Uses cpp_function's return_value_policy by default - template - class_ &def_property(const char *name, const cpp_function &fget, const cpp_function &fset, const Extra& ...extra) { - return def_property_static(name, fget, fset, is_method(*this), extra...); - } - - /// Uses return_value_policy::reference by default - template - class_ &def_property_static(const char *name, const Getter &fget, const cpp_function &fset, const Extra& ...extra) { - return def_property_static(name, cpp_function(fget), fset, return_value_policy::reference, extra...); - } - - /// Uses cpp_function's return_value_policy by default - template - class_ &def_property_static(const char *name, const cpp_function &fget, const cpp_function &fset, const Extra& ...extra) { - auto rec_fget = get_function_record(fget), rec_fset = get_function_record(fset); - auto *rec_active = rec_fget; - if (rec_fget) { - char *doc_prev = rec_fget->doc; /* 'extra' field may include a property-specific documentation string */ - detail::process_attributes::init(extra..., rec_fget); - if (rec_fget->doc && rec_fget->doc != doc_prev) { - free(doc_prev); - rec_fget->doc = strdup(rec_fget->doc); - } - } - if (rec_fset) { - char *doc_prev = rec_fset->doc; - detail::process_attributes::init(extra..., rec_fset); - if (rec_fset->doc && rec_fset->doc != doc_prev) { - free(doc_prev); - rec_fset->doc = strdup(rec_fset->doc); - } - if (! rec_active) rec_active = rec_fset; - } - def_property_static_impl(name, fget, fset, rec_active); - return *this; - } - -private: - /// Initialize holder object, variant 1: object derives from enable_shared_from_this - template - static void init_holder(detail::instance *inst, detail::value_and_holder &v_h, - const holder_type * /* unused */, const std::enable_shared_from_this * /* dummy */) { - try { - auto sh = std::dynamic_pointer_cast( - v_h.value_ptr()->shared_from_this()); - if (sh) { - new (&v_h.holder()) holder_type(std::move(sh)); - v_h.set_holder_constructed(); - } - } catch (const std::bad_weak_ptr &) {} - - if (!v_h.holder_constructed() && inst->owned) { - new (&v_h.holder()) holder_type(v_h.value_ptr()); - v_h.set_holder_constructed(); - } - } - - static void init_holder_from_existing(const detail::value_and_holder &v_h, - const holder_type *holder_ptr, std::true_type /*is_copy_constructible*/) { - new (&v_h.holder()) holder_type(*reinterpret_cast(holder_ptr)); - } - - static void init_holder_from_existing(const detail::value_and_holder &v_h, - const holder_type *holder_ptr, std::false_type /*is_copy_constructible*/) { - new (&v_h.holder()) holder_type(std::move(*const_cast(holder_ptr))); - } - - /// Initialize holder object, variant 2: try to construct from existing holder object, if possible - static void init_holder(detail::instance *inst, detail::value_and_holder &v_h, - const holder_type *holder_ptr, const void * /* dummy -- not enable_shared_from_this) */) { - if (holder_ptr) { - init_holder_from_existing(v_h, holder_ptr, std::is_copy_constructible()); - v_h.set_holder_constructed(); - } else if (inst->owned || detail::always_construct_holder::value) { - new (&v_h.holder()) holder_type(v_h.value_ptr()); - v_h.set_holder_constructed(); - } - } - - /// Performs instance initialization including constructing a holder and registering the known - /// instance. Should be called as soon as the `type` value_ptr is set for an instance. Takes an - /// optional pointer to an existing holder to use; if not specified and the instance is - /// `.owned`, a new holder will be constructed to manage the value pointer. - static void init_instance(detail::instance *inst, const void *holder_ptr) { - auto v_h = inst->get_value_and_holder(detail::get_type_info(typeid(type))); - if (!v_h.instance_registered()) { - register_instance(inst, v_h.value_ptr(), v_h.type); - v_h.set_instance_registered(); - } - init_holder(inst, v_h, (const holder_type *) holder_ptr, v_h.value_ptr()); - } - - /// Deallocates an instance; via holder, if constructed; otherwise via operator delete. - static void dealloc(detail::value_and_holder &v_h) { - if (v_h.holder_constructed()) { - v_h.holder().~holder_type(); - v_h.set_holder_constructed(false); - } - else { - detail::call_operator_delete(v_h.value_ptr(), v_h.type->type_size); - } - v_h.value_ptr() = nullptr; - } - - static detail::function_record *get_function_record(handle h) { - h = detail::get_function(h); - return h ? (detail::function_record *) reinterpret_borrow(PyCFunction_GET_SELF(h.ptr())) - : nullptr; - } -}; - -/// Binds an existing constructor taking arguments Args... -template detail::initimpl::constructor init() { return {}; } -/// Like `init()`, but the instance is always constructed through the alias class (even -/// when not inheriting on the Python side). -template detail::initimpl::alias_constructor init_alias() { return {}; } - -/// Binds a factory function as a constructor -template > -Ret init(Func &&f) { return {std::forward(f)}; } - -/// Dual-argument factory function: the first function is called when no alias is needed, the second -/// when an alias is needed (i.e. due to python-side inheritance). Arguments must be identical. -template > -Ret init(CFunc &&c, AFunc &&a) { - return {std::forward(c), std::forward(a)}; -} - -/// Binds pickling functions `__getstate__` and `__setstate__` and ensures that the type -/// returned by `__getstate__` is the same as the argument accepted by `__setstate__`. -template -detail::initimpl::pickle_factory pickle(GetState &&g, SetState &&s) { - return {std::forward(g), std::forward(s)}; -} - -/// Binds C++ enumerations and enumeration classes to Python -template class enum_ : public class_ { -public: - using class_::def; - using class_::def_property_readonly_static; - using Scalar = typename std::underlying_type::type; - - template - enum_(const handle &scope, const char *name, const Extra&... extra) - : class_(scope, name, extra...), m_entries(), m_parent(scope) { - - constexpr bool is_arithmetic = detail::any_of...>::value; - - auto m_entries_ptr = m_entries.inc_ref().ptr(); - def("__repr__", [name, m_entries_ptr](Type value) -> pybind11::str { - for (const auto &kv : reinterpret_borrow(m_entries_ptr)) { - if (pybind11::cast(kv.second[int_(0)]) == value) - return pybind11::str("{}.{}").format(name, kv.first); - } - return pybind11::str("{}.???").format(name); - }); - def_property_readonly_static("__doc__", [m_entries_ptr](handle self) { - std::string docstring; - const char *tp_doc = ((PyTypeObject *) self.ptr())->tp_doc; - if (tp_doc) - docstring += std::string(tp_doc) + "\n\n"; - docstring += "Members:"; - for (const auto &kv : reinterpret_borrow(m_entries_ptr)) { - auto key = std::string(pybind11::str(kv.first)); - auto comment = kv.second[int_(1)]; - docstring += "\n\n " + key; - if (!comment.is_none()) - docstring += " : " + (std::string) pybind11::str(comment); - } - return docstring; - }); - def_property_readonly_static("__members__", [m_entries_ptr](handle /* self */) { - dict m; - for (const auto &kv : reinterpret_borrow(m_entries_ptr)) - m[kv.first] = kv.second[int_(0)]; - return m; - }, return_value_policy::copy); - def(init([](Scalar i) { return static_cast(i); })); - def("__int__", [](Type value) { return (Scalar) value; }); - #if PY_MAJOR_VERSION < 3 - def("__long__", [](Type value) { return (Scalar) value; }); - #endif - def("__eq__", [](const Type &value, Type *value2) { return value2 && value == *value2; }); - def("__ne__", [](const Type &value, Type *value2) { return !value2 || value != *value2; }); - if (is_arithmetic) { - def("__lt__", [](const Type &value, Type *value2) { return value2 && value < *value2; }); - def("__gt__", [](const Type &value, Type *value2) { return value2 && value > *value2; }); - def("__le__", [](const Type &value, Type *value2) { return value2 && value <= *value2; }); - def("__ge__", [](const Type &value, Type *value2) { return value2 && value >= *value2; }); - } - if (std::is_convertible::value) { - // Don't provide comparison with the underlying type if the enum isn't convertible, - // i.e. if Type is a scoped enum, mirroring the C++ behaviour. (NB: we explicitly - // convert Type to Scalar below anyway because this needs to compile). - def("__eq__", [](const Type &value, Scalar value2) { return (Scalar) value == value2; }); - def("__ne__", [](const Type &value, Scalar value2) { return (Scalar) value != value2; }); - if (is_arithmetic) { - def("__lt__", [](const Type &value, Scalar value2) { return (Scalar) value < value2; }); - def("__gt__", [](const Type &value, Scalar value2) { return (Scalar) value > value2; }); - def("__le__", [](const Type &value, Scalar value2) { return (Scalar) value <= value2; }); - def("__ge__", [](const Type &value, Scalar value2) { return (Scalar) value >= value2; }); - def("__invert__", [](const Type &value) { return ~((Scalar) value); }); - def("__and__", [](const Type &value, Scalar value2) { return (Scalar) value & value2; }); - def("__or__", [](const Type &value, Scalar value2) { return (Scalar) value | value2; }); - def("__xor__", [](const Type &value, Scalar value2) { return (Scalar) value ^ value2; }); - def("__rand__", [](const Type &value, Scalar value2) { return (Scalar) value & value2; }); - def("__ror__", [](const Type &value, Scalar value2) { return (Scalar) value | value2; }); - def("__rxor__", [](const Type &value, Scalar value2) { return (Scalar) value ^ value2; }); - def("__and__", [](const Type &value, const Type &value2) { return (Scalar) value & (Scalar) value2; }); - def("__or__", [](const Type &value, const Type &value2) { return (Scalar) value | (Scalar) value2; }); - def("__xor__", [](const Type &value, const Type &value2) { return (Scalar) value ^ (Scalar) value2; }); - } - } - def("__hash__", [](const Type &value) { return (Scalar) value; }); - // Pickling and unpickling -- needed for use with the 'multiprocessing' module - def(pickle([](const Type &value) { return pybind11::make_tuple((Scalar) value); }, - [](tuple t) { return static_cast(t[0].cast()); })); - } - - /// Export enumeration entries into the parent scope - enum_& export_values() { - for (const auto &kv : m_entries) - m_parent.attr(kv.first) = kv.second[int_(0)]; - return *this; - } - - /// Add an enumeration entry - enum_& value(char const* name, Type value, const char *doc = nullptr) { - auto v = pybind11::cast(value, return_value_policy::copy); - this->attr(name) = v; - m_entries[pybind11::str(name)] = std::make_pair(v, doc); - return *this; - } - -private: - dict m_entries; - handle m_parent; -}; - -NAMESPACE_BEGIN(detail) - - -inline void keep_alive_impl(handle nurse, handle patient) { - if (!nurse || !patient) - pybind11_fail("Could not activate keep_alive!"); - - if (patient.is_none() || nurse.is_none()) - return; /* Nothing to keep alive or nothing to be kept alive by */ - - auto tinfo = all_type_info(Py_TYPE(nurse.ptr())); - if (!tinfo.empty()) { - /* It's a pybind-registered type, so we can store the patient in the - * internal list. */ - add_patient(nurse.ptr(), patient.ptr()); - } - else { - /* Fall back to clever approach based on weak references taken from - * Boost.Python. This is not used for pybind-registered types because - * the objects can be destroyed out-of-order in a GC pass. */ - cpp_function disable_lifesupport( - [patient](handle weakref) { patient.dec_ref(); weakref.dec_ref(); }); - - weakref wr(nurse, disable_lifesupport); - - patient.inc_ref(); /* reference patient and leak the weak reference */ - (void) wr.release(); - } -} - -PYBIND11_NOINLINE inline void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret) { - auto get_arg = [&](size_t n) { - if (n == 0) - return ret; - else if (n == 1 && call.init_self) - return call.init_self; - else if (n <= call.args.size()) - return call.args[n - 1]; - return handle(); - }; - - keep_alive_impl(get_arg(Nurse), get_arg(Patient)); -} - -inline std::pair all_type_info_get_cache(PyTypeObject *type) { - auto res = get_internals().registered_types_py -#ifdef __cpp_lib_unordered_map_try_emplace - .try_emplace(type); -#else - .emplace(type, std::vector()); -#endif - if (res.second) { - // New cache entry created; set up a weak reference to automatically remove it if the type - // gets destroyed: - weakref((PyObject *) type, cpp_function([type](handle wr) { - get_internals().registered_types_py.erase(type); - wr.dec_ref(); - })).release(); - } - - return res; -} - -template -struct iterator_state { - Iterator it; - Sentinel end; - bool first_or_done; -}; - -NAMESPACE_END(detail) - -/// Makes a python iterator from a first and past-the-end C++ InputIterator. -template ()), - typename... Extra> -iterator make_iterator(Iterator first, Sentinel last, Extra &&... extra) { - typedef detail::iterator_state state; - - if (!detail::get_type_info(typeid(state), false)) { - class_(handle(), "iterator", pybind11::module_local()) - .def("__iter__", [](state &s) -> state& { return s; }) - .def("__next__", [](state &s) -> ValueType { - if (!s.first_or_done) - ++s.it; - else - s.first_or_done = false; - if (s.it == s.end) { - s.first_or_done = true; - throw stop_iteration(); - } - return *s.it; - }, std::forward(extra)..., Policy); - } - - return cast(state{first, last, true}); -} - -/// Makes an python iterator over the keys (`.first`) of a iterator over pairs from a -/// first and past-the-end InputIterator. -template ()).first), - typename... Extra> -iterator make_key_iterator(Iterator first, Sentinel last, Extra &&... extra) { - typedef detail::iterator_state state; - - if (!detail::get_type_info(typeid(state), false)) { - class_(handle(), "iterator", pybind11::module_local()) - .def("__iter__", [](state &s) -> state& { return s; }) - .def("__next__", [](state &s) -> KeyType { - if (!s.first_or_done) - ++s.it; - else - s.first_or_done = false; - if (s.it == s.end) { - s.first_or_done = true; - throw stop_iteration(); - } - return (*s.it).first; - }, std::forward(extra)..., Policy); - } - - return cast(state{first, last, true}); -} - -/// Makes an iterator over values of an stl container or other container supporting -/// `std::begin()`/`std::end()` -template iterator make_iterator(Type &value, Extra&&... extra) { - return make_iterator(std::begin(value), std::end(value), extra...); -} - -/// Makes an iterator over the keys (`.first`) of a stl map-like container supporting -/// `std::begin()`/`std::end()` -template iterator make_key_iterator(Type &value, Extra&&... extra) { - return make_key_iterator(std::begin(value), std::end(value), extra...); -} - -template void implicitly_convertible() { - struct set_flag { - bool &flag; - set_flag(bool &flag) : flag(flag) { flag = true; } - ~set_flag() { flag = false; } - }; - auto implicit_caster = [](PyObject *obj, PyTypeObject *type) -> PyObject * { - static bool currently_used = false; - if (currently_used) // implicit conversions are non-reentrant - return nullptr; - set_flag flag_helper(currently_used); - if (!detail::make_caster().load(obj, false)) - return nullptr; - tuple args(1); - args[0] = obj; - PyObject *result = PyObject_Call((PyObject *) type, args.ptr(), nullptr); - if (result == nullptr) - PyErr_Clear(); - return result; - }; - - if (auto tinfo = detail::get_type_info(typeid(OutputType))) - tinfo->implicit_conversions.push_back(implicit_caster); - else - pybind11_fail("implicitly_convertible: Unable to find type " + type_id()); -} - -template -void register_exception_translator(ExceptionTranslator&& translator) { - detail::get_internals().registered_exception_translators.push_front( - std::forward(translator)); -} - -/** - * Wrapper to generate a new Python exception type. - * - * This should only be used with PyErr_SetString for now. - * It is not (yet) possible to use as a py::base. - * Template type argument is reserved for future use. - */ -template -class exception : public object { -public: - exception(handle scope, const char *name, PyObject *base = PyExc_Exception) { - std::string full_name = scope.attr("__name__").cast() + - std::string(".") + name; - m_ptr = PyErr_NewException(const_cast(full_name.c_str()), base, NULL); - if (hasattr(scope, name)) - pybind11_fail("Error during initialization: multiple incompatible " - "definitions with name \"" + std::string(name) + "\""); - scope.attr(name) = *this; - } - - // Sets the current python exception to this exception object with the given message - void operator()(const char *message) { - PyErr_SetString(m_ptr, message); - } -}; - -/** - * Registers a Python exception in `m` of the given `name` and installs an exception translator to - * translate the C++ exception to the created Python exception using the exceptions what() method. - * This is intended for simple exception translations; for more complex translation, register the - * exception object and translator directly. - */ -template -exception ®ister_exception(handle scope, - const char *name, - PyObject *base = PyExc_Exception) { - static exception ex(scope, name, base); - register_exception_translator([](std::exception_ptr p) { - if (!p) return; - try { - std::rethrow_exception(p); - } catch (const CppException &e) { - ex(e.what()); - } - }); - return ex; -} - -NAMESPACE_BEGIN(detail) -PYBIND11_NOINLINE inline void print(tuple args, dict kwargs) { - auto strings = tuple(args.size()); - for (size_t i = 0; i < args.size(); ++i) { - strings[i] = str(args[i]); - } - auto sep = kwargs.contains("sep") ? kwargs["sep"] : cast(" "); - auto line = sep.attr("join")(strings); - - object file; - if (kwargs.contains("file")) { - file = kwargs["file"].cast(); - } else { - try { - file = module::import("sys").attr("stdout"); - } catch (const error_already_set &) { - /* If print() is called from code that is executed as - part of garbage collection during interpreter shutdown, - importing 'sys' can fail. Give up rather than crashing the - interpreter in this case. */ - return; - } - } - - auto write = file.attr("write"); - write(line); - write(kwargs.contains("end") ? kwargs["end"] : cast("\n")); - - if (kwargs.contains("flush") && kwargs["flush"].cast()) - file.attr("flush")(); -} -NAMESPACE_END(detail) - -template -void print(Args &&...args) { - auto c = detail::collect_arguments(std::forward(args)...); - detail::print(c.args(), c.kwargs()); -} - -#if defined(WITH_THREAD) && !defined(PYPY_VERSION) - -/* The functions below essentially reproduce the PyGILState_* API using a RAII - * pattern, but there are a few important differences: - * - * 1. When acquiring the GIL from an non-main thread during the finalization - * phase, the GILState API blindly terminates the calling thread, which - * is often not what is wanted. This API does not do this. - * - * 2. The gil_scoped_release function can optionally cut the relationship - * of a PyThreadState and its associated thread, which allows moving it to - * another thread (this is a fairly rare/advanced use case). - * - * 3. The reference count of an acquired thread state can be controlled. This - * can be handy to prevent cases where callbacks issued from an external - * thread would otherwise constantly construct and destroy thread state data - * structures. - * - * See the Python bindings of NanoGUI (http://github.com/wjakob/nanogui) for an - * example which uses features 2 and 3 to migrate the Python thread of - * execution to another thread (to run the event loop on the original thread, - * in this case). - */ - -class gil_scoped_acquire { -public: - PYBIND11_NOINLINE gil_scoped_acquire() { - auto const &internals = detail::get_internals(); - tstate = (PyThreadState *) PyThread_get_key_value(internals.tstate); - - if (!tstate) { - tstate = PyThreadState_New(internals.istate); - #if !defined(NDEBUG) - if (!tstate) - pybind11_fail("scoped_acquire: could not create thread state!"); - #endif - tstate->gilstate_counter = 0; - #if PY_MAJOR_VERSION < 3 - PyThread_delete_key_value(internals.tstate); - #endif - PyThread_set_key_value(internals.tstate, tstate); - } else { - release = detail::get_thread_state_unchecked() != tstate; - } - - if (release) { - /* Work around an annoying assertion in PyThreadState_Swap */ - #if defined(Py_DEBUG) - PyInterpreterState *interp = tstate->interp; - tstate->interp = nullptr; - #endif - PyEval_AcquireThread(tstate); - #if defined(Py_DEBUG) - tstate->interp = interp; - #endif - } - - inc_ref(); - } - - void inc_ref() { - ++tstate->gilstate_counter; - } - - PYBIND11_NOINLINE void dec_ref() { - --tstate->gilstate_counter; - #if !defined(NDEBUG) - if (detail::get_thread_state_unchecked() != tstate) - pybind11_fail("scoped_acquire::dec_ref(): thread state must be current!"); - if (tstate->gilstate_counter < 0) - pybind11_fail("scoped_acquire::dec_ref(): reference count underflow!"); - #endif - if (tstate->gilstate_counter == 0) { - #if !defined(NDEBUG) - if (!release) - pybind11_fail("scoped_acquire::dec_ref(): internal error!"); - #endif - PyThreadState_Clear(tstate); - PyThreadState_DeleteCurrent(); - PyThread_delete_key_value(detail::get_internals().tstate); - release = false; - } - } - - PYBIND11_NOINLINE ~gil_scoped_acquire() { - dec_ref(); - if (release) - PyEval_SaveThread(); - } -private: - PyThreadState *tstate = nullptr; - bool release = true; -}; - -class gil_scoped_release { -public: - explicit gil_scoped_release(bool disassoc = false) : disassoc(disassoc) { - // `get_internals()` must be called here unconditionally in order to initialize - // `internals.tstate` for subsequent `gil_scoped_acquire` calls. Otherwise, an - // initialization race could occur as multiple threads try `gil_scoped_acquire`. - const auto &internals = detail::get_internals(); - tstate = PyEval_SaveThread(); - if (disassoc) { - auto key = internals.tstate; - #if PY_MAJOR_VERSION < 3 - PyThread_delete_key_value(key); - #else - PyThread_set_key_value(key, nullptr); - #endif - } - } - ~gil_scoped_release() { - if (!tstate) - return; - PyEval_RestoreThread(tstate); - if (disassoc) { - auto key = detail::get_internals().tstate; - #if PY_MAJOR_VERSION < 3 - PyThread_delete_key_value(key); - #endif - PyThread_set_key_value(key, tstate); - } - } -private: - PyThreadState *tstate; - bool disassoc; -}; -#elif defined(PYPY_VERSION) -class gil_scoped_acquire { - PyGILState_STATE state; -public: - gil_scoped_acquire() { state = PyGILState_Ensure(); } - ~gil_scoped_acquire() { PyGILState_Release(state); } -}; - -class gil_scoped_release { - PyThreadState *state; -public: - gil_scoped_release() { state = PyEval_SaveThread(); } - ~gil_scoped_release() { PyEval_RestoreThread(state); } -}; -#else -class gil_scoped_acquire { }; -class gil_scoped_release { }; -#endif - -error_already_set::~error_already_set() { - if (type) { - gil_scoped_acquire gil; - type.release().dec_ref(); - value.release().dec_ref(); - trace.release().dec_ref(); - } -} - -inline function get_type_overload(const void *this_ptr, const detail::type_info *this_type, const char *name) { - handle self = detail::get_object_handle(this_ptr, this_type); - if (!self) - return function(); - handle type = self.get_type(); - auto key = std::make_pair(type.ptr(), name); - - /* Cache functions that aren't overloaded in Python to avoid - many costly Python dictionary lookups below */ - auto &cache = detail::get_internals().inactive_overload_cache; - if (cache.find(key) != cache.end()) - return function(); - - function overload = getattr(self, name, function()); - if (overload.is_cpp_function()) { - cache.insert(key); - return function(); - } - - /* Don't call dispatch code if invoked from overridden function. - Unfortunately this doesn't work on PyPy. */ -#if !defined(PYPY_VERSION) - PyFrameObject *frame = PyThreadState_Get()->frame; - if (frame && (std::string) str(frame->f_code->co_name) == name && - frame->f_code->co_argcount > 0) { - PyFrame_FastToLocals(frame); - PyObject *self_caller = PyDict_GetItem( - frame->f_locals, PyTuple_GET_ITEM(frame->f_code->co_varnames, 0)); - if (self_caller == self.ptr()) - return function(); - } -#else - /* PyPy currently doesn't provide a detailed cpyext emulation of - frame objects, so we have to emulate this using Python. This - is going to be slow..*/ - dict d; d["self"] = self; d["name"] = pybind11::str(name); - PyObject *result = PyRun_String( - "import inspect\n" - "frame = inspect.currentframe()\n" - "if frame is not None:\n" - " frame = frame.f_back\n" - " if frame is not None and str(frame.f_code.co_name) == name and " - "frame.f_code.co_argcount > 0:\n" - " self_caller = frame.f_locals[frame.f_code.co_varnames[0]]\n" - " if self_caller == self:\n" - " self = None\n", - Py_file_input, d.ptr(), d.ptr()); - if (result == nullptr) - throw error_already_set(); - if (d["self"].is_none()) - return function(); - Py_DECREF(result); -#endif - - return overload; -} - -template function get_overload(const T *this_ptr, const char *name) { - auto tinfo = detail::get_type_info(typeid(T)); - return tinfo ? get_type_overload(this_ptr, tinfo, name) : function(); -} - -#define PYBIND11_OVERLOAD_INT(ret_type, cname, name, ...) { \ - pybind11::gil_scoped_acquire gil; \ - pybind11::function overload = pybind11::get_overload(static_cast(this), name); \ - if (overload) { \ - auto o = overload(__VA_ARGS__); \ - if (pybind11::detail::cast_is_temporary_value_reference::value) { \ - static pybind11::detail::overload_caster_t caster; \ - return pybind11::detail::cast_ref(std::move(o), caster); \ - } \ - else return pybind11::detail::cast_safe(std::move(o)); \ - } \ - } - -#define PYBIND11_OVERLOAD_NAME(ret_type, cname, name, fn, ...) \ - PYBIND11_OVERLOAD_INT(ret_type, cname, name, __VA_ARGS__) \ - return cname::fn(__VA_ARGS__) - -#define PYBIND11_OVERLOAD_PURE_NAME(ret_type, cname, name, fn, ...) \ - PYBIND11_OVERLOAD_INT(ret_type, cname, name, __VA_ARGS__) \ - pybind11::pybind11_fail("Tried to call pure virtual function \"" #cname "::" name "\""); - -#define PYBIND11_OVERLOAD(ret_type, cname, fn, ...) \ - PYBIND11_OVERLOAD_NAME(ret_type, cname, #fn, fn, __VA_ARGS__) - -#define PYBIND11_OVERLOAD_PURE(ret_type, cname, fn, ...) \ - PYBIND11_OVERLOAD_PURE_NAME(ret_type, cname, #fn, fn, __VA_ARGS__) - -NAMESPACE_END(PYBIND11_NAMESPACE) - -#if defined(_MSC_VER) -# pragma warning(pop) -#elif defined(__INTEL_COMPILER) -/* Leave ignored warnings on */ -#elif defined(__GNUG__) && !defined(__clang__) -# pragma GCC diagnostic pop -#endif diff --git a/VFRendering/thirdparty/pybind11/include/pybind11/pytypes.h b/VFRendering/thirdparty/pybind11/include/pybind11/pytypes.h deleted file mode 100644 index bcee8b5b8..000000000 --- a/VFRendering/thirdparty/pybind11/include/pybind11/pytypes.h +++ /dev/null @@ -1,1335 +0,0 @@ -/* - pybind11/pytypes.h: Convenience wrapper classes for basic Python types - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "detail/common.h" -#include "buffer_info.h" -#include -#include - -NAMESPACE_BEGIN(PYBIND11_NAMESPACE) - -/* A few forward declarations */ -class handle; class object; -class str; class iterator; -struct arg; struct arg_v; - -NAMESPACE_BEGIN(detail) -class args_proxy; -inline bool isinstance_generic(handle obj, const std::type_info &tp); - -// Accessor forward declarations -template class accessor; -namespace accessor_policies { - struct obj_attr; - struct str_attr; - struct generic_item; - struct sequence_item; - struct list_item; - struct tuple_item; -} -using obj_attr_accessor = accessor; -using str_attr_accessor = accessor; -using item_accessor = accessor; -using sequence_accessor = accessor; -using list_accessor = accessor; -using tuple_accessor = accessor; - -/// Tag and check to identify a class which implements the Python object API -class pyobject_tag { }; -template using is_pyobject = std::is_base_of>; - -/** \rst - A mixin class which adds common functions to `handle`, `object` and various accessors. - The only requirement for `Derived` is to implement ``PyObject *Derived::ptr() const``. -\endrst */ -template -class object_api : public pyobject_tag { - const Derived &derived() const { return static_cast(*this); } - -public: - /** \rst - Return an iterator equivalent to calling ``iter()`` in Python. The object - must be a collection which supports the iteration protocol. - \endrst */ - iterator begin() const; - /// Return a sentinel which ends iteration. - iterator end() const; - - /** \rst - Return an internal functor to invoke the object's sequence protocol. Casting - the returned ``detail::item_accessor`` instance to a `handle` or `object` - subclass causes a corresponding call to ``__getitem__``. Assigning a `handle` - or `object` subclass causes a call to ``__setitem__``. - \endrst */ - item_accessor operator[](handle key) const; - /// See above (the only difference is that they key is provided as a string literal) - item_accessor operator[](const char *key) const; - - /** \rst - Return an internal functor to access the object's attributes. Casting the - returned ``detail::obj_attr_accessor`` instance to a `handle` or `object` - subclass causes a corresponding call to ``getattr``. Assigning a `handle` - or `object` subclass causes a call to ``setattr``. - \endrst */ - obj_attr_accessor attr(handle key) const; - /// See above (the only difference is that they key is provided as a string literal) - str_attr_accessor attr(const char *key) const; - - /** \rst - Matches * unpacking in Python, e.g. to unpack arguments out of a ``tuple`` - or ``list`` for a function call. Applying another * to the result yields - ** unpacking, e.g. to unpack a dict as function keyword arguments. - See :ref:`calling_python_functions`. - \endrst */ - args_proxy operator*() const; - - /// Check if the given item is contained within this object, i.e. ``item in obj``. - template bool contains(T &&item) const; - - /** \rst - Assuming the Python object is a function or implements the ``__call__`` - protocol, ``operator()`` invokes the underlying function, passing an - arbitrary set of parameters. The result is returned as a `object` and - may need to be converted back into a Python object using `handle::cast()`. - - When some of the arguments cannot be converted to Python objects, the - function will throw a `cast_error` exception. When the Python function - call fails, a `error_already_set` exception is thrown. - \endrst */ - template - object operator()(Args &&...args) const; - template - PYBIND11_DEPRECATED("call(...) was deprecated in favor of operator()(...)") - object call(Args&&... args) const; - - /// Equivalent to ``obj is other`` in Python. - bool is(object_api const& other) const { return derived().ptr() == other.derived().ptr(); } - /// Equivalent to ``obj is None`` in Python. - bool is_none() const { return derived().ptr() == Py_None; } - PYBIND11_DEPRECATED("Use py::str(obj) instead") - pybind11::str str() const; - - /// Get or set the object's docstring, i.e. ``obj.__doc__``. - str_attr_accessor doc() const; - - /// Return the object's current reference count - int ref_count() const { return static_cast(Py_REFCNT(derived().ptr())); } - /// Return a handle to the Python type object underlying the instance - handle get_type() const; -}; - -NAMESPACE_END(detail) - -/** \rst - Holds a reference to a Python object (no reference counting) - - The `handle` class is a thin wrapper around an arbitrary Python object (i.e. a - ``PyObject *`` in Python's C API). It does not perform any automatic reference - counting and merely provides a basic C++ interface to various Python API functions. - - .. seealso:: - The `object` class inherits from `handle` and adds automatic reference - counting features. -\endrst */ -class handle : public detail::object_api { -public: - /// The default constructor creates a handle with a ``nullptr``-valued pointer - handle() = default; - /// Creates a ``handle`` from the given raw Python object pointer - handle(PyObject *ptr) : m_ptr(ptr) { } // Allow implicit conversion from PyObject* - - /// Return the underlying ``PyObject *`` pointer - PyObject *ptr() const { return m_ptr; } - PyObject *&ptr() { return m_ptr; } - - /** \rst - Manually increase the reference count of the Python object. Usually, it is - preferable to use the `object` class which derives from `handle` and calls - this function automatically. Returns a reference to itself. - \endrst */ - const handle& inc_ref() const & { Py_XINCREF(m_ptr); return *this; } - - /** \rst - Manually decrease the reference count of the Python object. Usually, it is - preferable to use the `object` class which derives from `handle` and calls - this function automatically. Returns a reference to itself. - \endrst */ - const handle& dec_ref() const & { Py_XDECREF(m_ptr); return *this; } - - /** \rst - Attempt to cast the Python object into the given C++ type. A `cast_error` - will be throw upon failure. - \endrst */ - template T cast() const; - /// Return ``true`` when the `handle` wraps a valid Python object - explicit operator bool() const { return m_ptr != nullptr; } - /** \rst - Deprecated: Check that the underlying pointers are the same. - Equivalent to ``obj1 is obj2`` in Python. - \endrst */ - PYBIND11_DEPRECATED("Use obj1.is(obj2) instead") - bool operator==(const handle &h) const { return m_ptr == h.m_ptr; } - PYBIND11_DEPRECATED("Use !obj1.is(obj2) instead") - bool operator!=(const handle &h) const { return m_ptr != h.m_ptr; } - PYBIND11_DEPRECATED("Use handle::operator bool() instead") - bool check() const { return m_ptr != nullptr; } -protected: - PyObject *m_ptr = nullptr; -}; - -/** \rst - Holds a reference to a Python object (with reference counting) - - Like `handle`, the `object` class is a thin wrapper around an arbitrary Python - object (i.e. a ``PyObject *`` in Python's C API). In contrast to `handle`, it - optionally increases the object's reference count upon construction, and it - *always* decreases the reference count when the `object` instance goes out of - scope and is destructed. When using `object` instances consistently, it is much - easier to get reference counting right at the first attempt. -\endrst */ -class object : public handle { -public: - object() = default; - PYBIND11_DEPRECATED("Use reinterpret_borrow() or reinterpret_steal()") - object(handle h, bool is_borrowed) : handle(h) { if (is_borrowed) inc_ref(); } - /// Copy constructor; always increases the reference count - object(const object &o) : handle(o) { inc_ref(); } - /// Move constructor; steals the object from ``other`` and preserves its reference count - object(object &&other) noexcept { m_ptr = other.m_ptr; other.m_ptr = nullptr; } - /// Destructor; automatically calls `handle::dec_ref()` - ~object() { dec_ref(); } - - /** \rst - Resets the internal pointer to ``nullptr`` without without decreasing the - object's reference count. The function returns a raw handle to the original - Python object. - \endrst */ - handle release() { - PyObject *tmp = m_ptr; - m_ptr = nullptr; - return handle(tmp); - } - - object& operator=(const object &other) { - other.inc_ref(); - dec_ref(); - m_ptr = other.m_ptr; - return *this; - } - - object& operator=(object &&other) noexcept { - if (this != &other) { - handle temp(m_ptr); - m_ptr = other.m_ptr; - other.m_ptr = nullptr; - temp.dec_ref(); - } - return *this; - } - - // Calling cast() on an object lvalue just copies (via handle::cast) - template T cast() const &; - // Calling on an object rvalue does a move, if needed and/or possible - template T cast() &&; - -protected: - // Tags for choosing constructors from raw PyObject * - struct borrowed_t { }; - struct stolen_t { }; - - template friend T reinterpret_borrow(handle); - template friend T reinterpret_steal(handle); - -public: - // Only accessible from derived classes and the reinterpret_* functions - object(handle h, borrowed_t) : handle(h) { inc_ref(); } - object(handle h, stolen_t) : handle(h) { } -}; - -/** \rst - Declare that a `handle` or ``PyObject *`` is a certain type and borrow the reference. - The target type ``T`` must be `object` or one of its derived classes. The function - doesn't do any conversions or checks. It's up to the user to make sure that the - target type is correct. - - .. code-block:: cpp - - PyObject *p = PyList_GetItem(obj, index); - py::object o = reinterpret_borrow(p); - // or - py::tuple t = reinterpret_borrow(p); // <-- `p` must be already be a `tuple` -\endrst */ -template T reinterpret_borrow(handle h) { return {h, object::borrowed_t{}}; } - -/** \rst - Like `reinterpret_borrow`, but steals the reference. - - .. code-block:: cpp - - PyObject *p = PyObject_Str(obj); - py::str s = reinterpret_steal(p); // <-- `p` must be already be a `str` -\endrst */ -template T reinterpret_steal(handle h) { return {h, object::stolen_t{}}; } - -NAMESPACE_BEGIN(detail) -inline std::string error_string(); -NAMESPACE_END(detail) - -/// Fetch and hold an error which was already set in Python. An instance of this is typically -/// thrown to propagate python-side errors back through C++ which can either be caught manually or -/// else falls back to the function dispatcher (which then raises the captured error back to -/// python). -class error_already_set : public std::runtime_error { -public: - /// Constructs a new exception from the current Python error indicator, if any. The current - /// Python error indicator will be cleared. - error_already_set() : std::runtime_error(detail::error_string()) { - PyErr_Fetch(&type.ptr(), &value.ptr(), &trace.ptr()); - } - - error_already_set(const error_already_set &) = default; - error_already_set(error_already_set &&) = default; - - inline ~error_already_set(); - - /// Give the currently-held error back to Python, if any. If there is currently a Python error - /// already set it is cleared first. After this call, the current object no longer stores the - /// error variables (but the `.what()` string is still available). - void restore() { PyErr_Restore(type.release().ptr(), value.release().ptr(), trace.release().ptr()); } - - // Does nothing; provided for backwards compatibility. - PYBIND11_DEPRECATED("Use of error_already_set.clear() is deprecated") - void clear() {} - - /// Check if the currently trapped error type matches the given Python exception class (or a - /// subclass thereof). May also be passed a tuple to search for any exception class matches in - /// the given tuple. - bool matches(handle ex) const { return PyErr_GivenExceptionMatches(ex.ptr(), type.ptr()); } - -private: - object type, value, trace; -}; - -/** \defgroup python_builtins _ - Unless stated otherwise, the following C++ functions behave the same - as their Python counterparts. - */ - -/** \ingroup python_builtins - \rst - Return true if ``obj`` is an instance of ``T``. Type ``T`` must be a subclass of - `object` or a class which was exposed to Python as ``py::class_``. -\endrst */ -template ::value, int> = 0> -bool isinstance(handle obj) { return T::check_(obj); } - -template ::value, int> = 0> -bool isinstance(handle obj) { return detail::isinstance_generic(obj, typeid(T)); } - -template <> inline bool isinstance(handle obj) = delete; -template <> inline bool isinstance(handle obj) { return obj.ptr() != nullptr; } - -/// \ingroup python_builtins -/// Return true if ``obj`` is an instance of the ``type``. -inline bool isinstance(handle obj, handle type) { - const auto result = PyObject_IsInstance(obj.ptr(), type.ptr()); - if (result == -1) - throw error_already_set(); - return result != 0; -} - -/// \addtogroup python_builtins -/// @{ -inline bool hasattr(handle obj, handle name) { - return PyObject_HasAttr(obj.ptr(), name.ptr()) == 1; -} - -inline bool hasattr(handle obj, const char *name) { - return PyObject_HasAttrString(obj.ptr(), name) == 1; -} - -inline object getattr(handle obj, handle name) { - PyObject *result = PyObject_GetAttr(obj.ptr(), name.ptr()); - if (!result) { throw error_already_set(); } - return reinterpret_steal(result); -} - -inline object getattr(handle obj, const char *name) { - PyObject *result = PyObject_GetAttrString(obj.ptr(), name); - if (!result) { throw error_already_set(); } - return reinterpret_steal(result); -} - -inline object getattr(handle obj, handle name, handle default_) { - if (PyObject *result = PyObject_GetAttr(obj.ptr(), name.ptr())) { - return reinterpret_steal(result); - } else { - PyErr_Clear(); - return reinterpret_borrow(default_); - } -} - -inline object getattr(handle obj, const char *name, handle default_) { - if (PyObject *result = PyObject_GetAttrString(obj.ptr(), name)) { - return reinterpret_steal(result); - } else { - PyErr_Clear(); - return reinterpret_borrow(default_); - } -} - -inline void setattr(handle obj, handle name, handle value) { - if (PyObject_SetAttr(obj.ptr(), name.ptr(), value.ptr()) != 0) { throw error_already_set(); } -} - -inline void setattr(handle obj, const char *name, handle value) { - if (PyObject_SetAttrString(obj.ptr(), name, value.ptr()) != 0) { throw error_already_set(); } -} - -inline ssize_t hash(handle obj) { - auto h = PyObject_Hash(obj.ptr()); - if (h == -1) { throw error_already_set(); } - return h; -} - -/// @} python_builtins - -NAMESPACE_BEGIN(detail) -inline handle get_function(handle value) { - if (value) { -#if PY_MAJOR_VERSION >= 3 - if (PyInstanceMethod_Check(value.ptr())) - value = PyInstanceMethod_GET_FUNCTION(value.ptr()); - else -#endif - if (PyMethod_Check(value.ptr())) - value = PyMethod_GET_FUNCTION(value.ptr()); - } - return value; -} - -// Helper aliases/functions to support implicit casting of values given to python accessors/methods. -// When given a pyobject, this simply returns the pyobject as-is; for other C++ type, the value goes -// through pybind11::cast(obj) to convert it to an `object`. -template ::value, int> = 0> -auto object_or_cast(T &&o) -> decltype(std::forward(o)) { return std::forward(o); } -// The following casting version is implemented in cast.h: -template ::value, int> = 0> -object object_or_cast(T &&o); -// Match a PyObject*, which we want to convert directly to handle via its converting constructor -inline handle object_or_cast(PyObject *ptr) { return ptr; } - - -template -class accessor : public object_api> { - using key_type = typename Policy::key_type; - -public: - accessor(handle obj, key_type key) : obj(obj), key(std::move(key)) { } - accessor(const accessor &) = default; - accessor(accessor &&) = default; - - // accessor overload required to override default assignment operator (templates are not allowed - // to replace default compiler-generated assignments). - void operator=(const accessor &a) && { std::move(*this).operator=(handle(a)); } - void operator=(const accessor &a) & { operator=(handle(a)); } - - template void operator=(T &&value) && { - Policy::set(obj, key, object_or_cast(std::forward(value))); - } - template void operator=(T &&value) & { - get_cache() = reinterpret_borrow(object_or_cast(std::forward(value))); - } - - template - PYBIND11_DEPRECATED("Use of obj.attr(...) as bool is deprecated in favor of pybind11::hasattr(obj, ...)") - explicit operator enable_if_t::value || - std::is_same::value, bool>() const { - return hasattr(obj, key); - } - template - PYBIND11_DEPRECATED("Use of obj[key] as bool is deprecated in favor of obj.contains(key)") - explicit operator enable_if_t::value, bool>() const { - return obj.contains(key); - } - - operator object() const { return get_cache(); } - PyObject *ptr() const { return get_cache().ptr(); } - template T cast() const { return get_cache().template cast(); } - -private: - object &get_cache() const { - if (!cache) { cache = Policy::get(obj, key); } - return cache; - } - -private: - handle obj; - key_type key; - mutable object cache; -}; - -NAMESPACE_BEGIN(accessor_policies) -struct obj_attr { - using key_type = object; - static object get(handle obj, handle key) { return getattr(obj, key); } - static void set(handle obj, handle key, handle val) { setattr(obj, key, val); } -}; - -struct str_attr { - using key_type = const char *; - static object get(handle obj, const char *key) { return getattr(obj, key); } - static void set(handle obj, const char *key, handle val) { setattr(obj, key, val); } -}; - -struct generic_item { - using key_type = object; - - static object get(handle obj, handle key) { - PyObject *result = PyObject_GetItem(obj.ptr(), key.ptr()); - if (!result) { throw error_already_set(); } - return reinterpret_steal(result); - } - - static void set(handle obj, handle key, handle val) { - if (PyObject_SetItem(obj.ptr(), key.ptr(), val.ptr()) != 0) { throw error_already_set(); } - } -}; - -struct sequence_item { - using key_type = size_t; - - static object get(handle obj, size_t index) { - PyObject *result = PySequence_GetItem(obj.ptr(), static_cast(index)); - if (!result) { throw error_already_set(); } - return reinterpret_steal(result); - } - - static void set(handle obj, size_t index, handle val) { - // PySequence_SetItem does not steal a reference to 'val' - if (PySequence_SetItem(obj.ptr(), static_cast(index), val.ptr()) != 0) { - throw error_already_set(); - } - } -}; - -struct list_item { - using key_type = size_t; - - static object get(handle obj, size_t index) { - PyObject *result = PyList_GetItem(obj.ptr(), static_cast(index)); - if (!result) { throw error_already_set(); } - return reinterpret_borrow(result); - } - - static void set(handle obj, size_t index, handle val) { - // PyList_SetItem steals a reference to 'val' - if (PyList_SetItem(obj.ptr(), static_cast(index), val.inc_ref().ptr()) != 0) { - throw error_already_set(); - } - } -}; - -struct tuple_item { - using key_type = size_t; - - static object get(handle obj, size_t index) { - PyObject *result = PyTuple_GetItem(obj.ptr(), static_cast(index)); - if (!result) { throw error_already_set(); } - return reinterpret_borrow(result); - } - - static void set(handle obj, size_t index, handle val) { - // PyTuple_SetItem steals a reference to 'val' - if (PyTuple_SetItem(obj.ptr(), static_cast(index), val.inc_ref().ptr()) != 0) { - throw error_already_set(); - } - } -}; -NAMESPACE_END(accessor_policies) - -/// STL iterator template used for tuple, list, sequence and dict -template -class generic_iterator : public Policy { - using It = generic_iterator; - -public: - using difference_type = ssize_t; - using iterator_category = typename Policy::iterator_category; - using value_type = typename Policy::value_type; - using reference = typename Policy::reference; - using pointer = typename Policy::pointer; - - generic_iterator() = default; - generic_iterator(handle seq, ssize_t index) : Policy(seq, index) { } - - reference operator*() const { return Policy::dereference(); } - reference operator[](difference_type n) const { return *(*this + n); } - pointer operator->() const { return **this; } - - It &operator++() { Policy::increment(); return *this; } - It operator++(int) { auto copy = *this; Policy::increment(); return copy; } - It &operator--() { Policy::decrement(); return *this; } - It operator--(int) { auto copy = *this; Policy::decrement(); return copy; } - It &operator+=(difference_type n) { Policy::advance(n); return *this; } - It &operator-=(difference_type n) { Policy::advance(-n); return *this; } - - friend It operator+(const It &a, difference_type n) { auto copy = a; return copy += n; } - friend It operator+(difference_type n, const It &b) { return b + n; } - friend It operator-(const It &a, difference_type n) { auto copy = a; return copy -= n; } - friend difference_type operator-(const It &a, const It &b) { return a.distance_to(b); } - - friend bool operator==(const It &a, const It &b) { return a.equal(b); } - friend bool operator!=(const It &a, const It &b) { return !(a == b); } - friend bool operator< (const It &a, const It &b) { return b - a > 0; } - friend bool operator> (const It &a, const It &b) { return b < a; } - friend bool operator>=(const It &a, const It &b) { return !(a < b); } - friend bool operator<=(const It &a, const It &b) { return !(a > b); } -}; - -NAMESPACE_BEGIN(iterator_policies) -/// Quick proxy class needed to implement ``operator->`` for iterators which can't return pointers -template -struct arrow_proxy { - T value; - - arrow_proxy(T &&value) : value(std::move(value)) { } - T *operator->() const { return &value; } -}; - -/// Lightweight iterator policy using just a simple pointer: see ``PySequence_Fast_ITEMS`` -class sequence_fast_readonly { -protected: - using iterator_category = std::random_access_iterator_tag; - using value_type = handle; - using reference = const handle; - using pointer = arrow_proxy; - - sequence_fast_readonly(handle obj, ssize_t n) : ptr(PySequence_Fast_ITEMS(obj.ptr()) + n) { } - - reference dereference() const { return *ptr; } - void increment() { ++ptr; } - void decrement() { --ptr; } - void advance(ssize_t n) { ptr += n; } - bool equal(const sequence_fast_readonly &b) const { return ptr == b.ptr; } - ssize_t distance_to(const sequence_fast_readonly &b) const { return ptr - b.ptr; } - -private: - PyObject **ptr; -}; - -/// Full read and write access using the sequence protocol: see ``detail::sequence_accessor`` -class sequence_slow_readwrite { -protected: - using iterator_category = std::random_access_iterator_tag; - using value_type = object; - using reference = sequence_accessor; - using pointer = arrow_proxy; - - sequence_slow_readwrite(handle obj, ssize_t index) : obj(obj), index(index) { } - - reference dereference() const { return {obj, static_cast(index)}; } - void increment() { ++index; } - void decrement() { --index; } - void advance(ssize_t n) { index += n; } - bool equal(const sequence_slow_readwrite &b) const { return index == b.index; } - ssize_t distance_to(const sequence_slow_readwrite &b) const { return index - b.index; } - -private: - handle obj; - ssize_t index; -}; - -/// Python's dictionary protocol permits this to be a forward iterator -class dict_readonly { -protected: - using iterator_category = std::forward_iterator_tag; - using value_type = std::pair; - using reference = const value_type; - using pointer = arrow_proxy; - - dict_readonly() = default; - dict_readonly(handle obj, ssize_t pos) : obj(obj), pos(pos) { increment(); } - - reference dereference() const { return {key, value}; } - void increment() { if (!PyDict_Next(obj.ptr(), &pos, &key, &value)) { pos = -1; } } - bool equal(const dict_readonly &b) const { return pos == b.pos; } - -private: - handle obj; - PyObject *key, *value; - ssize_t pos = -1; -}; -NAMESPACE_END(iterator_policies) - -#if !defined(PYPY_VERSION) -using tuple_iterator = generic_iterator; -using list_iterator = generic_iterator; -#else -using tuple_iterator = generic_iterator; -using list_iterator = generic_iterator; -#endif - -using sequence_iterator = generic_iterator; -using dict_iterator = generic_iterator; - -inline bool PyIterable_Check(PyObject *obj) { - PyObject *iter = PyObject_GetIter(obj); - if (iter) { - Py_DECREF(iter); - return true; - } else { - PyErr_Clear(); - return false; - } -} - -inline bool PyNone_Check(PyObject *o) { return o == Py_None; } - -inline bool PyUnicode_Check_Permissive(PyObject *o) { return PyUnicode_Check(o) || PYBIND11_BYTES_CHECK(o); } - -class kwargs_proxy : public handle { -public: - explicit kwargs_proxy(handle h) : handle(h) { } -}; - -class args_proxy : public handle { -public: - explicit args_proxy(handle h) : handle(h) { } - kwargs_proxy operator*() const { return kwargs_proxy(*this); } -}; - -/// Python argument categories (using PEP 448 terms) -template using is_keyword = std::is_base_of; -template using is_s_unpacking = std::is_same; // * unpacking -template using is_ds_unpacking = std::is_same; // ** unpacking -template using is_positional = satisfies_none_of; -template using is_keyword_or_ds = satisfies_any_of; - -// Call argument collector forward declarations -template -class simple_collector; -template -class unpacking_collector; - -NAMESPACE_END(detail) - -// TODO: After the deprecated constructors are removed, this macro can be simplified by -// inheriting ctors: `using Parent::Parent`. It's not an option right now because -// the `using` statement triggers the parent deprecation warning even if the ctor -// isn't even used. -#define PYBIND11_OBJECT_COMMON(Name, Parent, CheckFun) \ - public: \ - PYBIND11_DEPRECATED("Use reinterpret_borrow<"#Name">() or reinterpret_steal<"#Name">()") \ - Name(handle h, bool is_borrowed) : Parent(is_borrowed ? Parent(h, borrowed_t{}) : Parent(h, stolen_t{})) { } \ - Name(handle h, borrowed_t) : Parent(h, borrowed_t{}) { } \ - Name(handle h, stolen_t) : Parent(h, stolen_t{}) { } \ - PYBIND11_DEPRECATED("Use py::isinstance(obj) instead") \ - bool check() const { return m_ptr != nullptr && (bool) CheckFun(m_ptr); } \ - static bool check_(handle h) { return h.ptr() != nullptr && CheckFun(h.ptr()); } - -#define PYBIND11_OBJECT_CVT(Name, Parent, CheckFun, ConvertFun) \ - PYBIND11_OBJECT_COMMON(Name, Parent, CheckFun) \ - /* This is deliberately not 'explicit' to allow implicit conversion from object: */ \ - Name(const object &o) \ - : Parent(check_(o) ? o.inc_ref().ptr() : ConvertFun(o.ptr()), stolen_t{}) \ - { if (!m_ptr) throw error_already_set(); } \ - Name(object &&o) \ - : Parent(check_(o) ? o.release().ptr() : ConvertFun(o.ptr()), stolen_t{}) \ - { if (!m_ptr) throw error_already_set(); } \ - template \ - Name(const ::pybind11::detail::accessor &a) : Name(object(a)) { } - -#define PYBIND11_OBJECT(Name, Parent, CheckFun) \ - PYBIND11_OBJECT_COMMON(Name, Parent, CheckFun) \ - /* This is deliberately not 'explicit' to allow implicit conversion from object: */ \ - Name(const object &o) : Parent(o) { } \ - Name(object &&o) : Parent(std::move(o)) { } - -#define PYBIND11_OBJECT_DEFAULT(Name, Parent, CheckFun) \ - PYBIND11_OBJECT(Name, Parent, CheckFun) \ - Name() : Parent() { } - -/// \addtogroup pytypes -/// @{ - -/** \rst - Wraps a Python iterator so that it can also be used as a C++ input iterator - - Caveat: copying an iterator does not (and cannot) clone the internal - state of the Python iterable. This also applies to the post-increment - operator. This iterator should only be used to retrieve the current - value using ``operator*()``. -\endrst */ -class iterator : public object { -public: - using iterator_category = std::input_iterator_tag; - using difference_type = ssize_t; - using value_type = handle; - using reference = const handle; - using pointer = const handle *; - - PYBIND11_OBJECT_DEFAULT(iterator, object, PyIter_Check) - - iterator& operator++() { - advance(); - return *this; - } - - iterator operator++(int) { - auto rv = *this; - advance(); - return rv; - } - - reference operator*() const { - if (m_ptr && !value.ptr()) { - auto& self = const_cast(*this); - self.advance(); - } - return value; - } - - pointer operator->() const { operator*(); return &value; } - - /** \rst - The value which marks the end of the iteration. ``it == iterator::sentinel()`` - is equivalent to catching ``StopIteration`` in Python. - - .. code-block:: cpp - - void foo(py::iterator it) { - while (it != py::iterator::sentinel()) { - // use `*it` - ++it; - } - } - \endrst */ - static iterator sentinel() { return {}; } - - friend bool operator==(const iterator &a, const iterator &b) { return a->ptr() == b->ptr(); } - friend bool operator!=(const iterator &a, const iterator &b) { return a->ptr() != b->ptr(); } - -private: - void advance() { - value = reinterpret_steal(PyIter_Next(m_ptr)); - if (PyErr_Occurred()) { throw error_already_set(); } - } - -private: - object value = {}; -}; - -class iterable : public object { -public: - PYBIND11_OBJECT_DEFAULT(iterable, object, detail::PyIterable_Check) -}; - -class bytes; - -class str : public object { -public: - PYBIND11_OBJECT_CVT(str, object, detail::PyUnicode_Check_Permissive, raw_str) - - str(const char *c, size_t n) - : object(PyUnicode_FromStringAndSize(c, (ssize_t) n), stolen_t{}) { - if (!m_ptr) pybind11_fail("Could not allocate string object!"); - } - - // 'explicit' is explicitly omitted from the following constructors to allow implicit conversion to py::str from C++ string-like objects - str(const char *c = "") - : object(PyUnicode_FromString(c), stolen_t{}) { - if (!m_ptr) pybind11_fail("Could not allocate string object!"); - } - - str(const std::string &s) : str(s.data(), s.size()) { } - - explicit str(const bytes &b); - - /** \rst - Return a string representation of the object. This is analogous to - the ``str()`` function in Python. - \endrst */ - explicit str(handle h) : object(raw_str(h.ptr()), stolen_t{}) { } - - operator std::string() const { - object temp = *this; - if (PyUnicode_Check(m_ptr)) { - temp = reinterpret_steal(PyUnicode_AsUTF8String(m_ptr)); - if (!temp) - pybind11_fail("Unable to extract string contents! (encoding issue)"); - } - char *buffer; - ssize_t length; - if (PYBIND11_BYTES_AS_STRING_AND_SIZE(temp.ptr(), &buffer, &length)) - pybind11_fail("Unable to extract string contents! (invalid type)"); - return std::string(buffer, (size_t) length); - } - - template - str format(Args &&...args) const { - return attr("format")(std::forward(args)...); - } - -private: - /// Return string representation -- always returns a new reference, even if already a str - static PyObject *raw_str(PyObject *op) { - PyObject *str_value = PyObject_Str(op); -#if PY_MAJOR_VERSION < 3 - if (!str_value) throw error_already_set(); - PyObject *unicode = PyUnicode_FromEncodedObject(str_value, "utf-8", nullptr); - Py_XDECREF(str_value); str_value = unicode; -#endif - return str_value; - } -}; -/// @} pytypes - -inline namespace literals { -/** \rst - String literal version of `str` - \endrst */ -inline str operator"" _s(const char *s, size_t size) { return {s, size}; } -} - -/// \addtogroup pytypes -/// @{ -class bytes : public object { -public: - PYBIND11_OBJECT(bytes, object, PYBIND11_BYTES_CHECK) - - // Allow implicit conversion: - bytes(const char *c = "") - : object(PYBIND11_BYTES_FROM_STRING(c), stolen_t{}) { - if (!m_ptr) pybind11_fail("Could not allocate bytes object!"); - } - - bytes(const char *c, size_t n) - : object(PYBIND11_BYTES_FROM_STRING_AND_SIZE(c, (ssize_t) n), stolen_t{}) { - if (!m_ptr) pybind11_fail("Could not allocate bytes object!"); - } - - // Allow implicit conversion: - bytes(const std::string &s) : bytes(s.data(), s.size()) { } - - explicit bytes(const pybind11::str &s); - - operator std::string() const { - char *buffer; - ssize_t length; - if (PYBIND11_BYTES_AS_STRING_AND_SIZE(m_ptr, &buffer, &length)) - pybind11_fail("Unable to extract bytes contents!"); - return std::string(buffer, (size_t) length); - } -}; - -inline bytes::bytes(const pybind11::str &s) { - object temp = s; - if (PyUnicode_Check(s.ptr())) { - temp = reinterpret_steal(PyUnicode_AsUTF8String(s.ptr())); - if (!temp) - pybind11_fail("Unable to extract string contents! (encoding issue)"); - } - char *buffer; - ssize_t length; - if (PYBIND11_BYTES_AS_STRING_AND_SIZE(temp.ptr(), &buffer, &length)) - pybind11_fail("Unable to extract string contents! (invalid type)"); - auto obj = reinterpret_steal(PYBIND11_BYTES_FROM_STRING_AND_SIZE(buffer, length)); - if (!obj) - pybind11_fail("Could not allocate bytes object!"); - m_ptr = obj.release().ptr(); -} - -inline str::str(const bytes& b) { - char *buffer; - ssize_t length; - if (PYBIND11_BYTES_AS_STRING_AND_SIZE(b.ptr(), &buffer, &length)) - pybind11_fail("Unable to extract bytes contents!"); - auto obj = reinterpret_steal(PyUnicode_FromStringAndSize(buffer, (ssize_t) length)); - if (!obj) - pybind11_fail("Could not allocate string object!"); - m_ptr = obj.release().ptr(); -} - -class none : public object { -public: - PYBIND11_OBJECT(none, object, detail::PyNone_Check) - none() : object(Py_None, borrowed_t{}) { } -}; - -class bool_ : public object { -public: - PYBIND11_OBJECT_CVT(bool_, object, PyBool_Check, raw_bool) - bool_() : object(Py_False, borrowed_t{}) { } - // Allow implicit conversion from and to `bool`: - bool_(bool value) : object(value ? Py_True : Py_False, borrowed_t{}) { } - operator bool() const { return m_ptr && PyLong_AsLong(m_ptr) != 0; } - -private: - /// Return the truth value of an object -- always returns a new reference - static PyObject *raw_bool(PyObject *op) { - const auto value = PyObject_IsTrue(op); - if (value == -1) return nullptr; - return handle(value ? Py_True : Py_False).inc_ref().ptr(); - } -}; - -NAMESPACE_BEGIN(detail) -// Converts a value to the given unsigned type. If an error occurs, you get back (Unsigned) -1; -// otherwise you get back the unsigned long or unsigned long long value cast to (Unsigned). -// (The distinction is critically important when casting a returned -1 error value to some other -// unsigned type: (A)-1 != (B)-1 when A and B are unsigned types of different sizes). -template -Unsigned as_unsigned(PyObject *o) { - if (sizeof(Unsigned) <= sizeof(unsigned long) -#if PY_VERSION_HEX < 0x03000000 - || PyInt_Check(o) -#endif - ) { - unsigned long v = PyLong_AsUnsignedLong(o); - return v == (unsigned long) -1 && PyErr_Occurred() ? (Unsigned) -1 : (Unsigned) v; - } - else { - unsigned long long v = PyLong_AsUnsignedLongLong(o); - return v == (unsigned long long) -1 && PyErr_Occurred() ? (Unsigned) -1 : (Unsigned) v; - } -} -NAMESPACE_END(detail) - -class int_ : public object { -public: - PYBIND11_OBJECT_CVT(int_, object, PYBIND11_LONG_CHECK, PyNumber_Long) - int_() : object(PyLong_FromLong(0), stolen_t{}) { } - // Allow implicit conversion from C++ integral types: - template ::value, int> = 0> - int_(T value) { - if (sizeof(T) <= sizeof(long)) { - if (std::is_signed::value) - m_ptr = PyLong_FromLong((long) value); - else - m_ptr = PyLong_FromUnsignedLong((unsigned long) value); - } else { - if (std::is_signed::value) - m_ptr = PyLong_FromLongLong((long long) value); - else - m_ptr = PyLong_FromUnsignedLongLong((unsigned long long) value); - } - if (!m_ptr) pybind11_fail("Could not allocate int object!"); - } - - template ::value, int> = 0> - operator T() const { - return std::is_unsigned::value - ? detail::as_unsigned(m_ptr) - : sizeof(T) <= sizeof(long) - ? (T) PyLong_AsLong(m_ptr) - : (T) PYBIND11_LONG_AS_LONGLONG(m_ptr); - } -}; - -class float_ : public object { -public: - PYBIND11_OBJECT_CVT(float_, object, PyFloat_Check, PyNumber_Float) - // Allow implicit conversion from float/double: - float_(float value) : object(PyFloat_FromDouble((double) value), stolen_t{}) { - if (!m_ptr) pybind11_fail("Could not allocate float object!"); - } - float_(double value = .0) : object(PyFloat_FromDouble((double) value), stolen_t{}) { - if (!m_ptr) pybind11_fail("Could not allocate float object!"); - } - operator float() const { return (float) PyFloat_AsDouble(m_ptr); } - operator double() const { return (double) PyFloat_AsDouble(m_ptr); } -}; - -class weakref : public object { -public: - PYBIND11_OBJECT_DEFAULT(weakref, object, PyWeakref_Check) - explicit weakref(handle obj, handle callback = {}) - : object(PyWeakref_NewRef(obj.ptr(), callback.ptr()), stolen_t{}) { - if (!m_ptr) pybind11_fail("Could not allocate weak reference!"); - } -}; - -class slice : public object { -public: - PYBIND11_OBJECT_DEFAULT(slice, object, PySlice_Check) - slice(ssize_t start_, ssize_t stop_, ssize_t step_) { - int_ start(start_), stop(stop_), step(step_); - m_ptr = PySlice_New(start.ptr(), stop.ptr(), step.ptr()); - if (!m_ptr) pybind11_fail("Could not allocate slice object!"); - } - bool compute(size_t length, size_t *start, size_t *stop, size_t *step, - size_t *slicelength) const { - return PySlice_GetIndicesEx((PYBIND11_SLICE_OBJECT *) m_ptr, - (ssize_t) length, (ssize_t *) start, - (ssize_t *) stop, (ssize_t *) step, - (ssize_t *) slicelength) == 0; - } -}; - -class capsule : public object { -public: - PYBIND11_OBJECT_DEFAULT(capsule, object, PyCapsule_CheckExact) - PYBIND11_DEPRECATED("Use reinterpret_borrow() or reinterpret_steal()") - capsule(PyObject *ptr, bool is_borrowed) : object(is_borrowed ? object(ptr, borrowed_t{}) : object(ptr, stolen_t{})) { } - - explicit capsule(const void *value, const char *name = nullptr, void (*destructor)(PyObject *) = nullptr) - : object(PyCapsule_New(const_cast(value), name, destructor), stolen_t{}) { - if (!m_ptr) - pybind11_fail("Could not allocate capsule object!"); - } - - PYBIND11_DEPRECATED("Please pass a destructor that takes a void pointer as input") - capsule(const void *value, void (*destruct)(PyObject *)) - : object(PyCapsule_New(const_cast(value), nullptr, destruct), stolen_t{}) { - if (!m_ptr) - pybind11_fail("Could not allocate capsule object!"); - } - - capsule(const void *value, void (*destructor)(void *)) { - m_ptr = PyCapsule_New(const_cast(value), nullptr, [](PyObject *o) { - auto destructor = reinterpret_cast(PyCapsule_GetContext(o)); - void *ptr = PyCapsule_GetPointer(o, nullptr); - destructor(ptr); - }); - - if (!m_ptr) - pybind11_fail("Could not allocate capsule object!"); - - if (PyCapsule_SetContext(m_ptr, (void *) destructor) != 0) - pybind11_fail("Could not set capsule context!"); - } - - capsule(void (*destructor)()) { - m_ptr = PyCapsule_New(reinterpret_cast(destructor), nullptr, [](PyObject *o) { - auto destructor = reinterpret_cast(PyCapsule_GetPointer(o, nullptr)); - destructor(); - }); - - if (!m_ptr) - pybind11_fail("Could not allocate capsule object!"); - } - - template operator T *() const { - auto name = this->name(); - T * result = static_cast(PyCapsule_GetPointer(m_ptr, name)); - if (!result) pybind11_fail("Unable to extract capsule contents!"); - return result; - } - - const char *name() const { return PyCapsule_GetName(m_ptr); } -}; - -class tuple : public object { -public: - PYBIND11_OBJECT_CVT(tuple, object, PyTuple_Check, PySequence_Tuple) - explicit tuple(size_t size = 0) : object(PyTuple_New((ssize_t) size), stolen_t{}) { - if (!m_ptr) pybind11_fail("Could not allocate tuple object!"); - } - size_t size() const { return (size_t) PyTuple_Size(m_ptr); } - detail::tuple_accessor operator[](size_t index) const { return {*this, index}; } - detail::tuple_iterator begin() const { return {*this, 0}; } - detail::tuple_iterator end() const { return {*this, PyTuple_GET_SIZE(m_ptr)}; } -}; - -class dict : public object { -public: - PYBIND11_OBJECT_CVT(dict, object, PyDict_Check, raw_dict) - dict() : object(PyDict_New(), stolen_t{}) { - if (!m_ptr) pybind11_fail("Could not allocate dict object!"); - } - template ...>::value>, - // MSVC workaround: it can't compile an out-of-line definition, so defer the collector - typename collector = detail::deferred_t, Args...>> - explicit dict(Args &&...args) : dict(collector(std::forward(args)...).kwargs()) { } - - size_t size() const { return (size_t) PyDict_Size(m_ptr); } - detail::dict_iterator begin() const { return {*this, 0}; } - detail::dict_iterator end() const { return {}; } - void clear() const { PyDict_Clear(ptr()); } - bool contains(handle key) const { return PyDict_Contains(ptr(), key.ptr()) == 1; } - bool contains(const char *key) const { return PyDict_Contains(ptr(), pybind11::str(key).ptr()) == 1; } - -private: - /// Call the `dict` Python type -- always returns a new reference - static PyObject *raw_dict(PyObject *op) { - if (PyDict_Check(op)) - return handle(op).inc_ref().ptr(); - return PyObject_CallFunctionObjArgs((PyObject *) &PyDict_Type, op, nullptr); - } -}; - -class sequence : public object { -public: - PYBIND11_OBJECT_DEFAULT(sequence, object, PySequence_Check) - size_t size() const { return (size_t) PySequence_Size(m_ptr); } - detail::sequence_accessor operator[](size_t index) const { return {*this, index}; } - detail::sequence_iterator begin() const { return {*this, 0}; } - detail::sequence_iterator end() const { return {*this, PySequence_Size(m_ptr)}; } -}; - -class list : public object { -public: - PYBIND11_OBJECT_CVT(list, object, PyList_Check, PySequence_List) - explicit list(size_t size = 0) : object(PyList_New((ssize_t) size), stolen_t{}) { - if (!m_ptr) pybind11_fail("Could not allocate list object!"); - } - size_t size() const { return (size_t) PyList_Size(m_ptr); } - detail::list_accessor operator[](size_t index) const { return {*this, index}; } - detail::list_iterator begin() const { return {*this, 0}; } - detail::list_iterator end() const { return {*this, PyList_GET_SIZE(m_ptr)}; } - template void append(T &&val) const { - PyList_Append(m_ptr, detail::object_or_cast(std::forward(val)).ptr()); - } -}; - -class args : public tuple { PYBIND11_OBJECT_DEFAULT(args, tuple, PyTuple_Check) }; -class kwargs : public dict { PYBIND11_OBJECT_DEFAULT(kwargs, dict, PyDict_Check) }; - -class set : public object { -public: - PYBIND11_OBJECT_CVT(set, object, PySet_Check, PySet_New) - set() : object(PySet_New(nullptr), stolen_t{}) { - if (!m_ptr) pybind11_fail("Could not allocate set object!"); - } - size_t size() const { return (size_t) PySet_Size(m_ptr); } - template bool add(T &&val) const { - return PySet_Add(m_ptr, detail::object_or_cast(std::forward(val)).ptr()) == 0; - } - void clear() const { PySet_Clear(m_ptr); } -}; - -class function : public object { -public: - PYBIND11_OBJECT_DEFAULT(function, object, PyCallable_Check) - handle cpp_function() const { - handle fun = detail::get_function(m_ptr); - if (fun && PyCFunction_Check(fun.ptr())) - return fun; - return handle(); - } - bool is_cpp_function() const { return (bool) cpp_function(); } -}; - -class buffer : public object { -public: - PYBIND11_OBJECT_DEFAULT(buffer, object, PyObject_CheckBuffer) - - buffer_info request(bool writable = false) { - int flags = PyBUF_STRIDES | PyBUF_FORMAT; - if (writable) flags |= PyBUF_WRITABLE; - Py_buffer *view = new Py_buffer(); - if (PyObject_GetBuffer(m_ptr, view, flags) != 0) { - delete view; - throw error_already_set(); - } - return buffer_info(view); - } -}; - -class memoryview : public object { -public: - explicit memoryview(const buffer_info& info) { - static Py_buffer buf { }; - // Py_buffer uses signed sizes, strides and shape!.. - static std::vector py_strides { }; - static std::vector py_shape { }; - buf.buf = info.ptr; - buf.itemsize = info.itemsize; - buf.format = const_cast(info.format.c_str()); - buf.ndim = (int) info.ndim; - buf.len = info.size; - py_strides.clear(); - py_shape.clear(); - for (size_t i = 0; i < (size_t) info.ndim; ++i) { - py_strides.push_back(info.strides[i]); - py_shape.push_back(info.shape[i]); - } - buf.strides = py_strides.data(); - buf.shape = py_shape.data(); - buf.suboffsets = nullptr; - buf.readonly = false; - buf.internal = nullptr; - - m_ptr = PyMemoryView_FromBuffer(&buf); - if (!m_ptr) - pybind11_fail("Unable to create memoryview from buffer descriptor"); - } - - PYBIND11_OBJECT_CVT(memoryview, object, PyMemoryView_Check, PyMemoryView_FromObject) -}; -/// @} pytypes - -/// \addtogroup python_builtins -/// @{ -inline size_t len(handle h) { - ssize_t result = PyObject_Length(h.ptr()); - if (result < 0) - pybind11_fail("Unable to compute length of object"); - return (size_t) result; -} - -inline str repr(handle h) { - PyObject *str_value = PyObject_Repr(h.ptr()); - if (!str_value) throw error_already_set(); -#if PY_MAJOR_VERSION < 3 - PyObject *unicode = PyUnicode_FromEncodedObject(str_value, "utf-8", nullptr); - Py_XDECREF(str_value); str_value = unicode; - if (!str_value) throw error_already_set(); -#endif - return reinterpret_steal(str_value); -} - -inline iterator iter(handle obj) { - PyObject *result = PyObject_GetIter(obj.ptr()); - if (!result) { throw error_already_set(); } - return reinterpret_steal(result); -} -/// @} python_builtins - -NAMESPACE_BEGIN(detail) -template iterator object_api::begin() const { return iter(derived()); } -template iterator object_api::end() const { return iterator::sentinel(); } -template item_accessor object_api::operator[](handle key) const { - return {derived(), reinterpret_borrow(key)}; -} -template item_accessor object_api::operator[](const char *key) const { - return {derived(), pybind11::str(key)}; -} -template obj_attr_accessor object_api::attr(handle key) const { - return {derived(), reinterpret_borrow(key)}; -} -template str_attr_accessor object_api::attr(const char *key) const { - return {derived(), key}; -} -template args_proxy object_api::operator*() const { - return args_proxy(derived().ptr()); -} -template template bool object_api::contains(T &&item) const { - return attr("__contains__")(std::forward(item)).template cast(); -} - -template -pybind11::str object_api::str() const { return pybind11::str(derived()); } - -template -str_attr_accessor object_api::doc() const { return attr("__doc__"); } - -template -handle object_api::get_type() const { return (PyObject *) Py_TYPE(derived().ptr()); } - -NAMESPACE_END(detail) -NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/VFRendering/thirdparty/pybind11/include/pybind11/stl.h b/VFRendering/thirdparty/pybind11/include/pybind11/stl.h deleted file mode 100644 index e690e43fa..000000000 --- a/VFRendering/thirdparty/pybind11/include/pybind11/stl.h +++ /dev/null @@ -1,369 +0,0 @@ -/* - pybind11/stl.h: Transparent conversion for STL data types - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "pybind11.h" -#include -#include -#include -#include -#include -#include -#include - -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable: 4127) // warning C4127: Conditional expression is constant -#endif - -#ifdef __has_include -// std::optional (but including it in c++14 mode isn't allowed) -# if defined(PYBIND11_CPP17) && __has_include() -# include -# define PYBIND11_HAS_OPTIONAL 1 -# endif -// std::experimental::optional (but not allowed in c++11 mode) -# if defined(PYBIND11_CPP14) && __has_include() -# include -# define PYBIND11_HAS_EXP_OPTIONAL 1 -# endif -// std::variant -# if defined(PYBIND11_CPP17) && __has_include() -# include -# define PYBIND11_HAS_VARIANT 1 -# endif -#elif defined(_MSC_VER) && defined(PYBIND11_CPP17) -# include -# include -# define PYBIND11_HAS_OPTIONAL 1 -# define PYBIND11_HAS_VARIANT 1 -#endif - -NAMESPACE_BEGIN(PYBIND11_NAMESPACE) -NAMESPACE_BEGIN(detail) - -/// Extracts an const lvalue reference or rvalue reference for U based on the type of T (e.g. for -/// forwarding a container element). Typically used indirect via forwarded_type(), below. -template -using forwarded_type = conditional_t< - std::is_lvalue_reference::value, remove_reference_t &, remove_reference_t &&>; - -/// Forwards a value U as rvalue or lvalue according to whether T is rvalue or lvalue; typically -/// used for forwarding a container's elements. -template -forwarded_type forward_like(U &&u) { - return std::forward>(std::forward(u)); -} - -template struct set_caster { - using type = Type; - using key_conv = make_caster; - - bool load(handle src, bool convert) { - if (!isinstance(src)) - return false; - auto s = reinterpret_borrow(src); - value.clear(); - for (auto entry : s) { - key_conv conv; - if (!conv.load(entry, convert)) - return false; - value.insert(cast_op(std::move(conv))); - } - return true; - } - - template - static handle cast(T &&src, return_value_policy policy, handle parent) { - pybind11::set s; - for (auto &&value : src) { - auto value_ = reinterpret_steal(key_conv::cast(forward_like(value), policy, parent)); - if (!value_ || !s.add(value_)) - return handle(); - } - return s.release(); - } - - PYBIND11_TYPE_CASTER(type, _("Set[") + key_conv::name + _("]")); -}; - -template struct map_caster { - using key_conv = make_caster; - using value_conv = make_caster; - - bool load(handle src, bool convert) { - if (!isinstance(src)) - return false; - auto d = reinterpret_borrow(src); - value.clear(); - for (auto it : d) { - key_conv kconv; - value_conv vconv; - if (!kconv.load(it.first.ptr(), convert) || - !vconv.load(it.second.ptr(), convert)) - return false; - value.emplace(cast_op(std::move(kconv)), cast_op(std::move(vconv))); - } - return true; - } - - template - static handle cast(T &&src, return_value_policy policy, handle parent) { - dict d; - for (auto &&kv : src) { - auto key = reinterpret_steal(key_conv::cast(forward_like(kv.first), policy, parent)); - auto value = reinterpret_steal(value_conv::cast(forward_like(kv.second), policy, parent)); - if (!key || !value) - return handle(); - d[key] = value; - } - return d.release(); - } - - PYBIND11_TYPE_CASTER(Type, _("Dict[") + key_conv::name + _(", ") + value_conv::name + _("]")); -}; - -template struct list_caster { - using value_conv = make_caster; - - bool load(handle src, bool convert) { - if (!isinstance(src)) - return false; - auto s = reinterpret_borrow(src); - value.clear(); - reserve_maybe(s, &value); - for (auto it : s) { - value_conv conv; - if (!conv.load(it, convert)) - return false; - value.push_back(cast_op(std::move(conv))); - } - return true; - } - -private: - template ().reserve(0)), void>::value, int> = 0> - void reserve_maybe(sequence s, Type *) { value.reserve(s.size()); } - void reserve_maybe(sequence, void *) { } - -public: - template - static handle cast(T &&src, return_value_policy policy, handle parent) { - list l(src.size()); - size_t index = 0; - for (auto &&value : src) { - auto value_ = reinterpret_steal(value_conv::cast(forward_like(value), policy, parent)); - if (!value_) - return handle(); - PyList_SET_ITEM(l.ptr(), (ssize_t) index++, value_.release().ptr()); // steals a reference - } - return l.release(); - } - - PYBIND11_TYPE_CASTER(Type, _("List[") + value_conv::name + _("]")); -}; - -template struct type_caster> - : list_caster, Type> { }; - -template struct type_caster> - : list_caster, Type> { }; - -template struct array_caster { - using value_conv = make_caster; - -private: - template - bool require_size(enable_if_t size) { - if (value.size() != size) - value.resize(size); - return true; - } - template - bool require_size(enable_if_t size) { - return size == Size; - } - -public: - bool load(handle src, bool convert) { - if (!isinstance(src)) - return false; - auto l = reinterpret_borrow(src); - if (!require_size(l.size())) - return false; - size_t ctr = 0; - for (auto it : l) { - value_conv conv; - if (!conv.load(it, convert)) - return false; - value[ctr++] = cast_op(std::move(conv)); - } - return true; - } - - template - static handle cast(T &&src, return_value_policy policy, handle parent) { - list l(src.size()); - size_t index = 0; - for (auto &&value : src) { - auto value_ = reinterpret_steal(value_conv::cast(forward_like(value), policy, parent)); - if (!value_) - return handle(); - PyList_SET_ITEM(l.ptr(), (ssize_t) index++, value_.release().ptr()); // steals a reference - } - return l.release(); - } - - PYBIND11_TYPE_CASTER(ArrayType, _("List[") + value_conv::name + _(_(""), _("[") + _() + _("]")) + _("]")); -}; - -template struct type_caster> - : array_caster, Type, false, Size> { }; - -template struct type_caster> - : array_caster, Type, true> { }; - -template struct type_caster> - : set_caster, Key> { }; - -template struct type_caster> - : set_caster, Key> { }; - -template struct type_caster> - : map_caster, Key, Value> { }; - -template struct type_caster> - : map_caster, Key, Value> { }; - -// This type caster is intended to be used for std::optional and std::experimental::optional -template struct optional_caster { - using value_conv = make_caster; - - template - static handle cast(T_ &&src, return_value_policy policy, handle parent) { - if (!src) - return none().inc_ref(); - return value_conv::cast(*std::forward(src), policy, parent); - } - - bool load(handle src, bool convert) { - if (!src) { - return false; - } else if (src.is_none()) { - return true; // default-constructed value is already empty - } - value_conv inner_caster; - if (!inner_caster.load(src, convert)) - return false; - - value.emplace(cast_op(std::move(inner_caster))); - return true; - } - - PYBIND11_TYPE_CASTER(T, _("Optional[") + value_conv::name + _("]")); -}; - -#if PYBIND11_HAS_OPTIONAL -template struct type_caster> - : public optional_caster> {}; - -template<> struct type_caster - : public void_caster {}; -#endif - -#if PYBIND11_HAS_EXP_OPTIONAL -template struct type_caster> - : public optional_caster> {}; - -template<> struct type_caster - : public void_caster {}; -#endif - -/// Visit a variant and cast any found type to Python -struct variant_caster_visitor { - return_value_policy policy; - handle parent; - - using result_type = handle; // required by boost::variant in C++11 - - template - result_type operator()(T &&src) const { - return make_caster::cast(std::forward(src), policy, parent); - } -}; - -/// Helper class which abstracts away variant's `visit` function. `std::variant` and similar -/// `namespace::variant` types which provide a `namespace::visit()` function are handled here -/// automatically using argument-dependent lookup. Users can provide specializations for other -/// variant-like classes, e.g. `boost::variant` and `boost::apply_visitor`. -template class Variant> -struct visit_helper { - template - static auto call(Args &&...args) -> decltype(visit(std::forward(args)...)) { - return visit(std::forward(args)...); - } -}; - -/// Generic variant caster -template struct variant_caster; - -template class V, typename... Ts> -struct variant_caster> { - static_assert(sizeof...(Ts) > 0, "Variant must consist of at least one alternative."); - - template - bool load_alternative(handle src, bool convert, type_list) { - auto caster = make_caster(); - if (caster.load(src, convert)) { - value = cast_op(caster); - return true; - } - return load_alternative(src, convert, type_list{}); - } - - bool load_alternative(handle, bool, type_list<>) { return false; } - - bool load(handle src, bool convert) { - // Do a first pass without conversions to improve constructor resolution. - // E.g. `py::int_(1).cast>()` needs to fill the `int` - // slot of the variant. Without two-pass loading `double` would be filled - // because it appears first and a conversion is possible. - if (convert && load_alternative(src, false, type_list{})) - return true; - return load_alternative(src, convert, type_list{}); - } - - template - static handle cast(Variant &&src, return_value_policy policy, handle parent) { - return visit_helper::call(variant_caster_visitor{policy, parent}, - std::forward(src)); - } - - using Type = V; - PYBIND11_TYPE_CASTER(Type, _("Union[") + detail::concat(make_caster::name...) + _("]")); -}; - -#if PYBIND11_HAS_VARIANT -template -struct type_caster> : variant_caster> { }; -#endif -NAMESPACE_END(detail) - -inline std::ostream &operator<<(std::ostream &os, const handle &obj) { - os << (std::string) str(obj); - return os; -} - -NAMESPACE_END(PYBIND11_NAMESPACE) - -#if defined(_MSC_VER) -#pragma warning(pop) -#endif diff --git a/VFRendering/thirdparty/pybind11/include/pybind11/stl_bind.h b/VFRendering/thirdparty/pybind11/include/pybind11/stl_bind.h deleted file mode 100644 index 7ef687878..000000000 --- a/VFRendering/thirdparty/pybind11/include/pybind11/stl_bind.h +++ /dev/null @@ -1,599 +0,0 @@ -/* - pybind11/std_bind.h: Binding generators for STL data types - - Copyright (c) 2016 Sergey Lyskov and Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - -#pragma once - -#include "detail/common.h" -#include "operators.h" - -#include -#include - -NAMESPACE_BEGIN(PYBIND11_NAMESPACE) -NAMESPACE_BEGIN(detail) - -/* SFINAE helper class used by 'is_comparable */ -template struct container_traits { - template static std::true_type test_comparable(decltype(std::declval() == std::declval())*); - template static std::false_type test_comparable(...); - template static std::true_type test_value(typename T2::value_type *); - template static std::false_type test_value(...); - template static std::true_type test_pair(typename T2::first_type *, typename T2::second_type *); - template static std::false_type test_pair(...); - - static constexpr const bool is_comparable = std::is_same(nullptr))>::value; - static constexpr const bool is_pair = std::is_same(nullptr, nullptr))>::value; - static constexpr const bool is_vector = std::is_same(nullptr))>::value; - static constexpr const bool is_element = !is_pair && !is_vector; -}; - -/* Default: is_comparable -> std::false_type */ -template -struct is_comparable : std::false_type { }; - -/* For non-map data structures, check whether operator== can be instantiated */ -template -struct is_comparable< - T, enable_if_t::is_element && - container_traits::is_comparable>> - : std::true_type { }; - -/* For a vector/map data structure, recursively check the value type (which is std::pair for maps) */ -template -struct is_comparable::is_vector>> { - static constexpr const bool value = - is_comparable::value; -}; - -/* For pairs, recursively check the two data types */ -template -struct is_comparable::is_pair>> { - static constexpr const bool value = - is_comparable::value && - is_comparable::value; -}; - -/* Fallback functions */ -template void vector_if_copy_constructible(const Args &...) { } -template void vector_if_equal_operator(const Args &...) { } -template void vector_if_insertion_operator(const Args &...) { } -template void vector_modifiers(const Args &...) { } - -template -void vector_if_copy_constructible(enable_if_t::value, Class_> &cl) { - cl.def(init(), "Copy constructor"); -} - -template -void vector_if_equal_operator(enable_if_t::value, Class_> &cl) { - using T = typename Vector::value_type; - - cl.def(self == self); - cl.def(self != self); - - cl.def("count", - [](const Vector &v, const T &x) { - return std::count(v.begin(), v.end(), x); - }, - arg("x"), - "Return the number of times ``x`` appears in the list" - ); - - cl.def("remove", [](Vector &v, const T &x) { - auto p = std::find(v.begin(), v.end(), x); - if (p != v.end()) - v.erase(p); - else - throw value_error(); - }, - arg("x"), - "Remove the first item from the list whose value is x. " - "It is an error if there is no such item." - ); - - cl.def("__contains__", - [](const Vector &v, const T &x) { - return std::find(v.begin(), v.end(), x) != v.end(); - }, - arg("x"), - "Return true the container contains ``x``" - ); -} - -// Vector modifiers -- requires a copyable vector_type: -// (Technically, some of these (pop and __delitem__) don't actually require copyability, but it seems -// silly to allow deletion but not insertion, so include them here too.) -template -void vector_modifiers(enable_if_t::value, Class_> &cl) { - using T = typename Vector::value_type; - using SizeType = typename Vector::size_type; - using DiffType = typename Vector::difference_type; - - cl.def("append", - [](Vector &v, const T &value) { v.push_back(value); }, - arg("x"), - "Add an item to the end of the list"); - - cl.def(init([](iterable it) { - auto v = std::unique_ptr(new Vector()); - v->reserve(len(it)); - for (handle h : it) - v->push_back(h.cast()); - return v.release(); - })); - - cl.def("extend", - [](Vector &v, const Vector &src) { - v.insert(v.end(), src.begin(), src.end()); - }, - arg("L"), - "Extend the list by appending all the items in the given list" - ); - - cl.def("insert", - [](Vector &v, SizeType i, const T &x) { - if (i > v.size()) - throw index_error(); - v.insert(v.begin() + (DiffType) i, x); - }, - arg("i") , arg("x"), - "Insert an item at a given position." - ); - - cl.def("pop", - [](Vector &v) { - if (v.empty()) - throw index_error(); - T t = v.back(); - v.pop_back(); - return t; - }, - "Remove and return the last item" - ); - - cl.def("pop", - [](Vector &v, SizeType i) { - if (i >= v.size()) - throw index_error(); - T t = v[i]; - v.erase(v.begin() + (DiffType) i); - return t; - }, - arg("i"), - "Remove and return the item at index ``i``" - ); - - cl.def("__setitem__", - [](Vector &v, SizeType i, const T &t) { - if (i >= v.size()) - throw index_error(); - v[i] = t; - } - ); - - /// Slicing protocol - cl.def("__getitem__", - [](const Vector &v, slice slice) -> Vector * { - size_t start, stop, step, slicelength; - - if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) - throw error_already_set(); - - Vector *seq = new Vector(); - seq->reserve((size_t) slicelength); - - for (size_t i=0; ipush_back(v[start]); - start += step; - } - return seq; - }, - arg("s"), - "Retrieve list elements using a slice object" - ); - - cl.def("__setitem__", - [](Vector &v, slice slice, const Vector &value) { - size_t start, stop, step, slicelength; - if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) - throw error_already_set(); - - if (slicelength != value.size()) - throw std::runtime_error("Left and right hand size of slice assignment have different sizes!"); - - for (size_t i=0; i= v.size()) - throw index_error(); - v.erase(v.begin() + DiffType(i)); - }, - "Delete the list elements at index ``i``" - ); - - cl.def("__delitem__", - [](Vector &v, slice slice) { - size_t start, stop, step, slicelength; - - if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) - throw error_already_set(); - - if (step == 1 && false) { - v.erase(v.begin() + (DiffType) start, v.begin() + DiffType(start + slicelength)); - } else { - for (size_t i = 0; i < slicelength; ++i) { - v.erase(v.begin() + DiffType(start)); - start += step - 1; - } - } - }, - "Delete list elements using a slice object" - ); - -} - -// If the type has an operator[] that doesn't return a reference (most notably std::vector), -// we have to access by copying; otherwise we return by reference. -template using vector_needs_copy = negation< - std::is_same()[typename Vector::size_type()]), typename Vector::value_type &>>; - -// The usual case: access and iterate by reference -template -void vector_accessor(enable_if_t::value, Class_> &cl) { - using T = typename Vector::value_type; - using SizeType = typename Vector::size_type; - using ItType = typename Vector::iterator; - - cl.def("__getitem__", - [](Vector &v, SizeType i) -> T & { - if (i >= v.size()) - throw index_error(); - return v[i]; - }, - return_value_policy::reference_internal // ref + keepalive - ); - - cl.def("__iter__", - [](Vector &v) { - return make_iterator< - return_value_policy::reference_internal, ItType, ItType, T&>( - v.begin(), v.end()); - }, - keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */ - ); -} - -// The case for special objects, like std::vector, that have to be returned-by-copy: -template -void vector_accessor(enable_if_t::value, Class_> &cl) { - using T = typename Vector::value_type; - using SizeType = typename Vector::size_type; - using ItType = typename Vector::iterator; - cl.def("__getitem__", - [](const Vector &v, SizeType i) -> T { - if (i >= v.size()) - throw index_error(); - return v[i]; - } - ); - - cl.def("__iter__", - [](Vector &v) { - return make_iterator< - return_value_policy::copy, ItType, ItType, T>( - v.begin(), v.end()); - }, - keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */ - ); -} - -template auto vector_if_insertion_operator(Class_ &cl, std::string const &name) - -> decltype(std::declval() << std::declval(), void()) { - using size_type = typename Vector::size_type; - - cl.def("__repr__", - [name](Vector &v) { - std::ostringstream s; - s << name << '['; - for (size_type i=0; i < v.size(); ++i) { - s << v[i]; - if (i != v.size() - 1) - s << ", "; - } - s << ']'; - return s.str(); - }, - "Return the canonical string representation of this list." - ); -} - -// Provide the buffer interface for vectors if we have data() and we have a format for it -// GCC seems to have "void std::vector::data()" - doing SFINAE on the existence of data() is insufficient, we need to check it returns an appropriate pointer -template -struct vector_has_data_and_format : std::false_type {}; -template -struct vector_has_data_and_format::format(), std::declval().data()), typename Vector::value_type*>::value>> : std::true_type {}; - -// Add the buffer interface to a vector -template -enable_if_t...>::value> -vector_buffer(Class_& cl) { - using T = typename Vector::value_type; - - static_assert(vector_has_data_and_format::value, "There is not an appropriate format descriptor for this vector"); - - // numpy.h declares this for arbitrary types, but it may raise an exception and crash hard at runtime if PYBIND11_NUMPY_DTYPE hasn't been called, so check here - format_descriptor::format(); - - cl.def_buffer([](Vector& v) -> buffer_info { - return buffer_info(v.data(), static_cast(sizeof(T)), format_descriptor::format(), 1, {v.size()}, {sizeof(T)}); - }); - - cl.def(init([](buffer buf) { - auto info = buf.request(); - if (info.ndim != 1 || info.strides[0] % static_cast(sizeof(T))) - throw type_error("Only valid 1D buffers can be copied to a vector"); - if (!detail::compare_buffer_info::compare(info) || (ssize_t) sizeof(T) != info.itemsize) - throw type_error("Format mismatch (Python: " + info.format + " C++: " + format_descriptor::format() + ")"); - - auto vec = std::unique_ptr(new Vector()); - vec->reserve((size_t) info.shape[0]); - T *p = static_cast(info.ptr); - ssize_t step = info.strides[0] / static_cast(sizeof(T)); - T *end = p + info.shape[0] * step; - for (; p != end; p += step) - vec->push_back(*p); - return vec.release(); - })); - - return; -} - -template -enable_if_t...>::value> vector_buffer(Class_&) {} - -NAMESPACE_END(detail) - -// -// std::vector -// -template , typename... Args> -class_ bind_vector(handle scope, std::string const &name, Args&&... args) { - using Class_ = class_; - - // If the value_type is unregistered (e.g. a converting type) or is itself registered - // module-local then make the vector binding module-local as well: - using vtype = typename Vector::value_type; - auto vtype_info = detail::get_type_info(typeid(vtype)); - bool local = !vtype_info || vtype_info->module_local; - - Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward(args)...); - - // Declare the buffer interface if a buffer_protocol() is passed in - detail::vector_buffer(cl); - - cl.def(init<>()); - - // Register copy constructor (if possible) - detail::vector_if_copy_constructible(cl); - - // Register comparison-related operators and functions (if possible) - detail::vector_if_equal_operator(cl); - - // Register stream insertion operator (if possible) - detail::vector_if_insertion_operator(cl, name); - - // Modifiers require copyable vector value type - detail::vector_modifiers(cl); - - // Accessor and iterator; return by value if copyable, otherwise we return by ref + keep-alive - detail::vector_accessor(cl); - - cl.def("__bool__", - [](const Vector &v) -> bool { - return !v.empty(); - }, - "Check whether the list is nonempty" - ); - - cl.def("__len__", &Vector::size); - - - - -#if 0 - // C++ style functions deprecated, leaving it here as an example - cl.def(init()); - - cl.def("resize", - (void (Vector::*) (size_type count)) & Vector::resize, - "changes the number of elements stored"); - - cl.def("erase", - [](Vector &v, SizeType i) { - if (i >= v.size()) - throw index_error(); - v.erase(v.begin() + i); - }, "erases element at index ``i``"); - - cl.def("empty", &Vector::empty, "checks whether the container is empty"); - cl.def("size", &Vector::size, "returns the number of elements"); - cl.def("push_back", (void (Vector::*)(const T&)) &Vector::push_back, "adds an element to the end"); - cl.def("pop_back", &Vector::pop_back, "removes the last element"); - - cl.def("max_size", &Vector::max_size, "returns the maximum possible number of elements"); - cl.def("reserve", &Vector::reserve, "reserves storage"); - cl.def("capacity", &Vector::capacity, "returns the number of elements that can be held in currently allocated storage"); - cl.def("shrink_to_fit", &Vector::shrink_to_fit, "reduces memory usage by freeing unused memory"); - - cl.def("clear", &Vector::clear, "clears the contents"); - cl.def("swap", &Vector::swap, "swaps the contents"); - - cl.def("front", [](Vector &v) { - if (v.size()) return v.front(); - else throw index_error(); - }, "access the first element"); - - cl.def("back", [](Vector &v) { - if (v.size()) return v.back(); - else throw index_error(); - }, "access the last element "); - -#endif - - return cl; -} - - - -// -// std::map, std::unordered_map -// - -NAMESPACE_BEGIN(detail) - -/* Fallback functions */ -template void map_if_insertion_operator(const Args &...) { } -template void map_assignment(const Args &...) { } - -// Map assignment when copy-assignable: just copy the value -template -void map_assignment(enable_if_t::value, Class_> &cl) { - using KeyType = typename Map::key_type; - using MappedType = typename Map::mapped_type; - - cl.def("__setitem__", - [](Map &m, const KeyType &k, const MappedType &v) { - auto it = m.find(k); - if (it != m.end()) it->second = v; - else m.emplace(k, v); - } - ); -} - -// Not copy-assignable, but still copy-constructible: we can update the value by erasing and reinserting -template -void map_assignment(enable_if_t< - !std::is_copy_assignable::value && - is_copy_constructible::value, - Class_> &cl) { - using KeyType = typename Map::key_type; - using MappedType = typename Map::mapped_type; - - cl.def("__setitem__", - [](Map &m, const KeyType &k, const MappedType &v) { - // We can't use m[k] = v; because value type might not be default constructable - auto r = m.emplace(k, v); - if (!r.second) { - // value type is not copy assignable so the only way to insert it is to erase it first... - m.erase(r.first); - m.emplace(k, v); - } - } - ); -} - - -template auto map_if_insertion_operator(Class_ &cl, std::string const &name) --> decltype(std::declval() << std::declval() << std::declval(), void()) { - - cl.def("__repr__", - [name](Map &m) { - std::ostringstream s; - s << name << '{'; - bool f = false; - for (auto const &kv : m) { - if (f) - s << ", "; - s << kv.first << ": " << kv.second; - f = true; - } - s << '}'; - return s.str(); - }, - "Return the canonical string representation of this map." - ); -} - - -NAMESPACE_END(detail) - -template , typename... Args> -class_ bind_map(handle scope, const std::string &name, Args&&... args) { - using KeyType = typename Map::key_type; - using MappedType = typename Map::mapped_type; - using Class_ = class_; - - // If either type is a non-module-local bound type then make the map binding non-local as well; - // otherwise (e.g. both types are either module-local or converting) the map will be - // module-local. - auto tinfo = detail::get_type_info(typeid(MappedType)); - bool local = !tinfo || tinfo->module_local; - if (local) { - tinfo = detail::get_type_info(typeid(KeyType)); - local = !tinfo || tinfo->module_local; - } - - Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward(args)...); - - cl.def(init<>()); - - // Register stream insertion operator (if possible) - detail::map_if_insertion_operator(cl, name); - - cl.def("__bool__", - [](const Map &m) -> bool { return !m.empty(); }, - "Check whether the map is nonempty" - ); - - cl.def("__iter__", - [](Map &m) { return make_key_iterator(m.begin(), m.end()); }, - keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */ - ); - - cl.def("items", - [](Map &m) { return make_iterator(m.begin(), m.end()); }, - keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */ - ); - - cl.def("__getitem__", - [](Map &m, const KeyType &k) -> MappedType & { - auto it = m.find(k); - if (it == m.end()) - throw key_error(); - return it->second; - }, - return_value_policy::reference_internal // ref + keepalive - ); - - // Assignment provided only if the type is copyable - detail::map_assignment(cl); - - cl.def("__delitem__", - [](Map &m, const KeyType &k) { - auto it = m.find(k); - if (it == m.end()) - throw key_error(); - return m.erase(it); - } - ); - - cl.def("__len__", &Map::size); - - return cl; -} - -NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/VFRendering/thirdparty/pybind11/pybind11/__init__.py b/VFRendering/thirdparty/pybind11/pybind11/__init__.py deleted file mode 100644 index a765692fe..000000000 --- a/VFRendering/thirdparty/pybind11/pybind11/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -from ._version import version_info, __version__ # noqa: F401 imported but unused - - -def get_include(*args, **kwargs): - import os - try: - from pip import locations - return os.path.dirname( - locations.distutils_scheme('pybind11', *args, **kwargs)['headers']) - except ImportError: - return 'include' diff --git a/VFRendering/thirdparty/pybind11/pybind11/__main__.py b/VFRendering/thirdparty/pybind11/pybind11/__main__.py deleted file mode 100644 index 9ef837802..000000000 --- a/VFRendering/thirdparty/pybind11/pybind11/__main__.py +++ /dev/null @@ -1,37 +0,0 @@ -from __future__ import print_function - -import argparse -import sys -import sysconfig - -from . import get_include - - -def print_includes(): - dirs = [sysconfig.get_path('include'), - sysconfig.get_path('platinclude'), - get_include(), - get_include(True)] - - # Make unique but preserve order - unique_dirs = [] - for d in dirs: - if d not in unique_dirs: - unique_dirs.append(d) - - print(' '.join('-I' + d for d in unique_dirs)) - - -def main(): - parser = argparse.ArgumentParser(prog='python -m pybind11') - parser.add_argument('--includes', action='store_true', - help='Include flags for both pybind11 and Python headers.') - args = parser.parse_args() - if not sys.argv[1:]: - parser.print_help() - if args.includes: - print_includes() - - -if __name__ == '__main__': - main() diff --git a/VFRendering/thirdparty/pybind11/pybind11/_version.py b/VFRendering/thirdparty/pybind11/pybind11/_version.py deleted file mode 100644 index c046ed71e..000000000 --- a/VFRendering/thirdparty/pybind11/pybind11/_version.py +++ /dev/null @@ -1,2 +0,0 @@ -version_info = (2, 3, 'dev0') -__version__ = '.'.join(map(str, version_info)) diff --git a/VFRendering/thirdparty/pybind11/setup.cfg b/VFRendering/thirdparty/pybind11/setup.cfg deleted file mode 100644 index 369788b28..000000000 --- a/VFRendering/thirdparty/pybind11/setup.cfg +++ /dev/null @@ -1,10 +0,0 @@ -[bdist_wheel] -universal=1 - -[flake8] -max-line-length = 99 -show_source = True -exclude = .git, __pycache__, build, dist, docs, tools, venv -ignore = - # required for pretty matrix formatting: multiple spaces after `,` and `[` - E201, E241 diff --git a/VFRendering/thirdparty/pybind11/setup.py b/VFRendering/thirdparty/pybind11/setup.py deleted file mode 100644 index 5b03bb2ce..000000000 --- a/VFRendering/thirdparty/pybind11/setup.py +++ /dev/null @@ -1,108 +0,0 @@ -#!/usr/bin/env python - -# Setup script for PyPI; use CMakeFile.txt to build extension modules - -from setuptools import setup -from distutils.command.install_headers import install_headers -from pybind11 import __version__ -import os - -# Prevent installation of pybind11 headers by setting -# PYBIND11_USE_CMAKE. -if os.environ.get('PYBIND11_USE_CMAKE'): - headers = [] -else: - headers = [ - 'include/pybind11/detail/class.h', - 'include/pybind11/detail/common.h', - 'include/pybind11/detail/descr.h', - 'include/pybind11/detail/init.h', - 'include/pybind11/detail/internals.h', - 'include/pybind11/detail/typeid.h', - 'include/pybind11/attr.h', - 'include/pybind11/buffer_info.h', - 'include/pybind11/cast.h', - 'include/pybind11/chrono.h', - 'include/pybind11/common.h', - 'include/pybind11/complex.h', - 'include/pybind11/eigen.h', - 'include/pybind11/embed.h', - 'include/pybind11/eval.h', - 'include/pybind11/functional.h', - 'include/pybind11/iostream.h', - 'include/pybind11/numpy.h', - 'include/pybind11/operators.h', - 'include/pybind11/options.h', - 'include/pybind11/pybind11.h', - 'include/pybind11/pytypes.h', - 'include/pybind11/stl.h', - 'include/pybind11/stl_bind.h', - ] - - -class InstallHeaders(install_headers): - """Use custom header installer because the default one flattens subdirectories""" - def run(self): - if not self.distribution.headers: - return - - for header in self.distribution.headers: - subdir = os.path.dirname(os.path.relpath(header, 'include/pybind11')) - install_dir = os.path.join(self.install_dir, subdir) - self.mkpath(install_dir) - - (out, _) = self.copy_file(header, install_dir) - self.outfiles.append(out) - - -setup( - name='pybind11', - version=__version__, - description='Seamless operability between C++11 and Python', - author='Wenzel Jakob', - author_email='wenzel.jakob@epfl.ch', - url='https://github.com/pybind11/pybind11', - download_url='https://github.com/pybind11/pybind11/tarball/v' + __version__, - packages=['pybind11'], - license='BSD', - headers=headers, - cmdclass=dict(install_headers=InstallHeaders), - classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'Intended Audience :: Developers', - 'Topic :: Software Development :: Libraries :: Python Modules', - 'Topic :: Utilities', - 'Programming Language :: C++', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.2', - 'Programming Language :: Python :: 3.3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'License :: OSI Approved :: BSD License' - ], - keywords='C++11, Python bindings', - long_description="""pybind11 is a lightweight header-only library that -exposes C++ types in Python and vice versa, mainly to create Python bindings of -existing C++ code. Its goals and syntax are similar to the excellent -Boost.Python by David Abrahams: to minimize boilerplate code in traditional -extension modules by inferring type information using compile-time -introspection. - -The main issue with Boost.Python-and the reason for creating such a similar -project-is Boost. Boost is an enormously large and complex suite of utility -libraries that works with almost every C++ compiler in existence. This -compatibility has its cost: arcane template tricks and workarounds are -necessary to support the oldest and buggiest of compiler specimens. Now that -C++11-compatible compilers are widely available, this heavy machinery has -become an excessively large and unnecessary dependency. - -Think of this library as a tiny self-contained version of Boost.Python with -everything stripped away that isn't relevant for binding generation. Without -comments, the core header files only require ~4K lines of code and depend on -Python (2.7 or 3.x, or PyPy2.7 >= 5.7) and the C++ standard library. This -compact implementation was possible thanks to some of the new C++11 language -features (specifically: tuples, lambda functions and variadic templates). Since -its creation, this library has grown beyond Boost.Python in many ways, leading -to dramatically simpler binding code in many common situations.""") diff --git a/VFRendering/thirdparty/pybind11/tools/FindCatch.cmake b/VFRendering/thirdparty/pybind11/tools/FindCatch.cmake deleted file mode 100644 index 9d490c5aa..000000000 --- a/VFRendering/thirdparty/pybind11/tools/FindCatch.cmake +++ /dev/null @@ -1,57 +0,0 @@ -# - Find the Catch test framework or download it (single header) -# -# This is a quick module for internal use. It assumes that Catch is -# REQUIRED and that a minimum version is provided (not EXACT). If -# a suitable version isn't found locally, the single header file -# will be downloaded and placed in the build dir: PROJECT_BINARY_DIR. -# -# This code sets the following variables: -# CATCH_INCLUDE_DIR - path to catch.hpp -# CATCH_VERSION - version number - -if(NOT Catch_FIND_VERSION) - message(FATAL_ERROR "A version number must be specified.") -elseif(Catch_FIND_REQUIRED) - message(FATAL_ERROR "This module assumes Catch is not required.") -elseif(Catch_FIND_VERSION_EXACT) - message(FATAL_ERROR "Exact version numbers are not supported, only minimum.") -endif() - -# Extract the version number from catch.hpp -function(_get_catch_version) - file(STRINGS "${CATCH_INCLUDE_DIR}/catch.hpp" version_line REGEX "Catch v.*" LIMIT_COUNT 1) - if(version_line MATCHES "Catch v([0-9]+)\\.([0-9]+)\\.([0-9]+)") - set(CATCH_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}" PARENT_SCOPE) - endif() -endfunction() - -# Download the single-header version of Catch -function(_download_catch version destination_dir) - message(STATUS "Downloading catch v${version}...") - set(url https://github.com/philsquared/Catch/releases/download/v${version}/catch.hpp) - file(DOWNLOAD ${url} "${destination_dir}/catch.hpp" STATUS status) - list(GET status 0 error) - if(error) - message(FATAL_ERROR "Could not download ${url}") - endif() - set(CATCH_INCLUDE_DIR "${destination_dir}" CACHE INTERNAL "") -endfunction() - -# Look for catch locally -find_path(CATCH_INCLUDE_DIR NAMES catch.hpp PATH_SUFFIXES catch) -if(CATCH_INCLUDE_DIR) - _get_catch_version() -endif() - -# Download the header if it wasn't found or if it's outdated -if(NOT CATCH_VERSION OR CATCH_VERSION VERSION_LESS ${Catch_FIND_VERSION}) - if(DOWNLOAD_CATCH) - _download_catch(${Catch_FIND_VERSION} "${PROJECT_BINARY_DIR}/catch/") - _get_catch_version() - else() - set(CATCH_FOUND FALSE) - return() - endif() -endif() - -set(CATCH_FOUND TRUE) diff --git a/VFRendering/thirdparty/pybind11/tools/FindEigen3.cmake b/VFRendering/thirdparty/pybind11/tools/FindEigen3.cmake deleted file mode 100644 index 9c546a05d..000000000 --- a/VFRendering/thirdparty/pybind11/tools/FindEigen3.cmake +++ /dev/null @@ -1,81 +0,0 @@ -# - Try to find Eigen3 lib -# -# This module supports requiring a minimum version, e.g. you can do -# find_package(Eigen3 3.1.2) -# to require version 3.1.2 or newer of Eigen3. -# -# Once done this will define -# -# EIGEN3_FOUND - system has eigen lib with correct version -# EIGEN3_INCLUDE_DIR - the eigen include directory -# EIGEN3_VERSION - eigen version - -# Copyright (c) 2006, 2007 Montel Laurent, -# Copyright (c) 2008, 2009 Gael Guennebaud, -# Copyright (c) 2009 Benoit Jacob -# Redistribution and use is allowed according to the terms of the 2-clause BSD license. - -if(NOT Eigen3_FIND_VERSION) - if(NOT Eigen3_FIND_VERSION_MAJOR) - set(Eigen3_FIND_VERSION_MAJOR 2) - endif(NOT Eigen3_FIND_VERSION_MAJOR) - if(NOT Eigen3_FIND_VERSION_MINOR) - set(Eigen3_FIND_VERSION_MINOR 91) - endif(NOT Eigen3_FIND_VERSION_MINOR) - if(NOT Eigen3_FIND_VERSION_PATCH) - set(Eigen3_FIND_VERSION_PATCH 0) - endif(NOT Eigen3_FIND_VERSION_PATCH) - - set(Eigen3_FIND_VERSION "${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}") -endif(NOT Eigen3_FIND_VERSION) - -macro(_eigen3_check_version) - file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header) - - string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}") - set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}") - string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen3_major_version_match "${_eigen3_version_header}") - set(EIGEN3_MAJOR_VERSION "${CMAKE_MATCH_1}") - string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen3_minor_version_match "${_eigen3_version_header}") - set(EIGEN3_MINOR_VERSION "${CMAKE_MATCH_1}") - - set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION}) - if(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) - set(EIGEN3_VERSION_OK FALSE) - else(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) - set(EIGEN3_VERSION_OK TRUE) - endif(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) - - if(NOT EIGEN3_VERSION_OK) - - message(STATUS "Eigen3 version ${EIGEN3_VERSION} found in ${EIGEN3_INCLUDE_DIR}, " - "but at least version ${Eigen3_FIND_VERSION} is required") - endif(NOT EIGEN3_VERSION_OK) -endmacro(_eigen3_check_version) - -if (EIGEN3_INCLUDE_DIR) - - # in cache already - _eigen3_check_version() - set(EIGEN3_FOUND ${EIGEN3_VERSION_OK}) - -else (EIGEN3_INCLUDE_DIR) - - find_path(EIGEN3_INCLUDE_DIR NAMES signature_of_eigen3_matrix_library - PATHS - ${CMAKE_INSTALL_PREFIX}/include - ${KDE4_INCLUDE_DIR} - PATH_SUFFIXES eigen3 eigen - ) - - if(EIGEN3_INCLUDE_DIR) - _eigen3_check_version() - endif(EIGEN3_INCLUDE_DIR) - - include(FindPackageHandleStandardArgs) - find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK) - - mark_as_advanced(EIGEN3_INCLUDE_DIR) - -endif(EIGEN3_INCLUDE_DIR) - diff --git a/VFRendering/thirdparty/pybind11/tools/FindPythonLibsNew.cmake b/VFRendering/thirdparty/pybind11/tools/FindPythonLibsNew.cmake deleted file mode 100644 index ad3ed48fa..000000000 --- a/VFRendering/thirdparty/pybind11/tools/FindPythonLibsNew.cmake +++ /dev/null @@ -1,195 +0,0 @@ -# - Find python libraries -# This module finds the libraries corresponding to the Python interpeter -# FindPythonInterp provides. -# This code sets the following variables: -# -# PYTHONLIBS_FOUND - have the Python libs been found -# PYTHON_PREFIX - path to the Python installation -# PYTHON_LIBRARIES - path to the python library -# PYTHON_INCLUDE_DIRS - path to where Python.h is found -# PYTHON_MODULE_EXTENSION - lib extension, e.g. '.so' or '.pyd' -# PYTHON_MODULE_PREFIX - lib name prefix: usually an empty string -# PYTHON_SITE_PACKAGES - path to installation site-packages -# PYTHON_IS_DEBUG - whether the Python interpreter is a debug build -# -# Thanks to talljimbo for the patch adding the 'LDVERSION' config -# variable usage. - -#============================================================================= -# Copyright 2001-2009 Kitware, Inc. -# Copyright 2012 Continuum Analytics, Inc. -# -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# * Neither the names of Kitware, Inc., the Insight Software Consortium, -# nor the names of their contributors may be used to endorse or promote -# products derived from this software without specific prior written -# permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#============================================================================= - -# Checking for the extension makes sure that `LibsNew` was found and not just `Libs`. -if(PYTHONLIBS_FOUND AND PYTHON_MODULE_EXTENSION) - return() -endif() - -# Use the Python interpreter to find the libs. -if(PythonLibsNew_FIND_REQUIRED) - find_package(PythonInterp ${PythonLibsNew_FIND_VERSION} REQUIRED) -else() - find_package(PythonInterp ${PythonLibsNew_FIND_VERSION}) -endif() - -if(NOT PYTHONINTERP_FOUND) - set(PYTHONLIBS_FOUND FALSE) - return() -endif() - -# According to http://stackoverflow.com/questions/646518/python-how-to-detect-debug-interpreter -# testing whether sys has the gettotalrefcount function is a reliable, cross-platform -# way to detect a CPython debug interpreter. -# -# The library suffix is from the config var LDVERSION sometimes, otherwise -# VERSION. VERSION will typically be like "2.7" on unix, and "27" on windows. -execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" - "from distutils import sysconfig as s;import sys;import struct; -print('.'.join(str(v) for v in sys.version_info)); -print(sys.prefix); -print(s.get_python_inc(plat_specific=True)); -print(s.get_python_lib(plat_specific=True)); -print(s.get_config_var('SO')); -print(hasattr(sys, 'gettotalrefcount')+0); -print(struct.calcsize('@P')); -print(s.get_config_var('LDVERSION') or s.get_config_var('VERSION')); -print(s.get_config_var('LIBDIR') or ''); -print(s.get_config_var('MULTIARCH') or ''); -" - RESULT_VARIABLE _PYTHON_SUCCESS - OUTPUT_VARIABLE _PYTHON_VALUES - ERROR_VARIABLE _PYTHON_ERROR_VALUE) - -if(NOT _PYTHON_SUCCESS MATCHES 0) - if(PythonLibsNew_FIND_REQUIRED) - message(FATAL_ERROR - "Python config failure:\n${_PYTHON_ERROR_VALUE}") - endif() - set(PYTHONLIBS_FOUND FALSE) - return() -endif() - -# Convert the process output into a list -string(REGEX REPLACE ";" "\\\\;" _PYTHON_VALUES ${_PYTHON_VALUES}) -string(REGEX REPLACE "\n" ";" _PYTHON_VALUES ${_PYTHON_VALUES}) -list(GET _PYTHON_VALUES 0 _PYTHON_VERSION_LIST) -list(GET _PYTHON_VALUES 1 PYTHON_PREFIX) -list(GET _PYTHON_VALUES 2 PYTHON_INCLUDE_DIR) -list(GET _PYTHON_VALUES 3 PYTHON_SITE_PACKAGES) -list(GET _PYTHON_VALUES 4 PYTHON_MODULE_EXTENSION) -list(GET _PYTHON_VALUES 5 PYTHON_IS_DEBUG) -list(GET _PYTHON_VALUES 6 PYTHON_SIZEOF_VOID_P) -list(GET _PYTHON_VALUES 7 PYTHON_LIBRARY_SUFFIX) -list(GET _PYTHON_VALUES 8 PYTHON_LIBDIR) -list(GET _PYTHON_VALUES 9 PYTHON_MULTIARCH) - -# Make sure the Python has the same pointer-size as the chosen compiler -# Skip if CMAKE_SIZEOF_VOID_P is not defined -if(CMAKE_SIZEOF_VOID_P AND (NOT "${PYTHON_SIZEOF_VOID_P}" STREQUAL "${CMAKE_SIZEOF_VOID_P}")) - if(PythonLibsNew_FIND_REQUIRED) - math(EXPR _PYTHON_BITS "${PYTHON_SIZEOF_VOID_P} * 8") - math(EXPR _CMAKE_BITS "${CMAKE_SIZEOF_VOID_P} * 8") - message(FATAL_ERROR - "Python config failure: Python is ${_PYTHON_BITS}-bit, " - "chosen compiler is ${_CMAKE_BITS}-bit") - endif() - set(PYTHONLIBS_FOUND FALSE) - return() -endif() - -# The built-in FindPython didn't always give the version numbers -string(REGEX REPLACE "\\." ";" _PYTHON_VERSION_LIST ${_PYTHON_VERSION_LIST}) -list(GET _PYTHON_VERSION_LIST 0 PYTHON_VERSION_MAJOR) -list(GET _PYTHON_VERSION_LIST 1 PYTHON_VERSION_MINOR) -list(GET _PYTHON_VERSION_LIST 2 PYTHON_VERSION_PATCH) - -# Make sure all directory separators are '/' -string(REGEX REPLACE "\\\\" "/" PYTHON_PREFIX ${PYTHON_PREFIX}) -string(REGEX REPLACE "\\\\" "/" PYTHON_INCLUDE_DIR ${PYTHON_INCLUDE_DIR}) -string(REGEX REPLACE "\\\\" "/" PYTHON_SITE_PACKAGES ${PYTHON_SITE_PACKAGES}) - -if(CMAKE_HOST_WIN32) - set(PYTHON_LIBRARY - "${PYTHON_PREFIX}/libs/Python${PYTHON_LIBRARY_SUFFIX}.lib") - - # when run in a venv, PYTHON_PREFIX points to it. But the libraries remain in the - # original python installation. They may be found relative to PYTHON_INCLUDE_DIR. - if(NOT EXISTS "${PYTHON_LIBRARY}") - get_filename_component(_PYTHON_ROOT ${PYTHON_INCLUDE_DIR} DIRECTORY) - set(PYTHON_LIBRARY - "${_PYTHON_ROOT}/libs/Python${PYTHON_LIBRARY_SUFFIX}.lib") - endif() - - # raise an error if the python libs are still not found. - if(NOT EXISTS "${PYTHON_LIBRARY}") - message(FATAL_ERROR "Python libraries not found") - endif() - -else() - if(PYTHON_MULTIARCH) - set(_PYTHON_LIBS_SEARCH "${PYTHON_LIBDIR}/${PYTHON_MULTIARCH}" "${PYTHON_LIBDIR}") - else() - set(_PYTHON_LIBS_SEARCH "${PYTHON_LIBDIR}") - endif() - #message(STATUS "Searching for Python libs in ${_PYTHON_LIBS_SEARCH}") - # Probably this needs to be more involved. It would be nice if the config - # information the python interpreter itself gave us were more complete. - find_library(PYTHON_LIBRARY - NAMES "python${PYTHON_LIBRARY_SUFFIX}" - PATHS ${_PYTHON_LIBS_SEARCH} - NO_DEFAULT_PATH) - - # If all else fails, just set the name/version and let the linker figure out the path. - if(NOT PYTHON_LIBRARY) - set(PYTHON_LIBRARY python${PYTHON_LIBRARY_SUFFIX}) - endif() -endif() - -MARK_AS_ADVANCED( - PYTHON_LIBRARY - PYTHON_INCLUDE_DIR -) - -# We use PYTHON_INCLUDE_DIR, PYTHON_LIBRARY and PYTHON_DEBUG_LIBRARY for the -# cache entries because they are meant to specify the location of a single -# library. We now set the variables listed by the documentation for this -# module. -SET(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}") -SET(PYTHON_LIBRARIES "${PYTHON_LIBRARY}") -SET(PYTHON_DEBUG_LIBRARIES "${PYTHON_DEBUG_LIBRARY}") - -find_package_message(PYTHON - "Found PythonLibs: ${PYTHON_LIBRARY}" - "${PYTHON_EXECUTABLE}${PYTHON_VERSION}") - -set(PYTHONLIBS_FOUND TRUE) diff --git a/VFRendering/thirdparty/pybind11/tools/check-style.sh b/VFRendering/thirdparty/pybind11/tools/check-style.sh deleted file mode 100644 index 0a9f7d24f..000000000 --- a/VFRendering/thirdparty/pybind11/tools/check-style.sh +++ /dev/null @@ -1,70 +0,0 @@ -#!/bin/bash -# -# Script to check include/test code for common pybind11 code style errors. -# -# This script currently checks for -# -# 1. use of tabs instead of spaces -# 2. MSDOS-style CRLF endings -# 3. trailing spaces -# 4. missing space between keyword and parenthesis, e.g.: for(, if(, while( -# 5. Missing space between right parenthesis and brace, e.g. 'for (...){' -# 6. opening brace on its own line. It should always be on the same line as the -# if/while/for/do statement. -# -# Invoke as: tools/check-style.sh -# - -check_style_errors=0 -IFS=$'\n' - -found="$( GREP_COLORS='mt=41' GREP_COLOR='41' grep $'\t' include tests/*.{cpp,py,h} docs/*.rst -rn --color=always )" -if [ -n "$found" ]; then - # The mt=41 sets a red background for matched tabs: - echo -e '\033[31;01mError: found tab characters in the following files:\033[0m' - check_style_errors=1 - echo "$found" | sed -e 's/^/ /' -fi - - -found="$( grep -IUlr $'\r' include tests/*.{cpp,py,h} docs/*.rst --color=always )" -if [ -n "$found" ]; then - echo -e '\033[31;01mError: found CRLF characters in the following files:\033[0m' - check_style_errors=1 - echo "$found" | sed -e 's/^/ /' -fi - -found="$(GREP_COLORS='mt=41' GREP_COLOR='41' grep '[[:blank:]]\+$' include tests/*.{cpp,py,h} docs/*.rst -rn --color=always )" -if [ -n "$found" ]; then - # The mt=41 sets a red background for matched trailing spaces - echo -e '\033[31;01mError: found trailing spaces in the following files:\033[0m' - check_style_errors=1 - echo "$found" | sed -e 's/^/ /' -fi - -found="$(grep '\<\(if\|for\|while\|catch\)(\|){' include tests/*.{cpp,h} -rn --color=always)" -if [ -n "$found" ]; then - echo -e '\033[31;01mError: found the following coding style problems:\033[0m' - check_style_errors=1 - echo "$found" | sed -e 's/^/ /' -fi - -found="$(awk ' -function prefix(filename, lineno) { - return " \033[35m" filename "\033[36m:\033[32m" lineno "\033[36m:\033[0m" -} -function mark(pattern, string) { sub(pattern, "\033[01;31m&\033[0m", string); return string } -last && /^\s*{/ { - print prefix(FILENAME, FNR-1) mark("\\)\\s*$", last) - print prefix(FILENAME, FNR) mark("^\\s*{", $0) - last="" -} -{ last = /(if|for|while|catch|switch)\s*\(.*\)\s*$/ ? $0 : "" } -' $(find include -type f) tests/*.{cpp,h} docs/*.rst)" -if [ -n "$found" ]; then - check_style_errors=1 - echo -e '\033[31;01mError: braces should occur on the same line as the if/while/.. statement. Found issues in the following files:\033[0m' - echo "$found" -fi - -exit $check_style_errors diff --git a/VFRendering/thirdparty/pybind11/tools/clang/.gitignore b/VFRendering/thirdparty/pybind11/tools/clang/.gitignore deleted file mode 100644 index 8819bdaf3..000000000 --- a/VFRendering/thirdparty/pybind11/tools/clang/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -*.swp -*.swo -*.pyc -__pycache__ diff --git a/VFRendering/thirdparty/pybind11/tools/clang/LICENSE.TXT b/VFRendering/thirdparty/pybind11/tools/clang/LICENSE.TXT deleted file mode 100644 index 6c224f84c..000000000 --- a/VFRendering/thirdparty/pybind11/tools/clang/LICENSE.TXT +++ /dev/null @@ -1,63 +0,0 @@ -============================================================================== -LLVM Release License -============================================================================== -University of Illinois/NCSA -Open Source License - -Copyright (c) 2007-2012 University of Illinois at Urbana-Champaign. -All rights reserved. - -Developed by: - - LLVM Team - - University of Illinois at Urbana-Champaign - - http://llvm.org - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal with -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimers. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimers in the - documentation and/or other materials provided with the distribution. - - * Neither the names of the LLVM Team, University of Illinois at - Urbana-Champaign, nor the names of its contributors may be used to - endorse or promote products derived from this Software without specific - prior written permission. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE -SOFTWARE. - -============================================================================== -The LLVM software contains code written by third parties. Such software will -have its own individual LICENSE.TXT file in the directory in which it appears. -This file will describe the copyrights, license, and restrictions which apply -to that code. - -The disclaimer of warranty in the University of Illinois Open Source License -applies to all code in the LLVM Distribution, and nothing in any of the -other licenses gives permission to use the names of the LLVM Team or the -University of Illinois to endorse or promote products derived from this -Software. - -The following pieces of software have additional or alternate copyrights, -licenses, and/or restrictions: - -Program Directory -------- --------- - - diff --git a/VFRendering/thirdparty/pybind11/tools/clang/README.md b/VFRendering/thirdparty/pybind11/tools/clang/README.md deleted file mode 100644 index efb892166..000000000 --- a/VFRendering/thirdparty/pybind11/tools/clang/README.md +++ /dev/null @@ -1,2 +0,0 @@ -This is simply clang's Python bindings (clang.cindex) ported to Python 3. Please see http://llvm.org/svn/llvm-project/cfe/trunk/bindings/python/ for the original project. - diff --git a/VFRendering/thirdparty/pybind11/tools/clang/__init__.py b/VFRendering/thirdparty/pybind11/tools/clang/__init__.py deleted file mode 100644 index 88f308123..000000000 --- a/VFRendering/thirdparty/pybind11/tools/clang/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -#===- __init__.py - Clang Python Bindings --------------------*- python -*--===# -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -#===------------------------------------------------------------------------===# - -r""" -Clang Library Bindings -====================== - -This package provides access to the Clang compiler and libraries. - -The available modules are: - - cindex - - Bindings for the Clang indexing library. -""" - -__all__ = ['cindex'] - diff --git a/VFRendering/thirdparty/pybind11/tools/clang/cindex.py b/VFRendering/thirdparty/pybind11/tools/clang/cindex.py deleted file mode 100644 index 3a083de0d..000000000 --- a/VFRendering/thirdparty/pybind11/tools/clang/cindex.py +++ /dev/null @@ -1,3884 +0,0 @@ -#===- cindex.py - Python Indexing Library Bindings -----------*- python -*--===# -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -#===------------------------------------------------------------------------===# - -r""" -Clang Indexing Library Bindings -=============================== - -This module provides an interface to the Clang indexing library. It is a -low-level interface to the indexing library which attempts to match the Clang -API directly while also being "pythonic". Notable differences from the C API -are: - - * string results are returned as Python strings, not CXString objects. - - * null cursors are translated to None. - - * access to child cursors is done via iteration, not visitation. - -The major indexing objects are: - - Index - - The top-level object which manages some global library state. - - TranslationUnit - - High-level object encapsulating the AST for a single translation unit. These - can be loaded from .ast files or parsed on the fly. - - Cursor - - Generic object for representing a node in the AST. - - SourceRange, SourceLocation, and File - - Objects representing information about the input source. - -Most object information is exposed using properties, when the underlying API -call is efficient. -""" - -# TODO -# ==== -# -# o API support for invalid translation units. Currently we can't even get the -# diagnostics on failure because they refer to locations in an object that -# will have been invalidated. -# -# o fix memory management issues (currently client must hold on to index and -# translation unit, or risk crashes). -# -# o expose code completion APIs. -# -# o cleanup ctypes wrapping, would be nice to separate the ctypes details more -# clearly, and hide from the external interface (i.e., help(cindex)). -# -# o implement additional SourceLocation, SourceRange, and File methods. - -from ctypes import * -import collections - -import clang.enumerations - -# ctypes doesn't implicitly convert c_void_p to the appropriate wrapper -# object. This is a problem, because it means that from_parameter will see an -# integer and pass the wrong value on platforms where int != void*. Work around -# this by marshalling object arguments as void**. -c_object_p = POINTER(c_void_p) - -callbacks = {} - -### Exception Classes ### - -class TranslationUnitLoadError(Exception): - """Represents an error that occurred when loading a TranslationUnit. - - This is raised in the case where a TranslationUnit could not be - instantiated due to failure in the libclang library. - - FIXME: Make libclang expose additional error information in this scenario. - """ - pass - -class TranslationUnitSaveError(Exception): - """Represents an error that occurred when saving a TranslationUnit. - - Each error has associated with it an enumerated value, accessible under - e.save_error. Consumers can compare the value with one of the ERROR_ - constants in this class. - """ - - # Indicates that an unknown error occurred. This typically indicates that - # I/O failed during save. - ERROR_UNKNOWN = 1 - - # Indicates that errors during translation prevented saving. The errors - # should be available via the TranslationUnit's diagnostics. - ERROR_TRANSLATION_ERRORS = 2 - - # Indicates that the translation unit was somehow invalid. - ERROR_INVALID_TU = 3 - - def __init__(self, enumeration, message): - assert isinstance(enumeration, int) - - if enumeration < 1 or enumeration > 3: - raise Exception("Encountered undefined TranslationUnit save error " - "constant: %d. Please file a bug to have this " - "value supported." % enumeration) - - self.save_error = enumeration - Exception.__init__(self, 'Error %d: %s' % (enumeration, message)) - -### Structures and Utility Classes ### - -class CachedProperty(object): - """Decorator that lazy-loads the value of a property. - - The first time the property is accessed, the original property function is - executed. The value it returns is set as the new value of that instance's - property, replacing the original method. - """ - - def __init__(self, wrapped): - self.wrapped = wrapped - try: - self.__doc__ = wrapped.__doc__ - except: - pass - - def __get__(self, instance, instance_type=None): - if instance is None: - return self - - value = self.wrapped(instance) - setattr(instance, self.wrapped.__name__, value) - - return value - - -class _CXString(Structure): - """Helper for transforming CXString results.""" - - _fields_ = [("spelling", c_char_p), ("free", c_int)] - - def __del__(self): - conf.lib.clang_disposeString(self) - - @staticmethod - def from_result(res, fn, args): - assert isinstance(res, _CXString) - return conf.lib.clang_getCString(res) - -class SourceLocation(Structure): - """ - A SourceLocation represents a particular location within a source file. - """ - _fields_ = [("ptr_data", c_void_p * 2), ("int_data", c_uint)] - _data = None - - def _get_instantiation(self): - if self._data is None: - f, l, c, o = c_object_p(), c_uint(), c_uint(), c_uint() - conf.lib.clang_getInstantiationLocation(self, byref(f), byref(l), - byref(c), byref(o)) - if f: - f = File(f) - else: - f = None - self._data = (f, int(l.value), int(c.value), int(o.value)) - return self._data - - @staticmethod - def from_position(tu, file, line, column): - """ - Retrieve the source location associated with a given file/line/column in - a particular translation unit. - """ - return conf.lib.clang_getLocation(tu, file, line, column) - - @staticmethod - def from_offset(tu, file, offset): - """Retrieve a SourceLocation from a given character offset. - - tu -- TranslationUnit file belongs to - file -- File instance to obtain offset from - offset -- Integer character offset within file - """ - return conf.lib.clang_getLocationForOffset(tu, file, offset) - - @property - def file(self): - """Get the file represented by this source location.""" - return self._get_instantiation()[0] - - @property - def line(self): - """Get the line represented by this source location.""" - return self._get_instantiation()[1] - - @property - def column(self): - """Get the column represented by this source location.""" - return self._get_instantiation()[2] - - @property - def offset(self): - """Get the file offset represented by this source location.""" - return self._get_instantiation()[3] - - def __eq__(self, other): - return conf.lib.clang_equalLocations(self, other) - - def __ne__(self, other): - return not self.__eq__(other) - - def __repr__(self): - if self.file: - filename = self.file.name - else: - filename = None - return "" % ( - filename, self.line, self.column) - -class SourceRange(Structure): - """ - A SourceRange describes a range of source locations within the source - code. - """ - _fields_ = [ - ("ptr_data", c_void_p * 2), - ("begin_int_data", c_uint), - ("end_int_data", c_uint)] - - # FIXME: Eliminate this and make normal constructor? Requires hiding ctypes - # object. - @staticmethod - def from_locations(start, end): - return conf.lib.clang_getRange(start, end) - - @property - def start(self): - """ - Return a SourceLocation representing the first character within a - source range. - """ - return conf.lib.clang_getRangeStart(self) - - @property - def end(self): - """ - Return a SourceLocation representing the last character within a - source range. - """ - return conf.lib.clang_getRangeEnd(self) - - def __eq__(self, other): - return conf.lib.clang_equalRanges(self, other) - - def __ne__(self, other): - return not self.__eq__(other) - - def __contains__(self, other): - """Useful to detect the Token/Lexer bug""" - if not isinstance(other, SourceLocation): - return False - if other.file is None and self.start.file is None: - pass - elif ( self.start.file.name != other.file.name or - other.file.name != self.end.file.name): - # same file name - return False - # same file, in between lines - if self.start.line < other.line < self.end.line: - return True - elif self.start.line == other.line: - # same file first line - if self.start.column <= other.column: - return True - elif other.line == self.end.line: - # same file last line - if other.column <= self.end.column: - return True - return False - - def __repr__(self): - return "" % (self.start, self.end) - -class Diagnostic(object): - """ - A Diagnostic is a single instance of a Clang diagnostic. It includes the - diagnostic severity, the message, the location the diagnostic occurred, as - well as additional source ranges and associated fix-it hints. - """ - - Ignored = 0 - Note = 1 - Warning = 2 - Error = 3 - Fatal = 4 - - def __init__(self, ptr): - self.ptr = ptr - - def __del__(self): - conf.lib.clang_disposeDiagnostic(self) - - @property - def severity(self): - return conf.lib.clang_getDiagnosticSeverity(self) - - @property - def location(self): - return conf.lib.clang_getDiagnosticLocation(self) - - @property - def spelling(self): - return conf.lib.clang_getDiagnosticSpelling(self) - - @property - def ranges(self): - class RangeIterator: - def __init__(self, diag): - self.diag = diag - - def __len__(self): - return int(conf.lib.clang_getDiagnosticNumRanges(self.diag)) - - def __getitem__(self, key): - if (key >= len(self)): - raise IndexError - return conf.lib.clang_getDiagnosticRange(self.diag, key) - - return RangeIterator(self) - - @property - def fixits(self): - class FixItIterator: - def __init__(self, diag): - self.diag = diag - - def __len__(self): - return int(conf.lib.clang_getDiagnosticNumFixIts(self.diag)) - - def __getitem__(self, key): - range = SourceRange() - value = conf.lib.clang_getDiagnosticFixIt(self.diag, key, - byref(range)) - if len(value) == 0: - raise IndexError - - return FixIt(range, value) - - return FixItIterator(self) - - @property - def children(self): - class ChildDiagnosticsIterator: - def __init__(self, diag): - self.diag_set = conf.lib.clang_getChildDiagnostics(diag) - - def __len__(self): - return int(conf.lib.clang_getNumDiagnosticsInSet(self.diag_set)) - - def __getitem__(self, key): - diag = conf.lib.clang_getDiagnosticInSet(self.diag_set, key) - if not diag: - raise IndexError - return Diagnostic(diag) - - return ChildDiagnosticsIterator(self) - - @property - def category_number(self): - """The category number for this diagnostic or 0 if unavailable.""" - return conf.lib.clang_getDiagnosticCategory(self) - - @property - def category_name(self): - """The string name of the category for this diagnostic.""" - return conf.lib.clang_getDiagnosticCategoryText(self) - - @property - def option(self): - """The command-line option that enables this diagnostic.""" - return conf.lib.clang_getDiagnosticOption(self, None) - - @property - def disable_option(self): - """The command-line option that disables this diagnostic.""" - disable = _CXString() - conf.lib.clang_getDiagnosticOption(self, byref(disable)) - - return conf.lib.clang_getCString(disable) - - def __repr__(self): - return "" % ( - self.severity, self.location, self.spelling) - - def from_param(self): - return self.ptr - -class FixIt(object): - """ - A FixIt represents a transformation to be applied to the source to - "fix-it". The fix-it shouldbe applied by replacing the given source range - with the given value. - """ - - def __init__(self, range, value): - self.range = range - self.value = value - - def __repr__(self): - return "" % (self.range, self.value) - -class TokenGroup(object): - """Helper class to facilitate token management. - - Tokens are allocated from libclang in chunks. They must be disposed of as a - collective group. - - One purpose of this class is for instances to represent groups of allocated - tokens. Each token in a group contains a reference back to an instance of - this class. When all tokens from a group are garbage collected, it allows - this class to be garbage collected. When this class is garbage collected, - it calls the libclang destructor which invalidates all tokens in the group. - - You should not instantiate this class outside of this module. - """ - def __init__(self, tu, memory, count): - self._tu = tu - self._memory = memory - self._count = count - - def __del__(self): - conf.lib.clang_disposeTokens(self._tu, self._memory, self._count) - - @staticmethod - def get_tokens(tu, extent): - """Helper method to return all tokens in an extent. - - This functionality is needed multiple places in this module. We define - it here because it seems like a logical place. - """ - tokens_memory = POINTER(Token)() - tokens_count = c_uint() - - conf.lib.clang_tokenize(tu, extent, byref(tokens_memory), - byref(tokens_count)) - - count = int(tokens_count.value) - - # If we get no tokens, no memory was allocated. Be sure not to return - # anything and potentially call a destructor on nothing. - if count < 1: - return - - tokens_array = cast(tokens_memory, POINTER(Token * count)).contents - - token_group = TokenGroup(tu, tokens_memory, tokens_count) - - for i in range(0, count): - token = Token() - token.int_data = tokens_array[i].int_data - token.ptr_data = tokens_array[i].ptr_data - token._tu = tu - token._group = token_group - - yield token - -class TokenKind(object): - """Describes a specific type of a Token.""" - - _value_map = {} # int -> TokenKind - - def __init__(self, value, name): - """Create a new TokenKind instance from a numeric value and a name.""" - self.value = value - self.name = name - - def __repr__(self): - return 'TokenKind.%s' % (self.name,) - - @staticmethod - def from_value(value): - """Obtain a registered TokenKind instance from its value.""" - result = TokenKind._value_map.get(value, None) - - if result is None: - raise ValueError('Unknown TokenKind: %d' % value) - - return result - - @staticmethod - def register(value, name): - """Register a new TokenKind enumeration. - - This should only be called at module load time by code within this - package. - """ - if value in TokenKind._value_map: - raise ValueError('TokenKind already registered: %d' % value) - - kind = TokenKind(value, name) - TokenKind._value_map[value] = kind - setattr(TokenKind, name, kind) - -### Cursor Kinds ### -class BaseEnumeration(object): - """ - Common base class for named enumerations held in sync with Index.h values. - - Subclasses must define their own _kinds and _name_map members, as: - _kinds = [] - _name_map = None - These values hold the per-subclass instances and value-to-name mappings, - respectively. - - """ - - def __init__(self, value): - if value >= len(self.__class__._kinds): - self.__class__._kinds += [None] * (value - len(self.__class__._kinds) + 1) - if self.__class__._kinds[value] is not None: - raise ValueError('{0} value {1} already loaded'.format( - str(self.__class__), value)) - self.value = value - self.__class__._kinds[value] = self - self.__class__._name_map = None - - - def from_param(self): - return self.value - - @property - def name(self): - """Get the enumeration name of this cursor kind.""" - if self._name_map is None: - self._name_map = {} - for key, value in list(self.__class__.__dict__.items()): - if isinstance(value, self.__class__): - self._name_map[value] = key - return self._name_map[self] - - @classmethod - def from_id(cls, id): - if id >= len(cls._kinds) or cls._kinds[id] is None: - raise ValueError('Unknown template argument kind %d' % id) - return cls._kinds[id] - - def __repr__(self): - return '%s.%s' % (self.__class__, self.name,) - - -class CursorKind(BaseEnumeration): - """ - A CursorKind describes the kind of entity that a cursor points to. - """ - - # The required BaseEnumeration declarations. - _kinds = [] - _name_map = None - - @staticmethod - def get_all_kinds(): - """Return all CursorKind enumeration instances.""" - return [_f for _f in CursorKind._kinds if _f] - - def is_declaration(self): - """Test if this is a declaration kind.""" - return conf.lib.clang_isDeclaration(self) - - def is_reference(self): - """Test if this is a reference kind.""" - return conf.lib.clang_isReference(self) - - def is_expression(self): - """Test if this is an expression kind.""" - return conf.lib.clang_isExpression(self) - - def is_statement(self): - """Test if this is a statement kind.""" - return conf.lib.clang_isStatement(self) - - def is_attribute(self): - """Test if this is an attribute kind.""" - return conf.lib.clang_isAttribute(self) - - def is_invalid(self): - """Test if this is an invalid kind.""" - return conf.lib.clang_isInvalid(self) - - def is_translation_unit(self): - """Test if this is a translation unit kind.""" - return conf.lib.clang_isTranslationUnit(self) - - def is_preprocessing(self): - """Test if this is a preprocessing kind.""" - return conf.lib.clang_isPreprocessing(self) - - def is_unexposed(self): - """Test if this is an unexposed kind.""" - return conf.lib.clang_isUnexposed(self) - - def __repr__(self): - return 'CursorKind.%s' % (self.name,) - -### -# Declaration Kinds - -# A declaration whose specific kind is not exposed via this interface. -# -# Unexposed declarations have the same operations as any other kind of -# declaration; one can extract their location information, spelling, find their -# definitions, etc. However, the specific kind of the declaration is not -# reported. -CursorKind.UNEXPOSED_DECL = CursorKind(1) - -# A C or C++ struct. -CursorKind.STRUCT_DECL = CursorKind(2) - -# A C or C++ union. -CursorKind.UNION_DECL = CursorKind(3) - -# A C++ class. -CursorKind.CLASS_DECL = CursorKind(4) - -# An enumeration. -CursorKind.ENUM_DECL = CursorKind(5) - -# A field (in C) or non-static data member (in C++) in a struct, union, or C++ -# class. -CursorKind.FIELD_DECL = CursorKind(6) - -# An enumerator constant. -CursorKind.ENUM_CONSTANT_DECL = CursorKind(7) - -# A function. -CursorKind.FUNCTION_DECL = CursorKind(8) - -# A variable. -CursorKind.VAR_DECL = CursorKind(9) - -# A function or method parameter. -CursorKind.PARM_DECL = CursorKind(10) - -# An Objective-C @interface. -CursorKind.OBJC_INTERFACE_DECL = CursorKind(11) - -# An Objective-C @interface for a category. -CursorKind.OBJC_CATEGORY_DECL = CursorKind(12) - -# An Objective-C @protocol declaration. -CursorKind.OBJC_PROTOCOL_DECL = CursorKind(13) - -# An Objective-C @property declaration. -CursorKind.OBJC_PROPERTY_DECL = CursorKind(14) - -# An Objective-C instance variable. -CursorKind.OBJC_IVAR_DECL = CursorKind(15) - -# An Objective-C instance method. -CursorKind.OBJC_INSTANCE_METHOD_DECL = CursorKind(16) - -# An Objective-C class method. -CursorKind.OBJC_CLASS_METHOD_DECL = CursorKind(17) - -# An Objective-C @implementation. -CursorKind.OBJC_IMPLEMENTATION_DECL = CursorKind(18) - -# An Objective-C @implementation for a category. -CursorKind.OBJC_CATEGORY_IMPL_DECL = CursorKind(19) - -# A typedef. -CursorKind.TYPEDEF_DECL = CursorKind(20) - -# A C++ class method. -CursorKind.CXX_METHOD = CursorKind(21) - -# A C++ namespace. -CursorKind.NAMESPACE = CursorKind(22) - -# A linkage specification, e.g. 'extern "C"'. -CursorKind.LINKAGE_SPEC = CursorKind(23) - -# A C++ constructor. -CursorKind.CONSTRUCTOR = CursorKind(24) - -# A C++ destructor. -CursorKind.DESTRUCTOR = CursorKind(25) - -# A C++ conversion function. -CursorKind.CONVERSION_FUNCTION = CursorKind(26) - -# A C++ template type parameter -CursorKind.TEMPLATE_TYPE_PARAMETER = CursorKind(27) - -# A C++ non-type template paramater. -CursorKind.TEMPLATE_NON_TYPE_PARAMETER = CursorKind(28) - -# A C++ template template parameter. -CursorKind.TEMPLATE_TEMPLATE_PARAMETER = CursorKind(29) - -# A C++ function template. -CursorKind.FUNCTION_TEMPLATE = CursorKind(30) - -# A C++ class template. -CursorKind.CLASS_TEMPLATE = CursorKind(31) - -# A C++ class template partial specialization. -CursorKind.CLASS_TEMPLATE_PARTIAL_SPECIALIZATION = CursorKind(32) - -# A C++ namespace alias declaration. -CursorKind.NAMESPACE_ALIAS = CursorKind(33) - -# A C++ using directive -CursorKind.USING_DIRECTIVE = CursorKind(34) - -# A C++ using declaration -CursorKind.USING_DECLARATION = CursorKind(35) - -# A Type alias decl. -CursorKind.TYPE_ALIAS_DECL = CursorKind(36) - -# A Objective-C synthesize decl -CursorKind.OBJC_SYNTHESIZE_DECL = CursorKind(37) - -# A Objective-C dynamic decl -CursorKind.OBJC_DYNAMIC_DECL = CursorKind(38) - -# A C++ access specifier decl. -CursorKind.CXX_ACCESS_SPEC_DECL = CursorKind(39) - - -### -# Reference Kinds - -CursorKind.OBJC_SUPER_CLASS_REF = CursorKind(40) -CursorKind.OBJC_PROTOCOL_REF = CursorKind(41) -CursorKind.OBJC_CLASS_REF = CursorKind(42) - -# A reference to a type declaration. -# -# A type reference occurs anywhere where a type is named but not -# declared. For example, given: -# typedef unsigned size_type; -# size_type size; -# -# The typedef is a declaration of size_type (CXCursor_TypedefDecl), -# while the type of the variable "size" is referenced. The cursor -# referenced by the type of size is the typedef for size_type. -CursorKind.TYPE_REF = CursorKind(43) -CursorKind.CXX_BASE_SPECIFIER = CursorKind(44) - -# A reference to a class template, function template, template -# template parameter, or class template partial specialization. -CursorKind.TEMPLATE_REF = CursorKind(45) - -# A reference to a namespace or namepsace alias. -CursorKind.NAMESPACE_REF = CursorKind(46) - -# A reference to a member of a struct, union, or class that occurs in -# some non-expression context, e.g., a designated initializer. -CursorKind.MEMBER_REF = CursorKind(47) - -# A reference to a labeled statement. -CursorKind.LABEL_REF = CursorKind(48) - -# A reference to a set of overloaded functions or function templates -# that has not yet been resolved to a specific function or function template. -CursorKind.OVERLOADED_DECL_REF = CursorKind(49) - -# A reference to a variable that occurs in some non-expression -# context, e.g., a C++ lambda capture list. -CursorKind.VARIABLE_REF = CursorKind(50) - -### -# Invalid/Error Kinds - -CursorKind.INVALID_FILE = CursorKind(70) -CursorKind.NO_DECL_FOUND = CursorKind(71) -CursorKind.NOT_IMPLEMENTED = CursorKind(72) -CursorKind.INVALID_CODE = CursorKind(73) - -### -# Expression Kinds - -# An expression whose specific kind is not exposed via this interface. -# -# Unexposed expressions have the same operations as any other kind of -# expression; one can extract their location information, spelling, children, -# etc. However, the specific kind of the expression is not reported. -CursorKind.UNEXPOSED_EXPR = CursorKind(100) - -# An expression that refers to some value declaration, such as a function, -# varible, or enumerator. -CursorKind.DECL_REF_EXPR = CursorKind(101) - -# An expression that refers to a member of a struct, union, class, Objective-C -# class, etc. -CursorKind.MEMBER_REF_EXPR = CursorKind(102) - -# An expression that calls a function. -CursorKind.CALL_EXPR = CursorKind(103) - -# An expression that sends a message to an Objective-C object or class. -CursorKind.OBJC_MESSAGE_EXPR = CursorKind(104) - -# An expression that represents a block literal. -CursorKind.BLOCK_EXPR = CursorKind(105) - -# An integer literal. -CursorKind.INTEGER_LITERAL = CursorKind(106) - -# A floating point number literal. -CursorKind.FLOATING_LITERAL = CursorKind(107) - -# An imaginary number literal. -CursorKind.IMAGINARY_LITERAL = CursorKind(108) - -# A string literal. -CursorKind.STRING_LITERAL = CursorKind(109) - -# A character literal. -CursorKind.CHARACTER_LITERAL = CursorKind(110) - -# A parenthesized expression, e.g. "(1)". -# -# This AST node is only formed if full location information is requested. -CursorKind.PAREN_EXPR = CursorKind(111) - -# This represents the unary-expression's (except sizeof and -# alignof). -CursorKind.UNARY_OPERATOR = CursorKind(112) - -# [C99 6.5.2.1] Array Subscripting. -CursorKind.ARRAY_SUBSCRIPT_EXPR = CursorKind(113) - -# A builtin binary operation expression such as "x + y" or -# "x <= y". -CursorKind.BINARY_OPERATOR = CursorKind(114) - -# Compound assignment such as "+=". -CursorKind.COMPOUND_ASSIGNMENT_OPERATOR = CursorKind(115) - -# The ?: ternary operator. -CursorKind.CONDITIONAL_OPERATOR = CursorKind(116) - -# An explicit cast in C (C99 6.5.4) or a C-style cast in C++ -# (C++ [expr.cast]), which uses the syntax (Type)expr. -# -# For example: (int)f. -CursorKind.CSTYLE_CAST_EXPR = CursorKind(117) - -# [C99 6.5.2.5] -CursorKind.COMPOUND_LITERAL_EXPR = CursorKind(118) - -# Describes an C or C++ initializer list. -CursorKind.INIT_LIST_EXPR = CursorKind(119) - -# The GNU address of label extension, representing &&label. -CursorKind.ADDR_LABEL_EXPR = CursorKind(120) - -# This is the GNU Statement Expression extension: ({int X=4; X;}) -CursorKind.StmtExpr = CursorKind(121) - -# Represents a C11 generic selection. -CursorKind.GENERIC_SELECTION_EXPR = CursorKind(122) - -# Implements the GNU __null extension, which is a name for a null -# pointer constant that has integral type (e.g., int or long) and is the same -# size and alignment as a pointer. -# -# The __null extension is typically only used by system headers, which define -# NULL as __null in C++ rather than using 0 (which is an integer that may not -# match the size of a pointer). -CursorKind.GNU_NULL_EXPR = CursorKind(123) - -# C++'s static_cast<> expression. -CursorKind.CXX_STATIC_CAST_EXPR = CursorKind(124) - -# C++'s dynamic_cast<> expression. -CursorKind.CXX_DYNAMIC_CAST_EXPR = CursorKind(125) - -# C++'s reinterpret_cast<> expression. -CursorKind.CXX_REINTERPRET_CAST_EXPR = CursorKind(126) - -# C++'s const_cast<> expression. -CursorKind.CXX_CONST_CAST_EXPR = CursorKind(127) - -# Represents an explicit C++ type conversion that uses "functional" -# notion (C++ [expr.type.conv]). -# -# Example: -# \code -# x = int(0.5); -# \endcode -CursorKind.CXX_FUNCTIONAL_CAST_EXPR = CursorKind(128) - -# A C++ typeid expression (C++ [expr.typeid]). -CursorKind.CXX_TYPEID_EXPR = CursorKind(129) - -# [C++ 2.13.5] C++ Boolean Literal. -CursorKind.CXX_BOOL_LITERAL_EXPR = CursorKind(130) - -# [C++0x 2.14.7] C++ Pointer Literal. -CursorKind.CXX_NULL_PTR_LITERAL_EXPR = CursorKind(131) - -# Represents the "this" expression in C++ -CursorKind.CXX_THIS_EXPR = CursorKind(132) - -# [C++ 15] C++ Throw Expression. -# -# This handles 'throw' and 'throw' assignment-expression. When -# assignment-expression isn't present, Op will be null. -CursorKind.CXX_THROW_EXPR = CursorKind(133) - -# A new expression for memory allocation and constructor calls, e.g: -# "new CXXNewExpr(foo)". -CursorKind.CXX_NEW_EXPR = CursorKind(134) - -# A delete expression for memory deallocation and destructor calls, -# e.g. "delete[] pArray". -CursorKind.CXX_DELETE_EXPR = CursorKind(135) - -# Represents a unary expression. -CursorKind.CXX_UNARY_EXPR = CursorKind(136) - -# ObjCStringLiteral, used for Objective-C string literals i.e. "foo". -CursorKind.OBJC_STRING_LITERAL = CursorKind(137) - -# ObjCEncodeExpr, used for in Objective-C. -CursorKind.OBJC_ENCODE_EXPR = CursorKind(138) - -# ObjCSelectorExpr used for in Objective-C. -CursorKind.OBJC_SELECTOR_EXPR = CursorKind(139) - -# Objective-C's protocol expression. -CursorKind.OBJC_PROTOCOL_EXPR = CursorKind(140) - -# An Objective-C "bridged" cast expression, which casts between -# Objective-C pointers and C pointers, transferring ownership in the process. -# -# \code -# NSString *str = (__bridge_transfer NSString *)CFCreateString(); -# \endcode -CursorKind.OBJC_BRIDGE_CAST_EXPR = CursorKind(141) - -# Represents a C++0x pack expansion that produces a sequence of -# expressions. -# -# A pack expansion expression contains a pattern (which itself is an -# expression) followed by an ellipsis. For example: -CursorKind.PACK_EXPANSION_EXPR = CursorKind(142) - -# Represents an expression that computes the length of a parameter -# pack. -CursorKind.SIZE_OF_PACK_EXPR = CursorKind(143) - -# Represents a C++ lambda expression that produces a local function -# object. -# -# \code -# void abssort(float *x, unsigned N) { -# std::sort(x, x + N, -# [](float a, float b) { -# return std::abs(a) < std::abs(b); -# }); -# } -# \endcode -CursorKind.LAMBDA_EXPR = CursorKind(144) - -# Objective-c Boolean Literal. -CursorKind.OBJ_BOOL_LITERAL_EXPR = CursorKind(145) - -# Represents the "self" expression in a ObjC method. -CursorKind.OBJ_SELF_EXPR = CursorKind(146) - - -# A statement whose specific kind is not exposed via this interface. -# -# Unexposed statements have the same operations as any other kind of statement; -# one can extract their location information, spelling, children, etc. However, -# the specific kind of the statement is not reported. -CursorKind.UNEXPOSED_STMT = CursorKind(200) - -# A labelled statement in a function. -CursorKind.LABEL_STMT = CursorKind(201) - -# A compound statement -CursorKind.COMPOUND_STMT = CursorKind(202) - -# A case statement. -CursorKind.CASE_STMT = CursorKind(203) - -# A default statement. -CursorKind.DEFAULT_STMT = CursorKind(204) - -# An if statement. -CursorKind.IF_STMT = CursorKind(205) - -# A switch statement. -CursorKind.SWITCH_STMT = CursorKind(206) - -# A while statement. -CursorKind.WHILE_STMT = CursorKind(207) - -# A do statement. -CursorKind.DO_STMT = CursorKind(208) - -# A for statement. -CursorKind.FOR_STMT = CursorKind(209) - -# A goto statement. -CursorKind.GOTO_STMT = CursorKind(210) - -# An indirect goto statement. -CursorKind.INDIRECT_GOTO_STMT = CursorKind(211) - -# A continue statement. -CursorKind.CONTINUE_STMT = CursorKind(212) - -# A break statement. -CursorKind.BREAK_STMT = CursorKind(213) - -# A return statement. -CursorKind.RETURN_STMT = CursorKind(214) - -# A GNU-style inline assembler statement. -CursorKind.ASM_STMT = CursorKind(215) - -# Objective-C's overall @try-@catch-@finally statement. -CursorKind.OBJC_AT_TRY_STMT = CursorKind(216) - -# Objective-C's @catch statement. -CursorKind.OBJC_AT_CATCH_STMT = CursorKind(217) - -# Objective-C's @finally statement. -CursorKind.OBJC_AT_FINALLY_STMT = CursorKind(218) - -# Objective-C's @throw statement. -CursorKind.OBJC_AT_THROW_STMT = CursorKind(219) - -# Objective-C's @synchronized statement. -CursorKind.OBJC_AT_SYNCHRONIZED_STMT = CursorKind(220) - -# Objective-C's autorealease pool statement. -CursorKind.OBJC_AUTORELEASE_POOL_STMT = CursorKind(221) - -# Objective-C's for collection statement. -CursorKind.OBJC_FOR_COLLECTION_STMT = CursorKind(222) - -# C++'s catch statement. -CursorKind.CXX_CATCH_STMT = CursorKind(223) - -# C++'s try statement. -CursorKind.CXX_TRY_STMT = CursorKind(224) - -# C++'s for (* : *) statement. -CursorKind.CXX_FOR_RANGE_STMT = CursorKind(225) - -# Windows Structured Exception Handling's try statement. -CursorKind.SEH_TRY_STMT = CursorKind(226) - -# Windows Structured Exception Handling's except statement. -CursorKind.SEH_EXCEPT_STMT = CursorKind(227) - -# Windows Structured Exception Handling's finally statement. -CursorKind.SEH_FINALLY_STMT = CursorKind(228) - -# A MS inline assembly statement extension. -CursorKind.MS_ASM_STMT = CursorKind(229) - -# The null statement. -CursorKind.NULL_STMT = CursorKind(230) - -# Adaptor class for mixing declarations with statements and expressions. -CursorKind.DECL_STMT = CursorKind(231) - -# OpenMP parallel directive. -CursorKind.OMP_PARALLEL_DIRECTIVE = CursorKind(232) - -# OpenMP SIMD directive. -CursorKind.OMP_SIMD_DIRECTIVE = CursorKind(233) - -# OpenMP for directive. -CursorKind.OMP_FOR_DIRECTIVE = CursorKind(234) - -# OpenMP sections directive. -CursorKind.OMP_SECTIONS_DIRECTIVE = CursorKind(235) - -# OpenMP section directive. -CursorKind.OMP_SECTION_DIRECTIVE = CursorKind(236) - -# OpenMP single directive. -CursorKind.OMP_SINGLE_DIRECTIVE = CursorKind(237) - -# OpenMP parallel for directive. -CursorKind.OMP_PARALLEL_FOR_DIRECTIVE = CursorKind(238) - -# OpenMP parallel sections directive. -CursorKind.OMP_PARALLEL_SECTIONS_DIRECTIVE = CursorKind(239) - -# OpenMP task directive. -CursorKind.OMP_TASK_DIRECTIVE = CursorKind(240) - -# OpenMP master directive. -CursorKind.OMP_MASTER_DIRECTIVE = CursorKind(241) - -# OpenMP critical directive. -CursorKind.OMP_CRITICAL_DIRECTIVE = CursorKind(242) - -# OpenMP taskyield directive. -CursorKind.OMP_TASKYIELD_DIRECTIVE = CursorKind(243) - -# OpenMP barrier directive. -CursorKind.OMP_BARRIER_DIRECTIVE = CursorKind(244) - -# OpenMP taskwait directive. -CursorKind.OMP_TASKWAIT_DIRECTIVE = CursorKind(245) - -# OpenMP flush directive. -CursorKind.OMP_FLUSH_DIRECTIVE = CursorKind(246) - -# Windows Structured Exception Handling's leave statement. -CursorKind.SEH_LEAVE_STMT = CursorKind(247) - -# OpenMP ordered directive. -CursorKind.OMP_ORDERED_DIRECTIVE = CursorKind(248) - -# OpenMP atomic directive. -CursorKind.OMP_ATOMIC_DIRECTIVE = CursorKind(249) - -# OpenMP for SIMD directive. -CursorKind.OMP_FOR_SIMD_DIRECTIVE = CursorKind(250) - -# OpenMP parallel for SIMD directive. -CursorKind.OMP_PARALLELFORSIMD_DIRECTIVE = CursorKind(251) - -# OpenMP target directive. -CursorKind.OMP_TARGET_DIRECTIVE = CursorKind(252) - -# OpenMP teams directive. -CursorKind.OMP_TEAMS_DIRECTIVE = CursorKind(253) - -# OpenMP taskgroup directive. -CursorKind.OMP_TASKGROUP_DIRECTIVE = CursorKind(254) - -# OpenMP cancellation point directive. -CursorKind.OMP_CANCELLATION_POINT_DIRECTIVE = CursorKind(255) - -# OpenMP cancel directive. -CursorKind.OMP_CANCEL_DIRECTIVE = CursorKind(256) - -# OpenMP target data directive. -CursorKind.OMP_TARGET_DATA_DIRECTIVE = CursorKind(257) - -# OpenMP taskloop directive. -CursorKind.OMP_TASK_LOOP_DIRECTIVE = CursorKind(258) - -# OpenMP taskloop simd directive. -CursorKind.OMP_TASK_LOOP_SIMD_DIRECTIVE = CursorKind(259) - -# OpenMP distribute directive. -CursorKind.OMP_DISTRIBUTE_DIRECTIVE = CursorKind(260) - -# OpenMP target enter data directive. -CursorKind.OMP_TARGET_ENTER_DATA_DIRECTIVE = CursorKind(261) - -# OpenMP target exit data directive. -CursorKind.OMP_TARGET_EXIT_DATA_DIRECTIVE = CursorKind(262) - -# OpenMP target parallel directive. -CursorKind.OMP_TARGET_PARALLEL_DIRECTIVE = CursorKind(263) - -# OpenMP target parallel for directive. -CursorKind.OMP_TARGET_PARALLELFOR_DIRECTIVE = CursorKind(264) - -# OpenMP target update directive. -CursorKind.OMP_TARGET_UPDATE_DIRECTIVE = CursorKind(265) - -# OpenMP distribute parallel for directive. -CursorKind.OMP_DISTRIBUTE_PARALLELFOR_DIRECTIVE = CursorKind(266) - -# OpenMP distribute parallel for simd directive. -CursorKind.OMP_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE = CursorKind(267) - -# OpenMP distribute simd directive. -CursorKind.OMP_DISTRIBUTE_SIMD_DIRECTIVE = CursorKind(268) - -# OpenMP target parallel for simd directive. -CursorKind.OMP_TARGET_PARALLEL_FOR_SIMD_DIRECTIVE = CursorKind(269) - -# OpenMP target simd directive. -CursorKind.OMP_TARGET_SIMD_DIRECTIVE = CursorKind(270) - -# OpenMP teams distribute directive. -CursorKind.OMP_TEAMS_DISTRIBUTE_DIRECTIVE = CursorKind(271) - -### -# Other Kinds - -# Cursor that represents the translation unit itself. -# -# The translation unit cursor exists primarily to act as the root cursor for -# traversing the contents of a translation unit. -CursorKind.TRANSLATION_UNIT = CursorKind(300) - -### -# Attributes - -# An attribute whoe specific kind is note exposed via this interface -CursorKind.UNEXPOSED_ATTR = CursorKind(400) - -CursorKind.IB_ACTION_ATTR = CursorKind(401) -CursorKind.IB_OUTLET_ATTR = CursorKind(402) -CursorKind.IB_OUTLET_COLLECTION_ATTR = CursorKind(403) - -CursorKind.CXX_FINAL_ATTR = CursorKind(404) -CursorKind.CXX_OVERRIDE_ATTR = CursorKind(405) -CursorKind.ANNOTATE_ATTR = CursorKind(406) -CursorKind.ASM_LABEL_ATTR = CursorKind(407) -CursorKind.PACKED_ATTR = CursorKind(408) -CursorKind.PURE_ATTR = CursorKind(409) -CursorKind.CONST_ATTR = CursorKind(410) -CursorKind.NODUPLICATE_ATTR = CursorKind(411) -CursorKind.CUDACONSTANT_ATTR = CursorKind(412) -CursorKind.CUDADEVICE_ATTR = CursorKind(413) -CursorKind.CUDAGLOBAL_ATTR = CursorKind(414) -CursorKind.CUDAHOST_ATTR = CursorKind(415) -CursorKind.CUDASHARED_ATTR = CursorKind(416) - -CursorKind.VISIBILITY_ATTR = CursorKind(417) - -CursorKind.DLLEXPORT_ATTR = CursorKind(418) -CursorKind.DLLIMPORT_ATTR = CursorKind(419) - -### -# Preprocessing -CursorKind.PREPROCESSING_DIRECTIVE = CursorKind(500) -CursorKind.MACRO_DEFINITION = CursorKind(501) -CursorKind.MACRO_INSTANTIATION = CursorKind(502) -CursorKind.INCLUSION_DIRECTIVE = CursorKind(503) - -### -# Extra declaration - -# A module import declaration. -CursorKind.MODULE_IMPORT_DECL = CursorKind(600) -# A type alias template declaration -CursorKind.TYPE_ALIAS_TEMPLATE_DECL = CursorKind(601) -# A static_assert or _Static_assert node -CursorKind.STATIC_ASSERT = CursorKind(602) -# A friend declaration -CursorKind.FRIEND_DECL = CursorKind(603) - -# A code completion overload candidate. -CursorKind.OVERLOAD_CANDIDATE = CursorKind(700) - -### Template Argument Kinds ### -class TemplateArgumentKind(BaseEnumeration): - """ - A TemplateArgumentKind describes the kind of entity that a template argument - represents. - """ - - # The required BaseEnumeration declarations. - _kinds = [] - _name_map = None - -TemplateArgumentKind.NULL = TemplateArgumentKind(0) -TemplateArgumentKind.TYPE = TemplateArgumentKind(1) -TemplateArgumentKind.DECLARATION = TemplateArgumentKind(2) -TemplateArgumentKind.NULLPTR = TemplateArgumentKind(3) -TemplateArgumentKind.INTEGRAL = TemplateArgumentKind(4) - -### Cursors ### - -class Cursor(Structure): - """ - The Cursor class represents a reference to an element within the AST. It - acts as a kind of iterator. - """ - _fields_ = [("_kind_id", c_int), ("xdata", c_int), ("data", c_void_p * 3)] - - @staticmethod - def from_location(tu, location): - # We store a reference to the TU in the instance so the TU won't get - # collected before the cursor. - cursor = conf.lib.clang_getCursor(tu, location) - cursor._tu = tu - - return cursor - - def __eq__(self, other): - return conf.lib.clang_equalCursors(self, other) - - def __ne__(self, other): - return not self.__eq__(other) - - def is_definition(self): - """ - Returns true if the declaration pointed at by the cursor is also a - definition of that entity. - """ - return conf.lib.clang_isCursorDefinition(self) - - def is_const_method(self): - """Returns True if the cursor refers to a C++ member function or member - function template that is declared 'const'. - """ - return conf.lib.clang_CXXMethod_isConst(self) - - def is_converting_constructor(self): - """Returns True if the cursor refers to a C++ converting constructor. - """ - return conf.lib.clang_CXXConstructor_isConvertingConstructor(self) - - def is_copy_constructor(self): - """Returns True if the cursor refers to a C++ copy constructor. - """ - return conf.lib.clang_CXXConstructor_isCopyConstructor(self) - - def is_default_constructor(self): - """Returns True if the cursor refers to a C++ default constructor. - """ - return conf.lib.clang_CXXConstructor_isDefaultConstructor(self) - - def is_move_constructor(self): - """Returns True if the cursor refers to a C++ move constructor. - """ - return conf.lib.clang_CXXConstructor_isMoveConstructor(self) - - def is_default_method(self): - """Returns True if the cursor refers to a C++ member function or member - function template that is declared '= default'. - """ - return conf.lib.clang_CXXMethod_isDefaulted(self) - - def is_mutable_field(self): - """Returns True if the cursor refers to a C++ field that is declared - 'mutable'. - """ - return conf.lib.clang_CXXField_isMutable(self) - - def is_pure_virtual_method(self): - """Returns True if the cursor refers to a C++ member function or member - function template that is declared pure virtual. - """ - return conf.lib.clang_CXXMethod_isPureVirtual(self) - - def is_static_method(self): - """Returns True if the cursor refers to a C++ member function or member - function template that is declared 'static'. - """ - return conf.lib.clang_CXXMethod_isStatic(self) - - def is_virtual_method(self): - """Returns True if the cursor refers to a C++ member function or member - function template that is declared 'virtual'. - """ - return conf.lib.clang_CXXMethod_isVirtual(self) - - def get_definition(self): - """ - If the cursor is a reference to a declaration or a declaration of - some entity, return a cursor that points to the definition of that - entity. - """ - # TODO: Should probably check that this is either a reference or - # declaration prior to issuing the lookup. - return conf.lib.clang_getCursorDefinition(self) - - def get_usr(self): - """Return the Unified Symbol Resultion (USR) for the entity referenced - by the given cursor (or None). - - A Unified Symbol Resolution (USR) is a string that identifies a - particular entity (function, class, variable, etc.) within a - program. USRs can be compared across translation units to determine, - e.g., when references in one translation refer to an entity defined in - another translation unit.""" - return conf.lib.clang_getCursorUSR(self) - - @property - def kind(self): - """Return the kind of this cursor.""" - return CursorKind.from_id(self._kind_id) - - @property - def spelling(self): - """Return the spelling of the entity pointed at by the cursor.""" - if not hasattr(self, '_spelling'): - self._spelling = conf.lib.clang_getCursorSpelling(self) - - return self._spelling - - @property - def displayname(self): - """ - Return the display name for the entity referenced by this cursor. - - The display name contains extra information that helps identify the - cursor, such as the parameters of a function or template or the - arguments of a class template specialization. - """ - if not hasattr(self, '_displayname'): - self._displayname = conf.lib.clang_getCursorDisplayName(self) - - return self._displayname - - @property - def mangled_name(self): - """Return the mangled name for the entity referenced by this cursor.""" - if not hasattr(self, '_mangled_name'): - self._mangled_name = conf.lib.clang_Cursor_getMangling(self) - - return self._mangled_name - - @property - def location(self): - """ - Return the source location (the starting character) of the entity - pointed at by the cursor. - """ - if not hasattr(self, '_loc'): - self._loc = conf.lib.clang_getCursorLocation(self) - - return self._loc - - @property - def extent(self): - """ - Return the source range (the range of text) occupied by the entity - pointed at by the cursor. - """ - if not hasattr(self, '_extent'): - self._extent = conf.lib.clang_getCursorExtent(self) - - return self._extent - - @property - def storage_class(self): - """ - Retrieves the storage class (if any) of the entity pointed at by the - cursor. - """ - if not hasattr(self, '_storage_class'): - self._storage_class = conf.lib.clang_Cursor_getStorageClass(self) - - return StorageClass.from_id(self._storage_class) - - @property - def access_specifier(self): - """ - Retrieves the access specifier (if any) of the entity pointed at by the - cursor. - """ - if not hasattr(self, '_access_specifier'): - self._access_specifier = conf.lib.clang_getCXXAccessSpecifier(self) - - return AccessSpecifier.from_id(self._access_specifier) - - @property - def type(self): - """ - Retrieve the Type (if any) of the entity pointed at by the cursor. - """ - if not hasattr(self, '_type'): - self._type = conf.lib.clang_getCursorType(self) - - return self._type - - @property - def canonical(self): - """Return the canonical Cursor corresponding to this Cursor. - - The canonical cursor is the cursor which is representative for the - underlying entity. For example, if you have multiple forward - declarations for the same class, the canonical cursor for the forward - declarations will be identical. - """ - if not hasattr(self, '_canonical'): - self._canonical = conf.lib.clang_getCanonicalCursor(self) - - return self._canonical - - @property - def result_type(self): - """Retrieve the Type of the result for this Cursor.""" - if not hasattr(self, '_result_type'): - self._result_type = conf.lib.clang_getResultType(self.type) - - return self._result_type - - @property - def underlying_typedef_type(self): - """Return the underlying type of a typedef declaration. - - Returns a Type for the typedef this cursor is a declaration for. If - the current cursor is not a typedef, this raises. - """ - if not hasattr(self, '_underlying_type'): - assert self.kind.is_declaration() - self._underlying_type = \ - conf.lib.clang_getTypedefDeclUnderlyingType(self) - - return self._underlying_type - - @property - def enum_type(self): - """Return the integer type of an enum declaration. - - Returns a Type corresponding to an integer. If the cursor is not for an - enum, this raises. - """ - if not hasattr(self, '_enum_type'): - assert self.kind == CursorKind.ENUM_DECL - self._enum_type = conf.lib.clang_getEnumDeclIntegerType(self) - - return self._enum_type - - @property - def enum_value(self): - """Return the value of an enum constant.""" - if not hasattr(self, '_enum_value'): - assert self.kind == CursorKind.ENUM_CONSTANT_DECL - # Figure out the underlying type of the enum to know if it - # is a signed or unsigned quantity. - underlying_type = self.type - if underlying_type.kind == TypeKind.ENUM: - underlying_type = underlying_type.get_declaration().enum_type - if underlying_type.kind in (TypeKind.CHAR_U, - TypeKind.UCHAR, - TypeKind.CHAR16, - TypeKind.CHAR32, - TypeKind.USHORT, - TypeKind.UINT, - TypeKind.ULONG, - TypeKind.ULONGLONG, - TypeKind.UINT128): - self._enum_value = \ - conf.lib.clang_getEnumConstantDeclUnsignedValue(self) - else: - self._enum_value = conf.lib.clang_getEnumConstantDeclValue(self) - return self._enum_value - - @property - def objc_type_encoding(self): - """Return the Objective-C type encoding as a str.""" - if not hasattr(self, '_objc_type_encoding'): - self._objc_type_encoding = \ - conf.lib.clang_getDeclObjCTypeEncoding(self) - - return self._objc_type_encoding - - @property - def hash(self): - """Returns a hash of the cursor as an int.""" - if not hasattr(self, '_hash'): - self._hash = conf.lib.clang_hashCursor(self) - - return self._hash - - @property - def semantic_parent(self): - """Return the semantic parent for this cursor.""" - if not hasattr(self, '_semantic_parent'): - self._semantic_parent = conf.lib.clang_getCursorSemanticParent(self) - - return self._semantic_parent - - @property - def lexical_parent(self): - """Return the lexical parent for this cursor.""" - if not hasattr(self, '_lexical_parent'): - self._lexical_parent = conf.lib.clang_getCursorLexicalParent(self) - - return self._lexical_parent - - @property - def translation_unit(self): - """Returns the TranslationUnit to which this Cursor belongs.""" - # If this triggers an AttributeError, the instance was not properly - # created. - return self._tu - - @property - def referenced(self): - """ - For a cursor that is a reference, returns a cursor - representing the entity that it references. - """ - if not hasattr(self, '_referenced'): - self._referenced = conf.lib.clang_getCursorReferenced(self) - - return self._referenced - - @property - def brief_comment(self): - """Returns the brief comment text associated with that Cursor""" - return conf.lib.clang_Cursor_getBriefCommentText(self) - - @property - def raw_comment(self): - """Returns the raw comment text associated with that Cursor""" - return conf.lib.clang_Cursor_getRawCommentText(self) - - def get_arguments(self): - """Return an iterator for accessing the arguments of this cursor.""" - num_args = conf.lib.clang_Cursor_getNumArguments(self) - for i in range(0, num_args): - yield conf.lib.clang_Cursor_getArgument(self, i) - - def get_num_template_arguments(self): - """Returns the number of template args associated with this cursor.""" - return conf.lib.clang_Cursor_getNumTemplateArguments(self) - - def get_template_argument_kind(self, num): - """Returns the TemplateArgumentKind for the indicated template - argument.""" - return conf.lib.clang_Cursor_getTemplateArgumentKind(self, num) - - def get_template_argument_type(self, num): - """Returns the CXType for the indicated template argument.""" - return conf.lib.clang_Cursor_getTemplateArgumentType(self, num) - - def get_template_argument_value(self, num): - """Returns the value of the indicated arg as a signed 64b integer.""" - return conf.lib.clang_Cursor_getTemplateArgumentValue(self, num) - - def get_template_argument_unsigned_value(self, num): - """Returns the value of the indicated arg as an unsigned 64b integer.""" - return conf.lib.clang_Cursor_getTemplateArgumentUnsignedValue(self, num) - - def get_children(self): - """Return an iterator for accessing the children of this cursor.""" - - # FIXME: Expose iteration from CIndex, PR6125. - def visitor(child, parent, children): - # FIXME: Document this assertion in API. - # FIXME: There should just be an isNull method. - assert child != conf.lib.clang_getNullCursor() - - # Create reference to TU so it isn't GC'd before Cursor. - child._tu = self._tu - children.append(child) - return 1 # continue - children = [] - conf.lib.clang_visitChildren(self, callbacks['cursor_visit'](visitor), - children) - return iter(children) - - def walk_preorder(self): - """Depth-first preorder walk over the cursor and its descendants. - - Yields cursors. - """ - yield self - for child in self.get_children(): - for descendant in child.walk_preorder(): - yield descendant - - def get_tokens(self): - """Obtain Token instances formulating that compose this Cursor. - - This is a generator for Token instances. It returns all tokens which - occupy the extent this cursor occupies. - """ - return TokenGroup.get_tokens(self._tu, self.extent) - - def get_field_offsetof(self): - """Returns the offsetof the FIELD_DECL pointed by this Cursor.""" - return conf.lib.clang_Cursor_getOffsetOfField(self) - - def is_anonymous(self): - """ - Check if the record is anonymous. - """ - if self.kind == CursorKind.FIELD_DECL: - return self.type.get_declaration().is_anonymous() - return conf.lib.clang_Cursor_isAnonymous(self) - - def is_bitfield(self): - """ - Check if the field is a bitfield. - """ - return conf.lib.clang_Cursor_isBitField(self) - - def get_bitfield_width(self): - """ - Retrieve the width of a bitfield. - """ - return conf.lib.clang_getFieldDeclBitWidth(self) - - @staticmethod - def from_result(res, fn, args): - assert isinstance(res, Cursor) - # FIXME: There should just be an isNull method. - if res == conf.lib.clang_getNullCursor(): - return None - - # Store a reference to the TU in the Python object so it won't get GC'd - # before the Cursor. - tu = None - for arg in args: - if isinstance(arg, TranslationUnit): - tu = arg - break - - if hasattr(arg, 'translation_unit'): - tu = arg.translation_unit - break - - assert tu is not None - - res._tu = tu - return res - - @staticmethod - def from_cursor_result(res, fn, args): - assert isinstance(res, Cursor) - if res == conf.lib.clang_getNullCursor(): - return None - - res._tu = args[0]._tu - return res - -class StorageClass(object): - """ - Describes the storage class of a declaration - """ - - # The unique kind objects, index by id. - _kinds = [] - _name_map = None - - def __init__(self, value): - if value >= len(StorageClass._kinds): - StorageClass._kinds += [None] * (value - len(StorageClass._kinds) + 1) - if StorageClass._kinds[value] is not None: - raise ValueError('StorageClass already loaded') - self.value = value - StorageClass._kinds[value] = self - StorageClass._name_map = None - - def from_param(self): - return self.value - - @property - def name(self): - """Get the enumeration name of this storage class.""" - if self._name_map is None: - self._name_map = {} - for key,value in list(StorageClass.__dict__.items()): - if isinstance(value,StorageClass): - self._name_map[value] = key - return self._name_map[self] - - @staticmethod - def from_id(id): - if id >= len(StorageClass._kinds) or not StorageClass._kinds[id]: - raise ValueError('Unknown storage class %d' % id) - return StorageClass._kinds[id] - - def __repr__(self): - return 'StorageClass.%s' % (self.name,) - -StorageClass.INVALID = StorageClass(0) -StorageClass.NONE = StorageClass(1) -StorageClass.EXTERN = StorageClass(2) -StorageClass.STATIC = StorageClass(3) -StorageClass.PRIVATEEXTERN = StorageClass(4) -StorageClass.OPENCLWORKGROUPLOCAL = StorageClass(5) -StorageClass.AUTO = StorageClass(6) -StorageClass.REGISTER = StorageClass(7) - - -### C++ access specifiers ### - -class AccessSpecifier(BaseEnumeration): - """ - Describes the access of a C++ class member - """ - - # The unique kind objects, index by id. - _kinds = [] - _name_map = None - - def from_param(self): - return self.value - - def __repr__(self): - return 'AccessSpecifier.%s' % (self.name,) - -AccessSpecifier.INVALID = AccessSpecifier(0) -AccessSpecifier.PUBLIC = AccessSpecifier(1) -AccessSpecifier.PROTECTED = AccessSpecifier(2) -AccessSpecifier.PRIVATE = AccessSpecifier(3) -AccessSpecifier.NONE = AccessSpecifier(4) - -### Type Kinds ### - -class TypeKind(BaseEnumeration): - """ - Describes the kind of type. - """ - - # The unique kind objects, indexed by id. - _kinds = [] - _name_map = None - - @property - def spelling(self): - """Retrieve the spelling of this TypeKind.""" - return conf.lib.clang_getTypeKindSpelling(self.value) - - def __repr__(self): - return 'TypeKind.%s' % (self.name,) - -TypeKind.INVALID = TypeKind(0) -TypeKind.UNEXPOSED = TypeKind(1) -TypeKind.VOID = TypeKind(2) -TypeKind.BOOL = TypeKind(3) -TypeKind.CHAR_U = TypeKind(4) -TypeKind.UCHAR = TypeKind(5) -TypeKind.CHAR16 = TypeKind(6) -TypeKind.CHAR32 = TypeKind(7) -TypeKind.USHORT = TypeKind(8) -TypeKind.UINT = TypeKind(9) -TypeKind.ULONG = TypeKind(10) -TypeKind.ULONGLONG = TypeKind(11) -TypeKind.UINT128 = TypeKind(12) -TypeKind.CHAR_S = TypeKind(13) -TypeKind.SCHAR = TypeKind(14) -TypeKind.WCHAR = TypeKind(15) -TypeKind.SHORT = TypeKind(16) -TypeKind.INT = TypeKind(17) -TypeKind.LONG = TypeKind(18) -TypeKind.LONGLONG = TypeKind(19) -TypeKind.INT128 = TypeKind(20) -TypeKind.FLOAT = TypeKind(21) -TypeKind.DOUBLE = TypeKind(22) -TypeKind.LONGDOUBLE = TypeKind(23) -TypeKind.NULLPTR = TypeKind(24) -TypeKind.OVERLOAD = TypeKind(25) -TypeKind.DEPENDENT = TypeKind(26) -TypeKind.OBJCID = TypeKind(27) -TypeKind.OBJCCLASS = TypeKind(28) -TypeKind.OBJCSEL = TypeKind(29) -TypeKind.FLOAT128 = TypeKind(30) -TypeKind.HALF = TypeKind(31) -TypeKind.COMPLEX = TypeKind(100) -TypeKind.POINTER = TypeKind(101) -TypeKind.BLOCKPOINTER = TypeKind(102) -TypeKind.LVALUEREFERENCE = TypeKind(103) -TypeKind.RVALUEREFERENCE = TypeKind(104) -TypeKind.RECORD = TypeKind(105) -TypeKind.ENUM = TypeKind(106) -TypeKind.TYPEDEF = TypeKind(107) -TypeKind.OBJCINTERFACE = TypeKind(108) -TypeKind.OBJCOBJECTPOINTER = TypeKind(109) -TypeKind.FUNCTIONNOPROTO = TypeKind(110) -TypeKind.FUNCTIONPROTO = TypeKind(111) -TypeKind.CONSTANTARRAY = TypeKind(112) -TypeKind.VECTOR = TypeKind(113) -TypeKind.INCOMPLETEARRAY = TypeKind(114) -TypeKind.VARIABLEARRAY = TypeKind(115) -TypeKind.DEPENDENTSIZEDARRAY = TypeKind(116) -TypeKind.MEMBERPOINTER = TypeKind(117) -TypeKind.AUTO = TypeKind(118) -TypeKind.ELABORATED = TypeKind(119) - -class RefQualifierKind(BaseEnumeration): - """Describes a specific ref-qualifier of a type.""" - - # The unique kind objects, indexed by id. - _kinds = [] - _name_map = None - - def from_param(self): - return self.value - - def __repr__(self): - return 'RefQualifierKind.%s' % (self.name,) - -RefQualifierKind.NONE = RefQualifierKind(0) -RefQualifierKind.LVALUE = RefQualifierKind(1) -RefQualifierKind.RVALUE = RefQualifierKind(2) - -class Type(Structure): - """ - The type of an element in the abstract syntax tree. - """ - _fields_ = [("_kind_id", c_int), ("data", c_void_p * 2)] - - @property - def kind(self): - """Return the kind of this type.""" - return TypeKind.from_id(self._kind_id) - - def argument_types(self): - """Retrieve a container for the non-variadic arguments for this type. - - The returned object is iterable and indexable. Each item in the - container is a Type instance. - """ - class ArgumentsIterator(collections.Sequence): - def __init__(self, parent): - self.parent = parent - self.length = None - - def __len__(self): - if self.length is None: - self.length = conf.lib.clang_getNumArgTypes(self.parent) - - return self.length - - def __getitem__(self, key): - # FIXME Support slice objects. - if not isinstance(key, int): - raise TypeError("Must supply a non-negative int.") - - if key < 0: - raise IndexError("Only non-negative indexes are accepted.") - - if key >= len(self): - raise IndexError("Index greater than container length: " - "%d > %d" % ( key, len(self) )) - - result = conf.lib.clang_getArgType(self.parent, key) - if result.kind == TypeKind.INVALID: - raise IndexError("Argument could not be retrieved.") - - return result - - assert self.kind == TypeKind.FUNCTIONPROTO - return ArgumentsIterator(self) - - @property - def element_type(self): - """Retrieve the Type of elements within this Type. - - If accessed on a type that is not an array, complex, or vector type, an - exception will be raised. - """ - result = conf.lib.clang_getElementType(self) - if result.kind == TypeKind.INVALID: - raise Exception('Element type not available on this type.') - - return result - - @property - def element_count(self): - """Retrieve the number of elements in this type. - - Returns an int. - - If the Type is not an array or vector, this raises. - """ - result = conf.lib.clang_getNumElements(self) - if result < 0: - raise Exception('Type does not have elements.') - - return result - - @property - def translation_unit(self): - """The TranslationUnit to which this Type is associated.""" - # If this triggers an AttributeError, the instance was not properly - # instantiated. - return self._tu - - @staticmethod - def from_result(res, fn, args): - assert isinstance(res, Type) - - tu = None - for arg in args: - if hasattr(arg, 'translation_unit'): - tu = arg.translation_unit - break - - assert tu is not None - res._tu = tu - - return res - - def get_canonical(self): - """ - Return the canonical type for a Type. - - Clang's type system explicitly models typedefs and all the - ways a specific type can be represented. The canonical type - is the underlying type with all the "sugar" removed. For - example, if 'T' is a typedef for 'int', the canonical type for - 'T' would be 'int'. - """ - return conf.lib.clang_getCanonicalType(self) - - def is_const_qualified(self): - """Determine whether a Type has the "const" qualifier set. - - This does not look through typedefs that may have added "const" - at a different level. - """ - return conf.lib.clang_isConstQualifiedType(self) - - def is_volatile_qualified(self): - """Determine whether a Type has the "volatile" qualifier set. - - This does not look through typedefs that may have added "volatile" - at a different level. - """ - return conf.lib.clang_isVolatileQualifiedType(self) - - def is_restrict_qualified(self): - """Determine whether a Type has the "restrict" qualifier set. - - This does not look through typedefs that may have added "restrict" at - a different level. - """ - return conf.lib.clang_isRestrictQualifiedType(self) - - def is_function_variadic(self): - """Determine whether this function Type is a variadic function type.""" - assert self.kind == TypeKind.FUNCTIONPROTO - - return conf.lib.clang_isFunctionTypeVariadic(self) - - def is_pod(self): - """Determine whether this Type represents plain old data (POD).""" - return conf.lib.clang_isPODType(self) - - def get_pointee(self): - """ - For pointer types, returns the type of the pointee. - """ - return conf.lib.clang_getPointeeType(self) - - def get_declaration(self): - """ - Return the cursor for the declaration of the given type. - """ - return conf.lib.clang_getTypeDeclaration(self) - - def get_result(self): - """ - Retrieve the result type associated with a function type. - """ - return conf.lib.clang_getResultType(self) - - def get_array_element_type(self): - """ - Retrieve the type of the elements of the array type. - """ - return conf.lib.clang_getArrayElementType(self) - - def get_array_size(self): - """ - Retrieve the size of the constant array. - """ - return conf.lib.clang_getArraySize(self) - - def get_class_type(self): - """ - Retrieve the class type of the member pointer type. - """ - return conf.lib.clang_Type_getClassType(self) - - def get_named_type(self): - """ - Retrieve the type named by the qualified-id. - """ - return conf.lib.clang_Type_getNamedType(self) - def get_align(self): - """ - Retrieve the alignment of the record. - """ - return conf.lib.clang_Type_getAlignOf(self) - - def get_size(self): - """ - Retrieve the size of the record. - """ - return conf.lib.clang_Type_getSizeOf(self) - - def get_offset(self, fieldname): - """ - Retrieve the offset of a field in the record. - """ - return conf.lib.clang_Type_getOffsetOf(self, c_char_p(fieldname)) - - def get_ref_qualifier(self): - """ - Retrieve the ref-qualifier of the type. - """ - return RefQualifierKind.from_id( - conf.lib.clang_Type_getCXXRefQualifier(self)) - - def get_fields(self): - """Return an iterator for accessing the fields of this type.""" - - def visitor(field, children): - assert field != conf.lib.clang_getNullCursor() - - # Create reference to TU so it isn't GC'd before Cursor. - field._tu = self._tu - fields.append(field) - return 1 # continue - fields = [] - conf.lib.clang_Type_visitFields(self, - callbacks['fields_visit'](visitor), fields) - return iter(fields) - - @property - def spelling(self): - """Retrieve the spelling of this Type.""" - return conf.lib.clang_getTypeSpelling(self) - - def __eq__(self, other): - if type(other) != type(self): - return False - - return conf.lib.clang_equalTypes(self, other) - - def __ne__(self, other): - return not self.__eq__(other) - -## CIndex Objects ## - -# CIndex objects (derived from ClangObject) are essentially lightweight -# wrappers attached to some underlying object, which is exposed via CIndex as -# a void*. - -class ClangObject(object): - """ - A helper for Clang objects. This class helps act as an intermediary for - the ctypes library and the Clang CIndex library. - """ - def __init__(self, obj): - assert isinstance(obj, c_object_p) and obj - self.obj = self._as_parameter_ = obj - - def from_param(self): - return self._as_parameter_ - - -class _CXUnsavedFile(Structure): - """Helper for passing unsaved file arguments.""" - _fields_ = [("name", c_char_p), ("contents", c_char_p), ('length', c_ulong)] - -# Functions calls through the python interface are rather slow. Fortunately, -# for most symboles, we do not need to perform a function call. Their spelling -# never changes and is consequently provided by this spelling cache. -SpellingCache = { - # 0: CompletionChunk.Kind("Optional"), - # 1: CompletionChunk.Kind("TypedText"), - # 2: CompletionChunk.Kind("Text"), - # 3: CompletionChunk.Kind("Placeholder"), - # 4: CompletionChunk.Kind("Informative"), - # 5 : CompletionChunk.Kind("CurrentParameter"), - 6: '(', # CompletionChunk.Kind("LeftParen"), - 7: ')', # CompletionChunk.Kind("RightParen"), - 8: '[', # CompletionChunk.Kind("LeftBracket"), - 9: ']', # CompletionChunk.Kind("RightBracket"), - 10: '{', # CompletionChunk.Kind("LeftBrace"), - 11: '}', # CompletionChunk.Kind("RightBrace"), - 12: '<', # CompletionChunk.Kind("LeftAngle"), - 13: '>', # CompletionChunk.Kind("RightAngle"), - 14: ', ', # CompletionChunk.Kind("Comma"), - # 15: CompletionChunk.Kind("ResultType"), - 16: ':', # CompletionChunk.Kind("Colon"), - 17: ';', # CompletionChunk.Kind("SemiColon"), - 18: '=', # CompletionChunk.Kind("Equal"), - 19: ' ', # CompletionChunk.Kind("HorizontalSpace"), - # 20: CompletionChunk.Kind("VerticalSpace") -} - -class CompletionChunk: - class Kind: - def __init__(self, name): - self.name = name - - def __str__(self): - return self.name - - def __repr__(self): - return "" % self - - def __init__(self, completionString, key): - self.cs = completionString - self.key = key - self.__kindNumberCache = -1 - - def __repr__(self): - return "{'" + self.spelling + "', " + str(self.kind) + "}" - - @CachedProperty - def spelling(self): - if self.__kindNumber in SpellingCache: - return SpellingCache[self.__kindNumber] - return conf.lib.clang_getCompletionChunkText(self.cs, self.key).spelling - - # We do not use @CachedProperty here, as the manual implementation is - # apparently still significantly faster. Please profile carefully if you - # would like to add CachedProperty back. - @property - def __kindNumber(self): - if self.__kindNumberCache == -1: - self.__kindNumberCache = \ - conf.lib.clang_getCompletionChunkKind(self.cs, self.key) - return self.__kindNumberCache - - @CachedProperty - def kind(self): - return completionChunkKindMap[self.__kindNumber] - - @CachedProperty - def string(self): - res = conf.lib.clang_getCompletionChunkCompletionString(self.cs, - self.key) - - if (res): - return CompletionString(res) - else: - None - - def isKindOptional(self): - return self.__kindNumber == 0 - - def isKindTypedText(self): - return self.__kindNumber == 1 - - def isKindPlaceHolder(self): - return self.__kindNumber == 3 - - def isKindInformative(self): - return self.__kindNumber == 4 - - def isKindResultType(self): - return self.__kindNumber == 15 - -completionChunkKindMap = { - 0: CompletionChunk.Kind("Optional"), - 1: CompletionChunk.Kind("TypedText"), - 2: CompletionChunk.Kind("Text"), - 3: CompletionChunk.Kind("Placeholder"), - 4: CompletionChunk.Kind("Informative"), - 5: CompletionChunk.Kind("CurrentParameter"), - 6: CompletionChunk.Kind("LeftParen"), - 7: CompletionChunk.Kind("RightParen"), - 8: CompletionChunk.Kind("LeftBracket"), - 9: CompletionChunk.Kind("RightBracket"), - 10: CompletionChunk.Kind("LeftBrace"), - 11: CompletionChunk.Kind("RightBrace"), - 12: CompletionChunk.Kind("LeftAngle"), - 13: CompletionChunk.Kind("RightAngle"), - 14: CompletionChunk.Kind("Comma"), - 15: CompletionChunk.Kind("ResultType"), - 16: CompletionChunk.Kind("Colon"), - 17: CompletionChunk.Kind("SemiColon"), - 18: CompletionChunk.Kind("Equal"), - 19: CompletionChunk.Kind("HorizontalSpace"), - 20: CompletionChunk.Kind("VerticalSpace")} - -class CompletionString(ClangObject): - class Availability: - def __init__(self, name): - self.name = name - - def __str__(self): - return self.name - - def __repr__(self): - return "" % self - - def __len__(self): - return self.num_chunks - - @CachedProperty - def num_chunks(self): - return conf.lib.clang_getNumCompletionChunks(self.obj) - - def __getitem__(self, key): - if self.num_chunks <= key: - raise IndexError - return CompletionChunk(self.obj, key) - - @property - def priority(self): - return conf.lib.clang_getCompletionPriority(self.obj) - - @property - def availability(self): - res = conf.lib.clang_getCompletionAvailability(self.obj) - return availabilityKinds[res] - - @property - def briefComment(self): - if conf.function_exists("clang_getCompletionBriefComment"): - return conf.lib.clang_getCompletionBriefComment(self.obj) - return _CXString() - - def __repr__(self): - return " | ".join([str(a) for a in self]) \ - + " || Priority: " + str(self.priority) \ - + " || Availability: " + str(self.availability) \ - + " || Brief comment: " + str(self.briefComment.spelling) - -availabilityKinds = { - 0: CompletionChunk.Kind("Available"), - 1: CompletionChunk.Kind("Deprecated"), - 2: CompletionChunk.Kind("NotAvailable"), - 3: CompletionChunk.Kind("NotAccessible")} - -class CodeCompletionResult(Structure): - _fields_ = [('cursorKind', c_int), ('completionString', c_object_p)] - - def __repr__(self): - return str(CompletionString(self.completionString)) - - @property - def kind(self): - return CursorKind.from_id(self.cursorKind) - - @property - def string(self): - return CompletionString(self.completionString) - -class CCRStructure(Structure): - _fields_ = [('results', POINTER(CodeCompletionResult)), - ('numResults', c_int)] - - def __len__(self): - return self.numResults - - def __getitem__(self, key): - if len(self) <= key: - raise IndexError - - return self.results[key] - -class CodeCompletionResults(ClangObject): - def __init__(self, ptr): - assert isinstance(ptr, POINTER(CCRStructure)) and ptr - self.ptr = self._as_parameter_ = ptr - - def from_param(self): - return self._as_parameter_ - - def __del__(self): - conf.lib.clang_disposeCodeCompleteResults(self) - - @property - def results(self): - return self.ptr.contents - - @property - def diagnostics(self): - class DiagnosticsItr: - def __init__(self, ccr): - self.ccr= ccr - - def __len__(self): - return int(\ - conf.lib.clang_codeCompleteGetNumDiagnostics(self.ccr)) - - def __getitem__(self, key): - return conf.lib.clang_codeCompleteGetDiagnostic(self.ccr, key) - - return DiagnosticsItr(self) - - -class Index(ClangObject): - """ - The Index type provides the primary interface to the Clang CIndex library, - primarily by providing an interface for reading and parsing translation - units. - """ - - @staticmethod - def create(excludeDecls=False): - """ - Create a new Index. - Parameters: - excludeDecls -- Exclude local declarations from translation units. - """ - return Index(conf.lib.clang_createIndex(excludeDecls, 0)) - - def __del__(self): - conf.lib.clang_disposeIndex(self) - - def read(self, path): - """Load a TranslationUnit from the given AST file.""" - return TranslationUnit.from_ast_file(path, self) - - def parse(self, path, args=None, unsaved_files=None, options = 0): - """Load the translation unit from the given source code file by running - clang and generating the AST before loading. Additional command line - parameters can be passed to clang via the args parameter. - - In-memory contents for files can be provided by passing a list of pairs - to as unsaved_files, the first item should be the filenames to be mapped - and the second should be the contents to be substituted for the - file. The contents may be passed as strings or file objects. - - If an error was encountered during parsing, a TranslationUnitLoadError - will be raised. - """ - return TranslationUnit.from_source(path, args, unsaved_files, options, - self) - -class TranslationUnit(ClangObject): - """Represents a source code translation unit. - - This is one of the main types in the API. Any time you wish to interact - with Clang's representation of a source file, you typically start with a - translation unit. - """ - - # Default parsing mode. - PARSE_NONE = 0 - - # Instruct the parser to create a detailed processing record containing - # metadata not normally retained. - PARSE_DETAILED_PROCESSING_RECORD = 1 - - # Indicates that the translation unit is incomplete. This is typically used - # when parsing headers. - PARSE_INCOMPLETE = 2 - - # Instruct the parser to create a pre-compiled preamble for the translation - # unit. This caches the preamble (included files at top of source file). - # This is useful if the translation unit will be reparsed and you don't - # want to incur the overhead of reparsing the preamble. - PARSE_PRECOMPILED_PREAMBLE = 4 - - # Cache code completion information on parse. This adds time to parsing but - # speeds up code completion. - PARSE_CACHE_COMPLETION_RESULTS = 8 - - # Flags with values 16 and 32 are deprecated and intentionally omitted. - - # Do not parse function bodies. This is useful if you only care about - # searching for declarations/definitions. - PARSE_SKIP_FUNCTION_BODIES = 64 - - # Used to indicate that brief documentation comments should be included - # into the set of code completions returned from this translation unit. - PARSE_INCLUDE_BRIEF_COMMENTS_IN_CODE_COMPLETION = 128 - - @classmethod - def from_source(cls, filename, args=None, unsaved_files=None, options=0, - index=None): - """Create a TranslationUnit by parsing source. - - This is capable of processing source code both from files on the - filesystem as well as in-memory contents. - - Command-line arguments that would be passed to clang are specified as - a list via args. These can be used to specify include paths, warnings, - etc. e.g. ["-Wall", "-I/path/to/include"]. - - In-memory file content can be provided via unsaved_files. This is an - iterable of 2-tuples. The first element is the str filename. The - second element defines the content. Content can be provided as str - source code or as file objects (anything with a read() method). If - a file object is being used, content will be read until EOF and the - read cursor will not be reset to its original position. - - options is a bitwise or of TranslationUnit.PARSE_XXX flags which will - control parsing behavior. - - index is an Index instance to utilize. If not provided, a new Index - will be created for this TranslationUnit. - - To parse source from the filesystem, the filename of the file to parse - is specified by the filename argument. Or, filename could be None and - the args list would contain the filename(s) to parse. - - To parse source from an in-memory buffer, set filename to the virtual - filename you wish to associate with this source (e.g. "test.c"). The - contents of that file are then provided in unsaved_files. - - If an error occurs, a TranslationUnitLoadError is raised. - - Please note that a TranslationUnit with parser errors may be returned. - It is the caller's responsibility to check tu.diagnostics for errors. - - Also note that Clang infers the source language from the extension of - the input filename. If you pass in source code containing a C++ class - declaration with the filename "test.c" parsing will fail. - """ - if args is None: - args = [] - - if unsaved_files is None: - unsaved_files = [] - - if index is None: - index = Index.create() - - if isinstance(filename, str): - filename = filename.encode('utf8') - - args_length = len(args) - if args_length > 0: - args = (arg.encode('utf8') if isinstance(arg, str) else arg - for arg in args) - args_array = (c_char_p * args_length)(* args) - - unsaved_array = None - if len(unsaved_files) > 0: - unsaved_array = (_CXUnsavedFile * len(unsaved_files))() - for i, (name, contents) in enumerate(unsaved_files): - if hasattr(contents, "read"): - contents = contents.read() - - unsaved_array[i].name = name - unsaved_array[i].contents = contents - unsaved_array[i].length = len(contents) - - ptr = conf.lib.clang_parseTranslationUnit(index, filename, args_array, - args_length, unsaved_array, - len(unsaved_files), options) - - if not ptr: - raise TranslationUnitLoadError("Error parsing translation unit.") - - return cls(ptr, index=index) - - @classmethod - def from_ast_file(cls, filename, index=None): - """Create a TranslationUnit instance from a saved AST file. - - A previously-saved AST file (provided with -emit-ast or - TranslationUnit.save()) is loaded from the filename specified. - - If the file cannot be loaded, a TranslationUnitLoadError will be - raised. - - index is optional and is the Index instance to use. If not provided, - a default Index will be created. - """ - if index is None: - index = Index.create() - - ptr = conf.lib.clang_createTranslationUnit(index, filename) - if not ptr: - raise TranslationUnitLoadError(filename) - - return cls(ptr=ptr, index=index) - - def __init__(self, ptr, index): - """Create a TranslationUnit instance. - - TranslationUnits should be created using one of the from_* @classmethod - functions above. __init__ is only called internally. - """ - assert isinstance(index, Index) - self.index = index - ClangObject.__init__(self, ptr) - - def __del__(self): - conf.lib.clang_disposeTranslationUnit(self) - - @property - def cursor(self): - """Retrieve the cursor that represents the given translation unit.""" - return conf.lib.clang_getTranslationUnitCursor(self) - - @property - def spelling(self): - """Get the original translation unit source file name.""" - return conf.lib.clang_getTranslationUnitSpelling(self) - - def get_includes(self): - """ - Return an iterable sequence of FileInclusion objects that describe the - sequence of inclusions in a translation unit. The first object in - this sequence is always the input file. Note that this method will not - recursively iterate over header files included through precompiled - headers. - """ - def visitor(fobj, lptr, depth, includes): - if depth > 0: - loc = lptr.contents - includes.append(FileInclusion(loc.file, File(fobj), loc, depth)) - - # Automatically adapt CIndex/ctype pointers to python objects - includes = [] - conf.lib.clang_getInclusions(self, - callbacks['translation_unit_includes'](visitor), includes) - - return iter(includes) - - def get_file(self, filename): - """Obtain a File from this translation unit.""" - - return File.from_name(self, filename) - - def get_location(self, filename, position): - """Obtain a SourceLocation for a file in this translation unit. - - The position can be specified by passing: - - - Integer file offset. Initial file offset is 0. - - 2-tuple of (line number, column number). Initial file position is - (0, 0) - """ - f = self.get_file(filename) - - if isinstance(position, int): - return SourceLocation.from_offset(self, f, position) - - return SourceLocation.from_position(self, f, position[0], position[1]) - - def get_extent(self, filename, locations): - """Obtain a SourceRange from this translation unit. - - The bounds of the SourceRange must ultimately be defined by a start and - end SourceLocation. For the locations argument, you can pass: - - - 2 SourceLocation instances in a 2-tuple or list. - - 2 int file offsets via a 2-tuple or list. - - 2 2-tuple or lists of (line, column) pairs in a 2-tuple or list. - - e.g. - - get_extent('foo.c', (5, 10)) - get_extent('foo.c', ((1, 1), (1, 15))) - """ - f = self.get_file(filename) - - if len(locations) < 2: - raise Exception('Must pass object with at least 2 elements') - - start_location, end_location = locations - - if hasattr(start_location, '__len__'): - start_location = SourceLocation.from_position(self, f, - start_location[0], start_location[1]) - elif isinstance(start_location, int): - start_location = SourceLocation.from_offset(self, f, - start_location) - - if hasattr(end_location, '__len__'): - end_location = SourceLocation.from_position(self, f, - end_location[0], end_location[1]) - elif isinstance(end_location, int): - end_location = SourceLocation.from_offset(self, f, end_location) - - assert isinstance(start_location, SourceLocation) - assert isinstance(end_location, SourceLocation) - - return SourceRange.from_locations(start_location, end_location) - - @property - def diagnostics(self): - """ - Return an iterable (and indexable) object containing the diagnostics. - """ - class DiagIterator: - def __init__(self, tu): - self.tu = tu - - def __len__(self): - return int(conf.lib.clang_getNumDiagnostics(self.tu)) - - def __getitem__(self, key): - diag = conf.lib.clang_getDiagnostic(self.tu, key) - if not diag: - raise IndexError - return Diagnostic(diag) - - return DiagIterator(self) - - def reparse(self, unsaved_files=None, options=0): - """ - Reparse an already parsed translation unit. - - In-memory contents for files can be provided by passing a list of pairs - as unsaved_files, the first items should be the filenames to be mapped - and the second should be the contents to be substituted for the - file. The contents may be passed as strings or file objects. - """ - if unsaved_files is None: - unsaved_files = [] - - unsaved_files_array = 0 - if len(unsaved_files): - unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))() - for i,(name,value) in enumerate(unsaved_files): - if not isinstance(value, str): - # FIXME: It would be great to support an efficient version - # of this, one day. - value = value.read() - print(value) - if not isinstance(value, str): - raise TypeError('Unexpected unsaved file contents.') - unsaved_files_array[i].name = name - unsaved_files_array[i].contents = value - unsaved_files_array[i].length = len(value) - ptr = conf.lib.clang_reparseTranslationUnit(self, len(unsaved_files), - unsaved_files_array, options) - - def save(self, filename): - """Saves the TranslationUnit to a file. - - This is equivalent to passing -emit-ast to the clang frontend. The - saved file can be loaded back into a TranslationUnit. Or, if it - corresponds to a header, it can be used as a pre-compiled header file. - - If an error occurs while saving, a TranslationUnitSaveError is raised. - If the error was TranslationUnitSaveError.ERROR_INVALID_TU, this means - the constructed TranslationUnit was not valid at time of save. In this - case, the reason(s) why should be available via - TranslationUnit.diagnostics(). - - filename -- The path to save the translation unit to. - """ - options = conf.lib.clang_defaultSaveOptions(self) - result = int(conf.lib.clang_saveTranslationUnit(self, filename, - options)) - if result != 0: - raise TranslationUnitSaveError(result, - 'Error saving TranslationUnit.') - - def codeComplete(self, path, line, column, unsaved_files=None, - include_macros=False, include_code_patterns=False, - include_brief_comments=False): - """ - Code complete in this translation unit. - - In-memory contents for files can be provided by passing a list of pairs - as unsaved_files, the first items should be the filenames to be mapped - and the second should be the contents to be substituted for the - file. The contents may be passed as strings or file objects. - """ - options = 0 - - if include_macros: - options += 1 - - if include_code_patterns: - options += 2 - - if include_brief_comments: - options += 4 - - if unsaved_files is None: - unsaved_files = [] - - unsaved_files_array = 0 - if len(unsaved_files): - unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))() - for i,(name,value) in enumerate(unsaved_files): - if not isinstance(value, str): - # FIXME: It would be great to support an efficient version - # of this, one day. - value = value.read() - print(value) - if not isinstance(value, str): - raise TypeError('Unexpected unsaved file contents.') - unsaved_files_array[i].name = name - unsaved_files_array[i].contents = value - unsaved_files_array[i].length = len(value) - ptr = conf.lib.clang_codeCompleteAt(self, path, line, column, - unsaved_files_array, len(unsaved_files), options) - if ptr: - return CodeCompletionResults(ptr) - return None - - def get_tokens(self, locations=None, extent=None): - """Obtain tokens in this translation unit. - - This is a generator for Token instances. The caller specifies a range - of source code to obtain tokens for. The range can be specified as a - 2-tuple of SourceLocation or as a SourceRange. If both are defined, - behavior is undefined. - """ - if locations is not None: - extent = SourceRange(start=locations[0], end=locations[1]) - - return TokenGroup.get_tokens(self, extent) - -class File(ClangObject): - """ - The File class represents a particular source file that is part of a - translation unit. - """ - - @staticmethod - def from_name(translation_unit, file_name): - """Retrieve a file handle within the given translation unit.""" - return File(conf.lib.clang_getFile(translation_unit, file_name)) - - @property - def name(self): - """Return the complete file and path name of the file.""" - return conf.lib.clang_getCString(conf.lib.clang_getFileName(self)) - - @property - def time(self): - """Return the last modification time of the file.""" - return conf.lib.clang_getFileTime(self) - - def __bytes__(self): - return self.name - - def __repr__(self): - return "" % (self.name) - - @staticmethod - def from_cursor_result(res, fn, args): - assert isinstance(res, File) - - # Copy a reference to the TranslationUnit to prevent premature GC. - res._tu = args[0]._tu - return res - -class FileInclusion(object): - """ - The FileInclusion class represents the inclusion of one source file by - another via a '#include' directive or as the input file for the translation - unit. This class provides information about the included file, the including - file, the location of the '#include' directive and the depth of the included - file in the stack. Note that the input file has depth 0. - """ - - def __init__(self, src, tgt, loc, depth): - self.source = src - self.include = tgt - self.location = loc - self.depth = depth - - @property - def is_input_file(self): - """True if the included file is the input file.""" - return self.depth == 0 - -class CompilationDatabaseError(Exception): - """Represents an error that occurred when working with a CompilationDatabase - - Each error is associated to an enumerated value, accessible under - e.cdb_error. Consumers can compare the value with one of the ERROR_ - constants in this class. - """ - - # An unknown error occurred - ERROR_UNKNOWN = 0 - - # The database could not be loaded - ERROR_CANNOTLOADDATABASE = 1 - - def __init__(self, enumeration, message): - assert isinstance(enumeration, int) - - if enumeration > 1: - raise Exception("Encountered undefined CompilationDatabase error " - "constant: %d. Please file a bug to have this " - "value supported." % enumeration) - - self.cdb_error = enumeration - Exception.__init__(self, 'Error %d: %s' % (enumeration, message)) - -class CompileCommand(object): - """Represents the compile command used to build a file""" - def __init__(self, cmd, ccmds): - self.cmd = cmd - # Keep a reference to the originating CompileCommands - # to prevent garbage collection - self.ccmds = ccmds - - @property - def directory(self): - """Get the working directory for this CompileCommand""" - return conf.lib.clang_CompileCommand_getDirectory(self.cmd) - - @property - def filename(self): - """Get the working filename for this CompileCommand""" - return conf.lib.clang_CompileCommand_getFilename(self.cmd) - - @property - def arguments(self): - """ - Get an iterable object providing each argument in the - command line for the compiler invocation as a _CXString. - - Invariant : the first argument is the compiler executable - """ - length = conf.lib.clang_CompileCommand_getNumArgs(self.cmd) - for i in range(length): - yield conf.lib.clang_CompileCommand_getArg(self.cmd, i) - -class CompileCommands(object): - """ - CompileCommands is an iterable object containing all CompileCommand - that can be used for building a specific file. - """ - def __init__(self, ccmds): - self.ccmds = ccmds - - def __del__(self): - conf.lib.clang_CompileCommands_dispose(self.ccmds) - - def __len__(self): - return int(conf.lib.clang_CompileCommands_getSize(self.ccmds)) - - def __getitem__(self, i): - cc = conf.lib.clang_CompileCommands_getCommand(self.ccmds, i) - if not cc: - raise IndexError - return CompileCommand(cc, self) - - @staticmethod - def from_result(res, fn, args): - if not res: - return None - return CompileCommands(res) - -class CompilationDatabase(ClangObject): - """ - The CompilationDatabase is a wrapper class around - clang::tooling::CompilationDatabase - - It enables querying how a specific source file can be built. - """ - - def __del__(self): - conf.lib.clang_CompilationDatabase_dispose(self) - - @staticmethod - def from_result(res, fn, args): - if not res: - raise CompilationDatabaseError(0, - "CompilationDatabase loading failed") - return CompilationDatabase(res) - - @staticmethod - def fromDirectory(buildDir): - """Builds a CompilationDatabase from the database found in buildDir""" - errorCode = c_uint() - try: - cdb = conf.lib.clang_CompilationDatabase_fromDirectory(buildDir, - byref(errorCode)) - except CompilationDatabaseError as e: - raise CompilationDatabaseError(int(errorCode.value), - "CompilationDatabase loading failed") - return cdb - - def getCompileCommands(self, filename): - """ - Get an iterable object providing all the CompileCommands available to - build filename. Returns None if filename is not found in the database. - """ - return conf.lib.clang_CompilationDatabase_getCompileCommands(self, - filename) - - def getAllCompileCommands(self): - """ - Get an iterable object providing all the CompileCommands available from - the database. - """ - return conf.lib.clang_CompilationDatabase_getAllCompileCommands(self) - - -class Token(Structure): - """Represents a single token from the preprocessor. - - Tokens are effectively segments of source code. Source code is first parsed - into tokens before being converted into the AST and Cursors. - - Tokens are obtained from parsed TranslationUnit instances. You currently - can't create tokens manually. - """ - _fields_ = [ - ('int_data', c_uint * 4), - ('ptr_data', c_void_p) - ] - - @property - def spelling(self): - """The spelling of this token. - - This is the textual representation of the token in source. - """ - return conf.lib.clang_getTokenSpelling(self._tu, self) - - @property - def kind(self): - """Obtain the TokenKind of the current token.""" - return TokenKind.from_value(conf.lib.clang_getTokenKind(self)) - - @property - def location(self): - """The SourceLocation this Token occurs at.""" - return conf.lib.clang_getTokenLocation(self._tu, self) - - @property - def extent(self): - """The SourceRange this Token occupies.""" - return conf.lib.clang_getTokenExtent(self._tu, self) - - @property - def cursor(self): - """The Cursor this Token corresponds to.""" - cursor = Cursor() - - conf.lib.clang_annotateTokens(self._tu, byref(self), 1, byref(cursor)) - - return cursor - -# Now comes the plumbing to hook up the C library. - -# Register callback types in common container. -callbacks['translation_unit_includes'] = CFUNCTYPE(None, c_object_p, - POINTER(SourceLocation), c_uint, py_object) -callbacks['cursor_visit'] = CFUNCTYPE(c_int, Cursor, Cursor, py_object) -callbacks['fields_visit'] = CFUNCTYPE(c_int, Cursor, py_object) - -# Functions strictly alphabetical order. -functionList = [ - ("clang_annotateTokens", - [TranslationUnit, POINTER(Token), c_uint, POINTER(Cursor)]), - - ("clang_CompilationDatabase_dispose", - [c_object_p]), - - ("clang_CompilationDatabase_fromDirectory", - [c_char_p, POINTER(c_uint)], - c_object_p, - CompilationDatabase.from_result), - - ("clang_CompilationDatabase_getAllCompileCommands", - [c_object_p], - c_object_p, - CompileCommands.from_result), - - ("clang_CompilationDatabase_getCompileCommands", - [c_object_p, c_char_p], - c_object_p, - CompileCommands.from_result), - - ("clang_CompileCommands_dispose", - [c_object_p]), - - ("clang_CompileCommands_getCommand", - [c_object_p, c_uint], - c_object_p), - - ("clang_CompileCommands_getSize", - [c_object_p], - c_uint), - - ("clang_CompileCommand_getArg", - [c_object_p, c_uint], - _CXString, - _CXString.from_result), - - ("clang_CompileCommand_getDirectory", - [c_object_p], - _CXString, - _CXString.from_result), - - ("clang_CompileCommand_getFilename", - [c_object_p], - _CXString, - _CXString.from_result), - - ("clang_CompileCommand_getNumArgs", - [c_object_p], - c_uint), - - ("clang_codeCompleteAt", - [TranslationUnit, c_char_p, c_int, c_int, c_void_p, c_int, c_int], - POINTER(CCRStructure)), - - ("clang_codeCompleteGetDiagnostic", - [CodeCompletionResults, c_int], - Diagnostic), - - ("clang_codeCompleteGetNumDiagnostics", - [CodeCompletionResults], - c_int), - - ("clang_createIndex", - [c_int, c_int], - c_object_p), - - ("clang_createTranslationUnit", - [Index, c_char_p], - c_object_p), - - ("clang_CXXConstructor_isConvertingConstructor", - [Cursor], - bool), - - ("clang_CXXConstructor_isCopyConstructor", - [Cursor], - bool), - - ("clang_CXXConstructor_isDefaultConstructor", - [Cursor], - bool), - - ("clang_CXXConstructor_isMoveConstructor", - [Cursor], - bool), - - ("clang_CXXField_isMutable", - [Cursor], - bool), - - ("clang_CXXMethod_isConst", - [Cursor], - bool), - - ("clang_CXXMethod_isDefaulted", - [Cursor], - bool), - - ("clang_CXXMethod_isPureVirtual", - [Cursor], - bool), - - ("clang_CXXMethod_isStatic", - [Cursor], - bool), - - ("clang_CXXMethod_isVirtual", - [Cursor], - bool), - - ("clang_defaultDiagnosticDisplayOptions", - [], - c_uint), - - ("clang_defaultSaveOptions", - [TranslationUnit], - c_uint), - - ("clang_disposeCodeCompleteResults", - [CodeCompletionResults]), - -# ("clang_disposeCXTUResourceUsage", -# [CXTUResourceUsage]), - - ("clang_disposeDiagnostic", - [Diagnostic]), - - ("clang_disposeIndex", - [Index]), - - ("clang_disposeString", - [_CXString]), - - ("clang_disposeTokens", - [TranslationUnit, POINTER(Token), c_uint]), - - ("clang_disposeTranslationUnit", - [TranslationUnit]), - - ("clang_equalCursors", - [Cursor, Cursor], - bool), - - ("clang_equalLocations", - [SourceLocation, SourceLocation], - bool), - - ("clang_equalRanges", - [SourceRange, SourceRange], - bool), - - ("clang_equalTypes", - [Type, Type], - bool), - - ("clang_formatDiagnostic", - [Diagnostic, c_uint], - _CXString), - - ("clang_getArgType", - [Type, c_uint], - Type, - Type.from_result), - - ("clang_getArrayElementType", - [Type], - Type, - Type.from_result), - - ("clang_getArraySize", - [Type], - c_longlong), - - ("clang_getFieldDeclBitWidth", - [Cursor], - c_int), - - ("clang_getCanonicalCursor", - [Cursor], - Cursor, - Cursor.from_cursor_result), - - ("clang_getCanonicalType", - [Type], - Type, - Type.from_result), - - ("clang_getChildDiagnostics", - [Diagnostic], - c_object_p), - - ("clang_getCompletionAvailability", - [c_void_p], - c_int), - - ("clang_getCompletionBriefComment", - [c_void_p], - _CXString), - - ("clang_getCompletionChunkCompletionString", - [c_void_p, c_int], - c_object_p), - - ("clang_getCompletionChunkKind", - [c_void_p, c_int], - c_int), - - ("clang_getCompletionChunkText", - [c_void_p, c_int], - _CXString), - - ("clang_getCompletionPriority", - [c_void_p], - c_int), - - ("clang_getCString", - [_CXString], - c_char_p), - - ("clang_getCursor", - [TranslationUnit, SourceLocation], - Cursor), - - ("clang_getCursorDefinition", - [Cursor], - Cursor, - Cursor.from_result), - - ("clang_getCursorDisplayName", - [Cursor], - _CXString, - _CXString.from_result), - - ("clang_getCursorExtent", - [Cursor], - SourceRange), - - ("clang_getCursorLexicalParent", - [Cursor], - Cursor, - Cursor.from_cursor_result), - - ("clang_getCursorLocation", - [Cursor], - SourceLocation), - - ("clang_getCursorReferenced", - [Cursor], - Cursor, - Cursor.from_result), - - ("clang_getCursorReferenceNameRange", - [Cursor, c_uint, c_uint], - SourceRange), - - ("clang_getCursorSemanticParent", - [Cursor], - Cursor, - Cursor.from_cursor_result), - - ("clang_getCursorSpelling", - [Cursor], - _CXString, - _CXString.from_result), - - ("clang_getCursorType", - [Cursor], - Type, - Type.from_result), - - ("clang_getCursorUSR", - [Cursor], - _CXString, - _CXString.from_result), - - ("clang_Cursor_getMangling", - [Cursor], - _CXString, - _CXString.from_result), - -# ("clang_getCXTUResourceUsage", -# [TranslationUnit], -# CXTUResourceUsage), - - ("clang_getCXXAccessSpecifier", - [Cursor], - c_uint), - - ("clang_getDeclObjCTypeEncoding", - [Cursor], - _CXString, - _CXString.from_result), - - ("clang_getDiagnostic", - [c_object_p, c_uint], - c_object_p), - - ("clang_getDiagnosticCategory", - [Diagnostic], - c_uint), - - ("clang_getDiagnosticCategoryText", - [Diagnostic], - _CXString, - _CXString.from_result), - - ("clang_getDiagnosticFixIt", - [Diagnostic, c_uint, POINTER(SourceRange)], - _CXString, - _CXString.from_result), - - ("clang_getDiagnosticInSet", - [c_object_p, c_uint], - c_object_p), - - ("clang_getDiagnosticLocation", - [Diagnostic], - SourceLocation), - - ("clang_getDiagnosticNumFixIts", - [Diagnostic], - c_uint), - - ("clang_getDiagnosticNumRanges", - [Diagnostic], - c_uint), - - ("clang_getDiagnosticOption", - [Diagnostic, POINTER(_CXString)], - _CXString, - _CXString.from_result), - - ("clang_getDiagnosticRange", - [Diagnostic, c_uint], - SourceRange), - - ("clang_getDiagnosticSeverity", - [Diagnostic], - c_int), - - ("clang_getDiagnosticSpelling", - [Diagnostic], - _CXString, - _CXString.from_result), - - ("clang_getElementType", - [Type], - Type, - Type.from_result), - - ("clang_getEnumConstantDeclUnsignedValue", - [Cursor], - c_ulonglong), - - ("clang_getEnumConstantDeclValue", - [Cursor], - c_longlong), - - ("clang_getEnumDeclIntegerType", - [Cursor], - Type, - Type.from_result), - - ("clang_getFile", - [TranslationUnit, c_char_p], - c_object_p), - - ("clang_getFileName", - [File], - _CXString), # TODO go through _CXString.from_result? - - ("clang_getFileTime", - [File], - c_uint), - - ("clang_getIBOutletCollectionType", - [Cursor], - Type, - Type.from_result), - - ("clang_getIncludedFile", - [Cursor], - File, - File.from_cursor_result), - - ("clang_getInclusions", - [TranslationUnit, callbacks['translation_unit_includes'], py_object]), - - ("clang_getInstantiationLocation", - [SourceLocation, POINTER(c_object_p), POINTER(c_uint), POINTER(c_uint), - POINTER(c_uint)]), - - ("clang_getLocation", - [TranslationUnit, File, c_uint, c_uint], - SourceLocation), - - ("clang_getLocationForOffset", - [TranslationUnit, File, c_uint], - SourceLocation), - - ("clang_getNullCursor", - None, - Cursor), - - ("clang_getNumArgTypes", - [Type], - c_uint), - - ("clang_getNumCompletionChunks", - [c_void_p], - c_int), - - ("clang_getNumDiagnostics", - [c_object_p], - c_uint), - - ("clang_getNumDiagnosticsInSet", - [c_object_p], - c_uint), - - ("clang_getNumElements", - [Type], - c_longlong), - - ("clang_getNumOverloadedDecls", - [Cursor], - c_uint), - - ("clang_getOverloadedDecl", - [Cursor, c_uint], - Cursor, - Cursor.from_cursor_result), - - ("clang_getPointeeType", - [Type], - Type, - Type.from_result), - - ("clang_getRange", - [SourceLocation, SourceLocation], - SourceRange), - - ("clang_getRangeEnd", - [SourceRange], - SourceLocation), - - ("clang_getRangeStart", - [SourceRange], - SourceLocation), - - ("clang_getResultType", - [Type], - Type, - Type.from_result), - - ("clang_getSpecializedCursorTemplate", - [Cursor], - Cursor, - Cursor.from_cursor_result), - - ("clang_getTemplateCursorKind", - [Cursor], - c_uint), - - ("clang_getTokenExtent", - [TranslationUnit, Token], - SourceRange), - - ("clang_getTokenKind", - [Token], - c_uint), - - ("clang_getTokenLocation", - [TranslationUnit, Token], - SourceLocation), - - ("clang_getTokenSpelling", - [TranslationUnit, Token], - _CXString, - _CXString.from_result), - - ("clang_getTranslationUnitCursor", - [TranslationUnit], - Cursor, - Cursor.from_result), - - ("clang_getTranslationUnitSpelling", - [TranslationUnit], - _CXString, - _CXString.from_result), - - ("clang_getTUResourceUsageName", - [c_uint], - c_char_p), - - ("clang_getTypeDeclaration", - [Type], - Cursor, - Cursor.from_result), - - ("clang_getTypedefDeclUnderlyingType", - [Cursor], - Type, - Type.from_result), - - ("clang_getTypeKindSpelling", - [c_uint], - _CXString, - _CXString.from_result), - - ("clang_getTypeSpelling", - [Type], - _CXString, - _CXString.from_result), - - ("clang_hashCursor", - [Cursor], - c_uint), - - ("clang_isAttribute", - [CursorKind], - bool), - - ("clang_isConstQualifiedType", - [Type], - bool), - - ("clang_isCursorDefinition", - [Cursor], - bool), - - ("clang_isDeclaration", - [CursorKind], - bool), - - ("clang_isExpression", - [CursorKind], - bool), - - ("clang_isFileMultipleIncludeGuarded", - [TranslationUnit, File], - bool), - - ("clang_isFunctionTypeVariadic", - [Type], - bool), - - ("clang_isInvalid", - [CursorKind], - bool), - - ("clang_isPODType", - [Type], - bool), - - ("clang_isPreprocessing", - [CursorKind], - bool), - - ("clang_isReference", - [CursorKind], - bool), - - ("clang_isRestrictQualifiedType", - [Type], - bool), - - ("clang_isStatement", - [CursorKind], - bool), - - ("clang_isTranslationUnit", - [CursorKind], - bool), - - ("clang_isUnexposed", - [CursorKind], - bool), - - ("clang_isVirtualBase", - [Cursor], - bool), - - ("clang_isVolatileQualifiedType", - [Type], - bool), - - ("clang_parseTranslationUnit", - [Index, c_char_p, c_void_p, c_int, c_void_p, c_int, c_int], - c_object_p), - - ("clang_reparseTranslationUnit", - [TranslationUnit, c_int, c_void_p, c_int], - c_int), - - ("clang_saveTranslationUnit", - [TranslationUnit, c_char_p, c_uint], - c_int), - - ("clang_tokenize", - [TranslationUnit, SourceRange, POINTER(POINTER(Token)), POINTER(c_uint)]), - - ("clang_visitChildren", - [Cursor, callbacks['cursor_visit'], py_object], - c_uint), - - ("clang_Cursor_getNumArguments", - [Cursor], - c_int), - - ("clang_Cursor_getArgument", - [Cursor, c_uint], - Cursor, - Cursor.from_result), - - ("clang_Cursor_getNumTemplateArguments", - [Cursor], - c_int), - - ("clang_Cursor_getTemplateArgumentKind", - [Cursor, c_uint], - TemplateArgumentKind.from_id), - - ("clang_Cursor_getTemplateArgumentType", - [Cursor, c_uint], - Type, - Type.from_result), - - ("clang_Cursor_getTemplateArgumentValue", - [Cursor, c_uint], - c_longlong), - - ("clang_Cursor_getTemplateArgumentUnsignedValue", - [Cursor, c_uint], - c_ulonglong), - - ("clang_Cursor_isAnonymous", - [Cursor], - bool), - - ("clang_Cursor_isBitField", - [Cursor], - bool), - - ("clang_Cursor_getBriefCommentText", - [Cursor], - _CXString, - _CXString.from_result), - - ("clang_Cursor_getRawCommentText", - [Cursor], - _CXString, - _CXString.from_result), - - ("clang_Cursor_getOffsetOfField", - [Cursor], - c_longlong), - - ("clang_Type_getAlignOf", - [Type], - c_longlong), - - ("clang_Type_getClassType", - [Type], - Type, - Type.from_result), - - ("clang_Type_getOffsetOf", - [Type, c_char_p], - c_longlong), - - ("clang_Type_getSizeOf", - [Type], - c_longlong), - - ("clang_Type_getCXXRefQualifier", - [Type], - c_uint), - - ("clang_Type_getNamedType", - [Type], - Type, - Type.from_result), - - ("clang_Type_visitFields", - [Type, callbacks['fields_visit'], py_object], - c_uint), -] - -class LibclangError(Exception): - def __init__(self, message): - self.m = message - - def __str__(self): - return self.m - -def register_function(lib, item, ignore_errors): - # A function may not exist, if these bindings are used with an older or - # incompatible version of libclang.so. - try: - func = getattr(lib, item[0]) - except AttributeError as e: - msg = str(e) + ". Please ensure that your python bindings are "\ - "compatible with your libclang.so version." - if ignore_errors: - return - raise LibclangError(msg) - - if len(item) >= 2: - func.argtypes = item[1] - - if len(item) >= 3: - func.restype = item[2] - - if len(item) == 4: - func.errcheck = item[3] - -def register_functions(lib, ignore_errors): - """Register function prototypes with a libclang library instance. - - This must be called as part of library instantiation so Python knows how - to call out to the shared library. - """ - - def register(item): - return register_function(lib, item, ignore_errors) - - for f in functionList: - register(f) - -class Config: - library_path = None - library_file = None - compatibility_check = False - loaded = False - - @staticmethod - def set_library_path(path): - """Set the path in which to search for libclang""" - if Config.loaded: - raise Exception("library path must be set before before using " \ - "any other functionalities in libclang.") - - Config.library_path = path - - @staticmethod - def set_library_file(filename): - """Set the exact location of libclang""" - if Config.loaded: - raise Exception("library file must be set before before using " \ - "any other functionalities in libclang.") - - Config.library_file = filename - - @staticmethod - def set_compatibility_check(check_status): - """ Perform compatibility check when loading libclang - - The python bindings are only tested and evaluated with the version of - libclang they are provided with. To ensure correct behavior a (limited) - compatibility check is performed when loading the bindings. This check - will throw an exception, as soon as it fails. - - In case these bindings are used with an older version of libclang, parts - that have been stable between releases may still work. Users of the - python bindings can disable the compatibility check. This will cause - the python bindings to load, even though they are written for a newer - version of libclang. Failures now arise if unsupported or incompatible - features are accessed. The user is required to test themselves if the - features they are using are available and compatible between different - libclang versions. - """ - if Config.loaded: - raise Exception("compatibility_check must be set before before " \ - "using any other functionalities in libclang.") - - Config.compatibility_check = check_status - - @CachedProperty - def lib(self): - lib = self.get_cindex_library() - register_functions(lib, not Config.compatibility_check) - Config.loaded = True - return lib - - def get_filename(self): - if Config.library_file: - return Config.library_file - - import platform - name = platform.system() - - if name == 'Darwin': - file = 'libclang.dylib' - elif name == 'Windows': - file = 'libclang.dll' - else: - file = 'libclang.so' - - if Config.library_path: - file = Config.library_path + '/' + file - - return file - - def get_cindex_library(self): - try: - library = cdll.LoadLibrary(self.get_filename()) - except OSError as e: - msg = str(e) + ". To provide a path to libclang use " \ - "Config.set_library_path() or " \ - "Config.set_library_file()." - raise LibclangError(msg) - - return library - - def function_exists(self, name): - try: - getattr(self.lib, name) - except AttributeError: - return False - - return True - -def register_enumerations(): - for name, value in clang.enumerations.TokenKinds: - TokenKind.register(value, name) - -conf = Config() -register_enumerations() - -__all__ = [ - 'Config', - 'CodeCompletionResults', - 'CompilationDatabase', - 'CompileCommands', - 'CompileCommand', - 'CursorKind', - 'Cursor', - 'Diagnostic', - 'File', - 'FixIt', - 'Index', - 'SourceLocation', - 'SourceRange', - 'TokenKind', - 'Token', - 'TranslationUnitLoadError', - 'TranslationUnit', - 'TypeKind', - 'Type', -] diff --git a/VFRendering/thirdparty/pybind11/tools/clang/enumerations.py b/VFRendering/thirdparty/pybind11/tools/clang/enumerations.py deleted file mode 100644 index a86a48ade..000000000 --- a/VFRendering/thirdparty/pybind11/tools/clang/enumerations.py +++ /dev/null @@ -1,34 +0,0 @@ -#===- enumerations.py - Python Enumerations ------------------*- python -*--===# -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -#===------------------------------------------------------------------------===# - -""" -Clang Enumerations -================== - -This module provides static definitions of enumerations that exist in libclang. - -Enumerations are typically defined as a list of tuples. The exported values are -typically munged into other types or classes at module load time. - -All enumerations are centrally defined in this file so they are all grouped -together and easier to audit. And, maybe even one day this file will be -automatically generated by scanning the libclang headers! -""" - -# Maps to CXTokenKind. Note that libclang maintains a separate set of token -# enumerations from the C++ API. -TokenKinds = [ - ('PUNCTUATION', 0), - ('KEYWORD', 1), - ('IDENTIFIER', 2), - ('LITERAL', 3), - ('COMMENT', 4), -] - -__all__ = ['TokenKinds'] diff --git a/VFRendering/thirdparty/pybind11/tools/libsize.py b/VFRendering/thirdparty/pybind11/tools/libsize.py deleted file mode 100644 index 5dcb8b0d0..000000000 --- a/VFRendering/thirdparty/pybind11/tools/libsize.py +++ /dev/null @@ -1,38 +0,0 @@ -from __future__ import print_function, division -import os -import sys - -# Internal build script for generating debugging test .so size. -# Usage: -# python libsize.py file.so save.txt -- displays the size of file.so and, if save.txt exists, compares it to the -# size in it, then overwrites save.txt with the new size for future runs. - -if len(sys.argv) != 3: - sys.exit("Invalid arguments: usage: python libsize.py file.so save.txt") - -lib = sys.argv[1] -save = sys.argv[2] - -if not os.path.exists(lib): - sys.exit("Error: requested file ({}) does not exist".format(lib)) - -libsize = os.path.getsize(lib) - -print("------", os.path.basename(lib), "file size:", libsize, end='') - -if os.path.exists(save): - with open(save) as sf: - oldsize = int(sf.readline()) - - if oldsize > 0: - change = libsize - oldsize - if change == 0: - print(" (no change)") - else: - print(" (change of {:+} bytes = {:+.2%})".format(change, change / oldsize)) -else: - print() - -with open(save, 'w') as sf: - sf.write(str(libsize)) - diff --git a/VFRendering/thirdparty/pybind11/tools/mkdoc.py b/VFRendering/thirdparty/pybind11/tools/mkdoc.py deleted file mode 100644 index 1fd8cceed..000000000 --- a/VFRendering/thirdparty/pybind11/tools/mkdoc.py +++ /dev/null @@ -1,304 +0,0 @@ -#!/usr/bin/env python3 -# -# Syntax: mkdoc.py [-I ..] [.. a list of header files ..] -# -# Extract documentation from C++ header files to use it in Python bindings -# - -import os -import sys -import platform -import re -import textwrap - -from clang import cindex -from clang.cindex import CursorKind -from collections import OrderedDict -from threading import Thread, Semaphore -from multiprocessing import cpu_count - -RECURSE_LIST = [ - CursorKind.TRANSLATION_UNIT, - CursorKind.NAMESPACE, - CursorKind.CLASS_DECL, - CursorKind.STRUCT_DECL, - CursorKind.ENUM_DECL, - CursorKind.CLASS_TEMPLATE -] - -PRINT_LIST = [ - CursorKind.CLASS_DECL, - CursorKind.STRUCT_DECL, - CursorKind.ENUM_DECL, - CursorKind.ENUM_CONSTANT_DECL, - CursorKind.CLASS_TEMPLATE, - CursorKind.FUNCTION_DECL, - CursorKind.FUNCTION_TEMPLATE, - CursorKind.CONVERSION_FUNCTION, - CursorKind.CXX_METHOD, - CursorKind.CONSTRUCTOR, - CursorKind.FIELD_DECL -] - -CPP_OPERATORS = { - '<=': 'le', '>=': 'ge', '==': 'eq', '!=': 'ne', '[]': 'array', - '+=': 'iadd', '-=': 'isub', '*=': 'imul', '/=': 'idiv', '%=': - 'imod', '&=': 'iand', '|=': 'ior', '^=': 'ixor', '<<=': 'ilshift', - '>>=': 'irshift', '++': 'inc', '--': 'dec', '<<': 'lshift', '>>': - 'rshift', '&&': 'land', '||': 'lor', '!': 'lnot', '~': 'bnot', - '&': 'band', '|': 'bor', '+': 'add', '-': 'sub', '*': 'mul', '/': - 'div', '%': 'mod', '<': 'lt', '>': 'gt', '=': 'assign', '()': 'call' -} - -CPP_OPERATORS = OrderedDict( - sorted(CPP_OPERATORS.items(), key=lambda t: -len(t[0]))) - -job_count = cpu_count() -job_semaphore = Semaphore(job_count) - -output = [] - -def d(s): - return s.decode('utf8') - - -def sanitize_name(name): - name = re.sub(r'type-parameter-0-([0-9]+)', r'T\1', name) - for k, v in CPP_OPERATORS.items(): - name = name.replace('operator%s' % k, 'operator_%s' % v) - name = re.sub('<.*>', '', name) - name = ''.join([ch if ch.isalnum() else '_' for ch in name]) - name = re.sub('_$', '', re.sub('_+', '_', name)) - return '__doc_' + name - - -def process_comment(comment): - result = '' - - # Remove C++ comment syntax - leading_spaces = float('inf') - for s in comment.expandtabs(tabsize=4).splitlines(): - s = s.strip() - if s.startswith('/*'): - s = s[2:].lstrip('*') - elif s.endswith('*/'): - s = s[:-2].rstrip('*') - elif s.startswith('///'): - s = s[3:] - if s.startswith('*'): - s = s[1:] - if len(s) > 0: - leading_spaces = min(leading_spaces, len(s) - len(s.lstrip())) - result += s + '\n' - - if leading_spaces != float('inf'): - result2 = "" - for s in result.splitlines(): - result2 += s[leading_spaces:] + '\n' - result = result2 - - # Doxygen tags - cpp_group = '([\w:]+)' - param_group = '([\[\w:\]]+)' - - s = result - s = re.sub(r'\\c\s+%s' % cpp_group, r'``\1``', s) - s = re.sub(r'\\a\s+%s' % cpp_group, r'*\1*', s) - s = re.sub(r'\\e\s+%s' % cpp_group, r'*\1*', s) - s = re.sub(r'\\em\s+%s' % cpp_group, r'*\1*', s) - s = re.sub(r'\\b\s+%s' % cpp_group, r'**\1**', s) - s = re.sub(r'\\ingroup\s+%s' % cpp_group, r'', s) - s = re.sub(r'\\param%s?\s+%s' % (param_group, cpp_group), - r'\n\n$Parameter ``\2``:\n\n', s) - s = re.sub(r'\\tparam%s?\s+%s' % (param_group, cpp_group), - r'\n\n$Template parameter ``\2``:\n\n', s) - - for in_, out_ in { - 'return': 'Returns', - 'author': 'Author', - 'authors': 'Authors', - 'copyright': 'Copyright', - 'date': 'Date', - 'remark': 'Remark', - 'sa': 'See also', - 'see': 'See also', - 'extends': 'Extends', - 'throw': 'Throws', - 'throws': 'Throws' - }.items(): - s = re.sub(r'\\%s\s*' % in_, r'\n\n$%s:\n\n' % out_, s) - - s = re.sub(r'\\details\s*', r'\n\n', s) - s = re.sub(r'\\brief\s*', r'', s) - s = re.sub(r'\\short\s*', r'', s) - s = re.sub(r'\\ref\s*', r'', s) - - s = re.sub(r'\\code\s?(.*?)\s?\\endcode', - r"```\n\1\n```\n", s, flags=re.DOTALL) - - # HTML/TeX tags - s = re.sub(r'(.*?)', r'``\1``', s, flags=re.DOTALL) - s = re.sub(r'
(.*?)
', r"```\n\1\n```\n", s, flags=re.DOTALL) - s = re.sub(r'(.*?)', r'*\1*', s, flags=re.DOTALL) - s = re.sub(r'(.*?)', r'**\1**', s, flags=re.DOTALL) - s = re.sub(r'\\f\$(.*?)\\f\$', r'$\1$', s, flags=re.DOTALL) - s = re.sub(r'
  • ', r'\n\n* ', s) - s = re.sub(r'', r'', s) - s = re.sub(r'
  • ', r'\n\n', s) - - s = s.replace('``true``', '``True``') - s = s.replace('``false``', '``False``') - - # Re-flow text - wrapper = textwrap.TextWrapper() - wrapper.expand_tabs = True - wrapper.replace_whitespace = True - wrapper.drop_whitespace = True - wrapper.width = 70 - wrapper.initial_indent = wrapper.subsequent_indent = '' - - result = '' - in_code_segment = False - for x in re.split(r'(```)', s): - if x == '```': - if not in_code_segment: - result += '```\n' - else: - result += '\n```\n\n' - in_code_segment = not in_code_segment - elif in_code_segment: - result += x.strip() - else: - for y in re.split(r'(?: *\n *){2,}', x): - wrapped = wrapper.fill(re.sub(r'\s+', ' ', y).strip()) - if len(wrapped) > 0 and wrapped[0] == '$': - result += wrapped[1:] + '\n' - wrapper.initial_indent = \ - wrapper.subsequent_indent = ' ' * 4 - else: - if len(wrapped) > 0: - result += wrapped + '\n\n' - wrapper.initial_indent = wrapper.subsequent_indent = '' - return result.rstrip().lstrip('\n') - - -def extract(filename, node, prefix): - if not (node.location.file is None or - os.path.samefile(d(node.location.file.name), filename)): - return 0 - if node.kind in RECURSE_LIST: - sub_prefix = prefix - if node.kind != CursorKind.TRANSLATION_UNIT: - if len(sub_prefix) > 0: - sub_prefix += '_' - sub_prefix += d(node.spelling) - for i in node.get_children(): - extract(filename, i, sub_prefix) - if node.kind in PRINT_LIST: - comment = d(node.raw_comment) if node.raw_comment is not None else '' - comment = process_comment(comment) - sub_prefix = prefix - if len(sub_prefix) > 0: - sub_prefix += '_' - if len(node.spelling) > 0: - name = sanitize_name(sub_prefix + d(node.spelling)) - global output - output.append((name, filename, comment)) - - -class ExtractionThread(Thread): - def __init__(self, filename, parameters): - Thread.__init__(self) - self.filename = filename - self.parameters = parameters - job_semaphore.acquire() - - def run(self): - print('Processing "%s" ..' % self.filename, file=sys.stderr) - try: - index = cindex.Index( - cindex.conf.lib.clang_createIndex(False, True)) - tu = index.parse(self.filename, self.parameters) - extract(self.filename, tu.cursor, '') - finally: - job_semaphore.release() - -if __name__ == '__main__': - parameters = ['-x', 'c++', '-std=c++11'] - filenames = [] - - if platform.system() == 'Darwin': - dev_path = '/Applications/Xcode.app/Contents/Developer/' - lib_dir = dev_path + 'Toolchains/XcodeDefault.xctoolchain/usr/lib/' - sdk_dir = dev_path + 'Platforms/MacOSX.platform/Developer/SDKs' - libclang = lib_dir + 'libclang.dylib' - - if os.path.exists(libclang): - cindex.Config.set_library_path(os.path.dirname(libclang)) - - if os.path.exists(sdk_dir): - sysroot_dir = os.path.join(sdk_dir, next(os.walk(sdk_dir))[1][0]) - parameters.append('-isysroot') - parameters.append(sysroot_dir) - - for item in sys.argv[1:]: - if item.startswith('-'): - parameters.append(item) - else: - filenames.append(item) - - if len(filenames) == 0: - print('Syntax: %s [.. a list of header files ..]' % sys.argv[0]) - exit(-1) - - print('''/* - This file contains docstrings for the Python bindings. - Do not edit! These were automatically extracted by mkdoc.py - */ - -#define __EXPAND(x) x -#define __COUNT(_1, _2, _3, _4, _5, _6, _7, COUNT, ...) COUNT -#define __VA_SIZE(...) __EXPAND(__COUNT(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1)) -#define __CAT1(a, b) a ## b -#define __CAT2(a, b) __CAT1(a, b) -#define __DOC1(n1) __doc_##n1 -#define __DOC2(n1, n2) __doc_##n1##_##n2 -#define __DOC3(n1, n2, n3) __doc_##n1##_##n2##_##n3 -#define __DOC4(n1, n2, n3, n4) __doc_##n1##_##n2##_##n3##_##n4 -#define __DOC5(n1, n2, n3, n4, n5) __doc_##n1##_##n2##_##n3##_##n4##_##n5 -#define __DOC6(n1, n2, n3, n4, n5, n6) __doc_##n1##_##n2##_##n3##_##n4##_##n5##_##n6 -#define __DOC7(n1, n2, n3, n4, n5, n6, n7) __doc_##n1##_##n2##_##n3##_##n4##_##n5##_##n6##_##n7 -#define DOC(...) __EXPAND(__EXPAND(__CAT2(__DOC, __VA_SIZE(__VA_ARGS__)))(__VA_ARGS__)) - -#if defined(__GNUG__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-variable" -#endif -''') - - output.clear() - for filename in filenames: - thr = ExtractionThread(filename, parameters) - thr.start() - - print('Waiting for jobs to finish ..', file=sys.stderr) - for i in range(job_count): - job_semaphore.acquire() - - name_ctr = 1 - name_prev = None - for name, _, comment in list(sorted(output, key=lambda x: (x[0], x[1]))): - if name == name_prev: - name_ctr += 1 - name = name + "_%i" % name_ctr - else: - name_prev = name - name_ctr = 1 - print('\nstatic const char *%s =%sR"doc(%s)doc";' % - (name, '\n' if '\n' in comment else ' ', comment)) - - print(''' -#if defined(__GNUG__) -#pragma GCC diagnostic pop -#endif -''') diff --git a/VFRendering/thirdparty/pybind11/tools/pybind11Config.cmake.in b/VFRendering/thirdparty/pybind11/tools/pybind11Config.cmake.in deleted file mode 100644 index 3dd1b2c1a..000000000 --- a/VFRendering/thirdparty/pybind11/tools/pybind11Config.cmake.in +++ /dev/null @@ -1,100 +0,0 @@ -# pybind11Config.cmake -# -------------------- -# -# PYBIND11 cmake module. -# This module sets the following variables in your project:: -# -# pybind11_FOUND - true if pybind11 and all required components found on the system -# pybind11_VERSION - pybind11 version in format Major.Minor.Release -# pybind11_INCLUDE_DIRS - Directories where pybind11 and python headers are located. -# pybind11_INCLUDE_DIR - Directory where pybind11 headers are located. -# pybind11_DEFINITIONS - Definitions necessary to use pybind11, namely USING_pybind11. -# pybind11_LIBRARIES - compile flags and python libraries (as needed) to link against. -# pybind11_LIBRARY - empty. -# CMAKE_MODULE_PATH - appends location of accompanying FindPythonLibsNew.cmake and -# pybind11Tools.cmake modules. -# -# -# Available components: None -# -# -# Exported targets:: -# -# If pybind11 is found, this module defines the following :prop_tgt:`IMPORTED` -# interface library targets:: -# -# pybind11::module - for extension modules -# pybind11::embed - for embedding the Python interpreter -# -# Python headers, libraries (as needed by platform), and the C++ standard -# are attached to the target. Set PythonLibsNew variables to influence -# python detection and PYBIND11_CPP_STANDARD (-std=c++11 or -std=c++14) to -# influence standard setting. :: -# -# find_package(pybind11 CONFIG REQUIRED) -# message(STATUS "Found pybind11 v${pybind11_VERSION}: ${pybind11_INCLUDE_DIRS}") -# -# # Create an extension module -# add_library(mylib MODULE main.cpp) -# target_link_libraries(mylib pybind11::module) -# -# # Or embed the Python interpreter into an executable -# add_executable(myexe main.cpp) -# target_link_libraries(myexe pybind11::embed) -# -# Suggested usage:: -# -# find_package with version info is not recommended except for release versions. :: -# -# find_package(pybind11 CONFIG) -# find_package(pybind11 2.0 EXACT CONFIG REQUIRED) -# -# -# The following variables can be set to guide the search for this package:: -# -# pybind11_DIR - CMake variable, set to directory containing this Config file -# CMAKE_PREFIX_PATH - CMake variable, set to root directory of this package -# PATH - environment variable, set to bin directory of this package -# CMAKE_DISABLE_FIND_PACKAGE_pybind11 - CMake variable, disables -# find_package(pybind11) when not REQUIRED, perhaps to force internal build - -@PACKAGE_INIT@ - -set(PN pybind11) - -# location of pybind11/pybind11.h -set(${PN}_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_INCLUDEDIR@") - -set(${PN}_LIBRARY "") -set(${PN}_DEFINITIONS USING_${PN}) - -check_required_components(${PN}) - -# make detectable the FindPythonLibsNew.cmake module -list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}) - -include(pybind11Tools) - -if(NOT (CMAKE_VERSION VERSION_LESS 3.0)) -#----------------------------------------------------------------------------- -# Don't include targets if this file is being picked up by another -# project which has already built this as a subproject -#----------------------------------------------------------------------------- -if(NOT TARGET ${PN}::pybind11) - include("${CMAKE_CURRENT_LIST_DIR}/${PN}Targets.cmake") - - find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} MODULE REQUIRED) - set_property(TARGET ${PN}::pybind11 APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${PYTHON_INCLUDE_DIRS}) - set_property(TARGET ${PN}::embed APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${PYTHON_LIBRARIES}) - if(WIN32 OR CYGWIN) - set_property(TARGET ${PN}::module APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${PYTHON_LIBRARIES}) - endif() - - set_property(TARGET ${PN}::pybind11 APPEND PROPERTY INTERFACE_COMPILE_OPTIONS "${PYBIND11_CPP_STANDARD}") - - get_property(_iid TARGET ${PN}::pybind11 PROPERTY INTERFACE_INCLUDE_DIRECTORIES) - get_property(_ill TARGET ${PN}::module PROPERTY INTERFACE_LINK_LIBRARIES) - set(${PN}_INCLUDE_DIRS ${_iid}) - set(${PN}_LIBRARIES ${_ico} ${_ill}) -endif() -endif() diff --git a/VFRendering/thirdparty/pybind11/tools/pybind11Tools.cmake b/VFRendering/thirdparty/pybind11/tools/pybind11Tools.cmake deleted file mode 100644 index a7c471a07..000000000 --- a/VFRendering/thirdparty/pybind11/tools/pybind11Tools.cmake +++ /dev/null @@ -1,202 +0,0 @@ -# tools/pybind11Tools.cmake -- Build system for the pybind11 modules -# -# Copyright (c) 2015 Wenzel Jakob -# -# All rights reserved. Use of this source code is governed by a -# BSD-style license that can be found in the LICENSE file. - -cmake_minimum_required(VERSION 2.8.12) - -# Add a CMake parameter for choosing a desired Python version -if(NOT PYBIND11_PYTHON_VERSION) - set(PYBIND11_PYTHON_VERSION "" CACHE STRING "Python version to use for compiling modules") -endif() - -set(Python_ADDITIONAL_VERSIONS 3.7 3.6 3.5 3.4) -find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} REQUIRED) - -include(CheckCXXCompilerFlag) -include(CMakeParseArguments) - -if(NOT PYBIND11_CPP_STANDARD AND NOT CMAKE_CXX_STANDARD) - if(NOT MSVC) - check_cxx_compiler_flag("-std=c++14" HAS_CPP14_FLAG) - - if (HAS_CPP14_FLAG) - set(PYBIND11_CPP_STANDARD -std=c++14) - else() - check_cxx_compiler_flag("-std=c++11" HAS_CPP11_FLAG) - if (HAS_CPP11_FLAG) - set(PYBIND11_CPP_STANDARD -std=c++11) - else() - message(FATAL_ERROR "Unsupported compiler -- pybind11 requires C++11 support!") - endif() - endif() - elseif(MSVC) - set(PYBIND11_CPP_STANDARD /std:c++14) - endif() - - set(PYBIND11_CPP_STANDARD ${PYBIND11_CPP_STANDARD} CACHE STRING - "C++ standard flag, e.g. -std=c++11, -std=c++14, /std:c++14. Defaults to C++14 mode." FORCE) -endif() - -# Checks whether the given CXX/linker flags can compile and link a cxx file. cxxflags and -# linkerflags are lists of flags to use. The result variable is a unique variable name for each set -# of flags: the compilation result will be cached base on the result variable. If the flags work, -# sets them in cxxflags_out/linkerflags_out internal cache variables (in addition to ${result}). -function(_pybind11_return_if_cxx_and_linker_flags_work result cxxflags linkerflags cxxflags_out linkerflags_out) - set(CMAKE_REQUIRED_LIBRARIES ${linkerflags}) - check_cxx_compiler_flag("${cxxflags}" ${result}) - if (${result}) - set(${cxxflags_out} "${cxxflags}" CACHE INTERNAL "" FORCE) - set(${linkerflags_out} "${linkerflags}" CACHE INTERNAL "" FORCE) - endif() -endfunction() - -# Internal: find the appropriate link time optimization flags for this compiler -function(_pybind11_add_lto_flags target_name prefer_thin_lto) - if (NOT DEFINED PYBIND11_LTO_CXX_FLAGS) - set(PYBIND11_LTO_CXX_FLAGS "" CACHE INTERNAL "") - set(PYBIND11_LTO_LINKER_FLAGS "" CACHE INTERNAL "") - - if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") - set(cxx_append "") - set(linker_append "") - if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT APPLE) - # Clang Gold plugin does not support -Os; append -O3 to MinSizeRel builds to override it - set(linker_append ";$<$:-O3>") - elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU") - set(cxx_append ";-fno-fat-lto-objects") - endif() - - if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND prefer_thin_lto) - _pybind11_return_if_cxx_and_linker_flags_work(HAS_FLTO_THIN - "-flto=thin${cxx_append}" "-flto=thin${linker_append}" - PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS) - endif() - - if (NOT HAS_FLTO_THIN) - _pybind11_return_if_cxx_and_linker_flags_work(HAS_FLTO - "-flto${cxx_append}" "-flto${linker_append}" - PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS) - endif() - elseif (CMAKE_CXX_COMPILER_ID MATCHES "Intel") - # Intel equivalent to LTO is called IPO - _pybind11_return_if_cxx_and_linker_flags_work(HAS_INTEL_IPO - "-ipo" "-ipo" PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS) - elseif(MSVC) - # cmake only interprets libraries as linker flags when they start with a - (otherwise it - # converts /LTCG to \LTCG as if it was a Windows path). Luckily MSVC supports passing flags - # with - instead of /, even if it is a bit non-standard: - _pybind11_return_if_cxx_and_linker_flags_work(HAS_MSVC_GL_LTCG - "/GL" "-LTCG" PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS) - endif() - - if (PYBIND11_LTO_CXX_FLAGS) - message(STATUS "LTO enabled") - else() - message(STATUS "LTO disabled (not supported by the compiler and/or linker)") - endif() - endif() - - # Enable LTO flags if found, except for Debug builds - if (PYBIND11_LTO_CXX_FLAGS) - target_compile_options(${target_name} PRIVATE "$<$>:${PYBIND11_LTO_CXX_FLAGS}>") - endif() - if (PYBIND11_LTO_LINKER_FLAGS) - target_link_libraries(${target_name} PRIVATE "$<$>:${PYBIND11_LTO_LINKER_FLAGS}>") - endif() -endfunction() - -# Build a Python extension module: -# pybind11_add_module( [MODULE | SHARED] [EXCLUDE_FROM_ALL] -# [NO_EXTRAS] [THIN_LTO] source1 [source2 ...]) -# -function(pybind11_add_module target_name) - set(options MODULE SHARED EXCLUDE_FROM_ALL NO_EXTRAS THIN_LTO) - cmake_parse_arguments(ARG "${options}" "" "" ${ARGN}) - - if(ARG_MODULE AND ARG_SHARED) - message(FATAL_ERROR "Can't be both MODULE and SHARED") - elseif(ARG_SHARED) - set(lib_type SHARED) - else() - set(lib_type MODULE) - endif() - - if(ARG_EXCLUDE_FROM_ALL) - set(exclude_from_all EXCLUDE_FROM_ALL) - endif() - - add_library(${target_name} ${lib_type} ${exclude_from_all} ${ARG_UNPARSED_ARGUMENTS}) - - target_include_directories(${target_name} - PRIVATE ${PYBIND11_INCLUDE_DIR} # from project CMakeLists.txt - PRIVATE ${pybind11_INCLUDE_DIR} # from pybind11Config - PRIVATE ${PYTHON_INCLUDE_DIRS}) - - # The prefix and extension are provided by FindPythonLibsNew.cmake - set_target_properties(${target_name} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}") - set_target_properties(${target_name} PROPERTIES SUFFIX "${PYTHON_MODULE_EXTENSION}") - - # -fvisibility=hidden is required to allow multiple modules compiled against - # different pybind versions to work properly, and for some features (e.g. - # py::module_local). We force it on everything inside the `pybind11` - # namespace; also turning it on for a pybind module compilation here avoids - # potential warnings or issues from having mixed hidden/non-hidden types. - set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET "hidden") - - if(WIN32 OR CYGWIN) - # Link against the Python shared library on Windows - target_link_libraries(${target_name} PRIVATE ${PYTHON_LIBRARIES}) - elseif(APPLE) - # It's quite common to have multiple copies of the same Python version - # installed on one's system. E.g.: one copy from the OS and another copy - # that's statically linked into an application like Blender or Maya. - # If we link our plugin library against the OS Python here and import it - # into Blender or Maya later on, this will cause segfaults when multiple - # conflicting Python instances are active at the same time (even when they - # are of the same version). - - # Windows is not affected by this issue since it handles DLL imports - # differently. The solution for Linux and Mac OS is simple: we just don't - # link against the Python library. The resulting shared library will have - # missing symbols, but that's perfectly fine -- they will be resolved at - # import time. - - target_link_libraries(${target_name} PRIVATE "-undefined dynamic_lookup") - - if(ARG_SHARED) - # Suppress CMake >= 3.0 warning for shared libraries - set_target_properties(${target_name} PROPERTIES MACOSX_RPATH ON) - endif() - endif() - - # Make sure C++11/14 are enabled - target_compile_options(${target_name} PUBLIC ${PYBIND11_CPP_STANDARD}) - - if(ARG_NO_EXTRAS) - return() - endif() - - _pybind11_add_lto_flags(${target_name} ${ARG_THIN_LTO}) - - if (NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug) - # Strip unnecessary sections of the binary on Linux/Mac OS - if(CMAKE_STRIP) - if(APPLE) - add_custom_command(TARGET ${target_name} POST_BUILD - COMMAND ${CMAKE_STRIP} -x $) - else() - add_custom_command(TARGET ${target_name} POST_BUILD - COMMAND ${CMAKE_STRIP} $) - endif() - endif() - endif() - - if(MSVC) - # /MP enables multithreaded builds (relevant when there are many files), /bigobj is - # needed for bigger binding projects due to the limit to 64k addressable sections - target_compile_options(${target_name} PRIVATE /MP /bigobj) - endif() -endfunction() diff --git a/VFRendering/webdemo.cxx b/VFRendering/webdemo.cxx new file mode 100755 index 000000000..deba036df --- /dev/null +++ b/VFRendering/webdemo.cxx @@ -0,0 +1,96 @@ +#include +#include +#include + +#include "VFRendering/View.hxx" +#include "VFRendering/DotRenderer.hxx" +#include "VFRendering/ArrowRenderer.hxx" +#include "VFRendering/SphereRenderer.hxx" +#include "VFRendering/VectorSphereRenderer.hxx" +#include "VFRendering/CoordinateSystemRenderer.hxx" +#include "VFRendering/BoundingBoxRenderer.hxx" +#include "VFRendering/CombinedRenderer.hxx" +#include "VFRendering/IsosurfaceRenderer.hxx" + +static bool needs_redraw = false; +VFRendering::View view; + + +void framebufferSizeCallback(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context, int width, int height) { + (void)context; + view.setFramebufferSize(width, height); + needs_redraw = true; +} + +extern "C" void display() { + EmscriptenWebGLContextAttributes attrs; + emscripten_webgl_init_context_attributes(&attrs); + attrs.majorVersion=1; + attrs.minorVersion=0; + + EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = emscripten_webgl_create_context("#myCanvas", &attrs); + emscripten_webgl_make_context_current(context); + std::cout << "OpenGL Version: " << glGetString(GL_VERSION) << std::endl; + int width, height; + emscripten_webgl_get_drawing_buffer_size(context, &width, &height); + framebufferSizeCallback(context, width, height); + + std::vector positions; + std::vector directions; + for (int z = -20; z <= 20; z+=2) { + for (int y = -20; y <= 20; y+=2) { + for (int x = -20; x <= 20; x+=2) { + positions.push_back({x, y, z}); + directions.push_back(glm::vec3{x, y, z} / glm::length(positions.back())); + } + } + } + VFRendering::Geometry geometry = VFRendering::Geometry::cartesianGeometry({21, 21, 21}, {-20, -20, -20}, {20, 20, 20}); + VFRendering::VectorField vf = VFRendering::VectorField(geometry, directions); + + + VFRendering::Options options; + options.set((geometry.min() + geometry.max()) * 0.5f); + options.set(VFRendering::Utilities::getColormapImplementation(VFRendering::Utilities::Colormap::HSV)); + options.set({-40, 40, 80}); + options.set({0, 0, 0}); + options.set({0, 1, 0}); + view.updateOptions(options); + + auto isosurface_renderer_ptr = std::make_shared(view, vf); + isosurface_renderer_ptr->setOption([] (const glm::vec3& position, const glm::vec3& direction) -> VFRendering::IsosurfaceRenderer::isovalue_type { + (void)direction; + return position.z * position.z + position.y * position.y + position.x * position.x - 19*19; + }); + isosurface_renderer_ptr->setOption(0.0); + auto yzplane_renderer_ptr = std::make_shared(view, vf); + yzplane_renderer_ptr->setOption([] (const glm::vec3& position, const glm::vec3& direction) -> VFRendering::IsosurfaceRenderer::isovalue_type { + (void)direction; + return position.x; + }); + yzplane_renderer_ptr->setOption(0.0); + auto arrow_renderer_ptr = std::make_shared(view, vf); + auto dot_renderer_ptr = std::make_shared(view, vf); + auto sphere_renderer_ptr = std::make_shared(view, vf); + auto bounding_box_renderer_ptr = std::make_shared(VFRendering::BoundingBoxRenderer::forCuboid(view, (geometry.min()+geometry.max())*0.5f, geometry.max()-geometry.min(), (geometry.max()-geometry.min())*0.2f, 0.5f)); + auto coordinate_system_renderer_ptr = std::make_shared(view); + coordinate_system_renderer_ptr->setOption({0, 20, 20}); + coordinate_system_renderer_ptr->setOption(false); + + std::vector> renderers = { + isosurface_renderer_ptr, + yzplane_renderer_ptr, + arrow_renderer_ptr, + sphere_renderer_ptr, + dot_renderer_ptr, + bounding_box_renderer_ptr, + coordinate_system_renderer_ptr + }; + view.renderers({{std::make_shared(view, renderers), {{0, 0, 1, 1}}}}); + view.setOption("bool is_visible(vec3 position, vec3 direction) { return position.x >= 0.0; }"); + arrow_renderer_ptr->setOption("bool is_visible(vec3 position, vec3 direction) { return position.x <= 0.0; }"); + sphere_renderer_ptr->setOption("bool is_visible(vec3 position, vec3 direction) { return position.x <= 0.0; }"); + isosurface_renderer_ptr->setOption("float lighting(vec3 position, vec3 normal) { return -normal.z; }"); + + view.draw(); +} \ No newline at end of file diff --git a/VFRendering/webdemo.html b/VFRendering/webdemo.html new file mode 100755 index 000000000..8096ddc0b --- /dev/null +++ b/VFRendering/webdemo.html @@ -0,0 +1,17 @@ + + + +VFRendering Web Demo + + + + + + + diff --git a/clean.sh b/clean.sh index 5b39a629b..27be7d8ff 100755 --- a/clean.sh +++ b/clean.sh @@ -4,4 +4,4 @@ rm -rf Release find . -maxdepth 1 -wholename ./spirit* -delete find ./core/python/spirit -mindepth 1 -name *Spirit* -delete find ./core/julia/Spirit -mindepth 1 -name *Spirit* -delete -find ./ui-web -mindepth 1 -name spirit.js* -delete +find ./ui-web/js -mindepth 1 -name libSpirit.* -delete diff --git a/core/thirdparty/ovf/thirdparty/PEGTL/include/tao/pegtl/file_input.hpp b/core/thirdparty/ovf/thirdparty/PEGTL/include/tao/pegtl/file_input.hpp index 1959a095a..e96c873e3 100644 --- a/core/thirdparty/ovf/thirdparty/PEGTL/include/tao/pegtl/file_input.hpp +++ b/core/thirdparty/ovf/thirdparty/PEGTL/include/tao/pegtl/file_input.hpp @@ -8,7 +8,7 @@ #include "eol.hpp" #include "tracking_mode.hpp" -#if defined( __unix__ ) || ( defined( __APPLE__ ) && defined( __MACH__ ) ) +#if !defined(EMSCRIPTEN) && (defined( __unix__ ) || ( defined( __APPLE__ ) && defined( __MACH__ ) )) #include // Required for _POSIX_MAPPED_FILES #endif diff --git a/ui-web/CMakeLists.txt b/ui-web/CMakeLists.txt index 7df8ad5a5..7765fc7e4 100644 --- a/ui-web/CMakeLists.txt +++ b/ui-web/CMakeLists.txt @@ -40,71 +40,340 @@ set(SOURCE_UI_WEB_ROOT) ############################################# -######## Set export functions for Web UI ############################# +######## Set export functions for Spirit ############################# ### Place all functions which should be exported by emcc into this list set( INTERFACE_EXPORT_FUNCTIONS - '_Spirit_Version' '_Spirit_Version_Revision' '_Spirit_Version_Full' - # State - '_State_Setup' - # System - '_System_Get_Index' '_System_Get_NOS' '_System_Get_Spin_Directions' # Chain - '_Chain_Get_Index' '_Chain_Get_NOI' - '_Chain_next_Image' '_Chain_prev_Image' - '_Chain_Image_to_Clipboard' '_Chain_Insert_Image_Before' '_Chain_Insert_Image_After' '_Chain_Replace_Image' '_Chain_Delete_Image' - '_Chain_Update_Data' '_Chain_Setup_Data' - # Collection - '_Collection_Get_NOC' - '_Collection_next_Chain' '_Collection_prev_Chain' + '_Chain_Get_NOI' + '_Chain_next_Image' + '_Chain_prev_Image' + '_Chain_Jump_To_Image' + '_Chain_Set_Length' + '_Chain_Image_to_Clipboard' + '_Chain_Replace_Image' + '_Chain_Insert_Image_Before' + '_Chain_Insert_Image_After' + '_Chain_Push_Back' + '_Chain_Delete_Image' + '_Chain_Pop_Back' + '_Chain_Get_Rx' + '_Chain_Get_Rx_Interpolated' + '_Chain_Get_Energy' + '_Chain_Get_Energy_Interpolated' + '_Chain_Update_Data' + '_Chain_Setup_Data' + # Configuration + '_Configuration_To_Clipboard' + '_Configuration_From_Clipboard' + '_Configuration_From_Clipboard_Shift' + '_Configuration_Domain' + '_Configuration_PlusZ' + '_Configuration_MinusZ' + '_Configuration_Random' + '_Configuration_SpinSpiral' + '_Configuration_SpinSpiral_2q' + '_Configuration_Add_Noise_Temperature' + '_Configuration_Displace_Eigenmode' + '_Configuration_Skyrmion' + '_Configuration_Hopfion' + '_Configuration_Set_Pinned' + '_Configuration_Set_Atom_Type' + # Constants + '_Constants_mu_B' + '_Constants_mu_0' + '_Constants_k_B' + '_Constants_hbar' + '_Constants_mRy' + '_Constants_gamma' + '_Constants_g_e' + '_Constants_Pi' # Geometry + '_Geometry_Set_Bravais_Lattice_Type' + '_Geometry_Set_N_Cells' + '_Geometry_Set_Cell_Atoms' + '_Geometry_Set_mu_s' + '_Geometry_Set_Cell_Atom_Types' + '_Geometry_Set_Bravais_Vectors' + '_Geometry_Set_Lattice_Constant' + '_Geometry_Get_NOS' '_Geometry_Get_Positions' - '_Geometry_Set_mu_s' '_Geometry_Get_mu_s' - '_Geometry_Get_Bounds' '_Geometry_Get_Center' - '_Geometry_Get_Basis_Vectors' '_Geometry_Get_N_Cells' '_Geometry_Get_Translation_Vectors' '_Geometry_Get_Dimensionality' + '_Geometry_Get_Atom_Types' + '_Geometry_Get_Bounds' + '_Geometry_Get_Center' + '_Geometry_Get_Bravais_Lattice_Type' + '_Geometry_Get_Bravais_Vectors' + '_Geometry_Get_Dimensionality' + '_Geometry_Get_mu_s' + '_Geometry_Get_N_Cells' + '_Geometry_Get_Cell_Bounds' + '_Geometry_Get_N_Cell_Atoms' + '_Geometry_Get_Cell_Atoms' + '_Geometry_Get_Triangulation' + '_Geometry_Get_Tetrahedra' # Hamiltonian - '_Hamiltonian_Set_Boundary_Conditions' '_Hamiltonian_Set_Field' '_Hamiltonian_Set_Exchange' '_Hamiltonian_Set_DMI' '_Hamiltonian_Set_Anisotropy' '_Hamiltonian_Set_DDI' - '_Hamiltonian_Get_Boundary_Conditions' '_Hamiltonian_Get_Field' '_Hamiltonian_Get_Exchange' '_Hamiltonian_Get_DMI' '_Hamiltonian_Get_Anisotropy' - # Parameters LLG - '_Parameters_LLG_Set_Time_Step' '_Parameters_LLG_Set_Damping' - '_Parameters_LLG_Set_STT' '_Parameters_LLG_Set_Temperature' + '_Hamiltonian_Set_Boundary_Conditions' + '_Hamiltonian_Set_Field' + '_Hamiltonian_Set_Anisotropy' + '_Hamiltonian_Set_Exchange' + '_Hamiltonian_Set_DMI' + '_Hamiltonian_Set_DDI' + '_Hamiltonian_Get_Name' + '_Hamiltonian_Get_Boundary_Conditions' + '_Hamiltonian_Get_Field' + '_Hamiltonian_Get_Anisotropy' + '_Hamiltonian_Get_Exchange_Shells' + '_Hamiltonian_Get_Exchange_N_Pairs' + '_Hamiltonian_Get_Exchange_Pairs' + '_Hamiltonian_Get_DMI_Shells' + '_Hamiltonian_Get_DMI_N_Pairs' + '_Hamiltonian_Get_DDI' + # IO + '_IO_System_From_Config' + '_IO_Positions_Write' + '_IO_N_Images_In_File' + '_IO_Image_Read' + '_IO_Image_Write' + '_IO_Image_Append' + '_IO_Chain_Read' + '_IO_Chain_Write' + '_IO_Chain_Append' + '_IO_Image_Write_Neighbours_Exchange' + '_IO_Image_Write_Neighbours_DMI' + '_IO_Image_Write_Energy_per_Spin' + '_IO_Image_Write_Energy' + '_IO_Chain_Write_Energies' + '_IO_Chain_Write_Energies_Interpolated' + '_IO_Eigenmodes_Read' + '_IO_Eigenmodes_Write' + # Log + '_Log_Send' + '_Log_Append' + '_Log_Dump' + '_Log_Get_N_Entries' + '_Log_Get_N_Errors' + '_Log_Get_N_Warnings' + '_Log_Set_Output_File_Tag' + '_Log_Set_Output_Folder' + '_Log_Set_Output_To_Console' + '_Log_Set_Output_To_File' + '_Log_Get_Output_File_Tag' + '_Log_Get_Output_Folder' + '_Log_Get_Output_To_Console' + '_Log_Get_Output_Console_Level' + '_Log_Get_Output_To_File' + '_Log_Get_Output_File_Level' + # Parameters (EMA) + '_Parameters_EMA_Set_N_Modes' + '_Parameters_EMA_Set_N_Mode_Follow' + '_Parameters_EMA_Set_Frequency' + '_Parameters_EMA_Set_Amplitude' + '_Parameters_EMA_Set_Snapshot' + '_Parameters_EMA_Get_N_Modes' + '_Parameters_EMA_Get_N_Mode_Follow' + '_Parameters_EMA_Get_Frequency' + '_Parameters_EMA_Get_Amplitude' + '_Parameters_EMA_Get_Snapshot' + '_Parameters_GNEB_Set_Output_Tag' + '_Parameters_GNEB_Set_Output_Folder' + '_Parameters_GNEB_Set_Output_General' + '_Parameters_GNEB_Set_Output_Energies' + '_Parameters_GNEB_Set_Output_Chain' + '_Parameters_GNEB_Set_N_Iterations' + '_Parameters_GNEB_Set_Convergence' + '_Parameters_GNEB_Set_Spring_Constant' + '_Parameters_GNEB_Set_Spring_Force_Ratio' + '_Parameters_GNEB_Set_Path_Shortening_Constant' + '_Parameters_GNEB_Set_Climbing_Falling' + '_Parameters_GNEB_Set_Image_Type_Automatically' + '_Parameters_GNEB_Set_N_Energy_Interpolations' + '_Parameters_GNEB_Get_Output_Tag' + '_Parameters_GNEB_Get_Output_Folder' + '_Parameters_GNEB_Get_Output_General' + '_Parameters_GNEB_Get_Output_Energies' + '_Parameters_GNEB_Get_Output_Chain' + '_Parameters_GNEB_Get_N_Iterations' + '_Parameters_GNEB_Get_Convergence' + '_Parameters_GNEB_Get_Spring_Constant' + '_Parameters_GNEB_Get_Spring_Force_Ratio' + '_Parameters_GNEB_Get_Path_Shortening_Constant' + '_Parameters_GNEB_Get_Climbing_Falling' + '_Parameters_GNEB_Get_N_Energy_Interpolations' + # Parameters (LLG) + '_Parameters_LLG_Set_Output_Tag' + '_Parameters_LLG_Set_Output_Folder' + '_Parameters_LLG_Set_Output_General' + '_Parameters_LLG_Set_Output_Energy' + '_Parameters_LLG_Set_Output_Configuration' + '_Parameters_LLG_Set_N_Iterations' + '_Parameters_LLG_Set_Direct_Minimization' '_Parameters_LLG_Set_Convergence' - '_Parameters_LLG_Get_Time_Step' '_Parameters_LLG_Get_Damping' - '_Parameters_LLG_Get_STT' '_Parameters_LLG_Get_Temperature' - # Parameters GNEB - '_Parameters_Set_GNEB_Spring_Constant' '_Parameters_Set_GNEB_Climbing_Falling' - '_Parameters_Get_GNEB_Spring_Constant' '_Parameters_Get_GNEB_Climbing_Falling' '_Parameters_Get_GNEB_N_Energy_Interpolations' - # Configurations - '_Configuration_Domain' '_Configuration_PlusZ' '_Configuration_MinusZ' - '_Configuration_Random' '_Configuration_Add_Noise_Temperature' '_Configuration_Skyrmion' '_Configuration_SpinSpiral' - # Transitions - '_Transition_Homogeneous' '_Transition_Add_Noise_Temperature' + '_Parameters_LLG_Set_Time_Step' + '_Parameters_LLG_Set_Damping' + '_Parameters_LLG_Set_STT' + '_Parameters_LLG_Set_Temperature' + '_Parameters_LLG_Set_Temperature_Gradient' + '_Parameters_LLG_Get_Output_Tag' + '_Parameters_LLG_Get_Output_Folder' + '_Parameters_LLG_Get_Output_General' + '_Parameters_LLG_Get_Output_Energy' + '_Parameters_LLG_Get_Output_Configuration' + '_Parameters_LLG_Get_N_Iterations' + '_Parameters_LLG_Get_Direct_Minimization' + '_Parameters_LLG_Get_Convergence' + '_Parameters_LLG_Get_Time_Step' + '_Parameters_LLG_Get_Damping' + '_Parameters_LLG_Get_Temperature' + '_Parameters_LLG_Get_Temperature_Gradient' + '_Parameters_LLG_Get_STT' + # Parameters (MC) + '_Parameters_MC_Set_Output_Tag' + '_Parameters_MC_Set_Output_Folder' + '_Parameters_MC_Set_Output_General' + '_Parameters_MC_Set_Output_Energy' + '_Parameters_MC_Set_Output_Configuration' + '_Parameters_MC_Set_N_Iterations' + '_Parameters_MC_Set_Temperature' + '_Parameters_MC_Set_Metropolis_Cone' + '_Parameters_MC_Set_Random_Sample' + '_Parameters_MC_Get_Output_Tag' + '_Parameters_MC_Get_Output_Folder' + '_Parameters_MC_Get_Output_General' + '_Parameters_MC_Get_Output_Energy' + '_Parameters_MC_Get_Output_Configuration' + '_Parameters_MC_Get_N_Iterations' + '_Parameters_MC_Get_Temperature' + '_Parameters_MC_Get_Metropolis_Cone' + '_Parameters_MC_Get_Random_Sample' + # Parameters (MMF) + '_Parameters_MMF_Set_Output_Tag' + '_Parameters_MMF_Set_Output_Folder' + '_Parameters_MMF_Set_Output_General' + '_Parameters_MMF_Set_Output_Energy' + '_Parameters_MMF_Set_Output_Configuration' + '_Parameters_MMF_Set_N_Iterations' + '_Parameters_MMF_Set_N_Modes' + '_Parameters_MMF_Set_N_Mode_Follow' + '_Parameters_MMF_Get_Output_Tag' + '_Parameters_MMF_Get_Output_Folder' + '_Parameters_MMF_Get_Output_General' + '_Parameters_MMF_Get_Output_Energy' + '_Parameters_MMF_Get_Output_Configuration' + '_Parameters_MMF_Get_N_Iterations' + '_Parameters_MMF_Get_N_Modes' + '_Parameters_MMF_Get_N_Mode_Follow' + # Quantity + '_Quantity_Get_Magnetization' + '_Quantity_Get_Topological_Charge' # Simulation - '_Simulation_MC_Start' '_Simulation_LLG_Start' '_Simulation_GNEB_Start' - '_Simulation_SingleShot' '_Simulation_Stop' '_Simulation_Stop_All' - '_Simulation_Running_Image' '_Simulation_Running_Chain' '_Simulation_Running_Collection' - '_Simulation_Running_Anywhere_Chain' '_Simulation_Running_Anywhere_Collection' - # Log - '_Log_Send' '_Log_Get_N_Entries' '_Log_Append' '_Log_Dump' - ) + '_Simulation_MC_Start' + '_Simulation_LLG_Start' + '_Simulation_GNEB_Start' + '_Simulation_MMF_Start' + '_Simulation_EMA_Start' + '_Simulation_SingleShot' + '_Simulation_Stop' + '_Simulation_Stop_All' + '_Simulation_Get_MaxTorqueComponent' + '_Simulation_Get_Chain_MaxTorqueComponents' + '_Simulation_Get_IterationsPerSecond' + '_Simulation_Get_Iteration' + '_Simulation_Get_Time' + '_Simulation_Get_Wall_Time' + '_Simulation_Get_Solver_Name' + '_Simulation_Get_Method_Name' + '_Simulation_Running_On_Image' + '_Simulation_Running_On_Chain' + '_Simulation_Running_Anywhere_On_Chain' + # Spirit + '_Spirit_Version_Major' + '_Spirit_Version_Minor' + '_Spirit_Version_Patch' + '_Spirit_Version' + '_Spirit_Version_Revision' + '_Spirit_Version_Full' + # State + '_State_Setup' + '_State_Delete' + '_State_Update' + '_State_To_Config' + '_State_DateTime' + # System + '_System_Get_Index' + '_System_Get_NOS' + '_System_Get_Spin_Directions' + '_System_Get_Effective_Field' + '_System_Get_Eigenmode' + '_System_Get_Rx' + '_System_Get_Energy' + '_System_Get_Energy_Array' + '_System_Get_Eigenvalues' + '_System_Print_Energy_Array' + '_System_Update_Data' + '_System_Update_Eigenmodes' + # Transition + '_Transition_Homogeneous' + '_Transition_Add_Noise_Temperature' +) +######## Set export functions for VFRendering ######################## +set( INTERFACE_EXPORT_FUNCTIONS ${INTERFACE_EXPORT_FUNCTIONS} + '_initialize' + '_draw' + '_mouse_move' + '_mouse_scroll' + '_set_camera' + '_align_camera' + '_recenter_camera' + '_set_colormap' + '_set_visibility' + '_set_rendermode' + '_set_miniview' + '_set_background' + '_set_boundingbox' + '_set_boundingbox_colour' + '_set_vectorsphere' + '_set_coordinate_system' + '_set_dots' + '_set_arrows' + '_set_spheres' + '_set_boxes' + '_set_surface' + '_set_isosurface' + '_update_directions' + '_update_geometry' +) ### Replace ; in the list with , while transforming into a string string( REPLACE ";" ", " INTERFACE_EXPORT_FUNCTIONS_STRING "${INTERFACE_EXPORT_FUNCTIONS}") ###################################################################### +### ################### +add_executable( webui src/wrapper.cxx ) +target_link_libraries( webui ${SPIRIT_LIBRARIES_STATIC} VFRendering ) + +# target_link_libraries( webui ${SPIRIT_LINK_DEPS} ) -### We use executable to it actually gets compiled -add_executable( spirit_js main_js.cxx ${SPIRIT_OBJS} ) +set_target_properties( webui PROPERTIES OUTPUT_NAME "libSpirit" ) -target_link_libraries( spirit_js ${SPIRIT_LINK_DEPS} ) +### We want it to be placed under ui-web/js/ s.t. it is directly part of the python core module/package +set_target_properties( webui PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/ui-web/js/ ) -set_target_properties( spirit_js PROPERTIES OUTPUT_NAME "spirit" ) +set_property( TARGET webui PROPERTY CXX_STANDARD 11 ) +set_property( TARGET webui PROPERTY CXX_STANDARD_REQUIRED ON ) +set_property( TARGET webui PROPERTY CXX_EXTENSIONS OFF ) -### We want it to be placed under ui-web/ s.t. it is directly part of the python core module/package -set( SPIRIT_JS_OUTPUT_DIR ${CMAKE_SOURCE_DIR}/ui-web/ ) -set_target_properties( spirit_js PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${SPIRIT_JS_OUTPUT_DIR} ) +target_include_directories( webui PUBLIC ${CMAKE_SOURCE_DIR}/core/include ) +# target_include_directories( webui PUBLIC ${PROJECT_SOURCE_DIR}/include ) +# target_include_directories( webui PUBLIC ${PROJECT_SOURCE_DIR}/thirdparty/glm/include ) +# target_include_directories( webui PRIVATE ${PROJECT_SOURCE_DIR}/thirdparty/glad/include ) +# target_include_directories( webui PRIVATE ${qhull_INCLUDE_DIRS} ) ### Set specific flags for emcc -set_property( TARGET spirit_js PROPERTY COMPILE_FLAGS "-O3 -s WASM=1" ) -set_property( TARGET spirit_js PROPERTY LINK_FLAGS "-O3 -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s EXPORTED_FUNCTIONS=\"[${INTERFACE_EXPORT_FUNCTIONS_STRING}]\" -s EXTRA_EXPORTED_RUNTIME_METHODS=['cwrap']" ) +set_property( TARGET webui PROPERTY COMPILE_FLAGS + "-O3 -g -s EXPORT_NAME=\"'Module_Spirit'\" -s MODULARIZE=1 -s USE_WEBGL2=0 -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1 -s ASSERTIONS=1 -s DISABLE_EXCEPTION_CATCHING=0 -s FORCE_FILESYSTEM=1" ) + +set_property( TARGET webui PROPERTY LINK_FLAGS + "-O3 -g -s EXPORT_NAME=\"'Module_Spirit'\" -s MODULARIZE=1 -s USE_WEBGL2=0 -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1 -s ASSERTIONS=1 -s DISABLE_EXCEPTION_CATCHING=0 -s FORCE_FILESYSTEM=1 -s ALLOW_MEMORY_GROWTH=1 -s EXPORTED_FUNCTIONS=\"[${INTERFACE_EXPORT_FUNCTIONS_STRING}]\" -s EXTRA_EXPORTED_RUNTIME_METHODS=['cwrap, FS']" ) + +###################################################################### ######### Header and Source messages ######## @@ -116,4 +385,4 @@ endif( ) MESSAGE( STATUS ">> --------------------- UI - Web done -------------------------------- <<" ) -MESSAGE( STATUS ">> -------------------------------------------------------------------- <<" ) \ No newline at end of file +MESSAGE( STATUS ">> -------------------------------------------------------------------- <<" ) diff --git a/ui-web/css/style.css b/ui-web/css/style.css index 634f47491..3531a084c 100644 --- a/ui-web/css/style.css +++ b/ui-web/css/style.css @@ -1,114 +1,117 @@ html, body { - height: 100%; - width: 100%; - margin: 0; - padding: 0; - overflow: hidden; + height: 100%; + width: 100%; + margin: 0; + padding: 0; + overflow: hidden; } body, body > div{ - display: flex; - flex-direction: column; + display: flex; + flex-direction: column; +} +button { + max-width: 300px; } #div-load { - display:block; - position:fixed; - top:0; - bottom:0; - left:0; - right:0; - background-color:white; - opacity:0.9; - z-index:10000; - text-align:center; - vertical-align: middle; - line-height:100vh; - font-size:2em; + display:block; + position:fixed; + top:0; + bottom:0; + left:0; + right:0; + background-color:white; + opacity:0.9; + z-index:10000; + text-align:center; + vertical-align: middle; + line-height:100vh; + font-size:2em; } #visualization-container { - background-color:#777777; - position:relative; - padding:0; + background-color:#777777; + position:relative; + padding:0; } #webgl-canvas { - position: absolute; - width:100%; - height:100%; - margin:0; + position: absolute; + width:100%; + height:100%; + margin:0; } #webgl-controls { - position: absolute; - bottom:0; - left:50%; - width:360px; - height:50px; - margin-left: -180px; - padding:0; - text-align: center; + position: absolute; + bottom:0; + left:50%; + width:360px; + height:50px; + margin-left: -180px; + padding:0; + text-align: center; } #webgl-controls > i { - position:relative; - width:50px; - height:50px; - font-size:50px; - color:#999999; - opacity:0.9; - cursor: pointer; - z-index: 1; + position:relative; + width:50px; + height:50px; + font-size:50px; + color:#999999; + opacity:0.9; + cursor: pointer; + z-index: 1; } #webgl-controls > i:hover, #webgl-controls > i:focus, #webgl-controls > i:active { - opacity:0.75; + opacity:0.75; } #webgl-controls > span.spacer-25 { - position:relative; - width:25px; - height:0; - z-index: 1; - display:inline-block; - margin:0; - padding:0; + position:relative; + width:25px; + height:0; + z-index: 1; + display:inline-block; + margin:0; + padding:0; } #webgl-extended-controls { - position: absolute; - bottom: 75px; - left: 50%; - width: 300px; - height: 100px; - margin-left: -150px; - padding: 10px; - text-align: center; - background-color:white; - background-color:rgba(255, 255, 255, 0.5); - border-radius: 3px; + position: absolute; + bottom: 75px; + left: 50%; + width: 300px; + height: 100px; + margin-left: -150px; + padding: 10px; + text-align: center; + background-color:white; + background-color:rgba(255, 255, 255, 0.5); + border-radius: 3px; } #webgl-extended-controls.hidden { - display:none; + display:none; } #webgl-extended-controls > div{ - background-color:rgba(255, 255, 255, 0.6); - color:black; - border-radius: 3px; - border:1px solid black; + background-color:rgba(255, 255, 255, 0.6); + color:black; + border-radius: 3px; + border:1px solid black; } #settings-container { - padding:0.5em; - border-left:1px solid #BBBBBB; - overflow:auto; - max-height:100vh; + padding:0.5em; + border-left:1px solid #BBBBBB; + overflow:auto; + max-height:100vh; } #settings-container .form-group { - padding-left:10px; - padding-right:10px; + padding-left:10px; + padding-right:10px; } #settings-container .form-control { - padding:6px; - text-align:center; + padding:6px; + text-align:center; } #settings-container .col-sm-1, @@ -123,103 +126,103 @@ body, body > div{ #settings-container .col-sm-10, #settings-container .col-sm-11, #settings-container .col-sm-12 { - padding-left:5px; - padding-right:5px; + padding-left:5px; + padding-right:5px; } body > div { - flex-direction: row; - flex: 1; + flex-direction: row; + flex: 1; } #input-show-settings { - display:none; + display:none; } label[for="input-show-settings"] { - position: fixed; - top:0; - right:0; - z-index: 10; - background-color: #dddddd; - border-left:1px solid #bbbbbb; - border-bottom:1px solid #bbbbbb; - border-bottom-left-radius: 1em; - padding: 1em; + position: fixed; + top:0; + right:0; + z-index: 10; + background-color: #dddddd; + border-left:1px solid #bbbbbb; + border-bottom:1px solid #bbbbbb; + border-bottom-left-radius: 1em; + padding: 1em; } #visualization-container { - display: block; - flex: 1; + display: block; + flex: 1; } #settings-container { - display: none; - flex: 0; + display: none; + flex: 0; } /*#input-show-settings:checked ~ #visualization-container { - display: block; - flex: 0.5; + display: block; + flex: 0.5; } #input-show-settings:checked ~ #settings-container { - display: block; - flex: 0.5; + display: block; + flex: 0.5; }*/ #input-show-settings:checked ~ #visualization-container { - display: block; - flex: 1; + display: block; + flex: 1; } #input-show-settings:checked ~ #settings-container { - display: block; - flex: 0 0 350px; + display: block; + flex: 0 0 350px; } @media (-webkit-min-device-pixel-ratio: 2) or (min-resolution: 192dpi) { - @media (max-width: 1520px) { - #input-show-settings:checked ~ #visualization-container { - display: none; - flex: 0; - } + @media (max-width: 760px) { + #input-show-settings:checked ~ #visualization-container { + display: none; + flex: 0; + } - #input-show-settings:checked ~ #settings-container { - display: block; - flex: 1; - } - } + #input-show-settings:checked ~ #settings-container { + display: block; + flex: 1; + } + } } @media (max-width: 760px) { - #input-show-settings:checked ~ #visualization-container { - display: none; - flex: 0; - } + #input-show-settings:checked ~ #visualization-container { + display: none; + flex: 0; + } - #input-show-settings:checked ~ #settings-container { - display: block; - flex: 1; - } + #input-show-settings:checked ~ #settings-container { + display: block; + flex: 1; + } } /* @media (min-width: 768px) { - body > div { - flex-direction: row; - flex: 1; - } - #visualization-container { - flex: 1; - } - #settings-container { - flex: 0 0 350px; - overflow-y:scroll; - } - #settings-container > * { - height:0; - } + body > div { + flex-direction: row; + flex: 1; + } + #visualization-container { + flex: 1; + } + #settings-container { + flex: 0 0 350px; + overflow-y:scroll; + } + #settings-container > * { + height:0; + } } @media (max-width: 767px) { - #visualization-container { - height:100vh; - } + #visualization-container { + height:100vh; + } } span.input-group-addon { - width:53px; + width:53px; }*/ \ No newline at end of file diff --git a/ui-web/js/simulation.js b/ui-web/js/simulation.js deleted file mode 100644 index 0c9b80ecd..000000000 --- a/ui-web/js/simulation.js +++ /dev/null @@ -1,336 +0,0 @@ -"use strict"; - -var Module = { - preRun: [], - postRun: [], - print: function (text) { - if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' '); - console.log(text); - }, - printErr: function (text) { - if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' '); - console.error(text); - }, - onRuntimeInitialized: function () { - this.isReady = true; - for (var i in this._readyCallbacks) { - this._readyCallbacks[i](); - } - }, - isReady: false, - _readyCallbacks: [], - ready: function(readyCallback) { - if (this.isReady) { - readyCallback(); - } else { - this._readyCallbacks.push(readyCallback); - } - } -}; - -Module.ready(function() { - Module.State_Setup = Module.cwrap('State_Setup', 'number', ['string']); - window.Simulation = function(finishedCallback, options) { - var defaultOptions = { - }; - this._options = {}; - this._mergeOptions(options, defaultOptions); - - // FS.writeFile("/input.cfg", "translation_vectors\n1 0 0 20\n0 1 0 20\n0 0 1 1\n"); - - // var cfgfile = "input/skyrmions_2D.cfg"; - // var cfgfile = "input/skyrmions_3D.cfg"; - // var cfgfile = "input/nanostrip_skyrmions.cfg"; - var cfgfile = ""; - this.getConfig(cfgfile, function(config) { - // FS.writeFile("/input.cfg", config); - this._state = Module.State_Setup(""); - this.showBoundingBox = true; - finishedCallback(this); - }.bind(this)); - }; - - Module.iteration = Module.cwrap('Simulation_SingleShot', null, ['number', 'number', 'number']); - Simulation.prototype.performIteration = function() { - Module.iteration(this._state); - this.update(); - }; - - Module.startsim = Module.cwrap('Simulation_LLG_Start', null, ['number', 'number', 'number', 'number', Boolean, 'number', 'number']); - Simulation.prototype.startSimulation = function() { - Module.startsim(this._state, 1, 1000000, 1000, true); - } - - Module.stopsim = Module.cwrap('Simulation_Stop', null, ['number', 'number', 'number']); - Simulation.prototype.stopSimulation = function() { - Module.stopsim(this._state); - } - - Simulation.prototype.getConfig = function(cfg_name, callback) { - if (cfg_name != "") - { - $.get( cfg_name, {}, function(res) { - // console.log(res); - callback(res); - } - ); - } - else - { - callback(" "); - } - }; - - Simulation.prototype._mergeOptions = function(options, defaultOptions) { - this._options = {}; - for (var option in defaultOptions) { - this._options[option] = defaultOptions[option]; - } - for (var option in options) { - if (defaultOptions.hasOwnProperty(option)) { - this._options[option] = options[option]; - } else { - console.warn("Spirit Simulation does not recognize option '" + option +"'."); - } - } - }; - - Module.Spirit_Version_Full = Module.cwrap('Spirit_Version_Full', 'string', []); - Simulation.prototype.spiritVersion = function() { - return Module.Spirit_Version_Full(); - }; - - Module.getSpinDirections = Module.cwrap('System_Get_Spin_Directions', 'number', ['number']); - Module.getSpinPositions = Module.cwrap('Geometry_Get_Positions', 'number', ['number']); - Simulation.prototype.update = function() { - var _n = Simulation.prototype.getNCells(this._state); - var NX = _n[0]; - var NY = _n[1]; - var NZ = _n[2]; - var N = NX*NY*NZ; - var result_ptr = Module.getSpinDirections(this._state); - var double_directions = Module.HEAPF32.subarray(result_ptr/4, result_ptr/4+N*3); - var pos_ptr = Module.getSpinPositions(this._state); - var double_positions = Module.HEAPF32.subarray(pos_ptr/4, pos_ptr/4+N*3); - var spinPositions = []; - var spinDirections = []; - for (var i = 0; i < N; i++) { - var spinPosition = [double_positions[3*i], double_positions[3*i+1], double_positions[3*i+2]]; - Array.prototype.push.apply(spinPositions, spinPosition); - var spinDirection = [double_directions[3*i], double_directions[3*i+1], double_directions[3*i+2]]; - Array.prototype.push.apply(spinDirections, spinDirection); - } - webglspins.updateSpins(spinPositions, spinDirections); - var surfaceIndices = WebGLSpins.generateCartesianSurfaceIndices(NX, NY); - var boundingBox = null; - if (this. showBoundingBox) { - boundingBox = this.getBoundingBox(); - } - webglspins.updateOptions({ - surfaceIndices: surfaceIndices, - boundingBox: boundingBox - }); - }; - - Module.Configuration_PlusZ = Module.cwrap('Configuration_PlusZ', null, ['number', 'number', 'number', 'number', 'number', 'number', 'number', 'number']); - Simulation.prototype.setAllSpinsPlusZ = function() { - var pos = new Float32Array([0,0,0]); - var pos_ptr = Module._malloc(pos.length * pos.BYTES_PER_ELEMENT); - Module.HEAPF32.set(pos, pos_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); - var border = new Float32Array([-1,-1,-1]); - var border_ptr = Module._malloc(border.length * border.BYTES_PER_ELEMENT); - Module.HEAPF32.set(border, border_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); - Module.Configuration_PlusZ(this._state, pos_ptr, border_ptr, -1, -1, 0, 0, -1, -1); - this.update(); - }; - Module.Configuration_MinusZ = Module.cwrap('Configuration_MinusZ', null, ['number', 'number', 'number', 'number', 'number', 'number', 'number', 'number']); - Simulation.prototype.setAllSpinsMinusZ = function() { - var pos = new Float32Array([0,0,0]); - var pos_ptr = Module._malloc(pos.length * pos.BYTES_PER_ELEMENT); - Module.HEAPF32.set(pos, pos_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); - var border = new Float32Array([-1,-1,-1]); - var border_ptr = Module._malloc(border.length * border.BYTES_PER_ELEMENT); - Module.HEAPF32.set(border, border_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); - Module.Configuration_MinusZ(this._state, pos_ptr, border_ptr, -1, -1, 0, 0, -1, -1); - this.update(); - }; - Module.Configuration_Random = Module.cwrap('Configuration_Random', null, ['number', 'number', 'number', 'number', 'number', 'number', 'number', 'number']); - Simulation.prototype.setAllSpinsRandom = function() { - var pos = new Float32Array([0,0,0]); - var pos_ptr = Module._malloc(pos.length * pos.BYTES_PER_ELEMENT); - Module.HEAPF32.set(pos, pos_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); - var border = new Float32Array([-1,-1,-1]); - var border_ptr = Module._malloc(border.length * border.BYTES_PER_ELEMENT); - Module.HEAPF32.set(border, border_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); - Module.Configuration_Random(this._state, pos_ptr, border_ptr, -1, -1, 0, 0, -1, -1); - Module._free(pos_ptr); - Module._free(border_ptr); - this.update(); - }; - Module.Configuration_Skyrmion = Module.cwrap('Configuration_Skyrmion', null, ['number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number']); - Simulation.prototype.createSkyrmion = function(order, phase, radius, position, updown, rl, achiral) { - position = new Float32Array(position); - var position_ptr = Module._malloc(position.length * position.BYTES_PER_ELEMENT); - Module.HEAPF32.set(position, position_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); - var border = new Float32Array([-1,-1,-1]); - var border_ptr = Module._malloc(border.length * border.BYTES_PER_ELEMENT); - Module.HEAPF32.set(border, border_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); - Module.Configuration_Skyrmion(this._state, radius, order, phase, updown, achiral, rl, position_ptr, border_ptr, -1, -1, 0, 0, -1, -1); - Module._free(position_ptr); - this.update(); - }; - Module.Configuration_SpinSpiral = Module.cwrap('Configuration_SpinSpiral', null, ['number', 'string', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number']); - Simulation.prototype.createSpinSpiral = function(direction_type, q, axis, theta) { - q = new Float32Array(q); - var q_ptr = Module._malloc(q.length * q.BYTES_PER_ELEMENT); - Module.HEAPF32.set(q, q_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); - axis = new Float32Array(axis); - var axis_ptr = Module._malloc(axis.length * axis.BYTES_PER_ELEMENT); - Module.HEAPF32.set(axis, axis_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); - var pos = new Float32Array([0,0,0]); - var pos_ptr = Module._malloc(pos.length * pos.BYTES_PER_ELEMENT); - Module.HEAPF32.set(pos, pos_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); - var border = new Float32Array([-1,-1,-1]); - var border_ptr = Module._malloc(border.length * border.BYTES_PER_ELEMENT); - Module.HEAPF32.set(border, border_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); - Module.Configuration_SpinSpiral(this._state, direction_type, q_ptr, axis_ptr, theta, pos_ptr, border_ptr, -1, -1, 0, 0, -1, -1); - Module._free(q_ptr); - Module._free(axis_ptr); - this.update(); - }; - Module.Configuration_Domain = Module.cwrap('Configuration_Domain', null, ['number', 'number', 'number', 'number', 'number', 'number']); - Simulation.prototype.createDomain = function(direction, position, border) { - position = new Float32Array(position); - var position_ptr = Module._malloc(position.length * position.BYTES_PER_ELEMENT); - Module.HEAPF32.set(position, position_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); - direction = new Float32Array(direction); - var direction_ptr = Module._malloc(direction.length * direction.BYTES_PER_ELEMENT); - Module.HEAPF32.set(direction, direction_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); - border = new Float32Array(border); - var border_ptr = Module._malloc(border.length * border.BYTES_PER_ELEMENT); - Module.HEAPF32.set(border, border_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); - Module.Configuration_Domain(this._state, direction_ptr, position_ptr, border_ptr, -1, -1, 0, 0, -1, -1); - Module._free(position_ptr); - Module._free(direction_ptr); - this.update(); - }; - Module.Hamiltonian_Set_Boundary_Conditions = Module.cwrap('Hamiltonian_Set_Boundary_Conditions', null, ['number', 'number', 'number']); - Simulation.prototype.updateHamiltonianBoundaryConditions = function(periodical_a, periodical_b, periodical_c) { - var periodical = new Int8Array([periodical_a, periodical_b, periodical_c]); - var periodical_ptr = Module._malloc(periodical.length * periodical.BYTES_PER_ELEMENT); - Module.HEAP8.set(periodical, periodical_ptr/Module.HEAP8.BYTES_PER_ELEMENT); - Module.Hamiltonian_Set_Boundary_Conditions(this._state, periodical_ptr, -1, -1); - Module._free(periodical_ptr); - this.update(); - }; - Module.Hamiltonian_Set_mu_s = Module.cwrap('Geometry_Set_mu_s', null, ['number', 'number', 'number']); - Simulation.prototype.updateHamiltonianMuSpin = function(mu_spin) { - Module.Hamiltonian_Set_mu_s(this._state, mu_spin, -1, -1); - this.update(); - }; - Module.Hamiltonian_Set_Field = Module.cwrap('Hamiltonian_Set_Field', null, ['number', 'number', 'number', 'number']); - Simulation.prototype.updateHamiltonianExternalField = function(magnitude, normal_x, normal_y, normal_z) { - var normal = new Float32Array([normal_x, normal_y, normal_z]); - var normal_ptr = Module._malloc(normal.length * normal.BYTES_PER_ELEMENT); - Module.HEAPF32.set(normal, normal_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); - Module.Hamiltonian_Set_Field(this._state, magnitude, normal_ptr, -1, -1); - Module._free(normal_ptr); - this.update(); - }; - Module.Hamiltonian_Set_Exchange = Module.cwrap('Hamiltonian_Set_Exchange', null, ['number', 'number', 'number', 'number']); - Simulation.prototype.updateHamiltonianExchange = function(values) { - values = new Float32Array(values); - var values_ptr = Module._malloc(values.length * values.BYTES_PER_ELEMENT); - Module.HEAPF32.set(values, values_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); - Module.Hamiltonian_Set_Exchange(this._state, values.length, values_ptr, -1, -1); - Module._free(values_ptr); - this.update(); - }; - Module.Hamiltonian_Set_DMI = Module.cwrap('Hamiltonian_Set_DMI', null, ['number', 'number', 'number', 'number']); - Simulation.prototype.updateHamiltonianDMI = function(values) { - values = new Float32Array(values); - var values_ptr = Module._malloc(values.length * values.BYTES_PER_ELEMENT); - Module.HEAPF32.set(values, values_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); - Module.Hamiltonian_Set_DMI(this._state, values.length, values_ptr, -1, -1); - this.update(); - }; - Module.Hamiltonian_Set_Anisotropy = Module.cwrap('Hamiltonian_Set_Anisotropy', null, ['number', 'number', 'number', 'number', 'number']); - Simulation.prototype.updateHamiltonianAnisotropy = function(magnitude, normal_x, normal_y, normal_z) { - var normal = new Float32Array([normal_x, normal_y, normal_z]); - var normal_ptr = Module._malloc(normal.length * normal.BYTES_PER_ELEMENT); - Module.HEAPF32.set(normal, normal_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); - Module.Hamiltonian_Set_Anisotropy(this._state, magnitude, normal_ptr, -1, -1); - Module._free(normal_ptr); - this.update(); - }; - Module.Hamiltonian_Set_DDI = Module.cwrap('Hamiltonian_Set_DDI', null, ['number', 'number', 'number', 'number', 'number', 'number']); - Simulation.prototype.updateHamiltonianDDI = function(method, n_periodical) { - var periodical = new Int32Array([n_periodical, n_periodical, n_periodical]); - var periodical_ptr = Module._malloc(periodical.length * periodical.BYTES_PER_ELEMENT); - Module.HEAP32.set(periodical, periodical_ptr/Module.HEAP32.BYTES_PER_ELEMENT); - Module.Hamiltonian_Set_DDI(this._state, method, periodical_ptr, 0); - Module._free(periodical_ptr); - this.update(); - }; - Module.Parameters_LLG_Set_Convergence = Module.cwrap('Parameters_LLG_Set_Convergence', null, ['number', 'number', 'number', 'number']); - Simulation.prototype.updateLLGConvergence = function(convergence) { - Module.Parameters_LLG_Set_Convergence(this._state, convergence, -1 -1); - this.update(); - }; - Module.Parameters_LLG_Set_STT = Module.cwrap('Parameters_LLG_Set_STT', null, ['number', 'number', 'number', 'number', 'number', 'number']); - Simulation.prototype.updateHamiltonianSpinTorque = function(magnitude, normal_x, normal_y, normal_z) { - var normal = new Float32Array([normal_x, normal_y, normal_z]); - var normal_ptr = Module._malloc(normal.length * normal.BYTES_PER_ELEMENT); - Module.HEAPF32.set(normal, normal_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); - Module.Parameters_LLG_Set_STT(this._state, false, magnitude, normal_ptr, -1, -1); - Module._free(normal_ptr); - this.update(); - }; - Module.Parameters_LLG_Set_Temperature = Module.cwrap('Parameters_LLG_Set_Temperature', null, ['number', 'number', 'number', 'number']); - Simulation.prototype.updateHamiltonianTemperature = function(temperature) { - Module.Parameters_LLG_Set_Temperature(this._state, temperature, -1, -1); - this.update(); - }; - Module.Parameters_LLG_Set_Time_Step = Module.cwrap('Parameters_LLG_Set_Time_Step', null, ['number', 'number', 'number', 'number']); - Simulation.prototype.updateLLGTimeStep = function(time_step) { - Module.Parameters_LLG_Set_Time_Step(this._state, time_step, -1, -1); - this.update(); - }; - Module.Parameters_LLG_Set_Damping = Module.cwrap('Parameters_LLG_Set_Damping', null, ['number', 'number', 'number', 'number']); - Simulation.prototype.updateLLGDamping = function(damping) { - Module.Parameters_LLG_Set_Damping(this._state, damping); - this.update(); - }; - Module.Geometry_Get_Bounds = Module.cwrap('Geometry_Get_Bounds', null, ['number', 'number', 'number']); - Simulation.prototype.getBoundingBox = function() { - var bounding_box_ptr = Module._malloc(6*Module.HEAPF32.BYTES_PER_ELEMENT); - var xmin_ptr = bounding_box_ptr+0*Module.HEAPF32.BYTES_PER_ELEMENT; - var xmax_ptr = bounding_box_ptr+3*Module.HEAPF32.BYTES_PER_ELEMENT; - var ymin_ptr = bounding_box_ptr+1*Module.HEAPF32.BYTES_PER_ELEMENT; - var ymax_ptr = bounding_box_ptr+4*Module.HEAPF32.BYTES_PER_ELEMENT; - var zmin_ptr = bounding_box_ptr+2*Module.HEAPF32.BYTES_PER_ELEMENT; - var zmax_ptr = bounding_box_ptr+5*Module.HEAPF32.BYTES_PER_ELEMENT; - Module.Geometry_Get_Bounds(this._state, xmin_ptr, xmax_ptr); - var xmin = Module.HEAPF32[xmin_ptr/Module.HEAPF32.BYTES_PER_ELEMENT]; - var xmax = Module.HEAPF32[xmax_ptr/Module.HEAPF32.BYTES_PER_ELEMENT]; - var ymin = Module.HEAPF32[ymin_ptr/Module.HEAPF32.BYTES_PER_ELEMENT]; - var ymax = Module.HEAPF32[ymax_ptr/Module.HEAPF32.BYTES_PER_ELEMENT]; - var zmin = Module.HEAPF32[zmin_ptr/Module.HEAPF32.BYTES_PER_ELEMENT]; - var zmax = Module.HEAPF32[zmax_ptr/Module.HEAPF32.BYTES_PER_ELEMENT]; - Module._free(bounding_box_ptr); - return [xmin, ymin, zmin, xmax, ymax, zmax]; - }; - Module.Geometry_Get_N_Cells = Module.cwrap('Geometry_Get_N_Cells', null, ['number', 'number', 'number']); - Simulation.prototype.getNCells = function (state) { - var ncells_ptr = Module._malloc(3*Module.HEAP32.BYTES_PER_ELEMENT); - var na_ptr = ncells_ptr+0*Module.HEAP32.BYTES_PER_ELEMENT; - var nb_ptr = ncells_ptr+1*Module.HEAP32.BYTES_PER_ELEMENT; - var nc_ptr = ncells_ptr+2*Module.HEAP32.BYTES_PER_ELEMENT; - Module.Geometry_Get_N_Cells(state, ncells_ptr, -1, -1); - var NX = Module.HEAP32[na_ptr/Module.HEAP32.BYTES_PER_ELEMENT]; - var NY = Module.HEAP32[nb_ptr/Module.HEAP32.BYTES_PER_ELEMENT]; - var NZ = Module.HEAP32[nc_ptr/Module.HEAP32.BYTES_PER_ELEMENT]; - Module._free(ncells_ptr); - return [NX, NY, NZ]; - } -}); diff --git a/ui-web/js/spirit.js b/ui-web/js/spirit.js new file mode 100644 index 000000000..4607a098d --- /dev/null +++ b/ui-web/js/spirit.js @@ -0,0 +1,724 @@ +"use strict"; + +function Core(Module, finishedCallback) +{ + this._createSpiritBindings(Module); +} + +function VFRendering(Module, canvas, finishedCallback) +{ + this._canvas = canvas; + + this._options = {}; + this._mergeOptions(this._options, VFRendering.defaultOptions); + + this._createVFRenderingBindings(Module); + + this.isTouchDevice = 'ontouchstart' in document.documentElement; + this._options.useTouch = (VFRendering.defaultOptions.useTouch && this.isTouchDevice); + if (this.isTouchDevice) { + this._lastPanDeltaX = 0; + this._lastPanDeltaY = 0; + var mc = new Hammer.Manager(canvas, {}); + mc.add(new Hammer.Pan({ direction: Hammer.DIRECTION_ALL, threshold: 0, pointers: 1})); + mc.on("pan", this._handlePan.bind(this)); + mc.add(new Hammer.Pinch({})); + mc.on("pinchstart pinchin pinchout pinchmove pinchend", this._handlePinch.bind(this)); + } + this._mouseDown = false; + this._lastMouseX = null; + this._lastMouseY = null; + + canvas.addEventListener('mousewheel', this._handleMouseScroll.bind(this)); + canvas.addEventListener('DOMMouseScroll', this._handleMouseScroll.bind(this)); + canvas.addEventListener('mousedown', this._handleMouseDown.bind(this)); + canvas.addEventListener('mousemove', this._handleMouseMove.bind(this)); + document.addEventListener('mouseup', this._handleMouseUp.bind(this)); +} + + +VFRendering.defaultOptions = {}; +VFRendering.defaultOptions.allowCameraMovement = true; +VFRendering.defaultOptions.useTouch = true; + +VFRendering.prototype.updateOptions = function(options) +{ + var changedOptions = []; + for (var option in options) { + if (this._options.hasOwnProperty(option)) { + if (this._options[option] !== options[option]) { + this._options[option] = options[option]; + changedOptions.push(option); + } + } else { + console.warn("VFRendering does not recognize option '" + option +"'."); + } + } + if (changedOptions.length == 0) { + return; + } +}; + +VFRendering.prototype._mergeOptions = function(options, defaultOptions) { + this._options = {}; + for (var option in defaultOptions) { + this._options[option] = defaultOptions[option]; + } + for (var option in options) { + if (defaultOptions.hasOwnProperty(option)) { + this._options[option] = options[option]; + } else { + console.warn("VFRendering does not recognize option '" + option +"'."); + } + } +}; + +Core.prototype._createSpiritBindings = function(Module) +{ + Module.State_Setup = Module.cwrap('State_Setup', 'number', ['string']); + Core.prototype.setup = function(config) { + this._state = Module.State_Setup(config); + }; + + Core.prototype.getConfig = function(cfg_name, callback) { + if (cfg_name != "") + { + $.get( cfg_name, {}, function(res) { + // console.log(res); + callback(res); + } + ); + } + else + { + callback(" "); + } + }; + + // ------------------------------------------------ + + Module.Geometry_Get_N_Cells = Module.cwrap('Geometry_Get_N_Cells', null, ['number', 'number', 'number']); + Core.prototype.getNCells = function () { + var ncells_ptr = Module._malloc(3*Module.HEAP32.BYTES_PER_ELEMENT); + var na_ptr = ncells_ptr+0*Module.HEAP32.BYTES_PER_ELEMENT; + var nb_ptr = ncells_ptr+1*Module.HEAP32.BYTES_PER_ELEMENT; + var nc_ptr = ncells_ptr+2*Module.HEAP32.BYTES_PER_ELEMENT; + Module.Geometry_Get_N_Cells(this._state, ncells_ptr, -1, -1); + var NX = Module.HEAP32[na_ptr/Module.HEAP32.BYTES_PER_ELEMENT]; + var NY = Module.HEAP32[nb_ptr/Module.HEAP32.BYTES_PER_ELEMENT]; + var NZ = Module.HEAP32[nc_ptr/Module.HEAP32.BYTES_PER_ELEMENT]; + Module._free(ncells_ptr); + return [NX, NY, NZ]; + } + Module.Geometry_Set_N_Cells = Module.cwrap('Geometry_Set_N_Cells', null, ['number', 'number']); + Core.prototype.setNCells = function (n_cells) { + var ncells_ptr = Module._malloc(3*Module.HEAP32.BYTES_PER_ELEMENT); + var na_ptr = ncells_ptr+0*Module.HEAP32.BYTES_PER_ELEMENT; + var nb_ptr = ncells_ptr+1*Module.HEAP32.BYTES_PER_ELEMENT; + var nc_ptr = ncells_ptr+2*Module.HEAP32.BYTES_PER_ELEMENT; + Module.HEAP32[na_ptr/Module.HEAP32.BYTES_PER_ELEMENT] = n_cells[0]; + Module.HEAP32[nb_ptr/Module.HEAP32.BYTES_PER_ELEMENT] = n_cells[1]; + Module.HEAP32[nc_ptr/Module.HEAP32.BYTES_PER_ELEMENT] = n_cells[2]; + Module.Geometry_Set_N_Cells(this._state, ncells_ptr); + Module._free(ncells_ptr); + } + + // ------------------------------------------------ + + Module.Simulation_SingleShot = Module.cwrap('Simulation_SingleShot', null, ['number', 'number', 'number']); + Core.prototype.performIteration = function() { + Module.Simulation_SingleShot(this._state); + // this.update(); + }; + + Module.Simulation_LLG_Start = Module.cwrap('Simulation_LLG_Start', null, ['number', 'number', 'number', 'number', Boolean, 'number', 'number']); + Core.prototype.startSimulation = function() { + Module.Simulation_LLG_Start(this._state, 1, 1000000, 1000, true); + } + + Module.stopsim = Module.cwrap('Simulation_Stop', null, ['number', 'number', 'number']); + Core.prototype.stopSimulation = function() { + Module.stopsim(this._state); + } + + Module.simulation_running = Module.cwrap('Simulation_Running_Anywhere_On_Chain', Boolean, ['number', 'number']); + Core.prototype.simulationRunning = function() { + return Module.simulation_running(this._state); + } + + Module.Spirit_Version_Full = Module.cwrap('Spirit_Version_Full', 'string', []); + Core.prototype.spiritVersion = function() { + return Module.Spirit_Version_Full(); + }; + + // Module.System_Get_Spin_Directions = Module.cwrap('System_Get_Spin_Directions', 'number', ['number', 'number', 'number']); + // Core.prototype.getSpinDirections = function() { + // return Module.System_Get_Spin_Directions(this._state, -1, -1); + // }; + + Module.Geometry_Get_Positions = Module.cwrap('Geometry_Get_Positions', 'number', ['number']); + Core.prototype.getSpinPositions = function() { + return Module.Geometry_Get_Positions(this._state); + }; + + Module.Configuration_PlusZ = Module.cwrap('Configuration_PlusZ', null, ['number', 'number', 'number', 'number', 'number', 'number', 'number', 'number']); + Core.prototype.setAllSpinsPlusZ = function() { + var pos = new Float32Array([0,0,0]); + var pos_ptr = Module._malloc(pos.length * pos.BYTES_PER_ELEMENT); + Module.HEAPF32.set(pos, pos_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + var border = new Float32Array([-1,-1,-1]); + var border_ptr = Module._malloc(border.length * border.BYTES_PER_ELEMENT); + Module.HEAPF32.set(border, border_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + Module.Configuration_PlusZ(this._state, pos_ptr, border_ptr, -1, -1, 0, 0, -1, -1); + // this.update(); + }; + Module.Configuration_MinusZ = Module.cwrap('Configuration_MinusZ', null, ['number', 'number', 'number', 'number', 'number', 'number', 'number', 'number']); + Core.prototype.setAllSpinsMinusZ = function() { + var pos = new Float32Array([0,0,0]); + var pos_ptr = Module._malloc(pos.length * pos.BYTES_PER_ELEMENT); + Module.HEAPF32.set(pos, pos_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + var border = new Float32Array([-1,-1,-1]); + var border_ptr = Module._malloc(border.length * border.BYTES_PER_ELEMENT); + Module.HEAPF32.set(border, border_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + Module.Configuration_MinusZ(this._state, pos_ptr, border_ptr, -1, -1, 0, 0, -1, -1); + // this.update(); + }; + Module.Configuration_Random = Module.cwrap('Configuration_Random', null, ['number', 'number', 'number', 'number', 'number', 'number', 'number', 'number']); + Core.prototype.setAllSpinsRandom = function() { + var pos = new Float32Array([0,0,0]); + var pos_ptr = Module._malloc(pos.length * pos.BYTES_PER_ELEMENT); + Module.HEAPF32.set(pos, pos_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + var border = new Float32Array([-1,-1,-1]); + var border_ptr = Module._malloc(border.length * border.BYTES_PER_ELEMENT); + Module.HEAPF32.set(border, border_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + Module.Configuration_Random(this._state, pos_ptr, border_ptr, -1, -1, 0, 0, -1, -1); + Module._free(pos_ptr); + Module._free(border_ptr); + // this.update(); + }; + Module.Configuration_Skyrmion = Module.cwrap('Configuration_Skyrmion', null, ['number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number']); + Core.prototype.createSkyrmion = function(order, phase, radius, position, updown, rl, achiral) { + position = new Float32Array(position); + var position_ptr = Module._malloc(position.length * position.BYTES_PER_ELEMENT); + Module.HEAPF32.set(position, position_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + var border = new Float32Array([-1,-1,-1]); + var border_ptr = Module._malloc(border.length * border.BYTES_PER_ELEMENT); + Module.HEAPF32.set(border, border_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + Module.Configuration_Skyrmion(this._state, radius, order, phase, updown, achiral, rl, position_ptr, border_ptr, -1, -1, 0, 0, -1, -1); + Module._free(position_ptr); + // this.update(); + }; + Module.Configuration_Hopfion = Module.cwrap('Configuration_Hopfion', null, ['number', 'number', 'number', 'number', 'number', 'number', 'number', 'number']); + Core.prototype.createHopfion = function(radius, order, position) { + position = new Float32Array(position); + var position_ptr = Module._malloc(position.length * position.BYTES_PER_ELEMENT); + Module.HEAPF32.set(position, position_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + var border = new Float32Array([-1,-1,-1]); + var border_ptr = Module._malloc(border.length * border.BYTES_PER_ELEMENT); + Module.HEAPF32.set(border, border_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + Module.Configuration_Hopfion(this._state, radius, order, position_ptr, border_ptr, -1, -1, 0, 0, -1, -1); + Module._free(position_ptr); + // this.update(); + }; + Module.Configuration_SpinSpiral = Module.cwrap('Configuration_SpinSpiral', null, ['number', 'string', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number']); + Core.prototype.createSpinSpiral = function(direction_type, q, axis, theta) { + q = new Float32Array(q); + var q_ptr = Module._malloc(q.length * q.BYTES_PER_ELEMENT); + Module.HEAPF32.set(q, q_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + axis = new Float32Array(axis); + var axis_ptr = Module._malloc(axis.length * axis.BYTES_PER_ELEMENT); + Module.HEAPF32.set(axis, axis_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + var pos = new Float32Array([0,0,0]); + var pos_ptr = Module._malloc(pos.length * pos.BYTES_PER_ELEMENT); + Module.HEAPF32.set(pos, pos_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + var border = new Float32Array([-1,-1,-1]); + var border_ptr = Module._malloc(border.length * border.BYTES_PER_ELEMENT); + Module.HEAPF32.set(border, border_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + Module.Configuration_SpinSpiral(this._state, direction_type, q_ptr, axis_ptr, theta, pos_ptr, border_ptr, -1, -1, 0, 0, -1, -1); + Module._free(q_ptr); + Module._free(axis_ptr); + // this.update(); + }; + Module.Configuration_Domain = Module.cwrap('Configuration_Domain', null, ['number', 'number', 'number', 'number', 'number', 'number']); + Core.prototype.createDomain = function(direction, position, border) { + position = new Float32Array(position); + var position_ptr = Module._malloc(position.length * position.BYTES_PER_ELEMENT); + Module.HEAPF32.set(position, position_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + direction = new Float32Array(direction); + var direction_ptr = Module._malloc(direction.length * direction.BYTES_PER_ELEMENT); + Module.HEAPF32.set(direction, direction_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + border = new Float32Array(border); + var border_ptr = Module._malloc(border.length * border.BYTES_PER_ELEMENT); + Module.HEAPF32.set(border, border_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + Module.Configuration_Domain(this._state, direction_ptr, position_ptr, border_ptr, -1, -1, 0, 0, -1, -1); + Module._free(position_ptr); + Module._free(direction_ptr); + // this.update(); + }; + Module.Hamiltonian_Set_Boundary_Conditions = Module.cwrap('Hamiltonian_Set_Boundary_Conditions', null, ['number', 'number', 'number']); + Core.prototype.updateHamiltonianBoundaryConditions = function(periodical_a, periodical_b, periodical_c) { + var periodical = new Int8Array([periodical_a, periodical_b, periodical_c]); + var periodical_ptr = Module._malloc(periodical.length * periodical.BYTES_PER_ELEMENT); + Module.HEAP8.set(periodical, periodical_ptr/Module.HEAP8.BYTES_PER_ELEMENT); + Module.Hamiltonian_Set_Boundary_Conditions(this._state, periodical_ptr, -1, -1); + Module._free(periodical_ptr); + // this.update(); + }; + Module.Hamiltonian_Set_mu_s = Module.cwrap('Geometry_Set_mu_s', null, ['number', 'number', 'number']); + Core.prototype.updateHamiltonianMuSpin = function(mu_spin) { + Module.Hamiltonian_Set_mu_s(this._state, mu_spin, -1, -1); + // this.update(); + }; + Module.Hamiltonian_Set_Field = Module.cwrap('Hamiltonian_Set_Field', null, ['number', 'number', 'number', 'number']); + Core.prototype.updateHamiltonianExternalField = function(magnitude, normal_x, normal_y, normal_z) { + var normal = new Float32Array([normal_x, normal_y, normal_z]); + var normal_ptr = Module._malloc(normal.length * normal.BYTES_PER_ELEMENT); + Module.HEAPF32.set(normal, normal_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + Module.Hamiltonian_Set_Field(this._state, magnitude, normal_ptr, -1, -1); + Module._free(normal_ptr); + // this.update(); + }; + Module.Hamiltonian_Set_Exchange = Module.cwrap('Hamiltonian_Set_Exchange', null, ['number', 'number', 'number', 'number']); + Core.prototype.updateHamiltonianExchange = function(values) { + values = new Float32Array(values); + var values_ptr = Module._malloc(values.length * values.BYTES_PER_ELEMENT); + Module.HEAPF32.set(values, values_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + Module.Hamiltonian_Set_Exchange(this._state, values.length, values_ptr, -1, -1); + Module._free(values_ptr); + // this.update(); + }; + Module.Hamiltonian_Set_DMI = Module.cwrap('Hamiltonian_Set_DMI', null, ['number', 'number', 'number', 'number']); + Core.prototype.updateHamiltonianDMI = function(values) { + values = new Float32Array(values); + var values_ptr = Module._malloc(values.length * values.BYTES_PER_ELEMENT); + Module.HEAPF32.set(values, values_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + Module.Hamiltonian_Set_DMI(this._state, values.length, values_ptr, -1, -1); + // this.update(); + }; + Module.Hamiltonian_Set_Anisotropy = Module.cwrap('Hamiltonian_Set_Anisotropy', null, ['number', 'number', 'number', 'number', 'number']); + Core.prototype.updateHamiltonianAnisotropy = function(magnitude, normal_x, normal_y, normal_z) { + var normal = new Float32Array([normal_x, normal_y, normal_z]); + var normal_ptr = Module._malloc(normal.length * normal.BYTES_PER_ELEMENT); + Module.HEAPF32.set(normal, normal_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + Module.Hamiltonian_Set_Anisotropy(this._state, magnitude, normal_ptr, -1, -1); + Module._free(normal_ptr); + // this.update(); + }; + Module.Hamiltonian_Set_DDI = Module.cwrap('Hamiltonian_Set_DDI', null, ['number', 'number', 'number', 'number', 'number', 'number']); + Core.prototype.updateHamiltonianDDI = function(method, n_periodical) { + var periodical = new Int32Array([n_periodical, n_periodical, n_periodical]); + var periodical_ptr = Module._malloc(periodical.length * periodical.BYTES_PER_ELEMENT); + Module.HEAP32.set(periodical, periodical_ptr/Module.HEAP32.BYTES_PER_ELEMENT); + Module.Hamiltonian_Set_DDI(this._state, method, periodical_ptr, 0); + Module._free(periodical_ptr); + // this.update(); + }; + Module.Parameters_LLG_Set_Convergence = Module.cwrap('Parameters_LLG_Set_Convergence', null, ['number', 'number', 'number', 'number']); + Core.prototype.updateLLGConvergence = function(convergence) { + Module.Parameters_LLG_Set_Convergence(this._state, convergence, -1 -1); + // this.update(); + }; + Module.Parameters_LLG_Set_STT = Module.cwrap('Parameters_LLG_Set_STT', null, ['number', 'number', 'number', 'number', 'number', 'number']); + Core.prototype.updateHamiltonianSpinTorque = function(magnitude, normal_x, normal_y, normal_z) { + var normal = new Float32Array([normal_x, normal_y, normal_z]); + var normal_ptr = Module._malloc(normal.length * normal.BYTES_PER_ELEMENT); + Module.HEAPF32.set(normal, normal_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + Module.Parameters_LLG_Set_STT(this._state, false, magnitude, normal_ptr, -1, -1); + Module._free(normal_ptr); + // this.update(); + }; + Module.Parameters_LLG_Set_Temperature = Module.cwrap('Parameters_LLG_Set_Temperature', null, ['number', 'number', 'number', 'number']); + Core.prototype.updateHamiltonianTemperature = function(temperature) { + Module.Parameters_LLG_Set_Temperature(this._state, temperature, -1, -1); + // this.update(); + }; + Module.Parameters_LLG_Set_Time_Step = Module.cwrap('Parameters_LLG_Set_Time_Step', null, ['number', 'number', 'number', 'number']); + Core.prototype.updateLLGTimeStep = function(time_step) { + Module.Parameters_LLG_Set_Time_Step(this._state, time_step, -1, -1); + // this.update(); + }; + Module.Parameters_LLG_Set_Damping = Module.cwrap('Parameters_LLG_Set_Damping', null, ['number', 'number', 'number', 'number']); + Core.prototype.updateLLGDamping = function(damping) { + Module.Parameters_LLG_Set_Damping(this._state, damping); + // this.update(); + }; + Module.Geometry_Get_Bounds = Module.cwrap('Geometry_Get_Bounds', null, ['number', 'number', 'number']); + Core.prototype.getBoundingBox = function() { + var bounding_box_ptr = Module._malloc(6*Module.HEAPF32.BYTES_PER_ELEMENT); + var xmin_ptr = bounding_box_ptr+0*Module.HEAPF32.BYTES_PER_ELEMENT; + var xmax_ptr = bounding_box_ptr+3*Module.HEAPF32.BYTES_PER_ELEMENT; + var ymin_ptr = bounding_box_ptr+1*Module.HEAPF32.BYTES_PER_ELEMENT; + var ymax_ptr = bounding_box_ptr+4*Module.HEAPF32.BYTES_PER_ELEMENT; + var zmin_ptr = bounding_box_ptr+2*Module.HEAPF32.BYTES_PER_ELEMENT; + var zmax_ptr = bounding_box_ptr+5*Module.HEAPF32.BYTES_PER_ELEMENT; + Module.Geometry_Get_Bounds(this._state, xmin_ptr, xmax_ptr); + var xmin = Module.HEAPF32[xmin_ptr/Module.HEAPF32.BYTES_PER_ELEMENT]; + var xmax = Module.HEAPF32[xmax_ptr/Module.HEAPF32.BYTES_PER_ELEMENT]; + var ymin = Module.HEAPF32[ymin_ptr/Module.HEAPF32.BYTES_PER_ELEMENT]; + var ymax = Module.HEAPF32[ymax_ptr/Module.HEAPF32.BYTES_PER_ELEMENT]; + var zmin = Module.HEAPF32[zmin_ptr/Module.HEAPF32.BYTES_PER_ELEMENT]; + var zmax = Module.HEAPF32[zmax_ptr/Module.HEAPF32.BYTES_PER_ELEMENT]; + Module._free(bounding_box_ptr); + return [xmin, ymin, zmin, xmax, ymax, zmax]; + }; + Module.IO_Image_Write = Module.cwrap('IO_Image_Write', null, ['number', 'string', 'number', 'string', 'number', 'number']); + Core.prototype.exportOVFDataURI = function () { + Module.IO_Image_Write(this._state, "/export.ovf", 3, 'Generated with Spirit Web UI', -1, -1); + var ovf_data = FS.readFile("/export.ovf"); + function uint8ArrayToString_chunked(data){ + var CHUNK_SIZE = 32768; + var chunks = []; + for (var i=0; i < data.length; i += CHUNK_SIZE) { + chunks.push(String.fromCharCode.apply(null, data.subarray(i, i+CHUNK_SIZE))); + } + return chunks.join(""); + } + return "data:application/octet-stream;base64," + btoa(uint8ArrayToString_chunked(ovf_data)); + } + Module.IO_Image_Read = Module.cwrap('IO_Image_Read', null, ['number', 'string', 'number', 'number', 'number']); + Core.prototype.importOVFData = function (ovf_data) { + var stream = FS.open('/import.ovf', 'w'); + FS.write(stream, ovf_data, 0, ovf_data.length, 0); + FS.close(stream); + Module.IO_Image_Read(this._state, "/import.ovf", 0, -1, -1); + // this.update(); + } + Module.System_Update_Data = Module.cwrap('System_Update_Data', null, ['number', 'number', 'number']); + Core.prototype.System_Update_Data = function () { + Module.System_Update_Data(this._state, -1, -1); + } + Module.IO_Image_Write_Energy_per_Spin = Module.cwrap('IO_Image_Write_Energy_per_Spin', null, ['number', 'string', 'number', 'number', 'number']); + Core.prototype.exportEnergyDataURI = function () { + Module.IO_Image_Write_Energy_per_Spin(this._state, "/energy.txt", 3, -1, -1); + var energy_data = FS.readFile("/energy.txt"); + function uint8ArrayToString_chunked(data){ + var CHUNK_SIZE = 32768; + var chunks = []; + for (var i=0; i < data.length; i += CHUNK_SIZE) { + chunks.push(String.fromCharCode.apply(null, data.subarray(i, i+CHUNK_SIZE))); + } + return chunks.join(""); + } + return "data:application/octet-stream;base64," + btoa(uint8ArrayToString_chunked(energy_data)); + } +}; + +// ------------------------------------------------ + +VFRendering.prototype._createVFRenderingBindings = function(Module) +{ + Module.initialize = Module.cwrap('initialize', null, ['number']); + VFRendering.prototype.initialize = function() { + Module.initialize(this._state); + }; + + Module.draw = Module.cwrap('draw'); + VFRendering.prototype._draw = function() { + Module.draw(); + }; + + // Module.set_camera = Module.cwrap('set_camera'); + VFRendering.prototype.set_camera = function(position, center, up) { + position = new Float32Array(position); + var position_ptr = Module._malloc(position.length * position.BYTES_PER_ELEMENT); + Module.HEAPF32.set(position, position_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + center = new Float32Array(center); + var center_ptr = Module._malloc(center.length * center.BYTES_PER_ELEMENT); + Module.HEAPF32.set(center, center_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + up = new Float32Array(up); + var up_ptr = Module._malloc(up.length * up.BYTES_PER_ELEMENT); + Module.HEAPF32.set(up, up_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + Module._set_camera(position_ptr, center_ptr, up_ptr); + }; + + VFRendering.prototype.align_camera = function(direction, up) { + direction = new Float32Array(direction); + var direction_ptr = Module._malloc(direction.length * direction.BYTES_PER_ELEMENT); + Module.HEAPF32.set(direction, direction_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + up = new Float32Array(up); + var up_ptr = Module._malloc(up.length * up.BYTES_PER_ELEMENT); + Module.HEAPF32.set(up, up_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + Module._align_camera(direction_ptr, up_ptr); + }; + + VFRendering.prototype.recenter_camera = function() { + Module._recenter_camera(); + }; + + Module.set_background = Module.cwrap('set_background', null, ['number']); + VFRendering.prototype.set_background = function(colour) { + colour = new Float32Array(colour); + var colour_ptr = Module._malloc(colour.length * colour.BYTES_PER_ELEMENT); + Module.HEAPF32.set(colour, colour_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + Module.set_background(colour_ptr); + }; + + Module.set_coordinate_system = Module.cwrap('set_coordinate_system', null, ['number', 'number']); + VFRendering.prototype.set_coordinatesystem = function(show, position) { + Module.set_coordinate_system(this._state, show, position); + }; + + Module.set_miniview = Module.cwrap('set_miniview', null, ['number', 'number']); + VFRendering.prototype.set_miniview = function(show, position) { + Module.set_miniview(this._state, show, position); + Module._draw(); + } + + Module.set_boundingbox_colour = Module.cwrap('set_boundingbox_colour', null, ['number', 'number', 'number']); + VFRendering.prototype.set_boundingbox_colour = function(colour) { + colour = new Float32Array(colour); + var colour_ptr = Module._malloc(colour.length * colour.BYTES_PER_ELEMENT); + Module.HEAPF32.set(colour, colour_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + Module.set_boundingbox_colour(colour_ptr); + }; + + Module.set_boundingbox = Module.cwrap('set_boundingbox', null, ['number', 'number', 'number']); + VFRendering.prototype.set_boundingbox = function(show, line_width) { + Module.set_boundingbox(this._state, show, line_width); + }; + + Module.set_dots = Module.cwrap('set_dots', null, ['number', 'number']); + VFRendering.prototype.set_dots = function(show) { + Module.set_dots(this._state, show); + }; + + Module.set_arrows = Module.cwrap('set_arrows', null, ['number', 'number']); + VFRendering.prototype.set_arrows = function(show) { + Module.set_arrows(this._state, show); + }; + + Module.set_spheres = Module.cwrap('set_spheres', null, ['number', 'number']); + VFRendering.prototype.set_spheres = function(show) { + Module.set_spheres(this._state, show); + }; + + Module.set_boxes = Module.cwrap('set_boxes', null, ['number', 'number']); + VFRendering.prototype.set_boxes = function(show) { + Module.set_boxes(this._state, show); + }; + + Module.set_surface = Module.cwrap('set_surface', null, ['number', 'number']); + VFRendering.prototype.set_surface = function(show) { + Module.set_surface(this._state, show); + }; + + Module.set_isosurface = Module.cwrap('set_isosurface', null, ['number', 'number']); + VFRendering.prototype.set_isosurface = function(show) { + Module.set_isosurface(this._state, show); + }; + + // ----------------------- Functions + + VFRendering.prototype.draw = function() { + var width = this._canvas.clientWidth; + var height = this._canvas.clientHeight; + this._canvas.width = width; + this._canvas.height = height; + Module._draw(); + } + + VFRendering.prototype.updateDirections = function() { + Module._update_directions(this._state); + Module._draw(); + } + + VFRendering.prototype.updateGeometry = function() { + Module._update_geometry(this._state); + Module._draw(); + } + + VFRendering.prototype.set_rendermode = function(mode) { + Module._set_rendermode(mode); + Module._draw(); + } + + VFRendering.prototype.updateVisibility = function(zRange) { + Module._set_visibility(zRange[0], zRange[1]); + Module._draw(); + } + + VFRendering.prototype.setVectorSphere = function(pointSizeRange) { + Module._set_vectorsphere(pointSizeRange[0], pointSizeRange[1]); + Module._draw(); + } + + VFRendering.prototype.setColormap = function(colormap) { + var idx_cmap = 0; + if( colormap == "hsv" ) + { + idx_cmap = 0; + } + else if( colormap == "hue" ) + { + idx_cmap = 1; + } + else if( colormap == "bluered" ) + { + idx_cmap = 2; + } + else if( colormap == "bluegreenred" ) + { + idx_cmap = 3; + } + else if( colormap == "bluewhitered" ) + { + idx_cmap = 4; + } + else if( colormap == "red" ) + { + idx_cmap = 5; + } + else if( colormap == "white" ) + { + idx_cmap = 6; + } + else if( colormap == "gray" ) + { + idx_cmap = 7; + } + else if( colormap == "black" ) + { + idx_cmap = 8; + } + else if( colormap == "black" ) + { + idx_cmap = 8; + } + Module._set_colormap(idx_cmap); + Module._draw(); + } + + // ----------------------- Handlers + + VFRendering.prototype._handlePinch = function(event) { + if (!this._options.useTouch) return; + if (event.scale > 1) { + Module._mouse_scroll(-0.3*event.scale); + } else { + Module._mouse_scroll(0.3/event.scale); + } + this.draw(); + }; + + VFRendering.prototype._handlePan = function(event) { + if (!this._options.useTouch) return; + var deltaX = event.deltaX; + var deltaY = event.deltaY; + + var prev = Module._malloc(2*Module.HEAPF32.BYTES_PER_ELEMENT); + var na_ptr = prev+0*Module.HEAPF32.BYTES_PER_ELEMENT; + var nb_ptr = prev+1*Module.HEAPF32.BYTES_PER_ELEMENT; + Module.HEAPF32[na_ptr/Module.HEAPF32.BYTES_PER_ELEMENT] = this._lastPanDeltaX; + Module.HEAPF32[nb_ptr/Module.HEAPF32.BYTES_PER_ELEMENT] = this._lastPanDeltaY; + var current = Module._malloc(2*Module.HEAPF32.BYTES_PER_ELEMENT); + var na_ptr = current+0*Module.HEAPF32.BYTES_PER_ELEMENT; + var nb_ptr = current+1*Module.HEAPF32.BYTES_PER_ELEMENT; + Module.HEAPF32[na_ptr/Module.HEAPF32.BYTES_PER_ELEMENT] = deltaX; + Module.HEAPF32[nb_ptr/Module.HEAPF32.BYTES_PER_ELEMENT] = deltaY; + + if (event.isFinal) { + this._lastPanDeltaX = 0; + this._lastPanDeltaY = 0; + } else { + this._lastPanDeltaX = event.deltaX; + this._lastPanDeltaY = event.deltaY; + } + + Module._mouse_move(prev, current, 1); + this.draw(); + }; + + VFRendering.prototype._handleMouseDown = function(event) { + if (this._options.useTouch) return; + if (!this._options.allowCameraMovement) { + return; + } + this._mouseDown = true; + this._lastMouseX = event.clientX; + this._lastMouseY = event.clientY; + }; + + VFRendering.prototype._handleMouseUp = function(event) { + if (this._options.useTouch) return; + this._mouseDown = false; + }; + + VFRendering.prototype._handleMouseMove = function(event) { + if (this._options.useTouch) return; + if (!this._options.allowCameraMovement) { + return; + } + if (!this._mouseDown) { + return; + } + var newX = event.clientX; + var newY = event.clientY; + + var prev = Module._malloc(2*Module.HEAPF32.BYTES_PER_ELEMENT); + var na_ptr = prev+0*Module.HEAPF32.BYTES_PER_ELEMENT; + var nb_ptr = prev+1*Module.HEAPF32.BYTES_PER_ELEMENT; + Module.HEAPF32[na_ptr/Module.HEAPF32.BYTES_PER_ELEMENT] = this._lastMouseX; + Module.HEAPF32[nb_ptr/Module.HEAPF32.BYTES_PER_ELEMENT] = this._lastMouseY; + var current = Module._malloc(2*Module.HEAPF32.BYTES_PER_ELEMENT); + var na_ptr = current+0*Module.HEAPF32.BYTES_PER_ELEMENT; + var nb_ptr = current+1*Module.HEAPF32.BYTES_PER_ELEMENT; + Module.HEAPF32[na_ptr/Module.HEAPF32.BYTES_PER_ELEMENT] = newX; + Module.HEAPF32[nb_ptr/Module.HEAPF32.BYTES_PER_ELEMENT] = newY; + + Module._mouse_move(prev, current, 1); + this.draw(); + this._lastMouseX = newX; + this._lastMouseY = newY; + }; + + VFRendering.prototype._handleMouseScroll = function(event) { + if (this._options.useTouch) return; + if (!this._options.allowCameraMovement) { + return; + } + var scale = 1; + if (event.shiftKey) + { + scale = 0.1; + } + var delta = Math.max(-1, Math.min(1, (event.wheelDelta || -event.detail))); + Module._mouse_scroll(-delta*scale); + this.draw(); + }; +}; + +// -------------------------------------- + +function Spirit(Module, canvas) +{ + this.core = new Core(Module); + this.vfr = new VFRendering(Module, canvas); + + // --------------------------------------- + + this.core.setup(""); + + // Default geometry + this.core.setNCells([100, 100, 1]); + + // Default Hamiltonian + this.core.updateHamiltonianMuSpin(2); + this.core.updateHamiltonianExternalField(25, 0, 0, 1); + this.core.updateHamiltonianExchange([10]); + this.core.updateHamiltonianDMI([6]); + + // Default configuration + // this.core.setAllSpinsPlusZ(); + this.core.setAllSpinsRandom(); + + // --------------------------------------- + + this.vfr._state = this.core._state; + this.vfr.initialize(); + + // console.log("ready VFR"); + this.vfr.updateGeometry(); + this.vfr.updateDirections(); + this.vfr.recenter_camera(); + this.vfr.draw(); +}; \ No newline at end of file diff --git a/ui-web/js/ui.js b/ui-web/js/ui.js index 6ec601610..db8fe0282 100644 --- a/ui-web/js/ui.js +++ b/ui-web/js/ui.js @@ -1,706 +1,960 @@ -$(document).ready(function() { - $('form').attr('onsubmit', 'return false;'); - webglspins = new WebGLSpins(document.getElementById("webgl-canvas"), { - cameraLocation: [50, 50, 100], - centerLocation: [50, 50, 0], - upVector: [0, 1, 0], - backgroundColor: [0.5, 0.5, 0.5] - }); - WebGLSpins.colormapImplementations['hsv'] = ` - float atan2(float y, float x) { - return x == 0.0 ? sign(y)*3.14159/2.0 : atan(y, x); - } - vec3 hsv2rgb(vec3 c) { - vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); - vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); - return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); - } - vec3 colormap(vec3 direction) { - vec2 xy = normalize(direction.xy); - float hue = atan2(xy.x, xy.y) / 3.14159 / 2.0; - if (direction.z > 0.0) { - return hsv2rgb(vec3(hue, 1.0-direction.z, 1.0)); + +$(document).ready(function() +{ + $('form').attr('onsubmit', 'return false;'); + var isSimulating = false; + var canvas = document.getElementById("webgl-canvas"); + + Module_Spirit().then(function(Module) { + window.FS = Module.FS + window.spirit = new Spirit(Module, canvas); + } + ).then(function() + { + $( window ).resize(function() { + if (!isSimulating) { + spirit.vfr.draw(); + } + }); + $('.collapse').on('hidden.bs.collapse', function () { + if (!isSimulating) { + spirit.vfr.draw(); + } + }); + $('.collapse').on('shown.bs.collapse', function () { + if (!isSimulating) { + spirit.vfr.draw(); + } + }); + $('#input-show-settings').on('change', function () { + if (!isSimulating) { + spirit.vfr.draw(); + } + }); + + function simulation_start_stop() + { + isSimulating = !isSimulating; + $("#btn-play").toggleClass("fa-play fa-pause"); + if (isSimulating) { + spirit.core.startSimulation(); + window.requestAnimationFrame(function () { + update(); + }); + } + else { + spirit.core.stopSimulation(); + } + } + + $("#btn-play").click(function() { + simulation_start_stop(); + }); + + canvas.addEventListener('keydown', function(event) { + var key = event.keyCode || event.which; + if (key == 32) { // space + simulation_start_stop(); + } + // else{ + // console.log('key code ' + key + ' was pressed!'); + // } + }); + + window.addEventListener('keydown', function(event) { + var key = event.keyCode || event.which; + if (key == 88) { // x + spirit.vfr.align_camera([-1, 0, 0], [0, 0, 1]); + spirit.vfr.draw(); + } + else if (key == 89) { // y + spirit.vfr.align_camera([0, 1, 0], [0, 0, 1]); + spirit.vfr.draw(); + } + else if (key == 90) { // z + spirit.vfr.align_camera([0, 0, -1], [0, 1, 0]); + spirit.vfr.draw(); + } + // else{ + // console.log('key code ' + key + ' was pressed!'); + // } + }); + + function update() { + if (isSimulating) { + spirit.core.performIteration(); + spirit.vfr.updateDirections(); + spirit.vfr.draw(); + window.requestAnimationFrame(function () { + update() + }); + } + }; + + // -------------------------- + + function updateGridSize() { + var x = Number($('#input-gridsize-x').val()); + var y = Number($('#input-gridsize-y').val()); + var z = Number($('#input-gridsize-z').val()); + spirit.core.setNCells([x, y, z]); + spirit.vfr.updateGeometry(); + spirit.vfr.updateDirections(); + spirit.vfr.recenter_camera(); + spirit.vfr.draw(); + } + $('#button-gridsize-update').on('click', function(e) { + updateGridSize(); + }); + + // -------------------------- + + $('#button-plusz').on('click', function(e) { + spirit.core.setAllSpinsPlusZ(); + spirit.vfr.updateDirections(); + }); + $('#button-minusz').on('click', function(e) { + spirit.core.setAllSpinsMinusZ(); + spirit.vfr.updateDirections(); + }); + $('#button-random').on('click', function(e) { + spirit.core.setAllSpinsRandom(); + spirit.vfr.updateDirections(); + }); + + $('#button-skyrmion-create').on('click', function(e) { + var order = Number($('#input-skyrmion-order').val()); + var phase = Number($('#input-skyrmion-phase').val()); + var radius = Number($('#input-skyrmion-radius').val()); + var positionx = Number($('#input-skyrmion-positionx').val()); + var positiony = Number($('#input-skyrmion-positiony').val()); + var positionz = Number($('#input-skyrmion-positionz').val()); + var updown = $('#input-skyrmion-updown')[0].checked; + var rl = false;//$('#input-skyrmion-rl')[0].checked; + var achiral = $('#input-skyrmion-achiral')[0].checked; + // var exp = $('#input-skyrmion-exp')[0].checked; + var valid = true; + if (Number.isNaN(order)) { + valid = false; + $('#input-skyrmion-order').parent().addClass('has-error'); + } else { + $('#input-skyrmion-order').parent().removeClass('has-error'); + } + if (Number.isNaN(phase)) { + valid = false; + $('#input-skyrmion-phase').parent().addClass('has-error'); + } else { + $('#input-skyrmion-phase').parent().removeClass('has-error'); + } + if (Number.isNaN(radius)) { + valid = false; + $('#input-skyrmion-radius').parent().addClass('has-error'); + } else { + $('#input-skyrmion-radius').parent().removeClass('has-error'); + } + if (Number.isNaN(positionx)) { + valid = false; + $('#input-skyrmion-positionx').parent().addClass('has-error'); + } else { + $('#input-skyrmion-positionx').parent().removeClass('has-error'); + } + if (Number.isNaN(positiony)) { + valid = false; + $('#input-skyrmion-positiony').parent().addClass('has-error'); + } else { + $('#input-skyrmion-positiony').parent().removeClass('has-error'); + } + if (Number.isNaN(positionz)) { + valid = false; + $('#input-skyrmion-positionz').parent().addClass('has-error'); + } else { + $('#input-skyrmion-positionz').parent().removeClass('has-error'); + } + if (valid) { + var position = [positionx, positiony, positionz]; + spirit.core.createSkyrmion(order, phase, radius, position, updown, rl, achiral); + spirit.vfr.updateDirections(); + } + }); + + $('#button-hopfion-create').on('click', function(e) { + var order = Number($('#input-hopfion-order').val()); + var radius = Number($('#input-hopfion-radius').val()); + var positionx = Number($('#input-hopfion-positionx').val()); + var positiony = Number($('#input-hopfion-positiony').val()); + var positionz = Number($('#input-hopfion-positionz').val()); + // var exp = $('#input-hopfion-exp')[0].checked; + var valid = true; + if (Number.isNaN(order)) { + valid = false; + $('#input-hopfion-order').parent().addClass('has-error'); + } else { + $('#input-hopfion-order').parent().removeClass('has-error'); + } + if (Number.isNaN(radius)) { + valid = false; + $('#input-hopfion-radius').parent().addClass('has-error'); + } else { + $('#input-hopfion-radius').parent().removeClass('has-error'); + } + if (Number.isNaN(positionx)) { + valid = false; + $('#input-hopfion-positionx').parent().addClass('has-error'); + } else { + $('#input-hopfion-positionx').parent().removeClass('has-error'); + } + if (Number.isNaN(positiony)) { + valid = false; + $('#input-hopfion-positiony').parent().addClass('has-error'); + } else { + $('#input-hopfion-positiony').parent().removeClass('has-error'); + } + if (Number.isNaN(positionz)) { + valid = false; + $('#input-hopfion-positionz').parent().addClass('has-error'); + } else { + $('#input-hopfion-positionz').parent().removeClass('has-error'); + } + if (valid) { + var position = [positionx, positiony, positionz]; + spirit.core.createHopfion(radius, order, position); + spirit.vfr.updateDirections(); + } + }); + + $('#button-spinspiral-create').on('click', function(e) { + var qx = Number($('#input-spinspiral-qx').val()); + var qy = Number($('#input-spinspiral-qy').val()); + var qz = Number($('#input-spinspiral-qz').val()); + var axisx = Number($('#input-spinspiral-axisx').val()); + var axisy = Number($('#input-spinspiral-axisy').val()); + var axisz = Number($('#input-spinspiral-axisz').val()); + var angle = Number($('#input-spinspiral-angle').val()); + var wrt = $("option:selected", $('#select-spinspiral-wrt'))[0].value; + var valid = true; + if (Number.isNaN(qx)) { + valid = false; + $('#input-spinspiral-qx').parent().addClass('has-error'); + } else { + $('#input-spinspiral-qx').parent().removeClass('has-error'); + } + if (Number.isNaN(qy)) { + valid = false; + $('#input-spinspiral-qy').parent().addClass('has-error'); + } else { + $('#input-spinspiral-qy').parent().removeClass('has-error'); + } + if (Number.isNaN(qz)) { + valid = false; + $('#input-spinspiral-qz').parent().addClass('has-error'); + } else { + $('#input-spinspiral-qz').parent().removeClass('has-error'); + } + if (Number.isNaN(axisx)) { + valid = false; + $('#input-spinspiral-axisx').parent().addClass('has-error'); + } else { + $('#input-spinspiral-axisx').parent().removeClass('has-error'); + } + if (Number.isNaN(axisy)) { + valid = false; + $('#input-spinspiral-axisy').parent().addClass('has-error'); + } else { + $('#input-spinspiral-axisy').parent().removeClass('has-error'); + } + if (Number.isNaN(axisz)) { + valid = false; + $('#input-spinspiral-axisz').parent().addClass('has-error'); + } else { + $('#input-spinspiral-axisz').parent().removeClass('has-error'); + } + if (Number.isNaN(angle)) { + valid = false; + $('#input-spinspiral-angle').parent().addClass('has-error'); + } else { + $('#input-spinspiral-angle').parent().removeClass('has-error'); + } + if (valid) { + var q = [qx, qy, qz]; + var axis = [axisx, axisy, axisz]; + spirit.core.createSpinSpiral(wrt, q, axis, angle); + spirit.vfr.updateDirections(); + } + }); + + $('#button-domain-create').on('click', function(e) { + var positionx = Number($('#input-domain-positionx').val()); + var positiony = Number($('#input-domain-positiony').val()); + var positionz = Number($('#input-domain-positionz').val()); + var borderx = Number($('#input-domain-borderx').val()); + var bordery = Number($('#input-domain-bordery').val()); + var borderz = Number($('#input-domain-borderz').val()); + var directionx = Number($('#input-domain-directionx').val()); + var directiony = Number($('#input-domain-directiony').val()); + var directionz = Number($('#input-domain-directionz').val()); + // var greater = $('#input-domain-greater')[0].checked; + var valid = true; + if (Number.isNaN(positionx)) { + valid = false; + $('#input-domain-positionx').parent().addClass('has-error'); + } else { + $('#input-domain-positionx').parent().removeClass('has-error'); + } + if (Number.isNaN(positiony)) { + valid = false; + $('#input-domain-positiony').parent().addClass('has-error'); + } else { + $('#input-domain-positiony').parent().removeClass('has-error'); + } + if (Number.isNaN(positionz)) { + valid = false; + $('#input-domain-positionz').parent().addClass('has-error'); + } else { + $('#input-domain-positionz').parent().removeClass('has-error'); + } + if (Number.isNaN(borderx)) { + valid = false; + $('#input-domain-borderx').parent().addClass('has-error'); + } else { + $('#input-domain-borderx').parent().removeClass('has-error'); + } + if (Number.isNaN(bordery)) { + valid = false; + $('#input-domain-bordery').parent().addClass('has-error'); + } else { + $('#input-domain-bordery').parent().removeClass('has-error'); + } + if (Number.isNaN(borderz)) { + valid = false; + $('#input-domain-borderz').parent().addClass('has-error'); + } else { + $('#input-domain-borderz').parent().removeClass('has-error'); + } + if (Number.isNaN(directionx)) { + valid = false; + $('#input-domain-directionx').parent().addClass('has-error'); + } else { + $('#input-domain-directionx').parent().removeClass('has-error'); + } + if (Number.isNaN(directiony)) { + valid = false; + $('#input-domain-directiony').parent().addClass('has-error'); + } else { + $('#input-domain-directiony').parent().removeClass('has-error'); + } + if (Number.isNaN(directionz)) { + valid = false; + $('#input-domain-directionz').parent().addClass('has-error'); + } else { + $('#input-domain-directionz').parent().removeClass('has-error'); + } + if (valid) { + var position = [positionx, positiony, positionz]; + var border = [borderx, bordery, borderz]; + var direction = [directionx, directiony, directionz]; + spirit.core.createDomain(direction, position, border); + spirit.vfr.updateDirections(); + } + }); + + // -------------------------- + + function updateColormap() { + var colormap = $("option:selected", $('#select-colormap'))[0].value; + spirit.vfr.setColormap(colormap); + } + $('#select-colormap').on('change', updateColormap); + updateColormap(); + + function updateBackgroundColor() { + var backgroundColor = $("option:selected", $('#select-backgroundcolor'))[0].value; + var colors = { + 'white': [1.0, 1.0, 1.0], + 'gray': [0.5, 0.5, 0.5], + 'black': [0.0, 0.0, 0.0] + }; + var boundingBoxColors = { + 'white': [0.0, 0.0, 0.0], + 'gray': [1.0, 1.0, 1.0], + 'black': [1.0, 1.0, 1.0] + }; + spirit.vfr.set_background(colors[backgroundColor]); + spirit.vfr.set_boundingbox_colour(boundingBoxColors[backgroundColor]); + spirit.vfr.draw(); + // console.log("background update", colors[backgroundColor]); + } + $('#select-backgroundcolor').on('change', updateBackgroundColor); + updateBackgroundColor(); + + function updateRenderers() { + var rendermode = $("option:selected", $('#select-rendermode'))[0].value; + var show_miniview = $('#input-show-miniview').is(':checked'); + var show_coordinatesystem = $('#input-show-coordinatesystem').is(':checked'); + var show_boundingbox = $('#input-show-boundingbox').is(':checked'); + var boundingbox_line_width = 0; + var show_dots = $('#input-show-dots').is(':checked'); + var show_arrows = $('#input-show-arrows').is(':checked'); + var show_spheres = $('#input-show-spheres').is(':checked'); + var show_boxes = $('#input-show-boxes').is(':checked'); + var show_isosurface = $('#input-show-isosurface').is(':checked'); + var show_surface = $('#input-show-surface').is(':checked'); + // console.log(rendermode); + + // var coordinateSystemPosition = JSON.parse($("option:selected", $('#select-coordinatesystem-position'))[0].value); + // var miniViewPosition = JSON.parse($("option:selected", $('#select-miniview-position'))[0].value); + var coordinateSystemPosition = $('#select-coordinatesystem-position')[0].selectedIndex; + var miniViewPosition = $('#select-miniview-position')[0].selectedIndex; + + if( rendermode == "SYSTEM" ) + { + spirit.vfr.set_rendermode(0); + } + else + { + spirit.vfr.set_rendermode(1); + } + + spirit.vfr.set_miniview(show_miniview, miniViewPosition); + spirit.vfr.set_coordinatesystem(show_coordinatesystem, coordinateSystemPosition); + spirit.vfr.set_boundingbox(show_boundingbox, boundingbox_line_width); + spirit.vfr.set_dots(show_dots); + spirit.vfr.set_arrows(show_arrows); + spirit.vfr.set_spheres(show_spheres); + spirit.vfr.set_boxes(show_boxes); + spirit.vfr.set_surface(show_surface); + spirit.vfr.set_isosurface(show_isosurface); + + spirit.vfr.draw(); + } + $('#select-rendermode').on('change', updateRenderers); + $('#select-coordinatesystem-position').on('change', updateRenderers); + $('#select-miniview-position').on('change', updateRenderers); + $('#input-show-miniview').on('change', updateRenderers); + $('#input-show-coordinatesystem').on('change', updateRenderers); + $('#input-show-boundingbox').on('change', updateRenderers); + $('#input-show-dots').on('change', updateRenderers); + $('#input-show-arrows').on('change', updateRenderers); + $('#input-show-spheres').on('change', updateRenderers); + $('#input-show-boxes').on('change', updateRenderers); + $('#input-show-surface').on('change', updateRenderers); + $('#input-show-isosurface').on('change', updateRenderers); + updateRenderers(); + + $("#input-zrange-filter").slider(); + function updateZRangeFilter() { + var zRange = $("#input-zrange-filter").slider('getValue'); + spirit.vfr.updateVisibility(zRange); + } + $('#input-zrange-filter').on('change', updateZRangeFilter); + updateZRangeFilter(); + + $("#input-spinspherewidget-pointsize").slider(); + function updateSpherePointSize() { + var pointSizeRange = $("#input-spinspherewidget-pointsize").slider('getValue'); + spirit.vfr.setVectorSphere(pointSizeRange); + } + $('#input-spinspherewidget-pointsize').on('change', updateSpherePointSize); + updateSpherePointSize(); + + if (!VFRendering.isTouchDevice) { + $('#input-use-touch')[0].disabled="disabled"; + $('#input-use-touch')[0].checked = false; + } + + function updateHamiltonianBoundaryConditions() { + var periodical_a = 0; + var periodical_b = 0; + var periodical_c = 0; + if ($('#input-periodical-a')[0].checked) { + periodical_a = 1; + } + if ($('#input-periodical-b')[0].checked) { + periodical_b = 1; + } + if ($('#input-periodical-c')[0].checked) { + periodical_c = 1; + } + spirit.core.updateHamiltonianBoundaryConditions(periodical_a, periodical_b, periodical_c); + var show_boundingbox = $('#input-show-boundingbox').is(':checked'); + var boundingbox_line_width = 0; + spirit.vfr.set_boundingbox(show_boundingbox, boundingbox_line_width); + spirit.vfr.draw(); + } + $('#input-periodical-a').on('change', updateHamiltonianBoundaryConditions); + $('#input-periodical-b').on('change', updateHamiltonianBoundaryConditions); + $('#input-periodical-c').on('change', updateHamiltonianBoundaryConditions); + + function updateHamiltonianMuSpin() { + var muspin = Number($('#input-externalfield-muspin').val()); + var valid = true; + if (Number.isNaN(muspin)) { + valid = false; + $('#input-externalfield-muspin').parent().addClass('has-error'); + } else { + $('#input-externalfield-muspin').parent().removeClass('has-error'); + } + if (valid) { + spirit.core.updateHamiltonianMuSpin(muspin); + } + } + $('#input-externalfield-muspin').on('change', updateHamiltonianMuSpin); + + function updateHamiltonianExternalField() { + if ($('#input-externalfield')[0].checked) { + var magnitude = Number($('#input-externalfield-magnitude').val()); + var normalx = Number($('#input-externalfield-directionx').val()); + var normaly = Number($('#input-externalfield-directiony').val()); + var normalz = Number($('#input-externalfield-directionz').val()); + var valid = true; + if (Number.isNaN(magnitude)) { + valid = false; + $('#input-externalfield-magnitude').parent().addClass('has-error'); + } else { + $('#input-externalfield-magnitude').parent().removeClass('has-error'); + } + if (Number.isNaN(normalx)) { + valid = false; + $('#input-externalfield-directionx').parent().addClass('has-error'); + } else { + $('#input-externalfield-directionx').parent().removeClass('has-error'); + } + if (Number.isNaN(normaly)) { + valid = false; + $('#input-externalfield-directiony').parent().addClass('has-error'); + } else { + $('#input-externalfield-directiony').parent().removeClass('has-error'); + } + if (Number.isNaN(normalz)) { + valid = false; + $('#input-externalfield-directionz').parent().addClass('has-error'); + } else { + $('#input-externalfield-directionz').parent().removeClass('has-error'); + } + if (valid) { + spirit.core.updateHamiltonianExternalField(magnitude, normalx, normaly, normalz); + } + } else { + spirit.core.updateHamiltonianExternalField(0, 0, 0, 1); + } + } + $('#input-externalfield').on('change', updateHamiltonianExternalField); + $('#input-externalfield-magnitude').on('change', updateHamiltonianExternalField); + $('#input-externalfield-directionx').on('change', updateHamiltonianExternalField); + $('#input-externalfield-directiony').on('change', updateHamiltonianExternalField); + $('#input-externalfield-directionz').on('change', updateHamiltonianExternalField); + + function updateHamiltonianExchange() { + if ($('#input-exchange')[0].checked) { + var value1 = Number($('#input-exchangemagnitudes1').val()); + var value2 = Number($('#input-exchangemagnitudes2').val()); + var value3 = Number($('#input-exchangemagnitudes3').val()); + var value4 = Number($('#input-exchangemagnitudes4').val()); + var valid = true; + if (Number.isNaN(value1)) { + valid = false; + $('#input-exchangemagnitudes1').parent().addClass('has-error'); + } else { + $('#input-exchangemagnitudes1').parent().removeClass('has-error'); + } + if (Number.isNaN(value2)) { + valid = false; + $('#input-exchangemagnitudes2').parent().addClass('has-error'); + } else { + $('#input-exchangemagnitudes2').parent().removeClass('has-error'); + } + if (Number.isNaN(value3)) { + valid = false; + $('#input-exchangemagnitudes3').parent().addClass('has-error'); + } else { + $('#input-exchangemagnitudes3').parent().removeClass('has-error'); + } + if (Number.isNaN(value4)) { + valid = false; + $('#input-exchangemagnitudes4').parent().addClass('has-error'); + } else { + $('#input-exchangemagnitudes4').parent().removeClass('has-error'); + } + if (valid) { + spirit.core.updateHamiltonianExchange([value1, value2, value3, value4]); + } + } else { + spirit.core.updateHamiltonianExchange([0]); + } + } + $('#input-exchange').on('change', updateHamiltonianExchange); + $('#input-exchangemagnitudes1').on('change', updateHamiltonianExchange); + $('#input-exchangemagnitudes2').on('change', updateHamiltonianExchange); + $('#input-exchangemagnitudes3').on('change', updateHamiltonianExchange); + $('#input-exchangemagnitudes4').on('change', updateHamiltonianExchange); + + function updateHamiltonianDMI() { + if ($('#input-dmi')[0].checked) { + var dij = Number($('#input-dmi-magnitude').val()); + var valid = true; + if (Number.isNaN(dij)) { + valid = false; + $('#input-dmi-magnitude').parent().addClass('has-error'); + } else { + $('#input-dmi-magnitude').parent().removeClass('has-error'); + } + if (valid) { + spirit.core.updateHamiltonianDMI([dij]); + } + } else { + spirit.core.updateHamiltonianDMI([0]); + } + } + $('#input-dmi').on('change', updateHamiltonianDMI); + $('#input-dmi-magnitude').on('change', updateHamiltonianDMI); + + function updateHamiltonianAnisotropy() { + if ($('#input-anisotropy')[0].checked) { + var magnitude = Number($('#input-anisotropy-magnitude').val()); + var normalx = Number($('#input-anisotropy-directionx').val()); + var normaly = Number($('#input-anisotropy-directiony').val()); + var normalz = Number($('#input-anisotropy-directionz').val()); + var valid = true; + if (Number.isNaN(magnitude)) { + valid = false; + $('#input-anisotropy-magnitude').parent().addClass('has-error'); + } else { + $('#input-anisotropy-magnitude').parent().removeClass('has-error'); + } + if (Number.isNaN(normalx)) { + valid = false; + $('#input-anisotropy-directionx').parent().addClass('has-error'); + } else { + $('#input-anisotropy-directionx').parent().removeClass('has-error'); + } + if (Number.isNaN(normaly)) { + valid = false; + $('#input-anisotropy-directiony').parent().addClass('has-error'); + } else { + $('#input-anisotropy-directiony').parent().removeClass('has-error'); + } + if (Number.isNaN(normalz)) { + valid = false; + $('#input-anisotropy-directionz').parent().addClass('has-error'); + } else { + $('#input-anisotropy-directionz').parent().removeClass('has-error'); + } + if (valid) { + spirit.core.updateHamiltonianAnisotropy(magnitude, normalx, normaly, normalz); + } + } else { + spirit.core.updateHamiltonianAnisotropy(0, 0, 0, 1); + } + } + $('#input-anisotropy').on('change', updateHamiltonianAnisotropy); + $('#input-anisotropy-magnitude').on('change', updateHamiltonianAnisotropy); + $('#input-anisotropy-directionx').on('change', updateHamiltonianAnisotropy); + $('#input-anisotropy-directiony').on('change', updateHamiltonianAnisotropy); + $('#input-anisotropy-directionz').on('change', updateHamiltonianAnisotropy); + + function updateHamiltonianDDI() { + if ($('#input-ddi')[0].checked) { + spirit.core.updateHamiltonianDDI(1, 4); + } + else { + spirit.core.updateHamiltonianDDI(0, 4); + } + } + $('#input-ddi').on('change', updateHamiltonianDDI); + + function updateHamiltonianSpinTorque() { + if ($('#input-spintorque')[0].checked) { + var magnitude = Number($('#input-spintorque-magnitude').val()); + var normalx = Number($('#input-spintorque-directionx').val()); + var normaly = Number($('#input-spintorque-directiony').val()); + var normalz = Number($('#input-spintorque-directionz').val()); + var valid = true; + if (Number.isNaN(magnitude)) { + valid = false; + $('#input-spintorque-magnitude').parent().addClass('has-error'); + } else { + $('#input-spintorque-magnitude').parent().removeClass('has-error'); + } + if (Number.isNaN(normalx)) { + valid = false; + $('#input-spintorque-directionx').parent().addClass('has-error'); + } else { + $('#input-spintorque-directionx').parent().removeClass('has-error'); + } + if (Number.isNaN(normaly)) { + valid = false; + $('#input-spintorque-directiony').parent().addClass('has-error'); + } else { + $('#input-spintorque-directiony').parent().removeClass('has-error'); + } + if (Number.isNaN(normalz)) { + valid = false; + $('#input-spintorque-directionz').parent().addClass('has-error'); + } else { + $('#input-spintorque-directionz').parent().removeClass('has-error'); + } + if (valid) { + spirit.core.updateHamiltonianSpinTorque(magnitude, normalx, normaly, normalz); + } + } else { + spirit.core.updateHamiltonianSpinTorque(0, 0, 0, 1); + } + } + $('#input-spintorque').on('change', updateHamiltonianSpinTorque); + $('#input-spintorque-magnitude').on('change', updateHamiltonianSpinTorque); + $('#input-spintorque-directionx').on('change', updateHamiltonianSpinTorque); + $('#input-spintorque-directiony').on('change', updateHamiltonianSpinTorque); + $('#input-spintorque-directionz').on('change', updateHamiltonianSpinTorque); + + function updateHamiltonianTemperature() { + if ($('#input-temperature')[0].checked) { + var temperature = Number($('#input-temperature-value').val()); + var valid = true; + if (Number.isNaN(temperature)) { + valid = false; + $('#input-temperature-value').parent().addClass('has-error'); + } else { + $('#input-temperature-value').parent().removeClass('has-error'); + } + if (valid) { + spirit.core.updateHamiltonianTemperature(temperature); + } + } else { + spirit.core.updateHamiltonianTemperature(0); + } + } + $('#input-temperature').on('change', updateHamiltonianTemperature); + $('#input-temperature-value').on('change', updateHamiltonianTemperature); + + function updateLLGDamping() { + var damping = Number($('#input-llg-damping').val()); + var valid = true; + if (Number.isNaN(damping)) { + valid = false; + $('#input-llg-damping').parent().addClass('has-error'); + } else { + $('#input-llg-damping').parent().removeClass('has-error'); + } + if (valid) { + spirit.core.updateLLGDamping(damping); + } + } + $('#input-llg-damping').on('change', updateLLGDamping); + + function updateLLGTimeStep() { + var time_step = Number($('#input-llg-timestep').val()); + var valid = true; + if (Number.isNaN(time_step)) { + valid = false; + $('#input-llg-timestep').parent().addClass('has-error'); + } else { + $('#input-llg-timestep').parent().removeClass('has-error'); + } + if (valid) { + spirit.core.updateLLGTimeStep(time_step); + } + } + $('#input-llg-timestep').on('change', updateLLGTimeStep); + + // function updateGNEBSpringConstant() { + // var spring_constant = Number($('#input-gneb-springconst').val()); + // var valid = true; + // if (Number.isNaN(spring_constant)) { + // valid = false; + // $('#input-gneb-springconst').parent().addClass('has-error'); + // } else { + // $('#input-gneb-springconst').parent().removeClass('has-error'); + // } + // if (valid) { + // spirit.core.updateGNEBSpringConstant(spring_constant); + // } + // } + // $('#input-gneb-springconst').on('change', updateGNEBSpringConstant); + + // function updateGNEBClimbingFalling() { + // var climbing = $('#input-gneb-radio-climbing')[0].checked; + // var falling = $('#input-gneb-radio-falling')[0].checked; + // spirit.core.updateGNEBClimbingFalling(climbing, falling); + // } + // $('#input-gneb-radio-normal').on('change', updateGNEBClimbingFalling); + // $('#input-gneb-radio-climbing').on('change', updateGNEBClimbingFalling); + // $('#input-gneb-radio-falling').on('change', updateGNEBClimbingFalling); + + function updateUseTouch() { + var useTouch = $('#input-use-touch')[0].checked; + VFRendering.updateOptions({useTouch: useTouch}); + } + $('#input-use-touch').on('change', updateUseTouch); + + + $('#button-camera-x').on('click', function(e) { + spirit.vfr.align_camera([-1, 0, 0], [0, 0, 1]); + spirit.vfr.draw(); + }); + $('#button-camera-y').on('click', function(e) { + spirit.vfr.align_camera([0, 1, 0], [0, 0, 1]); + spirit.vfr.draw(); + }); + $('#button-camera-z').on('click', function(e) { + spirit.vfr.align_camera([0, 0, -1], [0, 1, 0]); + spirit.vfr.draw(); + }); + + function downloadURI(uri, name) { + var link = document.createElement("a"); + link.download = name; + link.href = uri; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + delete link; + } + + $('#button-screenshot').on('click', function(e) { + spirit.vfr.draw(); + downloadURI(canvas.toDataURL(), "spirit_screenshot.png"); + }); + if (window.File && window.FileReader && window.FileList && window.Blob) { + $('#input-import-ovf').on('change', function (e) { + if (e.target.files.length < 1) { + return; + } + var reader = new FileReader(); + reader.onload = function() { + spirit.core.importOVFData(new Uint8Array(reader.result)); + spirit.vfr.updateDirections(); + }; + reader.readAsArrayBuffer(e.target.files[0]); + }); } else { - return hsv2rgb(vec3(hue, 1.0, 1.0+direction.z)); + $('#input-import-ovf').parent().hide(); } - }`; - function updateColormap() { - var colormap = $("option:selected", $('#select-colormap'))[0].value; - webglspins.updateOptions({ - colormapImplementation: WebGLSpins.colormapImplementations[colormap] - }); - } - $('#select-colormap').on('change', updateColormap); - updateColormap(); - - function updateBackgroundColor() { - var backgroundColor = $("option:selected", $('#select-backgroundcolor'))[0].value; - var colors = { - 'white': [1.0, 1.0, 1.0], - 'gray': [0.5, 0.5, 0.5], - 'black': [0.0, 0.0, 0.0] - }; - var boundingBoxColors = { - 'white': [0.0, 0.0, 0.0], - 'gray': [1.0, 1.0, 1.0], - 'black': [1.0, 1.0, 1.0] - }; - webglspins.updateOptions({ - backgroundColor: colors[backgroundColor], - boundingBoxColor: boundingBoxColors[backgroundColor] - }); - } - $('#select-backgroundcolor').on('change', updateBackgroundColor); - updateBackgroundColor(); - - function updateRenderers() { - var rendermode = $("option:selected", $('#select-rendermode'))[0].value; - var renderers = [WebGLSpins.renderers[rendermode]]; - var showCoordinateSystemWidget = $('#input-show-coordinatesystem').is(':checked'); - if (showCoordinateSystemWidget) { - var coordinateSystemWidgetPosition = JSON.parse($("option:selected", $('#select-coordinatesystemwidget-position'))[0].value); - renderers.push([WebGLSpins.renderers.COORDINATESYSTEM, coordinateSystemWidgetPosition]); - } - var showSphereWidget = $('#input-show-spinspherewidget').is(':checked'); - var innerSphereRadius = 0.95; - if (showSphereWidget) { - var sphereWidgetPosition = JSON.parse($("option:selected", $('#select-spinspherewidget-position'))[0].value); - if (rendermode == 'SPHERE') { - renderers.push([WebGLSpins.renderers.SURFACE, sphereWidgetPosition]); - } else { - renderers.push([WebGLSpins.renderers.SPHERE, sphereWidgetPosition]); - } - } - webglspins.updateOptions({ - renderers: renderers, - innerSphereRadius: innerSphereRadius - }); - } - $('#select-rendermode').on('change', updateRenderers); - $('#input-show-coordinatesystem').on('change', updateRenderers); - $('#select-coordinatesystemwidget-position').on('change', updateRenderers); - $('#input-show-spinspherewidget').on('change', updateRenderers); - $('#select-spinspherewidget-position').on('change', updateRenderers); - updateRenderers(); - - function updateShowBoundingBox() { - var showBoundingBox = $('#input-show-boundingbox')[0].checked; - window.currentSimulation.showBoundingBox = showBoundingBox; - window.currentSimulation.update(); - } - - $('#input-show-boundingbox').on('change', updateShowBoundingBox); - - $('#button-plusz').on('click', function(e) { - var sim = window.currentSimulation; - sim.setAllSpinsPlusZ(); - }); - $('#button-minusz').on('click', function(e) { - var sim = window.currentSimulation; - sim.setAllSpinsMinusZ(); - }); - $('#button-random').on('click', function(e) { - var sim = window.currentSimulation; - sim.setAllSpinsRandom(); - }); - - $('#button-skyrmion-create').on('click', function(e) { - var order = Number($('#input-skyrmion-order').val()); - var phase = Number($('#input-skyrmion-phase').val()); - var radius = Number($('#input-skyrmion-radius').val()); - var positionx = Number($('#input-skyrmion-positionx').val()); - var positiony = Number($('#input-skyrmion-positiony').val()); - var positionz = Number($('#input-skyrmion-positionz').val()); - var updown = $('#input-skyrmion-updown')[0].checked; - var rl = false;//$('#input-skyrmion-rl')[0].checked; - var achiral = $('#input-skyrmion-achiral')[0].checked; - // var exp = $('#input-skyrmion-exp')[0].checked; - var valid = true; - if (Number.isNaN(order)) { - valid = false; - $('#input-skyrmion-order').parent().addClass('has-error'); - } else { - $('#input-skyrmion-order').parent().removeClass('has-error'); - } - if (Number.isNaN(phase)) { - valid = false; - $('#input-skyrmion-phase').parent().addClass('has-error'); - } else { - $('#input-skyrmion-phase').parent().removeClass('has-error'); - } - if (Number.isNaN(radius)) { - valid = false; - $('#input-skyrmion-radius').parent().addClass('has-error'); - } else { - $('#input-skyrmion-radius').parent().removeClass('has-error'); - } - if (Number.isNaN(positionx)) { - valid = false; - $('#input-skyrmion-positionx').parent().addClass('has-error'); - } else { - $('#input-skyrmion-positionx').parent().removeClass('has-error'); - } - if (Number.isNaN(positiony)) { - valid = false; - $('#input-skyrmion-positiony').parent().addClass('has-error'); - } else { - $('#input-skyrmion-positiony').parent().removeClass('has-error'); - } - if (Number.isNaN(positionz)) { - valid = false; - $('#input-skyrmion-positionz').parent().addClass('has-error'); - } else { - $('#input-skyrmion-positionz').parent().removeClass('has-error'); - } - if (valid) { - var position = [positionx, positiony, positionz]; - window.currentSimulation.createSkyrmion(order, phase, radius, position, updown, rl, achiral); - } - }); - - $('#button-spinspiral-create').on('click', function(e) { - var qx = Number($('#input-spinspiral-qx').val()); - var qy = Number($('#input-spinspiral-qy').val()); - var qz = Number($('#input-spinspiral-qz').val()); - var axisx = Number($('#input-spinspiral-axisx').val()); - var axisy = Number($('#input-spinspiral-axisy').val()); - var axisz = Number($('#input-spinspiral-axisz').val()); - var angle = Number($('#input-spinspiral-angle').val()); - var wrt = $("option:selected", $('#select-spinspiral-wrt'))[0].value; - var valid = true; - if (Number.isNaN(qx)) { - valid = false; - $('#input-spinspiral-qx').parent().addClass('has-error'); - } else { - $('#input-spinspiral-qx').parent().removeClass('has-error'); - } - if (Number.isNaN(qy)) { - valid = false; - $('#input-spinspiral-qy').parent().addClass('has-error'); - } else { - $('#input-spinspiral-qy').parent().removeClass('has-error'); - } - if (Number.isNaN(qz)) { - valid = false; - $('#input-spinspiral-qz').parent().addClass('has-error'); - } else { - $('#input-spinspiral-qz').parent().removeClass('has-error'); - } - if (Number.isNaN(axisx)) { - valid = false; - $('#input-spinspiral-axisx').parent().addClass('has-error'); - } else { - $('#input-spinspiral-axisx').parent().removeClass('has-error'); - } - if (Number.isNaN(axisy)) { - valid = false; - $('#input-spinspiral-axisy').parent().addClass('has-error'); - } else { - $('#input-spinspiral-axisy').parent().removeClass('has-error'); - } - if (Number.isNaN(axisz)) { - valid = false; - $('#input-spinspiral-axisz').parent().addClass('has-error'); - } else { - $('#input-spinspiral-axisz').parent().removeClass('has-error'); - } - if (Number.isNaN(angle)) { - valid = false; - $('#input-spinspiral-angle').parent().addClass('has-error'); - } else { - $('#input-spinspiral-angle').parent().removeClass('has-error'); - } - if (valid) { - var q = [qx, qy, qz]; - var axis = [axisx, axisy, axisz]; - window.currentSimulation.createSpinSpiral(wrt, q, axis, angle); - } - }); - - $('#button-domain-create').on('click', function(e) { - var positionx = Number($('#input-domain-positionx').val()); - var positiony = Number($('#input-domain-positiony').val()); - var positionz = Number($('#input-domain-positionz').val()); - var borderx = Number($('#input-domain-borderx').val()); - var bordery = Number($('#input-domain-bordery').val()); - var borderz = Number($('#input-domain-borderz').val()); - var directionx = Number($('#input-domain-directionx').val()); - var directiony = Number($('#input-domain-directiony').val()); - var directionz = Number($('#input-domain-directionz').val()); - // var greater = $('#input-domain-greater')[0].checked; - var valid = true; - if (Number.isNaN(positionx)) { - valid = false; - $('#input-domain-positionx').parent().addClass('has-error'); - } else { - $('#input-domain-positionx').parent().removeClass('has-error'); - } - if (Number.isNaN(positiony)) { - valid = false; - $('#input-domain-positiony').parent().addClass('has-error'); - } else { - $('#input-domain-positiony').parent().removeClass('has-error'); - } - if (Number.isNaN(positionz)) { - valid = false; - $('#input-domain-positionz').parent().addClass('has-error'); - } else { - $('#input-domain-positionz').parent().removeClass('has-error'); - } - if (Number.isNaN(borderx)) { - valid = false; - $('#input-domain-borderx').parent().addClass('has-error'); - } else { - $('#input-domain-borderx').parent().removeClass('has-error'); - } - if (Number.isNaN(bordery)) { - valid = false; - $('#input-domain-bordery').parent().addClass('has-error'); - } else { - $('#input-domain-bordery').parent().removeClass('has-error'); - } - if (Number.isNaN(borderz)) { - valid = false; - $('#input-domain-borderz').parent().addClass('has-error'); - } else { - $('#input-domain-borderz').parent().removeClass('has-error'); - } - if (Number.isNaN(directionx)) { - valid = false; - $('#input-domain-directionx').parent().addClass('has-error'); - } else { - $('#input-domain-directionx').parent().removeClass('has-error'); - } - if (Number.isNaN(directiony)) { - valid = false; - $('#input-domain-directiony').parent().addClass('has-error'); - } else { - $('#input-domain-directiony').parent().removeClass('has-error'); - } - if (Number.isNaN(directionz)) { - valid = false; - $('#input-domain-directionz').parent().addClass('has-error'); - } else { - $('#input-domain-directionz').parent().removeClass('has-error'); - } - if (valid) { - var position = [positionx, positiony, positionz]; - var border = [borderx, bordery, borderz]; - var direction = [directionx, directiony, directionz]; - window.currentSimulation.createDomain(direction, position, border); - } - }); - $("#input-zrange-filter").slider(); - function updateZRangeFilter() { - var zRange = $("#input-zrange-filter").slider('getValue'); - webglspins.updateOptions({ - zRange: zRange - }); - } - $('#input-zrange-filter').on('change', updateZRangeFilter); - updateZRangeFilter(); - - $("#input-spinspherewidget-pointsize").slider(); - function updateSpherePointSize() { - var pointSizeRange = $("#input-spinspherewidget-pointsize").slider('getValue'); - webglspins.updateOptions({ - pointSizeRange: pointSizeRange - }); - } - $('#input-spinspherewidget-pointsize').on('change', updateSpherePointSize); - updateSpherePointSize(); - - function updateHamiltonianBoundaryConditions() { - var periodical_a = 0; - var periodical_b = 0; - var periodical_c = 0; - if ($('#input-periodical-a')[0].checked) { - periodical_a = 1; - } - if ($('#input-periodical-b')[0].checked) { - periodical_b = 1; - } - if ($('#input-periodical-c')[0].checked) { - periodical_c = 1; - } - window.currentSimulation.updateHamiltonianBoundaryConditions(periodical_a, periodical_b, periodical_c); - } - - $('#input-periodical-a').on('change', updateHamiltonianBoundaryConditions); - $('#input-periodical-b').on('change', updateHamiltonianBoundaryConditions); - $('#input-periodical-c').on('change', updateHamiltonianBoundaryConditions); - - function updateHamiltonianMuSpin() { - var muspin = Number($('#input-externalfield-muspin').val()); - var valid = true; - if (Number.isNaN(muspin)) { - valid = false; - $('#input-externalfield-muspin').parent().addClass('has-error'); - } else { - $('#input-externalfield-muspin').parent().removeClass('has-error'); - } - if (valid) { - window.currentSimulation.updateHamiltonianMuSpin(muspin); - } - } - $('#input-externalfield-muspin').on('change', updateHamiltonianMuSpin); - - function updateHamiltonianExternalField() { - if ($('#input-externalfield')[0].checked) { - var magnitude = Number($('#input-externalfield-magnitude').val()); - var normalx = Number($('#input-externalfield-directionx').val()); - var normaly = Number($('#input-externalfield-directiony').val()); - var normalz = Number($('#input-externalfield-directionz').val()); - var valid = true; - if (Number.isNaN(magnitude)) { - valid = false; - $('#input-externalfield-magnitude').parent().addClass('has-error'); - } else { - $('#input-externalfield-magnitude').parent().removeClass('has-error'); - } - if (Number.isNaN(normalx)) { - valid = false; - $('#input-externalfield-directionx').parent().addClass('has-error'); - } else { - $('#input-externalfield-directionx').parent().removeClass('has-error'); - } - if (Number.isNaN(normaly)) { - valid = false; - $('#input-externalfield-directiony').parent().addClass('has-error'); - } else { - $('#input-externalfield-directiony').parent().removeClass('has-error'); - } - if (Number.isNaN(normalz)) { - valid = false; - $('#input-externalfield-directionz').parent().addClass('has-error'); - } else { - $('#input-externalfield-directionz').parent().removeClass('has-error'); - } - if (valid) { - window.currentSimulation.updateHamiltonianExternalField(magnitude, normalx, normaly, normalz); - } - } else { - window.currentSimulation.updateHamiltonianExternalField(0, 0, 0, 1); - } - } - $('#input-externalfield').on('change', updateHamiltonianExternalField); - $('#input-externalfield-magnitude').on('change', updateHamiltonianExternalField); - $('#input-externalfield-directionx').on('change', updateHamiltonianExternalField); - $('#input-externalfield-directiony').on('change', updateHamiltonianExternalField); - $('#input-externalfield-directionz').on('change', updateHamiltonianExternalField); - - function updateHamiltonianExchange() { - if ($('#input-exchange')[0].checked) { - var value1 = Number($('#input-exchangemagnitudes1').val()); - var value2 = Number($('#input-exchangemagnitudes2').val()); - var valid = true; - if (Number.isNaN(value1)) { - valid = false; - $('#input-exchangemagnitudes1').parent().addClass('has-error'); - } else { - $('#input-exchangemagnitudes1').parent().removeClass('has-error'); - } - if (Number.isNaN(value2)) { - valid = false; - $('#input-exchangemagnitudes2').parent().addClass('has-error'); - } else { - $('#input-exchangemagnitudes2').parent().removeClass('has-error'); - } - if (valid) { - window.currentSimulation.updateHamiltonianExchange([value1, value2]); - } - } else { - window.currentSimulation.updateHamiltonianExchange([0, 0]); - } - } - $('#input-exchange').on('change', updateHamiltonianExchange); - $('#input-exchangemagnitudes1').on('change', updateHamiltonianExchange); - $('#input-exchangemagnitudes2').on('change', updateHamiltonianExchange); - - function updateHamiltonianDMI() { - if ($('#input-dmi')[0].checked) { - var dij = Number($('#input-dmi-magnitude').val()); - var valid = true; - if (Number.isNaN(dij)) { - valid = false; - $('#input-dmi-magnitude').parent().addClass('has-error'); - } else { - $('#input-dmi-magnitude').parent().removeClass('has-error'); - } - if (valid) { - window.currentSimulation.updateHamiltonianDMI([dij]); - } - } else { - window.currentSimulation.updateHamiltonianDMI([0]); - } - } - $('#input-dmi').on('change', updateHamiltonianDMI); - $('#input-dmi-magnitude').on('change', updateHamiltonianDMI); - - function updateHamiltonianAnisotropy() { - if ($('#input-anisotropy')[0].checked) { - var magnitude = Number($('#input-anisotropy-magnitude').val()); - var normalx = Number($('#input-anisotropy-directionx').val()); - var normaly = Number($('#input-anisotropy-directiony').val()); - var normalz = Number($('#input-anisotropy-directionz').val()); - var valid = true; - if (Number.isNaN(magnitude)) { - valid = false; - $('#input-anisotropy-magnitude').parent().addClass('has-error'); - } else { - $('#input-anisotropy-magnitude').parent().removeClass('has-error'); - } - if (Number.isNaN(normalx)) { - valid = false; - $('#input-anisotropy-directionx').parent().addClass('has-error'); - } else { - $('#input-anisotropy-directionx').parent().removeClass('has-error'); - } - if (Number.isNaN(normaly)) { - valid = false; - $('#input-anisotropy-directiony').parent().addClass('has-error'); - } else { - $('#input-anisotropy-directiony').parent().removeClass('has-error'); - } - if (Number.isNaN(normalz)) { - valid = false; - $('#input-anisotropy-directionz').parent().addClass('has-error'); - } else { - $('#input-anisotropy-directionz').parent().removeClass('has-error'); - } - if (valid) { - window.currentSimulation.updateHamiltonianAnisotropy(magnitude, normalx, normaly, normalz); - } - } else { - window.currentSimulation.updateHamiltonianAnisotropy(0, 0, 0, 1); - } - } - $('#input-anisotropy').on('change', updateHamiltonianAnisotropy); - $('#input-anisotropy-magnitude').on('change', updateHamiltonianAnisotropy); - $('#input-anisotropy-directionx').on('change', updateHamiltonianAnisotropy); - $('#input-anisotropy-directiony').on('change', updateHamiltonianAnisotropy); - $('#input-anisotropy-directionz').on('change', updateHamiltonianAnisotropy); - - function updateHamiltonianDDI() { - if ($('#input-ddi')[0].checked) { - window.currentSimulation.updateHamiltonianDDI(1, 4); - } - else { - window.currentSimulation.updateHamiltonianDDI(0, 4); - } - } - $('#input-ddi').on('change', updateHamiltonianDDI); - - function updateHamiltonianSpinTorque() { - if ($('#input-spintorque')[0].checked) { - var magnitude = Number($('#input-spintorque-magnitude').val()); - var normalx = Number($('#input-spintorque-directionx').val()); - var normaly = Number($('#input-spintorque-directiony').val()); - var normalz = Number($('#input-spintorque-directionz').val()); - var valid = true; - if (Number.isNaN(magnitude)) { - valid = false; - $('#input-spintorque-magnitude').parent().addClass('has-error'); - } else { - $('#input-spintorque-magnitude').parent().removeClass('has-error'); - } - if (Number.isNaN(normalx)) { - valid = false; - $('#input-spintorque-directionx').parent().addClass('has-error'); - } else { - $('#input-spintorque-directionx').parent().removeClass('has-error'); - } - if (Number.isNaN(normaly)) { - valid = false; - $('#input-spintorque-directiony').parent().addClass('has-error'); - } else { - $('#input-spintorque-directiony').parent().removeClass('has-error'); - } - if (Number.isNaN(normalz)) { - valid = false; - $('#input-spintorque-directionz').parent().addClass('has-error'); - } else { - $('#input-spintorque-directionz').parent().removeClass('has-error'); - } - if (valid) { - window.currentSimulation.updateHamiltonianSpinTorque(magnitude, normalx, normaly, normalz); - } - } else { - window.currentSimulation.updateHamiltonianSpinTorque(0, 0, 0, 1); - } - } - $('#input-spintorque').on('change', updateHamiltonianSpinTorque); - $('#input-spintorque-magnitude').on('change', updateHamiltonianSpinTorque); - $('#input-spintorque-directionx').on('change', updateHamiltonianSpinTorque); - $('#input-spintorque-directiony').on('change', updateHamiltonianSpinTorque); - $('#input-spintorque-directionz').on('change', updateHamiltonianSpinTorque); - - function updateHamiltonianTemperature() { - if ($('#input-temperature')[0].checked) { - var temperature = Number($('#input-temperature-value').val()); - var valid = true; - if (Number.isNaN(temperature)) { - valid = false; - $('#input-temperature-value').parent().addClass('has-error'); - } else { - $('#input-temperature-value').parent().removeClass('has-error'); - } - if (valid) { - window.currentSimulation.updateHamiltonianTemperature(temperature); - } - } else { - window.currentSimulation.updateHamiltonianTemperature(0); - } - } - $('#input-temperature').on('change', updateHamiltonianTemperature); - $('#input-temperature-value').on('change', updateHamiltonianTemperature); - - function updateLLGDamping() { - var damping = Number($('#input-llg-damping').val()); - var valid = true; - if (Number.isNaN(damping)) { - valid = false; - $('#input-llg-damping').parent().addClass('has-error'); - } else { - $('#input-llg-damping').parent().removeClass('has-error'); - } - if (valid) { - window.currentSimulation.updateLLGDamping(damping); - } - } - $('#input-llg-damping').on('change', updateLLGDamping); - - function updateLLGTimeStep() { - var time_step = Number($('#input-llg-timestep').val()); - var valid = true; - if (Number.isNaN(time_step)) { - valid = false; - $('#input-llg-timestep').parent().addClass('has-error'); - } else { - $('#input-llg-timestep').parent().removeClass('has-error'); - } - if (valid) { - window.currentSimulation.updateLLGTimeStep(time_step); - } - } - $('#input-llg-timestep').on('change', updateLLGTimeStep); - - // function updateGNEBSpringConstant() { - // var spring_constant = Number($('#input-gneb-springconst').val()); - // var valid = true; - // if (Number.isNaN(spring_constant)) { - // valid = false; - // $('#input-gneb-springconst').parent().addClass('has-error'); - // } else { - // $('#input-gneb-springconst').parent().removeClass('has-error'); - // } - // if (valid) { - // window.currentSimulation.updateGNEBSpringConstant(spring_constant); - // } - // } - // $('#input-gneb-springconst').on('change', updateGNEBSpringConstant); - - // function updateGNEBClimbingFalling() { - // var climbing = $('#input-gneb-radio-climbing')[0].checked; - // var falling = $('#input-gneb-radio-falling')[0].checked; - // window.currentSimulation.updateGNEBClimbingFalling(climbing, falling); - // } - // $('#input-gneb-radio-normal').on('change', updateGNEBClimbingFalling); - // $('#input-gneb-radio-climbing').on('change', updateGNEBClimbingFalling); - // $('#input-gneb-radio-falling').on('change', updateGNEBClimbingFalling); - - function updateUseTouch() { - var useTouch = $('#input-use-touch')[0].checked; - webglspins.updateOptions({useTouch: useTouch}); - } - $('#input-use-touch').on('change', updateUseTouch); - - - $('#button-camera-x').on('click', function(e) { - webglspins.alignCamera([-1, 0, 0], [0, 0, 1]); - }); - $('#button-camera-y').on('click', function(e) { - webglspins.alignCamera([0, 1, 0], [0, 0, 1]); - }); - $('#button-camera-z').on('click', function(e) { - webglspins.alignCamera([0, 0, -1], [0, 1, 0]); - }); - - var isSimulating = false; - - function updateSimulation(sim){ - window.currentSimulation = sim; - if (!webglspins.isTouchDevice) { - $('#input-use-touch')[0].disabled="disabled"; - $('#input-use-touch')[0].checked = false; - } - sim.update(); - updateShowBoundingBox(); - updateHamiltonianBoundaryConditions(); - updateHamiltonianMuSpin(); - updateHamiltonianExternalField(); - updateHamiltonianExchange(); - updateHamiltonianDMI(); - updateHamiltonianAnisotropy(); - updateHamiltonianDDI(); - updateHamiltonianSpinTorque(); - updateHamiltonianTemperature(); - updateLLGDamping(); - updateLLGTimeStep(); - // updateGNEBSpringConstant(); - // updateGNEBClimbingFalling(); - $('#div-load').hide(); - $( window ).resize(function() { - if (!isSimulating) { - webglspins.draw(); - } - }); - $('.collapse').on('hidden.bs.collapse', function () { - if (!isSimulating) { - webglspins.draw(); - } - }); - $('.collapse').on('shown.bs.collapse', function () { - if (!isSimulating) { - webglspins.draw(); - } - }); - $('#input-show-settings').on('change', function () { - if (!isSimulating) { - webglspins.draw(); - } - }); - function update(sim) { - if (isSimulating) { - sim.performIteration(); - window.requestAnimationFrame(function () { - update(sim) + $('#button-export-ovf').on('click', function(e) { + downloadURI(spirit.core.exportOVFDataURI(), $('#input-export-spins').val()+'.ovf'); }); - } - }; - $("#btn-play").click(function() { - isSimulating = !isSimulating; - $("#btn-play").toggleClass("fa-play fa-pause"); - if (isSimulating) { - sim.startSimulation(); - window.requestAnimationFrame(function () { - update(sim); + + $('#button-export-energy').on('click', function(e) { + spirit.core.System_Update_Data(); + downloadURI(spirit.core.exportEnergyDataURI(), $('#input-export-energy').val()+'.txt'); }); - } - else { - sim.stopSimulation(); - } + + // --------------------------------------------------------------------- + + var url_string = window.location.href; + var url = new URL(url_string); + var example = String(url.searchParams.get("example")); + + // console.log(example); + // console.log(example.localeCompare("racetrack")); + // console.log(example.localeCompare("hopfion")); + + // Default camera + spirit.vfr.set_camera([50, 50, 100], [50, 50, 0], [0, 1, 0]); + + if( example.localeCompare("racetrack") == 0 ) + { + // Geometry + spirit.core.setNCells([120, 30, 1]); + document.getElementById('input-gridsize-x').value = 120; + document.getElementById('input-gridsize-y').value = 30; + document.getElementById('input-gridsize-z').value = 1; + + // Configuration + spirit.core.setAllSpinsPlusZ(); + spirit.core.createSkyrmion(1, -90, 5, [-15, 0, 0], false, false, false); + spirit.core.createSkyrmion(1, -90, 5, [15, 0, 0], false, false, false); + + // Hamiltonian + document.getElementById('input-periodical-a').checked = true; + document.getElementById('input-periodical-b').checked = false; + document.getElementById('input-periodical-c').checked = false; + + // Parameters + document.getElementById('input-spintorque').checked = true; + document.getElementById('input-spintorque-magnitude').value = 0.5; + document.getElementById('input-spintorque-directionx').value = -0.5; + document.getElementById('input-spintorque-directiony').value = 1; + document.getElementById('input-spintorque-directionz').value = 0; + + // Visualisation + document.getElementById('input-show-arrows').checked = false; + document.getElementById('input-show-surface').checked = true; + document.getElementById('select-colormap').value = "bluewhitered"; + spirit.vfr.set_camera([60, 15, 80], [60, 15, 0], [0, 1, 0]); + } + else if( example.localeCompare("hopfion") == 0 ) + { + // Geometry + spirit.core.setNCells([30, 30, 30]); + document.getElementById('input-gridsize-x').value = 30; + document.getElementById('input-gridsize-y').value = 30; + document.getElementById('input-gridsize-z').value = 30; + + // Configuration + spirit.core.setAllSpinsPlusZ(); + spirit.core.createHopfion(5, 1, [0, 0, 0]); + + // Hamiltonian (TODO) + // spirit.core.updateHamiltonianExternalField(5, 0, 0, 1); + // spirit.core.updateHamiltonianAnisotropy(0, 0, 0, 1); + // spirit.core.updateHamiltonianExchange([1, 0, 0, -0.1]); + // spirit.core.updateHamiltonianDMI([0.1]); + document.getElementById('input-periodical-a').checked = true; + document.getElementById('input-periodical-b').checked = true; + document.getElementById('input-periodical-c').checked = true; + document.getElementById('input-externalfield').checked = false; + document.getElementById('input-externalfield-magnitude').value = 0; + document.getElementById('input-externalfield-directionx').value = 0; + document.getElementById('input-externalfield-directiony').value = 0; + document.getElementById('input-externalfield-directionz').value = 1; + document.getElementById('input-anisotropy').checked = false; + document.getElementById('input-anisotropy-magnitude').value = 0; + document.getElementById('input-anisotropy-directionx').value = 0; + document.getElementById('input-anisotropy-directiony').value = 0; + document.getElementById('input-anisotropy-directionz').value = 1; + document.getElementById('input-exchangemagnitudes1').value = 1; + document.getElementById('input-exchangemagnitudes2').value = 0; + document.getElementById('input-exchangemagnitudes3').value = 0; + document.getElementById('input-exchangemagnitudes4').value = -0.25; + document.getElementById('input-dmi').checked = false; + document.getElementById('input-dmi-magnitude').value = 0; + + // Visualisation + document.getElementById('input-show-arrows').checked = false; + document.getElementById('input-show-isosurface').checked = true; + spirit.vfr.set_camera([-25, -25, 50], [15, 15, 15], [0, 0, 1]); + } + else + { + console.log("unknown example: ", example) + } + + // Grid + updateGridSize(); + + // Hamiltonian + updateHamiltonianBoundaryConditions(); + updateHamiltonianMuSpin(); + updateHamiltonianExternalField(); + updateHamiltonianExchange(); + updateHamiltonianDMI(); + updateHamiltonianAnisotropy(); + updateHamiltonianDDI(); + + // Parameters + updateHamiltonianSpinTorque(); + updateHamiltonianTemperature(); + updateLLGDamping(); + updateLLGTimeStep(); + + // Visualisation + updateRenderers(); + updateColormap(); + } + ).then(function() + { + var version = spirit.core.spiritVersion(); + document.getElementById("spirit-version").textContent="Version " + version; + $('#div-load').hide(); }); - sim.updateLLGConvergence(-1); - }; - Module.ready(function() { - new Simulation(updateSimulation); - - var version = window.currentSimulation.spiritVersion(); - document.getElementById("spirit-version").textContent="Version" + version; - }); - $("#btn-extended-controls").click(function() { - $("#webgl-extended-controls").toggleClass("hidden"); - }); }); \ No newline at end of file diff --git a/ui-web/js/vfrendering.js b/ui-web/js/vfrendering.js new file mode 100644 index 000000000..569ff58b0 --- /dev/null +++ b/ui-web/js/vfrendering.js @@ -0,0 +1,337 @@ +"use strict"; + + +function VFRendering(Module, canvas) { + this._canvas = canvas; + this._options = {}; + this._mergeOptions(this._options, VFRendering.defaultOptions); + // this._gl = null; + // this._gl_initialized = false; + // this._renderers = []; + // for (var i = 0; i < this._options.renderers.length; i++) { + // var renderer = this._options.renderers[i]; + // var viewport = [0, 0, 1, 1]; + // if (typeof renderer === typeof []) { + // viewport = renderer[1]; + // renderer = renderer[0]; + // } + // this._renderers.push([new renderer(this), viewport]); + // } + // this._initGLContext(); + // this._instancePositionArray = null; + // this._instanceDirectionArray = null; + + this._currentScale = 1; + this.isTouchDevice = 'ontouchstart' in document.documentElement; + // this._options.useTouch = (this._options.useTouch && this.isTouchDevice); + // if (this.isTouchDevice) { + // this._lastPanDeltaX = 0; + // this._lastPanDeltaY = 0; + // var mc = new Hammer.Manager(canvas, {}); + // mc.add(new Hammer.Pan({ direction: Hammer.DIRECTION_ALL, threshold: 0, pointers: 1})); + // mc.on("pan", this._handlePan.bind(this)); + // mc.add(new Hammer.Pinch({})); + // mc.on("pinchin pinchout pinchmove pinchend", this._handlePinch.bind(this)); + // mc.on("pinchstart", this._handlePinchStart.bind(this)); + // } + this._mouseDown = false; + this._lastMouseX = null; + this._lastMouseY = null; + + this._createBindings(Module); + + canvas.addEventListener('mousewheel', this._handleMouseScroll.bind(this)); + canvas.addEventListener('DOMMouseScroll', this._handleMouseScroll.bind(this)); + canvas.addEventListener('mousedown', this._handleMouseDown.bind(this)); + canvas.addEventListener('mousemove', this._handleMouseMove.bind(this)); + document.addEventListener('mouseup', this._handleMouseUp.bind(this)); +} + +VFRendering.defaultOptions = {}; +VFRendering.defaultOptions.verticalFieldOfView = 45; +VFRendering.defaultOptions.allowCameraMovement = true; +// VFRendering.defaultOptions.colormapImplementation = VFRendering.colormapImplementations['red']; +VFRendering.defaultOptions.cameraLocation = [50, 50, 100]; +VFRendering.defaultOptions.centerLocation = [50, 50, 0]; +VFRendering.defaultOptions.upVector = [0, 0, 1]; +VFRendering.defaultOptions.backgroundColor = [0.5, 0.5, 0.5]; +VFRendering.defaultOptions.zRange = [-1, 1]; +VFRendering.defaultOptions.boundingBox = null; +VFRendering.defaultOptions.boundingBoxColor = [1, 1, 1]; +VFRendering.defaultOptions.useTouch = true; + +VFRendering.prototype._mergeOptions = function(options, defaultOptions) { + this._options = {}; + for (var option in defaultOptions) { + this._options[option] = defaultOptions[option]; + } + for (var option in options) { + if (defaultOptions.hasOwnProperty(option)) { + this._options[option] = options[option]; + } else { + console.warn("VFRendering does not recognize option '" + option +"'."); + } + } +}; + +VFRendering.prototype._createBindings = function(Module) { + Module._initialize(); + // Module._draw(); + + Module.draw = Module.cwrap('draw'); + VFRendering.prototype._draw = function() { + Module.draw(); + }; + + // Module.set_camera = Module.cwrap('set_camera'); + VFRendering.prototype.set_camera = function(position, center, up) { + position = new Float32Array(position); + var position_ptr = Module._malloc(position.length * position.BYTES_PER_ELEMENT); + Module.HEAPF32.set(position, position_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + center = new Float32Array(center); + var center_ptr = Module._malloc(center.length * center.BYTES_PER_ELEMENT); + Module.HEAPF32.set(center, center_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + up = new Float32Array(up); + var up_ptr = Module._malloc(up.length * up.BYTES_PER_ELEMENT); + Module.HEAPF32.set(up, up_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + Module._set_camera(position_ptr, center_ptr, up_ptr); + }; + + VFRendering.prototype.align_camera = function(direction, up) { + direction = new Float32Array(direction); + var direction_ptr = Module._malloc(direction.length * direction.BYTES_PER_ELEMENT); + Module.HEAPF32.set(direction, direction_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + up = new Float32Array(up); + var up_ptr = Module._malloc(up.length * up.BYTES_PER_ELEMENT); + Module.HEAPF32.set(up, up_ptr/Module.HEAPF32.BYTES_PER_ELEMENT); + Module._align_camera(direction_ptr, up_ptr); + }; + + // ----------------------- Functions + + VFRendering.prototype.draw = function() { + var width = this._canvas.clientWidth; + var height = this._canvas.clientHeight; + this._canvas.width = width; + this._canvas.height = height; + Module._draw(); + } + + VFRendering.prototype.updateDirections = function(directions_ptr) { + Module._update_directions(directions_ptr); + Module._draw(); + } + + // ----------------------- Handlers + + VFRendering.prototype._handleMouseDown = function(event) { + // if (this._options.useTouch) return; + if (!this._options.allowCameraMovement) { + return; + } + this._mouseDown = true; + this._lastMouseX = event.clientX; + this._lastMouseY = event.clientY; + }; + + VFRendering.prototype._handleMouseUp = function(event) { + // if (this._options.useTouch) return; + this._mouseDown = false; + }; + + VFRendering.prototype._handleMouseMove = function(event) { + // console.log(event); + // if (this._options.useTouch) return; + if (!this._options.allowCameraMovement) { + return; + } + if (!this._mouseDown) { + return; + } + var newX = event.clientX; + var newY = event.clientY; + var deltaX = newX - this._lastMouseX; + var deltaY = newY - this._lastMouseY; + // if (event.shiftKey) + // { + // this.zoom(deltaY > 0 ? 1 : -1); + // } + // else + // { + // var forwardVector = VFRendering._difference(this._options.centerLocation, this._options.cameraLocation); + // var cameraDistance = VFRendering._length(forwardVector); + // forwardVector = VFRendering._normalize(forwardVector); + // this._options.upVector = VFRendering._normalize(this._options.upVector); + // var rightVector = VFRendering._cross(forwardVector, this._options.upVector); + // this._options.upVector = VFRendering._cross(rightVector, forwardVector); + // this._options.upVector = VFRendering._normalize(this._options.upVector); + // if (event.altKey) { + // var translation = [ + // (deltaY / 100 * this._options.upVector[0] - deltaX / 100 * rightVector[0])*cameraDistance*0.1, + // (deltaY / 100 * this._options.upVector[1] - deltaX / 100 * rightVector[1])*cameraDistance*0.1, + // (deltaY / 100 * this._options.upVector[2] - deltaX / 100 * rightVector[2])*cameraDistance*0.1]; + // this._options.cameraLocation[0] += translation[0]; + // this._options.cameraLocation[1] += translation[1]; + // this._options.cameraLocation[2] += translation[2]; + // this._options.centerLocation[0] += translation[0]; + // this._options.centerLocation[1] += translation[1]; + // this._options.centerLocation[2] += translation[2]; + // } else { + // this._rotationHelper(deltaX, deltaY); + // } + // } + var prev = Module._malloc(2*Module.HEAPF32.BYTES_PER_ELEMENT); + var na_ptr = prev+0*Module.HEAPF32.BYTES_PER_ELEMENT; + var nb_ptr = prev+1*Module.HEAPF32.BYTES_PER_ELEMENT; + Module.HEAPF32[na_ptr/Module.HEAPF32.BYTES_PER_ELEMENT] = this._lastMouseX; + Module.HEAPF32[nb_ptr/Module.HEAPF32.BYTES_PER_ELEMENT] = this._lastMouseY; + var current = Module._malloc(2*Module.HEAPF32.BYTES_PER_ELEMENT); + var na_ptr = current+0*Module.HEAPF32.BYTES_PER_ELEMENT; + var nb_ptr = current+1*Module.HEAPF32.BYTES_PER_ELEMENT; + Module.HEAPF32[na_ptr/Module.HEAPF32.BYTES_PER_ELEMENT] = newX; + Module.HEAPF32[nb_ptr/Module.HEAPF32.BYTES_PER_ELEMENT] = newY; + + Module._mouse_move(prev, current, 1); + this.draw(); + this._lastMouseX = newX; + this._lastMouseY = newY; + // console.log(newX); + // console.log(newY); + // this.draw(); + }; + + VFRendering.prototype._handleMouseScroll = function(event) { + // if (this._options.useTouch) return; + if (!this._options.allowCameraMovement) { + return; + } + var scale = 10; + if (event.shiftKey) + { + scale = 1; + } + var delta = Math.max(-1, Math.min(1, (event.wheelDelta || -event.detail))); + Module._mouse_scroll(delta, scale); + this.draw(); + }; +}; + +// Module_VFR().then(function(Module) { +// Module_VFR.ready(function() { + + + + // // ----------------------- Linear Algebra Utilities --------------------------- + + // VFRendering._difference = function(a, b) { + // return [ + // a[0]-b[0], + // a[1]-b[1], + // a[2]-b[2] + // ]; + // }; + + // VFRendering._length = function(a) { + // return Math.sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]); + // }; + + // VFRendering._normalize = function(a) { + // var length = VFRendering._length(a); + // return [a[0]/length, a[1]/length, a[2]/length]; + // }; + + // VFRendering._dot = function(a, b) { + // return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + // }; + + // VFRendering._cross = function(a, b) { + // return [ + // a[1]*b[2]-a[2]*b[1], + // a[2]*b[0]-a[0]*b[2], + // a[0]*b[1]-a[1]*b[0] + // ]; + // }; + + // VFRendering._rotationMatrix = function(axis, angle) { + // var c = Math.cos(Math.PI * angle / 180); + // var s = Math.sin(Math.PI * angle / 180); + // var x = axis[0]; + // var y = axis[1]; + // var z = axis[2]; + // return [ + // [x*x*(1-c)+c, x*y*(1-c)-z*s, x*z*(1-c)+y*s, 0], + // [x*y*(1-c)+z*s, y*y*(1-c)+c, z*y*(1-c)-x*s, 0], + // [x*z*(1-c)-y*s, z*y*(1-c)+x*s, z*z*(1-c)+c,0], + // [0, 0, 0, 1] + // ]; + // }; + + // VFRendering._matrixMultiply = function(matrix, vector) { + // var result = [0, 0, 0]; + // for(var i = 0; i < 3; i++) { + // for(var j = 0; j < 3; j++) { + // result[i] += matrix[i][j]*vector[j]; + // } + // result[i] += matrix[i][3]; + // } + // return result; + // }; + + // VFRendering._perspectiveProjectionMatrix = function(verticalFieldOfView, aspectRatio, zNear, zFar) { + // var f = 1.0/Math.tan(verticalFieldOfView*Math.PI/180/2); + // if (aspectRatio < 1.0) { + // f *= aspectRatio; + // } + // return [ + // [f/aspectRatio, 0, 0, 0], + // [0, f, 0, 0], + // [0, 0, (zNear+zFar)/(zNear-zFar), 2*zFar*zNear/(zNear-zFar)], + // [0, 0, -1, 0] + // ]; + // }; + + // VFRendering._orthographicProjectionMatrix = function(left, right, bottom, top, near, far) { + // var sx = 2.0/(right-left); + // var sy = 2.0/(top-bottom); + // var sz = 2.0/(far-near); + // var tx = (right+left)/(right-left); + // var ty = (top+bottom)/(top-bottom); + // var tz = (far+near)/(far-near); + // return [ + // [sx, 0, 0, tx], + // [0, sy, 0, ty], + // [0, 0, sz, tz], + // [0, 0, 0, 1] + // ]; + // } + + // VFRendering._lookAtMatrix = function(cameraLocation, centerLocation, upVector) { + // var forwardVector = VFRendering._difference(centerLocation, cameraLocation); + // forwardVector = VFRendering._normalize(forwardVector); + // upVector = VFRendering._normalize(upVector); + // var rightVector = VFRendering._cross(forwardVector, upVector); + // rightVector = VFRendering._normalize(rightVector); + // upVector = VFRendering._cross(rightVector, forwardVector); + // var matrix = [ + // [rightVector[0], rightVector[1], rightVector[2], 0], + // [upVector[0], upVector[1], upVector[2], 0], + // [-forwardVector[0], -forwardVector[1], -forwardVector[2], 0], + // [0, 0, 0, 1] + // ]; + // var translationVector = VFRendering._matrixMultiply(matrix, cameraLocation); + // matrix[0][3] = -translationVector[0]; + // matrix[1][3] = -translationVector[1]; + // matrix[2][3] = -translationVector[2]; + // return matrix; + // }; + + // VFRendering._toFloat32Array = function(matrix) { + // return new Float32Array([ + // matrix[0][0], matrix[1][0], matrix[2][0], matrix[3][0], + // matrix[0][1], matrix[1][1], matrix[2][1], matrix[3][1], + // matrix[0][2], matrix[1][2], matrix[2][2], matrix[3][2], + // matrix[0][3], matrix[1][3], matrix[2][3], matrix[3][3] + // ]); + // }; +// }); + diff --git a/ui-web/js/webglspins.js b/ui-web/js/webglspins.js deleted file mode 100644 index 449250814..000000000 --- a/ui-web/js/webglspins.js +++ /dev/null @@ -1,1595 +0,0 @@ -"use strict"; - -function WebGLSpins(canvas, options) { - this._canvas = canvas; - this._options = {}; - this._mergeOptions(options, WebGLSpins.defaultOptions); - this._gl = null; - this._gl_initialized = false; - this._renderers = []; - for (var i = 0; i < this._options.renderers.length; i++) { - var renderer = this._options.renderers[i]; - var viewport = [0, 0, 1, 1]; - if (typeof renderer === typeof []) { - viewport = renderer[1]; - renderer = renderer[0]; - } - this._renderers.push([new renderer(this), viewport]); - } - this._initGLContext(); - this._instancePositionArray = null; - this._instanceDirectionArray = null; - - this._currentScale = 1; - this.isTouchDevice = 'ontouchstart' in document.documentElement; - this._options.useTouch = (this._options.useTouch && this.isTouchDevice); - if (this.isTouchDevice) { - this._lastPanDeltaX = 0; - this._lastPanDeltaY = 0; - var mc = new Hammer.Manager(canvas, {}); - mc.add(new Hammer.Pan({ direction: Hammer.DIRECTION_ALL, threshold: 0, pointers: 1})); - mc.on("pan", this._handlePan.bind(this)); - mc.add(new Hammer.Pinch({})); - mc.on("pinchin pinchout pinchmove pinchend", this._handlePinch.bind(this)); - mc.on("pinchstart", this._handlePinchStart.bind(this)); - } - this._mouseDown = false; - this._lastMouseX = null; - this._lastMouseY = null; - canvas.addEventListener('mousewheel', this._handleMouseScroll.bind(this)); - canvas.addEventListener('DOMMouseScroll', this._handleMouseScroll.bind(this)); - canvas.addEventListener('mousedown', this._handleMouseDown.bind(this)); - canvas.addEventListener('mousemove', this._handleMouseMove.bind(this)); - document.addEventListener('mouseup', this._handleMouseUp.bind(this)); -} - -WebGLSpins.colormapImplementations = { - 'red': ` - vec3 colormap(vec3 direction) { - return vec3(1.0, 0.0, 0.0); - }`, - 'bluered': ` - vec3 colormap(vec3 direction) { - vec3 color_down = vec3(0.0, 0.0, 1.0); - vec3 color_up = vec3(1.0, 0.0, 0.0); - return mix(color_down, color_up, direction.z*0.5+0.5); - }`, - 'hue': ` - float atan2(float y, float x) { - return x == 0.0 ? sign(y)*3.14159/2.0 : atan(y, x); - } - vec3 hsv2rgb(vec3 c) { - vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); - vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); - return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); - } - vec3 colormap(vec3 direction) { - vec2 xy = normalize(direction.yz); - float hue = atan2(xy.x, xy.y) / 3.14159 / 2.0; - return hsv2rgb(vec3(hue, 1.0, 1.0)); - }`, - 'bluegreenred': ` - float atan2(float y, float x) { - return x == 0.0 ? sign(y)*3.14159/2.0 : atan(y, x); - } - vec3 hsv2rgb(vec3 c) { - vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); - vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); - return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); - } - - vec3 colormap(vec3 direction) { - float hue = 1.0/3.0-normalize(direction).z/3.0; - return hsv2rgb(vec3(hue, 1.0, 1.0)); - }`, - 'bluewhitered': ` - vec3 colormap(vec3 direction) { - if (direction.z < 0.0) { - vec3 color_down = vec3(0.0, 0.0, 1.0); - vec3 color_up = vec3(1.0, 1.0, 1.0); - return mix(color_down, color_up, direction.z+1.0); - } else { - vec3 color_down = vec3(1.0, 1.0, 1.0); - vec3 color_up = vec3(1.0, 0.0, 0.0); - return mix(color_down, color_up, direction.z); - } - }` -}; - -WebGLSpins.renderers = {}; - -WebGLSpins.defaultOptions = {}; -WebGLSpins.defaultOptions.verticalFieldOfView = 45; -WebGLSpins.defaultOptions.allowCameraMovement = true; -WebGLSpins.defaultOptions.colormapImplementation = WebGLSpins.colormapImplementations['red']; -WebGLSpins.defaultOptions.cameraLocation = [0, 0, 1]; -WebGLSpins.defaultOptions.centerLocation = [0, 0, 0]; -WebGLSpins.defaultOptions.upVector = [0, 1, 0]; -WebGLSpins.defaultOptions.backgroundColor = [0, 0, 0]; -WebGLSpins.defaultOptions.zRange = [-1, 1]; -WebGLSpins.defaultOptions.boundingBox = null; -WebGLSpins.defaultOptions.boundingBoxColor = [1, 1, 1]; -WebGLSpins.defaultOptions.useTouch = true; - -WebGLSpins.prototype.updateOptions = function(options) { - var changedOptions = []; - for (var option in options) { - if (this._options.hasOwnProperty(option)) { - if (this._options[option] !== options[option]) { - this._options[option] = options[option]; - changedOptions.push(option); - } - } else { - console.warn("WebGLSpins does not recognize option '" + option +"'."); - } - } - if (changedOptions.length == 0) { - return; - } - if (changedOptions.indexOf('renderers') != -1) { - for (var i = 0; i < this._renderers.length; i++) { - this._renderers[i][0].cleanup(); - } - this._renderers = []; - for (var i = 0; i < this._options.renderers.length; i++) { - var renderer = this._options.renderers[i]; - var viewport = [0, 0, 1, 1]; - if (typeof renderer === typeof []) { - viewport = renderer[1]; - renderer = renderer[0]; - } - this._renderers.push([new renderer(this), viewport]); - } - } else { - for (var i = 0; i < this._renderers.length; i++) { - this._renderers[i][0].optionsHaveChanged(changedOptions); - } - } - this.draw(); -}; - -WebGLSpins.prototype.updateSpins = function(instancePositions, instanceDirections) { - var gl = this._gl; - this._instancePositionArray = new Float32Array(instancePositions); - this._instanceDirectionArray = new Float32Array(instanceDirections); - if (this._instancePositionArray.length != this._instanceDirectionArray.length) { - console.error("instancePositions and instanceDirections need to be of equal length"); - return; - } - if ((this._instancePositionArray.length % 3) != 0) { - console.error("The length of instancePositions and instanceDirections needs to be a multiple of 3"); - return; - } - for (var i = 0; i < this._renderers.length; i++) { - this._renderers[i][0].updateSpins(this._instancePositionArray, this._instanceDirectionArray); - } - this.draw(); -}; - -WebGLSpins.prototype.draw = function() { - var gl = this._gl; - // Adjust framebuffer resolution to canvas resolution - var width = this._canvas.clientWidth; - var height = this._canvas.clientHeight; - this._canvas.width = width; - this._canvas.height = height; - gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); - // Redraw - gl.clearColor(this._options.backgroundColor[0], this._options.backgroundColor[1], this._options.backgroundColor[2], 1.0); - gl.clear(gl.COLOR_BUFFER_BIT); - - for (var i = 0; i < this._renderers.length; i++) { - gl.viewport( - gl.drawingBufferWidth*this._renderers[i][1][0], - gl.drawingBufferHeight*this._renderers[i][1][1], - gl.drawingBufferWidth*this._renderers[i][1][2], - gl.drawingBufferHeight*this._renderers[i][1][3]); - gl.clear(gl.DEPTH_BUFFER_BIT); - this._renderers[i][0].draw( - gl.drawingBufferWidth*this._renderers[i][1][2], - gl.drawingBufferHeight*this._renderers[i][1][3] - ); - } -}; - -WebGLSpins.prototype._mergeOptions = function(options, defaultOptions) { - this._options = {}; - for (var option in defaultOptions) { - this._options[option] = defaultOptions[option]; - } - for (var option in options) { - if (defaultOptions.hasOwnProperty(option)) { - this._options[option] = options[option]; - } else { - console.warn("WebGLSpins does not recognize option '" + option +"'."); - } - } -}; - -WebGLSpins.prototype._initGLContext = function() { - var gl = null; - try { - gl = this._canvas.getContext("webgl") || this._canvas.getContext("experimental-webgl"); - } catch (e) { - } - if (!gl) { - console.error("WebGLSpins was unable to initialize WebGL."); - return; - } - this._gl = gl; - - gl.enable(gl.DEPTH_TEST); - gl.depthFunc(gl.LEQUAL); - gl.enable(gl.CULL_FACE); - - for (var i = 0; i < this._renderers.length; i++) { - this._renderers[i][0].initGLContext(); - } - - this._gl_initialized = true; -}; - - -WebGLSpins._createProgram = function(gl, vertexShaderSource, fragmentShaderSource, attributes) { - - var vertexShader = gl.createShader(gl.VERTEX_SHADER); - gl.shaderSource(vertexShader, vertexShaderSource); - gl.compileShader(vertexShader); - if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) { - console.error("vertex shader info log:\n" + gl.getShaderInfoLog(vertexShader)); - return null; - } - - var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); - gl.shaderSource(fragmentShader, fragmentShaderSource); - gl.compileShader(fragmentShader); - if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) { - console.error("fragment shader info log:\n" + gl.getShaderInfoLog(fragmentShader)); - return null; - } - - var program = gl.createProgram(); - gl.attachShader(program, vertexShader); - gl.attachShader(program, fragmentShader); - for (var i = 0; i < attributes.length; i++) { - gl.bindAttribLocation(program, i, attributes[i]); - } - gl.linkProgram(program); - gl.deleteShader(vertexShader); - gl.deleteShader(fragmentShader); - - if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { - console.error("program info log:\n" + gl.getProgramInfoLog(program)); - return null; - } - return program; -}; - - -// ---------------------------- Camera Movement ------------------------------- - -WebGLSpins.prototype.alignCamera = function(forward, up) { - var forwardVector = WebGLSpins._difference(this._options.centerLocation, this._options.cameraLocation); - var cameraDistance = WebGLSpins._length(forwardVector); - - forwardVector = WebGLSpins._normalize(forward); - this._options.upVector = WebGLSpins._normalize(up); - var rightVector = WebGLSpins._cross(forwardVector, this._options.upVector); - this._options.upVector = WebGLSpins._cross(rightVector, forwardVector); - this._options.upVector = WebGLSpins._normalize(this._options.upVector); - this._options.cameraLocation[0] = this._options.centerLocation[0] - cameraDistance * forwardVector[0]; - this._options.cameraLocation[1] = this._options.centerLocation[1] - cameraDistance * forwardVector[1]; - this._options.cameraLocation[2] = this._options.centerLocation[2] - cameraDistance * forwardVector[2]; - this.draw(); -}; - -WebGLSpins.prototype._rotationHelper = function(deltaX, deltaY) { - var forwardVector = WebGLSpins._difference(this._options.centerLocation, this._options.cameraLocation); - var cameraDistance = WebGLSpins._length(forwardVector); - forwardVector = WebGLSpins._normalize(forwardVector); - this._options.upVector = WebGLSpins._normalize(this._options.upVector); - var rightVector = WebGLSpins._cross(forwardVector, this._options.upVector); - this._options.upVector = WebGLSpins._cross(rightVector, forwardVector); - this._options.upVector = WebGLSpins._normalize(this._options.upVector); - - var l = Math.sqrt(deltaX * deltaX + deltaY * deltaY); - if (l > 0) { - if (false) - { - var axis = [ - deltaX / l * this._options.upVector[0] + deltaY / l * rightVector[0], - deltaX / l * this._options.upVector[1] + deltaY / l * rightVector[1], - deltaX / l * this._options.upVector[2] + deltaY / l * rightVector[2]]; - var rotationMatrix = WebGLSpins._rotationMatrix(axis, -0.1 * l); - forwardVector = WebGLSpins._matrixMultiply(rotationMatrix, forwardVector); - this._options.upVector = WebGLSpins._matrixMultiply(rotationMatrix, this._options.upVector); - this._options.cameraLocation[0] = this._options.centerLocation[0] - cameraDistance * forwardVector[0]; - this._options.cameraLocation[1] = this._options.centerLocation[1] - cameraDistance * forwardVector[1]; - this._options.cameraLocation[2] = this._options.centerLocation[2] - cameraDistance * forwardVector[2]; - } - else - { - var zaxis = [0,0,1]; - rightVector = [ - rightVector[0] - zaxis[0]*WebGLSpins._dot(zaxis, rightVector), - rightVector[1] - zaxis[1]*WebGLSpins._dot(zaxis, rightVector), - rightVector[2] - zaxis[2]*WebGLSpins._dot(zaxis, rightVector)]; - this._options.upVector = [ - this._options.upVector[0] - rightVector[0]*WebGLSpins._dot(rightVector, this._options.upVector), - this._options.upVector[1] - rightVector[1]*WebGLSpins._dot(rightVector, this._options.upVector), - this._options.upVector[2] - rightVector[2]*WebGLSpins._dot(rightVector, this._options.upVector)]; - forwardVector = [ - forwardVector[0] - rightVector[0]*WebGLSpins._dot(rightVector, forwardVector), - forwardVector[1] - rightVector[1]*WebGLSpins._dot(rightVector, forwardVector), - forwardVector[2] - rightVector[2]*WebGLSpins._dot(rightVector, forwardVector)]; - var axis = [ - deltaX / l * zaxis[0] + deltaY / l * rightVector[0], - deltaX / l * zaxis[1] + deltaY / l * rightVector[1], - deltaX / l * zaxis[2] + deltaY / l * rightVector[2]]; - var rotationMatrix = WebGLSpins._rotationMatrix(axis, -0.1 * l); - forwardVector = WebGLSpins._matrixMultiply(rotationMatrix, forwardVector); - this._options.upVector = WebGLSpins._matrixMultiply(rotationMatrix, this._options.upVector); - this._options.cameraLocation[0] = this._options.centerLocation[0] - cameraDistance * forwardVector[0]; - this._options.cameraLocation[1] = this._options.centerLocation[1] - cameraDistance * forwardVector[1]; - this._options.cameraLocation[2] = this._options.centerLocation[2] - cameraDistance * forwardVector[2]; - } - } - - this.draw(); -}; - -WebGLSpins.prototype._handlePinch = function(event) { - if (!this._options.useTouch) return; - var forwardVector = WebGLSpins._difference(this._options.centerLocation, this._options.cameraLocation); - var cameraDistance = WebGLSpins._length(forwardVector); - var newCameraDistance = 1/event.scale * this._currentScale; - if (newCameraDistance < 2) { - newCameraDistance = 2; - } - this._options.cameraLocation[0] = this._options.centerLocation[0] - newCameraDistance/cameraDistance * forwardVector[0]; - this._options.cameraLocation[1] = this._options.centerLocation[1] - newCameraDistance/cameraDistance * forwardVector[1]; - this._options.cameraLocation[2] = this._options.centerLocation[2] - newCameraDistance/cameraDistance * forwardVector[2]; - this.draw(); -}; - -WebGLSpins.prototype._handlePinchStart = function(event) { - if (!this._options.useTouch) return; - var forwardVector = WebGLSpins._difference(this._options.centerLocation, this._options.cameraLocation); - var cameraDistance = WebGLSpins._length(forwardVector); - this._currentScale = cameraDistance; -}; - -WebGLSpins.prototype._handlePan = function(event) { - if (!this._options.useTouch) return; - var deltaX = event.deltaX; - var deltaY = event.deltaY; - if (!event.isFirst) { - deltaX -= this._lastPanDeltaX; - deltaY -= this._lastPanDeltaY; - } - if (deltaX != 0 && deltaY != 0) { - if (event.pointers.length == 1) { - this._rotationHelper(2*deltaX, 2*deltaY); - } - } - if (event.isFinal) { - this._lastPanDeltaX = 0; - this._lastPanDeltaY = 0; - } else { - this._lastPanDeltaX = event.deltaX; - this._lastPanDeltaY = event.deltaY; - } -}; - -WebGLSpins.prototype._handleMouseDown = function(event) { - if (this._options.useTouch) return; - if (!this._options.allowCameraMovement) { - return; - } - this._mouseDown = true; - this._lastMouseX = event.clientX; - this._lastMouseY = event.clientY; -}; - -WebGLSpins.prototype._handleMouseUp = function(event) { - if (this._options.useTouch) return; - this._mouseDown = false; -}; - -WebGLSpins.prototype._handleMouseMove = function(event) { - if (this._options.useTouch) return; - if (!this._options.allowCameraMovement) { - return; - } - if (!this._mouseDown) { - return; - } - var newX = event.clientX; - var newY = event.clientY; - var deltaX = newX - this._lastMouseX; - var deltaY = newY - this._lastMouseY; - if (event.shiftKey) { - this.zoom(deltaY > 0 ? 1 : -1); - } else { - var forwardVector = WebGLSpins._difference(this._options.centerLocation, this._options.cameraLocation); - var cameraDistance = WebGLSpins._length(forwardVector); - forwardVector = WebGLSpins._normalize(forwardVector); - this._options.upVector = WebGLSpins._normalize(this._options.upVector); - var rightVector = WebGLSpins._cross(forwardVector, this._options.upVector); - this._options.upVector = WebGLSpins._cross(rightVector, forwardVector); - this._options.upVector = WebGLSpins._normalize(this._options.upVector); - if (event.altKey) { - var translation = [ - (deltaY / 100 * this._options.upVector[0] - deltaX / 100 * rightVector[0])*cameraDistance*0.1, - (deltaY / 100 * this._options.upVector[1] - deltaX / 100 * rightVector[1])*cameraDistance*0.1, - (deltaY / 100 * this._options.upVector[2] - deltaX / 100 * rightVector[2])*cameraDistance*0.1]; - this._options.cameraLocation[0] += translation[0]; - this._options.cameraLocation[1] += translation[1]; - this._options.cameraLocation[2] += translation[2]; - this._options.centerLocation[0] += translation[0]; - this._options.centerLocation[1] += translation[1]; - this._options.centerLocation[2] += translation[2]; - } else { - this._rotationHelper(deltaX, deltaY); - } - } - this._lastMouseX = newX; - this._lastMouseY = newY; - this.draw(); -}; - -WebGLSpins.prototype._handleMouseScroll = function(event) { - if (this._options.useTouch) return; - if (!this._options.allowCameraMovement) { - return; - } - var delta = Math.max(-1, Math.min(1, (event.wheelDelta || -event.detail))); - this.zoom(delta); -}; - -WebGLSpins.prototype.zoom = function(delta) { - if (!this._options.allowCameraMovement) { - return; - } - var forwardVector = WebGLSpins._difference(this._options.centerLocation, this._options.cameraLocation); - var cameraDistance = WebGLSpins._length(forwardVector); - if (cameraDistance < 2 && delta < 1) { - return; - } - this._options.cameraLocation[0] = this._options.centerLocation[0] - (1+0.02*delta) * forwardVector[0]; - this._options.cameraLocation[1] = this._options.centerLocation[1] - (1+0.02*delta) * forwardVector[1]; - this._options.cameraLocation[2] = this._options.centerLocation[2] - (1+0.02*delta) * forwardVector[2]; - this.draw(); -}; - - -// ----------------------- Linear Algebra Utilities --------------------------- - -WebGLSpins._difference = function(a, b) { - return [ - a[0]-b[0], - a[1]-b[1], - a[2]-b[2] - ]; -}; - -WebGLSpins._length = function(a) { - return Math.sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]); -}; - -WebGLSpins._normalize = function(a) { - var length = WebGLSpins._length(a); - return [a[0]/length, a[1]/length, a[2]/length]; -}; - -WebGLSpins._dot = function(a, b) { - return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] -}; - -WebGLSpins._cross = function(a, b) { - return [ - a[1]*b[2]-a[2]*b[1], - a[2]*b[0]-a[0]*b[2], - a[0]*b[1]-a[1]*b[0] - ]; -}; - -WebGLSpins._rotationMatrix = function(axis, angle) { - var c = Math.cos(Math.PI * angle / 180); - var s = Math.sin(Math.PI * angle / 180); - var x = axis[0]; - var y = axis[1]; - var z = axis[2]; - return [ - [x*x*(1-c)+c, x*y*(1-c)-z*s, x*z*(1-c)+y*s, 0], - [x*y*(1-c)+z*s, y*y*(1-c)+c, z*y*(1-c)-x*s, 0], - [x*z*(1-c)-y*s, z*y*(1-c)+x*s, z*z*(1-c)+c,0], - [0, 0, 0, 1] - ]; -}; - -WebGLSpins._matrixMultiply = function(matrix, vector) { - var result = [0, 0, 0]; - for(var i = 0; i < 3; i++) { - for(var j = 0; j < 3; j++) { - result[i] += matrix[i][j]*vector[j]; - } - result[i] += matrix[i][3]; - } - return result; -}; - -WebGLSpins._perspectiveProjectionMatrix = function(verticalFieldOfView, aspectRatio, zNear, zFar) { - var f = 1.0/Math.tan(verticalFieldOfView*Math.PI/180/2); - if (aspectRatio < 1.0) { - f *= aspectRatio; - } - return [ - [f/aspectRatio, 0, 0, 0], - [0, f, 0, 0], - [0, 0, (zNear+zFar)/(zNear-zFar), 2*zFar*zNear/(zNear-zFar)], - [0, 0, -1, 0] - ]; -}; - -WebGLSpins._orthographicProjectionMatrix = function(left, right, bottom, top, near, far) { - var sx = 2.0/(right-left); - var sy = 2.0/(top-bottom); - var sz = 2.0/(far-near); - var tx = (right+left)/(right-left); - var ty = (top+bottom)/(top-bottom); - var tz = (far+near)/(far-near); - return [ - [sx, 0, 0, tx], - [0, sy, 0, ty], - [0, 0, sz, tz], - [0, 0, 0, 1] - ]; -} - -WebGLSpins._lookAtMatrix = function(cameraLocation, centerLocation, upVector) { - var forwardVector = WebGLSpins._difference(centerLocation, cameraLocation); - forwardVector = WebGLSpins._normalize(forwardVector); - upVector = WebGLSpins._normalize(upVector); - var rightVector = WebGLSpins._cross(forwardVector, upVector); - rightVector = WebGLSpins._normalize(rightVector); - upVector = WebGLSpins._cross(rightVector, forwardVector); - var matrix = [ - [rightVector[0], rightVector[1], rightVector[2], 0], - [upVector[0], upVector[1], upVector[2], 0], - [-forwardVector[0], -forwardVector[1], -forwardVector[2], 0], - [0, 0, 0, 1] - ]; - var translationVector = WebGLSpins._matrixMultiply(matrix, cameraLocation); - matrix[0][3] = -translationVector[0]; - matrix[1][3] = -translationVector[1]; - matrix[2][3] = -translationVector[2]; - return matrix; -}; - -WebGLSpins._toFloat32Array = function(matrix) { - return new Float32Array([ - matrix[0][0], matrix[1][0], matrix[2][0], matrix[3][0], - matrix[0][1], matrix[1][1], matrix[2][1], matrix[3][1], - matrix[0][2], matrix[1][2], matrix[2][2], matrix[3][2], - matrix[0][3], matrix[1][3], matrix[2][3], matrix[3][3] - ]); -}; - -// ---------------------------- Arrow Renderer -------------------------------- - -WebGLSpins._ArrowRenderer = function(webglspins) { - this._webglspins = webglspins; - this._options = webglspins._options; - this._program = null; - this._vbo = null; - this._ibo = null; - this._instancePositionVbo = 0; - this._instanceDirectionVbo = 0; - this._numIndices = 0; - this._numInstances = 0; - this._boundingBoxRenderer = new WebGLSpins._BoundingBoxRenderer(webglspins); - - if (webglspins._gl_initialized) { - this.initGLContext(); - } - if (webglspins._instancePositionArray != null && webglspins._instanceDirectionArray != null) { - this.updateSpins(webglspins._instancePositionArray, webglspins._instanceDirectionArray); - } -}; - -WebGLSpins.renderers.ARROWS = WebGLSpins._ArrowRenderer; - -WebGLSpins.defaultOptions.coneHeight = 0.6; -WebGLSpins.defaultOptions.coneRadius = 0.25; -WebGLSpins.defaultOptions.cylinderHeight = 0.7; -WebGLSpins.defaultOptions.cylinderRadius = 0.125; -WebGLSpins.defaultOptions.levelOfDetail = 20; -WebGLSpins.defaultOptions.renderers = [WebGLSpins.renderers.ARROWS]; - - -WebGLSpins._ArrowRenderer.prototype.optionsHaveChanged = function(changedOptions) { - var arrayContainsAny = function (array, values) { - for (var i = 0; i < values.length; i++) { - if (~array.indexOf(values[i])) { - return true; - } - } - return false; - }; - if (arrayContainsAny(changedOptions, ['coneHeight', 'coneRadius', 'cylinderHeight', 'cylinderRadius'])) { - this._updateVertexData(); - } - if (arrayContainsAny(changedOptions, ['colormapImplementation'])) { - this._updateShaderProgram(); - } - this._boundingBoxRenderer.optionsHaveChanged(changedOptions); -}; - -WebGLSpins._ArrowRenderer.prototype.updateSpins = function(instancePositionArray, instanceDirectionArray) { - var gl = this._webglspins._gl; - this._numInstances = instancePositionArray.length/3; - gl.bindBuffer(gl.ARRAY_BUFFER, this._instancePositionVbo); - gl.bufferData(gl.ARRAY_BUFFER, instancePositionArray, gl.STREAM_DRAW); - gl.bindBuffer(gl.ARRAY_BUFFER, this._instanceDirectionVbo); - gl.bufferData(gl.ARRAY_BUFFER, instanceDirectionArray, gl.STREAM_DRAW); - this._boundingBoxRenderer.updateSpins(instancePositionArray, instanceDirectionArray); -}; - -WebGLSpins._ArrowRenderer.prototype.draw = function(width, height) { - var gl = this._webglspins._gl; - if (this._numInstances <= 0) { - return; - } - - gl.bindBuffer(gl.ARRAY_BUFFER, this._vbo); - gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 4*3*2, 0); - gl.enableVertexAttribArray(0); - gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 4*3*2, 4*3); - gl.enableVertexAttribArray(1); - - gl.bindBuffer(gl.ARRAY_BUFFER, this._instancePositionVbo); - gl.vertexAttribPointer(2, 3, gl.FLOAT, false, 0, 0); - gl.enableVertexAttribArray(2); - gl.vertexAttribDivisor(2, 1); - - gl.bindBuffer(gl.ARRAY_BUFFER, this._instanceDirectionVbo); - gl.vertexAttribPointer(3, 3, gl.FLOAT, false, 0, 0); - gl.enableVertexAttribArray(3); - gl.vertexAttribDivisor(3, 1); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._ibo); - - gl.useProgram(this._program); - - var projectionMatrix = WebGLSpins._perspectiveProjectionMatrix(this._options.verticalFieldOfView, width / height, 0.1, 10000); - gl.uniformMatrix4fv(gl.getUniformLocation(this._program, "uProjectionMatrix"), false, WebGLSpins._toFloat32Array(projectionMatrix)); - var modelviewMatrix = WebGLSpins._lookAtMatrix(this._options.cameraLocation, this._options.centerLocation, this._options.upVector); - gl.uniformMatrix4fv(gl.getUniformLocation(this._program, "uModelviewMatrix"), false, WebGLSpins._toFloat32Array(modelviewMatrix)); - var lightPosition = WebGLSpins._matrixMultiply(modelviewMatrix, this._options.cameraLocation); - gl.uniform3f(gl.getUniformLocation(this._program, "uLightPosition"), lightPosition[0], lightPosition[1], lightPosition[2]); - var zMin = this._options.zRange[0]; - var zMax = this._options.zRange[1]; - if (zMin <= -1.0) { - zMin = -2.0; - } - if (zMax >= 1.0) { - zMax = 2.0; - } - gl.uniform2f(gl.getUniformLocation(this._program, "uZRange"), zMin, zMax); - - gl.drawElementsInstanced(gl.TRIANGLES, this._numIndices, gl.UNSIGNED_SHORT, null, this._numInstances); - this._boundingBoxRenderer.draw(width, height); -}; - -WebGLSpins._ArrowRenderer.prototype.initGLContext = function() { - var gl = this._webglspins._gl; - // Add extensions functions and constants to the context: - var angle_instanced_arrays_ext = gl.getExtension("ANGLE_instanced_arrays"); - if (!angle_instanced_arrays_ext) { - console.error('WebGL does not support ANGLE_instanced_arrays required by WebGLSpins'); - return; - } - gl.drawArraysInstanced = angle_instanced_arrays_ext.drawArraysInstancedANGLE.bind(angle_instanced_arrays_ext); - gl.drawElementsInstanced = angle_instanced_arrays_ext.drawElementsInstancedANGLE.bind(angle_instanced_arrays_ext); - gl.vertexAttribDivisor = angle_instanced_arrays_ext.vertexAttribDivisorANGLE.bind(angle_instanced_arrays_ext); - gl.VERTEX_ATTRIB_ARRAY_DIVISOR = angle_instanced_arrays_ext.VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE; - - this._vbo = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, this._vbo); - gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 4*3*2, 0); - gl.enableVertexAttribArray(0); - gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 4*3*2, 4*3); - gl.enableVertexAttribArray(1); - this._ibo = gl.createBuffer(); - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._ibo); - this._numIndices = 0; - - this._instancePositionVbo = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, this._instancePositionVbo); - gl.vertexAttribPointer(2, 3, gl.FLOAT, false, 0, 0); - gl.enableVertexAttribArray(2); - gl.vertexAttribDivisor(2, 1); - - this._instanceDirectionVbo = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, this._instanceDirectionVbo); - gl.vertexAttribPointer(3, 3, gl.FLOAT, false, 0, 0); - gl.enableVertexAttribArray(3); - gl.vertexAttribDivisor(3, 1); - this._numInstances = 0; - - this._updateShaderProgram(); - this._updateVertexData(); - this._boundingBoxRenderer.initGLContext(); -}; - -WebGLSpins._ArrowRenderer.prototype._updateShaderProgram = function() { - var gl = this._webglspins._gl; - if (this._program) { - gl.deleteProgram(this._program); - } - - var program = WebGLSpins._createProgram(gl, - ` - #version 100 - precision highp float; - - uniform mat4 uProjectionMatrix; - uniform mat4 uModelviewMatrix; - uniform vec2 uZRange; - attribute vec3 ivPosition; - attribute vec3 ivNormal; - attribute vec3 ivInstanceOffset; - attribute vec3 ivInstanceDirection; - varying vec3 vfPosition; - varying vec3 vfNormal; - varying vec3 vfColor; - - mat3 matrixFromDirection(vec3 direction) { - float c = direction.z; - float s = length(direction.xy); - float x = 1.0; - float y = 0.0; - if (s > 0.0001) { - x = -direction.y / s; - y = direction.x / s; - } - mat3 matrix; - matrix[0][0] = x*x*(1.0-c)+c; - matrix[0][1] = y*x*(1.0-c); - matrix[0][2] = -y*s; - matrix[1][0] = x*y*(1.0-c); - matrix[1][1] = y*y*(1.0-c)+c; - matrix[1][2] = x*s; - matrix[2][0] = y*s; - matrix[2][1] = -x*s; - matrix[2][2] = c; - return matrix; - } - - vec3 colormap(vec3 direction); - - void main(void) { - vfColor = colormap(normalize(ivInstanceDirection)); - mat3 instanceMatrix = matrixFromDirection(ivInstanceDirection); - vfNormal = (uModelviewMatrix * vec4(instanceMatrix*ivNormal, 0.0)).xyz; - vfPosition = (uModelviewMatrix * vec4(instanceMatrix*ivPosition+ivInstanceOffset, 1.0)).xyz; - if (ivInstanceDirection.z >= uZRange.x && ivInstanceDirection.z <= uZRange.y) { - gl_Position = uProjectionMatrix * vec4(vfPosition, 1.0); - } else { - gl_Position = vec4(2.0, 2.0, 2.0, 0.0); - } - } - `+this._options.colormapImplementation, - ` - #version 100 - precision highp float; - - uniform vec3 uLightPosition; - varying vec3 vfPosition; - varying vec3 vfNormal; - varying vec3 vfColor; - - void main(void) { - vec3 cameraLocation = vec3(0, 0, 0); - vec3 normal = normalize(vfNormal); - vec3 lightDirection = normalize(uLightPosition-vfPosition); - vec3 reflectionDirection = normalize(reflect(lightDirection, normal)); - float specular = 0.2*pow(max(0.0, -reflectionDirection.z), 8.0); - float diffuse = 0.7*max(0.0, dot(normal, lightDirection)); - float ambient = 0.2; - gl_FragColor = vec4((ambient+diffuse)*vfColor + specular*vec3(1, 1, 1), 1.0); - } - `, - ['ivPosition', 'ivNormal', 'ivInstanceOffset', 'ivInstanceDirection'] - ); - if (program == null) return; - this._program = program; -}; - -WebGLSpins._ArrowRenderer.prototype._updateVertexData = function() { - var gl = this._webglspins._gl; - - var levelOfDetail = this._options.levelOfDetail; - var coneHeight = this._options.coneHeight; - var coneRadius = this._options.coneRadius; - var cylinderHeight = this._options.cylinderHeight; - var cylinderRadius = this._options.cylinderRadius; - - // Enforce valid range - if (levelOfDetail < 3) { - levelOfDetail = 3; - } - if (coneHeight < 0) { - coneHeight = 0; - } - if (coneRadius < 0) { - coneRadius = 0; - } - if (cylinderHeight < 0) { - cylinderHeight = 0; - } - if (cylinderRadius < 0) { - cylinderRadius = 0; - } - var i; - var baseNormal = [0, 0, -1]; - var zOffset = (cylinderHeight-coneHeight)/2; - var l = Math.sqrt(coneRadius*coneRadius+coneHeight*coneHeight); - var f1 = coneRadius/l; - var f2 = coneHeight/l; - var alpha; - var position; - var vertexData = []; - // The tip has no normal to prevent a discontinuity. - Array.prototype.push.apply(vertexData, [0, 0, zOffset+coneHeight]); - Array.prototype.push.apply(vertexData, [0, 0, 0]); - for (i = 0; i < levelOfDetail; i++) { - alpha = 2*Math.PI*i/levelOfDetail; - position = [coneRadius*Math.cos(alpha), coneRadius*Math.sin(alpha), zOffset]; - var normal = [f2*Math.cos(alpha), f2*Math.sin(alpha), f1]; - Array.prototype.push.apply(vertexData, position); - Array.prototype.push.apply(vertexData, normal); - } - for (i = 0; i < levelOfDetail; i++) { - alpha = 2*Math.PI*i/levelOfDetail; - position = [coneRadius*Math.cos(alpha), coneRadius*Math.sin(alpha), zOffset]; - Array.prototype.push.apply(vertexData, position); - Array.prototype.push.apply(vertexData, baseNormal); - } - for (i = 0; i < levelOfDetail; i++) { - alpha = 2*Math.PI*i/levelOfDetail; - position = [cylinderRadius*Math.cos(alpha), cylinderRadius*Math.sin(alpha), zOffset-cylinderHeight]; - Array.prototype.push.apply(vertexData, position); - Array.prototype.push.apply(vertexData, baseNormal); - } - for (i = 0; i < levelOfDetail; i++) { - alpha = 2*Math.PI*i/levelOfDetail; - position = [cylinderRadius*Math.cos(alpha), cylinderRadius*Math.sin(alpha), zOffset-cylinderHeight]; - normal = [Math.cos(alpha), Math.sin(alpha), 0]; - Array.prototype.push.apply(vertexData, position); - Array.prototype.push.apply(vertexData, normal); - } - for (i = 0; i < levelOfDetail; i++) { - alpha = 2*Math.PI*i/levelOfDetail; - position = [cylinderRadius*Math.cos(alpha), cylinderRadius*Math.sin(alpha), zOffset]; - normal = [Math.cos(alpha), Math.sin(alpha), 0]; - Array.prototype.push.apply(vertexData, position); - Array.prototype.push.apply(vertexData, normal); - } - var indices = []; - var triangleIndices; - for (i = 0; i < levelOfDetail; i++) { - triangleIndices = [1+i, 1+(i+1)%levelOfDetail, 0]; - Array.prototype.push.apply(indices, triangleIndices); - } - for (i = 0; i < levelOfDetail; i++) { - triangleIndices = [levelOfDetail+1, levelOfDetail+1+(i+1)%levelOfDetail, levelOfDetail+1+i]; - Array.prototype.push.apply(indices, triangleIndices); - } - for (i = 0; i < levelOfDetail; i++) { - triangleIndices = [levelOfDetail*2+1, levelOfDetail*2+1+(i+1)%levelOfDetail, levelOfDetail*2+1+i]; - Array.prototype.push.apply(indices, triangleIndices); - } - for (i = 0; i < levelOfDetail; i++) { - triangleIndices = [levelOfDetail*3+1+i, levelOfDetail*3+1+(i+1)%levelOfDetail, levelOfDetail*4+1+i]; - Array.prototype.push.apply(indices, triangleIndices); - triangleIndices = [levelOfDetail*4+1+i, levelOfDetail*3+1+(i+1)%levelOfDetail, levelOfDetail*4+1+(i+1)%levelOfDetail]; - Array.prototype.push.apply(indices, triangleIndices); - } - - gl.bindBuffer(gl.ARRAY_BUFFER, this._vbo); - gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexData), gl.STATIC_DRAW); - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._ibo); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Int16Array(indices), gl.STATIC_DRAW); - this._numIndices = indices.length; -}; - -WebGLSpins._ArrowRenderer.prototype.cleanup = function() { - var gl = this._webglspins._gl; - gl.deleteBuffer(this._vbo); - gl.deleteBuffer(this._ibo); - gl.deleteBuffer(this._instancePositionVbo); - gl.deleteBuffer(this._instanceDirectionVbo); - gl.deleteProgram(this._program); - gl.disableVertexAttribArray(0); - gl.disableVertexAttribArray(1); - gl.disableVertexAttribArray(2); - gl.disableVertexAttribArray(3); - this._boundingBoxRenderer.cleanup(); -}; - -// --------------------------- Surface Renderer ------------------------------- - -WebGLSpins._SurfaceRenderer = function(webglspins) { - this._webglspins = webglspins; - this._options = webglspins._options; - this._program = null; - this._ibo = null; - this._instancePositionVbo = 0; - this._instanceDirectionVbo = 0; - this._numIndices = 0; - this._boundingBoxRenderer = new WebGLSpins._BoundingBoxRenderer(webglspins); - if (webglspins._gl_initialized) { - this.initGLContext(); - } - if (webglspins._instancePositionArray != null && webglspins._instanceDirectionArray != null) { - this.updateSpins(webglspins._instancePositionArray, webglspins._instanceDirectionArray); - } -}; - -WebGLSpins.renderers.SURFACE = WebGLSpins._SurfaceRenderer; - -WebGLSpins.defaultOptions.surfaceIndices = []; - -WebGLSpins._SurfaceRenderer.prototype.optionsHaveChanged = function(changedOptions) { - var arrayContainsAny = function (array, values) { - for (var i = 0; i < values.length; i++) { - if (~array.indexOf(values[i])) { - return true; - } - } - return false; - }; - if (arrayContainsAny(changedOptions, ['surfaceIndices'])) { - this._updateSurfaceIndices(); - } - if (arrayContainsAny(changedOptions, ['colormapImplementation'])) { - this._updateShaderProgram(); - } - this._boundingBoxRenderer.optionsHaveChanged(changedOptions); -}; - -WebGLSpins._SurfaceRenderer.prototype.updateSpins = function(instancePositionArray, instanceDirectionArray) { - var gl = this._webglspins._gl; - this._numInstances = instancePositionArray.length/3; - gl.bindBuffer(gl.ARRAY_BUFFER, this._instancePositionVbo); - gl.bufferData(gl.ARRAY_BUFFER, instancePositionArray, gl.STREAM_DRAW); - gl.bindBuffer(gl.ARRAY_BUFFER, this._instanceDirectionVbo); - gl.bufferData(gl.ARRAY_BUFFER, instanceDirectionArray, gl.STREAM_DRAW); - this._boundingBoxRenderer.updateSpins(instancePositionArray, instanceDirectionArray); -}; - -WebGLSpins._SurfaceRenderer.prototype.draw = function(width, height) { - var gl = this._webglspins._gl; - if (this._numIndices < 3) { - return; - } - - gl.bindBuffer(gl.ARRAY_BUFFER, this._instancePositionVbo); - gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); - gl.enableVertexAttribArray(0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this._instanceDirectionVbo); - gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 0, 0); - gl.enableVertexAttribArray(1); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._ibo); - - gl.useProgram(this._program); - - var projectionMatrix = WebGLSpins._perspectiveProjectionMatrix(this._options.verticalFieldOfView, width / height, 0.1, 10000); - gl.uniformMatrix4fv(gl.getUniformLocation(this._program, "uProjectionMatrix"), false, WebGLSpins._toFloat32Array(projectionMatrix)); - var modelviewMatrix = WebGLSpins._lookAtMatrix(this._options.cameraLocation, this._options.centerLocation, this._options.upVector); - gl.uniformMatrix4fv(gl.getUniformLocation(this._program, "uModelviewMatrix"), false, WebGLSpins._toFloat32Array(modelviewMatrix)); - var zMin = this._options.zRange[0]; - var zMax = this._options.zRange[1]; - if (zMin <= -1.0) { - zMin = -2.0; - } - if (zMax >= 1.0) { - zMax = 2.0; - } - gl.uniform2f(gl.getUniformLocation(this._program, "uZRange"), zMin, zMax); - - gl.disable(gl.CULL_FACE); - gl.drawElements(gl.TRIANGLES, this._numIndices, gl.UNSIGNED_INT, null); - gl.enable(gl.CULL_FACE); - - this._boundingBoxRenderer.draw(width, height); -}; - -WebGLSpins._SurfaceRenderer.prototype.initGLContext = function() { - var gl = this._webglspins._gl; - // Add extensions functions and constants to the context: - var oes_element_index_uint_ext = gl.getExtension("OES_element_index_uint"); - if (!oes_element_index_uint_ext) { - console.error('WebGL does not support OES_element_index_uint required by WebGLSpins'); - return; - } - - this._ibo = gl.createBuffer(); - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._ibo); - this._numIndices = 0; - - this._instancePositionVbo = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, this._instancePositionVbo); - gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); - gl.enableVertexAttribArray(0); - - this._instanceDirectionVbo = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, this._instanceDirectionVbo); - gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 0, 0); - gl.enableVertexAttribArray(1); - - this._updateShaderProgram(); - this._updateSurfaceIndices(); - this._boundingBoxRenderer.initGLContext(); -}; - -WebGLSpins._SurfaceRenderer.prototype._updateShaderProgram = function() { - var gl = this._webglspins._gl; - if (this._program) { - gl.deleteProgram(this._program); - } - var program = WebGLSpins._createProgram(gl, - ` - #version 100 - precision highp float; - - uniform mat4 uProjectionMatrix; - uniform mat4 uModelviewMatrix; - attribute vec3 ivPosition; - attribute vec3 ivDirection; - varying vec3 vfDirection; - - void main(void) { - vfDirection = normalize(ivDirection); - gl_Position = uProjectionMatrix * (uModelviewMatrix * vec4(ivPosition, 1.0)); - } - `, ` - #version 100 - precision highp float; - - uniform vec2 uZRange; - varying vec3 vfDirection; - - vec3 colormap(vec3 direction); - - void main(void) { - if (vfDirection.z >= uZRange.x && vfDirection.z <= uZRange.y) { - vec3 color = colormap(normalize(vfDirection)); - gl_FragColor = vec4(color, 1.0); - } else { - discard; - } - } - `+this._options.colormapImplementation, - ['ivPosition', 'ivDirection'] - ); - if (program == null) return; - this._program = program; -}; - -WebGLSpins._SurfaceRenderer.prototype._updateSurfaceIndices = function() { - var gl = this._webglspins._gl; - - var surfaceIndices = this._options.surfaceIndices; - - // Enforce valid range - if (surfaceIndices.length < 3) { - this._numIndices = 0; - return; - } - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._ibo); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Int32Array(surfaceIndices), gl.STATIC_DRAW); - this._numIndices = surfaceIndices.length; -}; - -WebGLSpins._SurfaceRenderer.prototype.cleanup = function() { - var gl = this._webglspins._gl; - gl.deleteBuffer(this._instancePositionVbo); - gl.deleteBuffer(this._instanceDirectionVbo); - gl.deleteBuffer(this._ibo); - gl.deleteProgram(this._program); - gl.disableVertexAttribArray(0); - gl.disableVertexAttribArray(1); - this._boundingBoxRenderer.cleanup(); -}; - -WebGLSpins.generateCartesianSurfaceIndices = function(nx, ny) { - var surfaceIndices = []; - for (var i = 0; i < ny-1; i++) { - for (var j = 0; j < nx-1; j++) { - var square_indices = [ - i*nx + j, i*nx + j + 1, (i+1)*nx + j, - (i+1)*nx + j, i*nx + j + 1, (i+1)*nx + j + 1 - ]; - Array.prototype.push.apply(surfaceIndices, square_indices); - } - } - return surfaceIndices; -}; - -// ---------------------------- Sphere Renderer ------------------------------- - -WebGLSpins._SphereRenderer = function(webglspins) { - this._webglspins = webglspins; - this._options = webglspins._options; - this._program = null; - this._instanceDirectionVbo = null; - this._numInstances = 0; - if (webglspins._gl_initialized) { - this.initGLContext(); - } - if (webglspins._instanceDirectionArray != null) { - this.updateSpins(null, webglspins._instanceDirectionArray); - } -}; - -WebGLSpins.renderers.SPHERE = WebGLSpins._SphereRenderer; - -WebGLSpins.defaultOptions.pointSizeRange = [1.0, 1.0]; -WebGLSpins.defaultOptions.innerSphereRadius = 0.95; -WebGLSpins.defaultOptions.useSphereFakePerspective = false; - -WebGLSpins._SphereRenderer.prototype.optionsHaveChanged = function(changedOptions) { - var arrayContainsAny = function (array, values) { - for (var i = 0; i < values.length; i++) { - if (~array.indexOf(values[i])) { - return true; - } - } - return false; - }; - if (arrayContainsAny(changedOptions, ['colormapImplementation'])) { - this._updateShaderProgram(); - } -}; - -WebGLSpins._SphereRenderer.prototype.updateSpins = function(instancePositionArray, instanceDirectionArray) { - var gl = this._webglspins._gl; - this._numInstances = instanceDirectionArray.length/3; - gl.bindBuffer(gl.ARRAY_BUFFER, this._instanceDirectionVbo); - gl.bufferData(gl.ARRAY_BUFFER, instanceDirectionArray, gl.STREAM_DRAW); -}; - -WebGLSpins._SphereRenderer.prototype.draw = function(width, height) { - var gl = this._webglspins._gl; - if (this._options.innerSphereRadius > 0.0) { - if (this._options.innerSphereRadius > 0.99) { - this._options.innerSphereRadius = 0.99; - } - gl.useProgram(this._program2); - - gl.bindBuffer(gl.ARRAY_BUFFER, this._fakeSphereVbo); - gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); - gl.enableVertexAttribArray(0); - gl.uniform1f(gl.getUniformLocation(this._program2, "uAspectRatio"), width / height); - gl.uniform1f(gl.getUniformLocation(this._program2, "uInnerSphereRadius"), this._options.innerSphereRadius); - gl.disable(gl.CULL_FACE); - gl.depthMask(false); - gl.drawArrays(gl.TRIANGLES, 0, 6); - gl.depthMask(true); - gl.enable(gl.CULL_FACE); - } - - if (this._numInstances <= 0) { - return; - } - - gl.bindBuffer(gl.ARRAY_BUFFER, this._instanceDirectionVbo); - gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); - gl.enableVertexAttribArray(0); - - gl.useProgram(this._program); - - if (width >= height) { - var projectionMatrix = WebGLSpins._orthographicProjectionMatrix(-width / height, width / height, -1, 1, 2, 0); - } else { - var projectionMatrix = WebGLSpins._orthographicProjectionMatrix(-1, 1, -height / width, height / width, 2, 0); - } - gl.uniformMatrix4fv(gl.getUniformLocation(this._program, "uProjectionMatrix"), false, WebGLSpins._toFloat32Array(projectionMatrix)); - var modelviewMatrix = WebGLSpins._lookAtMatrix(WebGLSpins._normalize(WebGLSpins._difference(this._options.cameraLocation, this._options.centerLocation)), [0, 0, 0], this._options.upVector); - gl.uniformMatrix4fv(gl.getUniformLocation(this._program, "uModelviewMatrix"), false, WebGLSpins._toFloat32Array(modelviewMatrix)); - var zMin = this._options.zRange[0]; - var zMax = this._options.zRange[1]; - if (zMin <= -1.0) { - zMin = -2.0; - } - if (zMax >= 1.0) { - zMax = 2.0; - } - gl.uniform2f(gl.getUniformLocation(this._program, "uZRange"), zMin, zMax); - gl.uniform2f(gl.getUniformLocation(this._program, "uPointSizeRange"), Math.floor(this._options.pointSizeRange[0]), Math.floor(this._options.pointSizeRange[1])); - gl.uniform1f(gl.getUniformLocation(this._program, "uAspectRatio"), width / height); - gl.uniform1f(gl.getUniformLocation(this._program, "uInnerSphereRadius"), this._options.innerSphereRadius); - if (this._options.useSphereFakePerspective) { - gl.uniform1f(gl.getUniformLocation(this._program, "uUseFakePerspective"), 1.0); - } else { - gl.uniform1f(gl.getUniformLocation(this._program, "uUseFakePerspective"), 0.0); - } - - gl.disable(gl.CULL_FACE); - gl.drawArrays(gl.POINTS, 0, this._numInstances); - gl.enable(gl.CULL_FACE); -}; - -WebGLSpins._SphereRenderer.prototype.initGLContext = function() { - var gl = this._webglspins._gl; - this._instanceDirectionVbo = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, this._instanceDirectionVbo); - gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); - gl.enableVertexAttribArray(0); - this._fakeSphereVbo = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, this._fakeSphereVbo); - gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); - gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ - -1, -1, 0, - 1, -1, 0, - -1, 1, 0, - -1, 1, 0, - 1, -1, 0, - 1, 1, 0]), gl.STATIC_DRAW); - gl.enableVertexAttribArray(0); - - this._updateShaderProgram(); -}; - -WebGLSpins._SphereRenderer.prototype._updateShaderProgram = function() { - var gl = this._webglspins._gl; - if (this._program) { - gl.deleteProgram(this._program); - } - - var program = WebGLSpins._createProgram(gl, - ` - #version 100 - precision highp float; - - uniform mat4 uProjectionMatrix; - uniform mat4 uModelviewMatrix; - uniform vec2 uPointSizeRange; - uniform float uAspectRatio; - uniform float uInnerSphereRadius; - uniform float uUseFakePerspective; - attribute vec3 ivDirection; - varying vec3 vfDirection; - - void main(void) { - vfDirection = normalize(ivDirection); - gl_Position = uProjectionMatrix * uModelviewMatrix * vec4(vfDirection*0.99, 1.0); - vec2 clipPosition = vec2(gl_Position.x * uAspectRatio, gl_Position.y); - float clipRadius = length(clipPosition); - float rotatedDirectionZ = dot(vec3(uModelviewMatrix[0][2], uModelviewMatrix[1][2], uModelviewMatrix[2][2]), vfDirection); - if ((clipRadius <= uInnerSphereRadius) && (rotatedDirectionZ < 0.0)) { - gl_Position = vec4(2.0, 2.0, 2.0, 1.0); - } - gl_PointSize = uPointSizeRange.x + (uPointSizeRange.y-uPointSizeRange.x) * sqrt(max(0.0, 1.0-clipRadius*clipRadius)) * (5.0-uUseFakePerspective*gl_Position.z) / 5.0; - } - `, ` - #version 100 - precision highp float; - - uniform vec2 uZRange; - varying vec3 vfDirection; - - vec3 colormap(vec3 direction); - - void main(void) { - if (vfDirection.z >= uZRange.x && vfDirection.z <= uZRange.y) { - vec3 color = colormap(normalize(vfDirection)); - gl_FragColor = vec4(color, 1.0); - } else { - discard; - } - } - `+this._options.colormapImplementation, - ['ivDirection'] - ); - if (program == null) return; - var program2 = WebGLSpins._createProgram(gl, - ` - #version 100 - precision highp float; - - uniform float uAspectRatio; - uniform float uInnerSphereRadius; - attribute vec3 ivPosition; - varying vec3 vfPosition; - - void main(void) { - vfPosition = ivPosition; - gl_Position = vec4(vfPosition.xy*vec2(uInnerSphereRadius/uAspectRatio, uInnerSphereRadius), 0.0, 1.0); - if (uAspectRatio < 1.0) { - gl_Position.xy *= uAspectRatio; - } - } - `, ` - #version 100 - precision highp float; - - varying vec3 vfPosition; - - - void main(void) { - float l = length(vfPosition); - if (l > 1.0) { - discard; - } else { - vec3 color = 0.2+0.4*sqrt(1.0-l*l)*vec3(1.0, 1.0, 1.0); - gl_FragColor = vec4(color, 1.0); - } - } - `, - ['ivPosition'] - ); - if (program2 == null) return; - this._program = program; - this._program2 = program2; -}; - -WebGLSpins._SphereRenderer.prototype.cleanup = function() { - var gl = this._webglspins._gl; - gl.deleteBuffer(this._instanceDirectionVbo); - gl.deleteBuffer(this._fakeSphereVbo); - gl.deleteProgram(this._program); - gl.deleteProgram(this._program2); - gl.disableVertexAttribArray(0); -}; - -// ----------------------- Coordinate System Renderer ------------------------- - -WebGLSpins._CoordinateSystemRenderer = function(webglspins) { - this._webglspins = webglspins; - this._options = webglspins._options; - this._program = null; - this._lineVbo = null; - if (webglspins._gl_initialized) { - this.initGLContext(); - } -}; - -WebGLSpins.renderers.COORDINATESYSTEM = WebGLSpins._CoordinateSystemRenderer; - -WebGLSpins._CoordinateSystemRenderer.prototype.optionsHaveChanged = function(changedOptions) { - var arrayContainsAny = function (array, values) { - for (var i = 0; i < values.length; i++) { - if (~array.indexOf(values[i])) { - return true; - } - } - return false; - }; - if (arrayContainsAny(changedOptions, ['colormapImplementation'])) { - this._updateShaderProgram(); - } -}; - -WebGLSpins._CoordinateSystemRenderer.prototype.updateSpins = function(instancePositionArray, instanceDirectionArray) {}; - -WebGLSpins._CoordinateSystemRenderer.prototype.draw = function(width, height) { - var gl = this._webglspins._gl; - - gl.bindBuffer(gl.ARRAY_BUFFER, this._lineVbo); - gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); - gl.enableVertexAttribArray(0); - - gl.useProgram(this._program); - - var projectionMatrix = WebGLSpins._perspectiveProjectionMatrix(this._options.verticalFieldOfView, width / height, 0.1, 10000); - gl.uniformMatrix4fv(gl.getUniformLocation(this._program, "uProjectionMatrix"), false, WebGLSpins._toFloat32Array(projectionMatrix)); - var modelviewMatrix = WebGLSpins._lookAtMatrix(WebGLSpins._normalize(WebGLSpins._difference(this._options.cameraLocation, this._options.centerLocation)), [0, 0, 0], this._options.upVector); - gl.uniformMatrix4fv(gl.getUniformLocation(this._program, "uModelviewMatrix"), false, WebGLSpins._toFloat32Array(modelviewMatrix)); - gl.uniform1f(gl.getUniformLocation(this._program, "uSinHalfVFoV"), Math.sin(this._options.verticalFieldOfView*0.5*Math.PI/180)); - - gl.disable(gl.CULL_FACE); - gl.drawArrays(gl.LINES, 0, 6); - gl.enable(gl.CULL_FACE); -}; - -WebGLSpins._CoordinateSystemRenderer.prototype.initGLContext = function() { - var gl = this._webglspins._gl; - this._lineVbo = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, this._lineVbo); - gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ - 0, 0, 0, - 1, 0, 0, - 0, 0, 0, - 0, 1, 0, - 0, 0, 0, - 0, 0, 1]), gl.STATIC_DRAW); - gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); - gl.enableVertexAttribArray(0); - - this._updateShaderProgram(); -}; - -WebGLSpins._CoordinateSystemRenderer.prototype._updateShaderProgram = function() { - var gl = this._webglspins._gl; - if (this._program) { - gl.deleteProgram(this._program); - } - - var program = WebGLSpins._createProgram(gl, - ` - #version 100 - precision highp float; - - uniform mat4 uProjectionMatrix; - uniform mat4 uModelviewMatrix; - uniform float uSinHalfVFoV; - attribute vec3 ivDirection; - varying vec3 vfDirection; - - void main(void) { - vfDirection = ivDirection; - gl_Position = uProjectionMatrix * (uModelviewMatrix * vec4(ivDirection*uSinHalfVFoV*0.99, 1.0)); - } - `, ` - #version 100 - precision highp float; - - uniform vec2 uZRange; - varying vec3 vfDirection; - - vec3 colormap(vec3 direction); - - void main(void) { - vec3 color = colormap(normalize(vfDirection)); - gl_FragColor = vec4(color, 1.0); - } - `+this._options.colormapImplementation, - ['ivDirection'] - ); - if (program == null) return; - this._program = program; -}; - -WebGLSpins._CoordinateSystemRenderer.prototype.cleanup = function() { - var gl = this._webglspins._gl; - gl.deleteBuffer(this._lineVbo); - gl.deleteProgram(this._program); - gl.disableVertexAttribArray(0); -}; - -// -------------------------- Bounding Box Renderer --------------------------- - -WebGLSpins._BoundingBoxRenderer = function(webglspins) { - this._webglspins = webglspins; - this._options = webglspins._options; - this._program = null; - this._lineVbo = null; - this._gl_initialized = false; - if (webglspins._gl_initialized) { - this.initGLContext(); - } -}; - -WebGLSpins._BoundingBoxRenderer.prototype.optionsHaveChanged = function(changedOptions) {}; - -WebGLSpins._BoundingBoxRenderer.prototype.updateSpins = function(instancePositionArray, instanceDirectionArray) {}; - -WebGLSpins._BoundingBoxRenderer.prototype.draw = function(width, height) { - var gl = this._webglspins._gl; - - if (this._options.boundingBox == null) { - return; - } - var xmin = this._options.boundingBox[0]; - var ymin = this._options.boundingBox[1]; - var zmin = this._options.boundingBox[2]; - var xmax = this._options.boundingBox[3]; - var ymax = this._options.boundingBox[4]; - var zmax = this._options.boundingBox[5]; - var red = this._options.boundingBoxColor[0]; - var green = this._options.boundingBoxColor[1]; - var blue = this._options.boundingBoxColor[2]; - - gl.bindBuffer(gl.ARRAY_BUFFER, this._lineVbo); - gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); - gl.enableVertexAttribArray(0); - - gl.useProgram(this._program); - - var projectionMatrix = WebGLSpins._perspectiveProjectionMatrix(this._options.verticalFieldOfView, width / height, 0.1, 10000); - gl.uniformMatrix4fv(gl.getUniformLocation(this._program, "uProjectionMatrix"), false, WebGLSpins._toFloat32Array(projectionMatrix)); - var modelviewMatrix = WebGLSpins._lookAtMatrix(this._options.cameraLocation, this._options.centerLocation, this._options.upVector); - gl.uniformMatrix4fv(gl.getUniformLocation(this._program, "uModelviewMatrix"), false, WebGLSpins._toFloat32Array(modelviewMatrix)); - gl.uniform3f(gl.getUniformLocation(this._program, "uBoundingBoxMin"), xmin, ymin, zmin); - gl.uniform3f(gl.getUniformLocation(this._program, "uBoundingBoxMax"), xmax, ymax, zmax); - gl.uniform3f(gl.getUniformLocation(this._program, "uBoundingBoxColor"), red, green, blue); - - gl.disable(gl.CULL_FACE); - gl.drawArrays(gl.LINES, 0, 24); - gl.enable(gl.CULL_FACE); -}; - -WebGLSpins._BoundingBoxRenderer.prototype.initGLContext = function() { - if (this._gl_initialized) return; - this._gl_initialized = true; - var gl = this._webglspins._gl; - this._lineVbo = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, this._lineVbo); - gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ - 0, 0, 0, - 1, 0, 0, - 1, 0, 0, - 1, 1, 0, - 1, 1, 0, - 0, 1, 0, - 0, 1, 0, - 0, 0, 0, - 0, 0, 1, - 1, 0, 1, - 1, 0, 1, - 1, 1, 1, - 1, 1, 1, - 0, 1, 1, - 0, 1, 1, - 0, 0, 1, - 0, 0, 0, - 0, 0, 1, - 1, 0, 0, - 1, 0, 1, - 1, 1, 0, - 1, 1, 1, - 0, 1, 0, - 0, 1, 1]), gl.STATIC_DRAW); - gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); - gl.enableVertexAttribArray(0); - - this._updateShaderProgram(); -}; - -WebGLSpins._BoundingBoxRenderer.prototype._updateShaderProgram = function() { - var gl = this._webglspins._gl; - if (this._program) { - gl.deleteProgram(this._program); - } - - var program = WebGLSpins._createProgram(gl, - ` - #version 100 - precision highp float; - - uniform mat4 uProjectionMatrix; - uniform mat4 uModelviewMatrix; - uniform vec3 uBoundingBoxMin; - uniform vec3 uBoundingBoxMax; - attribute vec3 ivPosition; - - void main(void) { - gl_Position = uProjectionMatrix * uModelviewMatrix * vec4(ivPosition * (uBoundingBoxMax-uBoundingBoxMin)+uBoundingBoxMin, 1.0); - } - `, ` - #version 100 - precision highp float; - uniform vec3 uBoundingBoxColor; - - void main(void) { - gl_FragColor = vec4(uBoundingBoxColor, 1.0); - }`, - ['ivPosition'] - ); - if (program == null) return; - this._program = program; -}; - -WebGLSpins._BoundingBoxRenderer.prototype.cleanup = function() { - var gl = this._webglspins._gl; - gl.deleteBuffer(this._lineVbo); - gl.deleteProgram(this._program); - gl.disableVertexAttribArray(0); -}; - diff --git a/ui-web/main_js.cxx b/ui-web/main_js.cxx deleted file mode 100644 index ede8be823..000000000 --- a/ui-web/main_js.cxx +++ /dev/null @@ -1,9 +0,0 @@ -/* This file solely exists to have a main function for emscripten. All - * functionality used by the Web frontend should be part of the common library - * C interface (see core/include/Spirit/). - */ - -int main(void) -{ - return 0; -} \ No newline at end of file diff --git a/ui-web/src/wrapper.cxx b/ui-web/src/wrapper.cxx new file mode 100755 index 000000000..0a811d009 --- /dev/null +++ b/ui-web/src/wrapper.cxx @@ -0,0 +1,602 @@ +#include +#include +#include + +#include "VFRendering/View.hxx" +#include "VFRendering/DotRenderer.hxx" +#include "VFRendering/ArrowRenderer.hxx" +#include "VFRendering/SphereRenderer.hxx" +#include "VFRendering/VectorSphereRenderer.hxx" +#include "VFRendering/CoordinateSystemRenderer.hxx" +#include "VFRendering/BoundingBoxRenderer.hxx" +#include "VFRendering/CombinedRenderer.hxx" +#include "VFRendering/IsosurfaceRenderer.hxx" +#include "VFRendering/ParallelepipedRenderer.hxx" +#include "VFRendering/SurfaceRenderer.hxx" + +#include +#include +#include + +static bool needs_redraw = false; +static const int default_mode = (int)VFRendering::CameraMovementModes::ROTATE_BOUNDED; +VFRendering::View view; + +// Data +std::vector positions; +std::vector directions; + +std::shared_ptr geometry; +std::shared_ptr vf; + +// Which to show +static bool show_bounding_box = true; +static bool show_dots = true; +static bool show_arrows = true; +static bool show_boxes = false; +static bool show_spheres = true; +static bool show_surface = true; +static bool show_isosurface = true; + +static bool mainview_is_system = true; +static bool show_coordinate_system = true; +static bool show_miniview = true; + +static int location_coordinatesystem = 2; +static int location_miniview = 3; + +// Renderers +std::shared_ptr bounding_box_renderer_ptr; +std::shared_ptr coordinate_system_renderer_ptr; +std::shared_ptr vectorsphere_renderer_ptr; +std::shared_ptr dot_renderer_ptr; +std::shared_ptr arrow_renderer_ptr; +std::shared_ptr sphere_renderer_ptr; +std::shared_ptr box_renderer_ptr; +std::shared_ptr surface_renderer_3d_ptr; +std::shared_ptr surface_renderer_2d_ptr; +std::shared_ptr isosurface_renderer_ptr; + +void framebufferSizeCallback(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context, int width, int height) +{ + (void)context; + view.setFramebufferSize(width, height); + needs_redraw = true; +} + +void update_renderers(State * state) +{ + int dimensionality = Geometry_Get_Dimensionality(state); + + std::vector> system_renderers(0); + if( show_bounding_box ) + system_renderers.push_back(bounding_box_renderer_ptr); + if( show_dots ) + system_renderers.push_back(dot_renderer_ptr); + if( show_arrows ) + system_renderers.push_back(arrow_renderer_ptr); + if( show_spheres ) + system_renderers.push_back(sphere_renderer_ptr); + if( show_boxes ) + system_renderers.push_back(box_renderer_ptr); + if( show_surface ) + { + if( dimensionality == 3 ) + system_renderers.push_back(surface_renderer_3d_ptr); + else if( dimensionality == 2 ) + system_renderers.push_back(surface_renderer_2d_ptr); + } + if( show_isosurface && dimensionality == 3 ) + system_renderers.push_back(isosurface_renderer_ptr); + + // --------------- + + std::array position_coordinatesystem; + if( location_coordinatesystem == 0 ) // TL + position_coordinatesystem = { 0, 0.7f, 0.25f, 0.25f }; + else if( location_coordinatesystem == 1 ) // TR + position_coordinatesystem = { 0.75f, 0.7f, 0.25f, 0.25f }; + else if( location_coordinatesystem == 2 ) // BR + position_coordinatesystem = { 0.75f, 0.05, 0.25f, 0.25f }; + else if( location_coordinatesystem == 3 ) // BL + position_coordinatesystem = { 0, 0.05f, 0.25f, 0.25f }; + + std::array position_miniview; + if( location_miniview == 0 ) // TL + position_miniview = { 0, 0.7f, 0.25f, 0.25f }; + else if( location_miniview == 1 ) // TR + position_miniview = { 0.75f, 0.7f, 0.25f, 0.25f }; + else if( location_miniview == 2 ) // BR + position_miniview = { 0.75f, 0.05f, 0.25f, 0.25f }; + else if( location_miniview == 3 ) // BL + position_miniview = { 0, 0.05f, 0.25f, 0.25f }; + + // --------------- + + std::vector, std::array>> view_renderers(0); + + if( mainview_is_system ) + { + view_renderers.push_back({std::make_shared(view, system_renderers), {{0, 0, 1, 1}}}); + if( show_miniview ) + view_renderers.push_back({vectorsphere_renderer_ptr, position_miniview}); + } + else + { + view_renderers.push_back({vectorsphere_renderer_ptr, {{0, 0, 1, 1}}}); + if( show_miniview ) + view_renderers.push_back({std::make_shared(view, system_renderers), position_miniview}); + } + + if( show_coordinate_system ) + view_renderers.push_back({coordinate_system_renderer_ptr, position_coordinatesystem}); + + // --------------- + + view.renderers(view_renderers); +} + +extern "C" void mouse_move(float previous_mouse_position[2], float current_mouse_position[2], int movement_mode=default_mode) +{ + glm::vec2 previous = {previous_mouse_position[0], previous_mouse_position[1]}; + glm::vec2 current = {current_mouse_position[0], current_mouse_position[1]}; + VFRendering::CameraMovementModes mode = VFRendering::CameraMovementModes(movement_mode); + view.mouseMove(previous, current, mode); + // // std::cerr << "move: "<< previous.x << " " << previous.y << " " << current.x << " " << current.y <<"\n"; +} + +extern "C" void mouse_scroll(float delta) +{ + view.mouseScroll( delta ); +} + +extern "C" void set_camera(float position[3], float center[3], float up[3]) +{ + VFRendering::Options options; + options.set((geometry->min() + geometry->max()) * 0.5f); + options.set({position[0], position[1], position[2]}); + // options.set({center[0], center[1], center[2]}); + options.set((geometry->min() + geometry->max()) * 0.5f); + options.set({up[0], up[1], up[2]}); + view.updateOptions(options); +} + +extern "C" void align_camera(float direction[3], float up[3]) +{ + glm::vec3 d = view.getOption() - view.getOption(); + float dist = glm::length(d); + glm::vec3 dir{direction[0], direction[1], direction[2]}; + glm::normalize(dir); + VFRendering::Options options; + options.set((geometry->min() + geometry->max()) * 0.5f - dist*dir); + // options.set({center[0], center[1], center[2]}); + options.set((geometry->min() + geometry->max()) * 0.5f); + options.set({up[0], up[1], up[2]}); + view.updateOptions(options); +} + +extern "C" void recenter_camera() +{ + view.setOption((geometry->min() + geometry->max()) * 0.5f); +} + +extern "C" void set_rendermode(int mode) +{ + if( mode == 0 ) + mainview_is_system = true; + else + mainview_is_system = false; +} + +extern "C" void set_background(float colour[3]) +{ + glm::vec3 c{colour[0], colour[1], colour[2]}; + view.setOption(c); +} + +extern "C" void set_boundingbox_colour(float colour[3]) +{ + glm::vec3 c{colour[0], colour[1], colour[2]}; + bounding_box_renderer_ptr->setOption(c); +} + +extern "C" void set_miniview(State * state, bool show, int position) +{ + show_miniview = show; + location_miniview = position; + update_renderers(state); +} + +extern "C" void set_boundingbox(State * state, bool show, float line_width) +{ + show_bounding_box = show; + + bool periodical[3]{false, false, false}; + Hamiltonian_Get_Boundary_Conditions(state, periodical); + + float indi_length = std::max(0.1f, glm::length(geometry->max()-geometry->min())*0.1f); + glm::vec3 indis{ indi_length*periodical[0], indi_length*periodical[1], indi_length*periodical[2] }; + int indi_dashes = 5; + float indi_dashes_per_length = 0.9f*(float)indi_dashes / indi_length; + + int n_cells[3]; + Geometry_Get_N_Cells(state, n_cells); + auto cell_size = glm::vec3{0,0,0}; + for( int dim=0; dim<3; ++dim) + { + if( n_cells[dim] > 1 ) + cell_size[dim] = 1; + } + + glm::vec3 c = bounding_box_renderer_ptr->getOption(); + bounding_box_renderer_ptr = std::make_shared( + VFRendering::BoundingBoxRenderer::forCuboid( + view, (geometry->min()+geometry->max())*0.5f, geometry->max()-geometry->min() + cell_size, indis, indi_dashes_per_length)); + bounding_box_renderer_ptr->setOption(c); + bounding_box_renderer_ptr->setOption(line_width); + update_renderers(state); +} + +extern "C" void set_coordinate_system(State * state, bool show, int position) +{ + show_coordinate_system = show; + location_coordinatesystem = position; + update_renderers(state); +} + +extern "C" void set_dots(State * state, bool show) +{ + show_dots = show; + update_renderers(state); +} + +extern "C" void set_arrows(State * state, bool show) +{ + show_arrows = show; + update_renderers(state); +} + +extern "C" void set_spheres(State * state, bool show) +{ + show_spheres = show; + update_renderers(state); +} + +extern "C" void set_boxes(State * state, bool show) +{ + show_boxes = show; + update_renderers(state); +} + +extern "C" void set_isosurface(State * state, bool show) +{ + show_isosurface = show; + update_renderers(state); +} + +extern "C" void set_surface(State * state, bool show) +{ + show_surface = show; + + glm::vec3 max = geometry->max(); + glm::vec3 min = geometry->min(); + if( Geometry_Get_Dimensionality(state) == 3 ) + { + surface_renderer_3d_ptr->setOption( + [min, max] (const glm::vec3& position, const glm::vec3& direction) -> VFRendering::IsosurfaceRenderer::isovalue_type { + (void)direction; + + glm::vec3 _min = min + glm::vec3{0.00001f, 0.00001f, 0.00001f}; + glm::vec3 _max = max - glm::vec3{0.00001f, 0.00001f, 0.00001f}; + + /* Transform position in selected cuboid to position in unit cube [-1,1]^3 */ + glm::vec3 normalized_position = 2.0f * (position - _min) / (_max - _min) - 1.0f; + + /* Calculate maximum metric / Chebyshev distance */ + glm::vec3 absolute_normalized_position = glm::abs(normalized_position); + float max_norm = glm::max(glm::max(absolute_normalized_position.x, absolute_normalized_position.y), absolute_normalized_position.z); + + /* Translate so that the selected cuboid surface has an isovalue of 0 */ + return max_norm - 1.0f; + }); + } + + update_renderers(state); +} + +extern "C" void set_colormap(int colormap) +{ + // std::string colormap_implementation(colormap); + glm::vec3 cardinal_a{1, 0, 0}; + glm::vec3 cardinal_b{0, 1, 0}; + glm::vec3 cardinal_c{0, 0, 1}; + float sign_xy = 1; + float P = 0; + std::string colormap_implementation; + if( colormap == 1 ) + colormap_implementation = R"( + float atan2(float y, float x) { + return x == 0.0 ? sign(y)*3.14159/2.0 : atan(y, x); + } + vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); + } + vec3 colormap(vec3 direction) { + vec3 cardinal_a = vec3()" + std::to_string(cardinal_a.x) + ", " + std::to_string(cardinal_a.y) + ", " + std::to_string(cardinal_a.z) + R"(); + vec3 cardinal_b = vec3()" + std::to_string(cardinal_b.x) + ", " + std::to_string(cardinal_b.y) + ", " + std::to_string(cardinal_b.z) + R"(); + vec3 cardinal_c = vec3()" + std::to_string(cardinal_c.x) + ", " + std::to_string(cardinal_c.y) + ", " + std::to_string(cardinal_c.z) + R"(); + vec3 projection = vec3( dot(direction, cardinal_a), dot(direction, cardinal_b), dot(direction, cardinal_c) ); + float hue = atan2()" + std::to_string(sign_xy) + R"(*projection.x, projection.y) / 3.14159 / 2.0 + )" + std::to_string(P) + R"(; + return hsv2rgb(vec3(hue, 1.0, 1.0)); + } + )"; + else if( colormap == 2 ) + colormap_implementation = VFRendering::Utilities::getColormapImplementation(VFRendering::Utilities::Colormap::BLUERED); + else if( colormap == 3 ) + colormap_implementation = VFRendering::Utilities::getColormapImplementation(VFRendering::Utilities::Colormap::BLUEGREENRED); + else if( colormap == 4 ) + colormap_implementation = VFRendering::Utilities::getColormapImplementation(VFRendering::Utilities::Colormap::BLUEWHITERED); + else if( colormap == 5 ) + colormap_implementation = R"( + vec3 colormap(vec3 direction) { + return vec3(0.5, 0, 0); + } + )"; + else if( colormap == 6 ) + colormap_implementation = VFRendering::Utilities::getColormapImplementation(VFRendering::Utilities::Colormap::WHITE); + else if( colormap == 7 ) + colormap_implementation = R"( + vec3 colormap(vec3 direction) { + return vec3(0.5, 0.5, 0.5); + } + )"; + else if( colormap == 8 ) + colormap_implementation = VFRendering::Utilities::getColormapImplementation(VFRendering::Utilities::Colormap::BLACK); + else + colormap_implementation = VFRendering::Utilities::getColormapImplementation(VFRendering::Utilities::Colormap::HSV); + + view.setOption(colormap_implementation); +} + +extern "C" void set_visibility(float zmin, float zmax) +{ + if( zmin <= -1 ) + zmin = -1.1f; + if( zmax >= 1 ) + zmax = 1.1f; + std::string s_zmin = std::to_string(zmin); + std::string s_zmax = std::to_string(zmax); + std::string visibility = "bool is_visible(vec3 position, vec3 direction) { return direction.z <= "+s_zmax+" && direction.z >= "+s_zmin+"; }"; + vectorsphere_renderer_ptr->setOption(visibility); + arrow_renderer_ptr->setOption(visibility); + dot_renderer_ptr->setOption(visibility); + sphere_renderer_ptr->setOption(visibility); + box_renderer_ptr->setOption(visibility); + surface_renderer_2d_ptr->setOption(visibility); + surface_renderer_3d_ptr->setOption(visibility); + isosurface_renderer_ptr->setOption(visibility); +} + +extern "C" void set_vectorsphere(float pointsize_range_min, float pointsize_range_max) +{ + view.setOption({pointsize_range_min, pointsize_range_max}); +} + +extern "C" void draw() +{ + EmscriptenWebGLContextAttributes attrs; + emscripten_webgl_init_context_attributes(&attrs); + attrs.majorVersion=1; + attrs.minorVersion=0; + EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = emscripten_webgl_create_context("#webgl-canvas", &attrs); + int width, height; + emscripten_webgl_get_drawing_buffer_size(context, &width, &height); + framebufferSizeCallback(context, width, height); + view.draw(); +} + + +extern "C" void update_geometry(State * state) +{ + int nos = System_Get_NOS(state); + int n_cells[3]; + Geometry_Get_N_Cells(state, n_cells); + + // float b_min[3], b_max[3]; + // Geometry_Get_Bounds(state.get(), b_min, b_max); + // glm::vec3 bounds_min = glm::make_vec3(b_min); + // glm::vec3 bounds_max = glm::make_vec3(b_max); + + scalar *spin_pos; + int *atom_types; + spin_pos = Geometry_Get_Positions(state); + atom_types = Geometry_Get_Atom_Types(state); + positions.resize(nos); + int icell = 0; + for( int cell_c=0; cell_c xs(n_cells[0]), ys(n_cells[1]), zs(n_cells[2]); + for( int i = 0; i < n_cells[0]; ++i ) + xs[i] = positions[i].x; + for( int i = 0; i < n_cells[1]; ++i ) + ys[i] = positions[i*n_cells[0]].y; + for( int i = 0; i < n_cells[2]; ++i ) + zs[i] = positions[i*n_cells[0]*n_cells[1]].z; + + if( Geometry_Get_Dimensionality(state) == 3 ) + { + *geometry = VFRendering::Geometry::rectilinearGeometry(xs, ys, zs); + } + else if( Geometry_Get_Dimensionality(state) == 2 ) + { + *geometry = VFRendering::Geometry::rectilinearGeometry(xs, ys, zs); + } + vf->updateGeometry(*geometry); + + auto line_width = bounding_box_renderer_ptr->getOption(); + set_boundingbox(state, show_bounding_box, line_width); +} + +extern "C" void update_directions(State * state) +{ + int nos = System_Get_NOS(state); + // int n_cells[3]; + // Geometry_Get_N_Cells(this->state.get(), n_cells); + // int n_cell_atoms = Geometry_Get_N_Cell_Atoms(this->state.get()); + + auto dirs = System_Get_Spin_Directions(state); + directions.resize(nos); + // int N = directions.size(); + // std::cerr << "N = " << N << std::endl; + for( int idx = 0; idx < nos; ++idx ) + { + directions[idx] = glm::vec3{dirs[3*idx], dirs[3*idx + 1], dirs[3*idx + 2]}; + // if( idx < 20 ) + // std::cerr << idx << " " << directions[idx].x << " " << directions[idx].y << " " << directions[idx].z << std::endl; + } + + // int icell = 0; + // for (int cell_c=0; cell_cupdateVectors(directions); +} + +extern "C" void initialize(State * state) +{ + EmscriptenWebGLContextAttributes attrs; + emscripten_webgl_init_context_attributes(&attrs); + attrs.majorVersion=1; + attrs.minorVersion=0; + + EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = emscripten_webgl_create_context("#webgl-canvas", &attrs); + emscripten_webgl_make_context_current(context); + std::cout << "OpenGL Version: " << glGetString(GL_VERSION) << std::endl; + int width, height; + emscripten_webgl_get_drawing_buffer_size(context, &width, &height); + framebufferSizeCallback(context, width, height); + + // Vectorfield + positions = std::vector(1); + directions = std::vector(1); + auto geo = VFRendering::Geometry::cartesianGeometry({1, 1, 1}, {-1, -1, -1}, {1, 1, 1}); + geometry = std::shared_ptr(new VFRendering::Geometry(geo)); + vf = std::shared_ptr(new VFRendering::VectorField(*geometry, directions)); + + // Default camera + float pos[3]{-25.f, -25.f, 50.f}; + float center[3]{0.f, 0.f, 0.f}; + float up[3]{0.f, 0.f, 1.f}; + set_camera(pos, center, up); + + // General options + view.setOption( + VFRendering::Utilities::getColormapImplementation(VFRendering::Utilities::Colormap::HSV)); + // view.setOption( + // "bool is_visible(vec3 position, vec3 direction) { return position.x >= 0.0; }"); + + // Background + float colour[3]{0.5, 0.5, 0.5}; + set_background(colour); + + // --- Renderers + // Bounding Box + bounding_box_renderer_ptr = std::make_shared( + VFRendering::BoundingBoxRenderer::forCuboid( + view, + (geometry->min()+geometry->max())*0.5f, + geometry->max()-geometry->min(), + (geometry->max()-geometry->min())*0.2f, + 0.5f)); + // Coordinate system + coordinate_system_renderer_ptr = std::make_shared(view); + coordinate_system_renderer_ptr->setOption({1, 1, 1}); + coordinate_system_renderer_ptr->setOption(true); + auto colormap_implementation = VFRendering::Utilities::getColormapImplementation(VFRendering::Utilities::Colormap::HSV); + coordinate_system_renderer_ptr->setOption(colormap_implementation); + + // Vectorsphere + // std::cerr << "//////////////////// INIT " << coordinate_system_renderer_ptr.get() << std::endl; + vectorsphere_renderer_ptr = std::make_shared(view, *vf); + // Dots + dot_renderer_ptr = std::make_shared(view, *vf); + dot_renderer_ptr->setOption(1000); + // Arrows + arrow_renderer_ptr = std::make_shared(view, *vf); + // arrow_renderer_ptr->setOption( + // "bool is_visible(vec3 position, vec3 direction) { return position.x <= 0.0; }"); + // Spheres + sphere_renderer_ptr = std::make_shared(view, *vf); + // sphere_renderer_ptr->setOption( + // "bool is_visible(vec3 position, vec3 direction) { return position.x <= 0.0; }"); + // Boxes + box_renderer_ptr = std::make_shared(view, *vf); + box_renderer_ptr->setOption(0.5); + box_renderer_ptr->setOption(0.5); + box_renderer_ptr->setOption(0.5); + box_renderer_ptr->setOption(false); + // Surface (2D) + surface_renderer_2d_ptr = std::make_shared(view, *vf); + // Surface (3D) + surface_renderer_3d_ptr = std::make_shared(view, *vf); + surface_renderer_3d_ptr->setOption(0.0); + // Isosurface + isosurface_renderer_ptr = std::make_shared(view, *vf); + // isosurface_renderer_ptr->setOption( + // [] (const glm::vec3& position, const glm::vec3& direction) -> VFRendering::IsosurfaceRenderer::isovalue_type { + // (void)direction; + // return position.z * position.z + position.y * position.y + position.x * position.x - 19*19; + // }); + // isosurface_renderer_ptr->setOption(0.0); + // isosurface_renderer_ptr->setOption( + // "float lighting(vec3 position, vec3 normal) { return -normal.z; }"); + // isosurface_renderer_ptr->setOption( + // "bool is_visible(vec3 position, vec3 direction) { return position.x >= 0.0; }"); + + isosurface_renderer_ptr->setOption( + [] (const glm::vec3& position, const glm::vec3& direction) -> VFRendering::IsosurfaceRenderer::isovalue_type { + (void)position; + return direction.z; + }); + isosurface_renderer_ptr->setOption(0.0); + isosurface_renderer_ptr->setOption( + "float lighting(vec3 position, vec3 normal) { return -normal.z; }"); + // isosurface_renderer_ptr->setOption( + // "bool is_visible(vec3 position, vec3 direction) { return position.x >= 0.0; }"); + + // Combine + update_renderers(state); + + // Get correct data + update_directions(state); + update_geometry(state); +} \ No newline at end of file diff --git a/ui-web/web.html b/ui-web/web.html index 75562dc9a..23340638b 100644 --- a/ui-web/web.html +++ b/ui-web/web.html @@ -14,7 +14,7 @@
    - +