1
1

Compare commits

...

646 Commits

Author SHA1 Message Date
2cbc328bdc Build bot release pipeline
* downloads builds from builder.blender.org
* generates checksums (still need to cleanup filenames)
* create source archive
* upload to download.blender.org

Next steps
* Next step is to place them in the correct folder
* file permissions download.blender.org
* snap package
* steam packages
* release notes

TODO:
* add more generic functions in master.cfg
* use a separate folder per build
2020-07-03 16:19:50 +02:00
314783f2e7 BuildbotLTS: Project Documentation
Added README.md containing a overview of the project.
2020-07-02 16:56:26 +02:00
fb0f0f4d79 Fluid: Added offset to control frame range
Added an offset field to control when to load the simulation files. Since this is a very small but helpful addition it is in my view safe to commit at this point of the bcon cycle.
2020-07-02 16:31:35 +02:00
f58f09c9a9 Fix T78513: Modifier apply shortcut not displayed
We can't specify the "apply_as" enum value, even though it's the default.
2020-07-02 08:26:59 -04:00
Jeroen Bakker
46ae115b88 Fix T78054: Crash Editing Instanced Objects with Tangent Normals
Similar track as for normal mesh. Don't store the tangent normals in CustomData
of the mesh, but in an unassociated CustomData instance.

Reviewed By: Clément Foucault

Differential Revision: https://developer.blender.org/D8161
2020-07-02 11:34:25 +02:00
Jeroen Bakker
ba2c039b05 Fix T77686: EEVEE environment pass with film transparency
When the film is set to transparent the environment pass should still be
rendered solid. otherwise it renders black.

Reviewed By: Clément Foucault

Differential Revision: https://developer.blender.org/D8046
2020-07-02 11:27:23 +02:00
945d0269e3 Fix crash calculating vertex parent in edit-mode
Regression in deaff945d0.
2020-07-02 19:12:54 +10:00
22197d7f8a Fix T76886: GPencil - Flickering when use Background or Camera image
The problem was if some stroke was empty and the changed flag was set to the last stroke wrongly.
2020-07-02 09:29:30 +02:00
26ffed7466 Cleanup: spelling 2020-07-02 13:03:46 +10:00
afd976a3b4 Fix T76806 UV Editor: Display as Outline do not work on macOS
This is a simple workaround using polyline shader. This is temporary and
a better solution should be found when we refactor the 2D view using DRW.
2020-07-02 02:32:10 +02:00
8bee200e2f Fix T76229 Overlay: Sulpt overlay not working if object use in-front option
Simple fix similar to paint overlay.
2020-07-02 01:41:02 +02:00
52b125a790 Fix alignment test when snap to edge while in vert or edge slide 2020-07-01 17:17:05 -03:00
b6f35531b6 Revert "Fix alignment test when snap to edge while in constraint"
This reverts commit e16972389e.
2020-07-01 17:13:13 -03:00
e16972389e Fix alignment test when snap to edge while in constraint 2020-07-01 16:42:06 -03:00
792cb8bdc7 Fix T77984: Cycles OpenCL error rendering empty scene 2020-07-01 20:01:25 +02:00
755c5c6e4c EEVEE: Shadows: Remove 1 pixel padding to the cubemap
This avoid having a much higher memory footprint as the underlying texture
size allocated by the driver is likely to be much higher (rounded to next
Power of 2 or other alignement requirements).
2020-07-01 19:52:05 +02:00
4723644e7f Fix T67587 Overlay: WeightPaint color blends with background in wireframe mode
Fix this by rendering to the overlay framebuffer when using alpha blend
mode.
2020-07-01 19:15:52 +02:00
6358c7754c Cleanup: Add functions to check the first brush step and symmetry passes
This adds three functions to check the state of the stroke in the
StrokeCache, removing the references to first_time and
mirror_symmetry_pass from the code. This makes easier to understand what
each code path is doing inside of each tool.

Some tools were using mirror_symmetry_pass incorrectly, so this should
also fix unreported bugs with radial and tiling symmetry related to that.

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D8164
2020-07-01 19:03:22 +02:00
bf5a656ff6 GPencil: Fix unreported primitive color always set as Vertex Color
When drawing a primitive, the color was always assigned as vertex color, so it was impossible to change it in the material settings.

Now, the color is set to material color or vertex color as expected.
2020-07-01 18:55:02 +02:00
11a1ddfd30 Fix T77780 Overlay: Weight colors are not in render in the right colorspace
This was just a missing conversion.
2020-07-01 18:53:48 +02:00
f228a8948b Cleanup: Two two spaces around python class 2020-07-01 12:36:00 -04:00
927448a1da Cleanup: typos in comment. 2020-07-01 18:10:05 +02:00
e9d1d1f725 Fix T77655 Overlay: Edit mode + wire drawtype + infront not transparent 2020-07-01 18:00:05 +02:00
2788b0261c Cloth: use the original vertex positions to build internal springs.
In order to ensure correct operation of the rest shape key feature,
it's necessary to create a temporary copy of the mesh with rest
vertex positions to run the BVH lookup on. If the rest shape key
isn't used, there is no need for additional overhead.
2020-07-01 18:16:44 +03:00
f4f00661a5 Fix T78330: Duplicating parented objects does not preserve relationships.
Caused by refactor of duplicate code in rBad6cccf058d0, we need to take
into account the duplication of groups of objects here too...
2020-07-01 17:12:12 +02:00
42be3964eb Cloth: correctly use the rest shape to compute the initial pressure volume.
Computing the original volume should use the rest positions of vertices,
like is done for initializing other parts of the simulation like springs.
Otherwise, features like rest shape key don't work correctly.
2020-07-01 17:42:05 +03:00
b5660f71fe Fix missing GPU image free in background mode
This is legacy code from before Eevee and Workbench rendering in background
mode was supported. Avoid memory leak by only queueing GPU textures to be
freed when we know they have been allocated.

Differential Revision: https://developer.blender.org/D8172
2020-07-01 16:05:54 +02:00
Yevgeny Makarov
5db82be980 Fix file-selector entering the directory on Ctrl-Click 2020-07-01 23:32:51 +10:00
6f0aca7973 Fix T78264: Auto Render stops working after rendering manually
Was caused by weird and feedback-loop based issue from a long time ago.

The auto-render was only happening for nodes which are tagged for exec.
This tag is assigned by edit operations on the tree (for example, when
adding or removing links). It is also set in the render pipeline for
nodes which are to be executed.

The issues comes from the fact that "life updates" during editing did
not clear the need_exec flag, ever. This made it so Auto Render was
working as expected. However, rendering the scene resets need_exec
flags at the end of rendering using ntreeCompositClearTags().
The actual need of such clear is not very clear, but it was making it
so Auto Render does not work after render.

To my knowledge the flag didn't really meant that the node is connected
to the output, so it couldn't have acted as attempt to ignore rendering
of an unused scene. It also should be possible to auto-render even if
node tree itself was never altered.

Long story short: lets ignore need_exec flag in auto-render check and
render scene node if the scene is used by the node.

Differential Revision: https://developer.blender.org/D8171
2020-07-01 15:08:16 +02:00
6a302e6845 UI: Fix alignment in kinematic constraint layout 2020-07-01 09:06:50 -04:00
9324e1117a LibOverride: Tweak more poll functions to prevent illegal operations.
We are likely still missing a lot of things, but most operators that
should not be allowed on liboverrides should now be properly disabled.
2020-07-01 14:45:27 +02:00
23cc2a2628 Fix ID reference counting asserts when freeing COW pose channels.
Take the do_id_user flag into account when freeing custom properties
attached to pose channels, so that pointer properties don't cause
assertion failures when DEG frees its COW instances.
2020-07-01 14:42:55 +03:00
323c5e1e0b Fix T78494: Edge slide crashes
Introduced in recent commit 9c29803255.
2020-07-01 21:28:27 +10:00
86e41ca775 UI: remove internal names (custom-data & loops) from tool-tip 2020-07-01 20:17:19 +10:00
ab0d02b704 UI: use term 'Current Frame' instead of 'Playhead'
Keep terminology consistent, 'Current Frame' is used nearly everywhere.
2020-07-01 20:16:27 +10:00
4387aff99e Transform: generalized custom-data correction support
Support custom-data correction based on surrounding geometry for all
transformation modes of the mesh transform operators.

The is the same logic used in Vert and Edge Slide.

In order not to change the current default behavior,
this property does not affect Vert and Edge Slide modes.
2020-07-01 17:49:38 +10:00
8d3c4aa2d7 Nodes: add utility method to access bsocket 2020-07-01 09:33:35 +02:00
6c7d0aebcb Fix T75483: 3D Text selection obscures text
This avoids logic op and having to draw on the render frame-buffer.
2020-07-01 16:55:20 +10:00
9f634a195d Fix crash drawing non-mesh objects with vertex color
Missing NULL check in f7bbc7cdbb
2020-07-01 16:50:28 +10:00
Stefan Werner
8c4703127a GPU: Apple/Nvidia Proxy check
Apple's Nvidia driverPROXY check also fails. Now the
configuration Apple/Nvidia will also bypass the
Proxy test.

Maniphest Tasks: T78175

Differential Revision: https://developer.blender.org/D8160
2020-07-01 07:55:10 +02:00
d885b1141c DRW: optimize mesh data extraction
Change extraction callbacks to take index ranges instead of calling them
for each mesh element (poly, loop, vert & edge).

This gives a minor overall performance gain in my tests, ~5% on average.

Details:

- Use typed parameter structs and macros for looping over elements.
  Without this, changes to these callbacks is time consuming as changes
  need to be made in many places.
- Avoid iterating over polygon-loops when iterating over polygons
  is sufficient.
- Simplify logic to access adjacent loops for faster line extraction.
- Rename 'loop' iterators to 'poly' (as they take polygon ranges)
  the iterator callbacks can operator on either polygon or loop data.
- Use term 'last' for the last index (inclusive),
  use 'end' when this value (not inclusive).
2020-07-01 14:56:39 +10:00
36d6aa428f Cleanup: spelling 2020-07-01 13:12:24 +10:00
63b8cf4518 Cleanup: python enum quoting 2020-07-01 13:11:39 +10:00
38bbd783b3 Cleanup: undeclared functions (make static) 2020-07-01 13:03:22 +10:00
039bfe0e05 UI: Constraints: Use single column for IK constraint 2020-06-30 22:11:11 -04:00
aeb4792044 Fix T77641 Sculpt mode performance regression in 2.83 2020-07-01 02:11:58 +02:00
a3e6b7c2ce Sculpt: Refactor persistent base to make it usable from other tools
This renames the layer persistent base and adds new API functions to get
the mesh state from the base, so it can be used from other tools and
replaced in the future with a better system.

Reviewed By: sergey

Maniphest Tasks: T77738

Differential Revision: https://developer.blender.org/D8003
2020-06-30 22:02:17 +02:00
981d7381cd Fix T77069 EEVEE: Mix shader with holdout & transparent BSDF fails
This follows Cycles closer.
2020-06-30 21:12:44 +02:00
3562be2bda UI: Cycles: Use Split layout for object motion blur 2020-06-30 13:23:12 -04:00
db7d370657 Fix T78201: Paint color not matching the UI and color picker
The color picker and brush->rgb values are in srgb, but sculpt vertex
colors works in linear, so they need to be converted.

Reviewed By: sergey

Maniphest Tasks: T78201

Differential Revision: https://developer.blender.org/D8111
2020-06-30 19:13:45 +02:00
7dbfc864e6 Outliner: Add auto scrolling during drag and drop
Pan the view when dragging elements near the borders. This uses the same
operator that scrolls the region during modifiers drag and drop.
2020-06-30 10:57:27 -06:00
21c2a64e79 Sculpt: Color filter fill mode
This implements a fill mode in the Color Filter tool, which fills the
entire mesh with a specific color.
As this functionality is part of the color filter, this allows to control
the blending of the fill color with the filter strength.

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D8158
2020-06-30 18:50:13 +02:00
0949140d36 Fix compile error
This is the same issue as in rBbcf49d13e53454.
2020-06-30 18:32:38 +02:00
8262e37d22 Outliner/UI: Show library state icons for data-blocks in "Data API" mode
Previously it was not possible to tell appart a linked data-block from its
override copy. In fact you couldn't tell appart any data-blocks with the same
name (which is possible with linking).
Now we show the library state icon as we do for data-blocks in other display
modes.

Old/new comparison (note the overriden "GEO-head"):
{F8608835} {F8608836}
2020-06-30 18:26:21 +02:00
9693163e2f Pointcache: store owner_id instead of object in PTCacheID
The new simulation type can also reference a point cache, but it is not an object.

Reviewers: brecht

Differential Revision: https://developer.blender.org/D8097
2020-06-30 18:25:08 +02:00
9d80e6a6bb Fix T76480 UI: Proportional Editing Color too Shallow on 2.9a
This changes the drawing by drawing 2 circles with different intensity to
avoid any readability issues. This removes the need for Logic OP which is
implementation dependent.
2020-06-30 18:21:45 +02:00
c2ebf3edb4 Functions: provide dummy multi function
Sometimes it is convenient to be able to return a reference to some
dummy function.
2020-06-30 18:18:48 +02:00
67da2bd23a Functions: add methods to multi-function network classes
Those are necessary to query and modify the network.
2020-06-30 18:18:48 +02:00
d67b7f3b52 Functions: use raw allocator for function signature
This allows multi-functions to have static storage duration.
2020-06-30 18:18:48 +02:00
613f62d15c Functions: add two more customizable multi-functions 2020-06-30 18:18:48 +02:00
d92e5f8950 BLI: support constructing Color4f from float pointer 2020-06-30 18:18:48 +02:00
5c9c3a3234 Nodes: add some utility methods to DerivedNodeTree 2020-06-30 18:18:47 +02:00
e60b6f586b Build: disable OpenXR in make deps for macOS, it's not supported 2020-06-30 18:12:08 +02:00
95ee06d068 Fix T77825: autosave missed too often while sculpting
Previously if a modal operator is active, which might leave Blender in a state
where it's not safe to autosave, it would try again in 10s. Now try again in
10ms so it's much less likely to be missed, since overhead of such a timer is
negligble anyway.

Also remove the debug print that was added to investigate a bug at some point.
2020-06-30 18:12:08 +02:00
d4b9b2c020 Cycles: bump version to 1.13, matching Blender 2.90 release cycle 2020-06-30 18:12:08 +02:00
Miguel Porces
03b8173059 Python API: support setting properties in nested data in node add operator
Differential Revision: https://developer.blender.org/D8093
2020-06-30 18:04:25 +02:00
6add0cc88a LibOverride: Fix lots of poll functions for Object operators.
Prevent operators that should not perform on override data to be
callable in those cases.
2020-06-30 17:52:36 +02:00
438bd82371 Sculpt: Pose Brush option to affect loose parts
This option allows posing meshes with different disconnected elements
using the Pose Brush.

This is achieved by doing the following:
- Creating an ID per vertex that stores the connected component of that vertex.
- By using those IDs, one fake topology connection is created per vertex to the nearest vertex in a different ID. The maximum distance to create that connection is determined by the "Max Element Distance" property. These fake connectivity neighbors are used in the Sculpt API functions iterators, so all the algorithms of the Pose Brush can run without modifications as if everything was part of the same mesh.

In order to make this work, the "Connected only" property of the Pose Brush needs to be disabled. This will add an extra performance cost to the Pose Brush and its preview. To achieve optimal results, max element distance should be as low as possible.

Reviewed By: sergey, campbellbarton

Differential Revision: https://developer.blender.org/D7282
2020-06-30 17:43:37 +02:00
6ac235a6f7 Fix T78038: Cycles crash rendering with volume object and motion blur 2020-06-30 17:36:02 +02:00
27783b4ac7 Fix T78358: random crash editing shader nodes with textures 2020-06-30 16:59:40 +02:00
26cdab02a8 Cleanup: move tests into their corresponding namespace 2020-06-30 16:46:52 +02:00
e0ef574c40 Fix T76337 Overlay: Wireframe: x-ray doesn't deactivate when set to 0
Also fix an issue with antialiasing when xray opacity is set to 0.
2020-06-30 16:12:12 +02:00
49d05687be LibOverride: Add most of Object properties as overridable. 2020-06-30 16:06:32 +02:00
37820651bb BLI: add Array constructor that does not initialize non-trivial types
This should rarely be necessary, but I have a use case coming up soon.
2020-06-30 15:58:29 +02:00
Demeter Dzadik
5b03f49302 Custom Properties: support default values for strings
Differential Revision: https://developer.blender.org/D8102
2020-06-30 15:06:33 +02:00
Vincent Blankfield
e93663363e Fix T77734: random crash when rendering animation
Differential Revision: https://developer.blender.org/D7986
2020-06-30 14:58:50 +02:00
4e9ed1dae9 Fix T78447: Cycles vertex color node not working with hair 2020-06-30 14:36:52 +02:00
8aaca88402 Fix missing relation in compositor depsgraph
This is a fix for c7694185c9. An object without base can still be in the
depsgraph, and then the `VIEW_LAYER_EVAL` node does not exist.

This popped up while @Sergey was looking into T78264.
2020-06-30 14:26:12 +02:00
2a1af5fa48 Cleanup: add missing extern "C" 2020-06-30 14:01:46 +02:00
bdbfdce766 Transform: Reduce the alpha in the Edge Slide drawing
It was very intense and could be confused with the `Even` option.
2020-06-30 09:00:22 -03:00
602cfdeac7 Transform: Add constraint intersection support
Snap to faces and edges is now enhanced in the Edge Slide.

It works in the same way that it already works in the Vert Slide.

Basically it now snaps to the intersection of the slid edge with the
face plane or the edge line.
2020-06-30 08:58:47 -03:00
84901f2eda Nodes: store nodes by bNodeType instead of idname
This is more efficient in most cases.
2020-06-30 13:35:45 +02:00
a6775efb4f Alembic exporter: Fix Windows build errors
Some Windows-specific code needed adjustment after 2917df21ad.
2020-06-30 13:09:44 +02:00
b838a51803 Cleanup: spelling 2020-06-30 20:54:31 +10:00
84f8b47c4c Cleanup: clang-format 2020-06-30 20:50:37 +10:00
0291039079 LibOverride: Add minimal support of liboverrides to shapekeys. 2020-06-30 12:19:11 +02:00
4c3d51326e LibOverride: Refactor 'make override' 3DView operator.
This one now uses a generic 'dependency detection' process to decide
which IDs should be overridden.

This will e.g. allow to override mesh and shapekeys when those have some
values controlled by drivers using an armature bone...
2020-06-30 12:19:11 +02:00
f6394e66ed LibOverride: Fix handling of owned ID pointers in diffing process. 2020-06-30 12:19:11 +02:00
a94a05ec19 LibOverride: Add proper handling of shapekeys to core override code itself. 2020-06-30 12:19:11 +02:00
24c4d3f1f7 LibOverride: Add necessary bits in RNA to deal with embedded IDs paths.
Note that this code is rather rough and slightly hacky, a proper
solution needs to be designed at some point probably, but for now this
should work fine.

As usual, master collections and root node trees remain TODO for now.
2020-06-30 12:19:11 +02:00
7556530bac LibOverride: properly tag owner ID for override refresh, when embedded one is affected.
Note that this is partially WIP code, we only take care of shapekeys
here for now.

Also, move this tagging for liboverride refresh into same chack as the
one for tagging editors, sounds more logical that way.
2020-06-30 12:19:11 +02:00
deb01eb199 LibOverride: Add concept of 'embedded'/'virtual' override.
IDs like embedded ones (master collections, root node trees) cannot be
linked, and thus cannot be real override themselves.

Since they are managed by their owner ID, that one will also have the
overrides for their locally edited properties.

We still need a way to mark them as overridden though, for various UI
and override-internal purposes, this is done using a new ID flag.

Note that since Shae Keys are not linkable, and their pointers are not
editable in RNA, they are also considered as embedded from override
point of view.
2020-06-30 12:19:11 +02:00
34027506f8 Cleanup: ID macros: cast to const ID * instead of ID *.
Allows to pass const pointers without getting complains from the
compiler.
2020-06-30 12:19:11 +02:00
737b0fd762 Cleanup: Use unsigned int when for enum values, instead of signed int. 2020-06-30 12:19:11 +02:00
906d93110e Cleanup: LibOverride: Naming. 2020-06-30 12:19:11 +02:00
fa7d990f10 LibOverride: Fix improper update of depsgraph relations. 2020-06-30 12:19:11 +02:00
0b3313e532 Cleanup: LibOverride: Replace raw pointers checks by proper macros.
This is cleaner, but also crucial to avoid weird issues when behaviors
of those checks are modified...
2020-06-30 12:19:11 +02:00
4783520bfa Cleanup (from clang format)... 2020-06-30 12:19:11 +02:00
2d8c59ccb9 Fix T77095: fix Cycles performance regression with AMD RX cards
Apply the workaround only for known problematic drivers. The latest pro driver
appears to work correctly, hopefully the regular driver will as well once it
is updated to the same OpenCL driver version (3075.13).
2020-06-30 12:01:40 +02:00
9dbe0f9c04 Fix T78367: triangulate modifier does not preserve sculpt vertex colors 2020-06-30 12:00:44 +02:00
2917df21ad Alembic: new exporter based on the USD exporter structure
The Alembic exporter has been restructured by leverages the
`AbstractHierarchyIterator` introduced by the USD exporter. The produced
Alembic files have not changed much (details below), as the Alembic
writing code has simply been moved from the old exporter to the new. How
the export hierarchy is handled changed a lot, though, and also the way
in which transforms are computed. As a result, T71395 is fixed.

Differences between the old and new exporter, in terms of the produced
Alembic file:
- Duplicated objects now have a unique numerical suffix.
- Matrices are computed differently, namely by simply computing the
  evaluated transform of the object relative to the evaluated transform
  of its export-parent. This fixes {T71395}, but otherwise should
  produce the same result as before (but with simpler code).

Compared to the old Alembic exporter, Subdivision modifiers are now
disabled in a cleaner, more efficient way (they are disabled when
exporting with the "Apply Subdivisions" option is unchecked). Previously
the exporter would move to a new frame, disable the modifier, evaluate
the object, and enable the modifier again. This is now done before
exporting starts, and modifiers are only restored when exporting ends.

Some issues with the old Alembic exporter that have NOT been fixed in
this patch:
- Exporting NURBS patches and curves (see T49114 for example).
- Exporting flattened hierarchy in combination with dupli-objects. This
  seems to be broken in the old Alembic exporter as well, but nobody
  reported this yet.

Differential Revision: https://developer.blender.org/D7664

Reviewed By: Sergey
2020-06-30 11:38:46 +02:00
a2b7c84ae8 Cleanup: unused arguments 2020-06-30 19:35:32 +10:00
7860fc9539 Codesign: Wait for unsigned directory to appear
Solves problem with different order of codesign server startup and
mount of network shares: avoids exception happening when server is
started prior to the mounts are ready.
2020-06-30 11:21:00 +02:00
53799d3ed2 Codesign: CLeanup, redundant semicolon 2020-06-30 11:20:37 +02:00
4176adaf96 Fix T78455: Failed assert when opening a viewport panel
Mistake from 1fa40c9f8a.
2020-06-30 10:47:49 +02:00
55ae55af66 Cleanup: remove unnecessary namespace specifiers 2020-06-30 10:35:50 +02:00
5d2005cbb5 UI: Add shortcuts for grease pencil modifier panels
See rB1fa40c9f8a81 for more details. The implementation is the same.
The only difference to the mesh modifier  commit is a slight rework of
edit_modifier_invoke_properties in order to pass through to check for
other keymap items with the same shortcut.
2020-06-29 21:04:45 -04:00
Adrian Newton
1d29822fa9 UI: Alphabetize grease pencil modifier list
The Texture Mapping Modifier was out of place

Differential Revision: https://developer.blender.org/D7474
2020-06-29 19:47:38 -04:00
062a843bfb EEVEE: Fix undefined behavior when using BSDF nodes inside volume shaders
This should fix T76171 Eevee bsdf shaders glitches
2020-06-30 01:32:00 +02:00
Adrian Newton
f28e59bd74 UI: Use single column for cycles ray visibility checkboxes
Differential Revision: https://developer.blender.org/D7612
2020-06-29 17:12:19 -04:00
b29fd7bab8 GPencil: Cleanup - Replace gp_ prefix with gpencil_
This was missing in previous cleanup commits.
2020-06-29 22:37:11 +02:00
421ac266d0 UI: Tweak Cache File Template Layout
The template was disorganized and didn't fit with the new layout style.

|          Old         |         New          |
| {F8641166 size=full} | {F8641167 size=full} |

Differential Revision: https://developer.blender.org/D8113
2020-06-29 16:36:19 -04:00
a71d3bd2df UI: Don't show modifier operation reports on button press
The reports should only show when using shortcuts.
2020-06-29 15:06:13 -04:00
1fa40c9f8a UI: Add shortcuts for modifier panels
The shortcuts act on the modifier with its panel under the mouse.
The following shortcuts are enabled by default:
  - Remove modifier: X, Delete
  - Apply modifier: Ctrl A
  - Duplicate modifier: Shift D
More shortcuts can be added in the keymap.

Each panel can now store a custom data RNA pointer, and a new
function is added to get the custom data for the panel under the
cursor. This custom data could be used to refactor the "List Panel
System" to generalize it and integrate it further with RNA.

The same functionality will be added  in further commits where it
applies to constraints, grease pencil modifiers, and effects.

Differential Revision: https://developer.blender.org/D8031
2020-06-29 15:00:25 -04:00
4f8a881715 Fix T78444: Duplicate "From Radius" in Cast Modifier UI
This button was meant to be "Use Transform"
2020-06-29 14:41:46 -04:00
5d31ef0820 Remove Threaded Sculpt option
Threaded Sculpt is now always enabled by default. If it causes
performance problems compared single threaded sculpt it should be
considered a bug.

Reviewed By: sergey

Maniphest Tasks: T77638

Differential Revision: https://developer.blender.org/D7960
2020-06-29 18:20:09 +02:00
3aced11d79 Nodes: rename node_socket.c to node_socket.cc
I have to add some C++ code in callbacks for socket types
for the new particle system.
2020-06-29 17:36:21 +02:00
bcf49d13e5 Fix compile error on Apple Clang
Needs to compile with `CMAKE_OSX_DEPLOYMENT_TARGET` of 10.14 at least to
have `std::optional<>::value()` available. So we have to increase the
minimum required compiler version, but that requires more changes. Just
fix the build error for now.
2020-06-29 17:28:37 +02:00
937d89afba UI: Show library status icons in search menus, rather than letter prefix
Rather than a `L` (linked), `O` (overridden) or `M` (missing) prefix for the
name, show the existing library status icons. See D7999 for screenshots.

Note that when using preview icons, or if the search menu contains items with
own icons (e.g. brush icons), we still fallback to the prefix solution.

Zero or fake user is still indicated with a prefix.

Differential Revision: https://developer.blender.org/D7999

Reviewed by: Bastien Montagne, William Reynish
2020-06-29 17:28:37 +02:00
5024c54271 RNA: properly tag 'embedded' ID pointers as owned.
This is important at several level, mainly for overrides currently.

Note that this also includes shape keys, since from RNA point of view
those are also 'embedded' (they are not editable, not linkable, ...).
2020-06-29 17:28:04 +02:00
583cfe2596 LibOverride: ignore all data arrays of meshes.
Those are not overridable, and comparing them is... costly.
2020-06-29 17:28:04 +02:00
28f4e5cd6b RNA: Add a way to prevent automatic addition of 'no ownership' flag for ID pointer properties.
Since makesrna runs after all properties have been defined, we have to
remember with a new internal flag when we explicitely disable the
'PROP_PTR_NO_OWNERSHIP' flag for a property.

Otherwise there was no way to do so for ID pointer properties...
2020-06-29 17:28:04 +02:00
febb2351ad Fix ShapeKeys not being deleted together with their owner ID.
Consistency with e.g. copying (copying a mesh also duplicates its
shapekey typically).

Baby step towards getting rid of this horrible ID, some day...

Note that for now we only do that when taking BMain into account, fancy
code dealing with non-main IDs and such has to deal with those itself.
2020-06-29 17:28:04 +02:00
dcdffe719f Fix ID_swap not keeping original recalc flags.
Note that we might be missing more things there still, maybe some tags
e.g. should also be swapped?
2020-06-29 17:28:04 +02:00
b723d38812 Add utils to remove an ID from the relations runtime data in Main. 2020-06-29 17:28:04 +02:00
cff688ce7b Cleanup: make some type casts explicit
Doing this so that I turn this into a .cc file.
2020-06-29 17:27:03 +02:00
bf87df3485 Fix T78323: Enable Unified and Secondary colors for Scultp Vertex Colors
The report does not include any file, but probably that file is using the
settings for unified colors, which are currently not available in the UI,
so it always paints black. This enables unified colors and secondary
colors for sculpt vertex colors, so it should solve that issue.

Unified color does not make much sense now as the Paint tool is the only
one that has paint capabilities, but it will do in the future when
sculpt and paint at the same time is enabled and the paint capability is
added to more tools.

Reviewed By: sergey

Maniphest Tasks: T78323

Differential Revision: https://developer.blender.org/D8136
2020-06-29 17:25:27 +02:00
3118636f81 Fix Smear Tool too weak on high poly meshes
The defaults for the Smear tool were making it too weak in high poly
meshes, specially the alpha/pressure option enabled by default. Now this
option is disabled, it has a linear pressure curve and less spacing.

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D8134
2020-06-29 17:23:43 +02:00
9c29803255 Transform: Draw edge considered in the slide value
Useful for identifying how the value is used and which edge
is considered in the snap.
2020-06-29 12:18:59 -03:00
7f1fd1818a Fix T77946: Problem snapping with "Project onto Self" on a curve with generated geometry 2020-06-29 11:38:35 -03:00
164a49f047 GPencil: Cleanup function names replace gp_ by gpencil_ prefix (cont) 2020-06-29 15:47:49 +02:00
a351eb0726 GPencil: Cleanup function names replace gp_ by gpencil_ prefix 2020-06-29 15:47:43 +02:00
399dbb1aa3 GPencil: Cleanup - Rename some functions from gp_ to gpencil_ 2020-06-29 15:47:38 +02:00
1cda374906 GPencil: Cleanup - Rename annotation function to new prefix
These functions were using the old gpencil or gp prefix.
2020-06-29 15:47:24 +02:00
13e2337da7 Fix T78361: Crash When Modelling
Forgot to free the tangent layer for bmesh in the drawing code.
2020-06-29 15:38:17 +02:00
cb5bfb32ba Depsgraph: introduce blender::deg namespace
Reviewers: sergey

Differential Revision: https://developer.blender.org/D8150
2020-06-29 15:21:30 +02:00
81fb08ad57 Fix T74290 Face Dots in front (X-ray) Visual Glitch
This is not likely to be the silver bullet but it fix the common case.
2020-06-29 15:02:29 +02:00
76e252ead3 Cleanup: use blender::bke namespace in simulation.cc 2020-06-29 14:47:00 +02:00
85cde12bff Cleanup: reduce code indentation and simplify some code flow 2020-06-29 09:33:57 -03:00
2476c47d75 VSE: Fix type mismatch introduced in rB8bcfa0d1fb9f
Pass `IMB_Proxy_Size` to `seq_can_use_proxy` and remove duplicate check.
2020-06-29 14:32:00 +02:00
18bff53c99 BLI: remove blender::Optional in favor of std::optional
`std::optional` can be used now, because we switched to C++17.
2020-06-29 14:30:06 +02:00
4fc5233467 Fix T78401: Convert Mesh to Grease Pencil with empty material slot crashes
Also create the 'simple fill' in case there are only empty material
slots.

Maniphest Tasks: T78401

Differential Revision: https://developer.blender.org/D8151
2020-06-29 14:23:10 +02:00
9feb0d5f2e Fix T74220 Mantaflow Color Mapping not ignoring alpha value
And also remove some sRGB hack.
2020-06-29 14:19:52 +02:00
bd6cc282d2 Fix T61573 GPencil: Annotation thickness doesn't work with on OSX
This fixes the issue by using the polyline shader but this does not gives
the best results.

A better way would be to have a dedicated shader for the lines to avoid
the line break at every angle change.
2020-06-29 14:19:52 +02:00
Stefan Werner
0d2e628964 Build: Point ISPC explicitly to the location of LLVM libraries.
Sometimes the ISPC build could pick up the system LLVM librareis
instead of the ones in the Blender lib directory.
2020-06-29 14:06:00 +02:00
9afad1de44 Fix compiler warning for deprecated variable use 2020-06-29 13:13:03 +02:00
8e494f7a45 Cleanup: minor change missed last commit 2020-06-29 21:03:42 +10:00
5a6145f32c Cleanup: use designated initializes for mesh extract structs
Better readability and allows adding new struct members without
adding empty slots to every 'MeshExtract' struct.
2020-06-29 20:52:19 +10:00
38c9deeb5a Cleanup: use std::make_unique instead of blender::make_unique
This is possible, because we use C++17 now.
2020-06-29 12:35:27 +02:00
2def6f5568 Fix T78415: Particle Edit mode Add brush with a radius > 181px crashes
Caused by short overflow, change to int instead.

Maniphest Tasks: T78415

Differential Revision: https://developer.blender.org/D8148
2020-06-29 12:03:39 +02:00
784911a4a0 Cleanup: rename namespace DotExport to dot 2020-06-29 11:53:17 +02:00
b51d6e8012 Cleanup: Use blender namespace in blenkernel 2020-06-29 11:48:22 +02:00
Jeroen Bakker
0baa000b85 Fix T73892: EEVEE Viewport Render Ignores Render As Wire
In the viewport an object can be set to be displayed as wire. When
rendering the viewport this setting is ignored and follows the
path or doing a final render. This patch will add an exception
when rendering a viewport render.

Reviewed By: Clément Foucault

Differential Revision: https://developer.blender.org/D8043
2020-06-29 08:19:14 +02:00
3b630bd563 Fix T78229: Playhead not refreshing when area is maximized
No other areas were tagged for redraw.
2020-06-29 08:13:48 +02:00
41bfdeaa53 Fix T78176: Sequencer renders playhead line twice 2020-06-29 07:37:40 +02:00
b21ba5e579 GPencil: Cleanup - replace loop with LISTBASE_FOREACH 2020-06-28 17:13:10 +02:00
3bdfd8c916 Fix T78353: GPencil: Make Circle select only select points inside circle
Now, instead of select the section of the stroke that is below circle, only the points inside circle are selected.

Also fixed a bug when segment selection mode is enabled.

Differential Revision: https://developer.blender.org/D8141
2020-06-28 16:51:28 +02:00
Tuomo Keskitalo
fa2c7709ff Deps Builder: Fix OSL build error.
When there is no system python OSL will fail to build the documentation.
Given we don't ship the documentation, this is safe to disable.

Originally part of D8123
2020-06-28 08:00:28 -06:00
6d8b6aec18 Fix T74024 Faces missing, weird faces added
Workaround by adding a special case for that driver in gpu_extensions.c
2020-06-28 15:51:15 +02:00
Ankit
340130719f Use const in nodeFindSocket
Since the function only iterates over the input members,
and matches their identifiers, `bNode *`can be `const`.

All other usages of the `nodeFindSocket` use it with
other functions that modify the node. (e.g.: ``nodeAddLink` )
But an exporter needs the node to be a `const`, so this
creates unnecessary and slightly unsafe design changes.

Reviewed By: JacquesLucke

Differential Revision: https://developer.blender.org/D8142
2020-06-28 15:27:29 +05:30
df8847de6d Fix T77549 GPUTexture: Crash caused by NULL parameter to glBindTextures...
... or glBindSamplers.
2020-06-28 01:44:17 +02:00
59d2dd2237 UI: Remove duplicate modifier error message
Thanks to J. Fran Matheu for pointing this out.
2020-06-27 17:56:29 -04:00
4ea92f775e Fix compile error in recent commit
This was introduced in rBd7b10e5b740fe2.
2020-06-27 21:07:20 +02:00
ff82049642 Functions: add MutableAttributesRef data structure
This will be used to reference the content of a CustomData structure
in C++ code, that does not need to know who owns the data but only
works with it.
2020-06-27 20:58:35 +02:00
e91d581167 Fix T78259: Proportional editing does not work in particle editing
And better identify what is bool and what is flag in the
proportional edit properties.
2020-06-27 14:19:59 -03:00
a55eac5107 UI: Better Grouping of FFmpeg audio settings
Some audio render settings were hidden in the scene properties. These 
settomgs belong in the render properties as they affect the output when 
using ffmpeg video.

Fixes T49241

Differential Revision: https://developer.blender.org/D8137
2020-06-27 12:00:38 -04:00
9f5fae1f2c Revert "Fix T78259: Proportional editing does not work in particle editing"
This reverts commit 5c48592ccd.
Ii introduced a stupid error.

Fix T78352
2020-06-27 11:13:02 -03:00
d7b10e5b74 Fix T78337: Fix crash when use GPencil merge without materials
If the object hadn't material, the index of material was negative.
2020-06-27 15:59:38 +02:00
2350159101 Cleanup: make it easier to check if a CPPType is a specific compile time type 2020-06-27 13:28:46 +02:00
563670ff9e Fix T78336: Gpencil selection unstable
The selection with the tweak tool was inprecise because it was using the bounding box and if the point was in a straight line in the border or in the corners it was very hard to select.

For this tool is better don't use the bounding box check.
2020-06-27 10:55:33 +02:00
fec2b2a809 Palettes: Remove threshold parameter when extract from images
Using a number greater than 1 produce a huge number of entries in the palette because any small variation in the color create a new entry.

Remove the threshold reduce the precision of the color extracted, but always is better than having a palette with thounsands of colors.

Related to T78317

Still pending the memory crash when it's impossible to allocate memory for the palette in the popover, but with this change I don't think we get this error again.
2020-06-27 10:40:37 +02:00
4b96f47831 Docs: correct invalid doxygen params & references 2020-06-27 15:43:20 +10:00
c1c5dff7c0 Doc: correct bpy.msgbus arguments 2020-06-27 13:48:18 +10:00
b7b57e7155 PyDoc: Update Python Package Requirements 2020-06-26 13:24:53 -04:00
daa815d7fc UI: Use term 'Blend Mode' 2020-06-26 13:24:53 -04:00
84e1e0cf95 Fix T78170: Mantaflow Crash | Whitewater Particles Baking
Fixed issue in the upstream Mantaflow repository.
2020-06-26 18:29:43 +02:00
fb68a30af6 Fix crash compiling Cycles OpenCL, after recent TBB changes 2020-06-26 17:44:24 +02:00
9c1d85117c Cleanup: Fix strict compiler warning about variable shadowing
Thanks Howard for double-checking!
2020-06-26 17:29:50 +02:00
06e24f6c91 Fix sample color operator not updating the color in the UI
Reviewed By: sergey

Differential Revision: https://developer.blender.org/D8110
2020-06-26 17:20:12 +02:00
4817426b3e Fix Color Filter not updating during modal operator
The code for tagging the updates was wrong

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D8109
2020-06-26 17:18:10 +02:00
0c98bb75cb Fix Edit Voxel Size label rotation and scale in rotated objects
Previously, the text rotation was always calculated in object space, so
the text rotation always had the object rotation applied. Now the
rotation is calculated in world space, so it always aligns correctly to
the view. Same applies to text scale not taking into account the object
position.

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D8068
2020-06-26 17:17:00 +02:00
5c48592ccd Fix T78259: Proportional editing does not work in particle editing
This is a long-standing bug, possibly proportional editing never worked
in particle mode.

Some parameter definitions in the transform code are scattered and
sometimes duplicated.

Proportional editing is a parameter that depends only on the Convert
type and not `spacetype`, `CTX_` or `obedit_type`.
2020-06-26 12:03:04 -03:00
e6e67da4ea Fix T78129: No audio playback with sound strip pasted to a new scene
Add DEG_relations_tag_update(bmain).

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D8130
2020-06-26 17:00:47 +02:00
4006cd2d2c Refactor: use new api for expand in blenloader
This is part of T76372.
2020-06-26 16:53:10 +02:00
9b4e621db0 Fix T77410: Effects doesn't update when Offset property is set
Enabling offset property caused strip to produce `SEQ_CACHE_STORE_RAW`
type image, which is kept in temp cache and is not invalidated.

Change update functions for all properties of effect strips that affect image
to `rna_Sequence_invalidate_raw_update`.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D8132
2020-06-26 16:30:03 +02:00
26b428186a Fix T78295: reload scripts disables Cycles render passes in the compositor
Don't auto update render passes in nodes when unregistering render passes or
quitting Blender, this should only happen on explicit user action to change the
engine or passes.
2020-06-26 16:18:46 +02:00
d10990af79 Refactor: use new api for lib linking id properties 2020-06-26 16:04:09 +02:00
5f4a66c0e8 Fix T78049: Wrong icon for add cone tool 2020-06-26 09:53:27 -04:00
d33e715259 Fix T77669: Copy-pasting strip twice crashes Blender
In rBeaee2b411935 I removed BKE_sequencer_base_clipboard_pointers_store from
paste function, because I wanted pasted strip to always reference copied
strip, not recently pasted one. This worked well with ordinary strips, but not
if they reference ID.

Add back BKE_sequencer_base_clipboard_pointers_store call.

I thought that always referencing original strip would be more correct approach,
but it doesn't matter now. Referencing recently pasted seems to be cleanest way
to do this.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D8129
2020-06-26 15:51:08 +02:00
8bcfa0d1fb Fix detecting proxy images.
Pass is_proxy_image to functions where images are loaded instead of comparing
image size to render size.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D8128
2020-06-26 15:51:08 +02:00
f26d7268bf Silence warning introduced in f7f3b2d318
Call function `BKE_scene_multiview_view_prefix_get` to ensure ext is not
NULL.

This already should happen in `seq_image_strip_is_multiview_render` though.

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D8081
2020-06-26 15:51:08 +02:00
ea4fa8abb0 Refactor: use new api for lib linking gpencil, palette, key, simulation, ipo and library 2020-06-26 15:44:56 +02:00
14e313bbb2 Refactor: use new api for lib linking hair, pointclout, volume, material, texture and image 2020-06-26 15:39:04 +02:00
26d0fb3aef Fix T78269: Mirror modifier lost UV offset only
Also fixed an issue with a decorator in the same subpanel
2020-06-26 09:37:50 -04:00
96d657cb84 Refactor: use new api for lib linking curve, mesh, cachefiles, armature and vfont 2020-06-26 15:30:43 +02:00
8b070b8a71 Fix T78199: reload scripts error when icon is used multiple times in toolbar 2020-06-26 15:26:51 +02:00
65f07a39b5 Refactor: use new api for lib linking sound, text, camera, light, latt and mball 2020-06-26 15:24:20 +02:00
9ec6b69ed1 Refactor: use new api for lib linking movieclip, world, lightprobe, speaker, paint curve and brush 2020-06-26 15:05:25 +02:00
1ce2457551 Refactor: use new api for lib linking linestyle, object, nodetree and action 2020-06-26 14:52:57 +02:00
0e75aa44fb Fix T78304: Scaling without a constraint axis shows wrong parameters in Adjust Last operator panel
Caused by {rB600fd1c6f0ed}
2020-06-26 09:14:51 -03:00
25eb0c9cf4 Fix T78151: Vertex/Edge Slide after enabling 'Even' doesn't cancel properly
Problem introduced by rBcf42721f
2020-06-26 09:14:51 -03:00
ede6e739dd Refactor: use new api for lib linking collection, scene and workspaces 2020-06-26 13:56:27 +02:00
e707ed43ef Build: show helpful error when accidentally using GNUMakefile on Windows 2020-06-26 11:55:34 +02:00
e1da4f09fc Fixed typo in previous commit (UV fix); had nonsensical self-test. 2020-06-26 07:35:50 -04:00
8b119a5524 Fix T76996: Don't allow baking when domain is not in object mode
This does not work, because the fluid modifier is not called when the
object is e.g. in edit mode. Another possible fix would be to switch
to object mode when baking starts automatically. However, I think it
is reasonable to simply not allow baking while the domain is in edit mode.

Reviewers: sebbas

Differential Revision: https://developer.blender.org/D7848
2020-06-26 13:29:15 +02:00
da2e71be2f Fix T78310: tweak layout in denoising panel to have more spacing 2020-06-26 13:19:34 +02:00
74c49492c2 Cycles: add experimental preference to replace magic debug value 256
Previously you'd have to run with --debug-value 256, now just make it
a preference so the Debug panel can be always available for developers.
2020-06-26 13:19:34 +02:00
d865ad59fc Cleanup: Depsgraph, remove unused Base * parameter
The `Base *` parameter of `DepsgraphRelationBuilder::build_object()` was
made redundant by c7694185c9. This commit actually removes it.

No functional changes.
2020-06-26 12:56:33 +02:00
e3a420c477 Fix T76199 Bevel materials "bleed" over faces.
When there is an odd number of segments, bevel has an ambiguous
choice as to which side face to use to copy face attributes from
and to use for UV (and other loops that have math function) interpolation.
We used to make choice arbitrarily, which led to visually inconsistent
results. Now there is tie-breaking code, face with lexicographic lowest
value in vector with these elements:
  (1) connected component (in math-layer space) id
  (2) selected (0) vs unselected (1)
  (3) material index
  (4,5,6): z,x,y components of face center, in that order.
2020-06-26 06:43:01 -04:00
c7694185c9 Fix T78071: Drivers reading object visibility not updating automatically
A driver reading `Object.hide_viewport` would break when that object was
hidden. Hidden objects don't have the `OBJECT_BASE_FLAGS` node in the
depsgraph, but that node was required for the driver to work.

Now the `OBJECT_FROM_LAYER` component (which optionally contains the
`OBJECT_FROM_LAYER` node) has explicit `ENTRY` and `EXIT` nodes, which
are used for relations with other components. These relations now remain
valid, even when the `OBJECT_FROM_LAYER` node is absent.

Differential Revision: https://developer.blender.org/D8124

Reviewed By: sergey
2020-06-26 12:34:38 +02:00
2a72421cfb Fix error when filtering in Outliner "Blender File" mode with libraries
Steps to reproduce were:
* Load factory settings
* Link any library
* Change to "Blender File" display mode in Outliner
* Enable filtering
* -> Assert fails

This may have had further side-effects for linked IDs.
Checked with Bastien, the NULL-check seems reasonable. It was initially there
but removed in d74f9c4b7b.

Fine to backport.
2020-06-26 12:30:59 +02:00
2036b9771e Fluid: Fix typos from OpenVDB update
Some typos that were not noticed in 9951858942.
2020-06-26 11:48:02 +02:00
646ef49e19 Cleanup: use percentage formatting
`str.format` and `f-string` use was minimal.
Prefer using a single style of string formatting
unless an alternative is more widely adopted.
2020-06-26 12:33:19 +10:00
2db4a81fe4 deps: Fix build issue with USD on windows.
When doing a release build the TBB debug libs are not
set which was causing an error during the configure
phase of USD, so always set them even if not used.
2020-06-25 18:50:28 -06:00
c9d94c2aba Fix T71539 EEVEE: Still redraw during playback when it shouldn't 2020-06-26 01:36:44 +02:00
46815753cf Fix T78237 UI: NLA colors black and broken
This was caused by missing GL blend. This patch also fix the broken
strip appearance under timeline zoom.
2020-06-26 01:27:36 +02:00
62aa103d48 Fix for T78191: Timeline lines changing thickness
Fixes issue where lines in timeline are sometimes double-width when hovering in area.

Differential Revision: https://developer.blender.org/D8116

Reviewed by Brecht Van Lommel
2020-06-25 14:53:59 -07:00
af4e68357b UI: Slightly simplify box style panel margin offset
A small cleanup to use fewer if statements.
2020-06-25 16:16:29 -04:00
fd0d8c710b Fix T77878: Hard minimum for voxel size of the remesh modifier
This patch fixes T77878 in the same way that T72747 was fixed.
A hard minimum for the voxel size was added to avoid an arithmetics error.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D8027
2020-06-25 18:42:43 +02:00
31ad8bda74 Fix T77204: Mantaflow Initial velocity bugged?
Always initialize the particle velocity of newly sampled particles to 0 if there are no initial velocities. Clearing the grid source makes sure that new particles will get a 0 velocity - and not interpolated from the associated grid.
2020-06-25 18:03:08 +02:00
Cody Winchester
2dad5a9754 Fix: Displace Modifier UV Layer UI not a pointer
The displace modifier's uv_layer property should be a pointer in the new
UI like the other modifiers use.

Differential Revision: https://developer.blender.org/D7990
2020-06-25 11:57:06 -04:00
230b9eac69 Fix T70193 Overlay: Grid floor disappears for orthographic camera
The fix is to disable the fading for in the +Z direction in this case.
2020-06-25 18:01:47 +02:00
47ff54b008 GPencil: Ensure previous brush is set when change mode
In some situations, the previous brush is not set. This usually happens with previous version files.

Related to T78155.
2020-06-25 17:13:34 +02:00
495b0eff9a Fix T77285: Incorrect Mantaflow fluid border interaction when collision is turned off
Incorrect boolean for 'open' domain borders.
2020-06-25 16:49:47 +02:00
b77fc70d13 Cleanup: Don't use "Use" in boolean names 2020-06-25 16:38:50 +02:00
dd9c0dbf5e Experimental Features: Use different "categories" for different features
Right now not all the features available there have the same level of
polishing. So I split the existing options in:

* New Features [Particles Nodes]
* Prototypes [Hair]
* Debugging [Undo]

Differential Revision: https://developer.blender.org/D8121
2020-06-25 16:33:19 +02:00
79c2581bfa Fix T78238: issue loading existing .blend files with Optix viewport denoiser
Also add additional validation to ensure the denoiser is supported before
trying to use it.
2020-06-25 15:39:10 +02:00
2b9ac1de49 Fix incorrect Python API description for bpy.data.version
Ref T76058
2020-06-25 15:39:10 +02:00
d0693c160a Revert "Fix T78071: Drivers reading object visibility not updating automatically"
This reverts commit baa0da3e69.

The commit causes some issues I didn't foresee, I'd rather take the time
to do it properly than hastily try and commit a fix for it.
2020-06-25 15:18:59 +02:00
fd5c185beb Cleanup: spelling 2020-06-25 23:14:36 +10:00
baa0da3e69 Fix T78071: Drivers reading object visibility not updating automatically
An object can be targeted by a driver that reads its `hide_viewport` or
`hide_render` property. The existence of such a driver will create a
relation between the 'sync base flags' depsgrpah node, and the datablock
containing the driver. When the object is hidden, however, it has no
base, and thus it had no 'sync base flags' depsgraph node. To support
such a driver, that depsgraph node is now always added, but for hidden
objects it will just be a no-op. If the node is not used by anything, it
will be automatically disconnected and have a negligible effect on
performance.
2020-06-25 14:33:56 +02:00
8903368490 Cycles: add support for rendering sculpt vertex colors
Ref T78041
2020-06-25 13:54:05 +02:00
d69bb06db8 Build: remove unused lapack/hidapi/mingw32 build infrastructure
Ref T76184
2020-06-25 13:15:55 +02:00
d3283ef121 Build: upgrade OpenImageDenoise to 1.2.1
This requires ISPC for building OpenImageDenoise, so that is now added as
a dependency as well. Blender itself does not need ISPC for building so it
is not included as part of the precompiled libraries.

Differential Revision: https://developer.blender.org/D7641
2020-06-25 13:00:58 +02:00
6431b11381 Build: upgrade a few smaller Linux/macOS only libraries to latest versions
* jemalloc 5.2.1
* xml2 2.9.10
* bzip2 1.0.8
* ffi 3.3
* lzma 5.2.5
* ssl 1.1.1g
* sqlite 3.31.1

Ref T78252
2020-06-25 13:00:58 +02:00
b30df982d2 Fix viewport denoising not working if start samples higher than total samples 2020-06-25 13:00:58 +02:00
64a584b38a Python API: add methods to allow copying of constraints.
Blender has an operator to do Copy & Paste of constraints between
objects and bones, but no simple method to do that directly via
the Python API is provided. This adds a copy() method to object
and pose bone constraint collections.

Differential Revision: https://developer.blender.org/D8112
2020-06-25 12:10:18 +03:00
6b53e0adbc Better fix for crash ( with gpu only ) on render end/abort introduced in 0dced1a 2020-06-25 11:06:56 +02:00
cdb69c20e1 Cleanup: spelling 2020-06-25 16:57:52 +10:00
0c4f4de23b Edit Mesh: minor drawing optimization extracting loop data
Gives around ~5% speedup on high poly meshes.
2020-06-25 16:57:52 +10:00
bcc086584f Fix unreported 1 pixel offset when drawing with GPencil
This bug was introduced in d82c3d8615

Reviewers: @fclem
2020-06-25 08:17:23 +02:00
ec776f18ff Fix crashing on render end/abort introduced in 0dced1a 2020-06-24 23:51:57 +02:00
eace5903cb Fix T67741 EEVEE: World update don't update lightcache if one viewport uses lookdev
Just a matter of not clearing the updating flag in this case.
2020-06-24 22:12:09 +02:00
2ad8e16c2d Fix T78215 EEVEE: incorrect Render Passes results when using motion blur
This was caused by a missing DRWPass initialization.

Now we create the passes for every timestep but avoid clearing the
buffer after the first sample.
2020-06-24 21:34:29 +02:00
0dced1af34 Fix T78149: Cycles memory leak rendering animation with Embree 2020-06-24 18:48:16 +02:00
b468023aa1 VR: Properly support outputting sRGB swapchain buffers
Latest SteamVR OpenXR updates brought OpenGL support, but only with sRGB
buffers. I think for DirectX it's the same now.
It's not a big issue for us to use sRGB buffers, so that's what I will
do for now. That way we shouldn't need hardcoded exceptions for specific
runtimes that don't transform linear buffers correctly.
2020-06-24 18:42:53 +02:00
5cfbc722d0 Fix T78047: Fix failing denoiser tests on windows
When we switched to MSVC2019 and C++17 we seemingly
managed to trigger a code-gen bug with MSVC in the
AVX code-path.

This change works around the issue by (hopefully
temporary) disabling the optimizer for the fast_exp2f4
function, given it is only used in a single pass
of the denoiser and nowhere else, this is luckily
not as bad as it could have been.

Once the compiler is fixed or a different fix is
available we'll have to revisit this.

Details and link to the repro posted to MS is
available in T78047
2020-06-24 10:42:00 -06:00
c2ab069dfc Fluid: Use OpenVDB as the default cache format for liquids too
With the updated OpenVDB setup, it is now perfectly fine to use OpenVDB for liquid domains.
2020-06-24 18:38:56 +02:00
ac0852cea0 Fluid: Fix OpenVDB compiler warnings
Kudos to brecht for noticing the issue
2020-06-24 18:36:42 +02:00
ba380fc0bf Fix T78213: Windows 10 Build Errors: Extern_Manaflow error messages
Kudos to LazyDodo for figuring this out
2020-06-24 18:01:34 +02:00
baff05ad1c UI: Add Free Handle Types to CurveProfile Widget
Under the hood the CurveProfile widget (used for bevel custom profiles)
uses a bezier curve, but right now though it only supports two of the
bezier curve handle types, vector and auto. This patch adds support for
free handles and adds all of the logic for editing them.

This is the first step to the ability to import and export curve objects
in the widget.

There's some code cleanup in curveprofile.c. Movement for handles and
control points is abstracted to functions there rather than happening
in interface_handlers.c.

An "Apply Preset" button is also added, which solves a confusing issue
where you apply a preset, then change the number of samples and the
preset doesn't change. The button makes it clear that the preset needs
to be reapplied.

Reviewed By: Severin

Differential Revision: https://developer.blender.org/D6470
2020-06-24 11:50:01 -04:00
ec7510b458 Fix T67319 DRW: Large objects gets incorrectly culled
To avoid this we just bypass culling if the object is too big to avoid
float precision issues.
2020-06-24 17:44:57 +02:00
560a73610b Fix artifact in Clay Strips when producing large deformations
The clay strips brush tip tests distances against a cube with beveled Z
aligned edges. This cube was positioned with its center in the surface
of the mesh, so when producing large deformation, some vertices that
should be deformed were positioned further than the cube's Z dimension,
so they were left behind, producing artifacts.
This displaces and deforms the local space to position the brush tip
cube (now a prism) towards the deformation direction, so more vertices
can be included, removing most of these artifacts.

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D8004
2020-06-24 17:29:58 +02:00
255638d223 Fix Surface Smooth not taking the sculpt mask into account
The sculpt mask was hardcoded to 0.0

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D8071
2020-06-24 17:28:51 +02:00
2b522e3345 Fix T78188: Sculpt mask glitching after using sculpt vertex colors
The face sets color copy to the GPU was done outside of the loop,
probably after a merge error in a rebase.

Also, the default color was initialized using the wrong type.

Reviewed By: sergey

Maniphest Tasks: T78188

Differential Revision: https://developer.blender.org/D8106
2020-06-24 17:27:53 +02:00
0f7851ee79 Fix T78192: Draw Face Sets tool not updating the viewport color
The draw face set tool always needs to redraw the nodes, but it only
needs the full update when in smooth mode because it moves the vertices.

Reviewed By: sergey

Maniphest Tasks: T78192

Differential Revision: https://developer.blender.org/D8108
2020-06-24 17:27:01 +02:00
b4e1571d0b Cleanup: compiler warnings 2020-06-24 17:25:44 +02:00
c78b831e69 Fix T78073 EEVEE: new motion blur and overscan produce wrong render
This was caused by the override viewport size not being maintained after
DRW_cache_restart().

Also this fixes issue with the inv_size not being updated correctly.
2020-06-24 17:22:31 +02:00
e761d0bdc9 Fix T78080: group node has incorrect sockets after changing group
It was only checking for the identifier, but the type has to be equivalent as well.

Reviewers: mano-wii, brecht

Differential Revision: https://developer.blender.org/D8101
2020-06-24 16:53:46 +02:00
ff0df7c546 UI: Add Extrude Manifold Icon
Differential Revision: https://developer.blender.org/D8016
2020-06-24 11:32:06 -03:00
9951858942 Fluid: Improved OpenVDB support for fluid caches
This commit makes uses of the new OpenVDB IO in Mantaflow (introduced in 781f783a66ac).

From now on, fluid cache files in OpenVDB format will contain a list of grids per frame (before: one .vdb file per grid per frame). Besides regular grids, particle systems are also stored using OpenVDBs PointGrid data structures.

All older cache formats will remain fully functional:
- Uni caches (.uni) files are still available from the UI and can be used as before
- Raw caches (.raw) are no longer available from the UI, but loading them is still possible
- Old OpenVDB caches (one .vdb per grid) can no longer be baked either, but loading them is still possible.

It is also no longer possible to choose file formats for 'Noise' and 'Particles'. Instead there are now options to set the file format for 'Volumetric' and for 'Mesh' data.

Known issues (planned to be resolved soon):
- OpenVDB files are currently not taking into consideration the clipping value (FluidDomainSettings). Empty cells are therefore being written too. Depending on the scene, this can make file sizes unnecessarily large.
- Domains are not being exported at their world position. Instead they are always clipped to the origin.
2020-06-24 16:07:35 +02:00
9fe64948ab Fluid: Updated Mantaflow source with latest OpenVDB changes
This updated set of Mantaflow files includes the improved  OpenVDB file IO. With this update it is finally possible to store multiple grids per file. It is also possible to save particle systems and particle data to OpenVDB files.
2020-06-24 16:07:35 +02:00
6fec2e4db0 Cleanup: fix typo in denoiser menu 2020-06-24 16:01:47 +02:00
d645525dae Fix missing WITH_CYCLES_EMBREE in the build configurations 2020-06-24 15:51:08 +02:00
3cfb687b55 Cleanup: make it possible to include util_tbb.h in any order 2020-06-24 15:28:00 +02:00
23b5e10dbd Fix T78112: VSE Sequencer/Preview crash after fullscreen
The region refresh callback wasn't called, which in the VSE ensures valid
region sizes and removes handlers of invisible regions.
2020-06-24 15:22:01 +02:00
669befdfbe Cycles: add Intel OpenImageDenoise support for viewport denoising
Compared to Optix denoise, this is usually slower since there is no GPU
acceleration. Some optimizations may still be possible, in avoid copies
to the GPU and/or denoising less often.

The main thing is that this adds viewport denoising support for computers
without an NVIDIA GPU (as long as the CPU supports SSE 4.1, which is nearly
all of them).

Ref T76259
2020-06-24 15:17:36 +02:00
0a3bde6300 Cycles: add denoising settings to the render properties
Enabling render and viewport denoising is now both done from the render
properties. View layers still can individually be enabled/disabled for
denoising and have their own denoising parameters.

Note that the denoising engine also affects how denoising data passes are
output even if no denoising happens on the render itself, to make the passes
compatible with the engine.

This includes internal refactoring for how denoising parameters are passed
along, trying to avoid code duplication and unclear naming.

Ref T76259
2020-06-24 15:17:36 +02:00
88157b9efb Python API: support integer default for bpy.props.EnumProperty
This must match the specified number in enum items, and is supported for both
static and dynamic enums. Previously dynamic enums did not support a default
value at all.
2020-06-24 15:17:36 +02:00
073ab4703e Fix build error on Windows after recent changes 2020-06-24 15:17:36 +02:00
756e664e4f Fix T77913: Incorrect handling of negative-scale bit in DRWResourceHandle
Reviewers: fclem

Differential Revision: https://developer.blender.org/D8103
2020-06-24 14:42:46 +02:00
e59712b7c8 Sculpt: rename default vertex color layer name from Col to Color
No need for abbreviation here, and helps avoid conflicts with old vertex
color layers.

Ref T76659
2020-06-24 14:32:06 +02:00
e389c05410 Cleanup: move TBB includes into own header 2020-06-24 14:32:06 +02:00
a6c59863d3 EEVEE: Fix crash when using motion blur without postfx blur 2020-06-24 14:27:47 +02:00
dd328be0f0 Fix memory leak calculating deform modifiers in edit-mode
This bug goes back to 2.80 but doesn't seem to have been reported.
2020-06-24 22:13:27 +10:00
074929d1c5 MEM_guardedalloc: allow freeing const arrays with MEM_SAFE_FREE
'const' arrays couldn't use this macro with GNUC.
2020-06-24 22:13:27 +10:00
9b3dfbe651 Fix T77672 EEVEE: Reflections with reflection plane broken (regression) 2020-06-24 13:50:20 +02:00
be0622533d Fix T78190 EEVEE: Render passes broken in final render
This was caused by the step motion blur implementation.
`DRW_cache_restart` was reseting the cache and cause
`EEVEE_renderpasses_postprocess` to not work inside
`EEVEE_render_read_result`.
2020-06-24 13:23:43 +02:00
6f5a9dd8de Fix T78172: Undo crash due to IDTemplate operations missing undo push.
This should be included in 2.83 as well.
2020-06-24 12:51:08 +02:00
5c8e349c28 Cleanup: Replace GSet with Edgeset in Cloth Brush 2020-06-24 15:31:10 +10:00
d295261330 Text: add replace all operator
D8032 by @Poulpator with minor edits
2020-06-24 15:00:12 +10:00
be8f2c698e Cleanup: redundant self assignment 2020-06-24 14:30:18 +10:00
1daaac75b5 Cleanup: clang-format 2020-06-24 14:23:54 +10:00
31dd80e0de Cleanup: unused struct members 2020-06-24 14:19:25 +10:00
a9e5e58e16 Cleanup: unused functions 2020-06-24 14:19:24 +10:00
5b9bb688e7 UI: ShaderFX: Manually add X/Z labels for rim lighting
These need to be labeled manually  because offset is a #PROP_PIXEL.

Matches other changes made in rBbb4cef71eeaf36aa61187d47b8a8ae06ba55f7c0
2020-06-23 19:21:06 -04:00
49234c15e2 UI: Cycles: Use Title Case 2020-06-23 17:54:09 -04:00
c26abd1c29 Fix T66934 Overlay: "Outline Selected" overlay doesnt affect armatures
This is a really small fix. Could be included in 2.83 LTS branch.
2020-06-23 23:45:46 +02:00
b0449cac66 API Docs: Small edits to recent commit
- Revert string formatting change
- Add missing text edit
2020-06-23 17:10:07 -04:00
d82c3d8615 Fix T62961 EEVEE: Viewport refresh when hovering widgets
We now bypass EEVEE's rendering if the TAA accumulation has ended.
2020-06-23 22:59:55 +02:00
5fbbe1fca9 UI: Remove unnecessary ellipsis 2020-06-23 16:56:37 -04:00
65006bfaf4 Snapping: Snap to the origin of Light and Camera objects
I see no reason to ignore them.
This is not a limitation.
2020-06-23 16:18:01 -03:00
ede1a247d8 Fix camera snapping in camera View
The `T_CAMERA` flag was being set in the wrong place.
2020-06-23 16:14:06 -03:00
11a390e85e GPencil: Implement antialiasing parameter to Pixel FX
Related to T78153

Differential Revision: https://developer.blender.org/D8100
2020-06-23 19:20:02 +02:00
f3a8192ef7 Refactor: use new api for lib linking mask, windowmanager and screen
This is part of T76372.
2020-06-23 17:55:23 +02:00
2dd60e6c2c Fix T77830: Crash in VR session when opening material preview
Draw-manager mutex has to be set before activating OpenGL/GPU context.
Otherwise, parallel jobs (like preview rendering) may try to activate
the context from another thread.

Also: Use WM wrappers for activating/releasing OpenGL context, which
have an additional assert check.

Suggest to backport this for 2.83.1.
2020-06-23 17:28:53 +02:00
1e0426da7c Refactor: move more modifier specific code out of readfile.c 2020-06-23 17:25:44 +02:00
9ef5cc44a6 Refactor: move blenloader code of bevel modifier 2020-06-23 17:08:39 +02:00
56f9529775 Refactor: move blenloader code of curve profile to blenkernel 2020-06-23 17:08:39 +02:00
f345625ded Fix T77712: Crash on proxied rig, custom bone shape, driver targeting rig
It turns out that
`DepsgraphNodeBuilder::build_object_data_geometry(Object *object, bool
is_object_visible)` was called for the custom shape with
`is_object_visible=false` when there are drivers, and
`is_object_visible=true` when there aren't any.
2020-06-23 17:03:36 +02:00
adcb7a2ce7 Refactor: move blenloader code of surface deform modifier 2020-06-23 16:51:43 +02:00
8b59b97c10 Refactor: move more blenloader code into modifier files 2020-06-23 16:42:08 +02:00
f7bbc7cdbb Sculpt Vertex Colors: Initial implementation
Sculpt Vertex Colors is a painting system that runs inside sculpt mode, reusing all its tools and optimizations. This provides much better performance, easier to maintain code and more advanced features (new brush engine, filters, symmetry options, masks and face sets compatibility...). This is also the initial step for future features like vertex painting in Multires and brushes that can sculpt and paint at the same time.

This commit includes:
  - SCULPT_UNDO_COLOR for undo support in sculpt mode
  - SCULPT_UPDATE_COLOR and PBVH flags and rendering
  - Sculpt Color API functions
  - Sculpt capability for sculpt tools (only enabled in the Paint Brush for now)
  - Rendering support in workbench (default to Sculpt Vertex Colors except in Vertex Paint)
  - Conversion operator between MPropCol (Sculpt Vertex Colors) and MLoopCol (Vertex Paint)
  - Remesher reprojection in the Voxel Remehser
  - Paint Brush and Smear Brush with color smoothing in alt-smooth mode
  - Parameters for the new brush engine (density, opacity, flow, wet paint mixing, tip scale) implemented in Sculpt Vertex Colors
  - Color Filter
  - Color picker (uses S shortcut, replaces smooth)
  - Color selector in the top bar

Reviewed By: brecht

Maniphest Tasks: T72866

Differential Revision: https://developer.blender.org/D5975
2020-06-23 16:28:50 +02:00
27972c4225 UI: Don't expand bevel active tool setting 2020-06-23 10:16:28 -04:00
4284ddefab Fix mistake in bevel versioning
Use the correct modifier struct name
2020-06-23 10:07:22 -04:00
bab2b02507 Cleanup: style, raw multi-line string sphinx updater 2020-06-23 23:32:47 +10:00
6d639a606c Docs: quiet deprecation warning, add missing context members 2020-06-23 23:32:36 +10:00
Tobias Heinke
23f8ab4250 API docs: intro overhaul
- Update terminology, spelling, formatting.
- Rename screen to workspace.
- Update for 2.8 UI changes.
2020-06-23 23:13:10 +10:00
Jeroen Bakker
0aa7c11788 Fix T77803: IK Degrees of freedom drawing glitch
Forgot to update the lineOutput what resulted in that the sphere was not
rendered on all platforms.

Reviewed By: Clément Foucault

Differential Revision: https://developer.blender.org/D8098
2020-06-23 14:51:15 +02:00
Jeroen Bakker
8f97a64dec Fix T77893: Crash drawmanager threading custom data
Tangent normals were temporarily saved in the original given layers but
the typeinfo wasn't updated. This lead to several issues since we
changed the threading of the mesh extraction.

This patch stores the tangent normals in a temporary custom data on the
stack this way the typemap doesn't need to be updated.

Still need to run the tests for an hour to see if it is fixed

Reviewed By: Clément Foucault, Philipp Oeser

Differential Revision: https://developer.blender.org/D8095
2020-06-23 14:33:26 +02:00
439b40e601 EEVEE: Motion Blur: Add accumulation motion blur for better precision
This revisit the render pipeline to support time slicing for better motion
blur.

We support accumulation with or without the Post-process motion blur.

If using the post-process, we reuse last step next motion data to avoid
another scene reevaluation.

This also adds support for hair motion blur which is handled in a similar
way as mesh motion blur.

The total number of samples is distributed evenly accross all timesteps to
avoid sampling weighting issues. For this reason, the sample count is
(internally) rounded up to the next multiple of the step count.

Only FX Motion BLur: {F8632258}

FX Motion Blur + 4 time steps: {F8632260}

FX Motion Blur + 32 time steps: {F8632261}

Reviewed By: jbakker

Differential Revision: https://developer.blender.org/D8079
2020-06-23 14:04:41 +02:00
Jeroen Bakker
cc3e808ab4 Animation: Only update timeline header during playback
The header of all SPACE_ACTIONs are tagged for redraw. Only when the
action editor is showing the timeline it is needed. No noticeable
performance increase. But better to save some CPU cycles.

Reviewed By: Sybren Stüvel

Differential Revision: https://developer.blender.org/D8074
2020-06-23 13:19:45 +02:00
072a224a28 Cleanup: remove some dead code 2020-06-23 12:23:46 +02:00
ef8aca65d8 Cleanup: renamed do_draw_overlay to do_draw_paintcursor
To make a better distinction with region overlay.
2020-06-23 12:07:50 +02:00
Jeroen Bakker
bbb2e0614f Performance: Draw play head as an overlay
When playing back animations a playhead is updated in all the animation editors.
The drawing of the playhead is part of the drawing of the main region
`RGN_TYPE_WINDOW` that redraws the whole region.

This change will draw the play head and window scrollers when updating the
screen. This affects the Action editor, Timeline, Graph editor, NLA editor and
Sequence editor. There is noticeable speedup when using complex animation files.

Spring 02_020_A.anim.blend fps went from 11.8 to 12.5 when showing a timeline
and a action editor on a Ryzen 1700.

* When playing back animation the markers don't jump up/down when near the
  frame. This could be added back.

Reviewed By: Brecht van Lommel

Differential Revision: https://developer.blender.org/D8066
2020-06-23 12:03:17 +02:00
87ceff3d1b Preferences: New experimental settings for particle system and hair
This replaces the cmake options `WITH_NEW_OBJECT_TYPES` and
`WITH_NEW_SIMULATION_TYPE` with two experimental userpref settings:

* `use_new_particle_system`: Enables the point cloud type and the simulation editor.
* `use_new_hair_type`: Only displays the add-operator in the add menu for now.

Note, in the current state you can't do anything productive with the new particle
system or the new hair type. Features will be added step by step in the upcoming
weeks and months.

Reviewers: brecht

Differential Revision: https://developer.blender.org/D8096
2020-06-23 11:30:46 +02:00
13a5b954c3 Cleanup: USD, move code from USD to blender::io::usd namespace
No functional changes.
2020-06-23 11:07:52 +02:00
309cfbceaa Transform: default to median center instead of bounds
When neither bounds or median is selected, snapping the cursor to
the selection was using bounds which often doesn't give useful results.

Resolves T78135
2020-06-23 18:35:06 +10:00
3a3708cefb Functions: Multi Function Network
A multi-function network is a graph data structure, where nodes are
multi-functions (or dummies) and links represent data flow.
New multi-functions can be derived from such a network. For that
one just has to specify two sets of sockets in the network that
represent the inputs and outputs of the new function.

It is possible to do optimizations like constant folding on this
data structure, but that is not implemented in this patch yet.

In a next step, user generated node trees are converted into a
MFNetwork, so that they can be evaluated efficiently for many particles.

This patch also includes some tests that cover the majority of the code.
However, this seems to be the kind of code that is best tested by some
.blend files. Building graph structures in code is possible, but is
not easy to understand afterwards.

Reviewers: brecht

Differential Revision: https://developer.blender.org/D8049
2020-06-23 10:16:14 +02:00
Yevgeny Makarov
c24b1c060d Fix T77743: Number pad key-map items missing from search 2020-06-23 17:55:36 +10:00
4040cb438f Cleanup: use doxy sections for BLI read/write headers
Add reference between the read/write functions too.
2020-06-23 16:38:52 +10:00
ed68fee665 Fix T78146: Crash using scroll bars
Regression in 2fdca5bd19
2020-06-23 15:22:59 +10:00
374e412813 Correct recent 'name' -> 'filepath' rename (missed Collada) 2020-06-23 14:58:38 +10:00
3f6f89a06b Cleanup: move text.c comments to the struct/flag declarations
Also update/correct some of the comments.
2020-06-23 14:09:13 +10:00
3f89322f08 Cleanup: remove Text.nlines
This isn't needed and wasn't properly updated when new-lines were added.
2020-06-23 13:48:19 +10:00
bdb49890cb Cleanup: use static sets instead of tuples 2020-06-23 13:30:21 +10:00
fd65055b69 Cleanup: A few small comment & naming changes in bevel 2020-06-22 22:41:02 -04:00
6703c7f7f1 Bevel: Refactor profile type input to use an enum
This will allow the easier addition of a constant radius mode in the
future and some changes in the UI to mirror the recent similar change
from "Only Vertices" to the "Affect" enum.
2020-06-22 22:25:55 -04:00
716a8241d3 Cleanup: rename 'name' to 'filepath' for DNA types
Using 'name' for the full path of a file reads badly,
especially when id.name is used in related code.
2020-06-23 11:29:36 +10:00
a573d7e8a1 Cleanup: rename Library.filepath to filepath_abs
Make it clear that this is the absolute path,
allow the 'name' to be renamed to 'filepath'.

Rename is safe since this is only for run-time.
2020-06-23 11:22:30 +10:00
58f3fabb97 Cleanup: unused argument 2020-06-23 09:53:11 +10:00
51bf04383a Fix T78045: CTL-ALT-S does nothing in pose mode and crashes when called from the menu 2020-06-22 19:06:24 -03:00
Jeroen Bakker
2fdca5bd19 Refactoring: View2DScrollers memory allocation
View2DScrollers used the memory manager to allocate memory. This isn't a
problem but in a upcoming change the scrollers will be drawn more often
than it used to (See {D8066}). To limit the number of allocations and
frees this patch will use the stack for allocation.

Reviewed By: Campbell Barton

Differential Revision: https://developer.blender.org/D8076
2020-06-22 21:46:04 +02:00
9335daac2a Trasnform: Support for other snapping types on Edge Slide
This completes T66426.

Since Vert Slide supports these other snapping types (since rBe2fc9a88bc),
it would be easy to miss this on Edge Slide.

So add support for Edge Slide too.
2020-06-22 15:28:38 -03:00
73d3f51c16 Fix T78136: Image editor - crash to desktop with changing the threshold for extract palette
Also fixed the same error in generate GPencil object from image.

The problem was the Render Result image hasn't  ibuf.
2020-06-22 20:06:43 +02:00
15dda0115c UI: Widget: Replace geometry by fragment shader drawing
This means all the antiailasing is done inside the fragment shader.

We use a Signed Distance Field to draw the 2D rounded boxes. This ensure
the best quality for AA.

This reduce the averge Batch for widget to 16 verts instead of ~600 and
reduce overshading a lot.

Theme Emboss alpha and tria alpha needs to be changed after this refactor.

The shadow drawing is left unchanged and still use geometry.

Reviewed By: Severin

Differential Revision: https://developer.blender.org/D7833
2020-06-22 19:57:53 +02:00
3cea42ce29 GPencil: Cleanup comments 2020-06-22 19:27:58 +02:00
9fbbd25e2a Fix T78134: GPencil interpolation crash
Need to verify active frame not NULL.
2020-06-22 19:09:11 +02:00
25d2222c30 Fix T77754: Crash after any alembic import undo in an empty scene
Thanks @mont29 for this patch.

This creates an explicit undo step after the Alembic importer has finished
running. This is necessary when the importer runs as a background job.
2020-06-22 18:10:42 +02:00
fdfe85c616 Fix: Wrong fake user icons in outliner orphan mode
The icons for toggling fake users on orphan datablocks in the outliner
were drawn as the quit and x icons instead of the fake user icon. This
changes to the correct icon, and removes the redundant "F" column.
2020-06-22 09:41:54 -06:00
bfaa41c00d UV Editor: Fix Vertex Overlay color not being color managed
Could be backported to 2.83 LTS
2020-06-22 17:31:51 +02:00
336a8f283f Fix T62917 UV editor: Edge overlay not shown when edge overlay type is Dash
Fix by changing the shader to always compute dash for uv and just change
dash size to something really big for other overlay types.
2020-06-22 17:31:51 +02:00
b175bb2503 Subdiv CCG: Add access to first grid index of a face
Is lazily-initialized array owned by the SubdivCCG. Allows to access
index of a first grid of a given face in the flat array of grids.

Currently unused, but is needed for multires bake.
2020-06-22 17:22:53 +02:00
41158a91f2 Fix (unreported) broken UI of modifiers for liboverrides.
Broken in recent refactor of modifiers UI code...
2020-06-22 16:54:30 +02:00
461ba2c74c Fix random crash in Cycles smoke volume loading
Don't access evaluated mesh data after freeing Blender depsgraph.

Potentially related to T77954.
2020-06-22 16:53:09 +02:00
4a68bf2078 Subdiv: Cleanup, remove unused code 2020-06-22 16:39:04 +02:00
c94a1f5349 Functions: add utilities that allow creating some multi-functions with less typing 2020-06-22 15:50:31 +02:00
6223385043 Functions: Various improvements to the spans and generic data structures
Most of this code is covered by unit tests.
2020-06-22 15:50:31 +02:00
7117ed9691 Fix Preferences not saved when changing translation settings 2020-06-22 15:47:05 +02:00
5726dec0e0 UI: Fix untranslated layout headings 2020-06-22 15:09:54 +02:00
6c76a782e9 UI/BPY: Make layout headings translatable from BPY
This was an oversight when layout headings were added. There's now the regular
translation context option in the Python API.
2020-06-22 15:09:54 +02:00
b0de36a5a3 Fix constraint alignment check on snap axis to plane 2020-06-22 09:53:33 -03:00
508e33842b Tools: rename 'Extrude, Dissolve and Intersect' to 'Extrude Manifold' 2020-06-22 09:20:43 -03:00
e2fc9a88bc Transform: Full snapping support for Vert Slide
Now all options for "snap to" affect the Vert Slide mode.

Reviewed By: campbellbarton

Maniphest Tasks: T66426

Differential Revision: https://developer.blender.org/D3440
2020-06-22 09:08:02 -03:00
85c6f0b472 LibOverride: Add CacheFile properties as overridable. 2020-06-22 14:03:39 +02:00
Damien Picard
961fa2251e External Player: update DJV to version 2 2020-06-22 21:34:56 +10:00
c877c3b8f6 Cleanup: remove workaround for boost 1.46
Part of D8055 by @pioverfour
2020-06-22 21:34:56 +10:00
3d570f7e1f Cleanup: remove blender 2.4 reference in animation playback 2020-06-22 21:34:56 +10:00
99436acde8 Cycles: enable Embree by default for CPU rendering
For GPU debugging purposes, it is still possible to render with the same BVH2
on the CPU using the Debug panel in the render properties.

Note that building Blender without Embree will now lead to significantly reduced
performance in CPU rendering, and a few of the Cycles regression tests will fail
due to small pixel differences.

Ref T73778

Depends on D8014

Maniphest Tasks: T73778

Differential Revision: https://developer.blender.org/D8015
2020-06-22 13:28:01 +02:00
2c41c8e94f Cycles: internal refactoring to make thick/ribbon curve separate primitives
Also removing the curve system manager which only stored a few curve intersection
settings. These are all changes towards making shape and subdivision settings
per-object instead of per-scene, but there is more work to do here.

Ref T73778

Depends on D8013

Maniphest Tasks: T73778

Differential Revision: https://developer.blender.org/D8014
2020-06-22 13:28:01 +02:00
207338bb58 Cycles: port curve-ray intersection from Embree for use in Cycles GPU
This keeps render results compatible for combined CPU + GPU rendering.
Peformance and quality primitives is quite different than before. There
are now two options:

* Rounded Ribbon: render hair as flat ribbon with (fake) rounded normals, for
  fast rendering. Hair curves are subdivided with a fixed number of user
  specified subdivisions.

  This gives relatively good results, especially when used with the Principled
  Hair BSDF and hair viewed from a typical distance. There are artifacts when
  viewed closed up, though this was also the case with all previous primitives
  (but different ones).

* 3D Curve: render hair as 3D curve, for accurate results when viewing hair
  close up. This automatically subdivides the curve until it is smooth.

  This gives higher quality than any of the previous primitives, but does come
  at a performance cost and is somewhat slower than our previous Thick curves.

The main problem here is performance. For CPU and OpenCL rendering performance
seems usually quite close or better for similar quality results.

However for CUDA and Optix, performance of 3D curve intersection is problematic,
with e.g. 1.45x longer render time in Koro (though there is no equivalent quality
and rounded ribbons seem fine for that scene). Any help or ideas to optimize this
are welcome.

Ref T73778

Depends on D8012

Maniphest Tasks: T73778

Differential Revision: https://developer.blender.org/D8013
2020-06-22 13:28:01 +02:00
d1ef5146d7 Cycles: remove SIMD BVH optimizations, to be replaced by Embree
Ref T73778

Depends on D8011

Maniphest Tasks: T73778

Differential Revision: https://developer.blender.org/D8012
2020-06-22 13:28:01 +02:00
1de0e13af6 Cycles: remove __UV__ and __INSTANCING__ as kernel options
The kernel did not work correctly when these were disabled anyway. The
optimized BVH traversal for the no instances case was also only used on
the CPU, so no longer makes sense to keep.

Ref T73778

Depends on D8010

Maniphest Tasks: T73778

Differential Revision: https://developer.blender.org/D8011
2020-06-22 13:28:01 +02:00
fed101a7be Cycles: always perform backface culling for curve, remove option
The hair BSDFs are already designed to assume this, and disabling backface
culling would break them in some cases.

Ref T73778

Depends on D8009

Maniphest Tasks: T73778

Differential Revision: https://developer.blender.org/D8010
2020-06-22 13:28:01 +02:00
c7d940278b Cycles: remove support for rendering hair as triangle and lines
Triangles were very memory intensive. The only reason they were not removed yet
is that they gave more accurate results, but there will be an accurate 3D curve
primitive added for this.

Line rendering was always poor quality since the ends do not match up. To keep CPU
and GPU compatibility we just remove them entirely. They could be brought back if
an Embree compatible implementation is added, but it's not clear to me that there
is a use case for these that we'd consider important.

Ref T73778

Reviewers: #cycles

Subscribers:
2020-06-22 13:28:01 +02:00
e50f1ddc65 Cycles: use TBB for task pools and task scheduler
No significant performance improvement is expected, but it means we have a
single thread pool throughout Blender. And it should make adding more
parallellization in the future easier.

After previous refactoring commits this is basically a drop-in replacement.
One difference is that the task pool had a mechanism for scheduling tasks to
the front of the queue to minimize memory usage. TBB has a smarter algorithm
to balance depth-first and breadth-first scheduling of tasks and we assume that
removes the need to manually provide hints to the scheduler.

Fixes T77533
2020-06-22 13:27:37 +02:00
54e3487c9e Cleanup: remove task pool stop() and finished() 2020-06-22 13:06:47 +02:00
b10b7cdb43 Cleanup: use lambdas instead of functors for task pools, remove threadid 2020-06-22 13:06:47 +02:00
d8c2092b15 Cycles: make TBB a required library dependency, and use in a few places
Now that the rest of Blender also relies on TBB, no point in maintaining custom
code for paraller_for and thread local storage.
2020-06-22 13:06:47 +02:00
ace3268482 Cleanup: minor refactoring around DeviceTask 2020-06-22 13:06:47 +02:00
b7c34c889b Cleanup: use move semantics for task pool functions 2020-06-22 13:06:47 +02:00
f9d138be51 Cleanup: compiler warning 2020-06-22 13:06:47 +02:00
8ffb006077 Add undo step to Alembic and Collada importers...
Re T77754.
2020-06-22 13:06:16 +02:00
c309177edd Fix initialization of Edge Slide with Single Side
It was not being initialized.
Error introduced in cf42721fe2
2020-06-22 07:54:36 -03:00
ba97da21ac Transform: Simplify and rearrange mirror code
No real functional changes.
2020-06-22 07:54:36 -03:00
d6e07a7cd3 Transform: Do not compute island center when not used
No functional changes from the user's point of view.
2020-06-22 07:54:36 -03:00
5db1ae2605 Cleanup: Remove goto in transform_convert_mesh code 2020-06-22 07:54:36 -03:00
2d866d77ae Cleanup: Rearrange transform_convert_mesh into doxy sections 2020-06-22 07:54:36 -03:00
3752c44b44 GPencil: Remove Fill selection with Tweak tool and fix bug
* Fixed selection of point in multiframe mode. The point was not selected.

* Removed the fill area selection because makes the tool imprecise, and for this tool need to be precise or the selection is impossible. Now only select if it's over the point, not over the filled area.
2020-06-22 10:48:49 +02:00
566b4f126d Fix T78123: Can't remove preset with brackets in the name 2020-06-22 18:30:47 +10:00
26e5718e29 Fix T77942: Add Cube scales immediately upon creation after changing Size attribute on prior Add Cube command
Always use the default size here, since desired bounds have been set
interactively, it does not make sense to use a different size from a
previous command.

Maniphest Tasks: T77942

Differential Revision: https://developer.blender.org/D8056
2020-06-22 09:48:30 +02:00
Harley Acheson
19c7b5f45a Fix error using 'char32_t' as 'wchar_t' on windows
FONT_OT_text_insert failed on Windows.

This change was missing from D6198.
2020-06-22 17:13:36 +10:00
61fa710aa3 Fix T77536: Extrude to cursor keybinding missing
Regression in cec7db2004
2020-06-22 17:03:13 +10:00
f8c8a5c092 Fix T77607: Edit-mode shading regression 2.90
Regression in deaff945d0
2020-06-22 16:44:33 +10:00
9215b5d869 UI: report when reloading unsaved text
Address confusion from T78114.
2020-06-22 16:02:42 +10:00
56d0df51a3 Python: support building again version 3.9 (unreleased)
Resolves T78089, no functional changes.
2020-06-22 14:55:36 +10:00
f2b5f731d5 UI: Only show constaint head/tail property with subtarget 2020-06-21 10:55:16 -04:00
0de14fbe78 UI: Fix view reset when toggling subpanel expansion
The view should only reset for the ctrl-click mode that collapses
all other panels.
2020-06-21 10:47:37 -04:00
3fc5826f7c GPencil: Fix unreported missing material onion filter
This feature was removed by error during the refactor done in draw engine.

Differential Revision: https://developer.blender.org/D8082
2020-06-21 15:51:50 +02:00
91117cad0f GPencil: Change effect tooltips for new Shader operators
Instead to use ShaderFx, use Effect and also fixed some wrong cases using Modifier word.
2020-06-21 10:24:08 +02:00
b4ba27f026 UI: A few small fixes for constraint layouts
- Head / Tail was stuck on two rows. It seems there is an issue with
        headings here, which means the first property has to place its own
        label. (So for example the small button can't be first in the row.)
      - Some misalignment and decorator fixes for aligned toggles
2020-06-20 21:51:32 -04:00
a7f1c68938 Cleanup: Outliner walk select naming
No functional changes. Don't use walk_element now that the walk element
flag is removed.
2020-06-20 16:15:42 -06:00
8ce1a60262 Fix T71812: Outliner walk navigation not activating
Walk navigation used a separate flag to select the element. This is
because activation and mode toggling were connected until rB702e00f91088
cleaned up the selection logic.

Now walk navigation can activate objects and other elements without
changing modes. This also addresses renaming in the outliner which
did renaming from the active element, not the walk element.
2020-06-20 16:15:18 -06:00
2d9ab46e0b Fix T77328: Crash on undo Draw Face Sets stroke with dyntopo active
Draw Face Sets does not work in Dyntopo and the sculpt API should be
responsible for that without needing to add checks all over the code,
but it was doing an undo push of type SCULPT_UNDO_FACE_SETS which is not
supported, causing the crash.

Reviewed By: sergey

Maniphest Tasks: T77328

Differential Revision: https://developer.blender.org/D7924
2020-06-20 21:48:11 +02:00
bb58d3d8e2 GPencil: Fix unreported multiuser datablock for onion message
This is not logic after the refactor.
2020-06-20 19:54:44 +02:00
Philipp Oeser
d994391e0c Fix T77994: VSE crash adding a glow effect strip
Since rB47f98a38d0f8 not all 3 effect inputs were assigned anymore. Their
ImBuf's rect was accessed though in do_glow_effect (even though unused in
the following dedicated functions).

Just pass NULL here instead.

Reviewed By: ISS

Differential Revision: https://developer.blender.org/D8064
2020-06-20 06:49:02 +02:00
73ffb3e067 Cleanup: use const args for property name/description access 2020-06-20 13:50:12 +10:00
d7152244f8 Fix T54112: curve.splines.new() ignores Curve.resolution_u/v 2020-06-20 13:17:40 +10:00
92c5b12df6 Fix T75074: Select Hierarchy error, when object is not on view layer 2020-06-20 12:50:24 +10:00
874af5301c Cleanup: Fix build-warning with MSVC
Draco sets CMAKE_CXX_STANDARD to 14, given we
set the c++ standard in the root level CMakeLists.txt
to c++17 this generated build warnings.

Given the rootlevel one is the one we want we can
safely remove this line in dracos cmakelists
2020-06-19 17:28:42 -06:00
466e716495 Bevel: add new 'Absolute' mode for interpreting 'amount' value.
This mode is like Percent, but measures absolute distance along
adjacent edges instead of a percentage.
So, for example, if you use this mode with 2 segments and profile=1,
you will see the length that the bevel moves along unbeveled edges
between beveled ones will match the value specified.
Many users seem to expect this behavior, even though it means the
bevel width is uneven, so this option is for them.
2020-06-19 17:56:01 -04:00
ab72cd2fc1 Cleanup: Spelling 2020-06-19 16:11:15 -04:00
a089286d7b UI: Fix all constraint subpanels empty
Silly typo in earlier fix
2020-06-19 16:07:20 -04:00
bb4cef71ee UI: ShaderFx Drag and Drop, Layout Updates
This patch implements the list panel system D7490 for grease pencil
shader effects. It also moves their drawing to a callback in
ShaderFxTypeInfo in line with the extensible architecture refactoring
goal T75724.

The implementation is basically exactly the same as for the modifier
patch (9b099c8612).

Thanks to Matias Mendiola (@mendio) for helping to develop the layout
changes.

Differential Revision: https://developer.blender.org/D7985
2020-06-19 15:07:13 -04:00
702e00f910 Outliner: Selection cleanup
No functional changes. The outliner selection operators shared many
different functions for selection, activation, mode toggling, and other
actions, but the code paths were not always clear, making any changes
difficult.

This cleans up the code and uses outliner_item_select() as the base
function for selection, activation, mode toggling between the different
selection operators. It also prepares for future features and fixes.

Reviewed By: Severin

Differential Revision: https://developer.blender.org/D5817
2020-06-19 12:43:01 -06:00
ec963d9d7d UI: Grease Pencil Modifier Drag and Drop, Layout Changes
This patch implements the list panel system D7490 for grease pencil
modifiers. It also moves their drawing to a callback in
GpencilModifierTypeInfo in line with the extensible architecture
refactoring goal T75724.

This also adds the "set_error" function for grease pencil modifiers,
which hadn't been copied from mesh modifiers yet.

The implementation is basically exactly the same as for the modifier
patch (9b099c8612).

Thanks to Matias Mendiola (mendio) for providing mockups for many
of the layout changes.

Differential Revision: https://developer.blender.org/D7978
2020-06-19 14:42:08 -04:00
fb7d8e2f4b UI: Fix check for constraint panel default expansion 2020-06-19 14:19:41 -04:00
0ded6f5525 Fix: Crash when closing window while Outliner shows screens
Steps to reproduce were:
* From factory settings, change Outliner Display Mode to "Blender File"
* Open "Screens" item, make sure all listed screens are visible
* Open Preference window, close it
* Mouse hover the outliner -> crash

Fix is to force an Outliner tree rebuild when closing screens.
2020-06-19 20:14:04 +02:00
254f164b27 UI: Minor optimization to Outliner lookup for hovered element
The lookup to find the hovered Outliner tree element would possibly check
children that can be skipped with a simple check.

I experimented with various ways to avoid work in this lookup. This one is
simple and reliable, which others wouldn't have been afaics. Plus, there's not
much performance to be gained here anyway.
2020-06-19 20:06:37 +02:00
15083d9e1e UI: Avoid rebuilding Outliner tree when opening/collapsing items
In big files, the Outliner would have a noticeable lag when opening or
collapsing items. That was because the entire tree was rebuilt, which isn't
actually needed in most cases. So we avoid it where possible now.
2020-06-19 20:06:37 +02:00
f4c0ea1d29 UI: Don't rebuild Outliner tree to remove highlight when leaving area
When leaving the Outliner's area, the highlight would be removed and cause a
full rebuild of the tree. This caused a noticable lag in bigger files.
2020-06-19 20:06:37 +02:00
e15f85f23d UI: Avoid rebuilding outliner tree when changing area size
In big files, ie typical production files, resizing the outliner area would be
very slow. The outliner tree would be rebuilt then, which can easily be avoided.
2020-06-19 20:06:37 +02:00
ce7a5a2376 Fix T78042: GPencil: Strokes go missing after Interpolation from another layer
This was due some strokes could be tagged and as the layer was locked, the strokes were not untagged and removed when all tagged strokes are removed.

The tagged strokes are used as temp ghost of the interpolation and removed at the end of the interpolation.
2020-06-19 19:39:30 +02:00
a24cd69d78 Cleanup: Remove unused BKE_constraint functions 2020-06-19 13:21:39 -04:00
eaa44afe70 UI: Drag and Drop Constraints, Layout Updates
This patch implements the list panel system D7490 for constraints.
In this case the panels are still defined in Python.

The layouts are also updated to use subpanels and the a more organized
single column layout. There may be more tweaks necessary for the
layouts.

Reviewed By: Severin, billreynish, Mets

Differential Revision: https://developer.blender.org/D7499
2020-06-19 12:40:48 -04:00
27fb75fec2 Fix T77476: Transform Align mode using View orientation by default 2020-06-19 12:56:53 -03:00
334e5005f4 USD: Upgrade library 20.02 → 20.05
The Blender USD code didn't have to change for this upgrade. Pixar's USD
did include a change that we had in the patch, so that's been removed
from our patch now. Some of the USD code that we patched changed as
well.
2020-06-19 17:37:14 +02:00
71363dd79c Cleanup: Alembic, replace ABC_INLINE with BLI_INLINE
The `ABC_INLINE` macro has been in the Alembic code since it was introduced
to Blender in rB61050f75b13e. It basically does the same a `BLI_INLINE`,
though, so there is no need to keep it around.
2020-06-19 17:08:21 +02:00
f84414d6e1 EEEVEE: Object Motion Blur: Initial Implementation
This adds object motion blur vectors for EEVEE as well as better noise
reduction for it.

For TAA reprojection we just compute the motion vector on the fly based on
camera motion and depth buffer. This makes possible to store another motion
vector only for the blurring which is not useful for TAA history fetching.

Motion Data is saved per object & per geometry if using deformation blur.
We support deformation motion blur by saving previous VBO and modifying the
actual GPUBatch for the geometry to include theses VBOs.

We store Previous and Next frame motion in the same motion vector buffer
(RG for prev and BA for next). This makes non linear motion blur (like
rotating objects) less prone to outward/inward blur.

We also improve the motion blur post process to expand outside the objects
border. We use a tile base approach and the max size of the blur is set via
a new render setting.

We use a background reconstruction method that needs another setting
(Background Separation).

Sampling is done using a fixed 8 dithered samples per direction. The final
render samples will clear the noise like other stochastic effects.

One caveat is that hair particles are not yet supported. Support will
come in another patch.

Reviewed By: jbakker

Differential Revision: https://developer.blender.org/D7297
2020-06-19 17:05:49 +02:00
e18d6f5206 LibOverride: Cleanup: remove unused parameter. 2020-06-19 17:01:20 +02:00
f6b23c63e1 LibOverride: Parallelize diffing of Main database.
This will not give any noticeable improvements in common editing tasks,
since then usually only a very few IDs are changed and checked for
override updates.

However, it makes full override diffing process several times faster
(happens usually when saving a .blend file, but could also help e.g.
when multi-editing several override objects at the same time...).
2020-06-19 17:01:20 +02:00
9905f5725c LibOverride: rempve ID preview from comparison (diffing) process.
Accessing this from RNA may actually create some data, which we do not
want to happen when comparing data. Further more, preview is not data,
but a view of it, so we should be safe ignoring it entirely here.
2020-06-19 17:01:20 +02:00
df25d3c2a3 LibOverride: add some more debug timing prints... 2020-06-19 17:01:20 +02:00
b50d01cbac Cleanup: Alembic, removed some unnecessary extern "C" {} declarations
No functional changes.
2020-06-19 16:43:27 +02:00
3ceb9faf1a Cleanup: IO, made some functions in AbstractHierarchyIterator protected
These functions are not needed in the public interface, only by the
`AbstractHierarchyIterator` class and its subclasses.

No functional changes.
2020-06-19 16:43:27 +02:00
Stefano Bonicatti
59b523c3c9 Fix build with USD, Clang and Linux
The important distinction for the linker flags is not between GCC and Clang,
but between the macOS and Linux.

Differential Revision: https://developer.blender.org/D8023
2020-06-19 15:42:33 +02:00
697b1736ef Cleanup: Alembic, replace #ifndef guards with #pragma once
No functional changes.
2020-06-19 15:30:18 +02:00
1a448c66ed Cleanup: Alembic, move the C++ code to blender::io::alembic namespace
This commit only moves code into the `blender::io::alembic` namespace,
it does not move `static` functions into an anonymous namespace.

No functional changes.
2020-06-19 15:30:18 +02:00
89b7f785e6 Cleanup: Alembic, moved exporter code into separate directory
This moves most of the exporter-related code
from `source/blender/io/alembic/intern`
to   `source/blender/io/alembic/exporter`

This is to prepare the Alembic code for the switchover to using
`blender::io::AbstractHierarchyIterator`. When that happens, a few more
files will be added, and having things in a separate 'exporter'
directory makes things less cluttered.

Note that exporting consists of multiple steps (determine export
hierarchy, create Alembic archive, and then write data into it), which
is why the directory is called "exporter", but many of the files are
called "writer".

No functional changes.
2020-06-19 15:30:18 +02:00
16d09a5864 Fix T67358: Compositor Disabled Node Config -> SegFault
The issue was caused by wrong conversion happening after some of the
proxies are removed. Easiest solution is to first remove proxies and
then add required converter operations.

Thanks Jeroen for the review!
2020-06-19 14:49:36 +02:00
28d77f9354 Performance: Never draw channels region during playback
Channels aren't visually changed by playing back an animation so there
is no need to do this. As rendering channels is using a lot of logic
(filtering animation data, converting fcurves to samples etc) it has an
noticeable overhead.

This change has no functional limitation. Users are still able to do
everything during animation playback. There are other mechanisms in
place that take care of that.

Spring 02_020_A.anim.blend went from 11.8 to 12.0 on a Ryzen 1700. I
didn't test with scenes but it should be more noticeable with more
complex scenes.

Reviewed By: Brecht van Lommel

Differential Revision: https://developer.blender.org/D8073
2020-06-19 14:45:55 +02:00
90010c3e04 CMake: Correct warning about which C++ version is required
Was only happening on unsupported compilers.
2020-06-19 14:44:03 +02:00
2193e28dfc USD Test: Don't use designated initializers
This isn't really in C++ standard, some corner cases work in some
compilers (like when all fields are specified), but in general they
do not work.

For some reason MSVC builder started to complain about it now,
weird but better not rely on compiler specifics.
2020-06-19 12:36:37 +02:00
e9a7f4d389 Upgrade C++ standard to C++17
Ref T76783
2020-06-19 12:02:21 +02:00
1f5f3b5588 Cycles: Make compatible with C++17 on 10.9 deployment target
OSLRenderServices contains a member which is 64 bytes aligned and this
is onlys supported by default allocators in SDK 10.14. Since we take
care of allocation ourselves ignoring the diagnostic is an acceptable
way dealign with it.
2020-06-19 12:02:21 +02:00
3f5b295084 Freestyle: Fix compilation error with C++17
AutoPtr class became a sub-class of unique_ptr with some special magic
to mimic behavior of auto_ptr for copy constructor.

The code was already there, but for some reason visual studio did not
set __cplusplus correctly for some reason.

The other change is remove of binary function usage, which is not
needed in the Freestyle code.
2020-06-19 12:02:21 +02:00
7ae9227794 Quadriflow: Fix compilation error with C++17
Unary function has been removed.
Unless I'm missing something subclass is not needed here.
2020-06-19 12:02:21 +02:00
b3b445979e Tests: Use explicit signature constants
Are reported by MSVC 2019 after C++17 switch.

One might suggest lets just silence the warning, I will say why to have
specific signed/unsigned types in API just to then (usafely) ignore the
sign conversion.
2020-06-19 12:02:21 +02:00
8c3dd6d83d Upgrade Google libraries
Upgrades Glog from 0.3.5 to 0.4.0, and Gtest from 0.8.0 to 0.10.0.

Hopefully this will solve compilation error on MSVC with C++17.
2020-06-19 12:02:21 +02:00
0f78a57904 Make BLI_edgehash_test compatible with C++17
random_shuffle was removed (at least the used version).
2020-06-19 12:02:21 +02:00
31ae833811 Ceres: Update to the latest upstream version
Using latest master because of various compilation error fixes.

Brings a lot of recent development. From most interesting parts:

- New threading model.
- Tiny solver.
- Compatibility with C++17.
2020-06-19 12:02:21 +02:00
171c4fb238 Update C++ standard to C++14
This is an intermittent state to get all dependencies to compile.

For example, the latest Ceres is needed to bring C++17 support,
but it has bumped minimal requirement to C++14.
2020-06-19 12:02:21 +02:00
9e70129952 Cloth: allow forces to act parallel to cloth.
Currently all force effectors can only act on cloth when the force is
perpendicular to the surface. This makes sense for wind, but not for
other forces; and the user may want even wind to have some friction.

This changes effector code to output two force vectors - although
you of course can pass the same pointer for both. The force is split
between the two outputs based on a new per-effector setting.

Differential Revision: https://developer.blender.org/D8017
2020-06-19 12:17:02 +03:00
f382109f38 Fix T78024: GPencil - Add missing UV Fill prop to RNA
This was changed in the refactor done in 2.83 and was not included by error.
2020-06-19 10:56:10 +02:00
2dff08c8ce Alembic: always export transforms as inheriting
Blender now always exports transforms as as "inheriting", as Blender has
no concept of parenting without inheriting the transform.

Previously only objects with an actual parent were marked as
"inheriting", and parentless objects as "non-inheriting". However,
certain packages (for example USD's Alembic plugin) are incompatible
with non-inheriting transforms and will completely ignore such
transforms, placing all such objects at the world origin.

When importing non-inheriting transforms from Alembic, Blender will
break the parent-child relation and thus force the child to (correctly)
interpret the transform as world matrix.
2020-06-19 10:24:57 +02:00
f106369ce8 Alembic: prevent spaces in names of exported particle systems
Other types already had spaces, periods, and colons replaced by
underscores. The upcoming Alembic exporter (based on the
`AbstractHierarcyIterator` class) will be more consistent and apply the
same naming rules everywhere. This is in preparation for that change.
The `get_…_name()` functions in `abc_util.{cc,h}` will be removed then.
2020-06-19 10:24:51 +02:00
0d744cf673 Alembic: export object data with object data name
Previously the Alembic exporter exported a mesh object to
`{object.name}/{object.name}Shape`. Now it exports to
`{object.name}/{mesh.name}` instead. The same change also applies to
other object data types.

Note that the code now is a bit hackish, as `m_name` is set even in
cases where it isn't used. This hackishness was already there, though,
but it's now just more visible. This will all be cleaned up when the
Alembic exporter is ported to use the `AbstractHierarchyImporter`
structure of the Universal Scene Description (USD) exporter.

Reviewed By: mont29

Differential Revision: https://developer.blender.org/D7672
2020-06-19 10:17:41 +02:00
0ae7883d7d IO: ensure export path and export name are always consistent
Before this, there was one code path that set `context.export_path`, and
a different code path for `context.export_name`, allowing the two to
diverge.

Keeping track of the export path of the export parent (which can be, but
is not always, the Blender parent object) also allows a concrete
subclass of `AbstractHierarchyIterator` to find the `AbstractWriter` for
the export parent. In case of exporting to Alembic this is important, as
it's not possible to simply give the Alembic library the full export
path of an object like we do in the Universal Scene Description (USD)
exporter; Alembic needs the C++ object of the parent.
2020-06-19 10:17:41 +02:00
69c3d9804f IO: Allow exporting a subset of the writers
This is in order to prepare for compatibility with the Alembic exporter.
That exporter is capable of writing object transforms and object data at
different (sub)frames.

The rename from `created_writers` to `used_writers` is necessary, as not
all created writers will be actually used in each iteration.

The Universal Scene Description (USD) exporter does not make use of
this.

Reviewed By: mont29

Differential Revision: https://developer.blender.org/D7670
2020-06-19 10:17:41 +02:00
084c5d6c7e IO: Move Abstract Hierarchy Iterator into io/common
The goal of the `AbstractHierarchyIterator` class (and supporting
classes) was to use it in different exporters. It shouldn't be part of
the USD module + namespace any more, now that it will also be used in
the upcoming Alembic exporter rewrite.

The source files are moved into `io/common`, which is compiled & linked
into a new library `bf_io_common`. The unittests are still inside the
`tests/gtests/usd` directory. They should be moved to a separate test
module too, but that will be delayed until after T73268 has been
resolved.

Reviewed By: mont29

Differential Revision: https://developer.blender.org/D7669
2020-06-19 10:17:41 +02:00
b1ce4ca40c Fix T77997: GPencil insert keyframe on timeline doen't update viewport
The reason was the datablock is changed but it was not tagged for depsgraph refresh.

In some cases it could be possible to tag several times the same datablock, but as this is not the case all the times and the number of tags is always very small, it doesn't worth a complex code to keep a memory list of the datablocks to tag.
2020-06-19 10:10:11 +02:00
fade37ff07 Writefile: move file flags to BlendFileWriteParams
This removes G_FILE_HISTORY, G_FILE_SAVE_COPY & G_FILE_USERPREFS.

Using file-flags made logic harder to follow since it's not so clear
which flags are expected to be in G.fileflags & which are meant to be
set and passed as arguments, these are shared between read & write
functions too.

Add BlendFileWriteParams so options which don't need to be stored
aren't mixed up with flags that are stored for reuse.
2020-06-19 16:47:12 +10:00
5a77f643f4 Cleanup: SPACE_ACTION does not have a RGB_TYPE_TOOL_HEADER
So no need to check this specific case.
2020-06-19 08:13:06 +02:00
d093f61667 Cleanup: use bool and enums in match_region_with_redraws
Function used int for everything.
2020-06-19 08:11:25 +02:00
642b19c8b8 Fix app-templates not resetting the user interface
Regression in 45b5f4e3df
2020-06-19 14:29:24 +10:00
41f0697501 Outliner: Show pose group icons
Pose groups previously showed a dot icon. Now it draws the correct icon.
2020-06-18 21:53:54 -06:00
1ee32ea228 Cleanup: use doxy sections 2020-06-19 13:17:10 +10:00
0479c28ddd Cleanup commented separator. 2020-06-19 02:04:59 +02:00
f1e5fd030a Cleanup: unsupported ATTR_FALLTHROUGH use, clang-format 2020-06-19 09:44:57 +10:00
b89898cbd3 Cleanup: Move snap callbacks to their respective transform mode
These functions are very specific to the mode.

More modes can support snap, and there is no reason to keep all
callbacks for each mode in the transform_snap.c file.
2020-06-18 16:05:48 -03:00
d56444392f Fix T78004: Instant crash when Shift+D duplicating a Collection Instance.
Dummy mistake in own recent refactor of duplicate code...
2020-06-18 20:34:39 +02:00
3aadf68b88 UI: Weight Modifiers Falloff: Use better step icon 2020-06-18 12:46:00 -04:00
d5954ef11c LibOverride: only tag actually changed orig IDs for automatic override diffing.
This makes any operation (including mere bone selection) several times
faster on some complex production character, since we typically now only
need to diff a single ID, instead of tens of them.
2020-06-18 18:27:49 +02:00
722adcfc48 LibOverride: Improve performances by using better string hashing function.
This is not really huge improvements, but 2% are always good to have.
2020-06-18 18:27:49 +02:00
52b8d668f4 Depsgraph: use blender::Map instead of std::map
We decided to use our own map data structure in general for better
readability and performance.

Reviewers: sergey

Differential Revision: https://developer.blender.org/D7987
2020-06-18 18:18:19 +02:00
44f7852660 LibOverride: increase speed of RNA diffing process.
By using own path construction instead of handy printf-like functions,
we get a 10% improvement on overall diffing process!

This remains way to slow on some complex production characters, but
always good to have still.
2020-06-18 18:00:41 +02:00
667ef9917f UI: Place "New Collection" item above list in Move/Link to Collection menu
This way "New Collection" is always assigned the same shortcut (N).
Whereas previously it would be automatically assigned the leftover key
from the list of available collections.

Nice side effect is that since N is next to M in most keyboard layouts,
moving to a new collection is super fast by hitting M then N.

{F8630575, size=full}

Paper-cut pointed out by DerekWatts on [devtalk](https://devtalk.blender.org/t/blender-ui-paper-cuts/2596/4211) (thanks!):
{F8630492, size=full}

Reviewed By: HooglyBoogly

Differential Revision: https://developer.blender.org/D8067
2020-06-18 17:54:49 +02:00
6899cb3c07 Fix for T77095: work around render artifacts with AMD Radeon RX 4xx and 5xx 2020-06-18 14:41:51 +02:00
64bf179a17 Fix T65986: Inaccurate center of mass, calculating mesh center
Use a median center of polygons as an initial value for volume center
calculation since the volume accumulation quickly generates very large
numbers that become inaccurate if the geometry is too far
from it's current center.
2020-06-18 22:37:32 +10:00
55ebf174bc Fluids: fix variable names
This seems to be an error in rBb91b90f0dd3c9bff3b1a6e563c2cce293722ed16.

I found it, because I could not open the file in T77263 anymore.

Reviewers: sebbas

Differential Revision: https://developer.blender.org/D8065
2020-06-18 14:27:58 +02:00
e36c05b3d1 Fix T77764: VSE: snap strip to current frame does not move associated
effect strips keyframes along

Maniphest Tasks: T77764

Differential Revision: https://developer.blender.org/D7996
2020-06-18 13:27:50 +02:00
dbf96e6252 Fix T77957: Height change in Camera Properties column when changing lens type
Remove unneeded extra column from perspective type properties.

Maniphest Tasks: T77957

Differential Revision: https://developer.blender.org/D8060
2020-06-18 11:09:53 +02:00
a5e176a8ed Allow interpolation of matrices with negative scale / axis flips
The matrix interpolation function `interp_m3_m3m3()` decomposes the
matrices into rotation and scale matrices, converts the rotation
matrices to quaternions, SLERPs the quaternions, and converts the result
back to a matrix. Since quaternions cannot represent axis flips, this
results in interpolation problems like described in T77154.

Our interpolation function is based on "Matrix Animation and Polar
Decomposition", by Ken Shoemake & Tom Duff. The paper states that it
produces invalid results when there is an axis flip in the rotation
matrix (or negative determinant, or negative scale, those all indicate
the same thing). Their solution is to multiply the rotation matrix with
`-I`, where `I` is the identity matrix. This is the same as element-wise
multiplication with `-1.0f`. My proposed solution is to not only do that
with the rotation matrix `R`, but also with the scale matrix `S`. This
ensures that the decomposition of `A = R * S` remains valid, while also
making it possible to conver the rotation component to a quaternion.

There is still an issue when interpolating between matrices with
different determinant. As the determinant represents the change in
volume when that matrix is applied to an object, interpolating between a
negative and a positive matrix will have to go through a zero
determinant. In this case the volume collapses to zero. I don't see this
as a big issue, though, as without this patch Blender would also produce
invalid results anyway.

Reviewed By: brecht, sergey

Differential Revision: https://developer.blender.org/D8048
2020-06-18 10:37:52 +02:00
46e4cdf788 Tests: added simple unittests for matrix interpolation
The interpolation of 4x4 and 3x3 matrices will fail when the rotation
component has a singularity, i.e. when there is one axis mirrored. Two
mirrored axes are just a rotation of 180 degrees around the third, and
three mirrored axes are such a rotation + a single axis mirror. To
prepare for a fix, I first wanted to cover the basic functionality with
a few unit tests.

These tests check that `interpolate(A, B, alpha)` always returns `A` for
`alpha=0`, always return `B` for `alpha=1`, and something in between for
`alpha=0.5`.
2020-06-18 10:37:46 +02:00
099d47f8a3 Sequencer: revert selection & keymap changes from D7679
These changes aren't aligned with other timeline selection keymaps
(graph & action for e.g.).

Revert these changes, shortcuts to time-line editors
should take other similar spaces into account.
2020-06-18 16:30:56 +10:00
502e6bd839 Fix doc generation for enum & attr's with multi-line descriptions 2020-06-18 16:26:16 +10:00
3ada1949f8 Python API: path mapping options for library writing function
When "Relative Remap" option was added, the intention was only to remap
paths that were already relative. However it remapped all paths.

This was reported as T62612 and fixed recently,
however some Python script authors depended on the old behavior.

For users, it's reasonable to use the existing operators to make paths
absolute/relative. For scripts however it's useful to be able to write
out individual data-blocks with the ability to make all paths relative.

Now `bpy.data.libraries.write()` takes a path_remap argument which can
be `NONE/RELATIVE/RELATIVE_ALL/ABSOLUTE` allowing the script author to
choose how paths are handled when writing out data-blocks.

Addresses T77768.
2020-06-18 15:49:10 +10:00
aab165b575 Cleanup: remove unnecessary flag clearing
This is not read from blend files.
2020-06-18 14:30:04 +10:00
978e2b6f98 BKE_global: No longer read/write G_FILE_HISTORY
This is a runtime only flag
which doesn't make sense to store in the file.
2020-06-18 14:30:04 +10:00
44f4eaf13b Cleanup: doxy sections for walk/fly operators 2020-06-18 14:30:04 +10:00
3aa1143d57 Cleanup: redundant parenthesis 2020-06-18 14:30:04 +10:00
790d942b69 Cleanup: unused variables 2020-06-18 14:30:04 +10:00
229ed078d1 Fix T75414: Incorrect masking in Color Balance modifier
Color balance factor was infinity. Clamp to +/- `FLT_MAX`

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D7884
2020-06-18 05:53:25 +02:00
f7f3b2d318 Cleanup: Remove goto statements from strip rendering functions
Remove goto statement from `seq_render_image_strip()` and `seq_render_movie_strip()`.
`seq_render_image_strip_view()` and `seq_render_movie_strip_view()` is used to render individual views in both monoview and multiview branch.

I have included `seq_can_use_proxy()` for convinience

Reviewed By: sybren

Differential Revision: https://developer.blender.org/D7870
2020-06-18 05:53:25 +02:00
67a822e086 Fix T73056: Cache not invalidated in fade operator
This operator is written in python it is inserting keyframes to create fade
effects.

Add Sequence.invalidate() python function to invalidate strip if it is
changed in python.

Perhaps I could implement cache invalidation to actual curve manipulation.
I guess it wouldn't be very hard to do but having means to invalidate form
python is useful as well.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D7885
2020-06-18 05:53:25 +02:00
47f98a38d0 VSE: Fix assigning effect strip inputs
Partialy fixes T73828

Currently all 3 effect inputs were assigned even if not all 3 were used.
This causes problems with reassigning effects in python, because 3rd input is
not accessible.

This patch will only assign inputs that are necessary for effect to work
properly.

Reviewed By: campbellbarton

Differential Revision: https://developer.blender.org/D6868
2020-06-18 05:53:25 +02:00
8df99b1c0c Cleanup: Remove unused code from seq_proxy_get_fname()
Reviewed By: brecht

Differential Revision: https://developer.blender.org/D7868
2020-06-18 05:53:25 +02:00
ac16d56aa8 Fix T66390: Update missing when snaping strips.
Effect strips bound recalculation was mixed with overlap handling, which
caused, that effects wasn't handled.

In some cases there may be problem with order of strips in seqbase. We should
traverse hierarchy instead. This is design issue that applies to all
operators, and should be fixed separately.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D7880
2020-06-18 05:53:25 +02:00
d8206602fe Transform: Snap to the intersection between constraint and geometry
This commit changes the behavior of 4 snapping combinations:

**1. While constraining to a plane, snap to an edge element:**
The snap is made at the intersection between the edge direction and the
constraint plane.

**2. While constraining to a plane, snap to a face element:**
The snap is made to the nearest point between the snap point and the
line that intersects the face plane with the constraint plane.

**3. While constraining to an axis, snap to an edge/line element:**
The snap is made to the nearest point on the axis to the edge/line.

**4. While constraining to an axis, snap to a face element:**
The snap is made at the intersection of the axis and the plane defined
by the face.

To avoid unpredictable jumps outside view boundaries, an alignment
check is made for each of these snapping combinations.

Resolve/fix T66422

Differential Revision: https://developer.blender.org/D5608
2020-06-18 00:01:05 -03:00
18ccf328ac Outliner: Fix (unreported) object select in multiple collections
Previous commits to fix parent selection introduced incorrect behavior
when selecting objects linked to multiple collections. The clicked
object would be selected, but also the first listed object in the tree
would be selected.

Instead of always searching for a parent object to select, only search
back when the selected element is not an ID_OB. This prevents multiple
selection of objects linked to multiple collections.
2020-06-17 20:31:55 -06:00
e079bf6996 GPencil: Chnage default Vertex Color mode to Stroke and Fill
The previous value was Stroke only.
2020-06-17 22:49:59 +02:00
ffa23b6c77 GPencil: Fix unreported Vertex Opacity Overlay not working
This values was not working because was removed by error in refactor.

Reviewed By: mendio, fclem

Differential Revision: https://developer.blender.org/D8061
2020-06-17 22:42:49 +02:00
a874cec02b UI: Match some properties set in keymaps with those set for buttons
This allows the operator's shortcut to appear in the context menu.

Except for the shortcut display, there is no functional change from the
user's point of view.

This fix T77839
2020-06-17 16:30:31 -03:00
eacdcb2dd8 Cycles: Add new Sky Texture method including direct sunlight
This commit adds a new model to the Sky Texture node, which is based on a
method by Nishita et al. and works by basically simulating volumetric
scattering in the atmosphere.

By making some approximations (such as only considering single scattering),
we get a fairly simple and fast simulation code that takes into account
Rayleigh and Mie scattering as well as Ozone absorption.

This code is used to precompute a 512x128 texture which is then looked up
during render time, and is fast enough to allow real-time tweaking in the
viewport.

Due to the nature of the simulation, it exposes several parameters that
allow for lots of flexibility in choosing the look and matching real-world
conditions (such as Air/Dust/Ozone density and altitude).

Additionally, the same volumetric approach can be used to compute absorption
of the direct sunlight, so the model also supports adding direct sunlight.
This makes it significantly easier to set up Sun+Sky illumination where
the direction, intensity and color of the sun actually matches the sky.

In order to support properly sampling the direct sun component, the commit
also adds logic for sampling a specific area to the kernel light sampling
code. This is combined with portal and background map sampling using MIS.

This sampling logic works for the common case of having one Sky texture
going into the Background shader, but if a custom input to the Vector
node is used or if there are multiple Sky textures, it falls back to using
only background map sampling (while automatically setting the resolution to
4096x2048 if auto resolution is used).

More infos and preview can be found here:
https://docs.google.com/document/d/1gQta0ygFWXTrl5Pmvl_nZRgUw0mWg0FJeRuNKS36m08/view

Underlying model, implementation and documentation by Marco (@nacioss).
Improvements, cleanup and sun sampling by @lukasstockner.

Differential Revision: https://developer.blender.org/D7896
2020-06-17 21:06:41 +02:00
d6ef9c157a UI: Solve crash with move to index in modifier menu 2020-06-17 14:43:48 -04:00
bcb2b8ab57 UI: Improve Modifier Panel Header Menu
This makes a few changes to the modifier panel header:
  1. Adds "move to top" and "move to bottom" buttons.
  2. Adds a checkmark icon for "apply"
  3. Makes it narrower, the text is closer to the dropdown icon.
     (Requires the change in ui_block_func_POPUP)

Differential Revision: https://developer.blender.org/D8040
2020-06-17 14:09:17 -04:00
4cfdd10c2b UI: Modifier Panel Header Improvements
This includes a few improvments:
  1. Always expose delete. This is the button everyone wants the most,
     it makes a lot of sense to expose this.
  2. Improve "name hiding capability." Basically always align the mode
     buttons to the right, and count their number to see if the name fits.
  3. Aligns more items, to look better, save space, and make the whole
     header seem more grouped.
  4. In my tests the "switch contexts" button never coincides with the
     delete button, so they share the same space.

Differential Revision: https://developer.blender.org/D8037
2020-06-17 13:51:33 -04:00
c1c02f45f7 UI: Ctrl-click on panel header expands & collapses subpanels
If the panel is already open and you ctrl click on its header, its
sub-panels are now expanded / collapsed instead of toggling the
expansion for all other panels. If you're toggling a panel's expansion
it's already in view anyway, so there is no need to collapse the
other panels.

Differential Revision: https://developer.blender.org/D8042
2020-06-17 13:37:59 -04:00
2e0ac1e0c4 Buildbot: Cleanup, remove unused script and change naming
Follow upstream convention.
2020-06-17 17:39:17 +02:00
e590526af6 Fix T76767: Cycles performance regression with CLI renders
When picking a small tile size when doing a CLI render will
yield many status updates being printed to the console
causing a slowdown in the render process. 2.79 with the
same amount of tiles did not have this slowdown.

The reason for this turned out to be a debugging aid added
in rBd2757d149bf2 which disabled buffering for stdout which
on windows caused every single character being printed to the
console to try to obtain a mutex, and worse the thread being
put to sleep when this mutex was unavailable leading to poor
performance.

This patch changes the behaviour by only disabling the
buffering in debug builds.

CLI render of the default cube with 16x16 tiles at 1080p

2.83 : 37.57s
now  : 17.03s

note: this only affected CLI renders, renders from the UI
do not report this kind of information and had no such
slowdown.
2020-06-17 09:26:49 -06:00
9bfd78ae14 Fix T77914: Blender Crashes if viewport is changed manually while having loop cut selected
The selection engine requires a viewport.
2020-06-17 12:16:32 -03:00
ddf4b909de Cleanup: Rearrange SELECTID_Context members for better alignment 2020-06-17 12:16:32 -03:00
13f591d400 ID Duplicate: Factorize a lot the code.
Now that we have a uniform consistent behavior in all our ID duplicate
funtions, we can easily factorize it greatly. Code gets cleaner,
smaller, and less error-prone.

Note that ultimately, this duplicate/deep copy behavior could be added
as a callback of IDTypeInfo.
We could also rethink the duplicate flags (some data, even some obdata,
like Lattice, are not coverred currently).
And so on. But at least code should now be much more easily maintainable
and extendable.
2020-06-17 17:06:05 +02:00
c84fee1ffe ID Duplicate: uniformize Action duplication.
Previously, object (and sub-data) actions would be controlled by the
user preferences flag, collections actions would never be duplicted, and
scenes actions were always duplicated...

Now they all follow the user preferences settings.
2020-06-17 17:06:05 +02:00
ad6cccf058 Refactor duplicate of data-blocks.
Main change from user side, besides that all pointers should now be
properly remapped to new IDs, is that linked objects are no longer
preserved when doing a full copy of scenes.

Will open a task to check whether we actually still want that behavior
(and re-code it in a more correct way then).

This is the main part of work done here, it aims at uniformizing and
sanitizing that 'deep copy' process for supported IDs (currently scenes,
collections and objects).

Note that there will be more follow up commits after that one, but this
should be the most risky and changing one.
2020-06-17 17:06:05 +02:00
514f80b0c4 Fix (unreported) broken logic in BKE_libblock_relink_to_newid
Existing code would not follow as expected into new sub-IDs if they were
only encoutered once in usages by parent IDs...
2020-06-17 17:06:05 +02:00
26c0ca3aa7 Outliner: Unified delete hierarchy operator
This resolves T73673 by allowing delete hierarchy in all outliner view
modes. It also unifies the collection and object hierarchy delete into a
single operator like in rBae98a033c856. This makes it easier to delete
all selected collection and object hierarchies at once.

This also removes the old object delete hierarchy code in favor of the
batch delete code which has been default for over a year.

Maniphest Tasks: T73673

Differential Revision: https://developer.blender.org/D7675
2020-06-17 09:00:04 -06:00
a2c4e5d222 Cleanup: clang-format 2020-06-17 16:07:26 +02:00
fc7c34e380 Cleanup: fix compiler warnings 2020-06-17 14:36:51 +02:00
25b8dedfb4 Fix T77915: Cycles OSL microfacet closure not working in custom shaders
The code to implement the newer closure in terms of the old one got lost in
the removal of our stdosl.h copy. Now implement it as a builtin closure.
2020-06-17 14:09:28 +02:00
8591ee748f Cleanup: doxy sections for meta-ball operators. 2020-06-17 21:22:08 +10:00
70c061ee0a Fix T63411: Crash adding meta-ball with a small radius
Change how the radius, changing the size of meta plane, sphere & cube.

Previously the size of these primitives would be kept the same,
with only the radius outside the primitive being scaled.

This led to small scale adding a lot of polygons instead
of scaling the primitive down as users would expect.

Also change behavior not to change the resolution when adding
to an existing meta-ball.
2020-06-17 21:13:47 +10:00
7dae6eb5a2 Doc: minor change to curve select more/less
Address T55218
2020-06-17 18:07:53 +10:00
1dfd262f2d Cleanup: name mesh join functions using ED_{type} prefix 2020-06-17 17:07:11 +10:00
4892470a47 Fix T70287: Connect vertex path can create duplicate edges/faces 2020-06-17 16:41:16 +10:00
ba312bc8a7 Cleanup: doxy comments 2020-06-17 14:00:09 +10:00
3ff9769762 Fix T76041: Low contrast dirty vertex colors with loose geometry
Add option to normalize vertex colors.
2020-06-17 13:43:20 +10:00
f9be5374ac Cleanup: warning 2020-06-17 13:43:20 +10:00
c7b03fe9c0 UI: Backspace is one word 2020-06-16 14:15:54 -04:00
efb1bf80df Buildbot: Cleanup, typo in logging 2020-06-16 18:12:15 +02:00
1b2a24aae0 Fix issue with uint in headers in recent own commit.
Would break on some systems/compilers...
2020-06-16 18:03:36 +02:00
16652185ce Fix (unreported) wrong size of UserPreferences' dupflag parameter.
Adding volume obdata option to `eDupli_ID_Flags` enum made it go beyond
the 16 bits of a short... Also, enums should typically be stored in
unsigned integers.
2020-06-16 17:40:30 +02:00
94fba47513 Cleanup: use explicit enum type for duplicate option of BKE_object_duplicate
Using enum type itself in implementations, and uint in headers (as using
enums types in headers is a pain when enum are not defined and used in a
single same header file...).
2020-06-16 17:40:30 +02:00
9e307117f8 Cleanup: remove hierarchy parameter from BKE_collection_duplicate
It makes no sense to deep-copy a collection and not also copy its
children collections... Parameter was not used anymore anyway.

So now this duplicate function will always at least deep-duplicate all
of its children collections, recursively.
2020-06-16 17:40:30 +02:00
2c435cf249 Cleanup: get rid of BKE_collection_copy.
We want to get rid of those for all ID types ultimately, but that one
was only used in one place, being the only one calling
`BKE_collection_duplicate` without hierarchical duplicate and parent
collection pointer, effectively using the full power of the complex deep
duplication code for a mere `BKE_id_copy` call...

This will allow for further cleanup in duplicate code.
2020-06-16 17:40:30 +02:00
2e5ef864ab Refactor: move .blend read/write of mesh deform modifier to MOD_meshdeform.c 2020-06-16 17:17:43 +02:00
25a1ed993a Cleanup: remove unnecessary indirection for .blend read/write of curvemapping 2020-06-16 17:04:03 +02:00
d3de5d7ca5 Refactor: Move curvemapping .blend read/write to blenkernel
This is necessary so that it can be accessed from `blendWrite`
and `blendRead` callbacks from modifiers.
2020-06-16 16:59:52 +02:00
4365de3870 Functions: Multi Function
This adds the `MultiFunction` type and some smallish utility types that it uses.
A `MultiFunction` encapsulates a function that is optimized for throughput by
always processing many elements at once.

This is an important part of the new particle system, because it allows us to
execute user generated node trees for many particles efficiently.

Reviewers: brecht

Differential Revision: https://developer.blender.org/D8030
2020-06-16 16:35:57 +02:00
f721308bd0 Fix bitscan_reverse_uint on MSVC compiler
Was a mistake from the very beginning of implementation.
2020-06-16 16:17:47 +02:00
2c2fd9f036 Buildbot: Switch WIndows builds to MSVC 2019 2020-06-16 16:17:47 +02:00
bc7a4b126a GPencil: Convert and Bake mesh animation to grease pencil strokes
This patch adds two options:

- Convert a mesh to grease pencil strokes.
- Bake the mesh animation into grease pencil strokes.

Both are related and must be included in the same patch.

Related to tasks: T77629 and T77630

Notice: The conversion is done for mesh edges and it's not considering any visibility clipping. All edges are exported, no matters if it's visible or not.

Example of Convert a Mesh to Grease Pencil strokes:

{F8606028}

This conversion was inspired by the technique used by @luamono in this tweet: https://twitter.com/luamono/status/1239983662176841730

Example of Bake Animation (the video is a little outdate, but the basic functionality is the same, only small changes in UI):

{F8606032}

Reviewed By: mendio, pepeland

Maniphest Tasks: T77629, T77630

Differential Revision: https://developer.blender.org/D7983
2020-06-16 15:28:46 +02:00
e54058b121 Fix T77803: IK Degrees of freedom drawing glitch
IK degrees of freedom is rendered using wires and a solid sphere. The
solid used the wireframe drawing what resulted into drawing glitches.
This patch adds a new shader to draw the solid shape.

Reviewed By: Clément Foucault

Differential Revision: https://developer.blender.org/D8044
2020-06-16 14:36:18 +02:00
76d50c51a3 Buildbot: Support multiple workers talking to single codesign server
Is achieved by replacing hard-coded signed/unsigned file names with
"<uuid>" which acts as a "request ID". This way multiple workers can
put their requests into a single directory without collisions. The
code sign server will handle the requests sequentially in an unknown
order.
2020-06-16 14:08:14 +02:00
21d862494b Buildbot: Don't use builder name in the build directory
The directory layout on worker goes as following:

  <Worker>
    <Builder Name>
      blender.git/
      build/
      install/
      lib/

Adding an extra <Builder Name> after build is redundant.

Differential Revision: https://developer.blender.org/D8045
2020-06-16 12:24:01 +02:00
7d7090710c CMake: Fix compilation errors related on missing dna_type_offsets.h
Some of the files were (indirectly) using dna_type_offsets.h without
adding dependency from bf_dna (which is needed to ensure the file is
generated prior to library compilation).
2020-06-16 12:22:06 +02:00
38c9573b23 BLI: fix Map.foreach_item method 2020-06-16 12:16:07 +02:00
d2587f6f93 Cleanup: unused headers, spelling 2020-06-16 16:59:26 +10:00
Alan Troth
a64b8aca39 Fix T61777: Proportional editing doesn't work with multi edit-mode 2020-06-16 16:45:53 +10:00
f72419b9ae Cleanup: doxy sections for camera, collections, text & seqmodifier 2020-06-16 12:56:45 +10:00
a76542cbbf Cleanup: Use LISTBASE_FOREACH in interface_panel.c 2020-06-15 21:38:16 -04:00
4db63b6486 Fix crash when opening some old/broken .blend files after recent fix.
Now that `BKE_main_collections_parent_relations_rebuild()` is called
from readfile code, we need to make it resilient to potential NULL
master collection pointer in scenes.
2020-06-15 18:49:46 +02:00
6a0ebb8088 Refactor: use new blenloader api for laplacian deform modifier 2020-06-15 18:37:30 +02:00
d97cb98b11 Fix unhandled RECALC options in depsgraph code after recent change.
Spotted by @LazyDodo on IRC, thanks.
2020-06-15 18:25:40 +02:00
bf1e5a2133 Blenloader: call blendRead and blendWrite of modifiers when available
This is part of T76372.
2020-06-15 17:55:06 +02:00
b6981d9e48 Modifiers: New callbacks for reading and writing .blend files
This is part of a greater blenloader decentralization effort (T76372).
For modifiers the goal is that fewer files have to be modified when
a new modifier is added.

This patch just adds the `blendWrite` and `blendRead` callbacks to
`ModifierTypeInfo` but does not change any other code yet. In the next
steps, modifier specific code will be moved from `writefile.c` and
`readfile.c` into their corresponding `MOD_*` files.
2020-06-15 17:43:30 +02:00
eaff606f2d Fix T77460: Easy to create cyclic dependencies in collections and crash Blender.
Cyclic check was not checking for collections instanciated by objects...
2020-06-15 17:25:51 +02:00
89bde99674 Fix (unreported) critical mistake in Collection liblink code in readfile.c.
Prelimenary step to fix T77460.

Not sure how or when that thing was done, but since that call walks
around collections relationships, it's an utterly critical violation of
liblinking principles (code here should never, ever 'get outside' of its
own ID scope).

This was wroking so far only because code called through this function
(`BKE_collection_parent_relations_rebuild`) was only following parents
pointers (in `BKE_collection_find_cycle()`), which would be either valid
or non-existent.

But next commit is going to change that to also check collection's
objects instancing of other collections.
2020-06-15 17:25:51 +02:00
Jeroen Bakker
624994caa2 Fix T77496: Bones Custom Shapes Wires not drawn
Lines loose extraction cannot happen on the fly as the render data isn't
complete. This patch will do the lines loose subbuffer extraction as a
simple task and not on the fly.

This patch introduces 2 sub-types of tasks that are executed single threaded.
`EXTRACT_MESH_EXTRACT` would do the extraction using Mesh/BMesh geometry.
`EXTRACT_LINES_LOOSE` creates the `lines_loose` subbuffer from already cached
`lines` IBO.

Reviewed By: Clément Foucault

Differential Revision: https://developer.blender.org/D7964
2020-06-15 16:47:21 +02:00
Bastien Montagne
df1ff76ee2 Fix T77774: New undo code broken by 'make local' behavior.
This is actually a nice issue due to too much optimization...
* Making an ID local just reuse the linked one whenever possible, instead of
  actually making a copy of it.
* Therefore, the collection containing that ID is seen as unchanged, since
  the pointer itself remained the same.
* But on undo step, there is no way to reuse that local object, which then
  gets deleted, and linked one gets re-created - at a different address.
* Collection, however, since unchanged, is not updated at all and thus keeps
  reference to the to-be-deleted local object, instead of the linked one.
* Issue gets even worse with viewlayers, this leads to the crash.

To address this, this patch adds a 'virtual' update flags that does nothing
in update case, but will ensure that the affected IDs using the one made local
are properly detected as changed across the relevant undo step.

Note that the recalc flags were chosen mostly for a logical reason, and also
because they are already properly dealt with and cleared by undo code,
so this looks like the optimal solution.

Reviewed By: brecht

Maniphest Tasks: T77774

Differential Revision: https://developer.blender.org/D8006
2020-06-15 15:35:49 +02:00
0945a79ed1 Fix crash using shrink-wrap modifier in edit-mode
Regression in deaff945d0.
2020-06-15 23:29:54 +10:00
Jeroen Bakker
ab8a691431 Fix T77342: Fail to draw loose edges
The underlying issue is that the loose edge extraction cannot be
threaded. This patch will extract the loose edges during initialization
of the render mesh data.

When working on this patch the mesh_render_data_update was split into
multiple functions to identify what part was failing. These functions
would also help us with debugging.

Reviewed By: Clément Foucault

Differential Revision: https://developer.blender.org/D7962
2020-06-15 15:26:21 +02:00
Jeroen Bakker
3c717a631b Fix Memory Leak introduced by Draw Manager Threading
The memory leak is noticeable when using custom bone shapes. When using custom
bone shapes objects could be extracted twice. Where the second extraction can
overwrite data created by the first extraction what causes the memory leak.

Options that have been checked:
1. Use two task graphs phases. One for normal extraction (DST.task_graph) and
   the other one will handle extractions that require blocking threads.
2. Keep a list of all objects that needs extraction and only start extraction
   when all objects have been populated.

The second would slow performance as the extraction only happens when all
objects have been populated. In the future we might want to go for the second
option when we have the capability to render multiple viewports with a single
populate. As this design isn't clear this patch will implement the first
option.

Reviewed By: Clément Foucault

Differential Revision: https://developer.blender.org/D7969
2020-06-15 15:22:57 +02:00
ec25084f5a Fix T77541: Unregistering DATA_PT_modifiers doesn't remove modifier panels
This is a pretty quick fix; the solution is just removing all the
instanced panels whena panel is unregistered. This also necessitates
adding the option to call UI_panels_free_instanced with NULL context.

Differential Revision: https://developer.blender.org/D7977
2020-06-15 09:06:54 -04:00
eadbdf170a Fix T77853: Error reloading linked library.
Issue related to how ID refcounting was changed when loading blendfile
data...
2020-06-15 15:03:53 +02:00
cf42721fe2 Cleanup: Rearrange Vert and Edge slide functions
And make `trans_mesh_customdata_correction` a more generic utility.
2020-06-15 09:53:18 -03:00
046afacbc6 Fix T77116: Current frame indicator text color hardcoded
Draw the text with the "header text highlight" theme color, which is
rarely used, making it a good candidate for this special case.

Differential Revision: https://developer.blender.org/D7897
2020-06-15 08:35:52 -04:00
73f8dd0f4c Fix T77596: UI: Correct "offset even" location in solidify modifier
This only applies in the "simple" solidify mode.

Differential Revision: https://developer.blender.org/D7967
2020-06-15 08:23:07 -04:00
2797a63a66 Cleanup: remove unnecessary code
This got committed due to a stupid mistake of mine, it does not belong
there at all.
2020-06-15 12:35:51 +02:00
ee61c1fe22 Cleanup: removed trailing spaces from install_deps.sh
No functional changes.
2020-06-15 11:58:58 +02:00
0d59a643aa x264: update URL and hash in versions.cmake
The old URL did have a Git commit hash in it, but apparently the server
was ignoring it and only used the `master` that was also mentioned in the
URL. As a result, every new download would get the latest version from
the `master` branch, invalidating the SHA256 checksum.

I replaced `master` with the actual commit hash. This should make the
situation stable.

No functional changes.
2020-06-15 11:58:58 +02:00
0102b9d47e Alembic: remove HDF5 support from CMake files
This is a follup to 0c38436227.

No functional changes to Blender, just the build scripts.
2020-06-15 11:58:58 +02:00
76ebc608af Fix T77871: GPencil masked points fails with previous point
If selected a point for masking, the previous point that is part of the same segment was included.

This bug was in Sculpt and Vertex paint modes because the code was very similar.
2020-06-15 11:49:08 +02:00
0c38436227 Alembic: remove support for HDF5 archive format
Alembic is not a single file format, it can be stored in two different
ways: Ogawa and HDF5. Ogawa replaced HDF5 and is smaller and much faster
(4-25x) to read ([source](http://exocortex.com/blog/alembic_is_about_to_get_really_fast)).

As long as Blender has had Alembic support, it has never supported the
HDF5 format in any release. There is a build option `WITH_ALEMBIC_HDF5`
that can be used to enable HDF5 support in your own build. This commit
removes this build option and the code that it manages.

In the years that I have been maintainer of Blender's Alembic code, I
only remember getting a request to support HDF5 once, and that was to
support very old software that has likely since then been updated to
support Ogawa. Ubuntu and Fedora also seem to bundle Blender without
HDF5 support.

This decision was discussed on
[DevTalk](https://devtalk.blender.org/t/alembic-hdf5-support-completely-remove)
where someone also mentioned that there is a tool available that can
convert HDF5 files to the Ogawa format.
2020-06-15 11:12:24 +02:00
ece7ebb3a8 Fix text after '|' being right aligned in the ID selector
Only use this to right align libraries when they are added to the name.

Caused by d62bbf4079.
2020-06-15 19:06:07 +10:00
fbf6eb509a Fix T77869: GPencil material preview not visible before frame 2
The problem was related to the change introduced in commit 11ba9eec70

As now the keyframe is only visible if the keyframe is greater or equal than current scene frame and  the preview file had all keyframes in frame number 2, it was not used in frame 0 or 1.

Now, the keyframes have been moved to frame 0.
2020-06-15 11:01:28 +02:00
b358a92faf Various UI messages fixes... 2020-06-15 10:51:26 +02:00
1d6529873f Fix T77735: Numinput of radial control operator behaved incorrectly
This fixes the behavior of `ctrl+F` and `shift+F` to control the angle
and strength of a brush when the unit scale is not one.

Reviewers: pablodp606

Differential Revision: https://developer.blender.org/D7992
2020-06-15 09:46:27 +02:00
bf8b62e874 Fix curve handle color ID display
Regression in 49f59092e7 caused all handles to display using
the 'aligned' theme color.

Arrange flags to fix this, add assert to avoid this happening again.

Also rename flag so it's use is clearer.
2020-06-15 15:33:42 +10:00
Tobias Heinke
24d77e7db7 API docs: mathutils leaked markup
Reviewed By: Blendify

Differential Revision: https://developer.blender.org/D8021
2020-06-14 19:15:05 -04:00
caa1b16acc UI: Do not use term 'Subsurf'
So not to be confused with subsurf scatter

Differential Revision: https://developer.blender.org/D8005
2020-06-14 19:06:58 -04:00
4155f8dc21 deps/windows/embree: Prevent exports leaking out of blender binary
embree marks a few of its functions with a dll_export macro
forcibly exporting these symbols from whatever binary links
them. Given we link embree statically and we do not want these
exports in the blender binary, the macro needs to be a no-op.
2020-06-14 11:09:32 -06:00
9464260ed7 Fix T76563: Transforming an auto-aligned point won't set it aligned
Correct previous commit that was checking values not yet initialized,
causing T77796.
2020-06-15 01:07:59 +10:00
cbd894e5a8 Cleanup: remove unnecessary header
Introduced in D8007
2020-06-15 01:07:50 +10:00
725cc959c7 install_deps: Update python default version to 3.7.7.
Re T77846.
2020-06-14 09:42:20 +02:00
b325ecef9c Deps builder: Python 3.7.7
This updates python to the latest patch level available for 3.7
also updates some of the packages we rely on:

idna 2.9
urllib3 1.25.9
cerifi 2020.4.5.2
requests 2.23.0
numpy 1.17.5
2020-06-13 15:25:19 -06:00
b29b1c4ef2 UI: Use consistent order for particle display icons
The viewport, render display order matches modifiers, physics,
and the outliner.

Differential Revision: https://developer.blender.org/D7998
2020-06-13 16:58:55 -04:00
23d0361b30 Sculpt: Fix creation of repeated constraints in the Cloth Brush
Previously, constraints were added multiple times from different
vertices. This adds a GSet to check that the same constraint is not
being added twice when iterating over the neighbors of two different
vertices.

Reviewed By: zeddb

Differential Revision: https://developer.blender.org/D8007
2020-06-13 19:15:29 +02:00
fe3ca3f6ce Fix T66786: Audio SDL: Video editor Sound muted without muting it
Porting fix for SDL 2 audio formats from audaspace upstream.
2020-06-13 15:19:03 +02:00
2a51feff99 Fix error selecting similar vertex groups after the 32nd
Replace 32bit int with bitmap to allow selecting
any number of vertex groups.
2020-06-13 16:56:23 +10:00
827959ff98 Cleanup: use const arguments to deform functions
This changes curve deform code not to set the objects inverse matrix,
this shouldn't cause problems as it's not used elsewhere afterwards.
2020-06-13 16:20:09 +10:00
dd4071b379 Cleanup: remove redundant casts 2020-06-13 15:56:40 +10:00
c5a0ce1ade Cleanup: naming for lattice deform functions
- BKE_lattice_deform_data_create    was init_latt_deform.
- BKE_lattice_deform_data_destroy   was end_latt_deform.
- BKE_lattice_deform_data_eval_co   was calc_latt_deform.
2020-06-13 15:56:40 +10:00
ca10903299 Cleanup: use 'r_' prefix for return arguments
Also improve alignment.
2020-06-13 15:56:36 +10:00
75aac463e7 Cleanup: comments, use bool return value 2020-06-13 15:16:18 +10:00
1754828e33 Cleanup: rename 'par', in deform code
Naming is from legacy code where the deforming object was the parent.
2020-06-13 15:02:47 +10:00
9f5833798c Modifier: skip edit-mesh conversion for armature, curve & lattice
This is an improvement over 2.7x which converted edit-mesh to mesh
(CDDM) for all 3 modifiers.

Overall this increases performance in edit-mode by around 15-20%.
2020-06-13 13:19:34 +10:00
a35de34eb7 Cleanup: clang-format, unused variable 2020-06-13 12:50:19 +10:00
dea2c3f256 Cleanup: spelling 2020-06-13 12:50:07 +10:00
098008f42d Fix T77295: Snapping in edit mode only works for non-selected polys/verts/edges
Caused by the optimization of `Skip EditMesh to Mesh Conversion`.

Now that EditMesh is used when the Mesh has no modifiers, do not
skip the selected elements.
2020-06-12 22:07:27 -03:00
fd8d245e6a LibOverride: Remove 'auto override' option.
Now all overrides are handled that way. Performances of the process look
decent enough, even with production characters...

If performance issues still arise, we'll investigate other solutions.

This should also make T73154 obsolete now.
2020-06-12 19:01:54 +02:00
b586f801fc Cycles: Improve CUDA and OptiX error reporting in the viewport
This patch makes the infamous "Cancel" error in the viewport a thing of the past. Instead it
now shows a more useful error message and streamlines the error handling process in CUDA.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D8008
2020-06-12 18:24:15 +02:00
Simone Barbieri
5dca72dfc9 Add ability to remove Library data-blocks through RNA API.
Just uses same code as for all the other ID types.

Reviewed By: mont29

Differential Revision: https://developer.blender.org/D7995
2020-06-12 17:52:14 +02:00
dupoxy
091d801e9f UI: Use consistent order for physics display icons
The viewport, display order matches modifiers and the outliner.

Differential Revision: https://developer.blender.org/D8001
2020-06-12 11:38:22 -04:00
b1f9799508 Cloth: implement support for a hydrostatic pressure gradient.
When a fluid is put under influence of gravity or acceleration, it
forms an internal pressure gradient, which causes observable effects
like buoyancy. Since now cloth has support for simulating pressure
changes caused by fluid compression or expansion, it makes sense to
also support the effects of gravity.

This is intended for better simulation of objects filled or
surrounded by fluids, especially when constrained by collisions
or pinned vertices, and should result in more realistic shapes.

Obviously, this doesn't actually simulate fluid dynamics; instead
it is assumed that the fluid immediately adapts to changes in the
shape or acceleration of the object without friction or turbulence,
and instantly reaches a new static equilibrium.

Differential Revision: https://developer.blender.org/D6442
2020-06-12 18:19:40 +03:00
0981b55182 install_deps: bumped USD library version 19.11 → 20.02 2020-06-12 17:09:53 +02:00
cfff8aa067 USD: Library upgrade 19.11 → 20.02
This upgrade required a few changes:
- Some parts of our patch are no longer necessary, as the USD library
  now includes those changes.
- The rest of the patch needed adjustment as the `pxr/base/lib/*`
  directories in USD's source code have moved to `pxr/base/*`.
- Updated library names on Windows -- thanks @LazyDodo.

Note that this does not enable the USD Python API for inclusion in
Blender. It just aims at being an as-simple-as-possible version upgrade
of the USD library.
2020-06-12 16:56:31 +02:00
dc80fe5a3f USD: Use new material binding API
The material binding API that we used was removed in the Universal Scene
Description library version 20.02. Using this new API, the code is
compatible with both USD 19.11 and 20.02.
2020-06-12 16:37:02 +02:00
7e43bbb790 Fix T77586 EEVEE: UDIM image Texture doesn't Display properly 2020-06-12 16:17:37 +02:00
9f5cc128d9 Buildbot: Switch to devtoolset-9
Famous "should just work", but will never know until actually attempted
 to be used.

Ref T76783.
2020-06-12 16:06:54 +02:00
326db1b7cd GPencil: Make accessible via python to keyframe type
This can be requiered for some add-ons and for some reason this prop was missing in RNA.
2020-06-12 15:44:58 +02:00
9cc0597556 Functions: Wrap into blender namespace
Similar to previous commit, aims to resolve compilation on
devtoolset-6.
2020-06-12 15:39:16 +02:00
f8696742bb Fix/workaround compilation error on devtoolset-6
Smells like GCC bug [1], which is backed up by the fact that locally
GCC-10 and CLang-10 works fine.

Since the change is trivial (and, arguably, correct since there is
no real difference between tests code and actual code) seems fine to
fix.

Fix suggested by Jacques Lucke, thanks!

[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480
2020-06-12 15:17:17 +02:00
fd14d1cceb DRW: Avoid undefined behavior when running multiple iteration
This was caused by DST.dupli_origin not being reset properly. This had
not effect in master but has effect in EEVEE motion blur branch.
2020-06-12 14:06:53 +02:00
a809631ff2 VR: Fix too dark rendering on SteamVR
Apply the sRGB transform workaround we already apply for Monado (and used
to apply for Windows Mixed Reality).
2020-06-12 13:12:45 +02:00
f12fe3c23e VR: SteamVR is now a supported OpenXR runtime! (Windows only)
Steam just released a SteamVR update with OpenXR Developer Preview
support:
https://steamcommunity.com/games/250820/announcements/detail/2396425843528787270.

Once SteamVR is set up for OpenXR (see link above), it works with
Blender "out of the box", thanks to OpenXR!

We have to apply the sRGB transform workaround for SteamVR though,
otherwise it renders way too dark. Done in the next commit.

Note that AMD users may still only see a pink screen, because the
OpenGL-DirectX compatibility fails. I will check on a fix again.
For SteamVR on Linux we may have to wait for until it supports OpenGL
rendering for OpenXR. Alternatively, we *could* add initial Vulkan
support at Ghost level and use Vulkan<->OpenGL interoperability
extensions, Monado uses these as  well.
2020-06-12 13:12:14 +02:00
16595b9ea1 Cleanup: split object data deform functions into their own files
Move armature/curve functions into their headers,
they were previously in BKE_lattice.h
2020-06-12 16:27:46 +10:00
5549fa5466 Cleanup: use doxy sections for armature.c 2020-06-12 15:06:07 +10:00
f79856f9fb Cleanup: minor changes to deform functions
- Use 'float (*)[3]' to avoid casts.
- Remove unnecessary float[3] copy in gpencil_deform_verts.
- Use MEM_SAFE_FREE
- Use const arguments.
2020-06-12 14:39:49 +10:00
24d39620fb Cleanup: split deform functions that take target object-data
Prefer meaningful function names over redundant NULL arguments.

Also clarify variable names as it wasn't obvious the object-data
is part of the object target.
2020-06-12 13:53:25 +10:00
c02baf8b50 Cleanup: use BKE_ prefix for deform functions 2020-06-12 12:52:24 +10:00
c73ee8d998 Makefile: Add build target for release
Fixes T77353
2020-06-11 17:28:01 -04:00
526e8a3da1 GPencil: Cleanup transform code 2020-06-11 20:35:50 +02:00
a03ebe9431 UI: Adjust names for Find/Replace Set Selection
This is really doing two operation so using the ampersand makes more 
sense.
Also selection sounds better than selected.
This also adjusts the name in the text Edit menu which was an issue 
raised in T68738
2020-06-11 14:05:57 -04:00
a61ba6c73d Fix possibility to add objects in override collections.
Override collections do not support that, add proper checks in BKE code
adding objects to collections.

Also try to find a suitable collection in parents in that case.

Note that this is enforced on 'public' API level, internal code can
still bypass those checks if needed. Exposing this possibility to public
API should not be needed.
2020-06-11 17:33:06 +02:00
3d18bd5c51 BLI: define default hash function for const types 2020-06-11 16:16:44 +02:00
49af2f85c3 BLI: fix forwarding with incorrect type 2020-06-11 16:01:25 +02:00
a364032dff Cleanup: fix terminology in comment 2020-06-11 15:39:53 +02:00
e44045745d BLI: don't pass const pointers to placement new operator
This resulted in compile errors.
2020-06-11 15:37:09 +02:00
e22098616c BLI: include <new> header
This header defines default placement versions of operator new.
2020-06-11 15:37:09 +02:00
Jeroen Bakker
ed00b5def6 Fix T77657: NVIDIA Quadro FX4800 crash on startup
Limit support for `GLEW_ARB_base_instance` to OpenGL 4.0 and higher. NVIDIA Quadro FX 4800
(TeraScale) report that they support GLEW_ARB_base_instance, but the driver does not support
`GLEW_ARB_draw_indirect` as it has an OpenGL3 context what also matches the minimum needed
requirements.

We use `GLEW_ARB_draw_indirect` as a target for `glMapBuffer(Range)` what is part of the
OpenGL 4 API. So better disable it when we don't have an OpenGL4 context.

Note: fix should be ported to Blender 2.83 LTS

Reviewed By: Clément Foucault

Differential Revision: https://developer.blender.org/D7994
2020-06-11 15:34:35 +02:00
9385d887d1 Fix bad poll function for constraints in liboverrides. 2020-06-11 12:01:20 +02:00
95aa8ffed5 BLI: fix printing name in print_stats methods of Map, Set and VectorSet 2020-06-11 11:21:51 +02:00
665acd2903 Fix T69497: Color Correction node ignores mask in certain cases
Happens when some of the color correction terms are mathematically
undefined: foe example, when pow() is to be calculated and the X
argument is negative.

There is no ground-truth result in such cases, so ignore such terms
entirely.

This is a generalization of D6696 from Jacques.

Differential Revision: https://developer.blender.org/D7966
2020-06-11 11:02:33 +02:00
f028760b83 BLI: make Map::Item and Map::MutableItem more accessible
This makes it easier to write range-for loops over all items
in the map without using auto.
2020-06-11 10:48:52 +02:00
3f648f5b42 Fix T77171: File selector doesn't tag preferences to be saved 2020-06-11 17:24:00 +10:00
e43a948a2c Sequencer: view toggle no longer cycles over SEQUENCER_PREVIEW state
- Remove the operator, use a generic operator instead.
- Switch between PREVIEW/SEQUENCER as the mixed state isn't as useful.
- Add menu item  to make the shortcut discoverable.
- Remove unused & broken "View Type" menu.
2020-06-11 16:36:23 +10:00
e916817520 Cleanup: move sequencer view operators into sequencer_view.c 2020-06-11 16:01:47 +10:00
cc064acf0f UI: exclude context menus from menu search
This causes the search result to be less predictable as well as
including menu items multiple times.
2020-06-11 15:39:03 +10:00
a76fc2f7ed WM: utility function to iterate on menu types 2020-06-11 15:35:46 +10:00
2c463a8250 ImBuf: use more accurate DPI/PPM conversion
Use 0.0254 for conversion as 39.3700787 isn't exactly 1/0.0254
and can't be written as a round float/double.
2020-06-11 15:04:11 +10:00
0439094105 Cleanup: make the sculpt convert type follow transform convention 2020-06-10 16:36:16 -03:00
bfa5eceb89 UI: Only set panel data expand flag for active panels
This solves a crash when switching from the modifiers tab to an armature
object and expanding a panel. Thanks to Alexander Gavrilov for mentioning
the problem.
2020-06-10 14:56:52 -04:00
faf5f7b63d Cleanup: fix compiler warning after recent changes
It would be good to use override for all member functions, but doing it for
only somes generates compiler warning.
2020-06-10 20:34:01 +02:00
63930c41bc Fix Cycles viewport missing refresh when changing scene hair settings
This code was not updated for the CoW depsgraph.
2020-06-10 19:48:08 +02:00
0621c13b3e Add proper handling of liboverrides to Scene deep copy.
Followup to rB74ec37b70cbc8dc2, also missed a case in collection
deepcopy then.
2020-06-10 19:45:52 +02:00
14bd92b12f Installdeps: Fix broken commit rBe3396d8bfc94.
Not sure why final version of the change was lost...
2020-06-10 19:45:52 +02:00
91462fbb31 Cleanup: Remove no more used ED_object_single_users.
This utils was only used for scenes' full copy, and was using old
deprecated ways to deal with ID relations and such. Good riddance!
2020-06-10 19:45:52 +02:00
4f314ee5b9 Cleanup: rename BKE_scene_copy to _update.
Matches other similar cases for collection and object, and general
naming rule (copy is for generic ID copying, duplicate is for more
involved and poweful behaviors specific to an ID type).
2020-06-10 19:45:52 +02:00
eee35ebdfb Make BKE_scene_copy fully handle all duplicate modes, deep copy included.
This greatly simplifies and unifies logic.

Also addresses T77255: full scene copy will now use same preferences
parameters as object or collection duplicate to choose which data-blocks
to copy along.
2020-06-10 19:45:52 +02:00
b05fa123d7 Make `BKE_collection_duplicate able to handle master collections.
Those are then assumed already duplicated, and not touched. However, all
of ther objects and sub-collections can still be processed as with any
other regular collection...
2020-06-10 19:45:52 +02:00
474b288933 BLI: add Map.pop_default method
There is a nice use case for this in depsgraph code.

Also I added some previously missing calls to std::move.
2020-06-10 19:02:34 +02:00
20658e6a29 Fix T77047: Dyntopo Sample detail size on hidden mesh causes crash
The `Toolbar` and `Sidebar` hide the corresponding panel
`VIEW3D_PT_sculpt_dyntopo` by polling for context.sculpt_object and
context.tool_settings.sculpt. In the Active Tool in the Properties
Editor this poll does not return False though, thus the
sample_detail_size is possible from there.

Second security check (the operator poll `SCULPT_mode_poll`) checks the
active object -- that is still valid even if hidden, so we are allowed
to execute the operator. However the active object becomes NULL once the
area is switched in `sample_detail()` -- see `CTX_wm_area_set`), leading
to the crash.

Dont think there is a quick and easy way to do this in the poll from the
Properties Editor, so just check for a valid active abject in the
operator and return OPERATOR_CANCELLED if we dont have it.

Maniphest Tasks: T77047

Differential Revision: https://developer.blender.org/D7832
2020-06-10 18:46:41 +02:00
4b39de677d Fix T74101: File Browser in macOS fullscreen crashes or makes windows unusable
When closing the File Browser window after making it fullscreen, Blender would
either crash or all windows would disappear, with no obvious way to bring them
back.

The "fix" is to not allow fullscreen for File Browsers (or any future "dialog"
windows), but only maximizing. From what I can tell that's how secondary
windows are supposed to work on macOS. What we previously did seemed like
something macOS doesn't handle cleanly, and I didn't find a simple way to do so
on our side.
2020-06-10 18:40:05 +02:00
84d4447bc5 BLI: fix type forwarding in Map
Without this change, the code might do an unwanted conversion.
2020-06-10 18:27:18 +02:00
4c172f7ca6 BLI: support constructing StringRef from start and end pointer 2020-06-10 18:27:18 +02:00
1679 changed files with 75780 additions and 63088 deletions

View File

@@ -278,7 +278,6 @@ option(WITH_CODEC_SNDFILE "Enable libsndfile Support (http://www.mega-nerd
# Alembic support
option(WITH_ALEMBIC "Enable Alembic Support" ON)
option(WITH_ALEMBIC_HDF5 "Enable Legacy Alembic Support (not officially supported)" OFF)
# Universal Scene Description support
option(WITH_USD "Enable Universal Scene Description (USD) Support" ON)
@@ -322,14 +321,6 @@ mark_as_advanced(WITH_SYSTEM_GLOG)
# Freestyle
option(WITH_FREESTYLE "Enable Freestyle (advanced edges rendering)" ON)
# New object types
option(WITH_NEW_OBJECT_TYPES "Enable new hair and pointcloud objects (use for development only, don't save in files)" OFF)
mark_as_advanced(WITH_NEW_OBJECT_TYPES)
# New simulation data block
option(WITH_NEW_SIMULATION_TYPE "Enable simulation data block (use for development only, don't save in files)" OFF)
mark_as_advanced(WITH_NEW_SIMULATION_TYPE)
# Misc
if(WIN32)
option(WITH_INPUT_IME "Enable Input Method Editor (IME) for complex Asian character input" ON)
@@ -371,7 +362,7 @@ option(WITH_CYCLES "Enable Cycles Render Engine" ON)
option(WITH_CYCLES_STANDALONE "Build Cycles standalone application" OFF)
option(WITH_CYCLES_STANDALONE_GUI "Build Cycles standalone with GUI" OFF)
option(WITH_CYCLES_OSL "Build Cycles with OSL support" ON)
option(WITH_CYCLES_EMBREE "Build Cycles with Embree support" OFF)
option(WITH_CYCLES_EMBREE "Build Cycles with Embree support" ON)
option(WITH_CYCLES_CUDA_BINARIES "Build Cycles CUDA binaries" OFF)
option(WITH_CYCLES_CUBIN_COMPILER "Build cubins with nvrtc based compiler instead of nvcc" OFF)
option(WITH_CYCLES_CUDA_BUILD_SERIAL "Build cubins one after another (useful on machines with limited RAM)" OFF)
@@ -655,6 +646,7 @@ if(WITH_BOOST AND NOT (WITH_CYCLES OR WITH_OPENIMAGEIO OR WITH_INTERNATIONAL OR
set(WITH_BOOST OFF)
endif()
set_and_warn_dependency(WITH_TBB WITH_CYCLES OFF)
set_and_warn_dependency(WITH_TBB WITH_USD OFF)
set_and_warn_dependency(WITH_TBB WITH_OPENIMAGEDENOISE OFF)
set_and_warn_dependency(WITH_TBB WITH_OPENVDB OFF)
@@ -1246,7 +1238,7 @@ endif()
if(WITH_LIBMV)
# We always have C++11 which includes unordered_map.
set(CERES_DEFINES -DCERES_STD_UNORDERED_MAP)
set(CERES_DEFINES "-DCERES_STD_UNORDERED_MAP;-DCERES_USE_CXX_THREADS")
endif()
#-----------------------------------------------------------------------------
@@ -1562,20 +1554,15 @@ if(WITH_PYTHON)
endif()
if(MSVC)
# MSVC needs to be tested first, since clang on windows will
# match the compiler test below but clang-cl does not accept -std=c++11
# since it is on by default and cannot be turned off.
#
# Nothing special is needed, C++11 features are available by default.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++17")
elseif(
CMAKE_COMPILER_IS_GNUCC OR
CMAKE_C_COMPILER_ID MATCHES "Clang" OR
CMAKE_C_COMPILER_ID MATCHES "Intel"
)
# TODO(sergey): Do we want c++11 or gnu-c++11 here?
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
else()
message(FATAL_ERROR "Unknown compiler ${CMAKE_C_COMPILER_ID}, can't enable C++11 build")
message(FATAL_ERROR "Unknown compiler ${CMAKE_C_COMPILER_ID}, can't enable C++17 build")
endif()
# Visual Studio has all standards it supports available by default

View File

@@ -32,6 +32,7 @@ Convenience Targets
* debug: Build a debug binary.
* full: Enable all supported dependencies & options.
* lite: Disable non essential features for a smaller binary and faster build.
* release Complete build with all options enabled including CUDA and Optix, matching the releases on blender.org
* headless: Build without an interface (renderfarm or server automation).
* cycles: Build Cycles standalone only, without Blender.
* bpy: Build as a python module which can be loaded from python directly.
@@ -141,6 +142,10 @@ Information
endef
# HELP_TEXT (end)
# This makefile is not meant for Windows
ifeq ($(OS),Windows_NT)
$(error On Windows, use "cmd //c make.bat" instead of "make")
endif
# System Vars
OS:=$(shell uname -s)
@@ -207,6 +212,10 @@ ifneq "$(findstring lite, $(MAKECMDGOALS))" ""
BUILD_DIR:=$(BUILD_DIR)_lite
CMAKE_CONFIG_ARGS:=-C"$(BLENDER_DIR)/build_files/cmake/config/blender_lite.cmake" $(CMAKE_CONFIG_ARGS)
endif
ifneq "$(findstring release, $(MAKECMDGOALS))" ""
BUILD_DIR:=$(BUILD_DIR)_release
CMAKE_CONFIG_ARGS:=-C"$(BLENDER_DIR)/build_files/cmake/config/blender_release.cmake" $(CMAKE_CONFIG_ARGS)
endif
ifneq "$(findstring cycles, $(MAKECMDGOALS))" ""
BUILD_DIR:=$(BUILD_DIR)_cycles
CMAKE_CONFIG_ARGS:=-C"$(BLENDER_DIR)/build_files/cmake/config/cycles_standalone.cmake" $(CMAKE_CONFIG_ARGS)
@@ -317,6 +326,7 @@ all: .FORCE
debug: all
full: all
lite: all
release: all
cycles: all
headless: all
bpy: all

View File

@@ -48,11 +48,7 @@ include(cmake/options.cmake)
include(cmake/versions.cmake)
if(ENABLE_MINGW64)
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
include(cmake/setup_mingw64.cmake)
else()
include(cmake/setup_mingw32.cmake)
endif()
include(cmake/setup_mingw64.cmake)
else()
set(mingw_LIBDIR ${LIBDIR})
endif()
@@ -97,17 +93,18 @@ if(UNIX)
else()
include(cmake/pugixml.cmake)
endif()
include(cmake/ispc.cmake)
include(cmake/openimagedenoise.cmake)
include(cmake/embree.cmake)
include(cmake/xr_openxr.cmake)
if(NOT APPLE)
include(cmake/xr_openxr.cmake)
endif()
if(WITH_WEBP)
include(cmake/webp.cmake)
endif()
if(WIN32)
# HMD branch deps
include(cmake/hidapi.cmake)
# OCIO deps
include(cmake/tinyxml.cmake)
include(cmake/yamlcpp.cmake)

View File

@@ -16,16 +16,6 @@
#
# ***** END GPL LICENSE BLOCK *****
if(ALEMBIC_HDF5)
set(ALEMBIC_HDF5_HL)
# in debug mode we do not build HDF5_hdf5_hl_LIBRARY which makes cmake really
# unhappy, stub it with the debug mode lib. it's not linking it in at this
# point in time anyhow
if(BUILD_MODE STREQUAL Debug)
set(ALEMBIC_HDF5_HL -DHDF5_hdf5_hl_LIBRARY=${LIBDIR}/hdf5/lib/libhdf5_hl_D.${LIBEXT})
endif()
endif()
set(ALEMBIC_EXTRA_ARGS
-DBUILDSTATIC=ON
-DLINKSTATIC=ON
@@ -53,7 +43,6 @@ set(ALEMBIC_EXTRA_ARGS
-DUSE_PRMAN=0
-DUSE_HDF5=Off
-DUSE_STATIC_HDF5=Off
-DHDF5_ROOT=${LIBDIR}/hdf5
-DUSE_TESTS=Off
-DALEMBIC_NO_OPENGL=1
-DUSE_BINARIES=ON
@@ -62,7 +51,6 @@ set(ALEMBIC_EXTRA_ARGS
-DGLUT_INCLUDE_DIR=""
-DZLIB_LIBRARY=${LIBDIR}/zlib/lib/${ZLIB_LIBRARY}
-DZLIB_INCLUDE_DIR=${LIBDIR}/zlib/include/
${ALEMBIC_HDF5_HL}
)
ExternalProject_Add(external_alembic

View File

@@ -51,6 +51,7 @@ ExternalProject_Add(external_embree
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH MD5=${EMBREE_HASH}
PREFIX ${BUILD_DIR}/embree
PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/embree/src/external_embree < ${PATCH_DIR}/embree.diff
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/embree ${DEFAULT_CMAKE_FLAGS} ${EMBREE_EXTRA_ARGS}
INSTALL_DIR ${LIBDIR}/embree
)

View File

@@ -43,21 +43,10 @@ if(BUILD_MODE STREQUAL Release)
# tiff
${CMAKE_COMMAND} -E copy ${LIBDIR}/tiff/lib/tiff.lib ${HARVEST_TARGET}/tiff/lib/libtiff.lib &&
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/tiff/include/ ${HARVEST_TARGET}/tiff/include/ &&
# hidapi
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/hidapi/ ${HARVEST_TARGET}/hidapi/
DEPENDS
)
endif()
if(BUILD_MODE STREQUAL Debug)
add_custom_target(Harvest_Debug_Results
COMMAND
# hdf5
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/hdf5/lib ${HARVEST_TARGET}/hdf5/lib &&
DEPENDS Package_Python
)
endif()
else(WIN32)
function(harvest from to)

View File

@@ -1,42 +0,0 @@
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ***** END GPL LICENSE BLOCK *****
set(HDF5_EXTRA_ARGS
-DHDF5_ENABLE_THREADSAFE=Off
-DHDF5_BUILD_CPP_LIB=Off
-DBUILD_TESTING=Off
-DHDF5_BUILD_TOOLS=Off
-DHDF5_BUILD_EXAMPLES=Off
-DHDF5_BUILD_HL_LIB=On
-DBUILD_STATIC_CRT_LIBS=On
-DBUILD_SHARED_LIBS=On
)
if(WIN32)
set(HDF5_PATCH ${PATCH_CMD} --verbose -p 0 -d ${BUILD_DIR}/hdf5/src/external_hdf5 < ${PATCH_DIR}/hdf5.diff)
endif()
ExternalProject_Add(external_hdf5
URL ${HDF5_URI}
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH MD5=${HDF5_HASH}
PREFIX ${BUILD_DIR}/hdf5
PATCH_COMMAND ${HDF5_PATCH}
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/hdf5 ${HDF5_EXTRA_ARGS}
INSTALL_DIR ${LIBDIR}/hdf5
)

View File

@@ -0,0 +1,63 @@
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ***** END GPL LICENSE BLOCK *****
if(WIN32)
set(ISPC_EXTRA_ARGS_WIN
-DFLEX_EXECUTABLE=${LIBDIR}/flexbison/win_flex.exe
-DBISON_EXECUTABLE=${LIBDIR}/flexbison/win_bison.exe
-DM4_EXECUTABLE=${DOWNLOAD_DIR}/mingw/mingw64/msys/1.0/bin/m4.exe
)
endif()
set(ISPC_EXTRA_ARGS
-DARM_ENABLED=Off
-DISPC_NO_DUMPS=On
-DISPC_INCLUDE_EXAMPLES=Off
-DISPC_INCLUDE_TESTS=Off
-DLLVM_ROOT=${LIBDIR}/llvm/lib/cmake/llvm
-DLLVM_LIBRARY_DIR=${LIBDIR}/llvm/lib
-DCLANG_EXECUTABLE=${LIBDIR}/clang/bin/clang
-DISPC_INCLUDE_TESTS=Off
-DCLANG_LIBRARY_DIR=${LIBDIR}/clang/lib
-DCLANG_INCLUDE_DIRS=${LIBDIR}/clang/include
${ISPC_EXTRA_ARGS_WIN}
)
ExternalProject_Add(external_ispc
URL ${ISPC_URI}
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH MD5=${ISPC_HASH}
PREFIX ${BUILD_DIR}/ispc
PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/ispc/src/external_ispc < ${PATCH_DIR}/ispc.diff
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/ispc -Wno-dev ${DEFAULT_CMAKE_FLAGS} ${ISPC_EXTRA_ARGS} ${BUILD_DIR}/ispc/src/external_ispc
INSTALL_DIR ${LIBDIR}/ispc
)
add_dependencies(
external_ispc
ll
external_clang
)
if(WIN32)
add_dependencies(
external_ispc
external_flexbison
)
endif()

View File

@@ -18,26 +18,41 @@
set(OIDN_EXTRA_ARGS
-DWITH_EXAMPLE=OFF
-DWITH_TEST=OFF
-DOIDN_APPS=OFF
-DTBB_ROOT=${LIBDIR}/tbb
-DTBB_STATIC_LIB=${TBB_STATIC_LIBRARY}
-DOIDN_STATIC_LIB=ON
-DOIDN_STATIC_RUNTIME=OFF
-DISPC_EXECUTABLE=${LIBDIR}/ispc/bin/ispc
)
if(WIN32)
set(OIDN_EXTRA_ARGS
${OIDN_EXTRA_ARGS}
-DTBB_DEBUG_LIBRARY=${LIBDIR}/tbb/lib/tbb.lib
-DTBB_DEBUG_LIBRARY_MALLOC=${LIBDIR}/tbb/lib/tbbmalloc.lib
)
else()
set(OIDN_EXTRA_ARGS
${OIDN_EXTRA_ARGS}
-Dtbb_LIBRARY_RELEASE=${LIBDIR}/tbb/lib/tbb_static.a
-Dtbbmalloc_LIBRARY_RELEASE=${LIBDIR}/tbb/lib/tbbmalloc_static.a
)
endif()
ExternalProject_Add(external_openimagedenoise
URL ${OIDN_URI}
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH MD5=${OIDN_HASH}
PREFIX ${BUILD_DIR}/openimagedenoise
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/openimagedenoise ${DEFAULT_CMAKE_FLAGS} ${OIDN_EXTRA_ARGS}
PATCH_COMMAND ${PATCH_CMD} --verbose -p 1 -N -d ${BUILD_DIR}/openimagedenoise/src/external_openimagedenoise < ${PATCH_DIR}/openimagedenoise.diff
INSTALL_DIR ${LIBDIR}/openimagedenoise
)
add_dependencies(
external_openimagedenoise
external_tbb
external_ispc
)
if(WIN32)
@@ -46,7 +61,7 @@ if(WIN32)
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/openimagedenoise/include ${HARVEST_TARGET}/openimagedenoise/include
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/openimagedenoise.lib ${HARVEST_TARGET}/openimagedenoise/lib/openimagedenoise.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/common.lib ${HARVEST_TARGET}/openimagedenoise/lib/common.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/mkldnn.lib ${HARVEST_TARGET}/openimagedenoise/lib/mkldnn.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/dnnl.lib ${HARVEST_TARGET}/openimagedenoise/lib/dnnl.lib
DEPENDEES install
)
endif()
@@ -54,7 +69,7 @@ if(WIN32)
ExternalProject_Add_Step(external_openimagedenoise after_install
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/openimagedenoise.lib ${HARVEST_TARGET}/openimagedenoise/lib/openimagedenoise_d.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/common.lib ${HARVEST_TARGET}/openimagedenoise/lib/common_d.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/mkldnn.lib ${HARVEST_TARGET}/openimagedenoise/lib/mkldnn_d.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/dnnl.lib ${HARVEST_TARGET}/openimagedenoise/lib/dnnl_d.lib
DEPENDEES install
)
endif()

View File

@@ -17,7 +17,7 @@
# ***** END GPL LICENSE BLOCK *****
if(WIN32)
option(ENABLE_MINGW64 "Enable building of ffmpeg/iconv/libsndfile/lapack/fftw3 by installing mingw64" ON)
option(ENABLE_MINGW64 "Enable building of ffmpeg/iconv/libsndfile/fftw3 by installing mingw64" ON)
endif()
option(WITH_WEBP "Enable building of oiio with webp support" OFF)
set(MAKE_THREADS 1 CACHE STRING "Number of threads to run make with")
@@ -45,11 +45,7 @@ message("PATCH_DIR = ${PATCH_DIR}")
message("BUILD_DIR = ${BUILD_DIR}")
if(WIN32)
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
set(PATCH_CMD ${DOWNLOAD_DIR}/mingw/mingw64/msys/1.0/bin/patch.exe)
else()
set(PATCH_CMD ${DOWNLOAD_DIR}/mingw/mingw32/msys/1.0/bin/patch.exe)
endif()
set(PATCH_CMD ${DOWNLOAD_DIR}/mingw/mingw64/msys/1.0/bin/patch.exe)
set(LIBEXT ".lib")
set(LIBPREFIX "")
@@ -82,17 +78,10 @@ if(WIN32)
set(PLATFORM_CXX_FLAGS)
set(PLATFORM_CMAKE_FLAGS)
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
set(MINGW_PATH ${DOWNLOAD_DIR}/mingw/mingw64)
set(MINGW_SHELL ming64sh.cmd)
set(PERL_SHELL ${DOWNLOAD_DIR}/perl/portableshell.bat)
set(MINGW_HOST x86_64-w64-mingw32)
else()
set(MINGW_PATH ${DOWNLOAD_DIR}/mingw/mingw32)
set(MINGW_SHELL ming32sh.cmd)
set(PERL_SHELL ${DOWNLOAD_DIR}/perl32/portableshell.bat)
set(MINGW_HOST i686-w64-mingw32)
endif()
set(MINGW_PATH ${DOWNLOAD_DIR}/mingw/mingw64)
set(MINGW_SHELL ming64sh.cmd)
set(PERL_SHELL ${DOWNLOAD_DIR}/perl/portableshell.bat)
set(MINGW_HOST x86_64-w64-mingw32)
set(CONFIGURE_ENV
cd ${MINGW_PATH} &&

View File

@@ -75,6 +75,7 @@ set(OSL_EXTRA_ARGS
-DUSE_LLVM_BITCODE=OFF
-DUSE_PARTIO=OFF
-DUSE_QT=OFF
-DINSTALL_DOCS=OFF
${OSL_SIMD_FLAGS}
-DPARTIO_LIBRARIES=
)

View File

@@ -1,227 +0,0 @@
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ***** END GPL LICENSE BLOCK *****
####################################################################################################################
# Mingw32 Builds
####################################################################################################################
# This installs mingw32+msys to compile ffmpeg/iconv/libsndfile/lapack/fftw3
####################################################################################################################
message("LIBDIR = ${LIBDIR}")
macro(cmake_to_msys_path MsysPath ResultingPath)
string(REPLACE ":" "" TmpPath "${MsysPath}")
string(SUBSTRING ${TmpPath} 0 1 Drive)
string(SUBSTRING ${TmpPath} 1 255 PathPart)
string(TOLOWER ${Drive} LowerDrive)
string(CONCAT ${ResultingPath} "/" ${LowerDrive} ${PathPart})
endmacro()
cmake_to_msys_path(${LIBDIR} mingw_LIBDIR)
message("mingw_LIBDIR = ${mingw_LIBDIR}")
message("Checking for mingw32")
# download mingw32
if(NOT EXISTS "${DOWNLOAD_DIR}/i686-4.9.4-release-win32-sjlj-rt_v5-rev0.7z")
message("Downloading mingw32")
file(DOWNLOAD "https://astuteinternet.dl.sourceforge.net/project/mingw-w64/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/4.9.4/threads-win32/sjlj/i686-4.9.4-release-win32-sjlj-rt_v5-rev0.7z" "${DOWNLOAD_DIR}/i686-4.9.4-release-win32-sjlj-rt_v5-rev0.7z")
endif()
# make mingw root directory
if(NOT EXISTS "${DOWNLOAD_DIR}/mingw")
execute_process(
COMMAND ${CMAKE_COMMAND} -E make_directory ${DOWNLOAD_DIR}/mingw
WORKING_DIRECTORY ${DOWNLOAD_DIR}
)
endif()
# extract mingw32
if((NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/ming32sh.cmd") AND (EXISTS "${DOWNLOAD_DIR}/i686-4.9.4-release-win32-sjlj-rt_v5-rev0.7z"))
message("Extracting mingw32")
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar jxf ${DOWNLOAD_DIR}/i686-4.9.4-release-win32-sjlj-rt_v5-rev0.7z
WORKING_DIRECTORY ${DOWNLOAD_DIR}/mingw
)
endif()
message("Checking for pkg-config")
if(NOT EXISTS "${DOWNLOAD_DIR}/pkg-config-lite-0.28-1_bin-win32.zip")
message("Downloading pkg-config")
file(DOWNLOAD "https://nchc.dl.sourceforge.net/project/pkgconfiglite/0.28-1/pkg-config-lite-0.28-1_bin-win32.zip" "${DOWNLOAD_DIR}/pkg-config-lite-0.28-1_bin-win32.zip")
endif()
# extract pkgconfig
if((NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/pkg-config.exe") AND (EXISTS "${DOWNLOAD_DIR}/pkg-config-lite-0.28-1_bin-win32.zip"))
message("Extracting pkg-config")
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar jxf "${DOWNLOAD_DIR}/pkg-config-lite-0.28-1_bin-win32.zip"
WORKING_DIRECTORY ${DOWNLOAD_DIR}/
)
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/pkg-config-lite-0.28-1/bin/pkg-config.exe" "${DOWNLOAD_DIR}/mingw/mingw32/bin/pkg-config.exe"
)
endif()
message("Checking for nasm")
if(NOT EXISTS "${DOWNLOAD_DIR}/nasm-2.13.02-win32.zip")
message("Downloading nasm")
file(DOWNLOAD "http://www.nasm.us/pub/nasm/releasebuilds/2.13.02/win32/nasm-2.13.02-win32.zip" "${DOWNLOAD_DIR}/nasm-2.13.02-win32.zip")
endif()
# extract nasm
if((NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/nasm.exe") AND (EXISTS "${DOWNLOAD_DIR}/nasm-2.13.02-win32.zip"))
message("Extracting nasm")
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar jxf "${DOWNLOAD_DIR}/nasm-2.13.02-win32.zip"
WORKING_DIRECTORY ${DOWNLOAD_DIR}/
)
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/nasm-2.13.02/nasm.exe" "${DOWNLOAD_DIR}/mingw/mingw32/bin/nasm.exe"
)
endif()
SET(NASM_PATH ${DOWNLOAD_DIR}/mingw/mingw32/bin/nasm.exe)
message("Checking for mingwGet")
if(NOT EXISTS "${DOWNLOAD_DIR}/mingw-get-0.6.2-mingw32-beta-20131004-1-bin.zip")
message("Downloading mingw-get")
file(DOWNLOAD "https://nchc.dl.sourceforge.net/project/mingw/Installer/mingw-get/mingw-get-0.6.2-beta-20131004-1/mingw-get-0.6.2-mingw32-beta-20131004-1-bin.zip" "${DOWNLOAD_DIR}/mingw-get-0.6.2-mingw32-beta-20131004-1-bin.zip")
endif()
# extract mingw_get
if((NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/mingw-get.exe") AND (EXISTS "${DOWNLOAD_DIR}/mingw-get-0.6.2-mingw32-beta-20131004-1-bin.zip"))
message("Extracting mingw-get")
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar jxf "${DOWNLOAD_DIR}/mingw-get-0.6.2-mingw32-beta-20131004-1-bin.zip"
WORKING_DIRECTORY ${DOWNLOAD_DIR}/mingw/mingw32/
)
endif()
if((EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/mingw-get.exe") AND (NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/msys/1.0/bin/make.exe"))
message("Installing MSYS")
execute_process(
COMMAND ${DOWNLOAD_DIR}/mingw/mingw32/bin/mingw-get install msys msys-patch
WORKING_DIRECTORY ${DOWNLOAD_DIR}/mingw/mingw32/bin/
)
endif()
if((EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/mingw-get.exe") AND (NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/msys/1.0/bin/mktemp.exe"))
message("Installing mktemp")
execute_process(
COMMAND ${DOWNLOAD_DIR}/mingw/mingw32/bin/mingw-get install msys msys-mktemp
WORKING_DIRECTORY ${DOWNLOAD_DIR}/mingw/mingw32/bin/
)
endif()
message("Checking for CoreUtils")
# download old core_utils for pr.exe (ffmpeg needs it to build)
if(NOT EXISTS "${DOWNLOAD_DIR}/coreutils-5.97-MSYS-1.0.11-snapshot.tar.bz2")
message("Downloading CoreUtils 5.97")
file(DOWNLOAD "https://nchc.dl.sourceforge.net/project/mingw/MSYS/Base/msys-core/_obsolete/coreutils-5.97-MSYS-1.0.11-2/coreutils-5.97-MSYS-1.0.11-snapshot.tar.bz2" "${DOWNLOAD_DIR}/coreutils-5.97-MSYS-1.0.11-snapshot.tar.bz2")
endif()
if((EXISTS "${DOWNLOAD_DIR}/coreutils-5.97-MSYS-1.0.11-snapshot.tar.bz2") AND (NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/msys/1.0/bin/pr.exe"))
message("Installing pr from CoreUtils 5.97")
execute_process(
COMMAND ${CMAKE_COMMAND} -E make_directory ${DOWNLOAD_DIR}/tmp_coreutils
WORKING_DIRECTORY ${DOWNLOAD_DIR}
)
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar jxf ${DOWNLOAD_DIR}/coreutils-5.97-MSYS-1.0.11-snapshot.tar.bz2
WORKING_DIRECTORY ${DOWNLOAD_DIR}/tmp_coreutils/
)
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy ${DOWNLOAD_DIR}/tmp_coreutils/coreutils-5.97/bin/pr.exe "${DOWNLOAD_DIR}/mingw/mingw32/msys/1.0/bin/pr.exe"
WORKING_DIRECTORY ${DOWNLOAD_DIR}/tmp_coreutils/
)
endif()
if(NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/ming32sh.cmd")
message("Installing ming32sh.cmd")
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy ${PATCH_DIR}/ming32sh.cmd ${DOWNLOAD_DIR}/mingw/mingw32/ming32sh.cmd
)
endif()
message("Checking for perl")
# download perl for libvpx
if(NOT EXISTS "${DOWNLOAD_DIR}/strawberry-perl-5.22.1.3-32bit-portable.zip")
message("Downloading perl")
file(DOWNLOAD "http://strawberryperl.com/download/5.22.1.3/strawberry-perl-5.22.1.3-32bit-portable.zip" "${DOWNLOAD_DIR}/strawberry-perl-5.22.1.3-32bit-portable.zip")
endif()
# make perl root directory
if(NOT EXISTS "${DOWNLOAD_DIR}/perl32")
execute_process(
COMMAND ${CMAKE_COMMAND} -E make_directory ${DOWNLOAD_DIR}/perl32
WORKING_DIRECTORY ${DOWNLOAD_DIR}
)
endif()
# extract perl
if((NOT EXISTS "${DOWNLOAD_DIR}/perl32/portable.perl") AND (EXISTS "${DOWNLOAD_DIR}/strawberry-perl-5.22.1.3-32bit-portable.zip"))
message("Extracting perl")
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar jxf ${DOWNLOAD_DIR}/strawberry-perl-5.22.1.3-32bit-portable.zip
WORKING_DIRECTORY ${DOWNLOAD_DIR}/perl32
)
endif()
# get yasm for vpx
if(NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/yasm.exe")
message("Downloading yasm")
file(DOWNLOAD "http://www.tortall.net/projects/yasm/releases/yasm-1.3.0-win32.exe" "${DOWNLOAD_DIR}/mingw/mingw32/bin/yasm.exe")
endif()
message("checking i686-w64-mingw32-strings")
# copy strings.exe to i686-w64-mingw32-strings for x264
if(NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/i686-w64-mingw32-strings.exe")
message("fixing i686-w64-mingw32-strings.exe")
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/mingw/mingw32/bin/strings.exe" "${DOWNLOAD_DIR}/mingw/mingw32/bin/i686-w64-mingw32-strings.exe"
)
endif()
message("checking i686-w64-mingw32-ar.exe")
# copy ar.exe to i686-w64-mingw32-ar.exe for x264
if(NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/i686-w64-mingw32-ar.exe")
message("fixing i686-w64-mingw32-ar.exe")
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/mingw/mingw32/bin/ar.exe" "${DOWNLOAD_DIR}/mingw/mingw32/bin/i686-w64-mingw32-ar.exe"
)
endif()
message("checking i686-w64-mingw32-strip.exe")
# copy strip.exe to i686-w64-mingw32-strip.exe for x264
if(NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/i686-w64-mingw32-strip.exe")
message("fixing i686-w64-mingw32-strip.exe")
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/mingw/mingw32/bin/strip.exe" "${DOWNLOAD_DIR}/mingw/mingw32/bin/i686-w64-mingw32-strip.exe"
)
endif()
message("checking i686-w64-mingw32-ranlib.exe")
# copy ranlib.exe to i686-w64-mingw32-ranlib.exe for x264
if(NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/i686-w64-mingw32-ranlib.exe")
message("fixing i686-w64-mingw32-ranlib.exe")
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/mingw/mingw32/bin/ranlib.exe" "${DOWNLOAD_DIR}/mingw/mingw32/bin/i686-w64-mingw32-ranlib.exe"
)
endif()

View File

@@ -19,7 +19,7 @@
####################################################################################################################
# Mingw64 Builds
####################################################################################################################
# This installs mingw64+msys to compile ffmpeg/iconv/libsndfile/lapack/fftw3
# This installs mingw64+msys to compile ffmpeg/iconv/libsndfile/fftw3
####################################################################################################################
message("LIBDIR = ${LIBDIR}")
@@ -128,6 +128,14 @@ if((EXISTS "${DOWNLOAD_DIR}/mingw/mingw64/bin/mingw-get.exe") AND (NOT EXISTS "$
)
endif()
if((EXISTS "${DOWNLOAD_DIR}/mingw/mingw64/bin/mingw-get.exe") AND (NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw64/msys/1.0/bin/m4.exe"))
message("Installing m4")
execute_process(
COMMAND ${DOWNLOAD_DIR}/mingw/mingw64/bin/mingw-get install msys msys-m4
WORKING_DIRECTORY ${DOWNLOAD_DIR}/mingw/mingw64/bin/
)
endif()
message("Checking for CoreUtils")
# download old core_utils for pr.exe (ffmpeg needs it to build)
if(NOT EXISTS "${DOWNLOAD_DIR}/coreutils-5.97-MSYS-1.0.11-snapshot.tar.bz2")

View File

@@ -1,4 +1,4 @@
%targets = (
my %targets = (
"blender-linux-x86" => {
inherit_from => [ "linux-x86" ],

View File

@@ -50,6 +50,13 @@ ExternalProject_Add(external_tbb
if(WIN32)
if(BUILD_MODE STREQUAL Release)
ExternalProject_Add_Step(external_tbb after_install
# findtbb.cmake in some deps *NEEDS* to find tbb_debug.lib even if they are not going to use it
# to make that test pass, we place a copy with the right name in the lib folder.
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/tbb/lib/tbb.lib ${HARVEST_TARGET}/tbb/lib/tbb_debug.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/tbb/lib/tbbmalloc.lib ${HARVEST_TARGET}/tbb/lib/tbbmalloc_debug.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/tbb/lib/tbb.dll ${HARVEST_TARGET}/tbb/lib/tbb_debug.dll
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/tbb/lib/tbbmalloc.dll ${HARVEST_TARGET}/tbb/lib/tbbmalloc_debug.dll
# Normal collection of build artifacts
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/tbb/lib/tbb.lib ${HARVEST_TARGET}/tbb/lib/tbb.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/tbb/lib/tbb.dll ${HARVEST_TARGET}/tbb/lib/tbb.dll
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/tbb/lib/tbbmalloc.lib ${HARVEST_TARGET}/tbb/lib/tbbmalloc.lib

View File

@@ -27,6 +27,9 @@ set(USD_EXTRA_ARGS
-DTBB_INCLUDE_DIRS=${LIBDIR}/tbb/include
-DTBB_LIBRARIES=${LIBDIR}/tbb/lib/${LIBPREFIX}${TBB_LIBRARY}${LIBEXT}
-DTbb_TBB_LIBRARY=${LIBDIR}/tbb/lib/${LIBPREFIX}${TBB_LIBRARY}${LIBEXT}
# USD wants the tbb debug lib set even when you are doing a release build
# Otherwise it will error out during the cmake configure phase.
-DTBB_LIBRARIES_DEBUG=${LIBDIR}/tbb/lib/${LIBPREFIX}${TBB_LIBRARY}${LIBEXT}
# This is a preventative measure that avoids possible conflicts when add-ons
# try to load another USD library into the same process space.
@@ -78,14 +81,14 @@ if(WIN32)
if(BUILD_MODE STREQUAL Release)
ExternalProject_Add_Step(external_usd after_install
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/usd/ ${HARVEST_TARGET}/usd
COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/usd/src/external_usd-build/pxr/Release/libusd_m.lib ${HARVEST_TARGET}/usd/lib/libusd_m.lib
COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/usd/src/external_usd-build/pxr/Release/usd_m.lib ${HARVEST_TARGET}/usd/lib/libusd_m.lib
DEPENDEES install
)
endif()
if(BUILD_MODE STREQUAL Debug)
ExternalProject_Add_Step(external_usd after_install
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/usd/lib ${HARVEST_TARGET}/usd/lib
COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/usd/src/external_usd-build/pxr/Debug/libusd_m_d.lib ${HARVEST_TARGET}/usd/lib/libusd_m_d.lib
COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/usd/src/external_usd-build/pxr/Debug/usd_m_d.lib ${HARVEST_TARGET}/usd/lib/libusd_m_d.lib
DEPENDEES install
)
endif()

View File

@@ -78,10 +78,6 @@ set(FREEGLUT_VERSION 3.0.0)
set(FREEGLUT_URI http://pilotfiber.dl.sourceforge.net/project/freeglut/freeglut/${FREEGLUT_VERSION}/freeglut-${FREEGLUT_VERSION}.tar.gz)
set(FREEGLUT_HASH 90c3ca4dd9d51cf32276bc5344ec9754)
set(HDF5_VERSION 1.8.17)
set(HDF5_URI https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-1.8/hdf5-${HDF5_VERSION}/src/hdf5-${HDF5_VERSION}.tar.gz)
set(HDF5_HASH 7d572f8f3b798a628b8245af0391a0ca)
set(ALEMBIC_VERSION 1.7.12)
set(ALEMBIC_URI https://github.com/alembic/alembic/archive/${ALEMBIC_VERSION}.tar.gz)
set(ALEMBIC_MD5 e2b3777f23c5c09481a008cc6f0f8a40)
@@ -139,11 +135,11 @@ set(OSL_VERSION 1.10.10)
set(OSL_URI https://github.com/imageworks/OpenShadingLanguage/archive/Release-${OSL_VERSION}.tar.gz)
set(OSL_HASH 00dec08a93c8084e53848b9ad047889f)
set(PYTHON_VERSION 3.7.4)
set(PYTHON_VERSION 3.7.7)
set(PYTHON_SHORT_VERSION 3.7)
set(PYTHON_SHORT_VERSION_NO_DOTS 37)
set(PYTHON_URI https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tar.xz)
set(PYTHON_HASH d33e4aae66097051c2eca45ee3604803)
set(PYTHON_HASH 172c650156f7bea68ce31b2fd01fa766)
set(TBB_VERSION 2019_U9)
set(TBB_URI https://github.com/oneapi-src/oneTBB/archive/${TBB_VERSION}.tar.gz)
@@ -153,16 +149,16 @@ set(OPENVDB_VERSION 7.0.0)
set(OPENVDB_URI https://github.com/dreamworksanimation/openvdb/archive/v${OPENVDB_VERSION}.tar.gz)
set(OPENVDB_HASH fd6c4f168282f7e0e494d290cd531fa8)
set(IDNA_VERSION 2.8)
set(IDNA_VERSION 2.9)
set(CHARDET_VERSION 3.0.4)
set(URLLIB3_VERSION 1.25.3)
set(CERTIFI_VERSION 2019.6.16)
set(REQUESTS_VERSION 2.22.0)
set(URLLIB3_VERSION 1.25.9)
set(CERTIFI_VERSION 2020.4.5.2)
set(REQUESTS_VERSION 2.23.0)
set(NUMPY_VERSION v1.17.0)
set(NUMPY_VERSION 1.17.5)
set(NUMPY_SHORT_VERSION 1.17)
set(NUMPY_URI https://files.pythonhosted.org/packages/da/32/1b8f2bb5fb50e4db68543eb85ce37b9fa6660cd05b58bddfafafa7ed62da/numpy-1.17.0.zip)
set(NUMPY_HASH aed49b31bcb44ec73b8155be78566135)
set(NUMPY_URI https://github.com/numpy/numpy/releases/download/v${NUMPY_VERSION}/numpy-${NUMPY_VERSION}.zip)
set(NUMPY_HASH 763a5646fa6eef7a22f4895bca0524f2)
set(LAME_VERSION 3.100)
set(LAME_URI http://downloads.sourceforge.net/project/lame/lame/3.100/lame-${LAME_VERSION}.tar.gz)
@@ -192,8 +188,8 @@ set(OPUS_VERSION 1.3.1)
set(OPUS_URI https://archive.mozilla.org/pub/opus/opus-${OPUS_VERSION}.tar.gz)
set(OPUS_HASH 65b58e1e25b2a114157014736a3d9dfeaad8d41be1c8179866f144a2fb44ff9d)
set(X264_URI https://code.videolan.org/videolan/x264/-/archive/master/x264-33f9e1474613f59392be5ab6a7e7abf60fa63622.tar.gz)
set(X264_HASH 300dfb5b6c35722516f168868ce9419252a9e9eb77a05d82c9cede925b691bd6)
set(X264_URI https://code.videolan.org/videolan/x264/-/archive/33f9e1474613f59392be5ab6a7e7abf60fa63622/x264-33f9e1474613f59392be5ab6a7e7abf60fa63622.tar.gz)
set(X264_HASH 5456450ee1ae02cd2328be3157367a232a0ab73315e8c8f80dab80469524f525)
set(XVIDCORE_VERSION 1.3.7)
set(XVIDCORE_URI https://downloads.xvid.com/downloads/xvidcore-${XVIDCORE_VERSION}.tar.gz)
@@ -216,10 +212,6 @@ set(ICONV_VERSION 1.16)
set(ICONV_URI http://ftp.gnu.org/pub/gnu/libiconv/libiconv-${ICONV_VERSION}.tar.gz)
set(ICONV_HASH 7d2a800b952942bb2880efb00cfd524c)
set(LAPACK_VERSION 3.6.0)
set(LAPACK_URI http://www.netlib.org/lapack/lapack-${LAPACK_VERSION}.tgz)
set(LAPACK_HASH f2f6c67134e851fe189bb3ca1fbb5101)
set(SNDFILE_VERSION 1.0.28)
set(SNDFILE_URI http://www.mega-nerd.com/libsndfile/files/libsndfile-${SNDFILE_VERSION}.tar.gz)
set(SNDFILE_HASH 646b5f98ce89ac60cdb060fcd398247c)
@@ -240,13 +232,13 @@ set(SPNAV_VERSION 0.2.3)
set(SPNAV_URI http://downloads.sourceforge.net/project/spacenav/spacenav%20library%20%28SDK%29/libspnav%20${SPNAV_VERSION}/libspnav-${SPNAV_VERSION}.tar.gz)
set(SPNAV_HASH 44d840540d53326d4a119c0f1aa7bf0a)
set(JEMALLOC_VERSION 5.0.1)
set(JEMALLOC_VERSION 5.2.1)
set(JEMALLOC_URI https://github.com/jemalloc/jemalloc/releases/download/${JEMALLOC_VERSION}/jemalloc-${JEMALLOC_VERSION}.tar.bz2)
set(JEMALLOC_HASH 507f7b6b882d868730d644510491d18f)
set(JEMALLOC_HASH 3d41fbf006e6ebffd489bdb304d009ae)
set(XML2_VERSION 2.9.4)
set(XML2_VERSION 2.9.10)
set(XML2_URI http://xmlsoft.org/sources/libxml2-${XML2_VERSION}.tar.gz)
set(XML2_HASH ae249165c173b1ff386ee8ad676815f5)
set(XML2_HASH 10942a1dc23137a8aa07f0639cbfece5)
set(TINYXML_VERSION 2_6_2)
set(TINYXML_VERSION_DOTS 2.6.2)
@@ -273,23 +265,23 @@ set(FLEXBISON_HASH d87a3938194520d904013abef3df10ce)
# NOTE: bzip.org domain does no longer belong to BZip 2 project, so we download
# sources from Debian packaging.
set(BZIP2_VERSION 1.0.6)
set(BZIP2_URI http://http.debian.net/debian/pool/main/b/bzip2/bzip2_${BZIP2_VERSION}.orig.tar.bz2)
set(BZIP2_HASH d70a9ccd8bdf47e302d96c69fecd54925f45d9c7b966bb4ef5f56b770960afa7)
set(BZIP2_VERSION 1.0.8)
set(BZIP2_URI http://http.debian.net/debian/pool/main/b/bzip2/bzip2_${BZIP2_VERSION}.orig.tar.gz)
set(BZIP2_HASH ab5a03176ee106d3f0fa90e381da478ddae405918153cca248e682cd0c4a2269)
set(FFI_VERSION 3.2.1)
set(FFI_VERSION 3.3)
set(FFI_URI https://sourceware.org/pub/libffi/libffi-${FFI_VERSION}.tar.gz)
set(FFI_HASH d06ebb8e1d9a22d19e38d63fdb83954253f39bedc5d46232a05645685722ca37)
set(FFI_HASH 72fba7922703ddfa7a028d513ac15a85c8d54c8d67f55fa5a4802885dc652056)
set(LZMA_VERSION 5.2.4)
set(LZMA_VERSION 5.2.5)
set(LZMA_URI https://tukaani.org/xz/xz-${LZMA_VERSION}.tar.bz2)
set(LZMA_HASH 3313fd2a95f43d88e44264e6b015e7d03053e681860b0d5d3f9baca79c57b7bf)
set(LZMA_HASH 5117f930900b341493827d63aa910ff5e011e0b994197c3b71c08a20228a42df)
set(SSL_VERSION 1.1.0i)
set(SSL_VERSION 1.1.1g)
set(SSL_URI https://www.openssl.org/source/openssl-${SSL_VERSION}.tar.gz)
set(SSL_HASH ebbfc844a8c8cc0ea5dc10b86c9ce97f401837f3fa08c17b2cdadc118253cf99)
set(SSL_HASH ddb04774f1e32f0c49751e21b67216ac87852ceb056b75209af2443400636d46)
set(SQLITE_VERSION 3.24.0)
set(SQLITE_VERSION 3.31.1)
set(SQLITE_URI https://www.sqlite.org/2018/sqlite-src-3240000.zip)
set(SQLITE_HASH fb558c49ee21a837713c4f1e7e413309aabdd9c7)
@@ -297,13 +289,13 @@ set(EMBREE_VERSION 3.10.0)
set(EMBREE_URI https://github.com/embree/embree/archive/v${EMBREE_VERSION}.zip)
set(EMBREE_HASH 4bbe29e7eaa46417efc75fc5f1e8eb87)
set(USD_VERSION 19.11)
set(USD_VERSION 20.05)
set(USD_URI https://github.com/PixarAnimationStudios/USD/archive/v${USD_VERSION}.tar.gz)
set(USD_HASH 79ff176167b3fe85f4953abd6cc5e0cc)
set(USD_HASH 6d679e739e7f65725d9c029e37dda9fc)
set(OIDN_VERSION 1.0.0)
set(OIDN_URI https://github.com/OpenImageDenoise/oidn/releases/download/v${OIDN_VERSION}/oidn-${OIDN_VERSION}.src.zip)
set(OIDN_HASH 19fe67b0164e8f020ac8a4f520defe60)
set(OIDN_VERSION 1.2.1)
set(OIDN_URI https://github.com/OpenImageDenoise/oidn/releases/download/v${OIDN_VERSION}/oidn-${OIDN_VERSION}.src.tar.gz)
set(OIDN_HASH cbebc1a25eb6de62af3a59e943063608)
set(LIBGLU_VERSION 9.0.1)
set(LIBGLU_URI ftp://ftp.freedesktop.org/pub/mesa/glu/glu-${LIBGLU_VERSION}.tar.xz)
@@ -316,3 +308,6 @@ set(MESA_HASH d60828056d77bfdbae0970f9b15fb1be)
set(XR_OPENXR_SDK_VERSION 1.0.8)
set(XR_OPENXR_SDK_URI https://github.com/KhronosGroup/OpenXR-SDK/archive/release-${XR_OPENXR_SDK_VERSION}.tar.gz)
set(XR_OPENXR_SDK_HASH c6de63d2e0f9029aa58dfa97cad8ce07)
set(ISPC_VERSION v1.13.0)
set(ISPC_URI https://github.com/ispc/ispc/archive/${ISPC_VERSION}.tar.gz)
set(ISPC_HASH 4bf5e8d0020c4b9980faa702c1a6f25f)

View File

@@ -376,7 +376,7 @@ USE_CXX11=true
CLANG_FORMAT_VERSION_MIN="6.0"
PYTHON_VERSION="3.7.4"
PYTHON_VERSION="3.7.7"
PYTHON_VERSION_MIN="3.7"
PYTHON_VERSION_INSTALLED=$PYTHON_VERSION_MIN
PYTHON_FORCE_BUILD=false
@@ -459,7 +459,7 @@ ALEMBIC_FORCE_BUILD=false
ALEMBIC_FORCE_REBUILD=false
ALEMBIC_SKIP=false
USD_VERSION="19.11"
USD_VERSION="20.05"
USD_FORCE_BUILD=false
USD_FORCE_REBUILD=false
USD_SKIP=false
@@ -1574,7 +1574,7 @@ compile_TBB() {
if [ ! -d $_inst ]; then
INFO "Building TBB-$TBB_VERSION$TBB_VERSION_UPDATE"
_is_building=true
# Rebuild dependencies as well!
_update_deps_tbb
@@ -1691,7 +1691,7 @@ compile_OCIO() {
if [ ! -d $_inst ]; then
INFO "Building OpenColorIO-$OCIO_VERSION"
_is_building=true
# Rebuild dependencies as well!
_update_deps_ocio
@@ -3428,7 +3428,7 @@ compile_XR_OpenXR_SDK() {
# Install on DEB-like
get_package_version_DEB() {
dpkg-query -W -f '${Version}' $1 | sed -r 's/([0-9]+:)?(([0-9]+\.?){$2}([0-9]+)).*/\2/'
dpkg-query -W -f '${Version}' $1 | sed -r 's/([0-9]+:)?(([0-9]+\.?)+([0-9]+)).*/\2/'
}
check_package_DEB() {
@@ -3631,7 +3631,7 @@ install_DEB() {
# Check cmake/glew versions and disable features for older distros.
# This is so Blender can at least compile.
PRINT ""
_cmake=`get_package_version_DEB cmake 3`
_cmake=`get_package_version_DEB cmake`
version_ge $_cmake "2.8.10"
if [ $? -eq 1 ]; then
version_ge $_cmake "2.8.8"
@@ -3646,7 +3646,7 @@ install_DEB() {
fi
PRINT ""
_glew=`get_package_version_DEB libglew-dev 3`
_glew=`get_package_version_DEB libglew-dev`
if [ -z $_glew ]; then
# Stupid virtual package in Ubuntu 12.04 doesn't show version number...
_glew=`apt-cache showpkg libglew-dev|tail -n1|awk '{print $2}'|sed 's/-.*//'`
@@ -3678,8 +3678,7 @@ install_DEB() {
check_package_version_ge_DEB python3-dev $PYTHON_VERSION_MIN
if [ $? -eq 0 ]; then
PYTHON_VERSION_INSTALLED=$(echo `get_package_version_DEB python3-dev` | sed -r 's/^([0-9]+\.[0-9]+).*/\1/')
PRINT $(echo `get_package_version_DEB python3-dev` | sed -r 's/^([0-9]+\.[0-9]+).*/\1/')
install_packages_DEB python3-dev
clean_Python
PRINT ""
@@ -3893,7 +3892,6 @@ install_DEB() {
INFO "Forced Alembic building, as requested..."
compile_ALEMBIC
else
# No package currently, only HDF5!
compile_ALEMBIC
fi
@@ -4302,8 +4300,7 @@ install_RPM() {
else
check_package_version_ge_RPM python3-devel $PYTHON_VERSION_MIN
if [ $? -eq 0 ]; then
get_package_version_RPM python3-devel
PYTHON_VERSION_INSTALLED=`echo $? | sed -r 's/([0-9]+:)?(([0-9]+\.?)?([0-9]+)).*/\2/'`
PYTHON_VERSION_INSTALLED=$(echo `get_package_version_RPM python3-devel` | sed -r 's/^([0-9]+\.[0-9]+).*/\1/')
install_packages_RPM python3-devel
clean_Python
@@ -4828,8 +4825,7 @@ install_ARCH() {
else
check_package_version_ge_ARCH python $PYTHON_VERSION_MIN
if [ $? -eq 0 ]; then
get_package_version_ARCH python
PYTHON_VERSION_INSTALLED=`echo $? | sed -r 's/([0-9]+:)?(([0-9]+\.?)?([0-9]+)).*/\2/'`
PYTHON_VERSION_INSTALLED=$(echo `get_package_version_ARCH python` | sed -r 's/^([0-9]+\.[0-9]+).*/\1/')
install_packages_ARCH python
clean_Python

View File

@@ -1,20 +0,0 @@
cmake_minimum_required(VERSION 2.8)
project(hidapi)
set(SRC_FILES
windows/hid.c
)
set(HEADER_FILES
hidapi/hidapi.h
)
include_directories(hidapi)
add_definitions(-DHID_API_STATIC)
add_library(hidapi STATIC ${SRC_FILES} ${HEADER_FILES})
install(TARGETS hidapi DESTINATION lib)
INSTALL(FILES hidapi/hidapi.h
DESTINATION "include"
)

View File

@@ -0,0 +1,14 @@
diff -Naur orig/common/sys/platform.h external_embree/common/sys/platform.h
--- orig/common/sys/platform.h 2020-05-13 23:08:53 -0600
+++ external_embree/common/sys/platform.h 2020-06-13 17:40:26 -0600
@@ -84,8 +84,8 @@
////////////////////////////////////////////////////////////////////////////////
#ifdef __WIN32__
-#define dll_export __declspec(dllexport)
-#define dll_import __declspec(dllimport)
+#define dll_export
+#define dll_import
#else
#define dll_export __attribute__ ((visibility ("default")))
#define dll_import

View File

@@ -1,15 +0,0 @@
--- hidapi/hidapi.h 2011-10-25 20:58:16 -0600
+++ hidapi/hidapi.h 2016-11-01 12:05:58 -0600
@@ -30,7 +30,11 @@
#include <wchar.h>
#ifdef _WIN32
- #define HID_API_EXPORT __declspec(dllexport)
+ #ifdef HID_API_STATIC
+ #define HID_API_EXPORT
+ #else
+ #define HID_API_EXPORT __declspec(dllexport)
+ #endif
#define HID_API_CALL
#else
#define HID_API_EXPORT /**< API export macro */

View File

@@ -0,0 +1,36 @@
diff -Naur external_ispc/CMakeLists.txt external_ispc_fixed/CMakeLists.txt
--- external_ispc/CMakeLists.txt 2020-04-23 17:29:06 -0600
+++ external_ispc_fixed/CMakeLists.txt 2020-05-05 09:01:09 -0600
@@ -389,7 +389,7 @@
# Link against Clang libraries
foreach(clangLib ${CLANG_LIBRARY_LIST})
- find_library(${clangLib}Path NAMES ${clangLib} HINTS ${LLVM_LIBRARY_DIRS})
+ find_library(${clangLib}Path NAMES ${clangLib} HINTS ${LLVM_LIBRARY_DIRS} ${CLANG_LIBRARY_DIR})
list(APPEND CLANG_LIBRARY_FULL_PATH_LIST ${${clangLib}Path})
endforeach()
target_link_libraries(${PROJECT_NAME} ${CLANG_LIBRARY_FULL_PATH_LIST})
diff -Naur orig/CMakeLists.txt external_ispc/CMakeLists.txt
--- orig/CMakeLists.txt 2020-05-05 09:19:11 -0600
+++ external_ispc/CMakeLists.txt 2020-05-05 09:26:44 -0600
@@ -333,7 +333,7 @@
# Include directories
target_include_directories(${PROJECT_NAME} PRIVATE
- ${LLVM_INCLUDE_DIRS}
+ ${LLVM_INCLUDE_DIRS} ${CLANG_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}/src
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR})
# Compile options
diff -Naur orig/cmake/GenerateBuiltins.cmake.txt external_ispc/cmake/GenerateBuiltins.cmake.txt
+++ orig/cmake/GenerateBuiltins.cmake 2020-05-25 13:32:40.830803821 +0200
+++ external_ispc/cmake/GenerateBuiltins.cmake 2020-05-25 13:32:40.830803821 +0200
@@ -97,6 +97,8 @@
if ("${bit}" STREQUAL "32" AND ${arch} STREQUAL "x86")
set(target_arch "i386")
+ # Blender: disable 32bit due to build issues on Linux and being unnecessary.
+ set(SKIP ON)
elseif ("${bit}" STREQUAL "64" AND ${arch} STREQUAL "x86")
set(target_arch "x86_64")
elseif ("${bit}" STREQUAL "32" AND ${arch} STREQUAL "arm")

View File

@@ -1,120 +0,0 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 70ec895..e616b63 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -178,7 +178,9 @@ set_property(TARGET ${PROJECT_NAME} PROPERTY SOVERSION "0")
## Open Image Denoise examples
## ----------------------------------------------------------------------------
-add_subdirectory(examples)
+if(WITH_EXAMPLE)
+ add_subdirectory(examples)
+endif()
## ----------------------------------------------------------------------------
## Open Image Denoise install and packaging
Submodule mkl-dnn contains modified content
diff --git a/mkl-dnn/cmake/TBB.cmake b/mkl-dnn/cmake/TBB.cmake
index 0711e699..c14210b6 100644
--- a/mkl-dnn/cmake/TBB.cmake
+++ b/mkl-dnn/cmake/TBB.cmake
@@ -138,13 +138,13 @@ else()
set(TBB_LIBRARY_MALLOC TBB_LIBRARY_MALLOC-NOTFOUND)
if(APPLE)
find_path(TBB_INCLUDE_DIR tbb/task_scheduler_init.h PATHS ${TBB_ROOT}/include NO_DEFAULT_PATH)
- find_library(TBB_LIBRARY tbb PATHS ${TBB_ROOT}/lib NO_DEFAULT_PATH)
- find_library(TBB_LIBRARY_MALLOC tbbmalloc PATHS ${TBB_ROOT}/lib NO_DEFAULT_PATH)
+ find_library(TBB_LIBRARY tbb_static PATHS ${TBB_ROOT}/lib NO_DEFAULT_PATH)
+ find_library(TBB_LIBRARY_MALLOC tbbmalloc_static PATHS ${TBB_ROOT}/lib NO_DEFAULT_PATH)
else()
find_path(TBB_INCLUDE_DIR tbb/task_scheduler_init.h PATHS ${TBB_ROOT}/include NO_DEFAULT_PATH)
set(TBB_HINTS HINTS ${TBB_ROOT}/lib/intel64/gcc4.4 ${TBB_ROOT}/lib ${TBB_ROOT}/lib64 PATHS /usr/libx86_64-linux-gnu/)
- find_library(TBB_LIBRARY tbb ${TBB_HINTS})
- find_library(TBB_LIBRARY_MALLOC tbbmalloc ${TBB_HINTS})
+ find_library(TBB_LIBRARY tbb_static ${TBB_HINTS})
+ find_library(TBB_LIBRARY_MALLOC tbbmalloc_static ${TBB_HINTS})
endif()
endif()
diff '--ignore-matching-lines=:' -ur '--exclude=*.svn*' -u -r
--- a/cmake/install.cmake 2019-08-12 18:02:20.794402575 +0200
+++ b/cmake/install.cmake 2019-08-12 18:06:07.470045703 +0200
@@ -18,6 +18,13 @@
## Install library
## ----------------------------------------------------------------------------
+if(UNIX)
+install(FILES
+ ${CMAKE_BINARY_DIR}/libOpenImageDenoise.a
+ ${CMAKE_BINARY_DIR}/libmkldnn.a
+ ${CMAKE_BINARY_DIR}/libcommon.a
+ DESTINATION ${CMAKE_INSTALL_LIBDIR})
+else()
install(TARGETS ${PROJECT_NAME}
EXPORT
${PROJECT_NAME}_Export
@@ -38,6 +45,7 @@
DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT devel
)
endif()
+endif()
## ----------------------------------------------------------------------------
## Install headers
@@ -78,6 +86,7 @@
## Install CMake configuration files
## ----------------------------------------------------------------------------
+if(NOT UNIX)
install(EXPORT ${PROJECT_NAME}_Export
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
#NAMESPACE ${PROJECT_NAME}::
@@ -92,3 +101,4 @@
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
COMPONENT devel
)
+endif()
diff '--ignore-matching-lines=:' -ur '--exclude=*.svn*' -u -r
--- a/CMakeLists.txt 2019-08-12 14:22:00.974078598 +0200
+++ b/CMakeLists.txt 2019-08-12 18:05:05.949057375 +0200
@@ -14,7 +14,11 @@
## limitations under the License. ##
## ======================================================================== ##
-cmake_minimum_required(VERSION 3.1)
+if(UNIX)
+ cmake_minimum_required(VERSION 3.1)
+else()
+ cmake_minimum_required(VERSION 3.13)
+endif()
set(OIDN_VERSION_MAJOR 1)
set(OIDN_VERSION_MINOR 0)
@@ -32,13 +36,8 @@
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake")
# Build as shared or static library
-if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0")
- option(OIDN_STATIC_LIB "Build Open Image Denoise as a static library.")
- mark_as_advanced(CLEAR OIDN_STATIC_LIB)
-else()
- set(OIDN_STATIC_LIB OFF CACHE BOOL "Build Open Image Denoise as a static library." FORCE)
- mark_as_advanced(OIDN_STATIC_LIB)
-endif()
+option(OIDN_STATIC_LIB "Build Open Image Denoise as a static library.")
+mark_as_advanced(CLEAR OIDN_STATIC_LIB)
if(OIDN_STATIC_LIB)
set(OIDN_LIB_TYPE STATIC)
else()
diff -Naur orig/core/api.cpp external_openimagedenoise/core/api.cpp
--- orig/core/api.cpp 2019-07-19 08:37:04 -0600
+++ external_openimagedenoise/core/api.cpp 2020-01-21 15:10:56 -0700
@@ -15,7 +15,7 @@
// ======================================================================== //
#ifdef _WIN32
-# define OIDN_API extern "C" __declspec(dllexport)
+# define OIDN_API extern "C"
#else
# define OIDN_API extern "C" __attribute__ ((visibility ("default")))
#endif

View File

@@ -1,14 +1,3 @@
diff -x .git -ur usd.orig/cmake/defaults/Options.cmake external_usd/cmake/defaults/Options.cmake
--- usd.orig/cmake/defaults/Options.cmake 2019-10-24 22:39:53.000000000 +0200
+++ external_usd/cmake/defaults/Options.cmake 2019-11-28 13:00:33.197957712 +0100
@@ -25,6 +25,7 @@
option(PXR_VALIDATE_GENERATED_CODE "Validate script generated code" OFF)
option(PXR_HEADLESS_TEST_MODE "Disallow GUI based tests, useful for running under headless CI systems." OFF)
option(PXR_BUILD_TESTS "Build tests" ON)
+option(PXR_BUILD_USD_TOOLS "Build commandline tools" ON)
option(PXR_BUILD_IMAGING "Build imaging components" ON)
option(PXR_BUILD_EMBREE_PLUGIN "Build embree imaging plugin" OFF)
option(PXR_BUILD_OPENIMAGEIO_PLUGIN "Build OpenImageIO plugin" OFF)
diff -x .git -ur usd.orig/cmake/defaults/Packages.cmake external_usd/cmake/defaults/Packages.cmake
--- usd.orig/cmake/defaults/Packages.cmake 2019-10-24 22:39:53.000000000 +0200
+++ external_usd/cmake/defaults/Packages.cmake 2019-11-28 13:00:33.185957483 +0100
@@ -21,11 +10,11 @@ diff -x .git -ur usd.orig/cmake/defaults/Packages.cmake external_usd/cmake/defau
add_definitions(${TBB_DEFINITIONS})
# --math
diff -x .git -ur usd.orig/pxr/base/lib/plug/initConfig.cpp external_usd/pxr/base/lib/plug/initConfig.cpp
--- usd.orig/pxr/base/lib/plug/initConfig.cpp 2019-10-24 22:39:53.000000000 +0200
+++ external_usd/pxr/base/lib/plug/initConfig.cpp 2019-12-11 11:00:37.643323127 +0100
@@ -69,8 +69,38 @@
diff -x .git -ur usd.orig/pxr/base/plug/initConfig.cpp external_usd/pxr/base/plug/initConfig.cpp
--- usd.orig/pxr/base/plug/initConfig.cpp.orig 2020-06-12 17:20:07.478199779 +0200
+++ external_usd/pxr/base/plug/initConfig.cpp 2020-06-12 17:25:28.648588552 +0200
@@ -69,10 +69,40 @@
ARCH_CONSTRUCTOR(Plug_InitConfig, 2, void)
{
+ /* The contents of this constructor have been moved to usd_initialise_plugin_path(...) */
@@ -50,7 +39,9 @@ diff -x .git -ur usd.orig/pxr/base/lib/plug/initConfig.cpp external_usd/pxr/base
+usd_initialise_plugin_path(const char *datafiles_usd_path)
+{
std::vector<std::string> result;
std::vector<std::string> debugMessages;
+ // Add Blender-specific paths. They MUST end in a slash, or symlinks will not be treated as directory.
+ if (datafiles_usd_path != NULL && datafiles_usd_path[0] != '\0') {
+ std::string datafiles_usd_path_str(datafiles_usd_path);
@@ -60,14 +51,14 @@ diff -x .git -ur usd.orig/pxr/base/lib/plug/initConfig.cpp external_usd/pxr/base
+ result.push_back(datafiles_usd_path_str);
+ }
+
// Determine the absolute path to the Plug shared library.
// Any relative paths specified in the plugin search path will be
// anchored to this directory, to allow for relocatability.
@@ -94,9 +124,24 @@
_AppendPathList(&result, installLocation, sharedLibPath);
// Determine the absolute path to the Plug shared library. Any relative
// paths specified in the plugin search path will be anchored to this
// directory, to allow for relocatability. Note that this can fail when pxr
@@ -114,9 +144,24 @@
_AppendPathList(&result, installLocation, binaryPath);
#endif // PXR_INSTALL_LOCATION
- Plug_SetPaths(result);
- Plug_SetPaths(result, debugMessages);
-}
+ if (!TfGetenv("PXR_PATH_DEBUG").empty()) {
+ printf("USD Plugin paths: (%zu in total):\n", result.size());
@@ -75,10 +66,10 @@ diff -x .git -ur usd.orig/pxr/base/lib/plug/initConfig.cpp external_usd/pxr/base
+ printf(" %s\n", path.c_str());
+ }
+ }
+ Plug_SetPaths(result);
+ Plug_SetPaths(result, debugMessages);
}
PXR_NAMESPACE_CLOSE_SCOPE
+
+/* Workaround to make it possible to pass a path at runtime to USD. */
@@ -90,37 +81,6 @@ diff -x .git -ur usd.orig/pxr/base/lib/plug/initConfig.cpp external_usd/pxr/base
+ PXR_NS::usd_initialise_plugin_path(datafiles_usd_path);
+}
+}
diff -x .git -ur usd.orig/pxr/usd/CMakeLists.txt external_usd/pxr/usd/CMakeLists.txt
--- usd.orig/pxr/usd/CMakeLists.txt 2019-10-24 22:39:53.000000000 +0200
+++ external_usd/pxr/usd/CMakeLists.txt 2019-11-28 13:00:33.197957712 +0100
@@ -1,6 +1,5 @@
set(DIRS
lib
- bin
plugin
)
@@ -8,3 +7,8 @@
add_subdirectory(${d})
endforeach()
+if (PXR_BUILD_USD_TOOLS)
+ add_subdirectory(bin)
+else()
+ message(STATUS "Skipping commandline tools because PXR_BUILD_USD_TOOLS=OFF")
+endif()
diff -Naur external_usd_orig/pxr/base/lib/tf/preprocessorUtils.h external_usd/pxr/base/lib/tf/preprocessorUtils.h
--- external_usd_orig/pxr/base/lib/tf/preprocessorUtils.h 2019-10-24 14:39:53 -0600
+++ external_usd/pxr/base/lib/tf/preprocessorUtils.h 2020-01-14 09:30:18 -0700
@@ -189,7 +189,7 @@
/// Exapnds to 1 if the argument is a tuple, and 0 otherwise.
/// \ingroup group_tf_Preprocessor
/// \hideinitializer
-#if defined(ARCH_OS_WINDOWS)
+#if defined(ARCH_COMPILER_MSVC)
#define TF_PP_IS_TUPLE(sequence) \
BOOST_VMD_IS_TUPLE(sequence)
#else
diff -Naur external_usd_base/cmake/macros/Public.cmake external_usd/cmake/macros/Public.cmake
--- external_usd_base/cmake/macros/Public.cmake 2019-10-24 14:39:53 -0600
+++ external_usd/cmake/macros/Public.cmake 2020-01-11 13:33:29 -0700

View File

@@ -0,0 +1,34 @@
Buildbot-lts
============
This folder contains configuration files and build scripts for making a release.
It originated when we started to do LTS releases what happens once every two
weeks. The idea is to automate the manual steps where possible and provide a
pipeline process for the manual steps that still needs to happen.
By using the same software as builder.blender.org it would already put us in
the right direction when we might want to make this part of builder.blender.org
for now it is running on a VM in the blender institute as it contains user
private keys and the process needs to be controlled security wise.
But of course the source and configurations are public available for anyone to
check, develop and use.
Setting up build-bot
--------------------
instructions from https://github.com/cjolowicz/docker-buildbot.
Create custom buildbot worker containing packages we need for building (git, wget).
cd docker
docker build -t buildbot --no-cache .
cd worker
docker build -t buildbot-worker --no-cache .
docker network create net-buildbot
docker rm lts-buildbot && docker run --init --name lts-buildbot --network net-buildbot --publish=127.0.0.1:8010:8010 -t -i buildbot
docker rm lts-worker && docker run --init --name lts-worker --network net-buildbot --name lts-worker -e BUILDMASTER=lts-buildbot -e WORKERNAME=lts-worker -e WORKERPASS=secret -t -i buildbot-worker

View File

@@ -0,0 +1,36 @@
FROM ubuntu:18.04
RUN apt update && apt upgrade -y
RUN apt install -y \
gosu \
wget \
openssh-client \
build-essential \
libffi-dev \
libssl-dev \
python3-dev \
python3-pip
ENV BUILDBOT_VERSION 2.5.0
RUN pip3 --no-cache-dir install --upgrade pip && pip --no-cache-dir install \
buildbot[bundle,tls]==$BUILDBOT_VERSION \
buildbot-docker-swarm-worker
COPY buildbot.tac /var/lib/buildbot/
COPY docker-entrypoint.sh /usr/local/bin/
COPY master.cfg /etc/buildbot/
COPY bin/create_checksum.sh /var/lib/buildbot/bin/
COPY bin/upload_file.sh /var/lib/buildbot/bin/
COPY .ssh/id_rsa /var/lib/buildbot/.ssh/
RUN adduser --home /var/lib/buildbot --disabled-password --gecos '' buildbot
WORKDIR /var/lib/buildbot
RUN ln -s /etc/buildbot/master.cfg
VOLUME /var/lib/buildbot
EXPOSE 8010
EXPOSE 9989
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["twistd", "--pidfile=", "--nodaemon", "--python=buildbot.tac"]

View File

@@ -0,0 +1,4 @@
#!/bin/sh
set -e
md5sum $1 > $2.md5
sha256sum $1 > $2.sha256

View File

@@ -0,0 +1,7 @@
#!/bin/sh
set -e
if [ ! -f /var/lib/buildbot/.ssh/known_hosts ]
then
ssh-keyscan download.blender.org > /var/lib/buildbot/.ssh/known_hosts
fi
scp $1 jeroen@download.blender.org:$2

View File

@@ -0,0 +1,20 @@
import os
import sys
from twisted.application import service
from twisted.python.log import FileLogObserver
from twisted.python.log import ILogObserver
from buildbot.master import BuildMaster
basedir = os.environ.get("BUILDBOT_BASEDIR",
os.path.abspath(os.path.dirname(__file__)))
configfile = 'master.cfg'
# note: this line is matched against to check that this is a buildmaster
# directory; do not edit it.
application = service.Application('buildmaster')
application.setComponent(ILogObserver, FileLogObserver(sys.stdout).emit)
m = BuildMaster(basedir, configfile, umask=None)
m.setServiceParent(application)

View File

@@ -0,0 +1,36 @@
version: '1'
services:
buildbot:
image: buildbot/buildbot-master:master
env_file:
- db.env
environment:
- BUILDBOT_CONFIG_DIR=config
- BUILDBOT_CONFIG_URL=https://github.com/buildbot/buildbot-docker-example-config/archive/master.tar.gz
- BUILDBOT_WORKER_PORT=9989
- BUILDBOT_WEB_URL=http://localhost:8010/
- BUILDBOT_WEB_PORT=tcp:port=8010
links:
- db
depends_on:
- db
ports:
- "8010:8010"
db:
env_file:
- db.env
image: "postgres:9.4"
expose:
- 5432
worker:
image: "buildbot/buildbot-worker:master"
environment:
BUILDMASTER: buildbot
BUILDMASTER_PORT: 9989
WORKERNAME: lts-worker
WORKERPASS: pass
WORKER_ENVIRONMENT_BLACKLIST: DOCKER_BUILDBOT* BUILDBOT_ENV_* BUILDBOT_1* WORKER_ENVIRONMENT_BLACKLIST
links:
- buildbot

View File

@@ -0,0 +1,18 @@
#!/bin/sh
set -e
buildbot upgrade-master .
chown buildbot /var/lib/buildbot/
chown buildbot /var/lib/buildbot/.ssh/
chown -R buildbot /var/lib/buildbot/*
if [ -S /var/run/docker.sock ]
then
group=$(stat -c '%g' /var/run/docker.sock)
else
group=buildbot
fi
gosu buildbot:$group "$@"

View File

@@ -0,0 +1,240 @@
# -*- python -*-
# ex: set filetype=python:
import os
from buildbot.plugins import *
# This is a sample buildmaster config file. It must be installed as
# 'master.cfg' in your buildmaster's base directory.
# This is the dictionary that the buildmaster pays attention to. We also use
# a shorter alias to save typing.
c = BuildmasterConfig = {}
####### WORKERS
# The 'workers' list defines the set of recognized workers. Each element is
# a Worker object, specifying a unique worker name and password. The same
# worker name and password must be configured on the worker.
c['workers'] = [worker.Worker("lts-worker", 'secret')]
if 'BUILDBOT_MQ_URL' in os.environ:
c['mq'] = {
'type' : 'wamp',
'router_url': os.environ['BUILDBOT_MQ_URL'],
'realm': os.environ.get('BUILDBOT_MQ_REALM', 'buildbot').decode('utf-8'),
'debug' : 'BUILDBOT_MQ_DEBUG' in os.environ,
'debug_websockets' : 'BUILDBOT_MQ_DEBUG' in os.environ,
'debug_lowlevel' : 'BUILDBOT_MQ_DEBUG' in os.environ,
}
# 'protocols' contains information about protocols which master will use for
# communicating with workers. You must define at least 'port' option that workers
# could connect to your master with this protocol.
# 'port' must match the value configured into the workers (with their
# --master option)
c['protocols'] = {'pb': {'port': os.environ.get("BUILDBOT_WORKER_PORT", 9989)}}
####### CHANGESOURCES
# the 'change_source' setting tells the buildmaster how it should find out
# about source code changes. We don't build when sources change.
c['change_source'] = []
####### SCHEDULERS
# Configure the Schedulers, which decide how to react to incoming changes. In this
# case, just kick off a 'runtests' build
c['schedulers'] = [
schedulers.ForceScheduler(
name="build",
builderNames=["release-blender-283"],
properties=[
util.StringParameter(
name="blender_version",
label="Version of blender.",
default="2.83"),
util.StringParameter(
name="blender_version_full",
label="Version of blender (Full).",
default="2.83.1")
]
),
schedulers.Triggerable(
name="deploy-source-archive",
builderNames=["deploy-source-archive"]
),
schedulers.Triggerable(
name="deploy-buildbot-packages",
builderNames=["deploy-buildbot-packages"]
),
]
####### BUILDERS
# The 'builders' list defines the Builders, which tell Buildbot how to perform a build:
# what steps, and which workers can execute them. Note that any particular build will
# only take place on one worker.
deploy_source_archive_factory = util.BuildFactory()
deploy_source_archive_factory.addStep(steps.Git(name="Checkout Blender Source", repourl='https://git.blender.org/blender.git', branch=util.Interpolate('blender-v%(prop:blender_version)s-release'), mode='full'))
deploy_source_archive_factory.addStep(steps.ShellSequence(name="Make source archive", commands=[
util.ShellArg(command=["make", "source_archive"], logfile='make_source_archive'),
# The next two shell commands are only needed during development
util.ShellArg(command=["mv", "blender-2.83.2-beta.tar.xz", util.Interpolate('blender-v%(prop:blender_version_full)s.tar.xz')]),
util.ShellArg(command=["mv", "blender-2.83.2-beta.tar.xz.md5sum", util.Interpolate('blender-v%(prop:blender_version_full)s.tar.xz.md5sum')]),
]))
deploy_source_archive_factory.addStep(steps.FileUpload(
name="Upload source archive",
workersrc=util.Interpolate('blender-v%(prop:blender_version_full)s.tar.xz'),
masterdest=util.Interpolate('/var/lib/buildbot/builds//blender-v%(prop:blender_version_full)s/blender-v%(prop:blender_version_full)s.tar.xz')))
deploy_source_archive_factory.addStep(steps.FileUpload(
name="Upload source archive checksum",
workersrc=util.Interpolate('blender-v%(prop:blender_version_full)s.tar.xz.md5sum'),
masterdest=util.Interpolate('/var/lib/buildbot/builds//blender-v%(prop:blender_version_full)s/blender-v%(prop:blender_version_full)s.tar.xz.md5sum')))
deploy_source_archive_factory.addStep(steps.MasterShellCommand(
name="Upload source archive",
command=[
'sh', '-C', '/var/lib/buildbot/bin/upload_file.sh',
util.Interpolate('/var/lib/buildbot/builds//blender-v%(prop:blender_version_full)s/blender-v%(prop:blender_version_full)s.tar.xz'),
util.Interpolate('/data/www/vhosts/download.blender.org/ftp/jeroen/')]))
deploy_source_archive_factory.addStep(steps.MasterShellCommand(
name="Upload windows64.zip build",
command=[
'sh', '-C', '/var/lib/buildbot/bin/upload_file.sh',
util.Interpolate('/var/lib/buildbot/builds//blender-v%(prop:blender_version_full)s/blender-v%(prop:blender_version_full)s.tar.xz.md5sum'),
util.Interpolate('/data/www/vhosts/download.blender.org/ftp/jeroen/')]))
deploy_buildbot_packages_factory = util.BuildFactory()
deploy_buildbot_packages_factory.addStep(steps.MasterShellCommand(
name="Download linux64 build",
command=[
'wget', util.Interpolate('https://builder.blender.org/download/blender-%(prop:blender_version_full)s-linux64.tar.xz'),
"-O", util.Interpolate('/var/lib/buildbot/builds//blender-v%(prop:blender_version_full)s/blender-%(prop:blender_version_full)s-linux64.tar.xz')]))
deploy_buildbot_packages_factory.addStep(steps.MasterShellCommand(
name="Download windows64.msi build",
command=[
'wget', util.Interpolate('https://builder.blender.org/download/blender-%(prop:blender_version_full)s-windows64.msi'),
"-O", util.Interpolate('/var/lib/buildbot/builds//blender-v%(prop:blender_version_full)s/blender-%(prop:blender_version_full)s-windows64.msi')]))
deploy_buildbot_packages_factory.addStep(steps.MasterShellCommand(
name="Download windows64.zip build",
command=[
'wget', util.Interpolate('https://builder.blender.org/download/blender-%(prop:blender_version_full)s-windows64.zip'),
"-O", util.Interpolate('/var/lib/buildbot/builds//blender-v%(prop:blender_version_full)s/blender-%(prop:blender_version_full)s-windows64.zip')]))
deploy_buildbot_packages_factory.addStep(steps.MasterShellCommand(
name="Download macOS build",
command=[
'wget', util.Interpolate('https://builder.blender.org/download/blender-%(prop:blender_version_full)s-macOS.dmg'),
"-O", util.Interpolate('/var/lib/buildbot/builds//blender-v%(prop:blender_version_full)s/blender-%(prop:blender_version_full)s-macOS.dmg')]))
deploy_buildbot_packages_factory.addStep(steps.MasterShellCommand(
name="Create checksum (md5/sha256)",
command=[
'sh',
'-C',
'/var/lib/buildbot/bin/create_checksum.sh',
util.Interpolate('/var/lib/buildbot/builds//blender-v%(prop:blender_version_full)s/blender-%(prop:blender_version_full)s-*'),
util.Interpolate('/var/lib/buildbot/builds//blender-v%(prop:blender_version_full)s/blender-%(prop:blender_version_full)s'),
]))
deploy_buildbot_packages_factory.addStep(steps.MasterShellCommand(
name="Upload linux64 build",
command=[
'sh', '-C', '/var/lib/buildbot/bin/upload_file.sh',
util.Interpolate('/var/lib/buildbot/builds//blender-v%(prop:blender_version_full)s/blender-%(prop:blender_version_full)s-linux64.tar.xz'),
util.Interpolate('/data/www/vhosts/download.blender.org/ftp/jeroen/')]))
deploy_buildbot_packages_factory.addStep(steps.MasterShellCommand(
name="Upload windows64.msi build",
command=[
'sh', '-C', '/var/lib/buildbot/bin/upload_file.sh',
util.Interpolate('/var/lib/buildbot/builds//blender-v%(prop:blender_version_full)s/blender-%(prop:blender_version_full)s-windows64.msi'),
util.Interpolate('/data/www/vhosts/download.blender.org/ftp/jeroen/')]))
deploy_buildbot_packages_factory.addStep(steps.MasterShellCommand(
name="Upload windows64.zip build",
command=[
'sh', '-C', '/var/lib/buildbot/bin/upload_file.sh',
util.Interpolate('/var/lib/buildbot/builds//blender-v%(prop:blender_version_full)s/blender-%(prop:blender_version_full)s-windows64.zip'),
util.Interpolate('/data/www/vhosts/download.blender.org/ftp/jeroen/')]))
deploy_buildbot_packages_factory.addStep(steps.MasterShellCommand(
name="Upload macOS build",
command=[
'sh', '-C', '/var/lib/buildbot/bin/upload_file.sh',
util.Interpolate('/var/lib/buildbot/builds//blender-v%(prop:blender_version_full)s/blender-%(prop:blender_version_full)s-macOS.dmg'),
util.Interpolate('/data/www/vhosts/download.blender.org/ftp/jeroen/')]))
deploy_buildbot_packages_factory.addStep(steps.MasterShellCommand(
name="Upload md5 checksum",
command=[
'sh', '-C', '/var/lib/buildbot/bin/upload_file.sh',
util.Interpolate('/var/lib/buildbot/builds//blender-v%(prop:blender_version_full)s/blender-%(prop:blender_version_full)s.md5'),
util.Interpolate('/data/www/vhosts/download.blender.org/ftp/jeroen/')]))
deploy_buildbot_packages_factory.addStep(steps.MasterShellCommand(
name="Upload sha256 checksum",
command=[
'sh', '-C', '/var/lib/buildbot/bin/upload_file.sh',
util.Interpolate('/var/lib/buildbot/builds//blender-v%(prop:blender_version_full)s/blender-%(prop:blender_version_full)s.sha256'),
util.Interpolate('/data/www/vhosts/download.blender.org/ftp/jeroen/')]))
factory = util.BuildFactory()
factory.addStep(steps.MasterShellCommand(name="Init release folder", command=["mkdir", "-p", util.Interpolate('/var/lib/buildbot/builds//blender-v%(prop:blender_version_full)s')]))
factory.addStep(steps.Trigger(
name='Deploy',
schedulerNames=[
'deploy-source-archive',
'deploy-buildbot-packages',
],
waitForFinish=True,
set_properties={
'blender_version_full': util.Property('blender_version_full'),
'blender_version': util.Property('blender_version'),
}
))
# Download builds from builder.blender.org
c['builders'] = [
util.BuilderConfig(name="release-blender-283",
workernames=["lts-worker"],
factory=factory),
util.BuilderConfig(name="deploy-source-archive",
workernames=["lts-worker"],
factory=deploy_source_archive_factory),
util.BuilderConfig(name="deploy-buildbot-packages",
workernames=["lts-worker"],
factory=deploy_buildbot_packages_factory),
]
####### STATUS TARGETS
# 'status' is a list of Status Targets. The results of each build will be
# pushed to these targets. buildbot/status/*.py has a variety to choose from,
# like IRC bots.
# c['status'] = []
####### PROJECT IDENTITY
# the 'title' string will appear at the top of this buildbot installation's
# home pages (linked to the 'titleURL').
c['title'] = "Blender Release LTS"
c['titleURL'] = "https://www.blender.org/download/lts/"
# the 'buildbotURL' string should point to the location where the buildbot's
# internal web server is visible. This typically uses the port number set in
# the 'www' entry below, but with an externally-visible host name which the
# buildbot cannot figure out without some help.
c['buildbotURL'] = os.environ.get("BUILDBOT_WEB_URL", "http://localhost:8010/")
# minimalistic config to activate new web UI
c['www'] = dict(port=os.environ.get("BUILDBOT_WEB_PORT", 8010),
plugins=dict(waterfall_view={}, console_view={}))
####### DB URL
c['db'] = {
# This specifies what database buildbot uses to store its state. You can leave
# this at its default for all but the largest installations.
'db_url' : os.environ.get("BUILDBOT_DB_URL", "sqlite://").format(**os.environ),
}

View File

@@ -0,0 +1,27 @@
FROM ubuntu:18.04
RUN set -ex; \
apt-get update; \
apt-get install -y --no-install-recommends \
build-essential \
git \
wget \
python3-dev \
python3-pip \
python3-setuptools \
python3-wheel \
; \
rm -rf /var/lib/apt/lists/*
ENV BUILDBOT_VERSION 2.5.0
RUN pip3 install --upgrade pip && \
pip --no-cache-dir install twisted[tls] && \
pip --no-cache-dir install buildbot_worker==$BUILDBOT_VERSION
RUN useradd --create-home --home-dir=/var/lib/buildbot buildbot
WORKDIR /var/lib/buildbot
USER buildbot
COPY buildbot.tac .
CMD ["twistd", "--pidfile=", "--nodaemon", "--python=buildbot.tac"]

View File

@@ -0,0 +1,39 @@
import fnmatch
import os
import sys
from twisted.application import service
from twisted.python.log import FileLogObserver
from twisted.python.log import ILogObserver
from buildbot_worker.bot import Worker
# setup worker
basedir = os.path.abspath(os.path.dirname(__file__))
application = service.Application('buildbot-worker')
application.setComponent(ILogObserver, FileLogObserver(sys.stdout).emit)
# and worker on the same process!
buildmaster_host = os.environ.get("BUILDMASTER", 'localhost')
port = int(os.environ.get("BUILDMASTER_PORT", 9989))
workername = os.environ.get("WORKERNAME", 'docker')
passwd = os.environ.get("WORKERPASS")
# delete the password from the environ so that it is not leaked in the log
blacklist = os.environ.get("WORKER_ENVIRONMENT_BLACKLIST", "WORKERPASS").split()
for name in list(os.environ.keys()):
for toremove in blacklist:
if fnmatch.fnmatch(name, toremove):
del os.environ[name]
keepalive = 600
umask = None
maxdelay = 300
allow_shutdown = None
maxretries = 10
s = Worker(buildmaster_host, port, workername, passwd, basedir,
keepalive, umask=umask, maxdelay=maxdelay,
allow_shutdown=allow_shutdown, maxRetries=maxretries)
s.setServiceParent(application)

View File

@@ -8,7 +8,7 @@ Code signing is done as part of INSTALL target, which makes it possible to sign
files which are aimed into a bundle and coming from a non-signed source (such as
libraries SVN).
This is achieved by specifying `slave_codesign.cmake` as a post-install script
This is achieved by specifying `worker_codesign.cmake` as a post-install script
run by CMake. This CMake script simply involves an utility script written in
Python which takes care of an actual signing.

View File

@@ -40,8 +40,8 @@ class Builder:
# Buildbot runs from build/ directory
self.blender_dir = os.path.abspath(os.path.join('..', 'blender.git'))
self.build_dir = os.path.abspath(os.path.join('..', 'build', name))
self.install_dir = os.path.abspath(os.path.join('..', 'install', name))
self.build_dir = os.path.abspath(os.path.join('..', 'build'))
self.install_dir = os.path.abspath(os.path.join('..', 'install'))
self.upload_dir = os.path.abspath(os.path.join('..', 'install'))
# Detect platform
@@ -51,7 +51,7 @@ class Builder:
elif name.startswith('linux'):
self.platform = 'linux'
if is_tool('scl'):
self.command_prefix = ['scl', 'enable', 'devtoolset-6', '--']
self.command_prefix = ['scl', 'enable', 'devtoolset-9', '--']
else:
self.command_prefix = []
elif name.startswith('win'):

View File

@@ -48,6 +48,7 @@ import shutil
import subprocess
import time
import tarfile
import uuid
from pathlib import Path
from tempfile import TemporaryDirectory
@@ -121,21 +122,10 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
# Consider this an input of the code signing server.
unsigned_storage_dir: Path
# Information about archive which contains files which are to be signed.
#
# This archive is created by the buildbot worked and acts as an input for
# the code signing server.
unsigned_archive_info: ArchiveWithIndicator
# Storage where signed files are stored.
# Consider this an output of the code signer server.
signed_storage_dir: Path
# Information about archive which contains signed files.
#
# This archive is created by the code signing server.
signed_archive_info: ArchiveWithIndicator
# Platform the code is currently executing on.
platform: util.Platform
@@ -146,50 +136,44 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
# Unsigned (signing server input) configuration.
self.unsigned_storage_dir = absolute_shared_storage_dir / 'unsigned'
self.unsigned_archive_info = ArchiveWithIndicator(
self.unsigned_storage_dir, 'unsigned_files.tar', 'ready.stamp')
# Signed (signing server output) configuration.
self.signed_storage_dir = absolute_shared_storage_dir / 'signed'
self.signed_archive_info = ArchiveWithIndicator(
self.signed_storage_dir, 'signed_files.tar', 'ready.stamp')
self.platform = util.get_current_platform()
"""
General note on cleanup environment functions.
It is expected that there is only one instance of the code signer server
running for a given input/output directory, and that it serves a single
buildbot worker.
By its nature, a buildbot worker only produces one build at a time and
never performs concurrent builds.
This leads to a conclusion that when starting in a clean environment
there shouldn't be any archives remaining from a previous build.
However, it is possible to have various failure scenarios which might
leave the environment in a non-clean state:
- Network hiccup which makes buildbot worker to stop current build
and re-start it after connection to server is re-established.
Note, this could also happen during buildbot server maintenance.
- Signing server might get restarted due to updates or other reasons.
Requiring manual interaction in such cases is not something good to
require, so here we simply assume that the system is used the way it is
intended to and restore environment to a prestine clean state.
"""
def cleanup_environment_for_builder(self) -> None:
self.unsigned_archive_info.clean()
self.signed_archive_info.clean()
# TODO(sergey): Revisit need of cleaning up the existing files.
# In practice it wasn't so helpful, and with multiple clients
# talking to the same server it becomes even mor etricky.
pass
def cleanup_environment_for_signing_server(self) -> None:
# Don't clear the requested to-be-signed archive since we might be
# restarting signing machine while the buildbot is busy.
self.signed_archive_info.clean()
# TODO(sergey): Revisit need of cleaning up the existing files.
# In practice it wasn't so helpful, and with multiple clients
# talking to the same server it becomes even mor etricky.
pass
def generate_request_id(self) -> str:
"""
Generate an unique identifier for code signing request.
"""
return str(uuid.uuid4())
def archive_info_for_request_id(
self, path: Path, request_id: str) -> ArchiveWithIndicator:
return ArchiveWithIndicator(
path, f'{request_id}.tar', f'{request_id}.ready')
def signed_archive_info_for_request_id(
self, request_id: str) -> ArchiveWithIndicator:
return self.archive_info_for_request_id(
self.signed_storage_dir, request_id)
def unsigned_archive_info_for_request_id(
self, request_id: str) -> ArchiveWithIndicator:
return self.archive_info_for_request_id(
self.unsigned_storage_dir, request_id)
############################################################################
# Buildbot worker side helpers.
@@ -232,7 +216,7 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
if self.check_file_is_to_be_signed(file)]
return files_to_be_signed
def wait_for_signed_archive_or_die(self) -> None:
def wait_for_signed_archive_or_die(self, request_id) -> None:
"""
Wait until archive with signed files is available.
@@ -240,13 +224,19 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
is still no responce from the signing server the application will exit
with a non-zero exit code.
"""
signed_archive_info = self.signed_archive_info_for_request_id(
request_id)
unsigned_archive_info = self.unsigned_archive_info_for_request_id(
request_id)
timeout_in_seconds = self.config.TIMEOUT_IN_SECONDS
time_start = time.monotonic()
while not self.signed_archive_info.is_ready():
while not signed_archive_info.is_ready():
time.sleep(1)
time_slept_in_seconds = time.monotonic() - time_start
if time_slept_in_seconds > timeout_in_seconds:
self.unsigned_archive_info.clean()
unsigned_archive_info.clean()
raise SystemExit("Signing server didn't finish signing in "
f"{timeout_in_seconds} seconds, dying :(")
@@ -303,13 +293,19 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
return
logger_builder.info('Found %d files to sign.', len(files))
request_id = self.generate_request_id()
signed_archive_info = self.signed_archive_info_for_request_id(
request_id)
unsigned_archive_info = self.unsigned_archive_info_for_request_id(
request_id)
pack_files(files=files,
archive_filepath=self.unsigned_archive_info.archive_filepath)
self.unsigned_archive_info.tag_ready()
archive_filepath=unsigned_archive_info.archive_filepath)
unsigned_archive_info.tag_ready()
# Wait for the signing server to finish signing.
logger_builder.info('Waiting signing server to sign the files...')
self.wait_for_signed_archive_or_die()
self.wait_for_signed_archive_or_die(request_id)
# Extract signed files from archive and move files to final location.
with TemporaryDirectory(prefix='blender-buildbot-') as temp_dir_str:
@@ -317,7 +313,7 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
logger_builder.info('Extracting signed files from archive...')
extract_files(
archive_filepath=self.signed_archive_info.archive_filepath,
archive_filepath=signed_archive_info.archive_filepath,
extraction_dir=unpacked_signed_files_dir)
destination_dir = path
@@ -327,19 +323,44 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
unpacked_signed_files_dir, destination_dir)
logger_builder.info('Removing archive with signed files...')
self.signed_archive_info.clean()
signed_archive_info.clean()
############################################################################
# Signing server side helpers.
def wait_for_sign_request(self) -> None:
def wait_for_sign_request(self) -> str:
"""
Wait for the buildbot to request signing of an archive.
Returns an identifier of signing request.
"""
# TOOD(sergey): Support graceful shutdown on Ctrl-C.
while not self.unsigned_archive_info.is_ready():
logger_server.info(
f'Waiting for a request directory {self.unsigned_storage_dir} to appear.')
while not self.unsigned_storage_dir.exists():
time.sleep(1)
logger_server.info(
'Waiting for a READY indicator of any signing request.')
request_id = None
while request_id is None:
for file in self.unsigned_storage_dir.iterdir():
if file.suffix != '.ready':
continue
request_id = file.stem
logger_server.info(f'Found READY for request ID {request_id}.')
if request_id is None:
time.sleep(1)
unsigned_archive_info = self.unsigned_archive_info_for_request_id(
request_id)
while not unsigned_archive_info.is_ready():
time.sleep(1)
return request_id
@abc.abstractmethod
def sign_all_files(self, files: List[AbsoluteAndRelativeFileName]) -> None:
"""
@@ -348,7 +369,7 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
NOTE: Signing should happen in-place.
"""
def run_signing_pipeline(self):
def run_signing_pipeline(self, request_id: str):
"""
Run the full signing pipeline starting from the point when buildbot
worker have requested signing.
@@ -360,9 +381,14 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
with TemporaryDirectory(prefix='blender-codesign-') as temp_dir_str:
temp_dir = Path(temp_dir_str)
signed_archive_info = self.signed_archive_info_for_request_id(
request_id)
unsigned_archive_info = self.unsigned_archive_info_for_request_id(
request_id)
logger_server.info('Extracting unsigned files from archive...')
extract_files(
archive_filepath=self.unsigned_archive_info.archive_filepath,
archive_filepath=unsigned_archive_info.archive_filepath,
extraction_dir=temp_dir)
logger_server.info('Collecting all files which needs signing...')
@@ -374,11 +400,11 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
logger_server.info('Packing signed files...')
pack_files(files=files,
archive_filepath=self.signed_archive_info.archive_filepath)
self.signed_archive_info.tag_ready()
archive_filepath=signed_archive_info.archive_filepath)
signed_archive_info.tag_ready()
logger_server.info('Removing signing request...')
self.unsigned_archive_info.clean()
unsigned_archive_info.clean()
logger_server.info('Signing is complete.')
@@ -389,11 +415,11 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
while True:
logger_server.info('Waiting for the signing request in %s...',
self.unsigned_storage_dir)
self.wait_for_sign_request()
request_id = self.wait_for_sign_request()
logger_server.info(
'Got signing request, beging signign procedure.')
self.run_signing_pipeline()
f'Beging signign procedure for request ID {request_id}.')
self.run_signing_pipeline(request_id)
############################################################################
# Command executing.

View File

@@ -1,37 +0,0 @@
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
# Runs on buildbot slave, rsync zip directly to buildbot server rather
# than using upload which is much slower
import buildbot_utils
import os
import sys
if __name__ == "__main__":
builder = buildbot_utils.create_builder_from_arguments()
# rsync, this assumes ssh keys are setup so no password is needed
local_zip = "buildbot_upload.zip"
remote_folder = "builder.blender.org:/data/buildbot-master/uploaded/"
remote_zip = remote_folder + "buildbot_upload_" + builder.name + ".zip"
command = ["rsync", "-avz", local_zip, remote_zip]
buildbot_utils.call(command)

View File

@@ -30,7 +30,7 @@ from tempfile import TemporaryDirectory, NamedTemporaryFile
from typing import List
BUILDBOT_DIRECTORY = Path(__file__).absolute().parent
CODESIGN_SCRIPT = BUILDBOT_DIRECTORY / 'slave_codesign.py'
CODESIGN_SCRIPT = BUILDBOT_DIRECTORY / 'worker_codesign.py'
BLENDER_GIT_ROOT_DIRECTORY = BUILDBOT_DIRECTORY.parent.parent
DARWIN_DIRECTORY = BLENDER_GIT_ROOT_DIRECTORY / 'release' / 'darwin'

View File

@@ -33,7 +33,7 @@ else()
endif()
execute_process(
COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_LIST_DIR}/slave_codesign.py"
COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_LIST_DIR}/worker_codesign.py"
"${CMAKE_INSTALL_PREFIX}"
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
RESULT_VARIABLE exit_code

View File

@@ -25,7 +25,7 @@ import buildbot_utils
def get_cmake_options(builder):
post_install_script = os.path.join(
builder.blender_dir, 'build_files', 'buildbot', 'slave_codesign.cmake')
builder.blender_dir, 'build_files', 'buildbot', 'worker_codesign.cmake')
config_file = "build_files/cmake/config/blender_release.cmake"
options = ['-DCMAKE_BUILD_TYPE:STRING=Release',
@@ -35,7 +35,7 @@ def get_cmake_options(builder):
options.append('-DCMAKE_OSX_ARCHITECTURES:STRING=x86_64')
options.append('-DCMAKE_OSX_DEPLOYMENT_TARGET=10.9')
elif builder.platform == 'win':
options.extend(['-G', 'Visual Studio 15 2017 Win64'])
options.extend(['-G', 'Visual Studio 16 2019', '-A', 'x64'])
options.extend(['-DPOSTINSTALL_SCRIPT:PATH=' + post_install_script])
elif builder.platform == 'linux':
config_file = "build_files/buildbot/config/blender_linux.cmake"

View File

@@ -18,7 +18,7 @@
# <pep8 compliant>
# Runs on buildbot slave, creating a release package using the build
# Runs on buildbot worker, creating a release package using the build
# system and zipping it into buildbot_upload.zip. This is then uploaded
# to the master in the next buildbot step.
@@ -110,7 +110,7 @@ def pack_mac(builder):
release_dir = os.path.join(builder.blender_dir, 'release', 'darwin')
buildbot_dir = os.path.join(builder.blender_dir, 'build_files', 'buildbot')
bundle_script = os.path.join(buildbot_dir, 'slave_bundle_dmg.py')
bundle_script = os.path.join(buildbot_dir, 'worker_bundle_dmg.py')
command = [bundle_script]
command += ['--dmg', package_filepath]

View File

@@ -1,65 +0,0 @@
# - Find HDF5 library
# Find the native HDF5 includes and libraries
# This module defines
# HDF5_INCLUDE_DIRS, where to find hdf5.h, Set when HDF5_INCLUDE_DIR is found.
# HDF5_LIBRARIES, libraries to link against to use HDF5.
# HDF5_ROOT_DIR, The base directory to search for HDF5.
# This can also be an environment variable.
# HDF5_FOUND, If false, do not try to use HDF5.
#
#=============================================================================
# Copyright 2016 Blender Foundation.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# If HDF5_ROOT_DIR was defined in the environment, use it.
IF(NOT HDF5_ROOT_DIR AND NOT $ENV{HDF5_ROOT_DIR} STREQUAL "")
SET(HDF5_ROOT_DIR $ENV{HDF5_ROOT_DIR})
ENDIF()
SET(_hdf5_SEARCH_DIRS
${HDF5_ROOT_DIR}
/opt/lib/hdf5
)
FIND_LIBRARY(HDF5_LIBRARY
NAMES
hdf5
HINTS
${_hdf5_SEARCH_DIRS}
PATH_SUFFIXES
lib64 lib
)
FIND_PATH(HDF5_INCLUDE_DIR
NAMES
hdf5.h
HINTS
${_hdf5_SEARCH_DIRS}
PATH_SUFFIXES
include
)
# handle the QUIETLY and REQUIRED arguments and set HDF5_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(HDF5 DEFAULT_MSG HDF5_LIBRARY HDF5_INCLUDE_DIR)
IF(HDF5_FOUND)
SET(HDF5_LIBRARIES ${HDF5_LIBRARY})
SET(HDF5_INCLUDE_DIRS ${HDF5_INCLUDE_DIR})
ENDIF(HDF5_FOUND)
MARK_AS_ADVANCED(
HDF5_INCLUDE_DIR
HDF5_LIBRARY
)
UNSET(_hdf5_SEARCH_DIRS)

View File

@@ -48,7 +48,14 @@ SET(_openimagedenoise_FIND_COMPONENTS
# These are needed when building statically
SET(_openimagedenoise_FIND_STATIC_COMPONENTS
common
# These additional library names change between versions, we list all of them
# so builds work with multiple versions. Missing libraries are skipped.
dnnl_cpu
dnnl_common
dnnl_cpu # Second time because of circular dependency
mkldnn
dnnl
)
SET(_openimagedenoise_LIBRARIES)

View File

@@ -11,6 +11,7 @@ set(WITH_CODEC_AVI ON CACHE BOOL "" FORCE)
set(WITH_CODEC_FFMPEG ON CACHE BOOL "" FORCE)
set(WITH_CODEC_SNDFILE ON CACHE BOOL "" FORCE)
set(WITH_CYCLES ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_EMBREE ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_OSL ON CACHE BOOL "" FORCE)
set(WITH_DRACO ON CACHE BOOL "" FORCE)
set(WITH_FFTW3 ON CACHE BOOL "" FORCE)

View File

@@ -15,6 +15,7 @@ set(WITH_CODEC_AVI OFF CACHE BOOL "" FORCE)
set(WITH_CODEC_FFMPEG OFF CACHE BOOL "" FORCE)
set(WITH_CODEC_SNDFILE OFF CACHE BOOL "" FORCE)
set(WITH_CYCLES OFF CACHE BOOL "" FORCE)
set(WITH_CYCLES_EMBREE OFF CACHE BOOL "" FORCE)
set(WITH_CYCLES_OSL OFF CACHE BOOL "" FORCE)
set(WITH_CYCLES_DEVICE_OPTIX OFF CACHE BOOL "" FORCE)
set(WITH_DRACO OFF CACHE BOOL "" FORCE)

View File

@@ -12,6 +12,7 @@ set(WITH_CODEC_AVI ON CACHE BOOL "" FORCE)
set(WITH_CODEC_FFMPEG ON CACHE BOOL "" FORCE)
set(WITH_CODEC_SNDFILE ON CACHE BOOL "" FORCE)
set(WITH_CYCLES ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_EMBREE ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_OSL ON CACHE BOOL "" FORCE)
set(WITH_DRACO ON CACHE BOOL "" FORCE)
set(WITH_FFTW3 ON CACHE BOOL "" FORCE)

View File

@@ -437,7 +437,6 @@ function(SETUP_LIBDIRS)
if(WITH_ALEMBIC)
link_directories(${ALEMBIC_LIBPATH})
link_directories(${HDF5_LIBPATH})
endif()
if(WITH_GHOST_WAYLAND)

View File

@@ -265,14 +265,8 @@ endif()
if(WITH_ALEMBIC)
find_package_wrapper(Alembic)
if(WITH_ALEMBIC_HDF5)
set(HDF5_ROOT_DIR ${LIBDIR}/hdf5)
find_package_wrapper(HDF5)
endif()
if(NOT ALEMBIC_FOUND OR (WITH_ALEMBIC_HDF5 AND NOT HDF5_FOUND))
if(NOT ALEMBIC_FOUND)
set(WITH_ALEMBIC OFF)
set(WITH_ALEMBIC_HDF5 OFF)
endif()
endif()

View File

@@ -539,10 +539,10 @@ if(WITH_OPENIMAGEDENOISE)
set(OPENIMAGEDENOISE_LIBRARIES
optimized ${OPENIMAGEDENOISE_LIBPATH}/OpenImageDenoise.lib
optimized ${OPENIMAGEDENOISE_LIBPATH}/common.lib
optimized ${OPENIMAGEDENOISE_LIBPATH}/mkldnn.lib
optimized ${OPENIMAGEDENOISE_LIBPATH}/dnnl.lib
debug ${OPENIMAGEDENOISE_LIBPATH}/OpenImageDenoise_d.lib
debug ${OPENIMAGEDENOISE_LIBPATH}/common_d.lib
debug ${OPENIMAGEDENOISE_LIBPATH}/mkldnn_d.lib)
debug ${OPENIMAGEDENOISE_LIBPATH}/dnnl_d.lib)
set(OPENIMAGEDENOISE_DEFINITIONS)
endif()

View File

@@ -1,2 +1,2 @@
Sphinx==3.0.3
sphinx_rtd_theme==0.5.0rc1
Sphinx==3.1.1
sphinx_rtd_theme==0.5.0

View File

@@ -427,7 +427,7 @@ offers a set of extensive examples, including advanced features.
Return evaluator parameters
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glGetMap.xml>`_
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glGetMap.xml>`__
:type target: Enumerated constant
:arg target: Specifies the symbolic name of a map.

View File

@@ -1,5 +1,5 @@
..
This document is appended to the auto generated bmesh api doc to avoid clogging up the C files with details.
This document is appended to the auto generated BMesh API doc to avoid clogging up the C files with details.
to test this run:
./blender.bin -b -noaudio -P doc/python_api/sphinx_doc_gen.py -- \
--partial bmesh* ; cd doc/python_api ; sphinx-build sphinx-in sphinx-out ; cd ../../
@@ -19,25 +19,24 @@ Submodules:
Introduction
------------
This API gives access the blenders internal mesh editing api, featuring geometry connectivity data and
This API gives access the Blender's internal mesh editing API, featuring geometry connectivity data and
access to editing operations such as split, separate, collapse and dissolve.
The features exposed closely follow the C API,
giving python access to the functions used by blenders own mesh editing tools.
giving Python access to the functions used by Blender's own mesh editing tools.
For an overview of BMesh data types and how they reference each other see:
`BMesh Design Document <https://wiki.blender.org/index.php/Dev:Source/Modeling/BMesh/Design>`_ .
`BMesh Design Document <https://wiki.blender.org/index.php/Dev:Source/Modeling/BMesh/Design>`__.
.. note::
**Disk** and **Radial** data is not exposed by the python api since this is for internal use only.
**Disk** and **Radial** data is not exposed by the Python API since this is for internal use only.
.. warning:: TODO items are...
* add access to BMesh **walkers**
* add custom-data manipulation functions add/remove/rename.
- add access to BMesh **walkers**.
- add custom-data manipulation functions add, remove or rename.
Example Script
@@ -46,55 +45,52 @@ Example Script
.. literalinclude:: __/__/__/release/scripts/templates_py/bmesh_simple.py
Stand-Alone Module
^^^^^^^^^^^^^^^^^^
Standalone Module
^^^^^^^^^^^^^^^^^
The bmesh module is written to be standalone except for :mod:`mathutils`
The BMesh module is written to be standalone except for :mod:`mathutils`
which is used for vertex locations and normals.
The only other exception to this are when converting mesh data to and from :class:`bpy.types.Mesh`.
Mesh Access
-----------
There are 2 ways to access BMesh data, you can create a new BMesh by converting a mesh from
:class:`bpy.types.BlendData.meshes` or by accessing the current edit mode mesh.
see: :class:`bmesh.types.BMesh.from_mesh` and :mod:`bmesh.from_edit_mesh` respectively.
There are two ways to access BMesh data, you can create a new BMesh by converting a mesh from
:class:`bpy.types.BlendData.meshes` or by accessing the current Edit-Mode mesh.
See: :class:`bmesh.types.BMesh.from_mesh` and :mod:`bmesh.from_edit_mesh` respectively.
When explicitly converting from mesh data python **owns** the data, that is to say -
that the mesh only exists while python holds a reference to it,
and the script is responsible for putting it back into a mesh data-block when the edits are done.
When explicitly converting from mesh data Python **owns** the data, that means that
the mesh only exists while Python holds a reference to it.
The script is responsible for putting it back into a mesh data-block when the edits are done.
Note that unlike :mod:`bpy`, a BMesh does not necessarily correspond to data in the currently open blend file,
Note that unlike :mod:`bpy`, a BMesh does not necessarily correspond to data in the currently open blend-file,
a BMesh can be created, edited and freed without the user ever seeing or having access to it.
Unlike edit mode, the bmesh module can use multiple BMesh instances at once.
Unlike Edit-Mode, the BMesh module can use multiple BMesh instances at once.
Take care when dealing with multiple BMesh instances since the mesh data can use a lot of memory, while a mesh that
python owns will be freed in when the script holds no references to it,
its good practice to call :class:`bmesh.types.BMesh.free` which will remove all the mesh data immediately and disable
further access.
Take care when dealing with multiple BMesh instances since the mesh data can use a lot of memory.
While a mesh that the Python script owns will be freed when the script holds no references to it,
it's good practice to call :class:`bmesh.types.BMesh.free` which will remove all the mesh data immediately
and disable further access.
EditMode Tessellation
^^^^^^^^^^^^^^^^^^^^^
Edit-Mode Tessellation
^^^^^^^^^^^^^^^^^^^^^^
When writing scripts that operate on editmode data you will normally want to re-calculate the tessellation after
running the script, this needs to be called explicitly.
The BMesh its self does not store the triangulated faces, they are stored in the :class:`bpy.types.Mesh`,
When writing scripts that operate on Edit-Mode data you will normally want to re-calculate the tessellation after
running the script, this needs to be called explicitly.
The BMesh itself does not store the triangulated faces, instead they are stored in the :class:`bpy.types.Mesh`,
to refresh tessellation triangles call :class:`bpy.types.Mesh.calc_loop_triangles`.
CustomData Access
-----------------
BMesh has a unified way to access mesh attributes such as UV's vertex colors, shape keys, edge crease etc.
BMesh has a unified way to access mesh attributes such as UVs, vertex colors, shape keys, edge crease, etc.
This works by having a **layers** property on BMesh data sequences to access the custom data layers
which can then be used to access the actual data on each vert, edge, face or loop.
This works by having a **layers** property on bmesh data sequences to access the custom data layers which can then be
used to access the actual data on each vert/edge/face/loop.
Here are some examples ...
Here are some examples:
.. code-block:: python
@@ -139,27 +135,27 @@ Here are some examples ...
Keeping a Correct State
-----------------------
When modeling in blender there are certain assumptions made about the state of the mesh.
When modeling in Blender there are certain assumptions made about the state of the mesh:
* hidden geometry isn't selected.
* when an edge is selected, its vertices are selected too.
* when a face is selected, its edges and vertices are selected.
* duplicate edges / faces don't exist.
* faces have at least 3 vertices.
- Hidden geometry isn't selected.
- When an edge is selected, its vertices are selected too.
- When a face is selected, its edges and vertices are selected.
- Duplicate edges / faces don't exist.
- Faces have at least three vertices.
To give developers flexibility these conventions are not enforced,
however tools must leave the mesh in a valid state else other tools may behave incorrectly.
yet tools must leave the mesh in a valid state or else other tools may behave incorrectly.
Any errors that arise from not following these conventions is considered a bug in the script,
not a bug in blender.
not a bug in Blender.
Selection / Flushing
^^^^^^^^^^^^^^^^^^^^
As mentioned above, it is possible to create an invalid selection state
(by selecting a state and then de-selecting one of its vertices's for example), mostly the best way to solve this is to
flush the selection after performing a series of edits. this validates the selection state.
(by selecting a state and then deselecting one of its vertices for example),
mostly the best way to solve this is to flush the selection
after performing a series of edits. This validates the selection state.
Module Functions

View File

@@ -3,94 +3,84 @@
Reference API Usage
*******************
Blender has many interlinking data types which have an auto-generated reference api which often has the information
Blender has many interlinking data types which have an auto-generated reference API which often has the information
you need to write a script, but can be difficult to use.
This document is designed to help you understand how to use the reference api.
This document is designed to help you understand how to use the reference API.
Reference API Scope
===================
The reference API covers :mod:`bpy.types`, which stores types accessed via :mod:`bpy.context` - *The user context*
or :mod:`bpy.data` - *Blend file data*.
The reference API covers :mod:`bpy.types`, which stores types accessed via :mod:`bpy.context` -- *the user context*
or :mod:`bpy.data` -- *blend-file data*.
Other modules such as :mod:`bmesh` and :mod:`aud` are not using Blenders data API
Other modules such as :mod:`bmesh` and :mod:`aud` are not using Blender's data API
so this document doesn't apply to those modules.
Data Access
===========
The most common case for using the reference API is to find out how to access data in the blend file.
Before going any further its best to be aware of ID Data-Blocks in Blender since you will often find properties
The most common case for using the reference API is to find out how to access data in the blend-file.
Before going any further its best to be aware of ID data-blocks in Blender since you will often find properties
relative to them.
ID Data
-------
ID Data-Blocks are used in Blender as top-level data containers.
ID data-blocks are used in Blender as top-level data containers.
From the user interface this isn't so obvious, but when developing you need to know about ID data-blocks.
ID data types include Scene, Group, Object, Mesh, Workspace, World, Armature, Image and Texture.
For a full list see the subclasses of :class:`bpy.types.ID`.
From the user interface this isn't so obvious, but when developing you need to know about ID Data-Blocks.
Here are some characteristics ID data-blocks share:
ID data types include Scene, Group, Object, Mesh, Screen, World, Armature, Image and Texture.
for a full list see the sub-classes of :class:`bpy.types.ID`
Here are some characteristics ID Data-Blocks share.
- ID's are blend file data, so loading a new blend file reloads an entire new set of Data-Blocks.
- ID's can be accessed in Python from ``bpy.data.*``
- IDs are blend-file data, so loading a new blend-file reloads an entire new set of data-blocks.
- IDs can be accessed in Python from ``bpy.data.*``.
- Each data-block has a unique ``.name`` attribute, displayed in the interface.
- Animation data is stored in ID's ``.animation_data``.
- ID's are the only data types that can be linked between blend files.
- ID's can be added/copied and removed via Python.
- ID's have their own garbage-collection system which frees unused ID's when saving.
- When a data-block has a reference to some external data, this is typically an ID Data-Block.
- Animation data is stored in IDs ``.animation_data``.
- IDs are the only data types that can be linked between blend-files.
- IDs can be added/copied and removed via Python.
- IDs have their own garbage-collection system which frees unused IDs when saving.
- When a data-block has a reference to some external data, this is typically an ID data-block.
Simple Data Access
------------------
Lets start with a simple case, say you want a python script to adjust the object's location.
In this simple case a Python script is used to adjust the object's location.
Start by collecting the information where the data is located.
Start by finding this setting in the interface ``Properties Window -> Object -> Transform -> Location``
From the button you can right click and select **Online Python Reference**, this will link you to:
:class:`bpy.types.Object.location`
Being an API reference, this link often gives little more information then the tool-tip, though some of the pages
First find this setting in the interface ``Properties editor -> Object -> Transform -> Location``.
From the button context menu select *Online Python Reference*, this will link you to:
:class:`bpy.types.Object.location`.
Being an API reference, this link often gives little more information then the tooltip, though some of the pages
include examples (normally at the top of the page).
But you now know that you have to use ``.location`` and that its an array of three floats.
At this point you may say *Now what?* - you know that you have to use ``.location`` and that its an array of 3 floats
but you're still left wondering how to access this in a script.
So the next step is to find out where to access objects, go down to the bottom of the page to the **References**
section, for objects there are many references, but one of the most common places to access objects is via the context.
It's easy to be overwhelmed at this point since there ``Object`` get referenced in so many places - modifiers,
functions, textures and constraints.
So the next step is to find out where to access objects, go down to the bottom of the page to the references section,
for objects there are many references, but one of the most common places to access objects is via the context.
It's easy to be overwhelmed at this point since there ``Object`` get referenced in so many places:
modifiers, functions, textures and constraints.
But if you want to access any data the user has selected
you typically only need to check the :mod:`bpy.context` references.
Even then, in this case there are quite a few though if you read over these - most are mode specific.
If you happen to be writing a tool that only runs in weight paint mode, then using ``weight_paint_object``
would be appropriate.
However to access an item the user last selected, look for the ``active`` members,
Having access to a single active member the user selects is a convention in Blender: eg. ``active_bone``,
``active_pose_bone``, ``active_node`` ... and in this case we can use - ``active_object``.
Even then, in this case there are quite a few though
if you read over these you'll notice that most are mode specific.
If you happen to be writing a tool that only runs in Weight Paint Mode,
then using ``weight_paint_object`` would be appropriate.
However, to access an item the user last selected, look for the ``active`` members,
Having access to a single active member the user selects is a convention in Blender:
e.g. ``active_bone``, ``active_pose_bone``, ``active_node``, etc. and in this case you can use ``active_object``.
So now we have enough information to find the location of the active object.
So now you have enough information to find the location of the active object.
.. code-block:: python
bpy.context.active_object.location
You can type this into the python console to see the result.
You can type this into the Python console to see the result.
The other common place to access objects in the reference is :class:`bpy.types.BlendData.objects`.
.. note::
@@ -100,7 +90,7 @@ The other common place to access objects in the reference is :class:`bpy.types.B
so the documentation points there.
With :mod:`bpy.data.objects`, this is a collection of objects so you need to access one of its members.
With :mod:`bpy.data.objects`, this is a collection of objects so you need to access one of its members:
.. code-block:: python
@@ -117,37 +107,34 @@ Here are some more complex examples:
.. code-block:: python
# access a render layers samples
bpy.context.scene.render.layers["RenderLayer"].samples
# Access the number of samples for the Cycles render engine.
bpy.context.scene.cycles.samples
# access to the current weight paint brush size
# Access to the current weight paint brush size.
bpy.context.tool_settings.weight_paint.brush.size
# check if the window is fullscreen
# Check if the window is full-screen.
bpy.context.window.screen.show_fullscreen
As you can see there are times when you want to access data which is nested
in a way that causes you to go through a few indirections.
The properties are arranged to match how data is stored internally (in Blender's C code) which is often logical
but not always quite what you would expect from using Blender.
So this takes some time to learn, it helps you understand how data fits together in Blender
which is important to know when writing scripts.
The properties are arranged to match how data is stored internally (in blenders C code) which is often logical but
not always quite what you would expect from using Blender.
So this takes some time to learn, it helps you understand how data fits together in Blender which is important
to know when writing scripts.
When starting out scripting you will often run into the problem where you're not sure how to access the data you want.
There are a few ways to do this.
When starting out scripting you will often run into the problem
where you're not sure how to access the data you want.
There are a few ways to do this:
- Use the Python console's auto-complete to inspect properties.
*This can be hit-and-miss but has the advantage
that you can easily see the values of properties and assign them to interactively see the results.*
- Copy the Data-Path from the user interface.
*Explained further in :ref:`Copy Data Path <info_data_path_copy>`*
- Copy the data path from the user interface.
*Explained further in* :ref:`Copy Data Path <info_data_path_copy>`.
- Using the documentation to follow references.
*Explained further in :ref:`Indirect Data Access <info_data_path_indirect>`*
*Explained further in* :ref:`Indirect Data Access <info_data_path_indirect>`.
.. _info_data_path_copy:
@@ -155,42 +142,36 @@ There are a few ways to do this.
Copy Data Path
--------------
Blender can compute the Python string to a property which is shown in the tool-tip, on the line below ``Python: ...``,
This saves having to use the API reference to click back up the references to find where data is accessed from.
There is a user-interface feature to copy the data-path which gives the path from an :class:`bpy.types.ID` data-block,
Blender can compute the Python string to a property which is shown in the tooltip,
on the line below ``Python: ...``. This saves having to open the API references to find where data is accessed from.
In the context menu is a copy data-path tool which gives the path from an :class:`bpy.types.ID` data-block,
to its property.
To see how this works we'll get the path to the Subdivision-Surface modifiers subdivision setting.
Start with the default scene and select the **Modifiers** tab, then add a **Subdivision-Surface** modifier to the cube.
Now hover your mouse over the button labeled **View**, The tool-tip includes :class:`bpy.types.SubsurfModifier.levels`
but we want the path from the object to this property.
To see how this works you'll get the path to the Subdivision Surface modifiers *Levels* setting.
Start with the default scene and select the Modifiers tab, then add a Subdivision Surface modifier to the cube.
Now hover your mouse over the button labeled *Levels Viewport*,
The tooltip includes :class:`bpy.types.SubsurfModifier.levels` but you want the path from the object to this property.
Note that the text copied won't include the ``bpy.data.collection["name"].`` component since its assumed that
you won't be doing collection look-ups on every access and typically you'll want to use the context rather
then access each :class:`bpy.types.ID` instance by name.
Type in the ID path into a Python console :mod:`bpy.context.active_object`.
Include the trailing dot and don't hit "enter", yet.
Include the trailing dot and don't execute the code, yet.
Now right-click on the button and select **Copy Data Path**, then paste the result into the console.
So now you should have the answer:
Now in the button's context menu select *Copy Data Path*, then paste the result into the console:
.. code-block:: python
bpy.context.active_object.modifiers["Subsurf"].levels
Hit "enter" and you'll get the current value of 1. Now try changing the value to 2:
Press :kbd:`Return` and you'll get the current value of 1. Now try changing the value to 2:
.. code-block:: python
bpy.context.active_object.modifiers["Subsurf"].levels = 2
bpy.context.active_object.modifiers["Subsurf"].levels = 2
You can see the value update in the Subdivision-Surface modifier's UI as well as the cube.
You can see the value update in the Subdivision Surface modifier's UI as well as the cube.
.. _info_data_path_indirect:
@@ -198,51 +179,45 @@ You can see the value update in the Subdivision-Surface modifier's UI as well as
Indirect Data Access
--------------------
For this example we'll go over something more involved, showing the steps to access the active sculpt brushes texture.
This more advanced example shows the steps to access the active sculpt brushes texture.
For example, if you want to access the texture of a brush via Python to adjust its ``contrast``.
Lets say we want to access the texture of a brush via Python, to adjust its ``contrast`` for example.
#. Start in the default scene and enable Sculpt Mode from the 3D Viewport header.
#. From the Sidebar expand the Brush Settings panel's *Texture* subpanel and add a new texture.
*Notice the texture data-block menu itself doesn't have very useful links (you can check the tooltips).*
#. The contrast setting isn't exposed in the Sidebar, so view the texture in the properties editor:
- Start in the default scene and enable 'Sculpt' mode from the 3D-View header.
- From the toolbar expand the **Texture** panel and add a new texture.
*Notice the texture button its self doesn't have very useful links (you can check the tooltips).*
- The contrast setting isn't exposed in the sculpt toolbar, so view the texture in the properties panel...
- In the properties editor select the Texture tab.
- Select brush texture.
- Expand the *Colors* panel to locate the *Contrast* number field.
#. Open the context menu of the contrast field and select *Online Python Reference*.
This takes you to ``bpy.types.Texture.contrast``. Now you can see that ``contrast`` is a property of texture.
#. To find out how to access the texture from the brush check on the references at the bottom of the page.
Sometimes there are many references, and it may take some guesswork to find the right one,
but in this case it's ``Brush.texture``.
- In the properties button select the Texture context.
- Select the Brush icon to show the brush texture.
- Expand the *Colors* panel to locate the *Contrast* button.
- Right click on the contrast button and select **Online Python Reference**
This takes you to ``bpy.types.Texture.contrast``
- Now we can see that ``contrast`` is a property of texture,
so next we'll check on how to access the texture from the brush.
- Check on the **References** at the bottom of the page, sometimes there are many references, and it may take
some guess work to find the right one, but in this case its obviously ``Brush.texture``.
#. Now you know that the texture can be accessed from ``bpy.data.brushes["BrushName"].texture``
but normally you *won't* want to access the brush by name, instead you want to access the active brush.
So the next step is to check on where brushes are accessed from via the references.
In this case there it is simply ``bpy.context.brush``.
*Now we know that the texture can be accessed from* ``bpy.data.brushes["BrushName"].texture``
*but normally you won't want to access the brush by name, so we'll see now to access the active brush instead.*
- So the next step is to check on where brushes are accessed from via the **References**.
In this case there is simply ``bpy.context.brush`` which is all we need.
Now you can use the Python console to form the nested properties needed to access brush textures contrast:
*Context -> Brush -> Texture -> Contrast*.
Now you can use the Python console to form the nested properties needed to access brush textures contrast,
logically we now know.
*Context -> Brush -> Texture -> Contrast*
Since the attribute for each is given along the way we can compose the data path in the python console:
Since the attribute for each is given along the way you can compose the data path in the Python console:
.. code-block:: python
bpy.context.brush.texture.contrast
There can be multiple ways to access the same data, which you choose often depends on the task.
An alternate path to access the same setting is...
An alternate path to access the same setting is:
.. code-block:: python
bpy.context.sculpt.brush.texture.contrast
Or access the brush directly...
Or access the brush directly:
.. code-block:: python
@@ -251,27 +226,24 @@ Or access the brush directly...
If you are writing a user tool normally you want to use the :mod:`bpy.context` since the user normally expects
the tool to operate on what they have selected.
For automation you are more likely to use :mod:`bpy.data` since you want to be able to access specific data and manipulate
it, no matter what the user currently has the view set at.
For automation you are more likely to use :mod:`bpy.data` since you want to be able to access specific data and
manipulate it, no matter what the user currently has the view set at.
Operators
=========
Most key-strokes and buttons in Blender call an operator which is also exposed to python via :mod:`bpy.ops`,
Most hotkeys and buttons in Blender call an operator which is also exposed to Python via :mod:`bpy.ops`.
To see the Python equivalent hover your mouse over the button and see the tool-tip,
eg ``Python: bpy.ops.render.render()``,
If there is no tool-tip or the ``Python:`` line is missing then this button is not using an operator and
can't be accessed from Python.
To see the Python equivalent hover your mouse over the button and see the tooltip,
e.g ``Python: bpy.ops.render.render()``,
If there is no tooltip or the ``Python:`` line is missing then this button is not using an operator
and can't be accessed from Python.
If you want to use this in a script you can press :kbd:`Control-C` while your mouse is over the button to copy it to the
clipboard.
You can also right click on the button and view the **Online Python Reference**, this mainly shows arguments and
their defaults however operators written in Python show their file and line number which may be useful if you
If you want to use this in a script you can press :kbd:`Ctrl-C` while your mouse is over the button
to copy it to the clipboard.
You can also use button's context menu and view the *Online Python Reference*, this mainly shows arguments and
their defaults, however, operators written in Python show their file and line number which may be useful if you
are interested to check on the source code.
.. note::
@@ -280,21 +252,18 @@ are interested to check on the source code.
for more on this see :ref:`using operators <using_operators>`.
Info View
---------
Info Editor
-----------
Blender records operators you run and displays them in the **Info** space.
This is located above the file-menu which can be dragged down to display its contents.
Blender records operators you run and displays them in the Info editor.
Select the Scripting workspace that comes default with Blender to see its output.
You can perform some actions and see them show up -- delete a vertex for example.
Select the **Script** screen that comes default with Blender to see its output.
You can perform some actions and see them show up - delete a vertex for example.
Each entry can be selected (Right-Mouse-Button),
then copied :kbd:`Control-C`, usually to paste in the text editor or python console.
Each entry can be selected, then copied :kbd:`Ctrl-C`, usually to paste in the text editor or Python console.
.. note::
Not all operators get registered for display,
zooming the view for example isn't so useful to repeat so its excluded from the output.
To display *every* operator that runs see :ref:`Show All Operators <info_show_all_operators>`
To display *every* operator that runs see :ref:`Show All Operators <info_show_all_operators>`.

View File

@@ -3,38 +3,34 @@
Best Practice
*************
When writing your own scripts python is great for new developers to pick up and become productive,
but you can also pick up odd habits or at least write scripts that are not easy for others to understand.
When writing your own scripts Python is great for new developers to pick up and become productive,
but you can also pick up bad practices or at least write scripts that are not easy for others to understand.
For your own work this is of course fine,
but if you want to collaborate with others or have your work included with blender there are practices we encourage.
but if you want to collaborate with others or have your work included with Blender there are practices we encourage.
Style Conventions
=================
For Blender/Python development we have chosen to follow python suggested style guide to avoid mixing styles
amongst our own scripts and make it easier to use python scripts from other projects.
For Blender Python development we have chosen to follow Python suggested style guide to avoid mixing styles
among our own scripts and make it easier to use Python scripts from other projects.
Using our style guide for your own scripts makes it easier if you eventually want to contribute them to Blender.
Using our style guide for your own scripts makes it easier if you eventually want to contribute them to blender.
This style guide is known as `pep8 <https://www.python.org/dev/peps/pep-0008/>`__
and here is a brief listing of pep8 criteria:
This style guide is known as pep8 and can be found `here <https://www.python.org/dev/peps/pep-0008/>`_
- Camel caps for class names: MyClass
- All lower case underscore separated module names: my_module
- Indentation of 4 spaces (no tabs)
- Spaces around operators: ``1 + 1``, not ``1+1``
- Only use explicit imports (no wildcard importing ``*``)
- Don't use multiple statements on a single line: ``if val: body``, separate onto two lines instead.
A brief listing of pep8 criteria.
- camel caps for class names: MyClass
- all lower case underscore separated module names: my_module
- indentation of 4 spaces (no tabs)
- spaces around operators. ``1 + 1``, not ``1+1``
- only use explicit imports, (no importing ``*``)
- don't use single line: ``if val: body``, separate onto 2 lines instead.
As well as pep8 we have other conventions used for blender python scripts.
As well as pep8 we have additional conventions used for Blender Python scripts:
- Use single quotes for enums, and double quotes for strings.
Both are of course strings, but in our internal API enums are unique items from a limited set. eg.
Both are of course strings, but in our internal API enums are unique items from a limited set, e.g:
.. code-block:: python
@@ -42,14 +38,14 @@ As well as pep8 we have other conventions used for blender python scripts.
bpy.context.scene.render.filepath = "//render_out"
- pep8 also defines that lines should not exceed 79 characters,
we felt this is too restrictive so this is optional per script.
we have decided that this is too restrictive so it is optional per script.
Periodically we run checks for pep8 compliance on blender scripts,
for scripts to be included in this check add this line as a comment at the top of the script.
Periodically we run checks for pep8 compliance on Blender scripts,
for scripts to be included in this check add this line as a comment at the top of the script:
``# <pep8 compliant>``
To enable line length checks use this instead.
To enable line length checks use this instead:
``# <pep8-80 compliant>``
@@ -59,85 +55,79 @@ User Interface Layout
Some notes to keep in mind when writing UI layouts:
- UI code is quite simple. Layout declarations are there to easily create a decent layout.
UI code is quite simple. Layout declarations are there to easily create a decent layout.
The general rule here is: If you need more code for the layout declaration,
than for the actual properties, then you are doing it wrong.
General rule here: If you need more code for the layout declaration,
then for the actual properties, you do it wrong.
Example layouts:
.. rubric:: Example layouts:
- layout()
``layout()``
The basic layout is a simple top-to-bottom layout.
The basic layout is a simple Top -> Bottom layout.
.. code-block:: python
.. code-block:: python
layout.prop()
layout.prop()
layout.prop()
layout.prop()
``layout.row()``
Use ``row()``, when you want more than one property in a single line.
- layout.row()
.. code-block:: python
Use row(), when you want more than 1 property in one line.
row = layout.row()
row.prop()
row.prop()
.. code-block:: python
``layout.column()``
Use ``column()``, when you want your properties in a column.
row = layout.row()
row.prop()
row.prop()
.. code-block:: python
- layout.column()
col = layout.column()
col.prop()
col.prop()
Use column(), when you want your properties in a column.
``layout.split()``
This can be used to create more complex layouts.
For example, you can split the layout and create two ``column()`` layouts next to each other.
Do not use split, when you simply want two properties in a row. Use ``row()`` instead.
.. code-block:: python
.. code-block:: python
col = layout.column()
col.prop()
col.prop()
split = layout.split()
- layout.split()
col = split.column()
col.prop()
col.prop()
This can be used to create more complex layouts.
For example you can split the layout and create two column() layouts next to each other.
Don't use split, when you simply want two properties in a row. Use row() for that.
col = split.column()
col.prop()
col.prop()
.. code-block:: python
split = layout.split()
col = split.column()
col.prop()
col.prop()
col = split.column()
col.prop()
col.prop()
Declaration names:
.. rubric:: Declaration names:
Try to only use these variable names for layout declarations:
- row for a row() layout
- col for a column() layout
- split for a split() layout
- flow for a column_flow() layout
- sub for a sub layout (a column inside a column for example)
:row: for a ``row()`` layout
:col: for a ``column()`` layout
:split: for a ``split()`` layout
:flow: for a ``column_flow()`` layout
:sub: for a sub layout (a column inside a column for example)
Script Efficiency
=================
List Manipulation (General Python Tips)
---------------------------------------
Searching for list items
Searching for List Items
^^^^^^^^^^^^^^^^^^^^^^^^
In Python there are some handy list functions that save you having to search through the list.
Even though you are not looping on the list data **python is**,
Even though you are not looping on the list data **Python is**,
so you need to be aware of functions that will slow down your script by searching the whole list.
.. code-block:: python
@@ -150,23 +140,21 @@ so you need to be aware of functions that will slow down your script by searchin
Modifying Lists
^^^^^^^^^^^^^^^
In python we can add and remove from a list, this is slower when the list length is modified,
especially at the start of the list, since all the data after the index of
modification needs to be moved up or down 1 place.
The most simple way to add onto the end of the list is to use
``my_list.append(list_item)`` or ``my_list.extend(some_list)`` and the fastest way to
remove an item is ``my_list.pop()`` or ``del my_list[-1]``.
In Python you can add and remove from a list, this is slower when the list length is modified,
especially at the start of the list, since all the data after the index of
modification needs to be moved up or down one place.
The fastest way to add onto the end of the list is to use
``my_list.append(list_item)`` or ``my_list.extend(some_list)`` and
to remove an item is ``my_list.pop()`` or ``del my_list[-1]``.
To use an index you can use ``my_list.insert(index, list_item)`` or ``list.pop(index)``
for list removal, but these are slower.
Sometimes its faster (but more memory hungry) to just rebuild the list.
Say you want to remove all triangular polygons in a list.
Rather than...
Sometimes it's faster (but less memory efficient) to just rebuild the list.
For example if you want to remove all triangular polygons in a list.
Rather than:
.. code-block:: python
@@ -179,7 +167,7 @@ Rather than...
polygons.pop(p_idx) # remove the triangle
It's faster to build a new list with list comprehension.
It's faster to build a new list with list comprehension:
.. code-block:: python
@@ -189,14 +177,14 @@ It's faster to build a new list with list comprehension.
Adding List Items
^^^^^^^^^^^^^^^^^
If you have a list that you want to add onto another list, rather than...
If you have a list that you want to add onto another list, rather than:
.. code-block:: python
for l in some_list:
my_list.append(l)
Use...
Use:
.. code-block:: python
@@ -205,9 +193,7 @@ Use...
Note that insert can be used when needed,
but it is slower than append especially when inserting at the start of a long list.
This example shows a very sub-optimal way of making a reversed list.
This example shows a very suboptimal way of making a reversed list:
.. code-block:: python
@@ -219,7 +205,6 @@ This example shows a very sub-optimal way of making a reversed list.
Python provides more convenient ways to reverse a list using the slice method,
but you may want to time this before relying on it too much:
.. code-block:: python
some_reversed_list = some_list[::-1]
@@ -228,12 +213,10 @@ but you may want to time this before relying on it too much:
Removing List Items
^^^^^^^^^^^^^^^^^^^
Use ``my_list.pop(index)`` rather than ``my_list.remove(list_item)``
Use ``my_list.pop(index)`` rather than ``my_list.remove(list_item)``.
This requires you to have the index of the list item but is faster since ``remove()`` will search the list.
Here is an example of how to remove items in 1 loop,
removing the last items first, which is faster (as explained above).
Here is an example of how to remove items in one loop,
removing the last items first, which is faster (as explained above):
.. code-block:: python
@@ -247,7 +230,7 @@ removing the last items first, which is faster (as explained above).
This example shows a fast way of removing items,
for use in cases where you can alter the list order without breaking the scripts functionality.
This works by swapping 2 list items, so the item you remove is always last.
This works by swapping two list items, so the item you remove is always last:
.. code-block:: python
@@ -260,64 +243,59 @@ This works by swapping 2 list items, so the item you remove is always last.
my_list.pop()
When removing many items in a large list this can provide a good speedup.
When removing many items in a large list this can provide a good speed-up.
Avoid Copying Lists
^^^^^^^^^^^^^^^^^^^
When passing a list/dictionary to a function,
When passing a list or dictionary to a function,
it is faster to have the function modify the list rather than returning
a new list so python doesn't have to duplicate the list in memory.
a new list so Python doesn't have to duplicate the list in memory.
Functions that modify a list in-place are more efficient than functions that create new lists.
This is generally slower so only use for functions when it makes sense not to modify the list in place.
This is generally slower so only use for functions when it makes sense not to modify the list in place:
>>> my_list = some_list_func(my_list)
This is generally faster since there is no re-assignment and no list duplication.
This is generally faster since there is no re-assignment and no list duplication:
>>> some_list_func(vec)
Also note that passing a sliced list makes a copy of the list in python memory.
Also note that, passing a sliced list makes a copy of the list in Python memory:
>>> foobar(my_list[:])
If my_list was a large array containing 10000's of items, a copy could use a lot of extra memory.
If my_list was a large array containing 10,000's of items, a copy could use a lot of extra memory.
Writing Strings to a File (Python General)
------------------------------------------
Here are 3 ways of joining multiple strings into one string for writing.
This also applies to any area of your code that involves a lot of string joining.
Here are three ways of joining multiple strings into one string for writing.
This also applies to any area of your code that involves a lot of string joining:
String concatenation
This is the slowest option, do **not** use if you can avoid it, especially when writing data in a loop.
>>> file.write(str1 + " " + str2 + " " + str3 + "\n")
String formatting
Use this when you are writing string data from floats and ints.
>>> file.write("%s %s %s\n" % (str1, str2, str3))
String joining
Use to join a list of strings (the list may be temporary). In the following example, the strings are joined with
a space " " in between, other examples are "" or ", ".
>>> file.write(" ".join((str1, str2, str3, "\n")))
``String addition`` -
this is the slowest option, *don't use if you can help it, especially when writing data in a loop*.
>>> file.write(str1 + " " + str2 + " " + str3 + "\n")
``String formatting`` -
use this when you are writing string data from floats and ints.
>>> file.write("%s %s %s\n" % (str1, str2, str3))
``String join() function``
use to join a list of strings (the list may be temporary). In the following example, the strings are joined with a space " " in between, other examples are "" or ", ".
>>> file.write(" ".join([str1, str2, str3, "\n"]))
Join is fastest on many strings,
`string formatting <https://wiki.blender.org/index.php/Dev:Source/Modeling/BMesh/Design>`__
is quite fast too (better for converting data types). String arithmetic is slowest.
Join is fastest on many strings, string formatting is quite fast too (better for converting data types).
String concatenation is the slowest.
Parsing Strings (Import/Exporting)
@@ -333,36 +311,35 @@ Parsing Numbers
^^^^^^^^^^^^^^^
Use ``float(string)`` rather than ``eval(string)``, if you know the value will be an int then ``int(string)``,
float() will work for an int too but it is faster to read ints with int().
``float()`` will work for an int too but it is faster to read ints with ``int()``.
Checking String Start/End
^^^^^^^^^^^^^^^^^^^^^^^^^
If you are checking the start of a string for a keyword, rather than...
If you are checking the start of a string for a keyword, rather than:
>>> if line[0:5] == "vert ": ...
use...
Use:
>>> if line.startswith("vert "):
Using ``startswith()`` is slightly faster (approx 5%) and also avoids a possible
error with the slice length not matching the string length.
Using ``startswith()`` is slightly faster (around 5%) and also avoids a possible error
with the slice length not matching the string length.
my_string.endswith("foo_bar") can be used for line endings too.
``my_string.endswith("foo_bar")`` can be used for line endings too.
If you are unsure whether the text is upper or lower case, use the ``lower()`` or ``upper()`` string function.
If you are unsure whether the text is upper or lower case, use the ``lower()`` or ``upper()`` string function:
>>> if line.lower().startswith("vert ")
Use try/except Sparingly
------------------------
Error Handling
--------------
The **try** statement is useful to save time writing error checking code.
However **try** is significantly slower than an **if** since an exception has to be set each time,
However, **try** is significantly slower than an **if** since an exception has to be set each time,
so avoid using **try** in areas of your code that execute in a loop and runs many times.
There are cases where using **try** is faster than checking whether the condition will raise an error,
@@ -382,7 +359,7 @@ In cases where you know you are checking for the same value which is referenced
Time Your Code
--------------
While developing a script it is good to time it to be aware of any changes in performance, this can be done simply.
While developing a script it is good to time it to be aware of any changes in performance, this can be done simply:
.. code-block:: python

View File

@@ -4,7 +4,7 @@ Gotchas
*******
This document attempts to help you work with the Blender API in areas
that can be troublesome and avoid practices that are known to give instability.
that can be troublesome and avoid practices that are known to cause instability.
.. _using_operators:
@@ -12,13 +12,13 @@ that can be troublesome and avoid practices that are known to give instability.
Using Operators
===============
Blender's operators are tools for users to access, that Python can access them too is very useful
nevertheless operators have limitations that can make them cumbersome to script.
Blender's operators are tools for users to access, that can access with Python too which is very useful.
Still operators have limitations that can make them cumbersome to script.
Main limits are...
The main limits are:
- Can't pass data such as objects, meshes or materials to operate on (operators use the context instead)
- The return value from calling an operator gives the success (if it finished or was canceled),
- Can't pass data such as objects, meshes or materials to operate on (operators use the context instead).
- The return value from calling an operator is the success (if it finished or was canceled),
in some cases it would be more logical from an API perspective to return the result of the operation.
- Operators poll function can fail where an API function would raise an exception giving details on exactly why.
@@ -34,26 +34,23 @@ When calling an operator gives an error like this:
Which raises the question as to what the correct context might be?
Typically operators check for the active area type, a selection or active object they can operate on,
but some operators are more picky about when they run.
but some operators are more strict when they run.
In most cases you can figure out what context an operator needs
simply be seeing how it's used in Blender and thinking about what it does.
Unfortunately if you're still stuck - the only way to **really** know
what's going on is to read the source code for the poll function and see what its checking.
by examining how it's used in Blender and thinking about what it does.
If you're still stuck, unfortunately, the only way to eventually know what is causing the error is
to read the source code for the poll function and see what it is checking.
For Python operators it's not so hard to find the source
since it's included with Blender and the source file/line is included in the operator reference docs.
since it's included with Blender and the source file and line is included in the operator reference docs.
Downloading and searching the C code isn't so simple,
especially if you're not familiar with the C language but by searching the
operator name or description you should be able to find the poll function with no knowledge of C.
especially if you're not familiar with the C language but by searching the operator name or description
you should be able to find the poll function with no knowledge of C.
.. note::
Blender does have the functionality for poll functions to describe why they fail,
but its currently not used much, if you're interested to help improve our API
feel free to add calls to ``CTX_wm_operator_poll_msg_set`` where its not obvious why poll fails.
but its currently not used much, if you're interested to help improve the API
feel free to add calls to ``CTX_wm_operator_poll_msg_set`` where its not obvious why poll fails, e.g:
>>> bpy.ops.gpencil.draw()
RuntimeError: Operator bpy.ops.gpencil.draw.poll() Failed to find Grease Pencil data to draw into
@@ -63,7 +60,7 @@ The operator still doesn't work!
--------------------------------
Certain operators in Blender are only intended for use in a specific context,
some operators for example are only called from the properties window where they check the current material,
some operators for example are only called from the properties editor where they check the current material,
modifier or constraint.
Examples of this are:
@@ -74,8 +71,8 @@ Examples of this are:
- :mod:`bpy.ops.buttons.file_browse`
Another possibility is that you are the first person to attempt to use this operator
in a script and some modifications need to be made to the operator to run in a different context,
if the operator should logically be able to run but fails when accessed from a script
in a script and some modifications need to be made to the operator to run in a different context.
If the operator should logically be able to run but fails when accessed from a script
it should be reported to the bug tracker.
@@ -85,22 +82,20 @@ Stale Data
No updates after setting values
-------------------------------
Sometimes you want to modify values from Python and immediately access the updated values, eg:
Sometimes you want to modify values from Python and immediately access the updated values, e.g:
Once changing the objects :class:`bpy.types.Object.location`
you may want to access its transformation right after from :class:`bpy.types.Object.matrix_world`,
but this doesn't work as you might expect.
Consider the calculations that might go into working out the object's final transformation, this includes:
Consider the calculations that might contribute to the object's final transformation, this includes:
- animation function curves.
- drivers and their Python expressions.
- constraints
- parent objects and all of their f-curves, constraints etc.
- Animation function curves.
- Drivers and their Python expressions.
- Constraints
- Parent objects and all of their F-curves, constraints, etc.
To avoid expensive recalculations every time a property is modified,
Blender defers making the actual calculations until they are needed.
Blender defers the evaluation until the results are needed.
However, while the script runs you may want to access the updated values.
In this case you need to call :class:`bpy.types.ViewLayer.update` after modifying values, for example:
@@ -110,44 +105,41 @@ In this case you need to call :class:`bpy.types.ViewLayer.update` after modifyin
bpy.context.view_layer.update()
Now all dependent data (child objects, modifiers, drivers... etc)
Now all dependent data (child objects, modifiers, drivers, etc.)
has been recalculated and is available to the script within active view layer.
Can I redraw during the script?
-------------------------------
Can I redraw during script execution?
-------------------------------------
The official answer to this is no, or... *"You don't want to do that"*.
To give some background on the topic...
To give some background on the topic:
While a script executes Blender waits for it to finish and is effectively locked until its done,
while in this state Blender won't redraw or respond to user input.
Normally this is not such a problem because scripts distributed with Blender
tend not to run for an extended period of time,
nevertheless scripts *can* take ages to execute and its nice to see what's going on in the view port.
nevertheless scripts *can* take a long time to complete and it would be nice to see progress in the viewport.
Tools that lock Blender in a loop and redraw are highly discouraged
since they conflict with Blenders ability to run multiple operators
When tools lock Blender in a loop redraw are highly discouraged
since they conflict with Blender's ability to run multiple operators
at once and update different parts of the interface as the tool runs.
So the solution here is to write a **modal** operator, that is - an operator which defines a modal() function,
See the modal operator template in the text editor.
So the solution here is to write a **modal** operator, which is an operator that defines a ``modal()`` function,
See the modal operator template in the text editor.
Modal operators execute on user input or setup their own timers to run frequently,
they can handle the events or pass through to be handled by the keymap or other modal operators.
Transform, Painting, Fly-Mode and File-Select are example of a modal operators.
Examples of a modal operators are Transform, Painting, Fly Navigation and File Select.
Writing modal operators takes more effort than a simple ``for`` loop
that happens to redraw but is more flexible and integrates better with Blenders design.
that contains draw calls but is more flexible and integrates better with Blender's design.
**Ok, Ok! I still want to draw from Python**
.. rubric:: Ok, Ok! I still want to draw from Python
If you insist - yes its possible, but scripts that use this hack won't be considered
for inclusion in Blender and any issues with using it won't be considered bugs,
this is also not guaranteed to work in future releases.
If you insist -- yes it's possible, but scripts that use this hack will not be considered
for inclusion in Blender and any issue with using it will not be considered a bug,
there is also no guaranteed compatibility in future releases.
.. code-block:: python
@@ -157,18 +149,18 @@ this is also not guaranteed to work in future releases.
Modes and Mesh Access
=====================
When working with mesh data you may run into the problem where a script fails to run as expected in edit-mode.
This is caused by edit-mode having its own data which is only written back to the mesh when exiting edit-mode.
When working with mesh data you may run into the problem where a script fails to run as expected in Edit-Mode.
This is caused by Edit-Mode having its own data which is only written back to the mesh when exiting Edit-Mode.
A common example is that exporters may access a mesh through ``obj.data`` (a :class:`bpy.types.Mesh`)
but the user is in edit-mode, where the mesh data is available but out of sync with the edit mesh.
when the user is in Edit-Mode, where the mesh data is available but out of sync with the edit mesh.
In this situation you can...
- Exit edit-mode before running the tool.
- Exit Edit-Mode before running the tool.
- Explicitly update the mesh by calling :class:`bmesh.types.BMesh.to_mesh`.
- Modify the script to support working on the edit-mode data directly, see: :mod:`bmesh.from_edit_mesh`.
- Report the context as incorrect and only allow the script to run outside edit-mode.
- Report the context as incorrect and only allow the script to run outside Edit-Mode.
.. _info_gotcha_mesh_faces:
@@ -176,24 +168,24 @@ In this situation you can...
N-Gons and Tessellation
=======================
Since 2.63 NGons are supported, this adds some complexity
Since 2.63 n-gons are supported, this adds some complexity
since in some cases you need to access triangles still (some exporters for example).
There are now 3 ways to access faces:
There are now three ways to access faces:
- :class:`bpy.types.MeshPolygon` -
this is the data structure which now stores faces in object mode
- :class:`bpy.types.MeshPolygon` --
this is the data structure which now stores faces in Object-Mode
(access as ``mesh.polygons`` rather than ``mesh.faces``).
- :class:`bpy.types.MeshLoopTriangle` -
- :class:`bpy.types.MeshLoopTriangle` --
the result of tessellating polygons into triangles
(access as ``mesh.loop_triangles``).
- :class:`bmesh.types.BMFace` -
the polygons as used in editmode.
- :class:`bmesh.types.BMFace` --
the polygons as used in Edit-Mode.
For the purpose of the following documentation,
these will be referred to as polygons, loop triangles and bmesh-faces respectively.
these will be referred to as polygons, loop triangles and BMesh-faces respectively.
5+ sided faces will be referred to as ``ngons``.
Faces with five or more sides will be referred to as ``ngons``.
Support Overview
@@ -216,58 +208,58 @@ Support Overview
- Unusable *(read-only)*.
- Best
* - Export/Output
- Good *(ngon support)*
- Good *(When ngons can't be used)*
- Good *(ngons, extra memory overhead)*
- Good *(n-gon support)*
- Good *(When n-gons cannot be used)*
- Good *(n-gons, extra memory overhead)*
.. note::
Using the :mod:`bmesh` API is completely separate API from :mod:`bpy`,
typically you would would use one or the other based on the level of editing needed,
typically you would use one or the other based on the level of editing needed,
not simply for a different way to access faces.
Creating
--------
All 3 datatypes can be used for face creation.
All three data types can be used for face creation:
- polygons are the most efficient way to create faces but the data structure is _very_ rigid and inflexible,
- Polygons are the most efficient way to create faces but the data structure is *very* rigid and inflexible,
you must have all your vertices and faces ready and create them all at once.
This is further complicated by the fact that each polygon does not store its own verts,
This is further complicated by the fact that each polygon does not store its own vertices,
rather they reference an index and size in :class:`bpy.types.Mesh.loops` which are a fixed array too.
- bmesh-faces are most likely the easiest way for new scripts to create faces,
since faces can be added one by one and the api has features intended for mesh manipulation.
- BMesh-faces are most likely the easiest way to create faces in new scripts,
since faces can be added one by one and the API has features intended for mesh manipulation.
While :class:`bmesh.types.BMesh` uses more memory it can be managed by only operating on one mesh at a time.
Editing
-------
Editing is where the 3 data types vary most.
Editing is where the three data types vary most.
- Polygons are very limited for editing,
changing materials and options like smooth works but for anything else
they are too inflexible and are only intended for storage.
- Tessfaces should not be used for editing geometry because doing so will cause existing ngons to be tessellated.
- BMesh-Faces are by far the best way to manipulate geometry.
- Tessfaces should not be used for editing geometry because doing so will cause existing n-gons to be tessellated.
- BMesh-faces are by far the best way to manipulate geometry.
Exporting
---------
All 3 data types can be used for exporting,
the choice mostly depends on whether the target format supports ngons or not.
All three data types can be used for exporting,
the choice mostly depends on whether the target format supports n-gons or not.
- Polygons are the most direct & efficient way to export providing they convert into the output format easily enough.
- Tessfaces work well for exporting to formats which don't support ngons,
- Polygons are the most direct and efficient way to export providing they convert into the output format easily enough.
- Tessfaces work well for exporting to formats which don't support n-gons,
in fact this is the only place where their use is encouraged.
- BMesh-Faces can work for exporting too but may not be necessary if polygons can be used
since using bmesh gives some overhead because its not the native storage format in object mode.
since using BMesh gives some overhead because its not the native storage format in Object-Mode.
EditBones, PoseBones, Bone... Bones
===================================
Edit Bones, Pose Bones, Bone... Bones
=====================================
Armature Bones in Blender have three distinct data structures that contain them.
If you are accessing the bones through one of them, you may not have access to the properties you really need.
@@ -280,43 +272,41 @@ If you are accessing the bones through one of them, you may not have access to t
Edit Bones
----------
``bpy.context.object.data.edit_bones`` contains a editbones;
to access them you must set the armature mode to edit mode first (editbones do not exist in object or pose mode).
``bpy.context.object.data.edit_bones`` contains an edit bones;
to access them you must set the armature mode to Edit-Mode first (edit bones do not exist in Object or Pose-Mode).
Use these to create new bones, set their head/tail or roll, change their parenting relationships to other bones, etc.
Example using :class:`bpy.types.EditBone` in armature editmode:
This is only possible in edit mode.
Example using :class:`bpy.types.EditBone` in armature Edit-Mode
which is only possible in Edit-Mode:
>>> bpy.context.object.data.edit_bones["Bone"].head = Vector((1.0, 2.0, 3.0))
This will be empty outside of editmode.
This will be empty outside of Edit-Mode:
>>> mybones = bpy.context.selected_editable_bones
Returns an editbone only in edit mode.
Returns an edit bone only in Edit-Mode:
>>> bpy.context.active_bone
Bones (Object Mode)
Bones (Object-Mode)
-------------------
``bpy.context.object.data.bones`` contains bones.
These *live* in object mode, and have various properties you can change,
These *live* in Object-Mode, and have various properties you can change,
note that the head and tail properties are read-only.
Example using :class:`bpy.types.Bone` in object or pose mode:
Returns a bone (not an editbone) outside of edit mode
Example using :class:`bpy.types.Bone` in Object or Pose-Mode
returning a bone (not an edit bone) outside of Edit-Mode:
>>> bpy.context.active_bone
This works, as with blender the setting can be edited in any mode
This works, as with Blender the setting can be edited in any mode:
>>> bpy.context.object.data.bones["Bone"].use_deform = True
Accessible but read-only
Accessible but read-only:
>>> tail = myobj.data.bones["Bone"].tail
@@ -326,42 +316,42 @@ Pose Bones
``bpy.context.object.pose.bones`` contains pose bones.
This is where animation data resides, i.e. animatable transformations
are applied to pose bones, as are constraints and ik-settings.
are applied to pose bones, as are constraints and IK-settings.
Examples using :class:`bpy.types.PoseBone` in object or pose mode:
Examples using :class:`bpy.types.PoseBone` in Object or Pose-Mode:
.. code-block:: python
# Gets the name of the first constraint (if it exists)
bpy.context.object.pose.bones["Bone"].constraints[0].name
# Gets the last selected pose bone (pose mode only)
# Gets the last selected pose bone (Pose-Mode only)
bpy.context.active_pose_bone
.. note::
Notice the pose is accessed from the object rather than the object data,
this is why blender can have 2 or more objects sharing the same armature in different poses.
this is why Blender can have two or more objects sharing the same armature in different poses.
.. note::
Strictly speaking PoseBone's are not bones, they are just the state of the armature,
Strictly speaking pose bones are not bones, they are just the state of the armature,
stored in the :class:`bpy.types.Object` rather than the :class:`bpy.types.Armature`,
the real bones are however accessible from the pose bones - :class:`bpy.types.PoseBone.bone`
yet the real bones are accessible from the pose bones via :class:`bpy.types.PoseBone.bone`.
Armature Mode Switching
-----------------------
While writing scripts that deal with armatures you may find you have to switch between modes,
when doing so take care when switching out of edit-mode not to keep references
to the edit-bones or their head/tail vectors.
Further access to these will crash blender so its important the script
when doing so take care when switching out of Edit-Mode not to keep references
to the edit bones or their head/tail vectors.
Further access to these will crash Blender so its important the script
clearly separates sections of the code which operate in different modes.
This is mainly an issue with editmode since pose data can be manipulated without having to be in pose mode,
however for operator access you may still need to enter pose mode.
This is mainly an issue with Edit-Mode since pose data can be manipulated without having to be in Pose-Mode,
yet for operator access you may still need to enter Pose-Mode.
Data Names
@@ -372,8 +362,7 @@ Naming Limitations
------------------
A common mistake is to assume newly created data is given the requested name.
This can cause bugs when you add some data (normally imported) then reference it later by name.
This can cause bugs when you add data (normally imported) then reference it later by name:
.. code-block:: python
@@ -383,7 +372,7 @@ This can cause bugs when you add some data (normally imported) then reference it
bpy.data.meshes[meshid]
Or with name assignment...
Or with name assignment:
.. code-block:: python
@@ -397,12 +386,12 @@ Data names may not match the assigned values if they exceed the maximum length,
Its better practice not to reference objects by names at all,
once created you can store the data in a list, dictionary, on a class etc,
once created you can store the data in a list, dictionary, on a class, etc;
there is rarely a reason to have to keep searching for the same data by name.
If you do need to use name references, its best to use a dictionary to maintain
a mapping between the names of the imported assets and the newly created data,
this way you don't run this risk of referencing existing data from the blend file, or worse modifying it.
this way you don't run this risk of referencing existing data from the blend-file, or worse modifying it.
.. code-block:: python
@@ -421,17 +410,14 @@ this way you don't run this risk of referencing existing data from the blend fil
Library Collisions
------------------
Blender keeps data names unique - :class:`bpy.types.ID.name` so you can't name two objects,
meshes, scenes etc the same thing by accident.
However when linking in library data from another blend file naming collisions can occur,
Blender keeps data names unique (:class:`bpy.types.ID.name`) so you can't name two objects,
meshes, scenes, etc., the same by accident.
However, when linking in library data from another blend-file naming collisions can occur,
so its best to avoid referencing data by name at all.
This can be tricky at times and not even blender handles this correctly in some case
(when selecting the modifier object for eg you can't select between multiple objects with the same name),
but its still good to try avoid problems in this area.
This can be tricky at times and not even Blender handles this correctly in some case
(when selecting the modifier object for e.g. you can't select between multiple objects with the same name),
but its still good to try avoiding these problems in this area.
If you need to select between local and library data, there is a feature in ``bpy.data`` members to allow for this.
.. code-block:: python
@@ -454,18 +440,17 @@ If you need to select between local and library data, there is a feature in ``bp
Relative File Paths
===================
Blenders relative file paths are not compatible with standard Python modules such as ``sys`` and ``os``.
Blender's relative file paths are not compatible with standard Python modules such as ``sys`` and ``os``.
Built-in Python functions don't understand Blender's ``//`` prefix which denotes the blend-file path.
Built in Python functions don't understand blenders ``//`` prefix which denotes the blend file path.
A common case where you would run into this problem is when exporting a material with associated image paths.
A common case where you would run into this problem is when exporting a material with associated image paths:
>>> bpy.path.abspath(image.filepath)
When using blender data from linked libraries there is an unfortunate complication
since the path will be relative to the library rather than the open blend file.
When the data block may be from an external blend file pass the library argument from the :class:`bpy.types.ID`.
When using Blender data from linked libraries there is an unfortunate complication
since the path will be relative to the library rather than the open blend-file.
When the data block may be from an external blend-file pass the library argument from the :class:`bpy.types.ID`.
>>> bpy.path.abspath(image.filepath, library=image.library)
@@ -478,19 +463,15 @@ Unicode Problems
Python supports many different encodings so there is nothing stopping you from
writing a script in ``latin1`` or ``iso-8859-15``.
See `PEP 263 <https://www.python.org/dev/peps/pep-0263/>`__.
See `pep-0263 <https://www.python.org/dev/peps/pep-0263/>`_
However this complicates matters for Blender's Python API because ``.blend`` files don't have an explicit encoding.
To avoid the problem for Python integration and script authors we have decided all strings in blend files
However, this complicates matters for Blender's Python API because ``.blend`` files don't have an explicit encoding.
To avoid the problem for Python integration and script authors we have decided all strings in blend-files
**must** be ``UTF-8``, ``ASCII`` compatible.
This means assigning strings with different encodings to an object names for instance will raise an error.
Paths are an exception to this rule since we cannot ignore the existence of non ``UTF-8`` paths on users file-system.
This means seemingly harmless expressions can raise errors, eg.
Paths are an exception to this rule since the existence of non-UTF-8 paths on user's file system cannot be ignored.
This means seemingly harmless expressions can raise errors, e.g:
>>> print(bpy.data.filepath)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 10-21: ordinal not in range(128)
@@ -501,7 +482,7 @@ This means seemingly harmless expressions can raise errors, eg.
TypeError: bpy_struct: item.attr= val: Object.name expected a string type, not str
Here are 2 ways around filesystem encoding issues:
Here are two ways around file-system encoding issues:
>>> print(repr(bpy.data.filepath))
@@ -512,11 +493,11 @@ Here are 2 ways around filesystem encoding issues:
Unicode encoding/decoding is a big topic with comprehensive Python documentation,
to avoid getting stuck too deep in encoding problems - here are some suggestions:
to keep it short about encoding problems -- here are some suggestions:
- Always use utf-8 encoding or convert to utf-8 where the input is unknown.
- Avoid manipulating filepaths as strings directly, use ``os.path`` functions instead.
- Use ``os.fsencode()`` / ``os.fsdecode()`` instead of built in string decoding functions when operating on paths.
- Always use UTF-8 encoding or convert to UTF-8 where the input is unknown.
- Avoid manipulating file paths as strings directly, use ``os.path`` functions instead.
- Use ``os.fsencode()`` or ``os.fsdecode()`` instead of built-in string decoding functions when operating on paths.
- To print paths or to include them in the user interface use ``repr(path)`` first
or ``"%r" % path`` with string formatting.
@@ -528,11 +509,11 @@ to avoid getting stuck too deep in encoding problems - here are some suggestions
some importers do this.
Strange errors using 'threading' module
=======================================
Strange Errors when Using the 'Threading' Module
================================================
Python threading with Blender only works properly when the threads finish up before the script does.
By using ``threading.join()`` for example.
Python threading with Blender only works properly when the threads finish up before the script does,
for example by using ``threading.join()``.
Here is an example of threading supported by Blender:
@@ -571,8 +552,8 @@ Here is an example of threading supported by Blender:
t.join()
This an example of a timer which runs many times a second and moves
the default cube continuously while Blender runs **(Unsupported)**.
This an example of a timer which runs many times a second
and moves the default cube continuously while Blender runs **(Unsupported)**.
.. code-block:: python
@@ -592,33 +573,33 @@ the default cube continuously while Blender runs **(Unsupported)**.
Use cases like the one above which leave the thread running once the script finishes
may seem to work for a while but end up causing random crashes or errors in Blender's own drawing code.
So far, no work has gone into making Blender's Python integration thread safe,
so until its properly supported, best not make use of this.
So far, no work has been done to make Blender's Python integration thread safe,
so until it's properly supported, it's best not make use of this.
.. note::
Pythons threads only allow co-currency and won't speed up your scripts on multi-processor systems,
the ``subprocess`` and ``multiprocess`` modules can be used with Blender and make use of multiple CPU's too.
Python threads only allow concurrency and won't speed up your scripts on multiprocessor systems,
the ``subprocess`` and ``multiprocess`` modules can be used with Blender to make use of multiple CPUs too.
Help! My script crashes Blender
===============================
**TL;DR:** Do not keep direct references to Blender data (of any kind) when modifying the container
of that data, and/or when some undo/redo may happen (e.g. during modal operators execution...).
:abbr:`TL;DR (Too long; didn't read.)` Do not keep direct references to Blender data (of any kind)
when modifying the container of that data, and/or when some undo/redo may happen
(e.g. during modal operators execution...).
Instead, use indices (or other data always stored by value in Python, like string keys...),
that allow you to get access to the desired data.
Ideally it would be impossible to crash Blender from Python
however there are some problems with the API where it can be made to crash.
Ideally it would be impossible to crash Blender from Python,
however, there are some problems with the API where it can be made to crash.
Strictly speaking this is a bug in the API but fixing it would mean adding memory verification
on every access since most crashes are caused by the Python objects referencing Blenders memory directly,
on every access since most crashes are caused by the Python objects referencing Blender's memory directly,
whenever the memory is freed or re-allocated, further Python access to it can crash the script.
But fixing this would make the scripts run very slow,
or writing a very different kind of API which doesn't reference the memory directly.
Here are some general hints to avoid running into these problems.
Here are some general hints to avoid running into these problems:
- Be aware of memory limits,
especially when working with large lists since Blender can crash simply by running out of memory.
@@ -631,16 +612,16 @@ Here are some general hints to avoid running into these problems.
- Modules or classes that remain active while Blender is used,
should not hold references to data the user may remove, instead,
fetch data from the context each time the script is activated.
- Crashes may not happen every time, they may happen more on some configurations/operating-systems.
- Be wary of recursive patterns, those are very efficient at hiding the issues described here.
- See last sub-section about `Unfortunate Corner Cases`_ for some known breaking exceptions.
- Crashes may not happen every time, they may happen more on some configurations or operating systems.
- Be careful with recursive patterns, those are very efficient at hiding the issues described here.
- See last subsection about `Unfortunate Corner Cases`_ for some known breaking exceptions.
.. note::
To find the line of your script that crashes you can use the ``faulthandler`` module.
See the `faulthandler docs <https://docs.python.org/dev/library/faulthandler.html>`_.
See the `Faulthandler docs <https://docs.python.org/dev/library/faulthandler.html>`__.
While the crash may be in Blenders C/C++ code,
While the crash may be in Blender's C/C++ code,
this can help a lot to track down the area of the script that causes the crash.
.. note::
@@ -654,7 +635,7 @@ Here are some general hints to avoid running into these problems.
in any possible way.
**Dont:**
.. rubric:: Do not:
.. code-block:: python
@@ -673,7 +654,7 @@ Here are some general hints to avoid running into these problems.
first_item.name = "foobar"
**Do:**
.. rubric:: Do:
.. code-block:: python
@@ -696,33 +677,31 @@ Here are some general hints to avoid running into these problems.
Undo/Redo
---------
Undo invalidates all :class:`bpy.types.ID` instances (Object, Scene, Mesh, Lamp... etc).
Undo invalidates all :class:`bpy.types.ID` instances (Object, Scene, Mesh, Light, etc.).
This example shows how you can tell undo changes the memory locations.
This example shows how you can tell undo changes the memory locations:
>>> hash(bpy.context.object)
-9223372036849950810
>>> hash(bpy.context.object)
-9223372036849950810
# ... move the active object, then undo
Move the active object, then undo:
>>> hash(bpy.context.object)
-9223372036849951740
As suggested above, simply not holding references to data when Blender is used
interactively by the user is the only way to ensure the script doesn't become unstable.
interactively by the user is the only way to make sure that the script doesn't become unstable.
Undo & Library Data
^^^^^^^^^^^^^^^^^^^
One of the advantages with Blenders library linking system that undo
One of the advantages with Blender's library linking system that undo
can skip checking changes in library data since it is assumed to be static.
Tools in Blender are not allowed to modify library data.
Python however does not enforce this restriction.
But Python does not enforce this restriction.
This can be useful in some cases, using a script to adjust material values for example.
But its also possible to use a script to make library data point to newly created local data,
@@ -733,13 +712,13 @@ So it's best to consider modifying library data an advanced usage of the API
and only to use it when you know what you're doing.
Edit Mode / Memory Access
Edit-Mode / Memory Access
-------------------------
Switching edit-mode ``bpy.ops.object.mode_set(mode='EDIT')`` / ``bpy.ops.object.mode_set(mode='OBJECT')``
Switching mode ``bpy.ops.object.mode_set(mode='EDIT')`` or ``bpy.ops.object.mode_set(mode='OBJECT')``
will re-allocate objects data,
any references to a meshes vertices/polygons/uvs, armatures bones,
curves points etc cannot be accessed after switching edit-mode.
any references to a meshes vertices/polygons/UVs, armatures bones,
curves points, etc. cannot be accessed after switching mode.
Only the reference to the data its self can be re-accessed, the following example will crash.
@@ -754,7 +733,7 @@ Only the reference to the data its self can be re-accessed, the following exampl
print(polygons)
So after switching edit-mode you need to re-access any object data variables,
So after switching mode you need to re-access any object data variables,
the following example shows how to avoid the crash above.
.. code-block:: python
@@ -770,7 +749,7 @@ the following example shows how to avoid the crash above.
These kinds of problems can happen for any functions which re-allocate
the object data but are most common when switching edit-mode.
the object data but are most common when switching mode.
Array Re-Allocation
@@ -791,21 +770,20 @@ internally the array which stores this data is re-allocated.
This can be avoided by re-assigning the point variables after adding the new one or by storing
indices to the points rather than the points themselves.
The best way is to sidestep the problem altogether add all the points to the curve at once.
This means you don't have to worry about array re-allocation and its faster too
since reallocating the entire array for every point added is inefficient.
The best way is to sidestep the problem altogether by adding all the points to the curve at once.
This means you don't have to worry about array re-allocation and it's faster too
since re-allocating the entire array for every added point is inefficient.
Removing Data
-------------
**Any** data that you remove shouldn't be modified or accessed afterwards,
this includes f-curves, drivers, render layers, timeline markers, modifiers, constraints
along with objects, scenes, collections, bones.. etc.
this includes: F-curves, drivers, render layers, timeline markers, modifiers, constraints
along with objects, scenes, collections, bones, etc.
The ``remove()`` api calls will invalidate the data they free to prevent common mistakes.
The following example shows how this precaution works.
The ``remove()`` API calls will invalidate the data they free to prevent common mistakes.
The following example shows how this precaution works:
.. code-block:: python
@@ -818,7 +796,7 @@ The following example shows how this precaution works.
But take care because this is limited to scripts accessing the variable which is removed,
the next example will still crash.
the next example will still crash:
.. code-block:: python
@@ -835,8 +813,8 @@ Besides all expected cases listed above, there are a few others that should not
an issue but, due to internal implementation details, currently are:
- ``Object.hide_viewport``, ``Object.hide_select`` and ``Object.hide_render``:
Setting any of those booleans will trigger a rebuild of Collection caches, hence breaking
any current iteration over ``Collection.all_objects``.
Setting any of those Booleans will trigger a rebuild of Collection caches,
thus breaking any current iteration over ``Collection.all_objects``.
sys.exit
@@ -848,5 +826,5 @@ as if Blender is crashing since ``sys.exit()`` will close Blender immediately.
For example, the ``argparse`` module will print an error and exit if the arguments are invalid.
An ugly way of troubleshooting this is to set ``sys.exit = None`` and see what line of Python code is quitting,
An dirty way of troubleshooting this is to set ``sys.exit = None`` and see what line of Python code is quitting,
you could of course replace ``sys.exit`` with your own function but manipulating Python in this way is bad practice.

View File

@@ -1,4 +1,3 @@
.. _info_overview:
*******************
@@ -6,24 +5,24 @@ Python API Overview
*******************
The purpose of this document is to explain how Python and Blender fit together,
covering some of the functionality that may not be obvious from reading the API
references and example scripts.
covering some of the functionality that may not be obvious from reading the API references
and example scripts.
Python in Blender
=================
Blender has an embedded Python interpreter which is loaded when Blender is started and stays
active while Blender is running. This interpreter runs scripts to draw the user interface
and is used for some of Blenders internal tools as well.
Blender has an embedded Python interpreter which is loaded when Blender is started
and stays active while Blender is running. This interpreter runs scripts to draw the user interface
and is used for some of Blender's internal tools as well.
Blender's embedded interpreter provides a typical Python environment, so code from tutorials
on how to write Python scripts can also be run with Blenders interpreter. Blender provides its
on how to write Python scripts can also be run with Blender's interpreter. Blender provides its
Python modules, such as :mod:`bpy` and :mod:`mathutils`, to the embedded interpreter so they can
be imported into a script and give access to Blender's data, classes, and functions. Scripts that
deal with Blender data will need to import the modules to work.
be imported into a script and give access to Blender's data, classes, and functions.
Scripts that deal with Blender data will need to import the modules to work.
Here is a simple example which moves a vertex attached to an object named **Cube**:
Here is a simple example which moves a vertex attached to an object named "Cube":
.. code-block:: python
@@ -31,7 +30,7 @@ Here is a simple example which moves a vertex attached to an object named **Cube
bpy.data.objects["Cube"].data.vertices[0].co.x += 1.0
This modifies Blender's internal data directly.
When you run this in the interactive console you will see the 3D viewport update.
When you run this in the interactive console you will see the 3D Viewport update.
The Default Environment
@@ -41,7 +40,7 @@ When developing your own scripts it may help to understand how Blender sets up i
Many Python scripts come bundled with Blender and can be used as a reference
because they use the same API that script authors write tools in.
Typical usage for scripts include: user interface, import/export,
scene manipulation, automation, defining your own toolset and customization.
scene manipulation, automation, defining your own tool set and customization.
On startup Blender scans the ``scripts/startup/`` directory for Python modules and imports them.
The exact location of this directory depends on your installation.
@@ -54,8 +53,8 @@ Script Loading
This may seem obvious, but it is important to note the difference between
executing a script directly and importing a script as a module.
Extending Blender by executing a script directly means the classes that the script
defines remain available inside Blender after the script finishes execution.
Extending Blender by executing a script directly means the classes that the script defines
remain available inside Blender after the script finishes execution.
Using scripts this way makes future access to their classes
(to unregister them for example) more difficult compared to importing the scripts as modules.
When a script is imported as a module, its class instances will remain
@@ -63,12 +62,11 @@ inside the module and can be accessed later on by importing that module again.
For this reason it is preferable to avoid directly executing scripts that extend Blender by registering classes.
Here are some ways to run scripts directly in Blender:
Here are some ways to run scripts directly in Blender.
- Loaded in the text editor and press **Run Script**.
- Loaded in the text editor and press *Run Script*.
- Typed or pasted into the interactive console.
- Execute a Python file from the command line with Blender, eg:
- Execute a Python file from the command line with Blender, e.g:
.. code-block:: sh
@@ -77,24 +75,22 @@ Here are some ways to run scripts directly in Blender.
To run as modules:
- The obvious way, ``import some_module`` command from the text window or interactive console.
- Open as a text block and tick "Register" option, this will load with the blend file.
- copy into one of the directories ``scripts/startup``, where they will be automatically imported on startup.
- define as an add-on, enabling the add-on will load it as a Python module.
- The obvious way, ``import some_module`` command from the text editor or interactive console.
- Open as a text data-block and check the *Register* option, this will load with the blend-file.
- Copy into one of the directories ``scripts/startup``, where they will be automatically imported on startup.
- Define as an add-on, enabling the add-on will load it as a Python module.
Add-ons
-------
Some of Blenders functionality is best kept optional,
alongside scripts loaded at startup we have add-ons which are kept in their own directory ``scripts/addons``,
and only load on startup if selected from the user preferences.
The only difference between add-ons and built-in Python modules is that add-ons must contain a ``bl_info``
variable which Blender uses to read metadata such as name, author, category and URL.
The User Preferences add-on listing uses **bl_info** to display information about each add-on.
Some of Blender's functionality is best kept optional,
alongside scripts loaded at startup there are add-ons which are kept in their own directory ``scripts/addons``,
They are only loaded on startup if selected from the user preferences.
The only difference between add-ons and built-in Python modules is that add-ons must contain a ``bl_info`` variable
which Blender uses to read metadata such as name, author, category and project link.
The User Preferences add-on listing uses ``bl_info`` to display information about each add-on.
`See Add-ons <https://wiki.blender.org/index.php/Dev:Py/Scripts/Guidelines/Addons>`__
for details on the ``bl_info`` dictionary.
@@ -105,7 +101,7 @@ Integration through Classes
Running Python scripts in the text editor is useful for testing but you'll
want to extend Blender to make tools accessible like other built-in functionality.
The Blender Python api allows integration for:
The Blender Python API allows integration for:
- :class:`bpy.types.Panel`
- :class:`bpy.types.Menu`
@@ -114,13 +110,12 @@ The Blender Python api allows integration for:
- :class:`bpy.types.KeyingSet`
- :class:`bpy.types.RenderEngine`
This is intentionally limited. Currently, for more advanced features such as mesh modifiers,
object types, or shader nodes, C/C++ must be used.
For Python integration Blender defines methods which are common to all types.
This works by creating a Python subclass of a Blender class which contains variables and functions
specified by the parent class which are pre-defined to interface with Blender.
specified by the parent class which are predefined to interface with Blender.
For example:
@@ -137,22 +132,20 @@ For example:
bpy.utils.register_class(SimpleOperator)
First note that we subclass a member of :mod:`bpy.types`,
First note that it defines a subclass as a member of :mod:`bpy.types`,
this is common for all classes which can be integrated with Blender and
used so we know if this is an Operator and not a Panel when registering.
is used to distinguish an Operator from a Panel when registering.
Both class properties start with a ``bl_`` prefix.
This is a convention used to distinguish Blender properties from those you add yourself.
Next see the execute function, which takes an instance of the operator and the current context.
A common prefix is not used for functions.
Lastly the register function is called, this takes the class and loads it into Blender. See `Class Registration`_.
Regarding inheritance, Blender doesn't impose restrictions on the kinds of class inheritance used,
the registration checks will use attributes and functions defined in parent classes.
class mix-in example:
Class mix-in example:
.. code-block:: python
@@ -173,8 +166,8 @@ While ``__init__()`` and ``__del__()`` will be called if defined,
the class instances lifetime only spans the execution.
So a panel for example will have a new instance for every redraw,
for this reason there is rarely a cause to store variables in the panel instance.
Instead, persistent variables should be stored in Blenders
ata so that the state can be restored when Blender is restarted.
Instead, persistent variables should be stored in Blender's data
so that the state can be restored when Blender is restarted.
.. note::
@@ -182,15 +175,14 @@ ata so that the state can be restored when Blender is restarted.
So once the class is registered with Blender, instancing the class and calling the functions is left up to Blender.
In fact you cannot instance these classes from the script as you would expect with most Python API's.
To run operators you can call them through the operator api, eg:
To run operators you can call them through the operator API, e.g:
.. code-block:: python
import bpy
bpy.ops.object.simple_operator()
User interface classes are given a context in which to draw, buttons window, file header, toolbar etc,
User interface classes are given a context in which to draw, buttons, window, file header, toolbar, etc.,
then they are drawn when that area is displayed so they are never called by Python scripts directly.
@@ -205,7 +197,7 @@ Module Registration
Blender modules loaded at startup require ``register()`` and ``unregister()`` functions.
These are the *only* functions that Blender calls from your code, which is otherwise a regular Python module.
A simple Blender/Python module can look like this:
A simple Blender Python module can look like this:
.. code-block:: python
@@ -225,16 +217,15 @@ A simple Blender/Python module can look like this:
These functions usually appear at the bottom of the script containing class registration sometimes adding menu items.
You can also use them for internal purposes setting up data for your own tools but take care
since register won't re-run when a new blend file is loaded.
since register won't re-run when a new blend-file is loaded.
The register/unregister calls are used so it's possible to toggle add-ons and reload scripts while Blender runs.
If the register calls were placed in the body of the script, registration would be called on import,
meaning there would be no distinction between importing a module or loading its classes into Blender.
This becomes problematic when a script imports classes from another module
making it difficult to manage which classes are being loaded and when.
The last 2 lines are only for testing:
The last two lines are only for testing:
.. code-block:: python
@@ -251,7 +242,6 @@ Class Registration
Registering a class with Blender results in the class definition being loaded into Blender,
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.
@@ -271,23 +261,23 @@ Using the function arguments ``def execute(self, context, spam)``, will raise an
``ValueError: expected Operator, SimpleOperator class "execute" function to have 2 args, found 3``
Using ``bl_idname = 1`` will raise.
Using ``bl_idname = 1`` will raise:
``TypeError: validating class error: Operator.bl_idname expected a string type, not int``
Inter Classes Dependencies
^^^^^^^^^^^^^^^^^^^^^^^^^^
Inter-Class Dependencies
^^^^^^^^^^^^^^^^^^^^^^^^
When customizing Blender you may want to group your own settings together,
after all, they will likely have to co-exist with other scripts.
To group these properties classes need to be defined,
for groups within groups or collections within groups
you can find yourself having to deal with order of registration/unregistration.
you can't avoid having to deal with the order of registration/unregistration.
Custom properties groups are themselves classes which need to be registered.
Say you want to store material settings for a custom engine.
For example, if you want to store material settings for a custom engine:
.. code-block:: python
@@ -311,7 +301,7 @@ Say you want to store material settings for a custom engine.
.. note::
*The class must be registered before being used in a property, failing to do so will raise an error:*
The class **must be** registered before being used in a property, failing to do so will raise an error:
``ValueError: bpy_struct "Material" registration error: my_custom_props could not register``
@@ -341,17 +331,17 @@ Say you want to store material settings for a custom engine.
if __name__ == "__main__":
register()
.. note::
.. important::
*The lower most class needs to be registered first and that unregister() is a mirror of register()*
The lower most class needs to be registered first and that ``unregister()`` is a mirror of ``register()``.
Manipulating Classes
^^^^^^^^^^^^^^^^^^^^
Properties can be added and removed as Blender runs,
normally happens on register or unregister but for some
special cases it may be useful to modify types as the script runs.
normally done on register or unregister but for some special cases
it may be useful to modify types as the script runs.
For example:
@@ -362,7 +352,7 @@ For example:
# remove
del bpy.types.Object.my_float
This works just as well for PropertyGroup subclasses you define yourself.
This works just as well for ``PropertyGroup`` subclasses you define yourself.
.. code-block:: python
@@ -370,7 +360,7 @@ This works just as well for PropertyGroup subclasses you define yourself.
pass
MyPropGroup.my_float: bpy.props.FloatProperty()
...this is equivalent to:
This is equivalent to:
.. code-block:: python
@@ -378,11 +368,11 @@ This works just as well for PropertyGroup subclasses you define yourself.
my_float: bpy.props.FloatProperty()
Dynamic Defined-Classes (Advanced)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Dynamic Class Definition (Advanced)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In some cases the specifier for data may not be in Blender, renderman shader definitions
for example, and it may be useful to define them as types and remove them on the fly.
In some cases the specifier for data may not be in Blender, for example a external render engines shader definitions,
and it may be useful to define them as types and remove them on the fly.
.. code-block:: python

View File

@@ -1,19 +1,16 @@
.. _info_quickstart:
***********************
Quickstart Introduction
***********************
**********
Quickstart
**********
Preface
=======
This :abbr:`API (Application Programming Interface)` is generally stable
but some areas are still being extended and improved.
This API is generally stable but some areas are still being added and improved.
The Blender/Python API can do the following:
.. rubric:: Blender Python API features:
- Edit any data the user interface can (Scenes, Meshes, Particles etc.).
- Modify user preferences, key-maps and themes.
- Modify user preferences, keymaps and themes.
- Run tools with own settings.
- Create user interface elements such as menus, headers and panels.
- Create new tools.
@@ -21,10 +18,10 @@ The Blender/Python API can do the following:
- Create new rendering engines that integrate with Blender.
- Subscribe to changes to data and it's properties.
- Define new settings in existing Blender data.
- Draw in the 3D view using Python.
- Draw in the 3D Viewport using Python.
The Blender/Python API **can't** (yet)...
.. rubric:: (Still) missing features:
- Create new space types.
- Assign custom properties to every type.
@@ -33,22 +30,21 @@ The Blender/Python API **can't** (yet)...
Before Starting
===============
This document isn't intended to fully cover each topic.
Rather, its purpose is to familiarize you with Blender Python API.
This document its intended to familiarize you with Blender Python API
but not to fully cover each topic.
A quick list of helpful things to know before starting:
- Blender uses Python 3.x; some online documentation still assumes 2.x.
- Blender uses Python 3.x; some online documentation still assumes version 2.x.
- The interactive console is great for testing one-liners.
It also has autocompletion so you can inspect the API quickly.
- Button tool tips show Python attributes and operator names.
- Right clicking on buttons and menu items directly links to API documentation.
- For more examples, the text menu has a templates section where some example operators can be found.
- Button tooltips show Python attributes and operator names.
- The context menu of buttons directly links to this API documentation.
- More operator examples can be found in the text editor's template menu.
- To examine further scripts distributed with Blender, see:
| ``scripts/startup/bl_ui`` for the user interface,
| ``scripts/startup/bl_operators`` for operators.
- ``scripts/startup/bl_ui`` for the user interface.
- ``scripts/startup/bl_operators`` for operators.
Exact location depends on platform, see:
:ref:`directory layout docs <blender_manual:blender-directory-layout>`.
@@ -59,19 +55,14 @@ Running Scripts
The two most common ways to execute Python scripts are using the built-in
text editor or entering commands in the Python console.
Both the *Text Editor* and *Python Console* are space types you can select from the view header.
Both the *Text Editor* and *Python Console* are space types you can select from the header.
Rather than manually configuring your spaces for Python development,
you may prefer to use the *Scripting* screen, included default with Blender,
accessible from the top headers screen selector.
you can use the *Scripting* workspace accessible from the Topbar tabs.
From the text editor you can open ``.py`` files or paste then from the clipboard, then test using *Run Script*.
The Python Console is typically used for typing in snippets and for testing to get immediate feedback,
but can also have entire scripts pasted into it.
Scripts can also run from the command line with Blender but to learn Blender/Python this isn't essential.
Scripts can also run from the command line with Blender but to learn scripting in Blender this isn't essential.
Key Concepts
@@ -80,14 +71,13 @@ Key Concepts
Data Access
-----------
Accessing DataBlocks
^^^^^^^^^^^^^^^^^^^^
Accessing Data-Blocks
^^^^^^^^^^^^^^^^^^^^^
Python accesses Blender's data in the same way as the animation system and user interface;
this implies that any setting that can be changed via a button can also be changed from Python.
Accessing data from the currently loaded blend file is done with the module :mod:`bpy.data`.
This gives access to library data. For example:
You can access Blender's data with the Python API in the same way as the animation system or user interface;
this implies that any setting that can be changed via a button can also be changed with Python.
Accessing data from the currently loaded blend-file is done with the module :mod:`bpy.data`.
It gives access to library data, for example:
>>> bpy.data.objects
<bpy_collection[3], BlendDataObjects>
@@ -99,12 +89,11 @@ This gives access to library data. For example:
<bpy_collection[1], BlendDataMaterials>
About Collections
^^^^^^^^^^^^^^^^^
Accessing Collections
^^^^^^^^^^^^^^^^^^^^^
You'll notice that an index as well as a string can be used to access members of the collection.
Unlike Python's dictionaries, both methods are acceptable;
You will notice that an index as well as a string can be used to access members of the collection.
Unlike Python dictionaries, both methods are available;
however, the index of a member may change while running Blender.
>>> list(bpy.data.objects)
@@ -120,7 +109,7 @@ however, the index of a member may change while running Blender.
Accessing Attributes
^^^^^^^^^^^^^^^^^^^^
Once you have a data block, such as a material, object, collections etc.,
Once you have a data-block, such as a material, object, collection, etc.,
its attributes can be accessed much like you would change a setting using the graphical interface.
In fact, the tooltip for each button also displays the Python attribute
which can help in finding what settings to change in a script.
@@ -135,8 +124,8 @@ which can help in finding what settings to change in a script.
bpy.data.materials['MyMaterial']
For testing what data to access it's useful to use the "Console", which is its own space type.
This supports auto-complete, giving you a fast way to dig into different data in your file.
For testing what data to access it's useful to use the Python Console, which is its own space type.
This supports auto-complete, giving you a fast way to explore the data in your file.
Example of a data path that can be quickly found via the console:
@@ -149,8 +138,8 @@ Example of a data path that can be quickly found via the console:
Data Creation/Removal
^^^^^^^^^^^^^^^^^^^^^
Those of you familiar with other Python API's may be surprised that
new data-blocks in the bpy API can't be created by calling the class:
When you are familiar with other Python APIs you may be surprised that
new data-blocks in the bpy API cannot be created by calling the class:
>>> bpy.types.Mesh()
Traceback (most recent call last):
@@ -159,10 +148,10 @@ new data-blocks in the bpy API can't be created by calling the class:
This is an intentional part of the API design.
The Blender/Python API can't create Blender data that exists outside the main Blender database
(accessed through :mod:`bpy.data`), because this data is managed by Blender (save/load/undo/append... etc).
The Blender Python API can't create Blender data that exists outside the main Blender database
(accessed through :mod:`bpy.data`), because this data is managed by Blender (save, load, undo, append, etc).
Data is added and removed via methods on the collections in :mod:`bpy.data`, eg:
Data is added and removed via methods on the collections in :mod:`bpy.data`, e.g:
>>> mesh = bpy.data.meshes.new(name="MyMesh")
>>> print(mesh)
@@ -174,14 +163,12 @@ Data is added and removed via methods on the collections in :mod:`bpy.data`, eg:
Custom Properties
^^^^^^^^^^^^^^^^^
Python can access properties on any datablock that has an ID
(data that can be linked in and accessed from :mod:`bpy.data`.
When assigning a property, you can make up your own names,
these will be created when needed or overwritten if they exist.
Python can access properties on any data-block that has an ID
(data that can be linked in and accessed from :mod:`bpy.data`).
When assigning a property, you can pick your own names,
these will be created when needed or overwritten if they already exist.
This data is saved with the blend file and copied with objects.
Example:
This data is saved with the blend-file and copied with objects, for example:
.. code-block:: python
@@ -201,10 +188,10 @@ Example:
del collection["MySettings"]
Note that these properties can only be assigned basic Python types.
Note that these properties can only be assigned basic Python types:
- int, float, string
- array of ints/floats
- array of ints or floats
- dictionary (only string keys are supported, values must be basic types too)
These properties are valid outside of Python. They can be animated by curves or used in driver paths.
@@ -218,18 +205,16 @@ it's more common to operate on the user's selection.
The context is always available from ``bpy.context`` and can be used to get the active object, scene,
tool settings along with many other attributes.
Common-use cases:
Some common use cases are:
>>> bpy.context.object
>>> bpy.context.selected_objects
>>> bpy.context.visible_bones
Note that the context is read-only.
These values cannot be modified directly,
though they may be changed by running API functions or by using the data API.
Note that the context is read-only, which means that these values cannot be modified directly.
But they can be changed by running API functions or by using the data API.
So ``bpy.context.active_object = obj`` will raise an error.
But ``bpy.context.view_layer.objects.active = obj`` works as expected.
The context attributes change depending on where they are accessed.
@@ -257,7 +242,7 @@ Examples:
.. tip::
The :ref:`Operator Cheat Sheet <blender_manual:bpy.ops.wm.operator_cheat_sheet>`.
The :ref:`Operator Cheat Sheet <blender_manual:bpy.ops.wm.operator_cheat_sheet>`
gives a list of all operators and their default values in Python syntax, along with the generated docs.
This is a good way to get an overview of all Blender's operators.
@@ -265,8 +250,8 @@ Examples:
Operator Poll()
^^^^^^^^^^^^^^^
Many operators have a "poll" function which may check that the cursor
is in a valid area or that the object is in the correct mode (Edit Mode, Weight Paint etc).
Many operators have a "poll" function which checks if the cursor
is in a valid area or if the object is in the correct mode (Edit Mode, Weight Paint Mode, etc).
When an operator's poll function fails within Python, an exception is raised.
For example, calling ``bpy.ops.view3d.render_border()`` from the console raises the following error:
@@ -275,10 +260,10 @@ For example, calling ``bpy.ops.view3d.render_border()`` from the console raises
RuntimeError: Operator bpy.ops.view3d.render_border.poll() failed, context is incorrect
In this case the context must be the 3d view with an active camera.
In this case the context must be the 3D Viewport with an active camera.
To avoid using try/except clauses wherever operators are called you can call the operators
own ``poll()`` function to check if it can run in the current context.
To avoid using try-except clauses wherever operators are called, you can call the operators
own ``poll()`` function to check if it can run the operator in the current context.
.. code-block:: python
@@ -291,11 +276,10 @@ Integration
Python scripts can integrate with Blender in the following ways:
- By defining a rendering engine.
- By defining a render engine.
- By defining operators.
- By defining menus, headers and panels.
- By inserting new buttons into existing menus, headers and panels
- By inserting new buttons into existing menus, headers and panels.
In Python, this is done by defining a class, which is a subclass of an existing type.
@@ -306,56 +290,52 @@ Example Operator
.. literalinclude:: __/__/__/release/scripts/templates_py/operator_simple.py
Once this script runs, ``SimpleOperator`` is registered with Blender
and can be called from the operator search popup or added to the toolbar.
and can be called from Operator Search or added to the toolbar.
To run the script:
#. Highlight the above code then press :kbd:`Ctrl-C` to copy it.
#. Start Blender
#. Press :kbd:`Ctrl-Right` twice to change to the Scripting layout.
#. Click the button labeled ``New`` and the confirmation pop up in order to create a new text block.
#. Press :kbd:`Ctrl-V` to paste the code into the text panel (the upper left frame).
#. Click on the button **Run Script**.
#. Start Blender and switch to the Scripting workspace.
#. Click the *New* button in the text editor to create a new text data-block.
#. Copy the code from above and paste it into the text editor.
#. Click on the *Run Script* button.
#. Move your cursor into the 3D Viewport,
open the :ref:`operator search menu <blender_manual:bpy.ops.wm.search_menu>`,
open the :ref:`Operator Search menu <blender_manual:bpy.ops.wm.search_menu>`,
and type "Simple".
#. Click on the "Simple Operator" item found in search.
.. seealso::
.. seealso:: The class members with the ``bl_`` prefix are documented in the API
reference :class:`bpy.types.Operator`
The class members with the ``bl_`` prefix are documented in the API reference :class:`bpy.types.Operator`.
.. note::
The output from the ``main`` function is sent to the terminal;
in order to see this, be sure to :ref:`use the terminal <use_the_terminal>`.
Example Panel
-------------
Panels register themselves as a class, like an operator.
Panels are registered as a class, like an operator.
Notice the extra ``bl_`` variables used to set the context they display in.
.. literalinclude:: __/__/__/release/scripts/templates_py/ui_panel_simple.py
To run the script:
#. Highlight the above code then press :kbd:`Ctrl-C` to copy it.
#. Start Blender.
#. Click on the tab for the *Scripting* workspace.
#. Click the button labeled ``New`` to create a new text block.
#. Press :kbd:`Ctrl-V` to paste the code into the text panel (the upper left frame).
#. Click on the button **Run Script**.
#. Start Blender and switch to the Scripting workspace.
#. Click the *New* button in the text editor to create a new text data-block.
#. Copy the code from above and paste it into the text editor.
#. Click on the *Run Script* button.
To view the results:
#. Select the the default cube.
#. Select the default cube.
#. Click on the Object properties icon in the buttons panel (far right; appears as a tiny cube).
#. Scroll down to see a panel named **Hello World Panel**.
#. Changing the object name also updates **Hello World Panel's** Name: field.
#. Scroll down to see a panel named "Hello World Panel".
#. Changing the object name also updates *Hello World Panel's* name: field.
Note the row distribution and the label and properties that are available through the code.
Note the row distribution and the label and properties that are defined through the code.
.. seealso:: :class:`bpy.types.Panel`
@@ -364,8 +344,7 @@ Types
=====
Blender defines a number of Python types but also uses Python native types.
Blender's Python API can be split up into 3 categories.
Blender's Python API can be split up into three categories.
Native Types
@@ -374,7 +353,7 @@ Native Types
In simple cases returning a number or a string as a custom type would be cumbersome,
so these are accessed as normal Python types.
- Blender float/int/boolean -> float/int/boolean
- Blender float, int, boolean -> float, int, boolean
- Blender enumerator -> string
>>> C.object.rotation_mode = 'AXIS_ANGLE'
@@ -393,11 +372,10 @@ so these are accessed as normal Python types.
Internal Types
--------------
Used for Blender data-blocks and collections: :class:`bpy.types.bpy_struct`
:class:`bpy.types.bpy_struct` is used for Blender data-blocks and collections.
Also for data that contains its own attributes: collections, meshes, bones, scenes, etc.
For data that contains its own attributes collections/meshes/bones/scenes... etc.
There are 2 main types that wrap Blenders data, one for data-blocks
There are two main types that wrap Blender's data, one for data-blocks
(known internally as ``bpy_struct``), another for properties.
>>> bpy.context.object
@@ -406,14 +384,13 @@ There are 2 main types that wrap Blenders data, one for data-blocks
>>> C.scene.objects
bpy.data.scenes['Scene'].objects
Note that these types reference Blender's data so modifying them is immediately visible.
Note that these types reference Blender's data so modifying them is visible immediately.
Mathutils Types
---------------
Used for vectors, quaternion, eulers, matrix and color types, accessible from :mod:`mathutils`
Accessible from :mod:`mathutils` are vectors, quaternions, Euler angles, matrix and color types.
Some attributes such as :class:`bpy.types.Object.location`,
:class:`bpy.types.PoseBone.rotation_euler` and :class:`bpy.types.Scene.cursor_location`
can be accessed as special math types which can be used together and manipulated in various useful ways.
@@ -422,14 +399,13 @@ Example of a matrix, vector multiplication:
.. code-block:: python
bpy.context.object.matrix_world * bpy.context.object.data.verts[0].co
bpy.context.object.matrix_world @ bpy.context.object.data.verts[0].co
.. note::
mathutils types keep a reference to Blender's internal data so changes can
be applied back.
Example:
.. code-block:: python
@@ -449,13 +425,11 @@ Example of a matrix, vector multiplication:
Animation
=========
There are 2 ways to add keyframes through Python.
There are two ways to add keyframes through Python.
The first is through key properties directly, which is similar to inserting a keyframe from the button as a user.
The first is through key properties directly, which is like inserting a keyframe from the button as a user.
You can also manually create the curves and keyframe data, then set the path to the property.
Here are examples of both methods.
Both examples insert a keyframe on the active object's Z axis.
Here are examples of both methods. Both insert a keyframe on the active object's Z axis.
Simple example:
@@ -467,7 +441,7 @@ Simple example:
obj.location[2] = 1.0
obj.keyframe_insert(data_path="location", frame=20.0, index=2)
Using Low-Level Functions:
Using low-level functions:
.. code-block:: python

View File

@@ -4,23 +4,22 @@ Tips and Tricks
***************
Here are various suggestions that you might find useful when writing scripts.
Some of these are just Python features that scripters may not have thought to use with Blender,
others are Blender specific.
Some of these are just Python features that you may not have thought to use with Blender,
others are Blender-specific.
.. _use_the_terminal:
Use The Terminal
Use the Terminal
================
When writing Python scripts, it's useful to have a terminal open,
this is not the built-in Python console but a terminal application which is used to start Blender.
There are 3 main uses for the terminal, these are:
The three main use cases for the terminal are:
- You can see the output of ``print()`` as your script runs, which is useful to view debug info.
- The error trace-back is printed in full to the terminal which won't always generate an error popup in
- The error traceback is printed in full to the terminal which won't always generate an report message in
Blender's user interface (depending on how the script is executed).
- If the script runs for too long or you accidentally enter an infinite loop,
:kbd:`Ctrl-C` in the terminal (:kbd:`Ctrl-Break` on Windows) will quit the script early.
@@ -28,26 +27,25 @@ There are 3 main uses for the terminal, these are:
.. note::
For Linux and macOS users this means starting the terminal first, then running Blender from within it.
On Windows the terminal can be enabled from the help menu.
On Windows the terminal can be enabled from the Help menu.
Interface Tricks
================
Access Operator Commands
------------------------
You may have noticed that the tooltip for menu items and buttons includes the ``bpy.ops.[...])`` command
You may have noticed that the tooltip for menu items and buttons includes the ``bpy.ops.[...]`` command
to run that button, a handy (hidden) feature is that you can press :kbd:`Ctrl-C` over
any menu item/button to copy this command into the clipboard.
any menu item or button to copy this command into the clipboard.
Access Data Path
----------------
To find the path from an :class:`ID` datablock to its setting isn't always so simple since it may be nested away.
To get this quickly you can right click on the setting and select select **Copy Data Path**,
To find the path from an :class:`ID` data-block to its setting isn't always so simple since it may be nested away.
To get this quickly open the context menu of the setting and select *Copy Data Path*,
if this can't be generated, only the property name is copied.
.. note::
@@ -62,11 +60,10 @@ if this can't be generated, only the property name is copied.
Show All Operators
==================
While Blender logs operators in the Info space,
this only reports operators with the ``REGISTER`` option enabeld so as not to flood the *Info* view
While Blender logs operators in the Info editor,
this only reports operators with the ``REGISTER`` option enabled so as not to flood the *Info* view
with calls to ``bpy.ops.view3d.smoothview`` and ``bpy.ops.view3d.zoom``.
However, for testing it can be useful to see **every** operator called in a terminal,
Yet for testing it can be useful to see **every** operator called in a terminal,
do this by enabling the debug option either by passing the ``--debug-wm`` argument when starting Blender
or by setting :mod:`bpy.app.debug_wm` to ``True`` while Blender is running.
@@ -74,20 +71,18 @@ or by setting :mod:`bpy.app.debug_wm` to ``True`` while Blender is running.
Use an External Editor
======================
Blenders text editor is fine for small changes and writing tests but its not full featured,
Blender's text editor is fine for small changes and writing tests but its not full featured,
for larger projects you'll probably want to use a standalone editor or Python IDE.
Editing a text file externally and having the same text open in Blender does work but isn't that optimal
so here are 2 ways you can easily use an external file from Blender.
Using the following examples you'll still need textblock in Blender to execute,
Editing a text file externally and having the same text open in Blender does work
but isn't that optimal so here are two ways you can use an external file from Blender.
Using the following examples you'll still need text data-block in Blender to execute,
but reference an external file rather than including it directly.
Executing External Scripts
--------------------------
This is the equivalent to running the script directly, referencing a scripts path from a 2 line text-block.
This is the equivalent to running the script directly, referencing a scripts path from a two line code block.
.. code-block:: python
@@ -95,7 +90,7 @@ This is the equivalent to running the script directly, referencing a scripts pat
exec(compile(open(filename).read(), filename, 'exec'))
You might want to reference a script relative to the blend file.
You might want to reference a script relative to the blend-file.
.. code-block:: python
@@ -128,9 +123,10 @@ has to call a function in the module, in this case ``main()`` but it can be any
an advantage with this is you can pass arguments to the function from this
small script which is often useful for testing different settings quickly.
The other issue with this is the script has to be in Pythons module search path.
While this is not best practice - for testing you can extend the search path,
this example adds the current blend files directory to the search path, then loads the script as a module.
The other issue with this is the script has to be in Python's module search path.
While this is not best practice -- for testing purposes you can extend the search path,
this following example adds the current blend-files directory to the search path
and then loads the script as a module.
.. code-block:: python
@@ -148,42 +144,40 @@ this example adds the current blend files directory to the search path, then loa
myscript.main()
Don't Use Blender!
==================
While developing your own scripts Blenders interface can get in the way,
manually reloading, running the scripts, opening file import etc. adds overhead.
Use Blender without it's User Interface
=======================================
While developing your own scripts Blender's interface can get in the way,
manually reloading, running the scripts, opening file import, etc. adds overhead.
For scripts that are not interactive it can end up being more efficient not to use
Blenders interface at all and instead execute the script on the command line.
Blender's interface at all and instead execute the script on the command line.
.. code-block:: sh
blender --background --python myscript.py
You might want to run this with a blend file so the script has some data to operate on.
You might want to run this with a blend-file so the script has some data to operate on.
.. code-block:: sh
blender myscene.blend --background --python myscript.py
.. note::
Depending on your setup you might have to enter the full path to the Blender executable.
Once the script is running properly in background mode, you'll want to check the output of the script,
this depends completely on the task at hand however here are some suggestions.
this depends completely on the task at hand, however, here are some suggestions:
- render the output to an image, use an image viewer and keep writing over the same image each time.
- save a new blend file, or export the file using one of Blenders exporters.
- if the results can be displayed as text - print them or write them to a file.
- Render the output to an image, use an image viewer and keep writing over the same image each time.
- Save a new blend-file, or export the file using one of Blender's exporters.
- If the results can be displayed as text then print them or write them to a file.
While this can take a little time to setup, it can be well worth the effort
to reduce the time it takes to test changes - you can even have
to reduce the time it takes to test changes. You can even have
Blender running the script every few seconds with a viewer updating the results,
so no need to leave your text editor to see changes.
@@ -200,7 +194,7 @@ but to quickly setup your own custom pipeline or writing one-off scripts this ca
Examples include:
- Run The Gimp in batch mode to execute custom scripts for advanced image processing.
- Run Gimp in batch mode to execute custom scripts for advanced image processing.
- Write out 3D models to use external mesh manipulation tools and read back in the results.
- Convert files into recognizable formats before reading.
@@ -209,15 +203,16 @@ Bundled Python & Extensions
===========================
The Blender releases distributed from blender.org include a complete Python installation on all platforms,
this has the disadvantage that any extensions you have installed in your systems Python won't be found by Blender.
this has the disadvantage that any extensions you have installed on your system's Python environment
will not be found by Blender.
There are 2 ways around this:
There are two ways to work around this:
- Remove Blender Python sub-directory, Blender will then fallback on the systems Python and use that instead.
- Remove Blender Python subdirectory, Blender will then fallback on the system's Python and use that instead.
Depending on your platform,
you may need to explicitly reference the location of your Python installation using the
``PYTHONPATH`` environment variable, eg:
you may need to explicitly reference the location of your Python installation using
the ``PYTHONPATH`` environment variable, e.g:
.. code-block:: sh
@@ -226,21 +221,21 @@ There are 2 ways around this:
.. warning::
The Python (major, minor) version must match the one that Blender comes with.
Therefor can't use Python 3.6 with Blender built to use Python 3.7.
Therefor you can't use Python 3.6 with Blender built to use Python 3.7.
- Copy or link the extensions into Blender's Python sub-directory so Blender can access them,
you could also copy the entire Python installation into Blenders sub-directory,
- Copy or link the extensions into Blender's Python subdirectory so Blender can access them,
you can also copy the entire Python installation into Blender's subdirectory,
replacing the one Blender comes with.
This works as long as the Python versions match and the paths are created in the same relative locations.
Doing this has the advantage that you can redistribute this bundle to others with Blender
including any extensions you rely on.
Drop Into a Python Interpreter in Your Script
=============================================
Insert a Python Interpreter into your Script
============================================
In the middle of a script you may want to inspect some variables,
run some function and generally dig about to see what's going on.
In the middle of a script you may want to inspect variables,
run functions and inspect the flow.
.. code-block:: python
@@ -248,7 +243,7 @@ run some function and generally dig about to see what's going on.
code.interact(local=locals())
If you want to access both global and local variables do this...
If you want to access both global and local variables run this:
.. code-block:: python
@@ -266,7 +261,7 @@ The next example is an equivalent single line version of the script above which
``code.interact`` can be added at any line in the script
and will pause the script an launch an interactive interpreter in the terminal,
and will pause the script to launch an interactive interpreter in the terminal,
when you're done you can quit the interpreter and the script will continue execution.
@@ -279,13 +274,14 @@ The IPython prompt has auto-complete and some useful features that the standard
IPython.embed()
Admittedly this highlights the lack of any Python debugging support built into Blender, but its still handy to know.
Admittedly this highlights the lack of any Python debugging support built into Blender,
but its still a handy thing to know.
Advanced
========
Blender as a module
Blender as a Module
-------------------
From a Python perspective it's nicer to have everything as an extension
@@ -293,26 +289,22 @@ which lets the Python script combine many components.
Advantages include:
- you can use external editors/IDE's with Blenders Python API and execute scripts within the IDE
- You can use external editors or IDEs with Blender's Python API and execute scripts within the IDE
(step over code, inspect variables as the script runs).
- editors/IDE's can auto complete Blender modules & variables.
- existing scripts can import Blender API's without having to run inside Blender.
- Editors or IDEs can auto-complete Blender modules and variables.
- Existing scripts can import Blender APIs without having to be run inside of Blender.
This is marked advanced because to run Blender as a Python module requires a special build option.
For instructions on building see
`Building Blender as a Python module <https://wiki.blender.org/wiki/Building_Blender/Other/BlenderAsPyModule>`_
`Building Blender as a Python module <https://wiki.blender.org/wiki/Building_Blender/Other/BlenderAsPyModule>`__.
Python Safety (Build Option)
----------------------------
Since it's possible to access data which has been removed (see Gotcha's),
this can be hard to track down the cause of crashes.
Since it's possible to access data which has been removed (see :doc:`Gotchas <info_gotcha>`),
can make it hard to track down the cause of crashes.
To raise Python exceptions on accessing freed data (rather than crashing),
enable the CMake build option ``WITH_PYTHON_SAFETY``.
This enables data tracking which makes data access about 2x slower
This enables data tracking which makes data access about two times slower
which is why the option isn't enabled in release builds.

View File

@@ -83,6 +83,8 @@ import inspect
import shutil
import logging
from textwrap import indent
from platform import platform
PLATFORM = platform().split('-')[0].lower() # 'linux', 'darwin', 'windows'
@@ -357,7 +359,7 @@ INFO_DOCS = (
("info_tips_and_tricks.rst",
"Tips and Tricks: Hints to help you while writing scripts for Blender"),
("info_gotcha.rst",
"Gotcha's: some of the problems you may come up against when writing scripts"),
"Gotcha's: some of the problems you may encounter when writing scripts"),
("change_log.rst", "List of changes since last Blender release"),
)
@@ -438,25 +440,30 @@ if ARGS.sphinx_build:
if ARGS.log:
SPHINX_BUILD_LOG = os.path.join(ARGS.output_dir, ".sphinx-build.log")
SPHINX_BUILD = ["sphinx-build",
"-w", SPHINX_BUILD_LOG,
SPHINX_IN, SPHINX_OUT]
SPHINX_BUILD = [
"sphinx-build",
"-w", SPHINX_BUILD_LOG,
SPHINX_IN, SPHINX_OUT,
]
# pdf build
if ARGS.sphinx_build_pdf:
SPHINX_OUT_PDF = os.path.join(ARGS.output_dir, "sphinx-out_pdf")
SPHINX_BUILD_PDF = ["sphinx-build",
"-b", "latex",
SPHINX_IN, SPHINX_OUT_PDF]
SPHINX_BUILD_PDF = [
"sphinx-build",
"-b", "latex",
SPHINX_IN, SPHINX_OUT_PDF,
]
SPHINX_MAKE_PDF = ["make", "-C", SPHINX_OUT_PDF]
SPHINX_MAKE_PDF_STDOUT = None
if ARGS.log:
SPHINX_BUILD_PDF_LOG = os.path.join(ARGS.output_dir, ".sphinx-build_pdf.log")
SPHINX_BUILD_PDF = ["sphinx-build", "-b", "latex",
"-w", SPHINX_BUILD_PDF_LOG,
SPHINX_IN, SPHINX_OUT_PDF]
SPHINX_BUILD_PDF = [
"sphinx-build", "-b", "latex",
"-w", SPHINX_BUILD_PDF_LOG,
SPHINX_IN, SPHINX_OUT_PDF,
]
sphinx_make_pdf_log = os.path.join(ARGS.output_dir, ".latex_make.log")
SPHINX_MAKE_PDF_STDOUT = open(sphinx_make_pdf_log, "w", encoding="utf-8")
@@ -1026,6 +1033,7 @@ context_type_map = {
"gpencil": ("GreasePencil", False),
"gpencil_data": ("GreasePencil", False),
"gpencil_data_owner": ("ID", False),
"hair": ("Hair", False),
"image_paint_object": ("Object", False),
"lattice": ("Lattice", False),
"light": ("Light", False),
@@ -1042,6 +1050,7 @@ context_type_map = {
"particle_settings": ("ParticleSettings", False),
"particle_system": ("ParticleSystem", False),
"particle_system_editable": ("ParticleSystem", False),
"pointcloud": ("PointCloud", False),
"pose_bone": ("PoseBone", False),
"pose_object": ("Object", False),
"scene": ("Scene", False),
@@ -1196,12 +1205,15 @@ def pyrna_enum2sphinx(prop, use_empty_descriptions=False):
break
if ok:
return "".join(["* ``%s`` %s.\n" %
(identifier,
", ".join(escape_rst(val) for val in (name, description) if val),
)
for identifier, name, description in prop.enum_items
])
return "".join([
"* ``%s``\n"
"%s.\n" % (
identifier,
# Account for multi-line enum descriptions, allowing this to be a block of text.
indent(", ".join(escape_rst(val) for val in (name, description) if val) or "Undocumented", " "),
)
for identifier, name, description in prop.enum_items
])
else:
return ""
@@ -1268,7 +1280,7 @@ def pyrna2sphinx(basepath):
fw(ident + ":%s%s:\n\n" % (id_name, identifier))
if prop.name or prop.description:
fw(ident + " " + ", ".join(val for val in (prop.name, prop.description) if val) + "\n\n")
fw(indent(", ".join(val for val in (prop.name, prop.description) if val), ident + " ") + "\n\n")
# special exception, can't use generic code here for enums
if enum_text:
@@ -1714,7 +1726,7 @@ class PatchedPythonDomain(PythonDomain):
# end workaround
fw("def setup(app):\n")
fw(" app.add_stylesheet('css/theme_overrides.css')\n")
fw(" app.add_css_file('css/theme_overrides.css')\n")
fw(" app.add_domain(PatchedPythonDomain, override=True)\n\n")
file.close()

View File

@@ -118,20 +118,19 @@ def main():
# III) Get Blender version info.
getver_file = os.path.join(tmp_dir, "blendver.txt")
getver_script = (
"import sys, bpy\n"
"with open(sys.argv[-1], 'w') as f:\n"
" is_release = bpy.app.version_cycle in {'rc', 'release'}\n"
" is_beta = bpy.app.version_cycle in {'beta'}\n"
" branch = bpy.app.build_branch.split()[0].decode()\n"
" f.write('%d\\n' % is_release)\n"
" f.write('%d\\n' % is_beta)\n"
" f.write('%s\\n' % branch)\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' % (bpy.app.version[0], bpy.app.version[1]))\n"
)
getver_script = (r"""import sys, bpy
with open(sys.argv[-1], 'w') as f:
is_release = bpy.app.version_cycle in {'rc', 'release'}
is_beta = bpy.app.version_cycle in {'beta'}
branch = bpy.app.build_branch.split()[0].decode()
f.write('%d\n' % is_release)
f.write('%d\n' % is_beta)
f.write('%s\n' % branch)
f.write('%d.%d\n' % (bpy.app.version[0], bpy.app.version[1]))
f.write('%d.%d\n' % (bpy.app.version[0], bpy.app.version[1])
if (is_release or is_beta) else '%s\n' % branch)
f.write('%d_%d' % (bpy.app.version[0], bpy.app.version[1]))
""")
get_ver_cmd = (args.blender, "--background", "-noaudio", "--factory-startup", "--python-exit-code", "1",
"--python-expr", getver_script, "--", getver_file)
subprocess.run(get_ver_cmd)

View File

@@ -52,7 +52,7 @@ SDLDevice::SDLDevice(DeviceSpecs specs, int buffersize) :
if(specs.channels == CHANNELS_INVALID)
specs.channels = CHANNELS_STEREO;
if(specs.format == FORMAT_INVALID)
specs.format = FORMAT_S16;
specs.format = FORMAT_FLOAT32;
if(specs.rate == RATE_INVALID)
specs.rate = RATE_48000;
@@ -61,10 +61,25 @@ SDLDevice::SDLDevice(DeviceSpecs specs, int buffersize) :
SDL_AudioSpec format, obtained;
format.freq = m_specs.rate;
if(m_specs.format == FORMAT_U8)
switch(m_specs.format)
{
case FORMAT_U8:
format.format = AUDIO_U8;
else
break;
case FORMAT_S16:
format.format = AUDIO_S16SYS;
break;
case FORMAT_S32:
format.format = AUDIO_S32SYS;
break;
case FORMAT_FLOAT32:
format.format = AUDIO_F32SYS;
break;
default:
format.format = AUDIO_F32SYS;
break;
}
format.channels = m_specs.channels;
format.samples = buffersize;
format.callback = SDLDevice::SDL_mix;
@@ -75,14 +90,25 @@ SDLDevice::SDLDevice(DeviceSpecs specs, int buffersize) :
m_specs.rate = (SampleRate)obtained.freq;
m_specs.channels = (Channels)obtained.channels;
if(obtained.format == AUDIO_U8)
m_specs.format = FORMAT_U8;
else if(obtained.format == AUDIO_S16LSB || obtained.format == AUDIO_S16MSB)
m_specs.format = FORMAT_S16;
else
switch(obtained.format)
{
case AUDIO_U8:
m_specs.format = FORMAT_U8;
break;
case AUDIO_S16SYS:
m_specs.format = FORMAT_S16;
break;
case AUDIO_S32SYS:
m_specs.format = FORMAT_S32;
break;
case AUDIO_F32SYS:
m_specs.format = FORMAT_FLOAT32;
break;
default:
SDL_CloseAudio();
AUD_THROW(DeviceException, "The sample format obtained from SDL is not supported.");
break;
}
create();

View File

@@ -37,223 +37,279 @@ set(INC_SYS
)
set(SRC
internal/ceres/array_utils.cc
internal/ceres/blas.cc
internal/ceres/block_evaluate_preparer.cc
internal/ceres/block_jacobian_writer.cc
internal/ceres/block_jacobi_preconditioner.cc
internal/ceres/block_random_access_dense_matrix.cc
internal/ceres/block_random_access_diagonal_matrix.cc
internal/ceres/block_random_access_matrix.cc
internal/ceres/block_random_access_sparse_matrix.cc
internal/ceres/block_sparse_matrix.cc
internal/ceres/block_structure.cc
internal/ceres/callbacks.cc
internal/ceres/c_api.cc
internal/ceres/cgnr_solver.cc
internal/ceres/compressed_col_sparse_matrix_utils.cc
internal/ceres/compressed_row_jacobian_writer.cc
internal/ceres/compressed_row_sparse_matrix.cc
internal/ceres/conditioned_cost_function.cc
internal/ceres/conjugate_gradients_solver.cc
internal/ceres/coordinate_descent_minimizer.cc
internal/ceres/corrector.cc
internal/ceres/covariance.cc
internal/ceres/covariance_impl.cc
internal/ceres/dense_normal_cholesky_solver.cc
internal/ceres/dense_qr_solver.cc
internal/ceres/dense_sparse_matrix.cc
internal/ceres/detect_structure.cc
internal/ceres/dogleg_strategy.cc
internal/ceres/dynamic_compressed_row_jacobian_writer.cc
internal/ceres/dynamic_compressed_row_sparse_matrix.cc
internal/ceres/evaluator.cc
internal/ceres/file.cc
internal/ceres/generated/partitioned_matrix_view_d_d_d.cc
internal/ceres/generated/schur_eliminator_d_d_d.cc
internal/ceres/gradient_checker.cc
internal/ceres/gradient_checking_cost_function.cc
internal/ceres/gradient_problem.cc
internal/ceres/gradient_problem_solver.cc
internal/ceres/implicit_schur_complement.cc
internal/ceres/is_close.cc
internal/ceres/iterative_schur_complement_solver.cc
internal/ceres/lapack.cc
internal/ceres/levenberg_marquardt_strategy.cc
internal/ceres/linear_least_squares_problems.cc
internal/ceres/linear_operator.cc
internal/ceres/linear_solver.cc
internal/ceres/line_search.cc
internal/ceres/line_search_direction.cc
internal/ceres/line_search_minimizer.cc
internal/ceres/line_search_preprocessor.cc
internal/ceres/local_parameterization.cc
internal/ceres/loss_function.cc
internal/ceres/low_rank_inverse_hessian.cc
internal/ceres/minimizer.cc
internal/ceres/normal_prior.cc
internal/ceres/parameter_block_ordering.cc
internal/ceres/partitioned_matrix_view.cc
internal/ceres/polynomial.cc
internal/ceres/preconditioner.cc
internal/ceres/preprocessor.cc
internal/ceres/problem.cc
internal/ceres/problem_impl.cc
internal/ceres/program.cc
internal/ceres/reorder_program.cc
internal/ceres/residual_block.cc
internal/ceres/residual_block_utils.cc
internal/ceres/schur_complement_solver.cc
internal/ceres/schur_eliminator.cc
internal/ceres/schur_jacobi_preconditioner.cc
internal/ceres/scratch_evaluate_preparer.cc
internal/ceres/solver.cc
internal/ceres/solver_utils.cc
internal/ceres/sparse_matrix.cc
internal/ceres/sparse_normal_cholesky_solver.cc
internal/ceres/split.cc
internal/ceres/stringprintf.cc
internal/ceres/triplet_sparse_matrix.cc
internal/ceres/trust_region_minimizer.cc
internal/ceres/trust_region_preprocessor.cc
internal/ceres/trust_region_step_evaluator.cc
internal/ceres/trust_region_strategy.cc
internal/ceres/types.cc
internal/ceres/wall_time.cc
internal/ceres/accelerate_sparse.cc
internal/ceres/array_utils.cc
internal/ceres/blas.cc
internal/ceres/block_evaluate_preparer.cc
internal/ceres/block_jacobian_writer.cc
internal/ceres/block_jacobi_preconditioner.cc
internal/ceres/block_random_access_dense_matrix.cc
internal/ceres/block_random_access_diagonal_matrix.cc
internal/ceres/block_random_access_matrix.cc
internal/ceres/block_random_access_sparse_matrix.cc
internal/ceres/block_sparse_matrix.cc
internal/ceres/block_structure.cc
internal/ceres/callbacks.cc
internal/ceres/canonical_views_clustering.cc
internal/ceres/c_api.cc
internal/ceres/cgnr_solver.cc
internal/ceres/compressed_col_sparse_matrix_utils.cc
internal/ceres/compressed_row_jacobian_writer.cc
internal/ceres/compressed_row_sparse_matrix.cc
internal/ceres/conditioned_cost_function.cc
internal/ceres/conjugate_gradients_solver.cc
internal/ceres/context.cc
internal/ceres/context_impl.cc
internal/ceres/coordinate_descent_minimizer.cc
internal/ceres/corrector.cc
internal/ceres/covariance.cc
internal/ceres/covariance_impl.cc
internal/ceres/cxsparse.cc
internal/ceres/dense_normal_cholesky_solver.cc
internal/ceres/dense_qr_solver.cc
internal/ceres/dense_sparse_matrix.cc
internal/ceres/detect_structure.cc
internal/ceres/dogleg_strategy.cc
internal/ceres/dynamic_compressed_row_jacobian_writer.cc
internal/ceres/dynamic_compressed_row_sparse_matrix.cc
internal/ceres/dynamic_sparse_normal_cholesky_solver.cc
internal/ceres/eigensparse.cc
internal/ceres/evaluator.cc
internal/ceres/file.cc
internal/ceres/float_cxsparse.cc
internal/ceres/float_suitesparse.cc
internal/ceres/function_sample.cc
internal/ceres/generated/partitioned_matrix_view_d_d_d.cc
internal/ceres/generated/schur_eliminator_d_d_d.cc
internal/ceres/gradient_checker.cc
internal/ceres/gradient_checking_cost_function.cc
internal/ceres/gradient_problem.cc
internal/ceres/gradient_problem_solver.cc
internal/ceres/implicit_schur_complement.cc
internal/ceres/inner_product_computer.cc
internal/ceres/is_close.cc
internal/ceres/iterative_refiner.cc
internal/ceres/iterative_schur_complement_solver.cc
internal/ceres/lapack.cc
internal/ceres/levenberg_marquardt_strategy.cc
internal/ceres/linear_least_squares_problems.cc
internal/ceres/linear_operator.cc
internal/ceres/linear_solver.cc
internal/ceres/line_search.cc
internal/ceres/line_search_direction.cc
internal/ceres/line_search_minimizer.cc
internal/ceres/line_search_preprocessor.cc
internal/ceres/local_parameterization.cc
internal/ceres/loss_function.cc
internal/ceres/low_rank_inverse_hessian.cc
internal/ceres/minimizer.cc
internal/ceres/normal_prior.cc
internal/ceres/parallel_for_cxx.cc
internal/ceres/parallel_for_nothreads.cc
internal/ceres/parallel_for_openmp.cc
internal/ceres/parallel_utils.cc
internal/ceres/parameter_block_ordering.cc
internal/ceres/partitioned_matrix_view.cc
internal/ceres/polynomial.cc
internal/ceres/preconditioner.cc
internal/ceres/preprocessor.cc
internal/ceres/problem.cc
internal/ceres/problem_impl.cc
internal/ceres/program.cc
internal/ceres/reorder_program.cc
internal/ceres/residual_block.cc
internal/ceres/residual_block_utils.cc
internal/ceres/schur_complement_solver.cc
internal/ceres/schur_eliminator.cc
internal/ceres/schur_jacobi_preconditioner.cc
internal/ceres/schur_templates.cc
internal/ceres/scratch_evaluate_preparer.cc
internal/ceres/single_linkage_clustering.cc
internal/ceres/solver.cc
internal/ceres/solver_utils.cc
internal/ceres/sparse_cholesky.cc
internal/ceres/sparse_matrix.cc
internal/ceres/sparse_normal_cholesky_solver.cc
internal/ceres/split.cc
internal/ceres/stringprintf.cc
internal/ceres/subset_preconditioner.cc
internal/ceres/suitesparse.cc
internal/ceres/thread_pool.cc
internal/ceres/thread_token_provider.cc
internal/ceres/triplet_sparse_matrix.cc
internal/ceres/trust_region_minimizer.cc
internal/ceres/trust_region_preprocessor.cc
internal/ceres/trust_region_step_evaluator.cc
internal/ceres/trust_region_strategy.cc
internal/ceres/types.cc
internal/ceres/visibility_based_preconditioner.cc
internal/ceres/visibility.cc
internal/ceres/wall_time.cc
include/ceres/autodiff_cost_function.h
include/ceres/autodiff_local_parameterization.h
include/ceres/c_api.h
include/ceres/ceres.h
include/ceres/conditioned_cost_function.h
include/ceres/cost_function.h
include/ceres/cost_function_to_functor.h
include/ceres/covariance.h
include/ceres/crs_matrix.h
include/ceres/dynamic_autodiff_cost_function.h
include/ceres/dynamic_cost_function_to_functor.h
include/ceres/dynamic_numeric_diff_cost_function.h
include/ceres/fpclassify.h
include/ceres/gradient_checker.h
include/ceres/gradient_problem.h
include/ceres/gradient_problem_solver.h
include/ceres/internal/autodiff.h
include/ceres/internal/disable_warnings.h
include/ceres/internal/eigen.h
include/ceres/internal/fixed_array.h
include/ceres/internal/macros.h
include/ceres/internal/manual_constructor.h
include/ceres/internal/numeric_diff.h
include/ceres/internal/port.h
include/ceres/internal/reenable_warnings.h
include/ceres/internal/scoped_ptr.h
include/ceres/internal/variadic_evaluate.h
include/ceres/iteration_callback.h
include/ceres/jet.h
include/ceres/local_parameterization.h
include/ceres/loss_function.h
include/ceres/normal_prior.h
include/ceres/numeric_diff_cost_function.h
include/ceres/numeric_diff_options.h
include/ceres/ordered_groups.h
include/ceres/problem.h
include/ceres/rotation.h
include/ceres/sized_cost_function.h
include/ceres/solver.h
include/ceres/types.h
include/ceres/version.h
internal/ceres/array_utils.h
internal/ceres/blas.h
internal/ceres/block_evaluate_preparer.h
internal/ceres/block_jacobian_writer.h
internal/ceres/block_jacobi_preconditioner.h
internal/ceres/block_random_access_dense_matrix.h
internal/ceres/block_random_access_diagonal_matrix.h
internal/ceres/block_random_access_matrix.h
internal/ceres/block_random_access_sparse_matrix.h
internal/ceres/block_sparse_matrix.h
internal/ceres/block_structure.h
internal/ceres/callbacks.h
internal/ceres/casts.h
internal/ceres/cgnr_linear_operator.h
internal/ceres/cgnr_solver.h
internal/ceres/collections_port.h
internal/ceres/compressed_col_sparse_matrix_utils.h
internal/ceres/compressed_row_jacobian_writer.h
internal/ceres/compressed_row_sparse_matrix.h
internal/ceres/conjugate_gradients_solver.h
internal/ceres/coordinate_descent_minimizer.h
internal/ceres/corrector.h
internal/ceres/covariance_impl.h
internal/ceres/cxsparse.h
internal/ceres/dense_jacobian_writer.h
internal/ceres/dense_normal_cholesky_solver.h
internal/ceres/dense_qr_solver.h
internal/ceres/dense_sparse_matrix.h
internal/ceres/detect_structure.h
internal/ceres/dogleg_strategy.h
internal/ceres/dynamic_compressed_row_finalizer.h
internal/ceres/dynamic_compressed_row_jacobian_writer.h
internal/ceres/dynamic_compressed_row_sparse_matrix.h
internal/ceres/evaluator.h
internal/ceres/execution_summary.h
internal/ceres/file.h
internal/ceres/gradient_checking_cost_function.h
internal/ceres/gradient_problem_evaluator.h
internal/ceres/graph_algorithms.h
internal/ceres/graph.h
internal/ceres/householder_vector.h
internal/ceres/implicit_schur_complement.h
internal/ceres/integral_types.h
internal/ceres/is_close.h
internal/ceres/iterative_schur_complement_solver.h
internal/ceres/lapack.h
internal/ceres/levenberg_marquardt_strategy.h
internal/ceres/linear_least_squares_problems.h
internal/ceres/linear_operator.h
internal/ceres/linear_solver.h
internal/ceres/line_search_direction.h
internal/ceres/line_search.h
internal/ceres/line_search_minimizer.h
internal/ceres/line_search_preprocessor.h
internal/ceres/low_rank_inverse_hessian.h
internal/ceres/map_util.h
internal/ceres/minimizer.h
internal/ceres/mutex.h
internal/ceres/parameter_block.h
internal/ceres/parameter_block_ordering.h
internal/ceres/partitioned_matrix_view.h
internal/ceres/partitioned_matrix_view_impl.h
internal/ceres/polynomial.h
internal/ceres/preconditioner.h
internal/ceres/preprocessor.h
internal/ceres/problem_impl.h
internal/ceres/program_evaluator.h
internal/ceres/program.h
internal/ceres/random.h
internal/ceres/reorder_program.h
internal/ceres/residual_block.h
internal/ceres/residual_block_utils.h
internal/ceres/schur_complement_solver.h
internal/ceres/schur_eliminator.h
internal/ceres/schur_eliminator_impl.h
internal/ceres/schur_jacobi_preconditioner.h
internal/ceres/scratch_evaluate_preparer.h
internal/ceres/small_blas.h
internal/ceres/solver_utils.h
internal/ceres/sparse_matrix.h
internal/ceres/sparse_normal_cholesky_solver.h
internal/ceres/split.h
internal/ceres/stl_util.h
internal/ceres/stringprintf.h
internal/ceres/suitesparse.h
internal/ceres/triplet_sparse_matrix.h
internal/ceres/trust_region_minimizer.h
internal/ceres/trust_region_preprocessor.h
internal/ceres/trust_region_step_evaluator.h
internal/ceres/trust_region_strategy.h
internal/ceres/visibility_based_preconditioner.h
internal/ceres/wall_time.h
include/ceres/autodiff_cost_function.h
include/ceres/autodiff_first_order_function.h
include/ceres/autodiff_local_parameterization.h
include/ceres/c_api.h
include/ceres/ceres.h
include/ceres/conditioned_cost_function.h
include/ceres/context.h
include/ceres/cost_function.h
include/ceres/cost_function_to_functor.h
include/ceres/covariance.h
include/ceres/crs_matrix.h
include/ceres/cubic_interpolation.h
include/ceres/dynamic_autodiff_cost_function.h
include/ceres/dynamic_cost_function.h
include/ceres/dynamic_cost_function_to_functor.h
include/ceres/dynamic_numeric_diff_cost_function.h
include/ceres/evaluation_callback.h
include/ceres/first_order_function.h
include/ceres/gradient_checker.h
include/ceres/gradient_problem.h
include/ceres/gradient_problem_solver.h
include/ceres/internal/array_selector.h
include/ceres/internal/autodiff.h
include/ceres/internal/disable_warnings.h
include/ceres/internal/eigen.h
include/ceres/internal/fixed_array.h
include/ceres/internal/householder_vector.h
include/ceres/internal/integer_sequence_algorithm.h
include/ceres/internal/line_parameterization.h
include/ceres/internal/memory.h
include/ceres/internal/numeric_diff.h
include/ceres/internal/parameter_dims.h
include/ceres/internal/port.h
include/ceres/internal/reenable_warnings.h
include/ceres/internal/variadic_evaluate.h
include/ceres/iteration_callback.h
include/ceres/jet.h
include/ceres/local_parameterization.h
include/ceres/loss_function.h
include/ceres/normal_prior.h
include/ceres/numeric_diff_cost_function.h
include/ceres/numeric_diff_options.h
include/ceres/ordered_groups.h
include/ceres/problem.h
include/ceres/rotation.h
include/ceres/sized_cost_function.h
include/ceres/solver.h
include/ceres/tiny_solver_autodiff_function.h
include/ceres/tiny_solver_cost_function_adapter.h
include/ceres/tiny_solver.h
include/ceres/types.h
include/ceres/version.h
internal/ceres/accelerate_sparse.h
internal/ceres/array_utils.h
internal/ceres/blas.h
internal/ceres/block_evaluate_preparer.h
internal/ceres/block_jacobian_writer.h
internal/ceres/block_jacobi_preconditioner.h
internal/ceres/block_random_access_dense_matrix.h
internal/ceres/block_random_access_diagonal_matrix.h
internal/ceres/block_random_access_matrix.h
internal/ceres/block_random_access_sparse_matrix.h
internal/ceres/block_sparse_matrix.h
internal/ceres/block_structure.h
internal/ceres/callbacks.h
internal/ceres/canonical_views_clustering.h
internal/ceres/casts.h
internal/ceres/cgnr_linear_operator.h
internal/ceres/cgnr_solver.h
internal/ceres/compressed_col_sparse_matrix_utils.h
internal/ceres/compressed_row_jacobian_writer.h
internal/ceres/compressed_row_sparse_matrix.h
internal/ceres/concurrent_queue.h
internal/ceres/conjugate_gradients_solver.h
internal/ceres/context_impl.h
internal/ceres/coordinate_descent_minimizer.h
internal/ceres/corrector.h
internal/ceres/covariance_impl.h
internal/ceres/cxsparse.h
internal/ceres/dense_jacobian_writer.h
internal/ceres/dense_normal_cholesky_solver.h
internal/ceres/dense_qr_solver.h
internal/ceres/dense_sparse_matrix.h
internal/ceres/detect_structure.h
internal/ceres/dogleg_strategy.h
internal/ceres/dynamic_compressed_row_finalizer.h
internal/ceres/dynamic_compressed_row_jacobian_writer.h
internal/ceres/dynamic_compressed_row_sparse_matrix.h
internal/ceres/dynamic_sparse_normal_cholesky_solver.h
internal/ceres/eigensparse.h
internal/ceres/evaluator.h
internal/ceres/execution_summary.h
internal/ceres/file.h
internal/ceres/float_cxsparse.h
internal/ceres/float_suitesparse.h
internal/ceres/function_sample.h
internal/ceres/gradient_checking_cost_function.h
internal/ceres/gradient_problem_evaluator.h
internal/ceres/graph_algorithms.h
internal/ceres/graph.h
internal/ceres/implicit_schur_complement.h
internal/ceres/inner_product_computer.h
internal/ceres/invert_psd_matrix.h
internal/ceres/is_close.h
internal/ceres/iterative_refiner.h
internal/ceres/iterative_schur_complement_solver.h
internal/ceres/lapack.h
internal/ceres/levenberg_marquardt_strategy.h
internal/ceres/linear_least_squares_problems.h
internal/ceres/linear_operator.h
internal/ceres/linear_solver.h
internal/ceres/line_search_direction.h
internal/ceres/line_search.h
internal/ceres/line_search_minimizer.h
internal/ceres/line_search_preprocessor.h
internal/ceres/low_rank_inverse_hessian.h
internal/ceres/map_util.h
internal/ceres/minimizer.h
internal/ceres/pair_hash.h
internal/ceres/parallel_for.h
internal/ceres/parallel_utils.h
internal/ceres/parameter_block.h
internal/ceres/parameter_block_ordering.h
internal/ceres/partitioned_matrix_view.h
internal/ceres/partitioned_matrix_view_impl.h
internal/ceres/polynomial.h
internal/ceres/preconditioner.h
internal/ceres/preprocessor.h
internal/ceres/problem_impl.h
internal/ceres/program_evaluator.h
internal/ceres/program.h
internal/ceres/random.h
internal/ceres/reorder_program.h
internal/ceres/residual_block.h
internal/ceres/residual_block_utils.h
internal/ceres/schur_complement_solver.h
internal/ceres/schur_eliminator.h
internal/ceres/schur_eliminator_impl.h
internal/ceres/schur_jacobi_preconditioner.h
internal/ceres/schur_templates.h
internal/ceres/scoped_thread_token.h
internal/ceres/scratch_evaluate_preparer.h
internal/ceres/single_linkage_clustering.h
internal/ceres/small_blas_generic.h
internal/ceres/small_blas.h
internal/ceres/solver_utils.h
internal/ceres/sparse_cholesky.h
internal/ceres/sparse_matrix.h
internal/ceres/sparse_normal_cholesky_solver.h
internal/ceres/split.h
internal/ceres/stl_util.h
internal/ceres/stringprintf.h
internal/ceres/subset_preconditioner.h
internal/ceres/suitesparse.h
internal/ceres/thread_pool.h
internal/ceres/thread_token_provider.h
internal/ceres/triplet_sparse_matrix.h
internal/ceres/trust_region_minimizer.h
internal/ceres/trust_region_preprocessor.h
internal/ceres/trust_region_step_evaluator.h
internal/ceres/trust_region_strategy.h
internal/ceres/visibility_based_preconditioner.h
internal/ceres/visibility.h
internal/ceres/wall_time.h
)
set(LIB
@@ -263,44 +319,48 @@ set(LIB
if(WITH_LIBMV_SCHUR_SPECIALIZATIONS)
list(APPEND SRC
internal/ceres/generated/partitioned_matrix_view_2_2_2.cc
internal/ceres/generated/partitioned_matrix_view_2_2_3.cc
internal/ceres/generated/partitioned_matrix_view_2_2_4.cc
internal/ceres/generated/partitioned_matrix_view_2_2_d.cc
internal/ceres/generated/partitioned_matrix_view_2_3_3.cc
internal/ceres/generated/partitioned_matrix_view_2_3_4.cc
internal/ceres/generated/partitioned_matrix_view_2_3_6.cc
internal/ceres/generated/partitioned_matrix_view_2_3_9.cc
internal/ceres/generated/partitioned_matrix_view_2_3_d.cc
internal/ceres/generated/partitioned_matrix_view_2_4_3.cc
internal/ceres/generated/partitioned_matrix_view_2_4_4.cc
internal/ceres/generated/partitioned_matrix_view_2_4_8.cc
internal/ceres/generated/partitioned_matrix_view_2_4_9.cc
internal/ceres/generated/partitioned_matrix_view_2_4_d.cc
internal/ceres/generated/partitioned_matrix_view_2_d_d.cc
internal/ceres/generated/partitioned_matrix_view_4_4_2.cc
internal/ceres/generated/partitioned_matrix_view_4_4_3.cc
internal/ceres/generated/partitioned_matrix_view_4_4_4.cc
internal/ceres/generated/partitioned_matrix_view_4_4_d.cc
internal/ceres/generated/schur_eliminator_2_2_2.cc
internal/ceres/generated/schur_eliminator_2_2_3.cc
internal/ceres/generated/schur_eliminator_2_2_4.cc
internal/ceres/generated/schur_eliminator_2_2_d.cc
internal/ceres/generated/schur_eliminator_2_3_3.cc
internal/ceres/generated/schur_eliminator_2_3_4.cc
internal/ceres/generated/schur_eliminator_2_3_6.cc
internal/ceres/generated/schur_eliminator_2_3_9.cc
internal/ceres/generated/schur_eliminator_2_3_d.cc
internal/ceres/generated/schur_eliminator_2_4_3.cc
internal/ceres/generated/schur_eliminator_2_4_4.cc
internal/ceres/generated/schur_eliminator_2_4_8.cc
internal/ceres/generated/schur_eliminator_2_4_9.cc
internal/ceres/generated/schur_eliminator_2_4_d.cc
internal/ceres/generated/schur_eliminator_2_d_d.cc
internal/ceres/generated/schur_eliminator_4_4_2.cc
internal/ceres/generated/schur_eliminator_4_4_3.cc
internal/ceres/generated/schur_eliminator_4_4_4.cc
internal/ceres/generated/schur_eliminator_4_4_d.cc
internal/ceres/generated/partitioned_matrix_view_2_2_2.cc
internal/ceres/generated/partitioned_matrix_view_2_2_3.cc
internal/ceres/generated/partitioned_matrix_view_2_2_4.cc
internal/ceres/generated/partitioned_matrix_view_2_2_d.cc
internal/ceres/generated/partitioned_matrix_view_2_3_3.cc
internal/ceres/generated/partitioned_matrix_view_2_3_4.cc
internal/ceres/generated/partitioned_matrix_view_2_3_6.cc
internal/ceres/generated/partitioned_matrix_view_2_3_9.cc
internal/ceres/generated/partitioned_matrix_view_2_3_d.cc
internal/ceres/generated/partitioned_matrix_view_2_4_3.cc
internal/ceres/generated/partitioned_matrix_view_2_4_4.cc
internal/ceres/generated/partitioned_matrix_view_2_4_6.cc
internal/ceres/generated/partitioned_matrix_view_2_4_8.cc
internal/ceres/generated/partitioned_matrix_view_2_4_9.cc
internal/ceres/generated/partitioned_matrix_view_2_4_d.cc
internal/ceres/generated/partitioned_matrix_view_2_d_d.cc
internal/ceres/generated/partitioned_matrix_view_3_3_3.cc
internal/ceres/generated/partitioned_matrix_view_4_4_2.cc
internal/ceres/generated/partitioned_matrix_view_4_4_3.cc
internal/ceres/generated/partitioned_matrix_view_4_4_4.cc
internal/ceres/generated/partitioned_matrix_view_4_4_d.cc
internal/ceres/generated/schur_eliminator_2_2_2.cc
internal/ceres/generated/schur_eliminator_2_2_3.cc
internal/ceres/generated/schur_eliminator_2_2_4.cc
internal/ceres/generated/schur_eliminator_2_2_d.cc
internal/ceres/generated/schur_eliminator_2_3_3.cc
internal/ceres/generated/schur_eliminator_2_3_4.cc
internal/ceres/generated/schur_eliminator_2_3_6.cc
internal/ceres/generated/schur_eliminator_2_3_9.cc
internal/ceres/generated/schur_eliminator_2_3_d.cc
internal/ceres/generated/schur_eliminator_2_4_3.cc
internal/ceres/generated/schur_eliminator_2_4_4.cc
internal/ceres/generated/schur_eliminator_2_4_6.cc
internal/ceres/generated/schur_eliminator_2_4_8.cc
internal/ceres/generated/schur_eliminator_2_4_9.cc
internal/ceres/generated/schur_eliminator_2_4_d.cc
internal/ceres/generated/schur_eliminator_2_d_d.cc
internal/ceres/generated/schur_eliminator_3_3_3.cc
internal/ceres/generated/schur_eliminator_4_4_2.cc
internal/ceres/generated/schur_eliminator_4_4_3.cc
internal/ceres/generated/schur_eliminator_4_4_4.cc
internal/ceres/generated/schur_eliminator_4_4_d.cc
)
else()
add_definitions(-DCERES_RESTRICT_SCHUR_SPECIALIZATION)
@@ -315,13 +375,9 @@ add_definitions(
-DCERES_NO_SUITESPARSE
-DCERES_NO_CXSPARSE
-DCERES_NO_LAPACK
-DCERES_NO_ACCELERATE_SPARSE
-DCERES_HAVE_RWLOCK
-DCERES_USE_CXX_THREADS
)
if(WITH_OPENMP)
add_definitions(
-DCERES_USE_OPENMP
)
endif()
blender_add_lib(extern_ceres "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")

1095
extern/ceres/ChangeLog vendored

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,6 @@ fi
repo="https://ceres-solver.googlesource.com/ceres-solver"
branch="master"
#tag="1.4.0"
tag=""
tmp=`mktemp -d`
checkout="$tmp/ceres"
@@ -157,14 +156,10 @@ add_definitions(
-DCERES_NO_SUITESPARSE
-DCERES_NO_CXSPARSE
-DCERES_NO_LAPACK
-DCERES_NO_ACCELERATE_SPARSE
-DCERES_HAVE_RWLOCK
-DCERES_USE_CXX_THREADS
)
if(WITH_OPENMP)
add_definitions(
-DCERES_USE_OPENMP
)
endif()
blender_add_lib(extern_ceres "\${SRC}" "\${INC}" "\${INC_SYS}" "\${LIB}")
EOF

View File

@@ -1,29 +1,37 @@
include/ceres/autodiff_cost_function.h
include/ceres/autodiff_first_order_function.h
include/ceres/autodiff_local_parameterization.h
include/ceres/c_api.h
include/ceres/ceres.h
include/ceres/conditioned_cost_function.h
include/ceres/context.h
include/ceres/cost_function.h
include/ceres/cost_function_to_functor.h
include/ceres/covariance.h
include/ceres/crs_matrix.h
include/ceres/cubic_interpolation.h
include/ceres/dynamic_autodiff_cost_function.h
include/ceres/dynamic_cost_function.h
include/ceres/dynamic_cost_function_to_functor.h
include/ceres/dynamic_numeric_diff_cost_function.h
include/ceres/fpclassify.h
include/ceres/evaluation_callback.h
include/ceres/first_order_function.h
include/ceres/gradient_checker.h
include/ceres/gradient_problem.h
include/ceres/gradient_problem_solver.h
include/ceres/internal/array_selector.h
include/ceres/internal/autodiff.h
include/ceres/internal/disable_warnings.h
include/ceres/internal/eigen.h
include/ceres/internal/fixed_array.h
include/ceres/internal/macros.h
include/ceres/internal/manual_constructor.h
include/ceres/internal/householder_vector.h
include/ceres/internal/integer_sequence_algorithm.h
include/ceres/internal/line_parameterization.h
include/ceres/internal/memory.h
include/ceres/internal/numeric_diff.h
include/ceres/internal/parameter_dims.h
include/ceres/internal/port.h
include/ceres/internal/reenable_warnings.h
include/ceres/internal/scoped_ptr.h
include/ceres/internal/variadic_evaluate.h
include/ceres/iteration_callback.h
include/ceres/jet.h
@@ -37,8 +45,13 @@ include/ceres/problem.h
include/ceres/rotation.h
include/ceres/sized_cost_function.h
include/ceres/solver.h
include/ceres/tiny_solver_autodiff_function.h
include/ceres/tiny_solver_cost_function_adapter.h
include/ceres/tiny_solver.h
include/ceres/types.h
include/ceres/version.h
internal/ceres/accelerate_sparse.cc
internal/ceres/accelerate_sparse.h
internal/ceres/array_utils.cc
internal/ceres/array_utils.h
internal/ceres/blas.cc
@@ -63,21 +76,26 @@ internal/ceres/block_structure.cc
internal/ceres/block_structure.h
internal/ceres/callbacks.cc
internal/ceres/callbacks.h
internal/ceres/canonical_views_clustering.cc
internal/ceres/canonical_views_clustering.h
internal/ceres/c_api.cc
internal/ceres/casts.h
internal/ceres/cgnr_linear_operator.h
internal/ceres/cgnr_solver.cc
internal/ceres/cgnr_solver.h
internal/ceres/collections_port.h
internal/ceres/compressed_col_sparse_matrix_utils.cc
internal/ceres/compressed_col_sparse_matrix_utils.h
internal/ceres/compressed_row_jacobian_writer.cc
internal/ceres/compressed_row_jacobian_writer.h
internal/ceres/compressed_row_sparse_matrix.cc
internal/ceres/compressed_row_sparse_matrix.h
internal/ceres/concurrent_queue.h
internal/ceres/conditioned_cost_function.cc
internal/ceres/conjugate_gradients_solver.cc
internal/ceres/conjugate_gradients_solver.h
internal/ceres/context.cc
internal/ceres/context_impl.cc
internal/ceres/context_impl.h
internal/ceres/coordinate_descent_minimizer.cc
internal/ceres/coordinate_descent_minimizer.h
internal/ceres/corrector.cc
@@ -85,6 +103,7 @@ internal/ceres/corrector.h
internal/ceres/covariance.cc
internal/ceres/covariance_impl.cc
internal/ceres/covariance_impl.h
internal/ceres/cxsparse.cc
internal/ceres/cxsparse.h
internal/ceres/dense_jacobian_writer.h
internal/ceres/dense_normal_cholesky_solver.cc
@@ -102,11 +121,21 @@ internal/ceres/dynamic_compressed_row_jacobian_writer.cc
internal/ceres/dynamic_compressed_row_jacobian_writer.h
internal/ceres/dynamic_compressed_row_sparse_matrix.cc
internal/ceres/dynamic_compressed_row_sparse_matrix.h
internal/ceres/dynamic_sparse_normal_cholesky_solver.cc
internal/ceres/dynamic_sparse_normal_cholesky_solver.h
internal/ceres/eigensparse.cc
internal/ceres/eigensparse.h
internal/ceres/evaluator.cc
internal/ceres/evaluator.h
internal/ceres/execution_summary.h
internal/ceres/file.cc
internal/ceres/file.h
internal/ceres/float_cxsparse.cc
internal/ceres/float_cxsparse.h
internal/ceres/float_suitesparse.cc
internal/ceres/float_suitesparse.h
internal/ceres/function_sample.cc
internal/ceres/function_sample.h
internal/ceres/generated/partitioned_matrix_view_2_2_2.cc
internal/ceres/generated/partitioned_matrix_view_2_2_3.cc
internal/ceres/generated/partitioned_matrix_view_2_2_4.cc
@@ -118,10 +147,12 @@ internal/ceres/generated/partitioned_matrix_view_2_3_9.cc
internal/ceres/generated/partitioned_matrix_view_2_3_d.cc
internal/ceres/generated/partitioned_matrix_view_2_4_3.cc
internal/ceres/generated/partitioned_matrix_view_2_4_4.cc
internal/ceres/generated/partitioned_matrix_view_2_4_6.cc
internal/ceres/generated/partitioned_matrix_view_2_4_8.cc
internal/ceres/generated/partitioned_matrix_view_2_4_9.cc
internal/ceres/generated/partitioned_matrix_view_2_4_d.cc
internal/ceres/generated/partitioned_matrix_view_2_d_d.cc
internal/ceres/generated/partitioned_matrix_view_3_3_3.cc
internal/ceres/generated/partitioned_matrix_view_4_4_2.cc
internal/ceres/generated/partitioned_matrix_view_4_4_3.cc
internal/ceres/generated/partitioned_matrix_view_4_4_4.cc
@@ -138,17 +169,18 @@ internal/ceres/generated/schur_eliminator_2_3_9.cc
internal/ceres/generated/schur_eliminator_2_3_d.cc
internal/ceres/generated/schur_eliminator_2_4_3.cc
internal/ceres/generated/schur_eliminator_2_4_4.cc
internal/ceres/generated/schur_eliminator_2_4_6.cc
internal/ceres/generated/schur_eliminator_2_4_8.cc
internal/ceres/generated/schur_eliminator_2_4_9.cc
internal/ceres/generated/schur_eliminator_2_4_d.cc
internal/ceres/generated/schur_eliminator_2_d_d.cc
internal/ceres/generated/schur_eliminator_3_3_3.cc
internal/ceres/generated/schur_eliminator_4_4_2.cc
internal/ceres/generated/schur_eliminator_4_4_3.cc
internal/ceres/generated/schur_eliminator_4_4_4.cc
internal/ceres/generated/schur_eliminator_4_4_d.cc
internal/ceres/generated/schur_eliminator_d_d_d.cc
internal/ceres/generate_eliminator_specialization.py
internal/ceres/generate_partitioned_matrix_view_specializations.py
internal/ceres/generate_template_specializations.py
internal/ceres/gradient_checker.cc
internal/ceres/gradient_checking_cost_function.cc
internal/ceres/gradient_checking_cost_function.h
@@ -157,12 +189,15 @@ internal/ceres/gradient_problem_evaluator.h
internal/ceres/gradient_problem_solver.cc
internal/ceres/graph_algorithms.h
internal/ceres/graph.h
internal/ceres/householder_vector.h
internal/ceres/implicit_schur_complement.cc
internal/ceres/implicit_schur_complement.h
internal/ceres/integral_types.h
internal/ceres/inner_product_computer.cc
internal/ceres/inner_product_computer.h
internal/ceres/invert_psd_matrix.h
internal/ceres/is_close.cc
internal/ceres/is_close.h
internal/ceres/iterative_refiner.cc
internal/ceres/iterative_refiner.h
internal/ceres/iterative_schur_complement_solver.cc
internal/ceres/iterative_schur_complement_solver.h
internal/ceres/lapack.cc
@@ -190,14 +225,21 @@ internal/ceres/low_rank_inverse_hessian.h
internal/ceres/map_util.h
internal/ceres/minimizer.cc
internal/ceres/minimizer.h
internal/ceres/mutex.h
internal/ceres/normal_prior.cc
internal/ceres/pair_hash.h
internal/ceres/parallel_for_cxx.cc
internal/ceres/parallel_for.h
internal/ceres/parallel_for_nothreads.cc
internal/ceres/parallel_for_openmp.cc
internal/ceres/parallel_utils.cc
internal/ceres/parallel_utils.h
internal/ceres/parameter_block.h
internal/ceres/parameter_block_ordering.cc
internal/ceres/parameter_block_ordering.h
internal/ceres/partitioned_matrix_view.cc
internal/ceres/partitioned_matrix_view.h
internal/ceres/partitioned_matrix_view_impl.h
internal/ceres/partitioned_matrix_view_template.py
internal/ceres/polynomial.cc
internal/ceres/polynomial.h
internal/ceres/preconditioner.cc
@@ -222,14 +264,23 @@ internal/ceres/schur_complement_solver.h
internal/ceres/schur_eliminator.cc
internal/ceres/schur_eliminator.h
internal/ceres/schur_eliminator_impl.h
internal/ceres/schur_eliminator_template.py
internal/ceres/schur_jacobi_preconditioner.cc
internal/ceres/schur_jacobi_preconditioner.h
internal/ceres/schur_templates.cc
internal/ceres/schur_templates.h
internal/ceres/scoped_thread_token.h
internal/ceres/scratch_evaluate_preparer.cc
internal/ceres/scratch_evaluate_preparer.h
internal/ceres/single_linkage_clustering.cc
internal/ceres/single_linkage_clustering.h
internal/ceres/small_blas_generic.h
internal/ceres/small_blas.h
internal/ceres/solver.cc
internal/ceres/solver_utils.cc
internal/ceres/solver_utils.h
internal/ceres/sparse_cholesky.cc
internal/ceres/sparse_cholesky.h
internal/ceres/sparse_matrix.cc
internal/ceres/sparse_matrix.h
internal/ceres/sparse_normal_cholesky_solver.cc
@@ -239,7 +290,14 @@ internal/ceres/split.h
internal/ceres/stl_util.h
internal/ceres/stringprintf.cc
internal/ceres/stringprintf.h
internal/ceres/subset_preconditioner.cc
internal/ceres/subset_preconditioner.h
internal/ceres/suitesparse.cc
internal/ceres/suitesparse.h
internal/ceres/thread_pool.cc
internal/ceres/thread_pool.h
internal/ceres/thread_token_provider.cc
internal/ceres/thread_token_provider.h
internal/ceres/triplet_sparse_matrix.cc
internal/ceres/triplet_sparse_matrix.h
internal/ceres/trust_region_minimizer.cc
@@ -251,7 +309,10 @@ internal/ceres/trust_region_step_evaluator.h
internal/ceres/trust_region_strategy.cc
internal/ceres/trust_region_strategy.h
internal/ceres/types.cc
internal/ceres/visibility_based_preconditioner.cc
internal/ceres/visibility_based_preconditioner.h
internal/ceres/visibility.cc
internal/ceres/visibility.h
internal/ceres/wall_time.cc
internal/ceres/wall_time.h
config/ceres/internal/config.h

View File

@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2015 Google Inc. All rights reserved.
// Copyright 2019 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
//
// Create CostFunctions as needed by the least squares framework, with
// Jacobians computed via automatic differentiation. For more
// information on automatic differentation, see the wikipedia article
// information on automatic differentiation, see the wikipedia article
// at http://en.wikipedia.org/wiki/Automatic_differentiation
//
// To get an auto differentiated cost function, you must define a class with a
@@ -54,7 +54,7 @@
// for a series of measurements, where there is an instance of the cost function
// for each measurement k.
//
// The actual cost added to the total problem is e^2, or (k - x'k)^2; however,
// The actual cost added to the total problem is e^2, or (k - x'y)^2; however,
// the squaring is implicitly done by the optimization framework.
//
// To write an auto-differentiable cost function for the above model, first
@@ -90,7 +90,7 @@
// Dimension of x ---------------+ |
// Dimension of y ------------------+
//
// In this example, there is usually an instance for each measumerent of k.
// In this example, there is usually an instance for each measurement of k.
//
// In the instantiation above, the template parameters following
// "MyScalarCostFunctor", "1, 2, 2", describe the functor as computing a
@@ -110,12 +110,8 @@
// Dimension of x ------------------------------------+ |
// Dimension of y ---------------------------------------+
//
// The framework can currently accommodate cost functions of up to 10
// independent variables, and there is no limit on the dimensionality
// of each of them.
//
// WARNING #1: Since the functor will get instantiated with different types for
// T, you must to convert from other numeric types to T before mixing
// T, you must convert from other numeric types to T before mixing
// computations with other variables of type T. In the example above, this is
// seen where instead of using k_ directly, k_ is wrapped with T(k_).
//
@@ -129,8 +125,9 @@
#ifndef CERES_PUBLIC_AUTODIFF_COST_FUNCTION_H_
#define CERES_PUBLIC_AUTODIFF_COST_FUNCTION_H_
#include <memory>
#include "ceres/internal/autodiff.h"
#include "ceres/internal/scoped_ptr.h"
#include "ceres/sized_cost_function.h"
#include "ceres/types.h"
#include "glog/logging.h"
@@ -138,7 +135,7 @@
namespace ceres {
// A cost function which computes the derivative of the cost with respect to
// the parameters (a.k.a. the jacobian) using an autodifferentiation framework.
// the parameters (a.k.a. the jacobian) using an auto differentiation framework.
// The first template argument is the functor object, described in the header
// comment. The second argument is the dimension of the residual (or
// ceres::DYNAMIC to indicate it will be set at runtime), and subsequent
@@ -153,27 +150,15 @@ namespace ceres {
// of residuals for a single autodiff cost function at runtime.
template <typename CostFunctor,
int kNumResiduals, // Number of residuals, or ceres::DYNAMIC.
int N0, // Number of parameters in block 0.
int N1 = 0, // Number of parameters in block 1.
int N2 = 0, // Number of parameters in block 2.
int N3 = 0, // Number of parameters in block 3.
int N4 = 0, // Number of parameters in block 4.
int N5 = 0, // Number of parameters in block 5.
int N6 = 0, // Number of parameters in block 6.
int N7 = 0, // Number of parameters in block 7.
int N8 = 0, // Number of parameters in block 8.
int N9 = 0> // Number of parameters in block 9.
class AutoDiffCostFunction : public SizedCostFunction<kNumResiduals,
N0, N1, N2, N3, N4,
N5, N6, N7, N8, N9> {
int... Ns> // Number of parameters in each parameter block.
class AutoDiffCostFunction : public SizedCostFunction<kNumResiduals, Ns...> {
public:
// Takes ownership of functor. Uses the template-provided value for the
// number of residuals ("kNumResiduals").
explicit AutoDiffCostFunction(CostFunctor* functor)
: functor_(functor) {
CHECK_NE(kNumResiduals, DYNAMIC)
<< "Can't run the fixed-size constructor if the "
<< "number of residuals is set to ceres::DYNAMIC.";
explicit AutoDiffCostFunction(CostFunctor* functor) : functor_(functor) {
static_assert(kNumResiduals != DYNAMIC,
"Can't run the fixed-size constructor if the number of "
"residuals is set to ceres::DYNAMIC.");
}
// Takes ownership of functor. Ignores the template-provided
@@ -183,13 +168,10 @@ class AutoDiffCostFunction : public SizedCostFunction<kNumResiduals,
// numbers of residuals at runtime.
AutoDiffCostFunction(CostFunctor* functor, int num_residuals)
: functor_(functor) {
CHECK_EQ(kNumResiduals, DYNAMIC)
<< "Can't run the dynamic-size constructor if the "
<< "number of residuals is not ceres::DYNAMIC.";
SizedCostFunction<kNumResiduals,
N0, N1, N2, N3, N4,
N5, N6, N7, N8, N9>
::set_num_residuals(num_residuals);
static_assert(kNumResiduals == DYNAMIC,
"Can't run the dynamic-size constructor if the number of "
"residuals is not ceres::DYNAMIC.");
SizedCostFunction<kNumResiduals, Ns...>::set_num_residuals(num_residuals);
}
virtual ~AutoDiffCostFunction() {}
@@ -197,29 +179,28 @@ class AutoDiffCostFunction : public SizedCostFunction<kNumResiduals,
// Implementation details follow; clients of the autodiff cost function should
// not have to examine below here.
//
// To handle varardic cost functions, some template magic is needed. It's
// To handle variadic cost functions, some template magic is needed. It's
// mostly hidden inside autodiff.h.
virtual bool Evaluate(double const* const* parameters,
double* residuals,
double** jacobians) const {
bool Evaluate(double const* const* parameters,
double* residuals,
double** jacobians) const override {
using ParameterDims =
typename SizedCostFunction<kNumResiduals, Ns...>::ParameterDims;
if (!jacobians) {
return internal::VariadicEvaluate<
CostFunctor, double, N0, N1, N2, N3, N4, N5, N6, N7, N8, N9>
::Call(*functor_, parameters, residuals);
return internal::VariadicEvaluate<ParameterDims>(
*functor_, parameters, residuals);
}
return internal::AutoDiff<CostFunctor, double,
N0, N1, N2, N3, N4, N5, N6, N7, N8, N9>::Differentiate(
*functor_,
parameters,
SizedCostFunction<kNumResiduals,
N0, N1, N2, N3, N4,
N5, N6, N7, N8, N9>::num_residuals(),
residuals,
jacobians);
}
return internal::AutoDifferentiate<kNumResiduals, ParameterDims>(
*functor_,
parameters,
SizedCostFunction<kNumResiduals, Ns...>::num_residuals(),
residuals,
jacobians);
};
private:
internal::scoped_ptr<CostFunctor> functor_;
std::unique_ptr<CostFunctor> functor_;
};
} // namespace ceres

View File

@@ -0,0 +1,151 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2019 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// 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 name of Google Inc. 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 OWNER 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.
//
// Author: sameeragarwal@google.com (Sameer Agarwal)
#ifndef CERES_PUBLIC_AUTODIFF_FIRST_ORDER_FUNCTION_H_
#define CERES_PUBLIC_AUTODIFF_FIRST_ORDER_FUNCTION_H_
#include <memory>
#include "ceres/first_order_function.h"
#include "ceres/internal/eigen.h"
#include "ceres/internal/fixed_array.h"
#include "ceres/jet.h"
#include "ceres/types.h"
namespace ceres {
// Create FirstOrderFunctions as needed by the GradientProblem
// framework, with gradients computed via automatic
// differentiation. For more information on automatic differentiation,
// see the wikipedia article at
// http://en.wikipedia.org/wiki/Automatic_differentiation
//
// To get an auto differentiated function, you must define a class
// with a templated operator() (a functor) that computes the cost
// function in terms of the template parameter T. The autodiff
// framework substitutes appropriate "jet" objects for T in order to
// compute the derivative when necessary, but this is hidden, and you
// should write the function as if T were a scalar type (e.g. a
// double-precision floating point number).
//
// The function must write the computed value in the last argument
// (the only non-const one) and return true to indicate
// success.
//
// For example, consider a scalar error e = x'y - a, where both x and y are
// two-dimensional column vector parameters, the prime sign indicates
// transposition, and a is a constant.
//
// To write an auto-differentiable FirstOrderFunction for the above model, first
// define the object
//
// class QuadraticCostFunctor {
// public:
// explicit QuadraticCostFunctor(double a) : a_(a) {}
// template <typename T>
// bool operator()(const T* const xy, T* cost) const {
// const T* const x = xy;
// const T* const y = xy + 2;
// *cost = x[0] * y[0] + x[1] * y[1] - T(a_);
// return true;
// }
//
// private:
// double a_;
// };
//
// Note that in the declaration of operator() the input parameters xy come
// first, and are passed as const pointers to arrays of T. The
// output is the last parameter.
//
// Then given this class definition, the auto differentiated FirstOrderFunction
// for it can be constructed as follows.
//
// FirstOrderFunction* function =
// new AutoDiffFirstOrderFunction<QuadraticCostFunctor, 4>(
// new QuadraticCostFunctor(1.0)));
//
// In the instantiation above, the template parameters following
// "QuadraticCostFunctor", "4", describe the functor as computing a
// 1-dimensional output from a four dimensional vector.
//
// WARNING: Since the functor will get instantiated with different types for
// T, you must convert from other numeric types to T before mixing
// computations with other variables of type T. In the example above, this is
// seen where instead of using a_ directly, a_ is wrapped with T(a_).
template <typename FirstOrderFunctor, int kNumParameters>
class AutoDiffFirstOrderFunction : public FirstOrderFunction {
public:
// Takes ownership of functor.
explicit AutoDiffFirstOrderFunction(FirstOrderFunctor* functor)
: functor_(functor) {
static_assert(kNumParameters > 0, "kNumParameters must be positive");
}
virtual ~AutoDiffFirstOrderFunction() {}
bool Evaluate(const double* const parameters,
double* cost,
double* gradient) const override {
if (gradient == nullptr) {
return (*functor_)(parameters, cost);
}
typedef Jet<double, kNumParameters> JetT;
internal::FixedArray<JetT, (256 * 7) / sizeof(JetT)> x(kNumParameters);
for (int i = 0; i < kNumParameters; ++i) {
x[i].a = parameters[i];
x[i].v.setZero();
x[i].v[i] = 1.0;
}
JetT output;
output.a = kImpossibleValue;
output.v.setConstant(kImpossibleValue);
if (!(*functor_)(x.data(), &output)) {
return false;
}
*cost = output.a;
VectorRef(gradient, kNumParameters) = output.v;
return true;
}
int NumParameters() const override { return kNumParameters; }
private:
std::unique_ptr<FirstOrderFunctor> functor_;
};
} // namespace ceres
#endif // CERES_PUBLIC_AUTODIFF_FIRST_ORDER_FUNCTION_H_

View File

@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2015 Google Inc. All rights reserved.
// Copyright 2019 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// Redistribution and use in source and binary forms, with or without
@@ -33,9 +33,10 @@
#ifndef CERES_PUBLIC_AUTODIFF_LOCAL_PARAMETERIZATION_H_
#define CERES_PUBLIC_AUTODIFF_LOCAL_PARAMETERIZATION_H_
#include "ceres/local_parameterization.h"
#include <memory>
#include "ceres/internal/autodiff.h"
#include "ceres/internal/scoped_ptr.h"
#include "ceres/local_parameterization.h"
namespace ceres {
@@ -107,21 +108,20 @@ namespace ceres {
template <typename Functor, int kGlobalSize, int kLocalSize>
class AutoDiffLocalParameterization : public LocalParameterization {
public:
AutoDiffLocalParameterization() :
functor_(new Functor()) {}
AutoDiffLocalParameterization() : functor_(new Functor()) {}
// Takes ownership of functor.
explicit AutoDiffLocalParameterization(Functor* functor) :
functor_(functor) {}
explicit AutoDiffLocalParameterization(Functor* functor)
: functor_(functor) {}
virtual ~AutoDiffLocalParameterization() {}
virtual bool Plus(const double* x,
const double* delta,
double* x_plus_delta) const {
bool Plus(const double* x,
const double* delta,
double* x_plus_delta) const override {
return (*functor_)(x, delta, x_plus_delta);
}
virtual bool ComputeJacobian(const double* x, double* jacobian) const {
bool ComputeJacobian(const double* x, double* jacobian) const override {
double zero_delta[kLocalSize];
for (int i = 0; i < kLocalSize; ++i) {
zero_delta[i] = 0.0;
@@ -133,20 +133,18 @@ class AutoDiffLocalParameterization : public LocalParameterization {
}
const double* parameter_ptrs[2] = {x, zero_delta};
double* jacobian_ptrs[2] = { NULL, jacobian };
return internal::AutoDiff<Functor, double, kGlobalSize, kLocalSize>
::Differentiate(*functor_,
parameter_ptrs,
kGlobalSize,
x_plus_delta,
jacobian_ptrs);
double* jacobian_ptrs[2] = {NULL, jacobian};
return internal::AutoDifferentiate<
kGlobalSize,
internal::StaticParameterDims<kGlobalSize, kLocalSize>>(
*functor_, parameter_ptrs, kGlobalSize, x_plus_delta, jacobian_ptrs);
}
virtual int GlobalSize() const { return kGlobalSize; }
virtual int LocalSize() const { return kLocalSize; }
int GlobalSize() const override { return kGlobalSize; }
int LocalSize() const override { return kLocalSize; }
private:
internal::scoped_ptr<Functor> functor_;
std::unique_ptr<Functor> functor_;
};
} // namespace ceres

View File

@@ -1,5 +1,5 @@
/* Ceres Solver - A fast non-linear least squares minimizer
* Copyright 2015 Google Inc. All rights reserved.
* Copyright 2019 Google Inc. All rights reserved.
* http://ceres-solver.org/
*
* Redistribution and use in source and binary forms, with or without
@@ -143,4 +143,4 @@ CERES_EXPORT void ceres_solve(ceres_problem_t* problem);
#include "ceres/internal/reenable_warnings.h"
#endif /* CERES_PUBLIC_C_API_H_ */
#endif /* CERES_PUBLIC_C_API_H_ */

View File

@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2015 Google Inc. All rights reserved.
// Copyright 2019 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// Redistribution and use in source and binary forms, with or without
@@ -36,12 +36,18 @@
#include "ceres/autodiff_cost_function.h"
#include "ceres/autodiff_local_parameterization.h"
#include "ceres/conditioned_cost_function.h"
#include "ceres/context.h"
#include "ceres/cost_function.h"
#include "ceres/cost_function_to_functor.h"
#include "ceres/covariance.h"
#include "ceres/crs_matrix.h"
#include "ceres/dynamic_autodiff_cost_function.h"
#include "ceres/dynamic_cost_function.h"
#include "ceres/dynamic_cost_function_to_functor.h"
#include "ceres/dynamic_numeric_diff_cost_function.h"
#include "ceres/evaluation_callback.h"
#include "ceres/gradient_checker.h"
#include "ceres/gradient_problem.h"
#include "ceres/gradient_problem_solver.h"
#include "ceres/iteration_callback.h"
@@ -49,6 +55,7 @@
#include "ceres/local_parameterization.h"
#include "ceres/loss_function.h"
#include "ceres/numeric_diff_cost_function.h"
#include "ceres/numeric_diff_options.h"
#include "ceres/ordered_groups.h"
#include "ceres/problem.h"
#include "ceres/sized_cost_function.h"

View File

@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2015 Google Inc. All rights reserved.
// Copyright 2019 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// Redistribution and use in source and binary forms, with or without
@@ -34,12 +34,12 @@
#ifndef CERES_PUBLIC_CONDITIONED_COST_FUNCTION_H_
#define CERES_PUBLIC_CONDITIONED_COST_FUNCTION_H_
#include <memory>
#include <vector>
#include "ceres/cost_function.h"
#include "ceres/internal/scoped_ptr.h"
#include "ceres/types.h"
#include "ceres/internal/disable_warnings.h"
#include "ceres/types.h"
namespace ceres {
@@ -77,17 +77,19 @@ class CERES_EXPORT ConditionedCostFunction : public CostFunction {
// per-residual conditioner. Takes ownership of all of the wrapped cost
// functions, or not, depending on the ownership parameter. Conditioners
// may be NULL, in which case the corresponding residual is not modified.
//
// The conditioners can repeat.
ConditionedCostFunction(CostFunction* wrapped_cost_function,
const std::vector<CostFunction*>& conditioners,
Ownership ownership);
virtual ~ConditionedCostFunction();
virtual bool Evaluate(double const* const* parameters,
double* residuals,
double** jacobians) const;
bool Evaluate(double const* const* parameters,
double* residuals,
double** jacobians) const override;
private:
internal::scoped_ptr<CostFunction> wrapped_cost_function_;
std::unique_ptr<CostFunction> wrapped_cost_function_;
std::vector<CostFunction*> conditioners_;
Ownership ownership_;
};

56
extern/ceres/include/ceres/context.h vendored Normal file
View File

@@ -0,0 +1,56 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2019 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// 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 name of Google Inc. 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 OWNER 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.
//
// Author: vitus@google.com (Michael Vitus)
#ifndef CERES_PUBLIC_CONTEXT_H_
#define CERES_PUBLIC_CONTEXT_H_
namespace ceres {
// A global context for processing data in Ceres. This provides a mechanism to
// allow Ceres to reuse items that are expensive to create between multiple
// calls; for example, thread pools. The same Context can be used on multiple
// Problems, either serially or in parallel. When using it with multiple
// Problems at the same time, they may end up contending for resources
// (e.g. threads) managed by the Context.
class Context {
public:
Context() {}
Context(const Context&) = delete;
void operator=(const Context&) = delete;
virtual ~Context() {}
// Creates a context object and the caller takes ownership.
static Context* Create();
};
} // namespace ceres
#endif // CERES_PUBLIC_CONTEXT_H_

View File

@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2015 Google Inc. All rights reserved.
// Copyright 2019 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// Redistribution and use in source and binary forms, with or without
@@ -44,18 +44,18 @@
#ifndef CERES_PUBLIC_COST_FUNCTION_H_
#define CERES_PUBLIC_COST_FUNCTION_H_
#include <cstdint>
#include <vector>
#include "ceres/internal/macros.h"
#include "ceres/internal/port.h"
#include "ceres/types.h"
#include "ceres/internal/disable_warnings.h"
#include "ceres/internal/port.h"
namespace ceres {
// This class implements the computation of the cost (a.k.a. residual) terms as
// a function of the input (control) variables, and is the interface for users
// to describe their least squares problem to Ceres. In other words, this is the
// modelling layer between users and the Ceres optimizer. The signature of the
// modeling layer between users and the Ceres optimizer. The signature of the
// function (number and sizes of input parameter blocks and number of outputs)
// is stored in parameter_block_sizes_ and num_residuals_ respectively. User
// code inheriting from this class is expected to set these two members with the
@@ -64,6 +64,8 @@ namespace ceres {
class CERES_EXPORT CostFunction {
public:
CostFunction() : num_residuals_(0) {}
CostFunction(const CostFunction&) = delete;
void operator=(const CostFunction&) = delete;
virtual ~CostFunction() {}
@@ -115,29 +117,24 @@ class CERES_EXPORT CostFunction {
double* residuals,
double** jacobians) const = 0;
const std::vector<int32>& parameter_block_sizes() const {
const std::vector<int32_t>& parameter_block_sizes() const {
return parameter_block_sizes_;
}
int num_residuals() const {
return num_residuals_;
}
int num_residuals() const { return num_residuals_; }
protected:
std::vector<int32>* mutable_parameter_block_sizes() {
std::vector<int32_t>* mutable_parameter_block_sizes() {
return &parameter_block_sizes_;
}
void set_num_residuals(int num_residuals) {
num_residuals_ = num_residuals;
}
void set_num_residuals(int num_residuals) { num_residuals_ = num_residuals; }
private:
// Cost function signature metadata: number of inputs & their sizes,
// number of outputs (residuals).
std::vector<int32> parameter_block_sizes_;
std::vector<int32_t> parameter_block_sizes_;
int num_residuals_;
CERES_DISALLOW_COPY_AND_ASSIGN(CostFunction);
};
} // namespace ceres

View File

@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2015 Google Inc. All rights reserved.
// Copyright 2019 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
//
// CostFunctionToFunctor is an adapter class that allows users to use
// SizedCostFunction objects in templated functors which are to be used for
// automatic differentiation. This allows the user to seamlessly mix
// automatic differentiation. This allows the user to seamlessly mix
// analytic, numeric and automatic differentiation.
//
// For example, let us assume that
@@ -38,16 +38,15 @@
// class IntrinsicProjection : public SizedCostFunction<2, 5, 3> {
// public:
// IntrinsicProjection(const double* observation);
// virtual bool Evaluate(double const* const* parameters,
// double* residuals,
// double** jacobians) const;
// bool Evaluate(double const* const* parameters,
// double* residuals,
// double** jacobians) const override;
// };
//
// is a cost function that implements the projection of a point in its
// local coordinate system onto its image plane and subtracts it from
// the observed point projection. It can compute its residual and
// either via analytic or numerical differentiation can compute its
// jacobians.
// jacobians either via analytic or numerical differentiation.
//
// Now we would like to compose the action of this CostFunction with
// the action of camera extrinsics, i.e., rotation and
@@ -87,594 +86,83 @@
#ifndef CERES_PUBLIC_COST_FUNCTION_TO_FUNCTOR_H_
#define CERES_PUBLIC_COST_FUNCTION_TO_FUNCTOR_H_
#include <cstdint>
#include <numeric>
#include <tuple>
#include <utility>
#include <vector>
#include "ceres/cost_function.h"
#include "ceres/dynamic_cost_function_to_functor.h"
#include "ceres/internal/fixed_array.h"
#include "ceres/internal/parameter_dims.h"
#include "ceres/internal/port.h"
#include "ceres/internal/scoped_ptr.h"
#include "ceres/types.h"
namespace ceres {
template <int kNumResiduals,
int N0, int N1 = 0, int N2 = 0, int N3 = 0, int N4 = 0,
int N5 = 0, int N6 = 0, int N7 = 0, int N8 = 0, int N9 = 0>
template <int kNumResiduals, int... Ns>
class CostFunctionToFunctor {
public:
// Takes ownership of cost_function.
explicit CostFunctionToFunctor(CostFunction* cost_function)
: cost_functor_(cost_function) {
CHECK_NOTNULL(cost_function);
CHECK(cost_function != nullptr);
CHECK(kNumResiduals > 0 || kNumResiduals == DYNAMIC);
// This block breaks the 80 column rule to keep it somewhat readable.
CHECK((!N1 && !N2 && !N3 && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||
((N1 > 0) && !N2 && !N3 && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||
((N1 > 0) && (N2 > 0) && !N3 && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) || // NOLINT
((N1 > 0) && (N2 > 0) && (N3 > 0) && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) || // NOLINT
((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && !N5 && !N6 && !N7 && !N8 && !N9) || // NOLINT
((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && !N6 && !N7 && !N8 && !N9) || // NOLINT
((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && !N7 && !N8 && !N9) || // NOLINT
((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && (N7 > 0) && !N8 && !N9) || // NOLINT
((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && (N7 > 0) && (N8 > 0) && !N9) || // NOLINT
((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && (N7 > 0) && (N8 > 0) && (N9 > 0))) // NOLINT
<< "Zero block cannot precede a non-zero block. Block sizes are "
<< "(ignore trailing 0s): " << N0 << ", " << N1 << ", " << N2 << ", "
<< N3 << ", " << N4 << ", " << N5 << ", " << N6 << ", " << N7 << ", "
<< N8 << ", " << N9;
const std::vector<int32>& parameter_block_sizes =
const std::vector<int32_t>& parameter_block_sizes =
cost_function->parameter_block_sizes();
const int num_parameter_blocks =
(N0 > 0) + (N1 > 0) + (N2 > 0) + (N3 > 0) + (N4 > 0) +
(N5 > 0) + (N6 > 0) + (N7 > 0) + (N8 > 0) + (N9 > 0);
const int num_parameter_blocks = ParameterDims::kNumParameterBlocks;
CHECK_EQ(static_cast<int>(parameter_block_sizes.size()),
num_parameter_blocks);
CHECK_EQ(N0, parameter_block_sizes[0]);
if (parameter_block_sizes.size() > 1) CHECK_EQ(N1, parameter_block_sizes[1]); // NOLINT
if (parameter_block_sizes.size() > 2) CHECK_EQ(N2, parameter_block_sizes[2]); // NOLINT
if (parameter_block_sizes.size() > 3) CHECK_EQ(N3, parameter_block_sizes[3]); // NOLINT
if (parameter_block_sizes.size() > 4) CHECK_EQ(N4, parameter_block_sizes[4]); // NOLINT
if (parameter_block_sizes.size() > 5) CHECK_EQ(N5, parameter_block_sizes[5]); // NOLINT
if (parameter_block_sizes.size() > 6) CHECK_EQ(N6, parameter_block_sizes[6]); // NOLINT
if (parameter_block_sizes.size() > 7) CHECK_EQ(N7, parameter_block_sizes[7]); // NOLINT
if (parameter_block_sizes.size() > 8) CHECK_EQ(N8, parameter_block_sizes[8]); // NOLINT
if (parameter_block_sizes.size() > 9) CHECK_EQ(N9, parameter_block_sizes[9]); // NOLINT
if (parameter_block_sizes.size() == num_parameter_blocks) {
for (int block = 0; block < num_parameter_blocks; ++block) {
CHECK_EQ(ParameterDims::GetDim(block), parameter_block_sizes[block])
<< "Parameter block size missmatch. The specified static parameter "
"block dimension does not match the one from the cost function.";
}
}
CHECK_EQ(accumulate(parameter_block_sizes.begin(),
parameter_block_sizes.end(), 0),
N0 + N1 + N2 + N3 + N4 + N5 + N6 + N7 + N8 + N9);
CHECK_EQ(accumulate(
parameter_block_sizes.begin(), parameter_block_sizes.end(), 0),
ParameterDims::kNumParameters);
}
bool operator()(const double* x0, double* residuals) const {
CHECK_NE(N0, 0);
CHECK_EQ(N1, 0);
CHECK_EQ(N2, 0);
CHECK_EQ(N3, 0);
CHECK_EQ(N4, 0);
CHECK_EQ(N5, 0);
CHECK_EQ(N6, 0);
CHECK_EQ(N7, 0);
CHECK_EQ(N8, 0);
CHECK_EQ(N9, 0);
template <typename T, typename... Ts>
bool operator()(const T* p1, Ts*... ps) const {
// Add one because of residual block.
static_assert(sizeof...(Ts) + 1 == ParameterDims::kNumParameterBlocks + 1,
"Invalid number of parameter blocks specified.");
return cost_functor_(&x0, residuals);
}
auto params = std::make_tuple(p1, ps...);
bool operator()(const double* x0,
const double* x1,
double* residuals) const {
CHECK_NE(N0, 0);
CHECK_NE(N1, 0);
CHECK_EQ(N2, 0);
CHECK_EQ(N3, 0);
CHECK_EQ(N4, 0);
CHECK_EQ(N5, 0);
CHECK_EQ(N6, 0);
CHECK_EQ(N7, 0);
CHECK_EQ(N8, 0);
CHECK_EQ(N9, 0);
internal::FixedArray<const double*> parameter_blocks(2);
parameter_blocks[0] = x0;
parameter_blocks[1] = x1;
return cost_functor_(parameter_blocks.get(), residuals);
}
// Extract residual pointer from params. The residual pointer is the
// last pointer.
constexpr int kResidualIndex = ParameterDims::kNumParameterBlocks;
T* residuals = std::get<kResidualIndex>(params);
bool operator()(const double* x0,
const double* x1,
const double* x2,
double* residuals) const {
CHECK_NE(N0, 0);
CHECK_NE(N1, 0);
CHECK_NE(N2, 0);
CHECK_EQ(N3, 0);
CHECK_EQ(N4, 0);
CHECK_EQ(N5, 0);
CHECK_EQ(N6, 0);
CHECK_EQ(N7, 0);
CHECK_EQ(N8, 0);
CHECK_EQ(N9, 0);
internal::FixedArray<const double*> parameter_blocks(3);
parameter_blocks[0] = x0;
parameter_blocks[1] = x1;
parameter_blocks[2] = x2;
return cost_functor_(parameter_blocks.get(), residuals);
}
// Extract parameter block pointers from params.
using Indices =
std::make_integer_sequence<int,
ParameterDims::kNumParameterBlocks>;
std::array<const T*, ParameterDims::kNumParameterBlocks> parameter_blocks =
GetParameterPointers<T>(params, Indices());
bool operator()(const double* x0,
const double* x1,
const double* x2,
const double* x3,
double* residuals) const {
CHECK_NE(N0, 0);
CHECK_NE(N1, 0);
CHECK_NE(N2, 0);
CHECK_NE(N3, 0);
CHECK_EQ(N4, 0);
CHECK_EQ(N5, 0);
CHECK_EQ(N6, 0);
CHECK_EQ(N7, 0);
CHECK_EQ(N8, 0);
CHECK_EQ(N9, 0);
internal::FixedArray<const double*> parameter_blocks(4);
parameter_blocks[0] = x0;
parameter_blocks[1] = x1;
parameter_blocks[2] = x2;
parameter_blocks[3] = x3;
return cost_functor_(parameter_blocks.get(), residuals);
}
bool operator()(const double* x0,
const double* x1,
const double* x2,
const double* x3,
const double* x4,
double* residuals) const {
CHECK_NE(N0, 0);
CHECK_NE(N1, 0);
CHECK_NE(N2, 0);
CHECK_NE(N3, 0);
CHECK_NE(N4, 0);
CHECK_EQ(N5, 0);
CHECK_EQ(N6, 0);
CHECK_EQ(N7, 0);
CHECK_EQ(N8, 0);
CHECK_EQ(N9, 0);
internal::FixedArray<const double*> parameter_blocks(5);
parameter_blocks[0] = x0;
parameter_blocks[1] = x1;
parameter_blocks[2] = x2;
parameter_blocks[3] = x3;
parameter_blocks[4] = x4;
return cost_functor_(parameter_blocks.get(), residuals);
}
bool operator()(const double* x0,
const double* x1,
const double* x2,
const double* x3,
const double* x4,
const double* x5,
double* residuals) const {
CHECK_NE(N0, 0);
CHECK_NE(N1, 0);
CHECK_NE(N2, 0);
CHECK_NE(N3, 0);
CHECK_NE(N4, 0);
CHECK_NE(N5, 0);
CHECK_EQ(N6, 0);
CHECK_EQ(N7, 0);
CHECK_EQ(N8, 0);
CHECK_EQ(N9, 0);
internal::FixedArray<const double*> parameter_blocks(6);
parameter_blocks[0] = x0;
parameter_blocks[1] = x1;
parameter_blocks[2] = x2;
parameter_blocks[3] = x3;
parameter_blocks[4] = x4;
parameter_blocks[5] = x5;
return cost_functor_(parameter_blocks.get(), residuals);
}
bool operator()(const double* x0,
const double* x1,
const double* x2,
const double* x3,
const double* x4,
const double* x5,
const double* x6,
double* residuals) const {
CHECK_NE(N0, 0);
CHECK_NE(N1, 0);
CHECK_NE(N2, 0);
CHECK_NE(N3, 0);
CHECK_NE(N4, 0);
CHECK_NE(N5, 0);
CHECK_NE(N6, 0);
CHECK_EQ(N7, 0);
CHECK_EQ(N8, 0);
CHECK_EQ(N9, 0);
internal::FixedArray<const double*> parameter_blocks(7);
parameter_blocks[0] = x0;
parameter_blocks[1] = x1;
parameter_blocks[2] = x2;
parameter_blocks[3] = x3;
parameter_blocks[4] = x4;
parameter_blocks[5] = x5;
parameter_blocks[6] = x6;
return cost_functor_(parameter_blocks.get(), residuals);
}
bool operator()(const double* x0,
const double* x1,
const double* x2,
const double* x3,
const double* x4,
const double* x5,
const double* x6,
const double* x7,
double* residuals) const {
CHECK_NE(N0, 0);
CHECK_NE(N1, 0);
CHECK_NE(N2, 0);
CHECK_NE(N3, 0);
CHECK_NE(N4, 0);
CHECK_NE(N5, 0);
CHECK_NE(N6, 0);
CHECK_NE(N7, 0);
CHECK_EQ(N8, 0);
CHECK_EQ(N9, 0);
internal::FixedArray<const double*> parameter_blocks(8);
parameter_blocks[0] = x0;
parameter_blocks[1] = x1;
parameter_blocks[2] = x2;
parameter_blocks[3] = x3;
parameter_blocks[4] = x4;
parameter_blocks[5] = x5;
parameter_blocks[6] = x6;
parameter_blocks[7] = x7;
return cost_functor_(parameter_blocks.get(), residuals);
}
bool operator()(const double* x0,
const double* x1,
const double* x2,
const double* x3,
const double* x4,
const double* x5,
const double* x6,
const double* x7,
const double* x8,
double* residuals) const {
CHECK_NE(N0, 0);
CHECK_NE(N1, 0);
CHECK_NE(N2, 0);
CHECK_NE(N3, 0);
CHECK_NE(N4, 0);
CHECK_NE(N5, 0);
CHECK_NE(N6, 0);
CHECK_NE(N7, 0);
CHECK_NE(N8, 0);
CHECK_EQ(N9, 0);
internal::FixedArray<const double*> parameter_blocks(9);
parameter_blocks[0] = x0;
parameter_blocks[1] = x1;
parameter_blocks[2] = x2;
parameter_blocks[3] = x3;
parameter_blocks[4] = x4;
parameter_blocks[5] = x5;
parameter_blocks[6] = x6;
parameter_blocks[7] = x7;
parameter_blocks[8] = x8;
return cost_functor_(parameter_blocks.get(), residuals);
}
bool operator()(const double* x0,
const double* x1,
const double* x2,
const double* x3,
const double* x4,
const double* x5,
const double* x6,
const double* x7,
const double* x8,
const double* x9,
double* residuals) const {
CHECK_NE(N0, 0);
CHECK_NE(N1, 0);
CHECK_NE(N2, 0);
CHECK_NE(N3, 0);
CHECK_NE(N4, 0);
CHECK_NE(N5, 0);
CHECK_NE(N6, 0);
CHECK_NE(N7, 0);
CHECK_NE(N8, 0);
CHECK_NE(N9, 0);
internal::FixedArray<const double*> parameter_blocks(10);
parameter_blocks[0] = x0;
parameter_blocks[1] = x1;
parameter_blocks[2] = x2;
parameter_blocks[3] = x3;
parameter_blocks[4] = x4;
parameter_blocks[5] = x5;
parameter_blocks[6] = x6;
parameter_blocks[7] = x7;
parameter_blocks[8] = x8;
parameter_blocks[9] = x9;
return cost_functor_(parameter_blocks.get(), residuals);
}
template <typename JetT>
bool operator()(const JetT* x0, JetT* residuals) const {
CHECK_NE(N0, 0);
CHECK_EQ(N1, 0);
CHECK_EQ(N2, 0);
CHECK_EQ(N3, 0);
CHECK_EQ(N4, 0);
CHECK_EQ(N5, 0);
CHECK_EQ(N6, 0);
CHECK_EQ(N7, 0);
CHECK_EQ(N8, 0);
CHECK_EQ(N9, 0);
return cost_functor_(&x0, residuals);
}
template <typename JetT>
bool operator()(const JetT* x0,
const JetT* x1,
JetT* residuals) const {
CHECK_NE(N0, 0);
CHECK_NE(N1, 0);
CHECK_EQ(N2, 0);
CHECK_EQ(N3, 0);
CHECK_EQ(N4, 0);
CHECK_EQ(N5, 0);
CHECK_EQ(N6, 0);
CHECK_EQ(N7, 0);
CHECK_EQ(N8, 0);
CHECK_EQ(N9, 0);
internal::FixedArray<const JetT*> jets(2);
jets[0] = x0;
jets[1] = x1;
return cost_functor_(jets.get(), residuals);
}
template <typename JetT>
bool operator()(const JetT* x0,
const JetT* x1,
const JetT* x2,
JetT* residuals) const {
CHECK_NE(N0, 0);
CHECK_NE(N1, 0);
CHECK_NE(N2, 0);
CHECK_EQ(N3, 0);
CHECK_EQ(N4, 0);
CHECK_EQ(N5, 0);
CHECK_EQ(N6, 0);
CHECK_EQ(N7, 0);
CHECK_EQ(N8, 0);
CHECK_EQ(N9, 0);
internal::FixedArray<const JetT*> jets(3);
jets[0] = x0;
jets[1] = x1;
jets[2] = x2;
return cost_functor_(jets.get(), residuals);
}
template <typename JetT>
bool operator()(const JetT* x0,
const JetT* x1,
const JetT* x2,
const JetT* x3,
JetT* residuals) const {
CHECK_NE(N0, 0);
CHECK_NE(N1, 0);
CHECK_NE(N2, 0);
CHECK_NE(N3, 0);
CHECK_EQ(N4, 0);
CHECK_EQ(N5, 0);
CHECK_EQ(N6, 0);
CHECK_EQ(N7, 0);
CHECK_EQ(N8, 0);
CHECK_EQ(N9, 0);
internal::FixedArray<const JetT*> jets(4);
jets[0] = x0;
jets[1] = x1;
jets[2] = x2;
jets[3] = x3;
return cost_functor_(jets.get(), residuals);
}
template <typename JetT>
bool operator()(const JetT* x0,
const JetT* x1,
const JetT* x2,
const JetT* x3,
const JetT* x4,
JetT* residuals) const {
CHECK_NE(N0, 0);
CHECK_NE(N1, 0);
CHECK_NE(N2, 0);
CHECK_NE(N3, 0);
CHECK_NE(N4, 0);
CHECK_EQ(N5, 0);
CHECK_EQ(N6, 0);
CHECK_EQ(N7, 0);
CHECK_EQ(N8, 0);
CHECK_EQ(N9, 0);
internal::FixedArray<const JetT*> jets(5);
jets[0] = x0;
jets[1] = x1;
jets[2] = x2;
jets[3] = x3;
jets[4] = x4;
return cost_functor_(jets.get(), residuals);
}
template <typename JetT>
bool operator()(const JetT* x0,
const JetT* x1,
const JetT* x2,
const JetT* x3,
const JetT* x4,
const JetT* x5,
JetT* residuals) const {
CHECK_NE(N0, 0);
CHECK_NE(N1, 0);
CHECK_NE(N2, 0);
CHECK_NE(N3, 0);
CHECK_NE(N4, 0);
CHECK_NE(N5, 0);
CHECK_EQ(N6, 0);
CHECK_EQ(N7, 0);
CHECK_EQ(N8, 0);
CHECK_EQ(N9, 0);
internal::FixedArray<const JetT*> jets(6);
jets[0] = x0;
jets[1] = x1;
jets[2] = x2;
jets[3] = x3;
jets[4] = x4;
jets[5] = x5;
return cost_functor_(jets.get(), residuals);
}
template <typename JetT>
bool operator()(const JetT* x0,
const JetT* x1,
const JetT* x2,
const JetT* x3,
const JetT* x4,
const JetT* x5,
const JetT* x6,
JetT* residuals) const {
CHECK_NE(N0, 0);
CHECK_NE(N1, 0);
CHECK_NE(N2, 0);
CHECK_NE(N3, 0);
CHECK_NE(N4, 0);
CHECK_NE(N5, 0);
CHECK_NE(N6, 0);
CHECK_EQ(N7, 0);
CHECK_EQ(N8, 0);
CHECK_EQ(N9, 0);
internal::FixedArray<const JetT*> jets(7);
jets[0] = x0;
jets[1] = x1;
jets[2] = x2;
jets[3] = x3;
jets[4] = x4;
jets[5] = x5;
jets[6] = x6;
return cost_functor_(jets.get(), residuals);
}
template <typename JetT>
bool operator()(const JetT* x0,
const JetT* x1,
const JetT* x2,
const JetT* x3,
const JetT* x4,
const JetT* x5,
const JetT* x6,
const JetT* x7,
JetT* residuals) const {
CHECK_NE(N0, 0);
CHECK_NE(N1, 0);
CHECK_NE(N2, 0);
CHECK_NE(N3, 0);
CHECK_NE(N4, 0);
CHECK_NE(N5, 0);
CHECK_NE(N6, 0);
CHECK_NE(N7, 0);
CHECK_EQ(N8, 0);
CHECK_EQ(N9, 0);
internal::FixedArray<const JetT*> jets(8);
jets[0] = x0;
jets[1] = x1;
jets[2] = x2;
jets[3] = x3;
jets[4] = x4;
jets[5] = x5;
jets[6] = x6;
jets[7] = x7;
return cost_functor_(jets.get(), residuals);
}
template <typename JetT>
bool operator()(const JetT* x0,
const JetT* x1,
const JetT* x2,
const JetT* x3,
const JetT* x4,
const JetT* x5,
const JetT* x6,
const JetT* x7,
const JetT* x8,
JetT* residuals) const {
CHECK_NE(N0, 0);
CHECK_NE(N1, 0);
CHECK_NE(N2, 0);
CHECK_NE(N3, 0);
CHECK_NE(N4, 0);
CHECK_NE(N5, 0);
CHECK_NE(N6, 0);
CHECK_NE(N7, 0);
CHECK_NE(N8, 0);
CHECK_EQ(N9, 0);
internal::FixedArray<const JetT*> jets(9);
jets[0] = x0;
jets[1] = x1;
jets[2] = x2;
jets[3] = x3;
jets[4] = x4;
jets[5] = x5;
jets[6] = x6;
jets[7] = x7;
jets[8] = x8;
return cost_functor_(jets.get(), residuals);
}
template <typename JetT>
bool operator()(const JetT* x0,
const JetT* x1,
const JetT* x2,
const JetT* x3,
const JetT* x4,
const JetT* x5,
const JetT* x6,
const JetT* x7,
const JetT* x8,
const JetT* x9,
JetT* residuals) const {
CHECK_NE(N0, 0);
CHECK_NE(N1, 0);
CHECK_NE(N2, 0);
CHECK_NE(N3, 0);
CHECK_NE(N4, 0);
CHECK_NE(N5, 0);
CHECK_NE(N6, 0);
CHECK_NE(N7, 0);
CHECK_NE(N8, 0);
CHECK_NE(N9, 0);
internal::FixedArray<const JetT*> jets(10);
jets[0] = x0;
jets[1] = x1;
jets[2] = x2;
jets[3] = x3;
jets[4] = x4;
jets[5] = x5;
jets[6] = x6;
jets[7] = x7;
jets[8] = x8;
jets[9] = x9;
return cost_functor_(jets.get(), residuals);
return cost_functor_(parameter_blocks.data(), residuals);
}
private:
using ParameterDims = internal::StaticParameterDims<Ns...>;
template <typename T, typename Tuple, int... Indices>
static std::array<const T*, ParameterDims::kNumParameterBlocks>
GetParameterPointers(const Tuple& paramPointers,
std::integer_sequence<int, Indices...>) {
return std::array<const T*, ParameterDims::kNumParameterBlocks>{
{std::get<Indices>(paramPointers)...}};
}
DynamicCostFunctionToFunctor cost_functor_;
};

View File

@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2015 Google Inc. All rights reserved.
// Copyright 2019 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// Redistribution and use in source and binary forms, with or without
@@ -31,12 +31,13 @@
#ifndef CERES_PUBLIC_COVARIANCE_H_
#define CERES_PUBLIC_COVARIANCE_H_
#include <memory>
#include <utility>
#include <vector>
#include "ceres/internal/port.h"
#include "ceres/internal/scoped_ptr.h"
#include "ceres/types.h"
#include "ceres/internal/disable_warnings.h"
#include "ceres/internal/port.h"
#include "ceres/types.h"
namespace ceres {
@@ -60,7 +61,7 @@ class CovarianceImpl;
// Background
// ==========
// One way to assess the quality of the solution returned by a
// non-linear least squares solve is to analyze the covariance of the
// non-linear least squares solver is to analyze the covariance of the
// solution.
//
// Let us consider the non-linear regression problem
@@ -158,7 +159,7 @@ class CovarianceImpl;
// Gauge Invariance
// ----------------
// In structure from motion (3D reconstruction) problems, the
// reconstruction is ambiguous upto a similarity transform. This is
// reconstruction is ambiguous up to a similarity transform. This is
// known as a Gauge Ambiguity. Handling Gauges correctly requires the
// use of SVD or custom inversion algorithms. For small problems the
// user can use the dense algorithm. For more details see
@@ -183,7 +184,7 @@ class CovarianceImpl;
// Covariance::Options options;
// Covariance covariance(options);
//
// std::vector<std::pair<const double*, const double*> > covariance_blocks;
// std::vector<std::pair<const double*, const double*>> covariance_blocks;
// covariance_blocks.push_back(make_pair(x, x));
// covariance_blocks.push_back(make_pair(y, y));
// covariance_blocks.push_back(make_pair(x, y));
@@ -200,19 +201,19 @@ class CovarianceImpl;
class CERES_EXPORT Covariance {
public:
struct CERES_EXPORT Options {
Options()
#ifndef CERES_NO_SUITESPARSE
: algorithm_type(SUITE_SPARSE_QR),
// Sparse linear algebra library to use when a sparse matrix
// factorization is being used to compute the covariance matrix.
//
// Currently this only applies to SPARSE_QR.
SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type =
#if !defined(CERES_NO_SUITESPARSE)
SUITE_SPARSE;
#else
: algorithm_type(EIGEN_SPARSE_QR),
// Eigen's QR factorization is always available.
EIGEN_SPARSE;
#endif
min_reciprocal_condition_number(1e-14),
null_space_rank(0),
num_threads(1),
apply_loss_function(true) {
}
// Ceres supports three different algorithms for covariance
// Ceres supports two different algorithms for covariance
// estimation, which represent different tradeoffs in speed,
// accuracy and reliability.
//
@@ -229,23 +230,20 @@ class CERES_EXPORT Covariance {
// for small to moderate sized problems. It can handle
// full-rank as well as rank deficient Jacobians.
//
// 2. EIGEN_SPARSE_QR uses the sparse QR factorization algorithm
// in Eigen to compute the decomposition
// 2. SPARSE_QR uses the sparse QR factorization algorithm
// to compute the decomposition
//
// Q * R = J
//
// [J'J]^-1 = [R*R']^-1
//
// It is a moderately fast algorithm for sparse matrices.
//
// 3. SUITE_SPARSE_QR uses the SuiteSparseQR sparse QR
// factorization algorithm. It uses dense linear algebra and is
// multi threaded, so for large sparse sparse matrices it is
// significantly faster than EIGEN_SPARSE_QR.
//
// Neither EIGEN_SPARSE_QR not SUITE_SPARSE_QR are capable of
// computing the covariance if the Jacobian is rank deficient.
CovarianceAlgorithmType algorithm_type;
// SPARSE_QR is not capable of computing the covariance if the
// Jacobian is rank deficient. Depending on the value of
// Covariance::Options::sparse_linear_algebra_library_type, either
// Eigen's Sparse QR factorization algorithm will be used or
// SuiteSparse's high performance SuiteSparseQR algorithm will be
// used.
CovarianceAlgorithmType algorithm_type = SPARSE_QR;
// If the Jacobian matrix is near singular, then inverting J'J
// will result in unreliable results, e.g, if
@@ -270,7 +268,7 @@ class CERES_EXPORT Covariance {
// where min_sigma and max_sigma are the minimum and maxiumum
// singular values of J respectively.
//
// 2. SUITE_SPARSE_QR and EIGEN_SPARSE_QR
// 2. SPARSE_QR
//
// rank(J) < num_col(J)
//
@@ -278,7 +276,7 @@ class CERES_EXPORT Covariance {
// sparse QR factorization algorithm. It is a fairly reliable
// indication of rank deficiency.
//
double min_reciprocal_condition_number;
double min_reciprocal_condition_number = 1e-14;
// When using DENSE_SVD, the user has more control in dealing with
// singular and near singular covariance matrices.
@@ -313,9 +311,9 @@ class CERES_EXPORT Covariance {
//
// This option has no effect on the SUITE_SPARSE_QR and
// EIGEN_SPARSE_QR algorithms.
int null_space_rank;
int null_space_rank = 0;
int num_threads;
int num_threads = 1;
// Even though the residual blocks in the problem may contain loss
// functions, setting apply_loss_function to false will turn off
@@ -323,7 +321,7 @@ class CERES_EXPORT Covariance {
// function and in turn its effect on the covariance.
//
// TODO(sameergaarwal): Expand this based on Jim's experiments.
bool apply_loss_function;
bool apply_loss_function = true;
};
explicit Covariance(const Options& options);
@@ -352,10 +350,9 @@ class CERES_EXPORT Covariance {
// covariance computation. Please see the documentation for
// Covariance::Options for more on the conditions under which this
// function returns false.
bool Compute(
const std::vector<std::pair<const double*,
const double*> >& covariance_blocks,
Problem* problem);
bool Compute(const std::vector<std::pair<const double*, const double*>>&
covariance_blocks,
Problem* problem);
// Compute a part of the covariance matrix.
//
@@ -428,8 +425,8 @@ class CERES_EXPORT Covariance {
// a square matrix whose row and column count is equal to the sum of
// the sizes of the individual parameter blocks. The covariance
// matrix will be a row-major matrix.
bool GetCovarianceMatrix(const std::vector<const double *> &parameter_blocks,
double *covariance_matrix);
bool GetCovarianceMatrix(const std::vector<const double*>& parameter_blocks,
double* covariance_matrix) const;
// Return the covariance matrix corresponding to parameter_blocks
// in the tangent space if a local parameterization is associated
@@ -448,10 +445,10 @@ class CERES_EXPORT Covariance {
// blocks. The covariance matrix will be a row-major matrix.
bool GetCovarianceMatrixInTangentSpace(
const std::vector<const double*>& parameter_blocks,
double* covariance_matrix);
double* covariance_matrix) const;
private:
internal::scoped_ptr<internal::CovarianceImpl> impl_;
std::unique_ptr<internal::CovarianceImpl> impl_;
};
} // namespace ceres

View File

@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2015 Google Inc. All rights reserved.
// Copyright 2019 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// Redistribution and use in source and binary forms, with or without
@@ -32,8 +32,9 @@
#define CERES_PUBLIC_CRS_MATRIX_H_
#include <vector>
#include "ceres/internal/port.h"
#include "ceres/internal/disable_warnings.h"
#include "ceres/internal/port.h"
namespace ceres {

View File

@@ -0,0 +1,436 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2019 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// 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 name of Google Inc. 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 OWNER 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.
//
// Author: sameeragarwal@google.com (Sameer Agarwal)
#ifndef CERES_PUBLIC_CUBIC_INTERPOLATION_H_
#define CERES_PUBLIC_CUBIC_INTERPOLATION_H_
#include "Eigen/Core"
#include "ceres/internal/port.h"
#include "glog/logging.h"
namespace ceres {
// Given samples from a function sampled at four equally spaced points,
//
// p0 = f(-1)
// p1 = f(0)
// p2 = f(1)
// p3 = f(2)
//
// Evaluate the cubic Hermite spline (also known as the Catmull-Rom
// spline) at a point x that lies in the interval [0, 1].
//
// This is also the interpolation kernel (for the case of a = 0.5) as
// proposed by R. Keys, in:
//
// "Cubic convolution interpolation for digital image processing".
// IEEE Transactions on Acoustics, Speech, and Signal Processing
// 29 (6): 1153-1160.
//
// For more details see
//
// http://en.wikipedia.org/wiki/Cubic_Hermite_spline
// http://en.wikipedia.org/wiki/Bicubic_interpolation
//
// f if not NULL will contain the interpolated function values.
// dfdx if not NULL will contain the interpolated derivative values.
template <int kDataDimension>
void CubicHermiteSpline(const Eigen::Matrix<double, kDataDimension, 1>& p0,
const Eigen::Matrix<double, kDataDimension, 1>& p1,
const Eigen::Matrix<double, kDataDimension, 1>& p2,
const Eigen::Matrix<double, kDataDimension, 1>& p3,
const double x,
double* f,
double* dfdx) {
typedef Eigen::Matrix<double, kDataDimension, 1> VType;
const VType a = 0.5 * (-p0 + 3.0 * p1 - 3.0 * p2 + p3);
const VType b = 0.5 * (2.0 * p0 - 5.0 * p1 + 4.0 * p2 - p3);
const VType c = 0.5 * (-p0 + p2);
const VType d = p1;
// Use Horner's rule to evaluate the function value and its
// derivative.
// f = ax^3 + bx^2 + cx + d
if (f != NULL) {
Eigen::Map<VType>(f, kDataDimension) = d + x * (c + x * (b + x * a));
}
// dfdx = 3ax^2 + 2bx + c
if (dfdx != NULL) {
Eigen::Map<VType>(dfdx, kDataDimension) = c + x * (2.0 * b + 3.0 * a * x);
}
}
// Given as input an infinite one dimensional grid, which provides the
// following interface.
//
// class Grid {
// public:
// enum { DATA_DIMENSION = 2; };
// void GetValue(int n, double* f) const;
// };
//
// Here, GetValue gives the value of a function f (possibly vector
// valued) for any integer n.
//
// The enum DATA_DIMENSION indicates the dimensionality of the
// function being interpolated. For example if you are interpolating
// rotations in axis-angle format over time, then DATA_DIMENSION = 3.
//
// CubicInterpolator uses cubic Hermite splines to produce a smooth
// approximation to it that can be used to evaluate the f(x) and f'(x)
// at any point on the real number line.
//
// For more details on cubic interpolation see
//
// http://en.wikipedia.org/wiki/Cubic_Hermite_spline
//
// Example usage:
//
// const double data[] = {1.0, 2.0, 5.0, 6.0};
// Grid1D<double, 1> grid(data, 0, 4);
// CubicInterpolator<Grid1D<double, 1>> interpolator(grid);
// double f, dfdx;
// interpolator.Evaluator(1.5, &f, &dfdx);
template <typename Grid>
class CubicInterpolator {
public:
explicit CubicInterpolator(const Grid& grid) : grid_(grid) {
// The + casts the enum into an int before doing the
// comparison. It is needed to prevent
// "-Wunnamed-type-template-args" related errors.
CHECK_GE(+Grid::DATA_DIMENSION, 1);
}
void Evaluate(double x, double* f, double* dfdx) const {
const int n = std::floor(x);
Eigen::Matrix<double, Grid::DATA_DIMENSION, 1> p0, p1, p2, p3;
grid_.GetValue(n - 1, p0.data());
grid_.GetValue(n, p1.data());
grid_.GetValue(n + 1, p2.data());
grid_.GetValue(n + 2, p3.data());
CubicHermiteSpline<Grid::DATA_DIMENSION>(p0, p1, p2, p3, x - n, f, dfdx);
}
// The following two Evaluate overloads are needed for interfacing
// with automatic differentiation. The first is for when a scalar
// evaluation is done, and the second one is for when Jets are used.
void Evaluate(const double& x, double* f) const { Evaluate(x, f, NULL); }
template <typename JetT>
void Evaluate(const JetT& x, JetT* f) const {
double fx[Grid::DATA_DIMENSION], dfdx[Grid::DATA_DIMENSION];
Evaluate(x.a, fx, dfdx);
for (int i = 0; i < Grid::DATA_DIMENSION; ++i) {
f[i].a = fx[i];
f[i].v = dfdx[i] * x.v;
}
}
private:
const Grid& grid_;
};
// An object that implements an infinite one dimensional grid needed
// by the CubicInterpolator where the source of the function values is
// an array of type T on the interval
//
// [begin, ..., end - 1]
//
// Since the input array is finite and the grid is infinite, values
// outside this interval needs to be computed. Grid1D uses the value
// from the nearest edge.
//
// The function being provided can be vector valued, in which case
// kDataDimension > 1. The dimensional slices of the function maybe
// interleaved, or they maybe stacked, i.e, if the function has
// kDataDimension = 2, if kInterleaved = true, then it is stored as
//
// f01, f02, f11, f12 ....
//
// and if kInterleaved = false, then it is stored as
//
// f01, f11, .. fn1, f02, f12, .. , fn2
//
template <typename T, int kDataDimension = 1, bool kInterleaved = true>
struct Grid1D {
public:
enum { DATA_DIMENSION = kDataDimension };
Grid1D(const T* data, const int begin, const int end)
: data_(data), begin_(begin), end_(end), num_values_(end - begin) {
CHECK_LT(begin, end);
}
EIGEN_STRONG_INLINE void GetValue(const int n, double* f) const {
const int idx = std::min(std::max(begin_, n), end_ - 1) - begin_;
if (kInterleaved) {
for (int i = 0; i < kDataDimension; ++i) {
f[i] = static_cast<double>(data_[kDataDimension * idx + i]);
}
} else {
for (int i = 0; i < kDataDimension; ++i) {
f[i] = static_cast<double>(data_[i * num_values_ + idx]);
}
}
}
private:
const T* data_;
const int begin_;
const int end_;
const int num_values_;
};
// Given as input an infinite two dimensional grid like object, which
// provides the following interface:
//
// struct Grid {
// enum { DATA_DIMENSION = 1 };
// void GetValue(int row, int col, double* f) const;
// };
//
// Where, GetValue gives us the value of a function f (possibly vector
// valued) for any pairs of integers (row, col), and the enum
// DATA_DIMENSION indicates the dimensionality of the function being
// interpolated. For example if you are interpolating a color image
// with three channels (Red, Green & Blue), then DATA_DIMENSION = 3.
//
// BiCubicInterpolator uses the cubic convolution interpolation
// algorithm of R. Keys, to produce a smooth approximation to it that
// can be used to evaluate the f(r,c), df(r, c)/dr and df(r,c)/dc at
// any point in the real plane.
//
// For more details on the algorithm used here see:
//
// "Cubic convolution interpolation for digital image processing".
// Robert G. Keys, IEEE Trans. on Acoustics, Speech, and Signal
// Processing 29 (6): 1153-1160, 1981.
//
// http://en.wikipedia.org/wiki/Cubic_Hermite_spline
// http://en.wikipedia.org/wiki/Bicubic_interpolation
//
// Example usage:
//
// const double data[] = {1.0, 3.0, -1.0, 4.0,
// 3.6, 2.1, 4.2, 2.0,
// 2.0, 1.0, 3.1, 5.2};
// Grid2D<double, 1> grid(data, 3, 4);
// BiCubicInterpolator<Grid2D<double, 1>> interpolator(grid);
// double f, dfdr, dfdc;
// interpolator.Evaluate(1.2, 2.5, &f, &dfdr, &dfdc);
template <typename Grid>
class BiCubicInterpolator {
public:
explicit BiCubicInterpolator(const Grid& grid) : grid_(grid) {
// The + casts the enum into an int before doing the
// comparison. It is needed to prevent
// "-Wunnamed-type-template-args" related errors.
CHECK_GE(+Grid::DATA_DIMENSION, 1);
}
// Evaluate the interpolated function value and/or its
// derivative. Uses the nearest point on the grid boundary if r or
// c is out of bounds.
void Evaluate(
double r, double c, double* f, double* dfdr, double* dfdc) const {
// BiCubic interpolation requires 16 values around the point being
// evaluated. We will use pij, to indicate the elements of the
// 4x4 grid of values.
//
// col
// p00 p01 p02 p03
// row p10 p11 p12 p13
// p20 p21 p22 p23
// p30 p31 p32 p33
//
// The point (r,c) being evaluated is assumed to lie in the square
// defined by p11, p12, p22 and p21.
const int row = std::floor(r);
const int col = std::floor(c);
Eigen::Matrix<double, Grid::DATA_DIMENSION, 1> p0, p1, p2, p3;
// Interpolate along each of the four rows, evaluating the function
// value and the horizontal derivative in each row.
Eigen::Matrix<double, Grid::DATA_DIMENSION, 1> f0, f1, f2, f3;
Eigen::Matrix<double, Grid::DATA_DIMENSION, 1> df0dc, df1dc, df2dc, df3dc;
grid_.GetValue(row - 1, col - 1, p0.data());
grid_.GetValue(row - 1, col, p1.data());
grid_.GetValue(row - 1, col + 1, p2.data());
grid_.GetValue(row - 1, col + 2, p3.data());
CubicHermiteSpline<Grid::DATA_DIMENSION>(
p0, p1, p2, p3, c - col, f0.data(), df0dc.data());
grid_.GetValue(row, col - 1, p0.data());
grid_.GetValue(row, col, p1.data());
grid_.GetValue(row, col + 1, p2.data());
grid_.GetValue(row, col + 2, p3.data());
CubicHermiteSpline<Grid::DATA_DIMENSION>(
p0, p1, p2, p3, c - col, f1.data(), df1dc.data());
grid_.GetValue(row + 1, col - 1, p0.data());
grid_.GetValue(row + 1, col, p1.data());
grid_.GetValue(row + 1, col + 1, p2.data());
grid_.GetValue(row + 1, col + 2, p3.data());
CubicHermiteSpline<Grid::DATA_DIMENSION>(
p0, p1, p2, p3, c - col, f2.data(), df2dc.data());
grid_.GetValue(row + 2, col - 1, p0.data());
grid_.GetValue(row + 2, col, p1.data());
grid_.GetValue(row + 2, col + 1, p2.data());
grid_.GetValue(row + 2, col + 2, p3.data());
CubicHermiteSpline<Grid::DATA_DIMENSION>(
p0, p1, p2, p3, c - col, f3.data(), df3dc.data());
// Interpolate vertically the interpolated value from each row and
// compute the derivative along the columns.
CubicHermiteSpline<Grid::DATA_DIMENSION>(f0, f1, f2, f3, r - row, f, dfdr);
if (dfdc != NULL) {
// Interpolate vertically the derivative along the columns.
CubicHermiteSpline<Grid::DATA_DIMENSION>(
df0dc, df1dc, df2dc, df3dc, r - row, dfdc, NULL);
}
}
// The following two Evaluate overloads are needed for interfacing
// with automatic differentiation. The first is for when a scalar
// evaluation is done, and the second one is for when Jets are used.
void Evaluate(const double& r, const double& c, double* f) const {
Evaluate(r, c, f, NULL, NULL);
}
template <typename JetT>
void Evaluate(const JetT& r, const JetT& c, JetT* f) const {
double frc[Grid::DATA_DIMENSION];
double dfdr[Grid::DATA_DIMENSION];
double dfdc[Grid::DATA_DIMENSION];
Evaluate(r.a, c.a, frc, dfdr, dfdc);
for (int i = 0; i < Grid::DATA_DIMENSION; ++i) {
f[i].a = frc[i];
f[i].v = dfdr[i] * r.v + dfdc[i] * c.v;
}
}
private:
const Grid& grid_;
};
// An object that implements an infinite two dimensional grid needed
// by the BiCubicInterpolator where the source of the function values
// is an grid of type T on the grid
//
// [(row_start, col_start), ..., (row_start, col_end - 1)]
// [ ... ]
// [(row_end - 1, col_start), ..., (row_end - 1, col_end - 1)]
//
// Since the input grid is finite and the grid is infinite, values
// outside this interval needs to be computed. Grid2D uses the value
// from the nearest edge.
//
// The function being provided can be vector valued, in which case
// kDataDimension > 1. The data maybe stored in row or column major
// format and the various dimensional slices of the function maybe
// interleaved, or they maybe stacked, i.e, if the function has
// kDataDimension = 2, is stored in row-major format and if
// kInterleaved = true, then it is stored as
//
// f001, f002, f011, f012, ...
//
// A commonly occuring example are color images (RGB) where the three
// channels are stored interleaved.
//
// If kInterleaved = false, then it is stored as
//
// f001, f011, ..., fnm1, f002, f012, ...
template <typename T,
int kDataDimension = 1,
bool kRowMajor = true,
bool kInterleaved = true>
struct Grid2D {
public:
enum { DATA_DIMENSION = kDataDimension };
Grid2D(const T* data,
const int row_begin,
const int row_end,
const int col_begin,
const int col_end)
: data_(data),
row_begin_(row_begin),
row_end_(row_end),
col_begin_(col_begin),
col_end_(col_end),
num_rows_(row_end - row_begin),
num_cols_(col_end - col_begin),
num_values_(num_rows_ * num_cols_) {
CHECK_GE(kDataDimension, 1);
CHECK_LT(row_begin, row_end);
CHECK_LT(col_begin, col_end);
}
EIGEN_STRONG_INLINE void GetValue(const int r, const int c, double* f) const {
const int row_idx =
std::min(std::max(row_begin_, r), row_end_ - 1) - row_begin_;
const int col_idx =
std::min(std::max(col_begin_, c), col_end_ - 1) - col_begin_;
const int n = (kRowMajor) ? num_cols_ * row_idx + col_idx
: num_rows_ * col_idx + row_idx;
if (kInterleaved) {
for (int i = 0; i < kDataDimension; ++i) {
f[i] = static_cast<double>(data_[kDataDimension * n + i]);
}
} else {
for (int i = 0; i < kDataDimension; ++i) {
f[i] = static_cast<double>(data_[i * num_values_ + n]);
}
}
}
private:
const T* data_;
const int row_begin_;
const int row_end_;
const int col_begin_;
const int col_end_;
const int num_rows_;
const int num_cols_;
const int num_values_;
};
} // namespace ceres
#endif // CERES_PUBLIC_CUBIC_INTERPOLATOR_H_

View File

@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2015 Google Inc. All rights reserved.
// Copyright 2019 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// Redistribution and use in source and binary forms, with or without
@@ -28,7 +28,22 @@
//
// Author: sameeragarwal@google.com (Sameer Agarwal)
// mierle@gmail.com (Keir Mierle)
//
#ifndef CERES_PUBLIC_DYNAMIC_AUTODIFF_COST_FUNCTION_H_
#define CERES_PUBLIC_DYNAMIC_AUTODIFF_COST_FUNCTION_H_
#include <cmath>
#include <memory>
#include <numeric>
#include <vector>
#include "ceres/dynamic_cost_function.h"
#include "ceres/internal/fixed_array.h"
#include "ceres/jet.h"
#include "glog/logging.h"
namespace ceres {
// This autodiff implementation differs from the one found in
// autodiff_cost_function.h by supporting autodiff on cost functions
// with variable numbers of parameters with variable sizes. With the
@@ -43,7 +58,7 @@
// bool operator()(T const* const* parameters, T* residuals) const {
// // Use parameters[i] to access the i'th parameter block.
// }
// }
// };
//
// Since the sizing of the parameters is done at runtime, you must
// also specify the sizes after creating the dynamic autodiff cost
@@ -60,40 +75,17 @@
// default, controlled by the Stride template parameter) with each
// pass. There is a tradeoff with the size of the passes; you may want
// to experiment with the stride.
#ifndef CERES_PUBLIC_DYNAMIC_AUTODIFF_COST_FUNCTION_H_
#define CERES_PUBLIC_DYNAMIC_AUTODIFF_COST_FUNCTION_H_
#include <cmath>
#include <numeric>
#include <vector>
#include "ceres/cost_function.h"
#include "ceres/internal/scoped_ptr.h"
#include "ceres/jet.h"
#include "glog/logging.h"
namespace ceres {
template <typename CostFunctor, int Stride = 4>
class DynamicAutoDiffCostFunction : public CostFunction {
class DynamicAutoDiffCostFunction : public DynamicCostFunction {
public:
explicit DynamicAutoDiffCostFunction(CostFunctor* functor)
: functor_(functor) {}
: functor_(functor) {}
virtual ~DynamicAutoDiffCostFunction() {}
void AddParameterBlock(int size) {
mutable_parameter_block_sizes()->push_back(size);
}
void SetNumResiduals(int num_residuals) {
set_num_residuals(num_residuals);
}
virtual bool Evaluate(double const* const* parameters,
double* residuals,
double** jacobians) const {
bool Evaluate(double const* const* parameters,
double* residuals,
double** jacobians) const override {
CHECK_GT(num_residuals(), 0)
<< "You must call DynamicAutoDiffCostFunction::SetNumResiduals() "
<< "before DynamicAutoDiffCostFunction::Evaluate().";
@@ -112,20 +104,23 @@ class DynamicAutoDiffCostFunction : public CostFunction {
// depends on.
//
// To work around this issue, the solution here is to evaluate the
// jacobians in a series of passes, each one computing Stripe *
// jacobians in a series of passes, each one computing Stride *
// num_residuals() derivatives. This is done with small, fixed-size jets.
const int num_parameter_blocks = parameter_block_sizes().size();
const int num_parameters = std::accumulate(parameter_block_sizes().begin(),
parameter_block_sizes().end(),
0);
const int num_parameter_blocks =
static_cast<int>(parameter_block_sizes().size());
const int num_parameters = std::accumulate(
parameter_block_sizes().begin(), parameter_block_sizes().end(), 0);
// Allocate scratch space for the strided evaluation.
std::vector<Jet<double, Stride> > input_jets(num_parameters);
std::vector<Jet<double, Stride> > output_jets(num_residuals());
using JetT = Jet<double, Stride>;
internal::FixedArray<JetT, (256 * 7) / sizeof(JetT)> input_jets(
num_parameters);
internal::FixedArray<JetT, (256 * 7) / sizeof(JetT)> output_jets(
num_residuals());
// Make the parameter pack that is sent to the functor (reused).
std::vector<Jet<double, Stride>* > jet_parameters(num_parameter_blocks,
static_cast<Jet<double, Stride>* >(NULL));
internal::FixedArray<Jet<double, Stride>*> jet_parameters(
num_parameter_blocks, nullptr);
int num_active_parameters = 0;
// To handle constant parameters between non-constant parameter blocks, the
@@ -172,8 +167,8 @@ class DynamicAutoDiffCostFunction : public CostFunction {
// Evaluate all of the strides. Each stride is a chunk of the derivative to
// evaluate, typically some size proportional to the size of the SIMD
// registers of the CPU.
int num_strides = static_cast<int>(ceil(num_active_parameters /
static_cast<float>(Stride)));
int num_strides = static_cast<int>(
ceil(num_active_parameters / static_cast<float>(Stride)));
int current_derivative_section = 0;
int current_derivative_section_cursor = 0;
@@ -183,7 +178,7 @@ class DynamicAutoDiffCostFunction : public CostFunction {
// non-constant #Stride parameters.
const int initial_derivative_section = current_derivative_section;
const int initial_derivative_section_cursor =
current_derivative_section_cursor;
current_derivative_section_cursor;
int active_parameter_count = 0;
parameter_cursor = 0;
@@ -193,9 +188,9 @@ class DynamicAutoDiffCostFunction : public CostFunction {
++j, parameter_cursor++) {
input_jets[parameter_cursor].v.setZero();
if (active_parameter_count < Stride &&
parameter_cursor >= (
start_derivative_section[current_derivative_section] +
current_derivative_section_cursor)) {
parameter_cursor >=
(start_derivative_section[current_derivative_section] +
current_derivative_section_cursor)) {
if (jacobians[i] != NULL) {
input_jets[parameter_cursor].v[active_parameter_count] = 1.0;
++active_parameter_count;
@@ -222,9 +217,9 @@ class DynamicAutoDiffCostFunction : public CostFunction {
for (int j = 0; j < parameter_block_sizes()[i];
++j, parameter_cursor++) {
if (active_parameter_count < Stride &&
parameter_cursor >= (
start_derivative_section[current_derivative_section] +
current_derivative_section_cursor)) {
parameter_cursor >=
(start_derivative_section[current_derivative_section] +
current_derivative_section_cursor)) {
if (jacobians[i] != NULL) {
for (int k = 0; k < num_residuals(); ++k) {
jacobians[i][k * parameter_block_sizes()[i] + j] =
@@ -252,7 +247,7 @@ class DynamicAutoDiffCostFunction : public CostFunction {
}
private:
internal::scoped_ptr<CostFunctor> functor_;
std::unique_ptr<CostFunctor> functor_;
};
} // namespace ceres

View File

@@ -0,0 +1,56 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2019 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// 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 name of Google Inc. 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 OWNER 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.
//
// Author: sameeragarwal@google.com (Sameer Agarwal)
#ifndef CERES_PUBLIC_DYNAMIC_COST_FUNCTION_H_
#define CERES_PUBLIC_DYNAMIC_COST_FUNCTION_H_
#include "ceres/cost_function.h"
namespace ceres {
// A common base class for DynamicAutoDiffCostFunction and
// DynamicNumericDiffCostFunction which depend on methods that can add
// parameter blocks and set the number of residuals at run time.
class CERES_EXPORT DynamicCostFunction : public CostFunction {
public:
~DynamicCostFunction() {}
virtual void AddParameterBlock(int size) {
mutable_parameter_block_sizes()->push_back(size);
}
virtual void SetNumResiduals(int num_residuals) {
set_num_residuals(num_residuals);
}
};
} // namespace ceres
#endif // CERES_PUBLIC_DYNAMIC_COST_FUNCTION_H_

View File

@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2015 Google Inc. All rights reserved.
// Copyright 2019 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// Redistribution and use in source and binary forms, with or without
@@ -28,7 +28,20 @@
//
// Author: sameeragarwal@google.com (Sameer Agarwal)
// dgossow@google.com (David Gossow)
//
#ifndef CERES_PUBLIC_DYNAMIC_COST_FUNCTION_TO_FUNCTOR_H_
#define CERES_PUBLIC_DYNAMIC_COST_FUNCTION_TO_FUNCTOR_H_
#include <memory>
#include <numeric>
#include <vector>
#include "ceres/dynamic_cost_function.h"
#include "ceres/internal/fixed_array.h"
#include "ceres/internal/port.h"
namespace ceres {
// DynamicCostFunctionToFunctor allows users to use CostFunction
// objects in templated functors which are to be used for automatic
// differentiation. It works similar to CostFunctionToFunctor, with the
@@ -40,9 +53,9 @@
// class IntrinsicProjection : public CostFunction {
// public:
// IntrinsicProjection(const double* observation);
// virtual bool Evaluate(double const* const* parameters,
// double* residuals,
// double** jacobians) const;
// bool Evaluate(double const* const* parameters,
// double* residuals,
// double** jacobians) const override;
// };
//
// is a cost function that implements the projection of a point in its
@@ -87,26 +100,12 @@
// private:
// DynamicCostFunctionToFunctor intrinsic_projection_;
// };
#ifndef CERES_PUBLIC_DYNAMIC_COST_FUNCTION_TO_FUNCTOR_H_
#define CERES_PUBLIC_DYNAMIC_COST_FUNCTION_TO_FUNCTOR_H_
#include <numeric>
#include <vector>
#include "ceres/cost_function.h"
#include "ceres/internal/fixed_array.h"
#include "ceres/internal/port.h"
#include "ceres/internal/scoped_ptr.h"
namespace ceres {
class DynamicCostFunctionToFunctor {
public:
// Takes ownership of cost_function.
explicit DynamicCostFunctionToFunctor(CostFunction* cost_function)
: cost_function_(cost_function) {
CHECK_NOTNULL(cost_function);
CHECK(cost_function != nullptr);
}
bool operator()(double const* const* parameters, double* residuals) const {
@@ -115,12 +114,13 @@ class DynamicCostFunctionToFunctor {
template <typename JetT>
bool operator()(JetT const* const* inputs, JetT* output) const {
const std::vector<int32>& parameter_block_sizes =
const std::vector<int32_t>& parameter_block_sizes =
cost_function_->parameter_block_sizes();
const int num_parameter_blocks = parameter_block_sizes.size();
const int num_parameter_blocks =
static_cast<int>(parameter_block_sizes.size());
const int num_residuals = cost_function_->num_residuals();
const int num_parameters = std::accumulate(parameter_block_sizes.begin(),
parameter_block_sizes.end(), 0);
const int num_parameters = std::accumulate(
parameter_block_sizes.begin(), parameter_block_sizes.end(), 0);
internal::FixedArray<double> parameters(num_parameters);
internal::FixedArray<double*> parameter_blocks(num_parameter_blocks);
@@ -130,8 +130,8 @@ class DynamicCostFunctionToFunctor {
// Build a set of arrays to get the residuals and jacobians from
// the CostFunction wrapped by this functor.
double* parameter_ptr = parameters.get();
double* jacobian_ptr = jacobians.get();
double* parameter_ptr = parameters.data();
double* jacobian_ptr = jacobians.data();
for (int i = 0; i < num_parameter_blocks; ++i) {
parameter_blocks[i] = parameter_ptr;
jacobian_blocks[i] = jacobian_ptr;
@@ -141,9 +141,9 @@ class DynamicCostFunctionToFunctor {
jacobian_ptr += num_residuals * parameter_block_sizes[i];
}
if (!cost_function_->Evaluate(parameter_blocks.get(),
residuals.get(),
jacobian_blocks.get())) {
if (!cost_function_->Evaluate(parameter_blocks.data(),
residuals.data(),
jacobian_blocks.data())) {
return false;
}
@@ -170,7 +170,7 @@ class DynamicCostFunctionToFunctor {
output[i].v.setZero();
for (int j = 0; j < num_parameter_blocks; ++j) {
const int32 block_size = parameter_block_sizes[j];
const int32_t block_size = parameter_block_sizes[j];
for (int k = 0; k < parameter_block_sizes[j]; ++k) {
output[i].v +=
jacobian_blocks[j][i * block_size + k] * inputs[j][k].v;
@@ -182,7 +182,7 @@ class DynamicCostFunctionToFunctor {
}
private:
internal::scoped_ptr<CostFunction> cost_function_;
std::unique_ptr<CostFunction> cost_function_;
};
} // namespace ceres

View File

@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2015 Google Inc. All rights reserved.
// Copyright 2019 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,24 @@
// sameeragarwal@google.com (Sameer Agarwal)
// thadh@gmail.com (Thad Hughes)
// tbennun@gmail.com (Tal Ben-Nun)
//
#ifndef CERES_PUBLIC_DYNAMIC_NUMERIC_DIFF_COST_FUNCTION_H_
#define CERES_PUBLIC_DYNAMIC_NUMERIC_DIFF_COST_FUNCTION_H_
#include <cmath>
#include <memory>
#include <numeric>
#include <vector>
#include "ceres/dynamic_cost_function.h"
#include "ceres/internal/eigen.h"
#include "ceres/internal/numeric_diff.h"
#include "ceres/internal/parameter_dims.h"
#include "ceres/numeric_diff_options.h"
#include "glog/logging.h"
namespace ceres {
// This numeric diff implementation differs from the one found in
// numeric_diff_cost_function.h by supporting numericdiff on cost
// functions with variable numbers of parameters with variable
@@ -42,7 +59,9 @@
// numeric diff; the expected interface for the cost functors is:
//
// struct MyCostFunctor {
// bool operator()(double const* const* parameters, double* residuals) const {
// bool operator()(double const*
// const* parameters,
// double* residuals) const {
// // Use parameters[i] to access the i'th parameter block.
// }
// }
@@ -56,34 +75,14 @@
// cost_function.AddParameterBlock(5);
// cost_function.AddParameterBlock(10);
// cost_function.SetNumResiduals(21);
#ifndef CERES_PUBLIC_DYNAMIC_NUMERIC_DIFF_COST_FUNCTION_H_
#define CERES_PUBLIC_DYNAMIC_NUMERIC_DIFF_COST_FUNCTION_H_
#include <cmath>
#include <numeric>
#include <vector>
#include "ceres/cost_function.h"
#include "ceres/internal/scoped_ptr.h"
#include "ceres/internal/eigen.h"
#include "ceres/internal/numeric_diff.h"
#include "ceres/numeric_diff_options.h"
#include "glog/logging.h"
namespace ceres {
template <typename CostFunctor, NumericDiffMethodType method = CENTRAL>
class DynamicNumericDiffCostFunction : public CostFunction {
class DynamicNumericDiffCostFunction : public DynamicCostFunction {
public:
explicit DynamicNumericDiffCostFunction(
const CostFunctor* functor,
Ownership ownership = TAKE_OWNERSHIP,
const NumericDiffOptions& options = NumericDiffOptions())
: functor_(functor),
ownership_(ownership),
options_(options) {
}
: functor_(functor), ownership_(ownership), options_(options) {}
virtual ~DynamicNumericDiffCostFunction() {
if (ownership_ != TAKE_OWNERSHIP) {
@@ -91,28 +90,22 @@ class DynamicNumericDiffCostFunction : public CostFunction {
}
}
void AddParameterBlock(int size) {
mutable_parameter_block_sizes()->push_back(size);
}
void SetNumResiduals(int num_residuals) {
set_num_residuals(num_residuals);
}
virtual bool Evaluate(double const* const* parameters,
double* residuals,
double** jacobians) const {
bool Evaluate(double const* const* parameters,
double* residuals,
double** jacobians) const override {
using internal::NumericDiff;
CHECK_GT(num_residuals(), 0)
<< "You must call DynamicNumericDiffCostFunction::SetNumResiduals() "
<< "before DynamicNumericDiffCostFunction::Evaluate().";
const std::vector<int32>& block_sizes = parameter_block_sizes();
const std::vector<int32_t>& block_sizes = parameter_block_sizes();
CHECK(!block_sizes.empty())
<< "You must call DynamicNumericDiffCostFunction::AddParameterBlock() "
<< "before DynamicNumericDiffCostFunction::Evaluate().";
const bool status = EvaluateCostFunctor(parameters, residuals);
const bool status =
internal::VariadicEvaluate<internal::DynamicParameterDims>(
*functor_.get(), parameters, residuals);
if (jacobians == NULL || !status) {
return status;
}
@@ -123,8 +116,8 @@ class DynamicNumericDiffCostFunction : public CostFunction {
std::vector<double*> parameters_references_copy(block_sizes.size());
parameters_references_copy[0] = &parameters_copy[0];
for (size_t block = 1; block < block_sizes.size(); ++block) {
parameters_references_copy[block] = parameters_references_copy[block - 1]
+ block_sizes[block - 1];
parameters_references_copy[block] =
parameters_references_copy[block - 1] + block_sizes[block - 1];
}
// Copy the parameters into the local temp space.
@@ -136,18 +129,20 @@ class DynamicNumericDiffCostFunction : public CostFunction {
for (size_t block = 0; block < block_sizes.size(); ++block) {
if (jacobians[block] != NULL &&
!NumericDiff<CostFunctor, method, DYNAMIC,
DYNAMIC, DYNAMIC, DYNAMIC, DYNAMIC, DYNAMIC,
DYNAMIC, DYNAMIC, DYNAMIC, DYNAMIC, DYNAMIC,
DYNAMIC, DYNAMIC>::EvaluateJacobianForParameterBlock(
functor_.get(),
residuals,
options_,
this->num_residuals(),
block,
block_sizes[block],
&parameters_references_copy[0],
jacobians[block])) {
!NumericDiff<CostFunctor,
method,
ceres::DYNAMIC,
internal::DynamicParameterDims,
ceres::DYNAMIC,
ceres::DYNAMIC>::
EvaluateJacobianForParameterBlock(functor_.get(),
residuals,
options_,
this->num_residuals(),
block,
block_sizes[block],
&parameters_references_copy[0],
jacobians[block])) {
return false;
}
}
@@ -155,31 +150,7 @@ class DynamicNumericDiffCostFunction : public CostFunction {
}
private:
bool EvaluateCostFunctor(double const* const* parameters,
double* residuals) const {
return EvaluateCostFunctorImpl(functor_.get(),
parameters,
residuals,
functor_.get());
}
// Helper templates to allow evaluation of a functor or a
// CostFunction.
bool EvaluateCostFunctorImpl(const CostFunctor* functor,
double const* const* parameters,
double* residuals,
const void* /* NOT USED */) const {
return (*functor)(parameters, residuals);
}
bool EvaluateCostFunctorImpl(const CostFunctor* functor,
double const* const* parameters,
double* residuals,
const CostFunction* /* NOT USED */) const {
return functor->Evaluate(parameters, residuals, NULL);
}
internal::scoped_ptr<const CostFunctor> functor_;
std::unique_ptr<const CostFunctor> functor_;
Ownership ownership_;
NumericDiffOptions options_;
};

View File

@@ -0,0 +1,80 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2019 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// 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 name of Google Inc. 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 OWNER 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.
//
// Author: mierle@gmail.com (Keir Mierle)
#ifndef CERES_PUBLIC_EVALUATION_CALLBACK_H_
#define CERES_PUBLIC_EVALUATION_CALLBACK_H_
#include "ceres/internal/port.h"
namespace ceres {
// Using this callback interface, Ceres can notify you when it is
// about to evaluate the residuals or jacobians. With the callback,
// you can share computation between residual blocks by doing the
// shared computation in PrepareForEvaluation() before Ceres calls
// CostFunction::Evaluate(). It also enables caching results between a
// pure residual evaluation and a residual & jacobian evaluation, via
// the new_evaluation_point argument.
//
// One use case for this callback is if the cost function compute is
// moved to the GPU. In that case, the prepare call does the actual
// cost function evaluation, and subsequent calls from Ceres to the
// actual cost functions merely copy the results from the GPU onto the
// corresponding blocks for Ceres to plug into the solver.
//
// NOTE: Ceres provides no mechanism to share data other than the
// notification from the callback. Users must provide access to
// pre-computed shared data to their cost functions behind the scenes;
// this all happens without Ceres knowing.
//
// One approach is to put a pointer to the shared data in each cost
// function (recommended) or to use a global shared variable
// (discouraged; bug-prone). As far as Ceres is concerned, it is
// evaluating cost functions like any other; it just so happens that
// behind the scenes the cost functions reuse pre-computed data to
// execute faster.
class CERES_EXPORT EvaluationCallback {
public:
virtual ~EvaluationCallback() {}
// Called before Ceres requests residuals or jacobians for a given setting of
// the parameters. User parameters (the double* values provided to the cost
// functions) are fixed until the next call to PrepareForEvaluation(). If
// new_evaluation_point == true, then this is a new point that is different
// from the last evaluated point. Otherwise, it is the same point that was
// evaluated previously (either jacobian or residual) and the user can use
// cached results from previous evaluations.
virtual void PrepareForEvaluation(bool evaluate_jacobians,
bool new_evaluation_point) = 0;
};
} // namespace ceres
#endif // CERES_PUBLIC_EVALUATION_CALLBACK_H_

View File

@@ -0,0 +1,54 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2019 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// 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 name of Google Inc. 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 OWNER 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.
//
// Author: sameeragarwal@google.com (Sameer Agarwal)
#ifndef CERES_PUBLIC_FIRST_ORDER_FUNCTION_H_
#define CERES_PUBLIC_FIRST_ORDER_FUNCTION_H_
#include "ceres/internal/port.h"
namespace ceres {
// A FirstOrderFunction object implements the evaluation of a function
// and its gradient.
class CERES_EXPORT FirstOrderFunction {
public:
virtual ~FirstOrderFunction() {}
// cost is never null. gradient may be null. The return value
// indicates whether the evaluation was successful or not.
virtual bool Evaluate(const double* const parameters,
double* cost,
double* gradient) const = 0;
virtual int NumParameters() const = 0;
};
} // namespace ceres
#endif // CERES_PUBLIC_FIRST_ORDER_FUNCTION_H_

View File

@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2015 Google Inc. All rights reserved.
// Copyright 2019 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// Redistribution and use in source and binary forms, with or without
@@ -34,15 +34,14 @@
#ifndef CERES_PUBLIC_GRADIENT_CHECKER_H_
#define CERES_PUBLIC_GRADIENT_CHECKER_H_
#include <vector>
#include <memory>
#include <string>
#include <vector>
#include "ceres/cost_function.h"
#include "ceres/dynamic_numeric_diff_cost_function.h"
#include "ceres/internal/eigen.h"
#include "ceres/internal/fixed_array.h"
#include "ceres/internal/macros.h"
#include "ceres/internal/scoped_ptr.h"
#include "ceres/local_parameterization.h"
#include "glog/logging.h"
@@ -64,13 +63,13 @@ namespace ceres {
//
// How to use: Fill in an array of pointers to parameter blocks for your
// CostFunction, and then call Probe(). Check that the return value is 'true'.
class GradientChecker {
class CERES_EXPORT GradientChecker {
public:
// This will not take ownership of the cost function or local
// parameterizations.
//
// function: The cost function to probe.
// local_parameterization: A vector of local parameterizations for each
// local_parameterizations: A vector of local parameterizations for each
// parameter. May be NULL or contain NULL pointers to indicate that the
// respective parameter does not have a local parameterization.
// options: Options to use for numerical differentiation.
@@ -80,7 +79,7 @@ class GradientChecker {
const NumericDiffOptions& options);
// Contains results from a call to Probe for later inspection.
struct ProbeResults {
struct CERES_EXPORT ProbeResults {
// The return value of the cost function.
bool return_value;
@@ -100,10 +99,10 @@ class GradientChecker {
// Derivatives as computed by the cost function in local space.
std::vector<Matrix> local_jacobians;
// Derivatives as computed by nuerical differentiation in local space.
// Derivatives as computed by numerical differentiation in local space.
std::vector<Matrix> numeric_jacobians;
// Derivatives as computed by nuerical differentiation in local space.
// Derivatives as computed by numerical differentiation in local space.
std::vector<Matrix> local_numeric_jacobians;
// Contains the maximum relative error found in the local Jacobians.
@@ -137,11 +136,13 @@ class GradientChecker {
ProbeResults* results) const;
private:
CERES_DISALLOW_IMPLICIT_CONSTRUCTORS(GradientChecker);
GradientChecker() = delete;
GradientChecker(const GradientChecker&) = delete;
void operator=(const GradientChecker&) = delete;
std::vector<const LocalParameterization*> local_parameterizations_;
const CostFunction* function_;
internal::scoped_ptr<CostFunction> finite_diff_cost_function_;
std::unique_ptr<CostFunction> finite_diff_cost_function_;
};
} // namespace ceres

View File

@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2015 Google Inc. All rights reserved.
// Copyright 2019 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// Redistribution and use in source and binary forms, with or without
@@ -31,9 +31,10 @@
#ifndef CERES_PUBLIC_GRADIENT_PROBLEM_H_
#define CERES_PUBLIC_GRADIENT_PROBLEM_H_
#include "ceres/internal/macros.h"
#include <memory>
#include "ceres/first_order_function.h"
#include "ceres/internal/port.h"
#include "ceres/internal/scoped_ptr.h"
#include "ceres/local_parameterization.h"
namespace ceres {
@@ -105,21 +106,9 @@ class CERES_EXPORT GradientProblem {
bool Plus(const double* x, const double* delta, double* x_plus_delta) const;
private:
internal::scoped_ptr<FirstOrderFunction> function_;
internal::scoped_ptr<LocalParameterization> parameterization_;
internal::scoped_array<double> scratch_;
};
// A FirstOrderFunction object implements the evaluation of a function
// and its gradient.
class CERES_EXPORT FirstOrderFunction {
public:
virtual ~FirstOrderFunction() {}
// cost is never NULL. gradient may be null.
virtual bool Evaluate(const double* const parameters,
double* cost,
double* gradient) const = 0;
virtual int NumParameters() const = 0;
std::unique_ptr<FirstOrderFunction> function_;
std::unique_ptr<LocalParameterization> parameterization_;
std::unique_ptr<double[]> scratch_;
};
} // namespace ceres

View File

@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2015 Google Inc. All rights reserved.
// Copyright 2019 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// Redistribution and use in source and binary forms, with or without
@@ -34,11 +34,11 @@
#include <cmath>
#include <string>
#include <vector>
#include "ceres/internal/macros.h"
#include "ceres/internal/disable_warnings.h"
#include "ceres/internal/port.h"
#include "ceres/iteration_callback.h"
#include "ceres/types.h"
#include "ceres/internal/disable_warnings.h"
namespace ceres {
@@ -54,39 +54,15 @@ class CERES_EXPORT GradientProblemSolver {
//
// The constants are defined inside types.h
struct CERES_EXPORT Options {
// Default constructor that sets up a generic sparse problem.
Options() {
line_search_direction_type = LBFGS;
line_search_type = WOLFE;
nonlinear_conjugate_gradient_type = FLETCHER_REEVES;
max_lbfgs_rank = 20;
use_approximate_eigenvalue_bfgs_scaling = false;
line_search_interpolation_type = CUBIC;
min_line_search_step_size = 1e-9;
line_search_sufficient_function_decrease = 1e-4;
max_line_search_step_contraction = 1e-3;
min_line_search_step_contraction = 0.6;
max_num_line_search_step_size_iterations = 20;
max_num_line_search_direction_restarts = 5;
line_search_sufficient_curvature_decrease = 0.9;
max_line_search_step_expansion = 10.0;
max_num_iterations = 50;
max_solver_time_in_seconds = 1e9;
function_tolerance = 1e-6;
gradient_tolerance = 1e-10;
logging_type = PER_MINIMIZER_ITERATION;
minimizer_progress_to_stdout = false;
}
// Returns true if the options struct has a valid
// configuration. Returns false otherwise, and fills in *error
// with a message describing the problem.
bool IsValid(std::string* error) const;
// Minimizer options ----------------------------------------
LineSearchDirectionType line_search_direction_type;
LineSearchType line_search_type;
NonlinearConjugateGradientType nonlinear_conjugate_gradient_type;
LineSearchDirectionType line_search_direction_type = LBFGS;
LineSearchType line_search_type = WOLFE;
NonlinearConjugateGradientType nonlinear_conjugate_gradient_type = FLETCHER_REEVES;
// The LBFGS hessian approximation is a low rank approximation to
// the inverse of the Hessian matrix. The rank of the
@@ -111,8 +87,8 @@ class CERES_EXPORT GradientProblemSolver {
// method, please see:
//
// Nocedal, J. (1980). "Updating Quasi-Newton Matrices with
// Limited Storage". Mathematics of Computation 35 (151): 773782.
int max_lbfgs_rank;
// Limited Storage". Mathematics of Computation 35 (151): 773-782.
int max_lbfgs_rank = 20;
// As part of the (L)BFGS update step (BFGS) / right-multiply step (L-BFGS),
// the initial inverse Hessian approximation is taken to be the Identity.
@@ -134,18 +110,18 @@ class CERES_EXPORT GradientProblemSolver {
// Oren S.S., Self-scaling variable metric (SSVM) algorithms
// Part II: Implementation and experiments, Management Science,
// 20(5), 863-874, 1974.
bool use_approximate_eigenvalue_bfgs_scaling;
bool use_approximate_eigenvalue_bfgs_scaling = false;
// Degree of the polynomial used to approximate the objective
// function. Valid values are BISECTION, QUADRATIC and CUBIC.
//
// BISECTION corresponds to pure backtracking search with no
// interpolation.
LineSearchInterpolationType line_search_interpolation_type;
LineSearchInterpolationType line_search_interpolation_type = CUBIC;
// If during the line search, the step_size falls below this
// value, it is truncated to zero.
double min_line_search_step_size;
double min_line_search_step_size = 1e-9;
// Line search parameters.
@@ -159,7 +135,7 @@ class CERES_EXPORT GradientProblemSolver {
//
// f(step_size) <= f(0) + sufficient_decrease * f'(0) * step_size
//
double line_search_sufficient_function_decrease;
double line_search_sufficient_function_decrease = 1e-4;
// In each iteration of the line search,
//
@@ -169,7 +145,7 @@ class CERES_EXPORT GradientProblemSolver {
//
// 0 < max_step_contraction < min_step_contraction < 1
//
double max_line_search_step_contraction;
double max_line_search_step_contraction = 1e-3;
// In each iteration of the line search,
//
@@ -179,19 +155,19 @@ class CERES_EXPORT GradientProblemSolver {
//
// 0 < max_step_contraction < min_step_contraction < 1
//
double min_line_search_step_contraction;
double min_line_search_step_contraction = 0.6;
// Maximum number of trial step size iterations during each line search,
// if a step size satisfying the search conditions cannot be found within
// this number of trials, the line search will terminate.
int max_num_line_search_step_size_iterations;
int max_num_line_search_step_size_iterations = 20;
// Maximum number of restarts of the line search direction algorithm before
// terminating the optimization. Restarts of the line search direction
// algorithm occur when the current algorithm fails to produce a new descent
// direction. This typically indicates a numerical failure, or a breakdown
// in the validity of the approximations used.
int max_num_line_search_direction_restarts;
int max_num_line_search_direction_restarts = 5;
// The strong Wolfe conditions consist of the Armijo sufficient
// decrease condition, and an additional requirement that the
@@ -204,7 +180,7 @@ class CERES_EXPORT GradientProblemSolver {
//
// Where f() is the line search objective and f'() is the derivative
// of f w.r.t step_size (d f / d step_size).
double line_search_sufficient_curvature_decrease;
double line_search_sufficient_curvature_decrease = 0.9;
// During the bracketing phase of the Wolfe search, the step size is
// increased until either a point satisfying the Wolfe conditions is
@@ -215,36 +191,49 @@ class CERES_EXPORT GradientProblemSolver {
// new_step_size <= max_step_expansion * step_size.
//
// By definition for expansion, max_step_expansion > 1.0.
double max_line_search_step_expansion;
double max_line_search_step_expansion = 10.0;
// Maximum number of iterations for the minimizer to run for.
int max_num_iterations;
int max_num_iterations = 50;
// Maximum time for which the minimizer should run for.
double max_solver_time_in_seconds;
double max_solver_time_in_seconds = 1e9;
// Minimizer terminates when
//
// (new_cost - old_cost) < function_tolerance * old_cost;
//
double function_tolerance;
double function_tolerance = 1e-6;
// Minimizer terminates when
//
// max_i |x - Project(Plus(x, -g(x))| < gradient_tolerance
//
// This value should typically be 1e-4 * function_tolerance.
double gradient_tolerance;
double gradient_tolerance = 1e-10;
// Minimizer terminates when
//
// |step|_2 <= parameter_tolerance * ( |x|_2 + parameter_tolerance)
//
double parameter_tolerance = 1e-8;
// Logging options ---------------------------------------------------------
LoggingType logging_type;
LoggingType logging_type = PER_MINIMIZER_ITERATION;
// By default the Minimizer progress is logged to VLOG(1), which
// is sent to STDERR depending on the vlog level. If this flag is
// set to true, and logging_type is not SILENT, the logging output
// is sent to STDOUT.
bool minimizer_progress_to_stdout;
bool minimizer_progress_to_stdout = false;
// If true, the user's parameter blocks are updated at the end of
// every Minimizer iteration, otherwise they are updated when the
// Minimizer terminates. This is useful if, for example, the user
// wishes to visualize the state of the optimization every
// iteration.
bool update_state_every_iteration = false;
// Callbacks that are executed at the end of each iteration of the
// Minimizer. An iteration may terminate midway, either due to
@@ -265,8 +254,6 @@ class CERES_EXPORT GradientProblemSolver {
};
struct CERES_EXPORT Summary {
Summary();
// A brief one line description of the state of the solver after
// termination.
std::string BriefReport() const;
@@ -278,65 +265,72 @@ class CERES_EXPORT GradientProblemSolver {
bool IsSolutionUsable() const;
// Minimizer summary -------------------------------------------------
TerminationType termination_type;
TerminationType termination_type = FAILURE;
// Reason why the solver terminated.
std::string message;
std::string message = "ceres::GradientProblemSolve was not called.";
// Cost of the problem (value of the objective function) before
// the optimization.
double initial_cost;
double initial_cost = -1.0;
// Cost of the problem (value of the objective function) after the
// optimization.
double final_cost;
double final_cost = -1.0;
// IterationSummary for each minimizer iteration in order.
std::vector<IterationSummary> iterations;
// Number of times the cost (and not the gradient) was evaluated.
int num_cost_evaluations = -1;
// Number of times the gradient (and the cost) were evaluated.
int num_gradient_evaluations = -1;
// Sum total of all time spent inside Ceres when Solve is called.
double total_time_in_seconds;
double total_time_in_seconds = -1.0;
// Time (in seconds) spent evaluating the cost.
double cost_evaluation_time_in_seconds;
double cost_evaluation_time_in_seconds = -1.0;
// Time (in seconds) spent evaluating the gradient.
double gradient_evaluation_time_in_seconds;
double gradient_evaluation_time_in_seconds = -1.0;
// Time (in seconds) spent minimizing the interpolating polynomial
// to compute the next candidate step size as part of a line search.
double line_search_polynomial_minimization_time_in_seconds;
double line_search_polynomial_minimization_time_in_seconds = -1.0;
// Number of parameters in the probem.
int num_parameters;
// Number of parameters in the problem.
int num_parameters = -1;
// Dimension of the tangent space of the problem.
int num_local_parameters;
int num_local_parameters = -1;
// Type of line search direction used.
LineSearchDirectionType line_search_direction_type;
LineSearchDirectionType line_search_direction_type = LBFGS;
// Type of the line search algorithm used.
LineSearchType line_search_type;
LineSearchType line_search_type = WOLFE;
// When performing line search, the degree of the polynomial used
// to approximate the objective function.
LineSearchInterpolationType line_search_interpolation_type;
LineSearchInterpolationType line_search_interpolation_type = CUBIC;
// If the line search direction is NONLINEAR_CONJUGATE_GRADIENT,
// then this indicates the particular variant of non-linear
// conjugate gradient used.
NonlinearConjugateGradientType nonlinear_conjugate_gradient_type;
NonlinearConjugateGradientType nonlinear_conjugate_gradient_type =
FLETCHER_REEVES;
// If the type of the line search direction is LBFGS, then this
// indicates the rank of the Hessian approximation.
int max_lbfgs_rank;
int max_lbfgs_rank = -1;
};
// Once a least squares problem has been built, this function takes
// the problem and optimizes it based on the values of the options
// parameters. Upon return, a detailed summary of the work performed
// by the preprocessor, the non-linear minmizer and the linear
// by the preprocessor, the non-linear minimizer and the linear
// solver are reported in the summary object.
virtual void Solve(const GradientProblemSolver::Options& options,
const GradientProblem& problem,

View File

@@ -0,0 +1,95 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2020 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// 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 name of Google Inc. 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 OWNER 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.
//
// Author: darius.rueckert@fau.de (Darius Rueckert)
//
#ifndef CERES_PUBLIC_INTERNAL_ARRAY_SELECTOR_H_
#define CERES_PUBLIC_INTERNAL_ARRAY_SELECTOR_H_
#include <array>
#include <vector>
#include "ceres/internal/fixed_array.h"
#include "ceres/types.h"
namespace ceres {
namespace internal {
// StaticFixedArray selects the best array implementation based on template
// arguments. If the size is not known at compile-time, pass
// ceres::DYNAMIC as a size-template argument.
//
// Three different containers are selected in different scenarios:
//
// num_elements == DYNAMIC:
// -> ceres::internal::FixedArray<T, max_stack_size>(size)
// num_elements != DYNAMIC && num_elements <= max_stack_size
// -> std::array<T,num_elements>
// num_elements != DYNAMIC && num_elements > max_stack_size
// -> std::vector<T>(num_elements)
//
template <typename T,
int num_elements,
int max_num_elements_on_stack,
bool dynamic = (num_elements == DYNAMIC),
bool fits_on_stack = (num_elements <= max_num_elements_on_stack)>
struct ArraySelector {};
template <typename T,
int num_elements,
int max_num_elements_on_stack,
bool fits_on_stack>
struct ArraySelector<T,
num_elements,
max_num_elements_on_stack,
true,
fits_on_stack>
: ceres::internal::FixedArray<T, max_num_elements_on_stack> {
ArraySelector(int s)
: ceres::internal::FixedArray<T, max_num_elements_on_stack>(s) {}
};
template <typename T, int num_elements, int max_num_elements_on_stack>
struct ArraySelector<T, num_elements, max_num_elements_on_stack, false, true>
: std::array<T, num_elements> {
ArraySelector(int s) { CHECK_EQ(s, num_elements); }
};
template <typename T, int num_elements, int max_num_elements_on_stack>
struct ArraySelector<T, num_elements, max_num_elements_on_stack, false, false>
: std::vector<T> {
ArraySelector(int s) : std::vector<T>(s) { CHECK_EQ(s, num_elements); }
};
} // namespace internal
} // namespace ceres
#endif // CERES_PUBLIC_INTERNAL_ARRAY_SELECTOR_H_

View File

@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2015 Google Inc. All rights reserved.
// Copyright 2019 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// Redistribution and use in source and binary forms, with or without
@@ -30,10 +30,10 @@
//
// Computation of the Jacobian matrix for vector-valued functions of multiple
// variables, using automatic differentiation based on the implementation of
// dual numbers in jet.h. Before reading the rest of this file, it is adivsable
// dual numbers in jet.h. Before reading the rest of this file, it is advisable
// to read jet.h's header comment in detail.
//
// The helper wrapper AutoDiff::Differentiate() computes the jacobian of
// The helper wrapper AutoDifferentiate() computes the jacobian of
// functors with templated operator() taking this form:
//
// struct F {
@@ -57,7 +57,7 @@
// [ * ]
//
// Similar to the 2-parameter example for f described in jet.h, computing the
// jacobian dy/dx is done by substutiting a suitable jet object for x and all
// jacobian dy/dx is done by substituting a suitable jet object for x and all
// intermediate steps of the computation of F. Since x is has 4 dimensions, use
// a Jet<double, 4>.
//
@@ -142,16 +142,33 @@
#include <stddef.h>
#include "ceres/jet.h"
#include <array>
#include <utility>
#include "ceres/internal/array_selector.h"
#include "ceres/internal/eigen.h"
#include "ceres/internal/fixed_array.h"
#include "ceres/internal/parameter_dims.h"
#include "ceres/internal/variadic_evaluate.h"
#include "ceres/jet.h"
#include "ceres/types.h"
#include "glog/logging.h"
// If the number of parameters exceeds this values, the corresponding jets are
// placed on the heap. This will reduce performance by a factor of 2-5 on
// current compilers.
#ifndef CERES_AUTODIFF_MAX_PARAMETERS_ON_STACK
#define CERES_AUTODIFF_MAX_PARAMETERS_ON_STACK 50
#endif
#ifndef CERES_AUTODIFF_MAX_RESIDUALS_ON_STACK
#define CERES_AUTODIFF_MAX_RESIDUALS_ON_STACK 20
#endif
namespace ceres {
namespace internal {
// Extends src by a 1st order pertubation for every dimension and puts it in
// Extends src by a 1st order perturbation for every dimension and puts it in
// dst. The size of src is N. Since this is also used for perturbations in
// blocked arrays, offset is used to shift which part of the jet the
// perturbation occurs. This is used to set up the extended x augmented by an
@@ -165,21 +182,62 @@ namespace internal {
//
// is what would get put in dst if N was 3, offset was 3, and the jet type JetT
// was 8-dimensional.
template <typename JetT, typename T, int N>
inline void Make1stOrderPerturbation(int offset, const T* src, JetT* dst) {
DCHECK(src);
DCHECK(dst);
for (int j = 0; j < N; ++j) {
dst[j].a = src[j];
dst[j].v.setZero();
dst[j].v[offset + j] = T(1.0);
template <int j, int N, int Offset, typename T, typename JetT>
struct Make1stOrderPerturbation {
public:
inline static void Apply(const T* src, JetT* dst) {
if (j == 0) {
DCHECK(src);
DCHECK(dst);
}
dst[j] = JetT(src[j], j + Offset);
Make1stOrderPerturbation<j + 1, N, Offset, T, JetT>::Apply(src, dst);
}
}
};
template <int N, int Offset, typename T, typename JetT>
struct Make1stOrderPerturbation<N, N, Offset, T, JetT> {
public:
static void Apply(const T* /*src*/, JetT* /*dst*/) {}
};
// Calls Make1stOrderPerturbation for every parameter block.
//
// Example:
// If one having three parameter blocks with dimensions (3, 2, 4), the call
// Make1stOrderPerturbations<integer_sequence<3, 2, 4>::Apply(params, x);
// will result in the following calls to Make1stOrderPerturbation:
// Make1stOrderPerturbation<0, 3, 0>::Apply(params[0], x + 0);
// Make1stOrderPerturbation<0, 2, 3>::Apply(params[1], x + 3);
// Make1stOrderPerturbation<0, 4, 5>::Apply(params[2], x + 5);
template <typename Seq, int ParameterIdx = 0, int Offset = 0>
struct Make1stOrderPerturbations;
template <int N, int... Ns, int ParameterIdx, int Offset>
struct Make1stOrderPerturbations<std::integer_sequence<int, N, Ns...>,
ParameterIdx,
Offset> {
template <typename T, typename JetT>
inline static void Apply(T const* const* parameters, JetT* x) {
Make1stOrderPerturbation<0, N, Offset, T, JetT>::Apply(
parameters[ParameterIdx], x + Offset);
Make1stOrderPerturbations<std::integer_sequence<int, Ns...>,
ParameterIdx + 1,
Offset + N>::Apply(parameters, x);
}
};
// End of 'recursion'. Nothing more to do.
template <int ParameterIdx, int Total>
struct Make1stOrderPerturbations<std::integer_sequence<int>, ParameterIdx, Total> {
template <typename T, typename JetT>
static void Apply(T const* const* /* NOT USED */, JetT* /* NOT USED */) {}
};
// Takes the 0th order part of src, assumed to be a Jet type, and puts it in
// dst. This is used to pick out the "vector" part of the extended y.
template <typename JetT, typename T>
inline void Take0thOrderPart(int M, const JetT *src, T dst) {
inline void Take0thOrderPart(int M, const JetT* src, T dst) {
DCHECK(src);
for (int i = 0; i < M; ++i) {
dst[i] = src[i].a;
@@ -188,129 +246,118 @@ inline void Take0thOrderPart(int M, const JetT *src, T dst) {
// Takes N 1st order parts, starting at index N0, and puts them in the M x N
// matrix 'dst'. This is used to pick out the "matrix" parts of the extended y.
template <typename JetT, typename T, int N0, int N>
inline void Take1stOrderPart(const int M, const JetT *src, T *dst) {
template <int N0, int N, typename JetT, typename T>
inline void Take1stOrderPart(const int M, const JetT* src, T* dst) {
DCHECK(src);
DCHECK(dst);
for (int i = 0; i < M; ++i) {
Eigen::Map<Eigen::Matrix<T, N, 1> >(dst + N * i, N) =
Eigen::Map<Eigen::Matrix<T, N, 1>>(dst + N * i, N) =
src[i].v.template segment<N>(N0);
}
}
// This is in a struct because default template parameters on a
// function are not supported in C++03 (though it is available in
// C++0x). N0 through N5 are the dimension of the input arguments to
// the user supplied functor.
template <typename Functor, typename T,
int N0 = 0, int N1 = 0, int N2 = 0, int N3 = 0, int N4 = 0,
int N5 = 0, int N6 = 0, int N7 = 0, int N8 = 0, int N9 = 0>
struct AutoDiff {
static bool Differentiate(const Functor& functor,
T const *const *parameters,
int num_outputs,
T *function_value,
T **jacobians) {
// This block breaks the 80 column rule to keep it somewhat readable.
DCHECK_GT(num_outputs, 0);
DCHECK((!N1 && !N2 && !N3 && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||
((N1 > 0) && !N2 && !N3 && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||
((N1 > 0) && (N2 > 0) && !N3 && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) || // NOLINT
((N1 > 0) && (N2 > 0) && (N3 > 0) && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) || // NOLINT
((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && !N5 && !N6 && !N7 && !N8 && !N9) || // NOLINT
((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && !N6 && !N7 && !N8 && !N9) || // NOLINT
((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && !N7 && !N8 && !N9) || // NOLINT
((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && (N7 > 0) && !N8 && !N9) || // NOLINT
((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && (N7 > 0) && (N8 > 0) && !N9) || // NOLINT
((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && (N7 > 0) && (N8 > 0) && (N9 > 0))) // NOLINT
<< "Zero block cannot precede a non-zero block. Block sizes are "
<< "(ignore trailing 0s): " << N0 << ", " << N1 << ", " << N2 << ", "
<< N3 << ", " << N4 << ", " << N5 << ", " << N6 << ", " << N7 << ", "
<< N8 << ", " << N9;
// Calls Take1stOrderPart for every parameter block.
//
// Example:
// If one having three parameter blocks with dimensions (3, 2, 4), the call
// Take1stOrderParts<integer_sequence<3, 2, 4>::Apply(num_outputs,
// output,
// jacobians);
// will result in the following calls to Take1stOrderPart:
// if (jacobians[0]) {
// Take1stOrderPart<0, 3>(num_outputs, output, jacobians[0]);
// }
// if (jacobians[1]) {
// Take1stOrderPart<3, 2>(num_outputs, output, jacobians[1]);
// }
// if (jacobians[2]) {
// Take1stOrderPart<5, 4>(num_outputs, output, jacobians[2]);
// }
template <typename Seq, int ParameterIdx = 0, int Offset = 0>
struct Take1stOrderParts;
typedef Jet<T, N0 + N1 + N2 + N3 + N4 + N5 + N6 + N7 + N8 + N9> JetT;
FixedArray<JetT, (256 * 7) / sizeof(JetT)> x(
N0 + N1 + N2 + N3 + N4 + N5 + N6 + N7 + N8 + N9 + num_outputs);
// These are the positions of the respective jets in the fixed array x.
const int jet0 = 0;
const int jet1 = N0;
const int jet2 = N0 + N1;
const int jet3 = N0 + N1 + N2;
const int jet4 = N0 + N1 + N2 + N3;
const int jet5 = N0 + N1 + N2 + N3 + N4;
const int jet6 = N0 + N1 + N2 + N3 + N4 + N5;
const int jet7 = N0 + N1 + N2 + N3 + N4 + N5 + N6;
const int jet8 = N0 + N1 + N2 + N3 + N4 + N5 + N6 + N7;
const int jet9 = N0 + N1 + N2 + N3 + N4 + N5 + N6 + N7 + N8;
const JetT *unpacked_parameters[10] = {
x.get() + jet0,
x.get() + jet1,
x.get() + jet2,
x.get() + jet3,
x.get() + jet4,
x.get() + jet5,
x.get() + jet6,
x.get() + jet7,
x.get() + jet8,
x.get() + jet9,
};
JetT* output = x.get() + N0 + N1 + N2 + N3 + N4 + N5 + N6 + N7 + N8 + N9;
#define CERES_MAKE_1ST_ORDER_PERTURBATION(i) \
if (N ## i) { \
internal::Make1stOrderPerturbation<JetT, T, N ## i>( \
jet ## i, \
parameters[i], \
x.get() + jet ## i); \
template <int N, int... Ns, int ParameterIdx, int Offset>
struct Take1stOrderParts<std::integer_sequence<int, N, Ns...>,
ParameterIdx,
Offset> {
template <typename JetT, typename T>
inline static void Apply(int num_outputs, JetT* output, T** jacobians) {
if (jacobians[ParameterIdx]) {
Take1stOrderPart<Offset, N>(num_outputs, output, jacobians[ParameterIdx]);
}
CERES_MAKE_1ST_ORDER_PERTURBATION(0);
CERES_MAKE_1ST_ORDER_PERTURBATION(1);
CERES_MAKE_1ST_ORDER_PERTURBATION(2);
CERES_MAKE_1ST_ORDER_PERTURBATION(3);
CERES_MAKE_1ST_ORDER_PERTURBATION(4);
CERES_MAKE_1ST_ORDER_PERTURBATION(5);
CERES_MAKE_1ST_ORDER_PERTURBATION(6);
CERES_MAKE_1ST_ORDER_PERTURBATION(7);
CERES_MAKE_1ST_ORDER_PERTURBATION(8);
CERES_MAKE_1ST_ORDER_PERTURBATION(9);
#undef CERES_MAKE_1ST_ORDER_PERTURBATION
if (!VariadicEvaluate<Functor, JetT,
N0, N1, N2, N3, N4, N5, N6, N7, N8, N9>::Call(
functor, unpacked_parameters, output)) {
return false;
}
internal::Take0thOrderPart(num_outputs, output, function_value);
#define CERES_TAKE_1ST_ORDER_PERTURBATION(i) \
if (N ## i) { \
if (jacobians[i]) { \
internal::Take1stOrderPart<JetT, T, \
jet ## i, \
N ## i>(num_outputs, \
output, \
jacobians[i]); \
} \
}
CERES_TAKE_1ST_ORDER_PERTURBATION(0);
CERES_TAKE_1ST_ORDER_PERTURBATION(1);
CERES_TAKE_1ST_ORDER_PERTURBATION(2);
CERES_TAKE_1ST_ORDER_PERTURBATION(3);
CERES_TAKE_1ST_ORDER_PERTURBATION(4);
CERES_TAKE_1ST_ORDER_PERTURBATION(5);
CERES_TAKE_1ST_ORDER_PERTURBATION(6);
CERES_TAKE_1ST_ORDER_PERTURBATION(7);
CERES_TAKE_1ST_ORDER_PERTURBATION(8);
CERES_TAKE_1ST_ORDER_PERTURBATION(9);
#undef CERES_TAKE_1ST_ORDER_PERTURBATION
return true;
Take1stOrderParts<std::integer_sequence<int, Ns...>,
ParameterIdx + 1,
Offset + N>::Apply(num_outputs, output, jacobians);
}
};
// End of 'recursion'. Nothing more to do.
template <int ParameterIdx, int Offset>
struct Take1stOrderParts<std::integer_sequence<int>, ParameterIdx, Offset> {
template <typename T, typename JetT>
static void Apply(int /* NOT USED*/,
JetT* /* NOT USED*/,
T** /* NOT USED */) {}
};
template <int kNumResiduals,
typename ParameterDims,
typename Functor,
typename T>
inline bool AutoDifferentiate(const Functor& functor,
T const* const* parameters,
int dynamic_num_outputs,
T* function_value,
T** jacobians) {
typedef Jet<T, ParameterDims::kNumParameters> JetT;
using Parameters = typename ParameterDims::Parameters;
if (kNumResiduals != DYNAMIC) {
DCHECK_EQ(kNumResiduals, dynamic_num_outputs);
}
ArraySelector<JetT,
ParameterDims::kNumParameters,
CERES_AUTODIFF_MAX_PARAMETERS_ON_STACK>
parameters_as_jets(ParameterDims::kNumParameters);
// Pointers to the beginning of each parameter block
std::array<JetT*, ParameterDims::kNumParameterBlocks> unpacked_parameters =
ParameterDims::GetUnpackedParameters(parameters_as_jets.data());
// If the number of residuals is fixed, we use the template argument as the
// number of outputs. Otherwise we use the num_outputs parameter. Note: The
// ?-operator here is compile-time evaluated, therefore num_outputs is also
// a compile-time constant for functors with fixed residuals.
const int num_outputs =
kNumResiduals == DYNAMIC ? dynamic_num_outputs : kNumResiduals;
DCHECK_GT(num_outputs, 0);
ArraySelector<JetT, kNumResiduals, CERES_AUTODIFF_MAX_RESIDUALS_ON_STACK>
residuals_as_jets(num_outputs);
// Invalidate the output Jets, so that we can detect if the user
// did not assign values to all of them.
for (int i = 0; i < num_outputs; ++i) {
residuals_as_jets[i].a = kImpossibleValue;
residuals_as_jets[i].v.setConstant(kImpossibleValue);
}
Make1stOrderPerturbations<Parameters>::Apply(parameters,
parameters_as_jets.data());
if (!VariadicEvaluate<ParameterDims>(
functor, unpacked_parameters.data(), residuals_as_jets.data())) {
return false;
}
Take0thOrderPart(num_outputs, residuals_as_jets.data(), function_value);
Take1stOrderParts<Parameters>::Apply(
num_outputs, residuals_as_jets.data(), jacobians);
return true;
}
} // namespace internal
} // namespace ceres

View File

@@ -35,7 +35,7 @@
#ifdef _MSC_VER
#pragma warning( push )
// Disable the warning C4251 which is trigerred by stl classes in
// Disable the warning C4251 which is triggered by stl classes in
// Ceres' public interface. To quote MSDN: "C4251 can be ignored "
// "if you are deriving from a type in the Standard C++ Library"
#pragma warning( disable : 4251 )

View File

@@ -52,40 +52,27 @@ typedef Eigen::Matrix<double,
Eigen::ColMajor> ColMajorMatrix;
typedef Eigen::Map<ColMajorMatrix, 0,
Eigen::Stride<Eigen::Dynamic, 1> > ColMajorMatrixRef;
Eigen::Stride<Eigen::Dynamic, 1>> ColMajorMatrixRef;
typedef Eigen::Map<const ColMajorMatrix,
0,
Eigen::Stride<Eigen::Dynamic, 1> > ConstColMajorMatrixRef;
Eigen::Stride<Eigen::Dynamic, 1>> ConstColMajorMatrixRef;
// C++ does not support templated typdefs, thus the need for this
// struct so that we can support statically sized Matrix and Maps.
template <int num_rows = Eigen::Dynamic, int num_cols = Eigen::Dynamic>
template <int num_rows = Eigen::Dynamic, int num_cols = Eigen::Dynamic>
struct EigenTypes {
typedef Eigen::Matrix <double, num_rows, num_cols, Eigen::RowMajor>
Matrix;
typedef Eigen::Matrix<double,
num_rows,
num_cols,
num_cols == 1 ? Eigen::ColMajor : Eigen::RowMajor>
Matrix;
typedef Eigen::Map<
Eigen::Matrix<double, num_rows, num_cols, Eigen::RowMajor> >
MatrixRef;
typedef Eigen::Matrix <double, num_rows, 1>
Vector;
typedef Eigen::Map <
Eigen::Matrix<double, num_rows, 1> >
VectorRef;
typedef Eigen::Map<
const Eigen::Matrix<double, num_rows, num_cols, Eigen::RowMajor> >
ConstMatrixRef;
typedef Eigen::Map <
const Eigen::Matrix<double, num_rows, 1> >
ConstVectorRef;
typedef Eigen::Map<Matrix> MatrixRef;
typedef Eigen::Map<const Matrix> ConstMatrixRef;
typedef Eigen::Matrix<double, num_rows, 1> Vector;
typedef Eigen::Map<Eigen::Matrix<double, num_rows, 1>> VectorRef;
typedef Eigen::Map<const Eigen::Matrix<double, num_rows, 1>> ConstVectorRef;
};
} // namespace ceres

View File

@@ -1,189 +1,466 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2015 Google Inc. All rights reserved.
// http://ceres-solver.org/
// Copyright 2018 The Abseil Authors.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// * 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 name of Google Inc. nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
// https://www.apache.org/licenses/LICENSE-2.0
//
// 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 OWNER 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.
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: rennie@google.com (Jeffrey Rennie)
// Author: sanjay@google.com (Sanjay Ghemawat) -- renamed to FixedArray
// -----------------------------------------------------------------------------
// File: fixed_array.h
// -----------------------------------------------------------------------------
//
// A `FixedArray<T>` represents a non-resizable array of `T` where the length of
// the array can be determined at run-time. It is a good replacement for
// non-standard and deprecated uses of `alloca()` and variable length arrays
// within the GCC extension. (See
// https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html).
//
// `FixedArray` allocates small arrays inline, keeping performance fast by
// avoiding heap operations. It also helps reduce the chances of
// accidentally overflowing your stack if large input is passed to
// your function.
#ifndef CERES_PUBLIC_INTERNAL_FIXED_ARRAY_H_
#define CERES_PUBLIC_INTERNAL_FIXED_ARRAY_H_
#include <algorithm>
#include <array>
#include <cstddef>
#include "Eigen/Core"
#include "ceres/internal/macros.h"
#include "ceres/internal/manual_constructor.h"
#include <memory>
#include <tuple>
#include <type_traits>
#include <Eigen/Core> // For Eigen::aligned_allocator
#include "ceres/internal/memory.h"
#include "glog/logging.h"
namespace ceres {
namespace internal {
// A FixedArray<T> represents a non-resizable array of T where the
// length of the array does not need to be a compile time constant.
//
// FixedArray allocates small arrays inline, and large arrays on
// the heap. It is a good replacement for non-standard and deprecated
// uses of alloca() and variable length arrays (a GCC extension).
//
// FixedArray keeps performance fast for small arrays, because it
// avoids heap operations. It also helps reduce the chances of
// accidentally overflowing your stack if large input is passed to
// your function.
//
// Also, FixedArray is useful for writing portable code. Not all
// compilers support arrays of dynamic size.
constexpr static auto kFixedArrayUseDefault = static_cast<size_t>(-1);
// Most users should not specify an inline_elements argument and let
// FixedArray<> automatically determine the number of elements
// to store inline based on sizeof(T).
// The default fixed array allocator.
//
// If inline_elements is specified, the FixedArray<> implementation
// will store arrays of length <= inline_elements inline.
//
// Finally note that unlike vector<T> FixedArray<T> will not zero-initialize
// simple types like int, double, bool, etc.
//
// Non-POD types will be default-initialized just like regular vectors or
// arrays.
// As one can not easily detect if a struct contains or inherits from a fixed
// size Eigen type, to be safe the Eigen::aligned_allocator is used by default.
// But trivial types can never contain Eigen types, so std::allocator is used to
// safe some heap memory.
template <typename T>
using FixedArrayDefaultAllocator =
typename std::conditional<std::is_trivial<T>::value,
std::allocator<T>,
Eigen::aligned_allocator<T>>::type;
#if defined(_WIN64)
typedef __int64 ssize_t;
#elif defined(_WIN32)
typedef __int32 ssize_t;
#endif
template <typename T, ssize_t inline_elements = -1>
// -----------------------------------------------------------------------------
// FixedArray
// -----------------------------------------------------------------------------
//
// A `FixedArray` provides a run-time fixed-size array, allocating a small array
// inline for efficiency.
//
// Most users should not specify an `inline_elements` argument and let
// `FixedArray` automatically determine the number of elements
// to store inline based on `sizeof(T)`. If `inline_elements` is specified, the
// `FixedArray` implementation will use inline storage for arrays with a
// length <= `inline_elements`.
//
// Note that a `FixedArray` constructed with a `size_type` argument will
// default-initialize its values by leaving trivially constructible types
// uninitialized (e.g. int, int[4], double), and others default-constructed.
// This matches the behavior of c-style arrays and `std::array`, but not
// `std::vector`.
//
// Note that `FixedArray` does not provide a public allocator; if it requires a
// heap allocation, it will do so with global `::operator new[]()` and
// `::operator delete[]()`, even if T provides class-scope overrides for these
// operators.
template <typename T,
size_t N = kFixedArrayUseDefault,
typename A = FixedArrayDefaultAllocator<T>>
class FixedArray {
static_assert(!std::is_array<T>::value || std::extent<T>::value > 0,
"Arrays with unknown bounds cannot be used with FixedArray.");
static constexpr size_t kInlineBytesDefault = 256;
using AllocatorTraits = std::allocator_traits<A>;
// std::iterator_traits isn't guaranteed to be SFINAE-friendly until C++17,
// but this seems to be mostly pedantic.
template <typename Iterator>
using EnableIfForwardIterator = typename std::enable_if<std::is_convertible<
typename std::iterator_traits<Iterator>::iterator_category,
std::forward_iterator_tag>::value>::type;
static constexpr bool DefaultConstructorIsNonTrivial() {
return !std::is_trivially_default_constructible<StorageElement>::value;
}
public:
// For playing nicely with stl:
typedef T value_type;
typedef T* iterator;
typedef T const* const_iterator;
typedef T& reference;
typedef T const& const_reference;
typedef T* pointer;
typedef std::ptrdiff_t difference_type;
typedef size_t size_type;
using allocator_type = typename AllocatorTraits::allocator_type;
using value_type = typename AllocatorTraits::value_type;
using pointer = typename AllocatorTraits::pointer;
using const_pointer = typename AllocatorTraits::const_pointer;
using reference = value_type&;
using const_reference = const value_type&;
using size_type = typename AllocatorTraits::size_type;
using difference_type = typename AllocatorTraits::difference_type;
using iterator = pointer;
using const_iterator = const_pointer;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
// REQUIRES: n >= 0
// Creates an array object that can store "n" elements.
static constexpr size_type inline_elements =
(N == kFixedArrayUseDefault ? kInlineBytesDefault / sizeof(value_type)
: static_cast<size_type>(N));
FixedArray(const FixedArray& other,
const allocator_type& a = allocator_type())
: FixedArray(other.begin(), other.end(), a) {}
FixedArray(FixedArray&& other, const allocator_type& a = allocator_type())
: FixedArray(std::make_move_iterator(other.begin()),
std::make_move_iterator(other.end()),
a) {}
// Creates an array object that can store `n` elements.
// Note that trivially constructible elements will be uninitialized.
explicit FixedArray(size_type n, const allocator_type& a = allocator_type())
: storage_(n, a) {
if (DefaultConstructorIsNonTrivial()) {
ConstructRange(storage_.alloc(), storage_.begin(), storage_.end());
}
}
// Creates an array initialized with `n` copies of `val`.
FixedArray(size_type n,
const value_type& val,
const allocator_type& a = allocator_type())
: storage_(n, a) {
ConstructRange(storage_.alloc(), storage_.begin(), storage_.end(), val);
}
// Creates an array initialized with the size and contents of `init_list`.
FixedArray(std::initializer_list<value_type> init_list,
const allocator_type& a = allocator_type())
: FixedArray(init_list.begin(), init_list.end(), a) {}
// Creates an array initialized with the elements from the input
// range. The array's size will always be `std::distance(first, last)`.
// REQUIRES: Iterator must be a forward_iterator or better.
template <typename Iterator, EnableIfForwardIterator<Iterator>* = nullptr>
FixedArray(Iterator first,
Iterator last,
const allocator_type& a = allocator_type())
: storage_(std::distance(first, last), a) {
CopyRange(storage_.alloc(), storage_.begin(), first, last);
}
~FixedArray() noexcept {
for (auto* cur = storage_.begin(); cur != storage_.end(); ++cur) {
AllocatorTraits::destroy(storage_.alloc(), cur);
}
}
// Assignments are deleted because they break the invariant that the size of a
// `FixedArray` never changes.
void operator=(FixedArray&&) = delete;
void operator=(const FixedArray&) = delete;
// FixedArray::size()
//
// FixedArray<T> will not zero-initialiaze POD (simple) types like int,
// double, bool, etc.
// Non-POD types will be default-initialized just like regular vectors or
// arrays.
explicit FixedArray(size_type n);
// Returns the length of the fixed array.
size_type size() const { return storage_.size(); }
// Releases any resources.
~FixedArray();
// Returns the length of the array.
inline size_type size() const { return size_; }
// Returns the memory size of the array in bytes.
inline size_t memsize() const { return size_ * sizeof(T); }
// Returns a pointer to the underlying element array.
inline const T* get() const { return &array_[0].element; }
inline T* get() { return &array_[0].element; }
// REQUIRES: 0 <= i < size()
// Returns a reference to the "i"th element.
inline T& operator[](size_type i) {
DCHECK_LT(i, size_);
return array_[i].element;
// FixedArray::max_size()
//
// Returns the largest possible value of `std::distance(begin(), end())` for a
// `FixedArray<T>`. This is equivalent to the most possible addressable bytes
// over the number of bytes taken by T.
constexpr size_type max_size() const {
return (std::numeric_limits<difference_type>::max)() / sizeof(value_type);
}
// FixedArray::empty()
//
// Returns whether or not the fixed array is empty.
bool empty() const { return size() == 0; }
// FixedArray::memsize()
//
// Returns the memory size of the fixed array in bytes.
size_t memsize() const { return size() * sizeof(value_type); }
// FixedArray::data()
//
// Returns a const T* pointer to elements of the `FixedArray`. This pointer
// can be used to access (but not modify) the contained elements.
const_pointer data() const { return AsValueType(storage_.begin()); }
// Overload of FixedArray::data() to return a T* pointer to elements of the
// fixed array. This pointer can be used to access and modify the contained
// elements.
pointer data() { return AsValueType(storage_.begin()); }
// FixedArray::operator[]
//
// Returns a reference the ith element of the fixed array.
// REQUIRES: 0 <= i < size()
// Returns a reference to the "i"th element.
inline const T& operator[](size_type i) const {
DCHECK_LT(i, size_);
return array_[i].element;
reference operator[](size_type i) {
DCHECK_LT(i, size());
return data()[i];
}
inline iterator begin() { return &array_[0].element; }
inline iterator end() { return &array_[size_].element; }
// Overload of FixedArray::operator()[] to return a const reference to the
// ith element of the fixed array.
// REQUIRES: 0 <= i < size()
const_reference operator[](size_type i) const {
DCHECK_LT(i, size());
return data()[i];
}
inline const_iterator begin() const { return &array_[0].element; }
inline const_iterator end() const { return &array_[size_].element; }
// FixedArray::front()
//
// Returns a reference to the first element of the fixed array.
reference front() { return *begin(); }
// Overload of FixedArray::front() to return a reference to the first element
// of a fixed array of const values.
const_reference front() const { return *begin(); }
// FixedArray::back()
//
// Returns a reference to the last element of the fixed array.
reference back() { return *(end() - 1); }
// Overload of FixedArray::back() to return a reference to the last element
// of a fixed array of const values.
const_reference back() const { return *(end() - 1); }
// FixedArray::begin()
//
// Returns an iterator to the beginning of the fixed array.
iterator begin() { return data(); }
// Overload of FixedArray::begin() to return a const iterator to the
// beginning of the fixed array.
const_iterator begin() const { return data(); }
// FixedArray::cbegin()
//
// Returns a const iterator to the beginning of the fixed array.
const_iterator cbegin() const { return begin(); }
// FixedArray::end()
//
// Returns an iterator to the end of the fixed array.
iterator end() { return data() + size(); }
// Overload of FixedArray::end() to return a const iterator to the end of the
// fixed array.
const_iterator end() const { return data() + size(); }
// FixedArray::cend()
//
// Returns a const iterator to the end of the fixed array.
const_iterator cend() const { return end(); }
// FixedArray::rbegin()
//
// Returns a reverse iterator from the end of the fixed array.
reverse_iterator rbegin() { return reverse_iterator(end()); }
// Overload of FixedArray::rbegin() to return a const reverse iterator from
// the end of the fixed array.
const_reverse_iterator rbegin() const {
return const_reverse_iterator(end());
}
// FixedArray::crbegin()
//
// Returns a const reverse iterator from the end of the fixed array.
const_reverse_iterator crbegin() const { return rbegin(); }
// FixedArray::rend()
//
// Returns a reverse iterator from the beginning of the fixed array.
reverse_iterator rend() { return reverse_iterator(begin()); }
// Overload of FixedArray::rend() for returning a const reverse iterator
// from the beginning of the fixed array.
const_reverse_iterator rend() const {
return const_reverse_iterator(begin());
}
// FixedArray::crend()
//
// Returns a reverse iterator from the beginning of the fixed array.
const_reverse_iterator crend() const { return rend(); }
// FixedArray::fill()
//
// Assigns the given `value` to all elements in the fixed array.
void fill(const value_type& val) { std::fill(begin(), end(), val); }
// Relational operators. Equality operators are elementwise using
// `operator==`, while order operators order FixedArrays lexicographically.
friend bool operator==(const FixedArray& lhs, const FixedArray& rhs) {
return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}
friend bool operator!=(const FixedArray& lhs, const FixedArray& rhs) {
return !(lhs == rhs);
}
friend bool operator<(const FixedArray& lhs, const FixedArray& rhs) {
return std::lexicographical_compare(
lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}
friend bool operator>(const FixedArray& lhs, const FixedArray& rhs) {
return rhs < lhs;
}
friend bool operator<=(const FixedArray& lhs, const FixedArray& rhs) {
return !(rhs < lhs);
}
friend bool operator>=(const FixedArray& lhs, const FixedArray& rhs) {
return !(lhs < rhs);
}
private:
// Container to hold elements of type T. This is necessary to handle
// the case where T is a a (C-style) array. The size of InnerContainer
// and T must be the same, otherwise callers' assumptions about use
// of this code will be broken.
struct InnerContainer {
T element;
// StorageElement
//
// For FixedArrays with a C-style-array value_type, StorageElement is a POD
// wrapper struct called StorageElementWrapper that holds the value_type
// instance inside. This is needed for construction and destruction of the
// entire array regardless of how many dimensions it has. For all other cases,
// StorageElement is just an alias of value_type.
//
// Maintainer's Note: The simpler solution would be to simply wrap value_type
// in a struct whether it's an array or not. That causes some paranoid
// diagnostics to misfire, believing that 'data()' returns a pointer to a
// single element, rather than the packed array that it really is.
// e.g.:
//
// FixedArray<char> buf(1);
// sprintf(buf.data(), "foo");
//
// error: call to int __builtin___sprintf_chk(etc...)
// will always overflow destination buffer [-Werror]
//
template <typename OuterT,
typename InnerT = typename std::remove_extent<OuterT>::type,
size_t InnerN = std::extent<OuterT>::value>
struct StorageElementWrapper {
InnerT array[InnerN];
};
// How many elements should we store inline?
// a. If not specified, use a default of 256 bytes (256 bytes
// seems small enough to not cause stack overflow or unnecessary
// stack pollution, while still allowing stack allocation for
// reasonably long character arrays.
// b. Never use 0 length arrays (not ISO C++)
static const size_type S1 = ((inline_elements < 0)
? (256/sizeof(T)) : inline_elements);
static const size_type S2 = (S1 <= 0) ? 1 : S1;
static const size_type kInlineElements = S2;
using StorageElement =
typename std::conditional<std::is_array<value_type>::value,
StorageElementWrapper<value_type>,
value_type>::type;
size_type const size_;
InnerContainer* const array_;
static pointer AsValueType(pointer ptr) { return ptr; }
static pointer AsValueType(StorageElementWrapper<value_type>* ptr) {
return std::addressof(ptr->array);
}
// Allocate some space, not an array of elements of type T, so that we can
// skip calling the T constructors and destructors for space we never use.
ManualConstructor<InnerContainer> inline_space_[kInlineElements];
static_assert(sizeof(StorageElement) == sizeof(value_type), "");
static_assert(alignof(StorageElement) == alignof(value_type), "");
class NonEmptyInlinedStorage {
public:
StorageElement* data() { return reinterpret_cast<StorageElement*>(buff_); }
void AnnotateConstruct(size_type) {}
void AnnotateDestruct(size_type) {}
// #ifdef ADDRESS_SANITIZER
// void* RedzoneBegin() { return &redzone_begin_; }
// void* RedzoneEnd() { return &redzone_end_ + 1; }
// #endif // ADDRESS_SANITIZER
private:
// ADDRESS_SANITIZER_REDZONE(redzone_begin_);
alignas(StorageElement) char buff_[sizeof(StorageElement[inline_elements])];
// ADDRESS_SANITIZER_REDZONE(redzone_end_);
};
class EmptyInlinedStorage {
public:
StorageElement* data() { return nullptr; }
void AnnotateConstruct(size_type) {}
void AnnotateDestruct(size_type) {}
};
using InlinedStorage =
typename std::conditional<inline_elements == 0,
EmptyInlinedStorage,
NonEmptyInlinedStorage>::type;
// Storage
//
// An instance of Storage manages the inline and out-of-line memory for
// instances of FixedArray. This guarantees that even when construction of
// individual elements fails in the FixedArray constructor body, the
// destructor for Storage will still be called and out-of-line memory will be
// properly deallocated.
//
class Storage : public InlinedStorage {
public:
Storage(size_type n, const allocator_type& a)
: size_alloc_(n, a), data_(InitializeData()) {}
~Storage() noexcept {
if (UsingInlinedStorage(size())) {
InlinedStorage::AnnotateDestruct(size());
} else {
AllocatorTraits::deallocate(alloc(), AsValueType(begin()), size());
}
}
size_type size() const { return std::get<0>(size_alloc_); }
StorageElement* begin() const { return data_; }
StorageElement* end() const { return begin() + size(); }
allocator_type& alloc() { return std::get<1>(size_alloc_); }
private:
static bool UsingInlinedStorage(size_type n) {
return n <= inline_elements;
}
StorageElement* InitializeData() {
if (UsingInlinedStorage(size())) {
InlinedStorage::AnnotateConstruct(size());
return InlinedStorage::data();
} else {
return reinterpret_cast<StorageElement*>(
AllocatorTraits::allocate(alloc(), size()));
}
}
// Using std::tuple and not absl::CompressedTuple, as it has a lot of
// dependencies to other absl headers.
std::tuple<size_type, allocator_type> size_alloc_;
StorageElement* data_;
};
Storage storage_;
};
// Implementation details follow
template <typename T, size_t N, typename A>
constexpr size_t FixedArray<T, N, A>::kInlineBytesDefault;
template <class T, ssize_t S>
inline FixedArray<T, S>::FixedArray(typename FixedArray<T, S>::size_type n)
: size_(n),
array_((n <= kInlineElements
? reinterpret_cast<InnerContainer*>(inline_space_)
: new InnerContainer[n])) {
// Construct only the elements actually used.
if (array_ == reinterpret_cast<InnerContainer*>(inline_space_)) {
for (size_t i = 0; i != size_; ++i) {
inline_space_[i].Init();
}
}
}
template <class T, ssize_t S>
inline FixedArray<T, S>::~FixedArray() {
if (array_ != reinterpret_cast<InnerContainer*>(inline_space_)) {
delete[] array_;
} else {
for (size_t i = 0; i != size_; ++i) {
inline_space_[i].Destroy();
}
}
}
template <typename T, size_t N, typename A>
constexpr typename FixedArray<T, N, A>::size_type
FixedArray<T, N, A>::inline_elements;
} // namespace internal
} // namespace ceres

View File

@@ -28,8 +28,8 @@
//
// Author: vitus@google.com (Michael Vitus)
#ifndef CERES_PUBLIC_HOUSEHOLDER_VECTOR_H_
#define CERES_PUBLIC_HOUSEHOLDER_VECTOR_H_
#ifndef CERES_PUBLIC_INTERNAL_HOUSEHOLDER_VECTOR_H_
#define CERES_PUBLIC_INTERNAL_HOUSEHOLDER_VECTOR_H_
#include "Eigen/Core"
#include "glog/logging.h"
@@ -42,12 +42,15 @@ namespace internal {
// vector as pivot instead of first. This computes the vector v with v(n) = 1
// and beta such that H = I - beta * v * v^T is orthogonal and
// H * x = ||x||_2 * e_n.
template <typename Scalar>
void ComputeHouseholderVector(const Eigen::Matrix<Scalar, Eigen::Dynamic, 1>& x,
Eigen::Matrix<Scalar, Eigen::Dynamic, 1>* v,
//
// NOTE: Some versions of MSVC have trouble deducing the type of v if
// you do not specify all the template arguments explicitly.
template <typename XVectorType, typename Scalar, int N>
void ComputeHouseholderVector(const XVectorType& x,
Eigen::Matrix<Scalar, N, 1>* v,
Scalar* beta) {
CHECK_NOTNULL(beta);
CHECK_NOTNULL(v);
CHECK(beta != nullptr);
CHECK(v != nullptr);
CHECK_GT(x.rows(), 1);
CHECK_EQ(x.rows(), v->rows());
@@ -82,4 +85,4 @@ void ComputeHouseholderVector(const Eigen::Matrix<Scalar, Eigen::Dynamic, 1>& x,
} // namespace internal
} // namespace ceres
#endif // CERES_PUBLIC_HOUSEHOLDER_VECTOR_H_
#endif // CERES_PUBLIC_INTERNAL_HOUSEHOLDER_VECTOR_H_

View File

@@ -0,0 +1,165 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2018 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// 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 name of Google Inc. 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 OWNER 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.
//
// Author: jodebo_beck@gmx.de (Johannes Beck)
//
// Algorithms to be used together with integer_sequence, like computing the sum
// or the exclusive scan (sometimes called exclusive prefix sum) at compile
// time.
#ifndef CERES_PUBLIC_INTERNAL_INTEGER_SEQUENCE_ALGORITHM_H_
#define CERES_PUBLIC_INTERNAL_INTEGER_SEQUENCE_ALGORITHM_H_
#include <utility>
namespace ceres {
namespace internal {
// Implementation of calculating the sum of an integer sequence.
// Recursively instantiate SumImpl and calculate the sum of the N first
// numbers. This reduces the number of instantiations and speeds up
// compilation.
//
// Examples:
// 1) integer_sequence<int, 5>:
// Value = 5
//
// 2) integer_sequence<int, 4, 2>:
// Value = 4 + 2 + SumImpl<integer_sequence<int>>::Value
// Value = 4 + 2 + 0
//
// 3) integer_sequence<int, 2, 1, 4>:
// Value = 2 + 1 + SumImpl<integer_sequence<int, 4>>::Value
// Value = 2 + 1 + 4
template <typename Seq>
struct SumImpl;
// Strip of and sum the first number.
template <typename T, T N, T... Ns>
struct SumImpl<std::integer_sequence<T, N, Ns...>> {
static constexpr T Value = N + SumImpl<std::integer_sequence<T, Ns...>>::Value;
};
// Strip of and sum the first two numbers.
template <typename T, T N1, T N2, T... Ns>
struct SumImpl<std::integer_sequence<T, N1, N2, Ns...>> {
static constexpr T Value =
N1 + N2 + SumImpl<std::integer_sequence<T, Ns...>>::Value;
};
// Strip of and sum the first four numbers.
template <typename T, T N1, T N2, T N3, T N4, T... Ns>
struct SumImpl<std::integer_sequence<T, N1, N2, N3, N4, Ns...>> {
static constexpr T Value =
N1 + N2 + N3 + N4 + SumImpl<std::integer_sequence<T, Ns...>>::Value;
};
// Only one number is left. 'Value' is just that number ('recursion' ends).
template <typename T, T N>
struct SumImpl<std::integer_sequence<T, N>> {
static constexpr T Value = N;
};
// No number is left. 'Value' is the identity element (for sum this is zero).
template <typename T>
struct SumImpl<std::integer_sequence<T>> {
static constexpr T Value = T(0);
};
// Calculate the sum of an integer sequence. The resulting sum will be stored in
// 'Value'.
template <typename Seq>
class Sum {
using T = typename Seq::value_type;
public:
static constexpr T Value = SumImpl<Seq>::Value;
};
// Implementation of calculating an exclusive scan (exclusive prefix sum) of an
// integer sequence. Exclusive means that the i-th input element is not included
// in the i-th sum. Calculating the exclusive scan for an input array I results
// in the following output R:
//
// R[0] = 0
// R[1] = I[0];
// R[2] = I[0] + I[1];
// R[3] = I[0] + I[1] + I[2];
// ...
//
// In C++17 std::exclusive_scan does the same operation at runtime (but
// cannot be used to calculate the prefix sum at compile time). See
// https://en.cppreference.com/w/cpp/algorithm/exclusive_scan for a more
// detailed description.
//
// Example for integer_sequence<int, 1, 4, 3> (seq := integer_sequence):
// T , Sum, Ns... , Rs...
// ExclusiveScanImpl<int, 0, seq<int, 1, 4, 3>, seq<int >>
// ExclusiveScanImpl<int, 1, seq<int, 4, 3>, seq<int, 0 >>
// ExclusiveScanImpl<int, 5, seq<int, 3>, seq<int, 0, 1 >>
// ExclusiveScanImpl<int, 8, seq<int >, seq<int, 0, 1, 5>>
// ^^^^^^^^^^^^^^^^^
// resulting sequence
template <typename T, T Sum, typename SeqIn, typename SeqOut>
struct ExclusiveScanImpl;
template <typename T, T Sum, T N, T... Ns, T... Rs>
struct ExclusiveScanImpl<T, Sum, std::integer_sequence<T, N, Ns...>,
std::integer_sequence<T, Rs...>> {
using Type =
typename ExclusiveScanImpl<T, Sum + N, std::integer_sequence<T, Ns...>,
std::integer_sequence<T, Rs..., Sum>>::Type;
};
// End of 'recursion'. The resulting type is SeqOut.
template <typename T, T Sum, typename SeqOut>
struct ExclusiveScanImpl<T, Sum, std::integer_sequence<T>, SeqOut> {
using Type = SeqOut;
};
// Calculates the exclusive scan of the specified integer sequence. The last
// element (the total) is not included in the resulting sequence so they have
// same length. This means the exclusive scan of integer_sequence<int, 1, 2, 3>
// will be integer_sequence<int, 0, 1, 3>.
template <typename Seq>
class ExclusiveScanT {
using T = typename Seq::value_type;
public:
using Type =
typename ExclusiveScanImpl<T, T(0), Seq, std::integer_sequence<T>>::Type;
};
// Helper to use exclusive scan without typename.
template <typename Seq>
using ExclusiveScan = typename ExclusiveScanT<Seq>::Type;
} // namespace internal
} // namespace ceres
#endif // CERES_PUBLIC_INTERNAL_INTEGER_SEQUENCE_ALGORITHM_H_

View File

@@ -0,0 +1,183 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2020 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// 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 name of Google Inc. 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 OWNER 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.
//
// Author: jodebo_beck@gmx.de (Johannes Beck)
//
#ifndef CERES_PUBLIC_INTERNAL_LINE_PARAMETERIZATION_H_
#define CERES_PUBLIC_INTERNAL_LINE_PARAMETERIZATION_H_
#include "householder_vector.h"
namespace ceres {
template <int AmbientSpaceDimension>
bool LineParameterization<AmbientSpaceDimension>::Plus(
const double* x_ptr,
const double* delta_ptr,
double* x_plus_delta_ptr) const {
// We seek a box plus operator of the form
//
// [o*, d*] = Plus([o, d], [delta_o, delta_d])
//
// where o is the origin point, d is the direction vector, delta_o is
// the delta of the origin point and delta_d the delta of the direction and
// o* and d* is the updated origin point and direction.
//
// We separate the Plus operator into the origin point and directional part
// d* = Plus_d(d, delta_d)
// o* = Plus_o(o, d, delta_o)
//
// The direction update function Plus_d is the same as for the homogeneous
// vector parameterization:
//
// d* = H_{v(d)} [0.5 sinc(0.5 |delta_d|) delta_d, cos(0.5 |delta_d|)]^T
//
// where H is the householder matrix
// H_{v} = I - (2 / |v|^2) v v^T
// and
// v(d) = d - sign(d_n) |d| e_n.
//
// The origin point update function Plus_o is defined as
//
// o* = o + H_{v(d)} [0.5 delta_o, 0]^T.
static constexpr int kDim = AmbientSpaceDimension;
using AmbientVector = Eigen::Matrix<double, kDim, 1>;
using AmbientVectorRef = Eigen::Map<Eigen::Matrix<double, kDim, 1>>;
using ConstAmbientVectorRef =
Eigen::Map<const Eigen::Matrix<double, kDim, 1>>;
using ConstTangentVectorRef =
Eigen::Map<const Eigen::Matrix<double, kDim - 1, 1>>;
ConstAmbientVectorRef o(x_ptr);
ConstAmbientVectorRef d(x_ptr + kDim);
ConstTangentVectorRef delta_o(delta_ptr);
ConstTangentVectorRef delta_d(delta_ptr + kDim - 1);
AmbientVectorRef o_plus_delta(x_plus_delta_ptr);
AmbientVectorRef d_plus_delta(x_plus_delta_ptr + kDim);
const double norm_delta_d = delta_d.norm();
o_plus_delta = o;
// Shortcut for zero delta direction.
if (norm_delta_d == 0.0) {
d_plus_delta = d;
if (delta_o.isZero(0.0)) {
return true;
}
}
// Calculate the householder transformation which is needed for f_d and f_o.
AmbientVector v;
double beta;
// NOTE: The explicit template arguments are needed here because
// ComputeHouseholderVector is templated and some versions of MSVC
// have trouble deducing the type of v automatically.
internal::ComputeHouseholderVector<ConstAmbientVectorRef, double, kDim>(
d, &v, &beta);
if (norm_delta_d != 0.0) {
// Map the delta from the minimum representation to the over parameterized
// homogeneous vector. See section A6.9.2 on page 624 of Hartley & Zisserman
// (2nd Edition) for a detailed description. Note there is a typo on Page
// 625, line 4 so check the book errata.
const double norm_delta_div_2 = 0.5 * norm_delta_d;
const double sin_delta_by_delta =
std::sin(norm_delta_div_2) / norm_delta_div_2;
// Apply the delta update to remain on the unit sphere. See section A6.9.3
// on page 625 of Hartley & Zisserman (2nd Edition) for a detailed
// description.
AmbientVector y;
y.template head<kDim - 1>() = 0.5 * sin_delta_by_delta * delta_d;
y[kDim - 1] = std::cos(norm_delta_div_2);
d_plus_delta = d.norm() * (y - v * (beta * (v.transpose() * y)));
}
// The null space is in the direction of the line, so the tangent space is
// perpendicular to the line direction. This is achieved by using the
// householder matrix of the direction and allow only movements
// perpendicular to e_n.
//
// The factor of 0.5 is used to be consistent with the line direction
// update.
AmbientVector y;
y << 0.5 * delta_o, 0;
o_plus_delta += y - v * (beta * (v.transpose() * y));
return true;
}
template <int AmbientSpaceDimension>
bool LineParameterization<AmbientSpaceDimension>::ComputeJacobian(
const double* x_ptr, double* jacobian_ptr) const {
static constexpr int kDim = AmbientSpaceDimension;
using AmbientVector = Eigen::Matrix<double, kDim, 1>;
using ConstAmbientVectorRef =
Eigen::Map<const Eigen::Matrix<double, kDim, 1>>;
using MatrixRef = Eigen::Map<
Eigen::Matrix<double, 2 * kDim, 2 * (kDim - 1), Eigen::RowMajor>>;
ConstAmbientVectorRef d(x_ptr + kDim);
MatrixRef jacobian(jacobian_ptr);
// Clear the Jacobian as only half of the matrix is not zero.
jacobian.setZero();
AmbientVector v;
double beta;
// NOTE: The explicit template arguments are needed here because
// ComputeHouseholderVector is templated and some versions of MSVC
// have trouble deducing the type of v automatically.
internal::ComputeHouseholderVector<ConstAmbientVectorRef, double, kDim>(
d, &v, &beta);
// The Jacobian is equal to J = 0.5 * H.leftCols(kDim - 1) where H is
// the Householder matrix (H = I - beta * v * v') for the origin point. For
// the line direction part the Jacobian is scaled by the norm of the
// direction.
for (int i = 0; i < kDim - 1; ++i) {
jacobian.block(0, i, kDim, 1) = -0.5 * beta * v(i) * v;
jacobian.col(i)(i) += 0.5;
}
jacobian.template block<kDim, kDim - 1>(kDim, kDim - 1) =
jacobian.template block<kDim, kDim - 1>(0, 0) * d.norm();
return true;
}
} // namespace ceres
#endif // CERES_PUBLIC_INTERNAL_LINE_PARAMETERIZATION_H_

View File

@@ -1,170 +0,0 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2015 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// 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 name of Google Inc. 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 OWNER 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.
//
//
// Various Google-specific macros.
//
// This code is compiled directly on many platforms, including client
// platforms like Windows, Mac, and embedded systems. Before making
// any changes here, make sure that you're not breaking any platforms.
#ifndef CERES_PUBLIC_INTERNAL_MACROS_H_
#define CERES_PUBLIC_INTERNAL_MACROS_H_
#include <cstddef> // For size_t.
// A macro to disallow the copy constructor and operator= functions
// This should be used in the private: declarations for a class
//
// For disallowing only assign or copy, write the code directly, but declare
// the intend in a comment, for example:
//
// void operator=(const TypeName&); // _DISALLOW_ASSIGN
// Note, that most uses of CERES_DISALLOW_ASSIGN and CERES_DISALLOW_COPY
// are broken semantically, one should either use disallow both or
// neither. Try to avoid these in new code.
#define CERES_DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)
// A macro to disallow all the implicit constructors, namely the
// default constructor, copy constructor and operator= functions.
//
// This should be used in the private: declarations for a class
// that wants to prevent anyone from instantiating it. This is
// especially useful for classes containing only static methods.
#define CERES_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
TypeName(); \
CERES_DISALLOW_COPY_AND_ASSIGN(TypeName)
// The arraysize(arr) macro returns the # of elements in an array arr.
// The expression is a compile-time constant, and therefore can be
// used in defining new arrays, for example. If you use arraysize on
// a pointer by mistake, you will get a compile-time error.
//
// One caveat is that arraysize() doesn't accept any array of an
// anonymous type or a type defined inside a function. In these rare
// cases, you have to use the unsafe ARRAYSIZE() macro below. This is
// due to a limitation in C++'s template system. The limitation might
// eventually be removed, but it hasn't happened yet.
// This template function declaration is used in defining arraysize.
// Note that the function doesn't need an implementation, as we only
// use its type.
template <typename T, size_t N>
char (&ArraySizeHelper(T (&array)[N]))[N];
// That gcc wants both of these prototypes seems mysterious. VC, for
// its part, can't decide which to use (another mystery). Matching of
// template overloads: the final frontier.
#ifndef _WIN32
template <typename T, size_t N>
char (&ArraySizeHelper(const T (&array)[N]))[N];
#endif
#define arraysize(array) (sizeof(ArraySizeHelper(array)))
// ARRAYSIZE performs essentially the same calculation as arraysize,
// but can be used on anonymous types or types defined inside
// functions. It's less safe than arraysize as it accepts some
// (although not all) pointers. Therefore, you should use arraysize
// whenever possible.
//
// The expression ARRAYSIZE(a) is a compile-time constant of type
// size_t.
//
// ARRAYSIZE catches a few type errors. If you see a compiler error
//
// "warning: division by zero in ..."
//
// when using ARRAYSIZE, you are (wrongfully) giving it a pointer.
// You should only use ARRAYSIZE on statically allocated arrays.
//
// The following comments are on the implementation details, and can
// be ignored by the users.
//
// ARRAYSIZE(arr) works by inspecting sizeof(arr) (the # of bytes in
// the array) and sizeof(*(arr)) (the # of bytes in one array
// element). If the former is divisible by the latter, perhaps arr is
// indeed an array, in which case the division result is the # of
// elements in the array. Otherwise, arr cannot possibly be an array,
// and we generate a compiler error to prevent the code from
// compiling.
//
// Since the size of bool is implementation-defined, we need to cast
// !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final
// result has type size_t.
//
// This macro is not perfect as it wrongfully accepts certain
// pointers, namely where the pointer size is divisible by the pointee
// size. Since all our code has to go through a 32-bit compiler,
// where a pointer is 4 bytes, this means all pointers to a type whose
// size is 3 or greater than 4 will be (righteously) rejected.
//
// Kudos to Jorg Brown for this simple and elegant implementation.
//
// - wan 2005-11-16
//
// Starting with Visual C++ 2005, WinNT.h includes ARRAYSIZE. However,
// the definition comes from the over-broad windows.h header that
// introduces a macro, ERROR, that conflicts with the logging framework
// that Ceres uses. Instead, rename ARRAYSIZE to CERES_ARRAYSIZE.
#define CERES_ARRAYSIZE(a) \
((sizeof(a) / sizeof(*(a))) / \
static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
// Tell the compiler to warn about unused return values for functions
// declared with this macro. The macro should be used on function
// declarations following the argument list:
//
// Sprocket* AllocateSprocket() MUST_USE_RESULT;
//
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) \
&& !defined(COMPILER_ICC)
#define CERES_MUST_USE_RESULT __attribute__ ((warn_unused_result))
#else
#define CERES_MUST_USE_RESULT
#endif
// Platform independent macros to get aligned memory allocations.
// For example
//
// MyFoo my_foo CERES_ALIGN_ATTRIBUTE(16);
//
// Gives us an instance of MyFoo which is aligned at a 16 byte
// boundary.
#if defined(_MSC_VER)
#define CERES_ALIGN_ATTRIBUTE(n) __declspec(align(n))
#define CERES_ALIGN_OF(T) __alignof(T)
#elif defined(__GNUC__)
#define CERES_ALIGN_ATTRIBUTE(n) __attribute__((aligned(n)))
#define CERES_ALIGN_OF(T) __alignof(T)
#endif
#endif // CERES_PUBLIC_INTERNAL_MACROS_H_

View File

@@ -1,208 +0,0 @@
// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2015 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// 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 name of Google Inc. 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 OWNER 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.
//
// Author: kenton@google.com (Kenton Varda)
//
// ManualConstructor statically-allocates space in which to store some
// object, but does not initialize it. You can then call the constructor
// and destructor for the object yourself as you see fit. This is useful
// for memory management optimizations, where you want to initialize and
// destroy an object multiple times but only allocate it once.
//
// (When I say ManualConstructor statically allocates space, I mean that
// the ManualConstructor object itself is forced to be the right size.)
#ifndef CERES_PUBLIC_INTERNAL_MANUAL_CONSTRUCTOR_H_
#define CERES_PUBLIC_INTERNAL_MANUAL_CONSTRUCTOR_H_
#include <new>
namespace ceres {
namespace internal {
// ------- Define CERES_ALIGNED_CHAR_ARRAY --------------------------------
#ifndef CERES_ALIGNED_CHAR_ARRAY
// Because MSVC and older GCCs require that the argument to their alignment
// construct to be a literal constant integer, we use a template instantiated
// at all the possible powers of two.
template<int alignment, int size> struct AlignType { };
template<int size> struct AlignType<0, size> { typedef char result[size]; };
#if !defined(CERES_ALIGN_ATTRIBUTE)
#define CERES_ALIGNED_CHAR_ARRAY you_must_define_CERES_ALIGNED_CHAR_ARRAY_for_your_compiler
#else // !defined(CERES_ALIGN_ATTRIBUTE)
#define CERES_ALIGN_TYPE_TEMPLATE(X) \
template<int size> struct AlignType<X, size> { \
typedef CERES_ALIGN_ATTRIBUTE(X) char result[size]; \
}
CERES_ALIGN_TYPE_TEMPLATE(1);
CERES_ALIGN_TYPE_TEMPLATE(2);
CERES_ALIGN_TYPE_TEMPLATE(4);
CERES_ALIGN_TYPE_TEMPLATE(8);
CERES_ALIGN_TYPE_TEMPLATE(16);
CERES_ALIGN_TYPE_TEMPLATE(32);
CERES_ALIGN_TYPE_TEMPLATE(64);
CERES_ALIGN_TYPE_TEMPLATE(128);
CERES_ALIGN_TYPE_TEMPLATE(256);
CERES_ALIGN_TYPE_TEMPLATE(512);
CERES_ALIGN_TYPE_TEMPLATE(1024);
CERES_ALIGN_TYPE_TEMPLATE(2048);
CERES_ALIGN_TYPE_TEMPLATE(4096);
CERES_ALIGN_TYPE_TEMPLATE(8192);
// Any larger and MSVC++ will complain.
#undef CERES_ALIGN_TYPE_TEMPLATE
#define CERES_ALIGNED_CHAR_ARRAY(T, Size) \
typename AlignType<CERES_ALIGN_OF(T), sizeof(T) * Size>::result
#endif // !defined(CERES_ALIGN_ATTRIBUTE)
#endif // CERES_ALIGNED_CHAR_ARRAY
template <typename Type>
class ManualConstructor {
public:
// No constructor or destructor because one of the most useful uses of
// this class is as part of a union, and members of a union cannot have
// constructors or destructors. And, anyway, the whole point of this
// class is to bypass these.
inline Type* get() {
return reinterpret_cast<Type*>(space_);
}
inline const Type* get() const {
return reinterpret_cast<const Type*>(space_);
}
inline Type* operator->() { return get(); }
inline const Type* operator->() const { return get(); }
inline Type& operator*() { return *get(); }
inline const Type& operator*() const { return *get(); }
// This is needed to get around the strict aliasing warning GCC generates.
inline void* space() {
return reinterpret_cast<void*>(space_);
}
// You can pass up to four constructor arguments as arguments of Init().
inline void Init() {
new(space()) Type;
}
template <typename T1>
inline void Init(const T1& p1) {
new(space()) Type(p1);
}
template <typename T1, typename T2>
inline void Init(const T1& p1, const T2& p2) {
new(space()) Type(p1, p2);
}
template <typename T1, typename T2, typename T3>
inline void Init(const T1& p1, const T2& p2, const T3& p3) {
new(space()) Type(p1, p2, p3);
}
template <typename T1, typename T2, typename T3, typename T4>
inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4) {
new(space()) Type(p1, p2, p3, p4);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4,
const T5& p5) {
new(space()) Type(p1, p2, p3, p4, p5);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6>
inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4,
const T5& p5, const T6& p6) {
new(space()) Type(p1, p2, p3, p4, p5, p6);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7>
inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4,
const T5& p5, const T6& p6, const T7& p7) {
new(space()) Type(p1, p2, p3, p4, p5, p6, p7);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8>
inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4,
const T5& p5, const T6& p6, const T7& p7, const T8& p8) {
new(space()) Type(p1, p2, p3, p4, p5, p6, p7, p8);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9>
inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4,
const T5& p5, const T6& p6, const T7& p7, const T8& p8,
const T9& p9) {
new(space()) Type(p1, p2, p3, p4, p5, p6, p7, p8, p9);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10>
inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4,
const T5& p5, const T6& p6, const T7& p7, const T8& p8,
const T9& p9, const T10& p10) {
new(space()) Type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11>
inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4,
const T5& p5, const T6& p6, const T7& p7, const T8& p8,
const T9& p9, const T10& p10, const T11& p11) {
new(space()) Type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
}
inline void Destroy() {
get()->~Type();
}
private:
CERES_ALIGNED_CHAR_ARRAY(Type, 1) space_;
};
#undef CERES_ALIGNED_CHAR_ARRAY
} // namespace internal
} // namespace ceres
#endif // CERES_PUBLIC_INTERNAL_MANUAL_CONSTRUCTOR_H_

Some files were not shown because too many files have changed in this diff Show More