Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/doxygen/Doxyfile6
-rw-r--r--doc/python_api/examples/gpu.1.py20
-rw-r--r--doc/python_api/examples/gpu.10.py76
-rw-r--r--doc/python_api/examples/gpu.11.py65
-rw-r--r--doc/python_api/examples/gpu.2.py38
-rw-r--r--doc/python_api/examples/gpu.3.py44
-rw-r--r--doc/python_api/examples/gpu.4.py39
-rw-r--r--doc/python_api/examples/gpu.5.py37
-rw-r--r--doc/python_api/examples/gpu.6.py31
-rw-r--r--doc/python_api/examples/gpu.7.py77
-rw-r--r--doc/python_api/examples/gpu.8.py92
-rw-r--r--doc/python_api/examples/gpu.9.py61
-rw-r--r--doc/python_api/requirements.txt4
-rw-r--r--doc/python_api/rst/info_overview.rst8
-rw-r--r--doc/python_api/sphinx_doc_gen.py72
-rwxr-xr-xdoc/python_api/sphinx_doc_gen.sh8
-rwxr-xr-xdoc/python_api/sphinx_doc_update.py7
17 files changed, 344 insertions, 341 deletions
diff --git a/doc/doxygen/Doxyfile b/doc/doxygen/Doxyfile
index ecd60957f2b..1e430823b10 100644
--- a/doc/doxygen/Doxyfile
+++ b/doc/doxygen/Doxyfile
@@ -38,7 +38,7 @@ PROJECT_NAME = Blender
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = "V2.83"
+PROJECT_NUMBER = "V2.90"
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@@ -51,7 +51,7 @@ PROJECT_BRIEF =
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
# the logo to the output directory.
-PROJECT_LOGO = ../../release/freedesktop/icons/48x48/apps/blender.png
+PROJECT_LOGO = ../../release/freedesktop/icons/scalable/apps/blender.svg
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
# into which the generated documentation will be written. If a relative path is
@@ -1720,7 +1720,7 @@ COMPACT_LATEX = NO
# The default value is: a4.
# This tag requires that the tag GENERATE_LATEX is set to YES.
-PAPER_TYPE = a4wide
+PAPER_TYPE = a4
# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
# that should be included in the LaTeX output. The package can be specified just
diff --git a/doc/python_api/examples/gpu.1.py b/doc/python_api/examples/gpu.1.py
index 831349e5430..a014e69c2d2 100644
--- a/doc/python_api/examples/gpu.1.py
+++ b/doc/python_api/examples/gpu.1.py
@@ -119,4 +119,24 @@ Examples
To try these examples, just copy them into Blenders text editor and execute them.
To keep the examples relatively small, they just register a draw function that can't easily be removed anymore.
Blender has to be restarted in order to delete the draw handlers.
+
+3D Lines with Single Color
+--------------------------
"""
+
+import bpy
+import gpu
+from gpu_extras.batch import batch_for_shader
+
+coords = [(1, 1, 1), (-2, 0, 0), (-2, -1, 3), (0, 1, 1)]
+shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
+batch = batch_for_shader(shader, 'LINES', {"pos": coords})
+
+
+def draw():
+ shader.bind()
+ shader.uniform_float("color", (1, 1, 0, 1))
+ batch.draw(shader)
+
+
+bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
diff --git a/doc/python_api/examples/gpu.10.py b/doc/python_api/examples/gpu.10.py
index a4db576ecc0..2f255b7127d 100644
--- a/doc/python_api/examples/gpu.10.py
+++ b/doc/python_api/examples/gpu.10.py
@@ -1,41 +1,65 @@
"""
-Rendering the 3D View into a Texture
-------------------------------------
+Custom Shader for dotted 3D Line
+--------------------------------
-The scene has to have a camera for this example to work.
-You could also make this independent of a specific camera,
-but Blender does not expose good functions to create view and projection matrices yet.
+In this example the arc length (distance to the first point on the line) is calculated in every vertex.
+Between the vertex and fragment shader that value is automatically interpolated
+for all points that will be visible on the screen.
+In the fragment shader the ``sin`` of the arc length is calculated.
+Based on the result a decision is made on whether the fragment should be drawn or not.
"""
import bpy
-import bgl
import gpu
-from gpu_extras.presets import draw_texture_2d
+from random import random
+from mathutils import Vector
+from gpu_extras.batch import batch_for_shader
-WIDTH = 512
-HEIGHT = 256
+vertex_shader = '''
+ uniform mat4 u_ViewProjectionMatrix;
-offscreen = gpu.types.GPUOffScreen(WIDTH, HEIGHT)
+ in vec3 position;
+ in float arcLength;
+ out float v_ArcLength;
-def draw():
- context = bpy.context
- scene = context.scene
+ void main()
+ {
+ v_ArcLength = arcLength;
+ gl_Position = u_ViewProjectionMatrix * vec4(position, 1.0f);
+ }
+'''
+
+fragment_shader = '''
+ uniform float u_Scale;
+
+ in float v_ArcLength;
- view_matrix = scene.camera.matrix_world.inverted()
+ void main()
+ {
+ if (step(sin(v_ArcLength * u_Scale), 0.5) == 1) discard;
+ gl_FragColor = vec4(1.0);
+ }
+'''
- projection_matrix = scene.camera.calc_matrix_camera(
- context.evaluated_depsgraph_get(), x=WIDTH, y=HEIGHT)
+coords = [Vector((random(), random(), random())) * 5 for _ in range(5)]
- offscreen.draw_view3d(
- scene,
- context.view_layer,
- context.space_data,
- context.region,
- view_matrix,
- projection_matrix)
+arc_lengths = [0]
+for a, b in zip(coords[:-1], coords[1:]):
+ arc_lengths.append(arc_lengths[-1] + (a - b).length)
- bgl.glDisable(bgl.GL_DEPTH_TEST)
- draw_texture_2d(offscreen.color_texture, (10, 10), WIDTH, HEIGHT)
+shader = gpu.types.GPUShader(vertex_shader, fragment_shader)
+batch = batch_for_shader(
+ shader, 'LINE_STRIP',
+ {"position": coords, "arcLength": arc_lengths},
+)
+
+
+def draw():
+ shader.bind()
+ matrix = bpy.context.region_data.perspective_matrix
+ shader.uniform_float("u_ViewProjectionMatrix", matrix)
+ shader.uniform_float("u_Scale", 10)
+ batch.draw(shader)
-bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL')
+bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
diff --git a/doc/python_api/examples/gpu.11.py b/doc/python_api/examples/gpu.11.py
deleted file mode 100644
index 2f255b7127d..00000000000
--- a/doc/python_api/examples/gpu.11.py
+++ /dev/null
@@ -1,65 +0,0 @@
-"""
-Custom Shader for dotted 3D Line
---------------------------------
-
-In this example the arc length (distance to the first point on the line) is calculated in every vertex.
-Between the vertex and fragment shader that value is automatically interpolated
-for all points that will be visible on the screen.
-In the fragment shader the ``sin`` of the arc length is calculated.
-Based on the result a decision is made on whether the fragment should be drawn or not.
-"""
-import bpy
-import gpu
-from random import random
-from mathutils import Vector
-from gpu_extras.batch import batch_for_shader
-
-vertex_shader = '''
- uniform mat4 u_ViewProjectionMatrix;
-
- in vec3 position;
- in float arcLength;
-
- out float v_ArcLength;
-
- void main()
- {
- v_ArcLength = arcLength;
- gl_Position = u_ViewProjectionMatrix * vec4(position, 1.0f);
- }
-'''
-
-fragment_shader = '''
- uniform float u_Scale;
-
- in float v_ArcLength;
-
- void main()
- {
- if (step(sin(v_ArcLength * u_Scale), 0.5) == 1) discard;
- gl_FragColor = vec4(1.0);
- }
-'''
-
-coords = [Vector((random(), random(), random())) * 5 for _ in range(5)]
-
-arc_lengths = [0]
-for a, b in zip(coords[:-1], coords[1:]):
- arc_lengths.append(arc_lengths[-1] + (a - b).length)
-
-shader = gpu.types.GPUShader(vertex_shader, fragment_shader)
-batch = batch_for_shader(
- shader, 'LINE_STRIP',
- {"position": coords, "arcLength": arc_lengths},
-)
-
-
-def draw():
- shader.bind()
- matrix = bpy.context.region_data.perspective_matrix
- shader.uniform_float("u_ViewProjectionMatrix", matrix)
- shader.uniform_float("u_Scale", 10)
- batch.draw(shader)
-
-
-bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
diff --git a/doc/python_api/examples/gpu.2.py b/doc/python_api/examples/gpu.2.py
index d1e8ac32589..4bee9acebe3 100644
--- a/doc/python_api/examples/gpu.2.py
+++ b/doc/python_api/examples/gpu.2.py
@@ -1,19 +1,45 @@
"""
-3D Lines with Single Color
---------------------------
+Triangle with Custom Shader
+---------------------------
"""
import bpy
import gpu
from gpu_extras.batch import batch_for_shader
-coords = [(1, 1, 1), (-2, 0, 0), (-2, -1, 3), (0, 1, 1)]
-shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
-batch = batch_for_shader(shader, 'LINES', {"pos": coords})
+vertex_shader = '''
+ uniform mat4 viewProjectionMatrix;
+
+ in vec3 position;
+ out vec3 pos;
+
+ void main()
+ {
+ pos = position;
+ gl_Position = viewProjectionMatrix * vec4(position, 1.0f);
+ }
+'''
+
+fragment_shader = '''
+ uniform float brightness;
+
+ in vec3 pos;
+
+ void main()
+ {
+ gl_FragColor = vec4(pos * brightness, 1.0);
+ }
+'''
+
+coords = [(1, 1, 1), (2, 0, 0), (-2, -1, 3)]
+shader = gpu.types.GPUShader(vertex_shader, fragment_shader)
+batch = batch_for_shader(shader, 'TRIS', {"position": coords})
def draw():
shader.bind()
- shader.uniform_float("color", (1, 1, 0, 1))
+ matrix = bpy.context.region_data.perspective_matrix
+ shader.uniform_float("viewProjectionMatrix", matrix)
+ shader.uniform_float("brightness", 0.5)
batch.draw(shader)
diff --git a/doc/python_api/examples/gpu.3.py b/doc/python_api/examples/gpu.3.py
index 4bee9acebe3..0c86b52bcf5 100644
--- a/doc/python_api/examples/gpu.3.py
+++ b/doc/python_api/examples/gpu.3.py
@@ -1,45 +1,29 @@
"""
-Triangle with Custom Shader
----------------------------
+Wireframe Cube using Index Buffer
+---------------------------------
"""
import bpy
import gpu
from gpu_extras.batch import batch_for_shader
-vertex_shader = '''
- uniform mat4 viewProjectionMatrix;
+coords = (
+ (-1, -1, -1), (+1, -1, -1),
+ (-1, +1, -1), (+1, +1, -1),
+ (-1, -1, +1), (+1, -1, +1),
+ (-1, +1, +1), (+1, +1, +1))
- in vec3 position;
- out vec3 pos;
+indices = (
+ (0, 1), (0, 2), (1, 3), (2, 3),
+ (4, 5), (4, 6), (5, 7), (6, 7),
+ (0, 4), (1, 5), (2, 6), (3, 7))
- void main()
- {
- pos = position;
- gl_Position = viewProjectionMatrix * vec4(position, 1.0f);
- }
-'''
-
-fragment_shader = '''
- uniform float brightness;
-
- in vec3 pos;
-
- void main()
- {
- gl_FragColor = vec4(pos * brightness, 1.0);
- }
-'''
-
-coords = [(1, 1, 1), (2, 0, 0), (-2, -1, 3)]
-shader = gpu.types.GPUShader(vertex_shader, fragment_shader)
-batch = batch_for_shader(shader, 'TRIS', {"position": coords})
+shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
+batch = batch_for_shader(shader, 'LINES', {"pos": coords}, indices=indices)
def draw():
shader.bind()
- matrix = bpy.context.region_data.perspective_matrix
- shader.uniform_float("viewProjectionMatrix", matrix)
- shader.uniform_float("brightness", 0.5)
+ shader.uniform_float("color", (1, 0, 0, 1))
batch.draw(shader)
diff --git a/doc/python_api/examples/gpu.4.py b/doc/python_api/examples/gpu.4.py
index 0c86b52bcf5..e05290a9442 100644
--- a/doc/python_api/examples/gpu.4.py
+++ b/doc/python_api/examples/gpu.4.py
@@ -1,30 +1,39 @@
"""
-Wireframe Cube using Index Buffer
----------------------------------
+Mesh with Random Vertex Colors
+------------------------------
"""
import bpy
import gpu
+import bgl
+import numpy as np
+from random import random
from gpu_extras.batch import batch_for_shader
-coords = (
- (-1, -1, -1), (+1, -1, -1),
- (-1, +1, -1), (+1, +1, -1),
- (-1, -1, +1), (+1, -1, +1),
- (-1, +1, +1), (+1, +1, +1))
+mesh = bpy.context.active_object.data
+mesh.calc_loop_triangles()
-indices = (
- (0, 1), (0, 2), (1, 3), (2, 3),
- (4, 5), (4, 6), (5, 7), (6, 7),
- (0, 4), (1, 5), (2, 6), (3, 7))
+vertices = np.empty((len(mesh.vertices), 3), 'f')
+indices = np.empty((len(mesh.loop_triangles), 3), 'i')
-shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
-batch = batch_for_shader(shader, 'LINES', {"pos": coords}, indices=indices)
+mesh.vertices.foreach_get(
+ "co", np.reshape(vertices, len(mesh.vertices) * 3))
+mesh.loop_triangles.foreach_get(
+ "vertices", np.reshape(indices, len(mesh.loop_triangles) * 3))
+
+vertex_colors = [(random(), random(), random(), 1) for _ in range(len(mesh.vertices))]
+
+shader = gpu.shader.from_builtin('3D_SMOOTH_COLOR')
+batch = batch_for_shader(
+ shader, 'TRIS',
+ {"pos": vertices, "color": vertex_colors},
+ indices=indices,
+)
def draw():
- shader.bind()
- shader.uniform_float("color", (1, 0, 0, 1))
+ bgl.glEnable(bgl.GL_DEPTH_TEST)
batch.draw(shader)
+ bgl.glDisable(bgl.GL_DEPTH_TEST)
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
diff --git a/doc/python_api/examples/gpu.5.py b/doc/python_api/examples/gpu.5.py
index e05290a9442..2edde46a364 100644
--- a/doc/python_api/examples/gpu.5.py
+++ b/doc/python_api/examples/gpu.5.py
@@ -1,39 +1,26 @@
"""
-Mesh with Random Vertex Colors
-------------------------------
+2D Rectangle
+------------
"""
import bpy
import gpu
-import bgl
-import numpy as np
-from random import random
from gpu_extras.batch import batch_for_shader
-mesh = bpy.context.active_object.data
-mesh.calc_loop_triangles()
+vertices = (
+ (100, 100), (300, 100),
+ (100, 200), (300, 200))
-vertices = np.empty((len(mesh.vertices), 3), 'f')
-indices = np.empty((len(mesh.loop_triangles), 3), 'i')
+indices = (
+ (0, 1, 2), (2, 1, 3))
-mesh.vertices.foreach_get(
- "co", np.reshape(vertices, len(mesh.vertices) * 3))
-mesh.loop_triangles.foreach_get(
- "vertices", np.reshape(indices, len(mesh.loop_triangles) * 3))
-
-vertex_colors = [(random(), random(), random(), 1) for _ in range(len(mesh.vertices))]
-
-shader = gpu.shader.from_builtin('3D_SMOOTH_COLOR')
-batch = batch_for_shader(
- shader, 'TRIS',
- {"pos": vertices, "color": vertex_colors},
- indices=indices,
-)
+shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR')
+batch = batch_for_shader(shader, 'TRIS', {"pos": vertices}, indices=indices)
def draw():
- bgl.glEnable(bgl.GL_DEPTH_TEST)
+ shader.bind()
+ shader.uniform_float("color", (0, 0.5, 0.5, 1.0))
batch.draw(shader)
- bgl.glDisable(bgl.GL_DEPTH_TEST)
-bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
+bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL')
diff --git a/doc/python_api/examples/gpu.6.py b/doc/python_api/examples/gpu.6.py
index 2edde46a364..69af65e163e 100644
--- a/doc/python_api/examples/gpu.6.py
+++ b/doc/python_api/examples/gpu.6.py
@@ -1,25 +1,36 @@
"""
-2D Rectangle
-------------
+2D Image
+--------
+
+To use this example you have to provide an image that should be displayed.
"""
import bpy
import gpu
+import bgl
from gpu_extras.batch import batch_for_shader
-vertices = (
- (100, 100), (300, 100),
- (100, 200), (300, 200))
+IMAGE_NAME = "Untitled"
+image = bpy.data.images[IMAGE_NAME]
-indices = (
- (0, 1, 2), (2, 1, 3))
+shader = gpu.shader.from_builtin('2D_IMAGE')
+batch = batch_for_shader(
+ shader, 'TRI_FAN',
+ {
+ "pos": ((100, 100), (200, 100), (200, 200), (100, 200)),
+ "texCoord": ((0, 0), (1, 0), (1, 1), (0, 1)),
+ },
+)
-shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR')
-batch = batch_for_shader(shader, 'TRIS', {"pos": vertices}, indices=indices)
+if image.gl_load():
+ raise Exception()
def draw():
+ bgl.glActiveTexture(bgl.GL_TEXTURE0)
+ bgl.glBindTexture(bgl.GL_TEXTURE_2D, image.bindcode)
+
shader.bind()
- shader.uniform_float("color", (0, 0.5, 0.5, 1.0))
+ shader.uniform_int("image", 0)
batch.draw(shader)
diff --git a/doc/python_api/examples/gpu.7.py b/doc/python_api/examples/gpu.7.py
index 69af65e163e..56cbb93c61a 100644
--- a/doc/python_api/examples/gpu.7.py
+++ b/doc/python_api/examples/gpu.7.py
@@ -1,37 +1,86 @@
"""
-2D Image
---------
+Generate a texture using Offscreen Rendering
+--------------------------------------------
-To use this example you have to provide an image that should be displayed.
+#. Create an :class:`gpu.types.GPUOffScreen` object.
+#. Draw some circles into it.
+#. Make a new shader for drawing a planar texture in 3D.
+#. Draw the generated texture using the new shader.
"""
import bpy
import gpu
import bgl
+from mathutils import Matrix
from gpu_extras.batch import batch_for_shader
+from gpu_extras.presets import draw_circle_2d
-IMAGE_NAME = "Untitled"
-image = bpy.data.images[IMAGE_NAME]
+# Create and fill offscreen
+##########################################
-shader = gpu.shader.from_builtin('2D_IMAGE')
+offscreen = gpu.types.GPUOffScreen(512, 512)
+
+with offscreen.bind():
+ bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)
+ with gpu.matrix.push_pop():
+ # reset matrices -> use normalized device coordinates [-1, 1]
+ gpu.matrix.load_matrix(Matrix.Identity(4))
+ gpu.matrix.load_projection_matrix(Matrix.Identity(4))
+
+ amount = 10
+ for i in range(-amount, amount + 1):
+ x_pos = i / amount
+ draw_circle_2d((x_pos, 0.0), (1, 1, 1, 1), 0.5, 200)
+
+
+# Drawing the generated texture in 3D space
+#############################################
+
+vertex_shader = '''
+ uniform mat4 modelMatrix;
+ uniform mat4 viewProjectionMatrix;
+
+ in vec2 position;
+ in vec2 uv;
+
+ out vec2 uvInterp;
+
+ void main()
+ {
+ uvInterp = uv;
+ gl_Position = viewProjectionMatrix * modelMatrix * vec4(position, 0.0, 1.0);
+ }
+'''
+
+fragment_shader = '''
+ uniform sampler2D image;
+
+ in vec2 uvInterp;
+
+ void main()
+ {
+ gl_FragColor = texture(image, uvInterp);
+ }
+'''
+
+shader = gpu.types.GPUShader(vertex_shader, fragment_shader)
batch = batch_for_shader(
shader, 'TRI_FAN',
{
- "pos": ((100, 100), (200, 100), (200, 200), (100, 200)),
- "texCoord": ((0, 0), (1, 0), (1, 1), (0, 1)),
+ "position": ((-1, -1), (1, -1), (1, 1), (-1, 1)),
+ "uv": ((0, 0), (1, 0), (1, 1), (0, 1)),
},
)
-if image.gl_load():
- raise Exception()
-
def draw():
bgl.glActiveTexture(bgl.GL_TEXTURE0)
- bgl.glBindTexture(bgl.GL_TEXTURE_2D, image.bindcode)
+ bgl.glBindTexture(bgl.GL_TEXTURE_2D, offscreen.color_texture)
shader.bind()
- shader.uniform_int("image", 0)
+ shader.uniform_float("modelMatrix", Matrix.Translation((1, 2, 3)) @ Matrix.Scale(3, 4))
+ shader.uniform_float("viewProjectionMatrix", bpy.context.region_data.perspective_matrix)
+ shader.uniform_float("image", 0)
batch.draw(shader)
-bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL')
+bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
diff --git a/doc/python_api/examples/gpu.8.py b/doc/python_api/examples/gpu.8.py
index 56cbb93c61a..470bd8a2dad 100644
--- a/doc/python_api/examples/gpu.8.py
+++ b/doc/python_api/examples/gpu.8.py
@@ -1,23 +1,28 @@
"""
-Generate a texture using Offscreen Rendering
---------------------------------------------
+Copy Offscreen Rendering result back to RAM
+-------------------------------------------
-#. Create an :class:`gpu.types.GPUOffScreen` object.
-#. Draw some circles into it.
-#. Make a new shader for drawing a planar texture in 3D.
-#. Draw the generated texture using the new shader.
+This will create a new image with the given name.
+If it already exists, it will override the existing one.
+
+Currently almost all of the execution time is spent in the last line.
+In the future this will hopefully be solved by implementing the Python buffer protocol
+for :class:`bgl.Buffer` and :class:`bpy.types.Image.pixels` (aka ``bpy_prop_array``).
"""
import bpy
import gpu
import bgl
+import random
from mathutils import Matrix
-from gpu_extras.batch import batch_for_shader
from gpu_extras.presets import draw_circle_2d
-# Create and fill offscreen
-##########################################
+IMAGE_NAME = "Generated Image"
+WIDTH = 512
+HEIGHT = 512
+RING_AMOUNT = 10
+
-offscreen = gpu.types.GPUOffScreen(512, 512)
+offscreen = gpu.types.GPUOffScreen(WIDTH, HEIGHT)
with offscreen.bind():
bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)
@@ -26,61 +31,20 @@ with offscreen.bind():
gpu.matrix.load_matrix(Matrix.Identity(4))
gpu.matrix.load_projection_matrix(Matrix.Identity(4))
- amount = 10
- for i in range(-amount, amount + 1):
- x_pos = i / amount
- draw_circle_2d((x_pos, 0.0), (1, 1, 1, 1), 0.5, 200)
-
-
-# Drawing the generated texture in 3D space
-#############################################
-
-vertex_shader = '''
- uniform mat4 modelMatrix;
- uniform mat4 viewProjectionMatrix;
-
- in vec2 position;
- in vec2 uv;
-
- out vec2 uvInterp;
-
- void main()
- {
- uvInterp = uv;
- gl_Position = viewProjectionMatrix * modelMatrix * vec4(position, 0.0, 1.0);
- }
-'''
-
-fragment_shader = '''
- uniform sampler2D image;
-
- in vec2 uvInterp;
-
- void main()
- {
- gl_FragColor = texture(image, uvInterp);
- }
-'''
-
-shader = gpu.types.GPUShader(vertex_shader, fragment_shader)
-batch = batch_for_shader(
- shader, 'TRI_FAN',
- {
- "position": ((-1, -1), (1, -1), (1, 1), (-1, 1)),
- "uv": ((0, 0), (1, 0), (1, 1), (0, 1)),
- },
-)
-
+ for i in range(RING_AMOUNT):
+ draw_circle_2d(
+ (random.uniform(-1, 1), random.uniform(-1, 1)),
+ (1, 1, 1, 1), random.uniform(0.1, 1), 20)
-def draw():
- bgl.glActiveTexture(bgl.GL_TEXTURE0)
- bgl.glBindTexture(bgl.GL_TEXTURE_2D, offscreen.color_texture)
+ buffer = bgl.Buffer(bgl.GL_BYTE, WIDTH * HEIGHT * 4)
+ bgl.glReadBuffer(bgl.GL_BACK)
+ bgl.glReadPixels(0, 0, WIDTH, HEIGHT, bgl.GL_RGBA, bgl.GL_UNSIGNED_BYTE, buffer)
- shader.bind()
- shader.uniform_float("modelMatrix", Matrix.Translation((1, 2, 3)) @ Matrix.Scale(3, 4))
- shader.uniform_float("viewProjectionMatrix", bpy.context.region_data.perspective_matrix)
- shader.uniform_float("image", 0)
- batch.draw(shader)
+offscreen.free()
-bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
+if not IMAGE_NAME in bpy.data.images:
+ bpy.data.images.new(IMAGE_NAME, WIDTH, HEIGHT)
+image = bpy.data.images[IMAGE_NAME]
+image.scale(WIDTH, HEIGHT)
+image.pixels = [v / 255 for v in buffer]
diff --git a/doc/python_api/examples/gpu.9.py b/doc/python_api/examples/gpu.9.py
index 470bd8a2dad..a4db576ecc0 100644
--- a/doc/python_api/examples/gpu.9.py
+++ b/doc/python_api/examples/gpu.9.py
@@ -1,50 +1,41 @@
"""
-Copy Offscreen Rendering result back to RAM
--------------------------------------------
+Rendering the 3D View into a Texture
+------------------------------------
-This will create a new image with the given name.
-If it already exists, it will override the existing one.
-
-Currently almost all of the execution time is spent in the last line.
-In the future this will hopefully be solved by implementing the Python buffer protocol
-for :class:`bgl.Buffer` and :class:`bpy.types.Image.pixels` (aka ``bpy_prop_array``).
+The scene has to have a camera for this example to work.
+You could also make this independent of a specific camera,
+but Blender does not expose good functions to create view and projection matrices yet.
"""
import bpy
-import gpu
import bgl
-import random
-from mathutils import Matrix
-from gpu_extras.presets import draw_circle_2d
+import gpu
+from gpu_extras.presets import draw_texture_2d
-IMAGE_NAME = "Generated Image"
WIDTH = 512
-HEIGHT = 512
-RING_AMOUNT = 10
-
+HEIGHT = 256
offscreen = gpu.types.GPUOffScreen(WIDTH, HEIGHT)
-with offscreen.bind():
- bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)
- with gpu.matrix.push_pop():
- # reset matrices -> use normalized device coordinates [-1, 1]
- gpu.matrix.load_matrix(Matrix.Identity(4))
- gpu.matrix.load_projection_matrix(Matrix.Identity(4))
- for i in range(RING_AMOUNT):
- draw_circle_2d(
- (random.uniform(-1, 1), random.uniform(-1, 1)),
- (1, 1, 1, 1), random.uniform(0.1, 1), 20)
+def draw():
+ context = bpy.context
+ scene = context.scene
+
+ view_matrix = scene.camera.matrix_world.inverted()
+
+ projection_matrix = scene.camera.calc_matrix_camera(
+ context.evaluated_depsgraph_get(), x=WIDTH, y=HEIGHT)
- buffer = bgl.Buffer(bgl.GL_BYTE, WIDTH * HEIGHT * 4)
- bgl.glReadBuffer(bgl.GL_BACK)
- bgl.glReadPixels(0, 0, WIDTH, HEIGHT, bgl.GL_RGBA, bgl.GL_UNSIGNED_BYTE, buffer)
+ offscreen.draw_view3d(
+ scene,
+ context.view_layer,
+ context.space_data,
+ context.region,
+ view_matrix,
+ projection_matrix)
-offscreen.free()
+ bgl.glDisable(bgl.GL_DEPTH_TEST)
+ draw_texture_2d(offscreen.color_texture, (10, 10), WIDTH, HEIGHT)
-if not IMAGE_NAME in bpy.data.images:
- bpy.data.images.new(IMAGE_NAME, WIDTH, HEIGHT)
-image = bpy.data.images[IMAGE_NAME]
-image.scale(WIDTH, HEIGHT)
-image.pixels = [v / 255 for v in buffer]
+bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL')
diff --git a/doc/python_api/requirements.txt b/doc/python_api/requirements.txt
index c2b5b2fd794..263b12eb604 100644
--- a/doc/python_api/requirements.txt
+++ b/doc/python_api/requirements.txt
@@ -1,2 +1,2 @@
-Sphinx==1.8.5
-sphinx_rtd_theme==0.4.3
+Sphinx==3.0.3
+sphinx_rtd_theme==0.5.0rc1
diff --git a/doc/python_api/rst/info_overview.rst b/doc/python_api/rst/info_overview.rst
index e341453fe93..562076c6c43 100644
--- a/doc/python_api/rst/info_overview.rst
+++ b/doc/python_api/rst/info_overview.rst
@@ -253,7 +253,13 @@ Registering a class with Blender results in the class definition being loaded in
where it becomes available alongside existing functionality.
Once this class is loaded you can access it from :mod:`bpy.types`,
-using the bl_idname rather than the classes original name.
+using the ``bl_idname`` rather than the classes original name.
+
+.. note::
+
+ There are some exceptions to this for class names which aren't guarantee to be unique.
+ In this case use: :func:`bpy.types.Struct.bl_rna_get_subclass`.
+
When loading a class, Blender performs sanity checks making sure all required properties and functions are found,
that properties have the correct type, and that functions have the right number of arguments.
diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py
index 68a7a0df075..d4cc1d37262 100644
--- a/doc/python_api/sphinx_doc_gen.py
+++ b/doc/python_api/sphinx_doc_gen.py
@@ -403,32 +403,21 @@ MODULE_GROUPING = {
# -------------------------------BLENDER----------------------------------------
-blender_version_strings = [str(v) for v in bpy.app.version]
-is_release = bpy.app.version_cycle in {"rc", "release"}
-
# converting bytes to strings, due to T30154
BLENDER_REVISION = str(bpy.app.build_hash, 'utf_8')
-if is_release:
- # '2.62a'
- BLENDER_VERSION_DOTS = ".".join(blender_version_strings[:2]) + bpy.app.version_char
-else:
- # '2.62.1'
- BLENDER_VERSION_DOTS = ".".join(blender_version_strings)
+# '2.83.0 Beta' or '2.83.0' or '2.83.1'
+BLENDER_VERSION_DOTS = bpy.app.version_string
if BLENDER_REVISION != "Unknown":
- # '2.62a SHA1' (release) or '2.62.1 SHA1' (non-release)
+ # SHA1 Git hash
BLENDER_VERSION_HASH = BLENDER_REVISION
else:
# Fallback: Should not be used
BLENDER_VERSION_HASH = "Hash Unknown"
-if is_release:
- # '2_62a_release'
- BLENDER_VERSION_PATH = "%s%s_release" % ("_".join(blender_version_strings[:2]), bpy.app.version_char)
-else:
- # '2_62_1'
- BLENDER_VERSION_PATH = "_".join(blender_version_strings)
+# '2_83'
+BLENDER_VERSION_PATH = "%d_%d" % (bpy.app.version[0], bpy.app.version[1])
# --------------------------DOWNLOADABLE FILES----------------------------------
@@ -492,6 +481,11 @@ if _BPY_PROP_COLLECTION_FAKE:
else:
_BPY_PROP_COLLECTION_ID = "collection"
+if _BPY_STRUCT_FAKE:
+ bpy_struct = bpy.types.bpy_struct
+else:
+ bpy_struct = None
+
def escape_rst(text):
""" Escape plain text which may contain characters used by RST.
@@ -512,7 +506,7 @@ def is_struct_seq(value):
def undocumented_message(module_name, type_name, identifier):
- return "Undocumented `contribute <https://developer.blender.org/T51061>`"
+ return "Undocumented, consider `contributing <https://developer.blender.org/T51061>`__."
def range_str(val):
@@ -694,11 +688,13 @@ def py_descr2sphinx(ident, fw, descr, module_name, type_name, identifier):
doc = undocumented_message(module_name, type_name, identifier)
if type(descr) == GetSetDescriptorType:
- fw(ident + ".. attribute:: %s\n\n" % identifier)
+ fw(ident + ".. attribute:: %s\n" % identifier)
+ fw(ident + " :noindex:\n\n")
write_indented_lines(ident + " ", fw, doc, False)
fw("\n")
elif type(descr) == MemberDescriptorType: # same as above but use 'data'
- fw(ident + ".. data:: %s\n\n" % identifier)
+ fw(ident + ".. data:: %s\n" % identifier)
+ fw(ident + " :noindex:\n\n")
write_indented_lines(ident + " ", fw, doc, False)
fw("\n")
elif type(descr) in {MethodDescriptorType, ClassMethodDescriptorType}:
@@ -738,11 +734,14 @@ def pyprop2sphinx(ident, fw, identifier, py_prop):
'''
# readonly properties use "data" directive, variables use "attribute" directive
if py_prop.fset is None:
- fw(ident + ".. data:: %s\n\n" % identifier)
+ fw(ident + ".. data:: %s\n" % identifier)
+ fw(ident + " :noindex:\n\n")
else:
- fw(ident + ".. attribute:: %s\n\n" % identifier)
+ fw(ident + ".. attribute:: %s\n" % identifier)
+ fw(ident + " :noindex:\n\n")
write_indented_lines(ident + " ", fw, py_prop.__doc__)
if py_prop.fset is None:
+ fw("\n")
fw(ident + " (readonly)\n\n")
else:
fw("\n")
@@ -908,7 +907,8 @@ def pymodule2sphinx(basepath, module_name, module, title):
elif issubclass(value_type, (bool, int, float, str, tuple)):
# constant, not much fun we can do here except to list it.
# TODO, figure out some way to document these!
- fw(".. data:: %s\n\n" % attribute)
+ fw(".. data:: %s\n" % attribute)
+ fw(" :noindex:\n\n")
write_indented_lines(" ", fw, "constant value %s" % repr(value), False)
fw("\n")
else:
@@ -1052,6 +1052,7 @@ context_type_map = {
"selected_editable_fcurves": ("FCurve", True),
"selected_editable_objects": ("Object", True),
"selected_editable_sequences": ("Sequence", True),
+ "selected_nla_strips": ("NlaStrip", True),
"selected_nodes": ("Node", True),
"selected_objects": ("Object", True),
"selected_pose_bones": ("PoseBone", True),
@@ -1115,7 +1116,8 @@ def pycontext2sphinx(basepath):
type_descr = prop.get_type_description(
class_fmt=":class:`bpy.types.%s`", collection_id=_BPY_PROP_COLLECTION_ID)
- fw(".. data:: %s\n\n" % prop.identifier)
+ fw(".. data:: %s\n" % prop.identifier)
+ fw(" :noindex:\n\n")
if prop.description:
fw(" %s\n\n" % prop.description)
@@ -1160,7 +1162,8 @@ def pycontext2sphinx(basepath):
i = 0
while char_array[i] is not None:
member = ctypes.string_at(char_array[i]).decode(encoding="ascii")
- fw(".. data:: %s\n\n" % member)
+ fw(".. data:: %s\n" % member)
+ fw(" :noindex:\n\n")
member_type, is_seq = context_type_map[member]
fw(" :type: %s :class:`bpy.types.%s`\n\n" % ("sequence of " if is_seq else "", member_type))
unique.add(member)
@@ -1304,7 +1307,7 @@ def pyrna2sphinx(basepath):
fw(title_string(title, "="))
- fw(".. module:: %s\n\n" % struct_module_name)
+ fw(".. module:: %s.%s\n\n" % (struct_module_name, struct_id))
# docs first?, ok
write_example_ref("", fw, "%s.%s" % (struct_module_name, struct_id))
@@ -1363,9 +1366,11 @@ def pyrna2sphinx(basepath):
type_descr = prop.get_type_description(class_fmt=":class:`%s`", collection_id=_BPY_PROP_COLLECTION_ID)
# readonly properties use "data" directive, variables properties use "attribute" directive
if 'readonly' in type_descr:
- fw(" .. data:: %s\n\n" % prop.identifier)
+ fw(" .. data:: %s\n" % prop.identifier)
+ fw(" :noindex:\n\n")
else:
- fw(" .. attribute:: %s\n\n" % prop.identifier)
+ fw(" .. attribute:: %s\n" % prop.identifier)
+ fw(" :noindex:\n\n")
if prop.description:
fw(" %s\n\n" % prop.description)
@@ -1442,7 +1447,7 @@ def pyrna2sphinx(basepath):
if _BPY_STRUCT_FAKE:
descr_items = [
- (key, descr) for key, descr in sorted(bpy.types.Struct.__bases__[0].__dict__.items())
+ (key, descr) for key, descr in sorted(bpy_struct.__dict__.items())
if not key.startswith("__")
]
@@ -1458,9 +1463,6 @@ def pyrna2sphinx(basepath):
for identifier, py_prop in base.get_py_properties():
lines.append(" * :class:`%s.%s`\n" % (base.identifier, identifier))
- for identifier, py_prop in base.get_py_properties():
- lines.append(" * :class:`%s.%s`\n" % (base.identifier, identifier))
-
if lines:
fw(".. rubric:: Inherited Properties\n\n")
@@ -1484,6 +1486,8 @@ def pyrna2sphinx(basepath):
lines.append(" * :class:`%s.%s`\n" % (base.identifier, func.identifier))
for identifier, py_func in base.get_py_functions():
lines.append(" * :class:`%s.%s`\n" % (base.identifier, identifier))
+ for identifier, py_func in base.get_py_c_functions():
+ lines.append(" * :class:`%s.%s`\n" % (base.identifier, identifier))
if lines:
fw(".. rubric:: Inherited Functions\n\n")
@@ -1536,7 +1540,7 @@ def pyrna2sphinx(basepath):
fw(title_string(class_name, "="))
- fw(".. module:: %s\n" % class_module_name)
+ fw(".. module:: %s.%s\n" % (class_module_name, class_name))
fw("\n")
if use_subclasses:
@@ -1571,7 +1575,7 @@ def pyrna2sphinx(basepath):
# write fake classes
if _BPY_STRUCT_FAKE:
- class_value = bpy.types.Struct.__bases__[0]
+ class_value = bpy_struct
fake_bpy_type(
"bpy.types", class_value, _BPY_STRUCT_FAKE,
"built-in base class for all classes in bpy.types.", use_subclasses=True,
@@ -1711,7 +1715,7 @@ class PatchedPythonDomain(PythonDomain):
fw("def setup(app):\n")
fw(" app.add_stylesheet('css/theme_overrides.css')\n")
- fw(" app.override_domain(PatchedPythonDomain)\n\n")
+ fw(" app.add_domain(PatchedPythonDomain, override=True)\n\n")
file.close()
diff --git a/doc/python_api/sphinx_doc_gen.sh b/doc/python_api/sphinx_doc_gen.sh
index 45cd6a229e5..1c5b9ec0b61 100755
--- a/doc/python_api/sphinx_doc_gen.sh
+++ b/doc/python_api/sphinx_doc_gen.sh
@@ -36,16 +36,10 @@ fi
blender_srcdir=$(dirname -- $0)/../..
blender_version_header="$blender_srcdir/source/blender/blenkernel/BKE_blender_version.h"
blender_version=$(grep "BLENDER_VERSION\s" "$blender_version_header" | awk '{print $3}')
-blender_version_char=$(grep "BLENDER_VERSION_CHAR\s" "$blender_version_header" | awk '{print $3}')
blender_version_cycle=$(grep "BLENDER_VERSION_CYCLE\s" "$blender_version_header" | awk '{print $3}')
-blender_subversion=$(grep "BLENDER_SUBVERSION\s" "$blender_version_header" | awk '{print $3}')
unset blender_version_header
-if [ "$blender_version_cycle" = "release" ] ; then
- BLENDER_VERSION=$(expr $blender_version / 100)_$(expr $blender_version % 100)$blender_version_char"_release"
-else
- BLENDER_VERSION=$(expr $blender_version / 100)_$(expr $blender_version % 100)_$blender_subversion
-fi
+BLENDER_VERSION=$(expr $blender_version / 100)_$(expr $blender_version % 100)
SSH_UPLOAD_FULL=$SSH_UPLOAD/"blender_python_api_"$BLENDER_VERSION
diff --git a/doc/python_api/sphinx_doc_update.py b/doc/python_api/sphinx_doc_update.py
index d3f42b1d26f..4495fca9274 100755
--- a/doc/python_api/sphinx_doc_update.py
+++ b/doc/python_api/sphinx_doc_update.py
@@ -127,11 +127,10 @@ def main():
" f.write('%d\\n' % is_release)\n"
" f.write('%d\\n' % is_beta)\n"
" f.write('%s\\n' % branch)\n"
- " f.write('%d.%d%s\\n' % (bpy.app.version[0], bpy.app.version[1], bpy.app.version_char))\n"
- " f.write('%d.%d%s\\n' % (bpy.app.version[0], bpy.app.version[1], bpy.app.version_char)\n"
+ " f.write('%d.%d\\n' % (bpy.app.version[0], bpy.app.version[1]))\n"
+ " f.write('%d.%d\\n' % (bpy.app.version[0], bpy.app.version[1])\n"
" if (is_release or is_beta) else '%s\\n' % branch)\n"
- " f.write('%d_%d%s_release' % (bpy.app.version[0], bpy.app.version[1], bpy.app.version_char)\n"
- " if is_release else '%d_%d_%d' % bpy.app.version)\n"
+ " f.write('%d_%d' % (bpy.app.version[0], bpy.app.version[1]))\n"
)
get_ver_cmd = (args.blender, "--background", "-noaudio", "--factory-startup", "--python-exit-code", "1",
"--python-expr", getver_script, "--", getver_file)