Compare commits

...

117 Commits

Author SHA1 Message Date
9e8835c1a9 Fixed typo in function OVERLAY_angular_limits 2022-02-15 22:36:12 +05:30
f5dd77d290 Added comments to RB_dworld_get_impulse to better explain the bullet terminologies 2022-02-15 22:05:47 +05:30
ad35f6181e Added comments to explain the calculations in hinge constraint debug drawing functions 2022-02-15 22:02:48 +05:30
e1846b874b Fixed issues caused by merge 2022-02-10 13:00:16 +05:30
211ac7b94b merge conflict helper removed 2022-02-09 16:11:34 +05:30
6c0987a2d5 Merge branch 'master' into soc-2021-simulation-display 2022-02-09 14:01:15 +05:30
81da638c44 Cleanup: move file descriptions into doxygen file section
Continuation of 19100aa57d.
2022-02-09 18:33:29 +11:00
19100aa57d Cleanup: move file descriptions into doxygen file section
Also other minor corrections & reformat particle system copyright.
2022-02-09 18:10:43 +11:00
2c7f2a0ba4 Cleanup: simplify copyright headers for sequence & imbuf 2022-02-09 16:47:15 +11:00
68a21697be Cleanup: remove "The Original Code is: ..." from code comments
This is almost always meaningless as most code has changed
since the comment was added. Besides this, version control can be used
to check if/when a file was modified.

Some cases of this were kept when they contain details
about the original copyright holder.
2022-02-09 16:04:31 +11:00
59a7095f79 Cleanup: use consistent copyright location, move descriptions
Order copyright immediately after the license block,
this was done almost everywhere with a few exceptions.

Remove authors from a few files (we had already removed "Contributors"
section however with old patches being applied this gets added back in).

Also move descriptive text into the doxygen comment block under \file.
In some cases remove the text as it was accidentally copied.
2022-02-09 16:00:16 +11:00
Shrey Aggarwal
f021d46752 Cleanup: GHOST_ISystem::toggleConsole API
GHOST_ISystem::toggleConsole had a somewhat misleading name
it could be fed 4 different values, so it was not as much a
toggle as a set console window state.

This change renames `toggleConsole` to a more appropriately
named `setConsoleWindowState` and replaces the integer it had
to an enum so it's easy to tell what is being asked of it at
the call site.

Reviewed By: LazyDodo
Differential Revision: https://developer.blender.org/D14020
2022-02-08 17:40:48 -07:00
Paolo Acampora
452a7f6731 Fix T91871: Symmetrize Armature on custom bone shape
Symmetrize Armature now also symmetrizes the transform of custom bone
shapes.

Adds a new property to `bpy.ops.armature.symmetrize`:

//Parameters//:

- **direction **(enum in ['NEGATIVE_X', 'POSITIVE_X'], (optional)) –
  **Direction**, Which sides to copy from and to (when both are selected)

- **custom_shape **(enum in ['SYMMETRIZE_SAME', 'SYMMETRIZE_ALL',
  'SYMMETRIZE_NONE'], (optional)) – **Custom Shapes**, Wether to
  symmetrize non symmetric custom bone shapes, all custom shapes, or
  none at all

//Rationale//:

Reviewed By: #animation_rigging, Mets, sybren

Maniphest Tasks: T91871

Differential Revision: https://developer.blender.org/D13416
2022-02-08 18:09:48 +01:00
55c90df316 BLF: Enable Filtering of woff and woff2 Fonts
Add files with extension ".woff" and ".woff2" to FILE_TYPE_FTFONT
file type. Allows selecting and using these types of font files.

See D13822 for more details.

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

Reviewed by Campbell Barton
2022-02-08 08:43:01 -08:00
5d9d2565d2 Cleanup: simplify DNA genfile casting
Avoid using the uint64_t as an intermediate cast since it complicates
behavior for signed types (which first need to be cast to an int64_t).

Assign both old_value_i & old_value_f from the original value to avoid
the need for different handling of signed/unsigned types.

Reviewed By: JacquesLucke

Ref D14039
2022-02-08 22:52:46 +11:00
460d1a4cb3 Eevee: support the no-op Bump node optimization like in Cycles.
A Bump node without a Height input is meaningless and does nothing.
As such, it is available as an old workaround that allows making Node
Group inputs that default to normal when not connected, by routing
via a no-op Bump node before doing math.

Cycles specifically recognizes this use case and either bypasses
the node, or converts it into a Geometry Normal node, but Eevee
was still evaluating it as usual. That incurred performance cost,
and also normalized the vector unlike Cycles.

This implements the same bypass logic for Eevee. Since I'm not
sure if it's possible to totally remove the node at this stage,
it emits a no-op function call to copy the input vector.

Differential Revision: https://developer.blender.org/D14045
2022-02-08 14:37:25 +03:00
3267c91b4d Fix T91253: Slow pose bone selection with many bones
Viewport cull bones during selection to avoid depth-picking
reading the depth buffer for bones that aren't in the viewport.

Files with thousands of bones could hang blender for seconds while
selecting. The issue could still happen with overlapping bones or when
zoomed out so all bones are under the cursor, however in practice this
rarely happens.

Now files with many bones select quickly.

Related changes include:

- Split `BKE_pchan_minmax` out of `BKE_pose_minmax`.
- Add `mat3_to_size_max_axis` to return the length of the largest
  axis (used for scaling the radius).

Reviewed By: sybren

Maniphest Tasks: T91253

Ref D13990
2022-02-08 22:16:51 +11:00
530be35516 Merge branch 'blender-v3.1-release' 2022-02-08 12:13:24 +01:00
de71860555 Fix T95570: missing task isolation when computing normals 2022-02-08 12:12:49 +01:00
923ccf6b10 LibOverride: Use new 'hierarchy root' info in relevant override code.
This new info simplifies greatly the handling of resync and deleting
liboverride hierarchies, and makes those operations more robust to
complex dependencies cases between different hierarchies.

Related to T95283.
2022-02-08 11:22:56 +01:00
98c242affd LibOverride: Add 'hierarchy root ID' info.
This change will make handling of liboverrides hierarchies (especially
resyncing) much easier and efficient. It should also make it more
resilient to 'degenerate' cases, and allow proper support of things like
parenting an override to another override of the same linked data (e.g.
a override character parented to another override of the same
character).

NOTE: this commit only implements minimal changes to add that data and
generate it for existing files on load. Actual refactor of resync code
to take advantage of this new info will happen separately.
2022-02-08 10:51:31 +01:00
32278b79a8 LibOverride: Add 'hierarchy root ID' info.
This change will make handling of liboverrides hierarchies (especially
resyncing) much easier and efficient. It should also make it more
resilient to 'degenerate' cases, and allow proper support of things like
parenting an override to another override of the same linked data (e.g.
a override character parented to another override of the same
character).

NOTE: this commit only implements minimal changes to add that data and
generate it for existing files on load. Actual refactor of resync code
to take advantage of this new info will happen separately.
2022-02-08 10:50:39 +01:00
0617efd51b Merge branch 'blender-v3.1-release' 2022-02-08 10:26:42 +01:00
1995aae6e3 Fix T94415: Nodes: poor selection behavior inside frame nodes
Previously, node selection made no distinction between a frame node and
other nodes. So a frame node would be selected by their whole rect or
center (depending on box/lasso/circle select). As a consequence of this,
box and lasso could not pratically be started inside a frame node (with
the intention to select a subset of contained child nodes) because the
frame would be selected immediately and tweak-transforming started.
Circle selecting would always contain the frame node as well (making
transforming a subset of nodes without also transforming the whole frame
impossible).

Now change selection behavior so that for all selection modes only the
border [the margin area that is automatically added around all nodes,
see note below] of a frame node is considered in selection. This makes
for a much more intuitive experience when arranging nodes inside frames.

note: to make the area of interest for selection/moving more obvious,
the cursor changes when hovering over (as is done for resizing).
note: this also makes the resize margin consistent with other nodes.
note: this also fixes right resize border (was exclusive instead of
inclusive as every other border)

Also fixes T46540.
2022-02-08 10:14:14 +01:00
67c12ed765 Cleanup: remove useless statement.
Layouts are active by default when created, no need to set this
explicitely. Leftover from proxy removal.
2022-02-08 09:16:49 +01:00
8abd8865d2 Mesh: add option to select vertices by similar vertex crease
This adds an option to the "Select Similar" operator in edit mode to
select vertices based on vertex crease similarity. The implementation
follows that of the edge crease, with a 1-dimensional KD-tree used to
store and retrieve vertex indices base on crease values.

To maintain compatibility with old files (scripts), the `SIMEDGE_CREASE`
enumeration identifier remains `CREASE`, while the one for the new
`SIMVERT_CREASE` is `VCREASE` to follow the naming convention of other
enum values.

Reviewed By: campbellbarton

Differential Revision: https://developer.blender.org/D14037
2022-02-08 06:10:22 +01:00
Dominik Fill
7047bd41c6 UI: Change computation of node socket position to align with label
This Diff changes the computation of the input and output socket
position to being always aligned with its corresponding label.

Reviewed By: campbellbarton

Ref D14025
2022-02-08 14:55:02 +11:00
667b4bc0e4 Cleanup: clang-format 2022-02-08 14:25:31 +11:00
9d674d9852 Fix dna_genfile error converting signed int types to floating point
Regression in 51befa4108
caused negative values to overflow into a uint64_t.

Resolve by casting to a signed int from originally signed types.

This caused D14033 not to work properly.
2022-02-08 11:54:44 +11:00
7df651367f Cleanup: use an intermediate value for cast_primitive_type
Assign the actual value before casting to large uint64_t/double types.

This improves readability, especially in cases where both pointer
and integer casts were used in one expression, to make matters worse
clang-format treated these casts as a multiplication.

This also made debugging/printing the values more of a hassle.

No functional changes (GCC produced identical output).
2022-02-08 11:54:44 +11:00
e5fc579073 Merge branch 'blender-v3.1-release' 2022-02-07 18:42:58 -06:00
b76918717d Fix T95573: Incorrect bounding box of evaluated curve
Account for `CurveEval`, which stores the proper deformed and
procedurally created data, unlike the `nurb` list, which has always
just meant a copy of the original curve.

Also account for the case when the curve is empty by using a -1, 1,
fallback bounding box in that case, just like mesh objects.
2022-02-07 18:42:31 -06:00
770793e545 Merge branch 'blender-v3.1-release' 2022-02-07 16:11:21 -06:00
Wannes Malfait
229d0ace02 Fix T95532: Merge node deletes everything for empty selections
The problem was that nullptr was returned which is a valid value for
Mesh * and hence the returned optional was treated as having some value.
There was no check for point clouds so that was fixed as well.

Differential Revision: https://developer.blender.org/D14026
2022-02-07 16:08:36 -06:00
11d785edea Fix T95502: macOS app has both python 3.9 and 3.10 executables 2022-02-07 20:51:03 +01:00
674e4640f6 Merge branch 'blender-v3.1-release' 2022-02-07 14:29:26 -05:00
Myles Walcott
880e85fc80 Cleanup: Grammar in doc/python_api
* Its -> It's
* Scripts -> Script's
* then -> than

Several phrasing grammar fixes.

Reviewed By: Blendify

Differential Revision: https://developer.blender.org/D14021
2022-02-07 14:28:12 -05:00
fe1816f67f Curves: Rename "Hair" types, variables, and functions to "Curves"
Based on discussions from T95355 and T94193, the plan is to use
the name "Curves" to describe the data-block container for multiple
curves. Eventually this will replace the existing "Curve" data-block.
However, it will be a while before the curve data-block can be replaced
so in order to distinguish the two curve types in the UI, "Hair Curves"
will be used, but eventually changed back to "Curves".

This patch renames "hair-related" files, functions, types, and variable
names to this convention. A deep rename is preferred to keep code
consistent and to avoid any "hair" terminology from leaking, since the
new data-block is meant for all curve types, not just hair use cases.

The downside of this naming is that the difference between "Curve"
and "Curves" has become important. That was considered during
design discussons and deemed acceptable, especially given the
non-permanent nature of the somewhat common conflict.

Some points of interest:
- All DNA compatibility is lost, just like rBf59767ff9729.
- I renamed `ID_HA` to `ID_CV` so there is no complete mismatch.
- `hair_curves` is used where necessary to distinguish from the
  existing "curves" plural.
- I didn't rename any of the cycles/rendering code function names,
  since that is also used by the old hair particle system.

Differential Revision: https://developer.blender.org/D14007
2022-02-07 11:56:48 -06:00
b8c764c5d1 Merge branch 'blender-v3.1-release' 2022-02-07 18:45:24 +01:00
65d287a14a Fix T95543: incorrect handling of implicit field inputs in ui 2022-02-07 18:44:30 +01:00
d3e9d74a5f Merge branch 'blender-v3.1-release' 2022-02-07 18:17:29 +01:00
eb071e3d3c Fix: missing null check
This fixes https://github.com/JacquesLucke/animation_nodes/issues/1827.
2022-02-07 18:16:35 +01:00
2f7aecb6ce Merge branch 'blender-v3.1-release' 2022-02-07 17:57:01 +01:00
2f868e5647 Fix T95578: missing update when linking selected nodes
This removes a "narrow" update in `snode_autoconnect` in favor
of the more general update in `node_make_link_exec`.
2022-02-07 17:56:25 +01:00
Charlie Jolly
fe4e85a924 Nodes: Dynamic node class for Map Range node
This patch makes it possible to set the UI color of a node's
header bar and override the default from the node's typeinfo.

Currently the color is taken from the `.nclass`
member of the node's bNodeType->TypeInfo struct.
This is created once when registering the node.
The TypeInfo is used for both UI and non-UI functionality.
Since the TypeInfo is shared, the header bar for the node
can't be changed without changing all nodes of that type.

The Map Range node is shown as a `Converter` or blue color by default.
This patch allows this to be changed dynamically to `Vector` or purple.

This is done by adding a `ui_class` callback to node typeinfo struct.

Reviewed By: HooglyBoogly

Differential Revision: https://developer.blender.org/D13936
2022-02-07 15:39:39 +00:00
a7b5982030 Fix missing removal of proxy references in py scripts.
Reported by studio (Hjalti), thanks.
2022-02-07 16:23:26 +01:00
Shrey Aggarwal
a5dd1bc53d Fix T90868: Console window flash when exiting
If the console was hidden on windows, it would
be made visible during shutdown in an effort
not hide a potentially active interactive console
session. This however did not take in account
if blender was actually launched from an interactive
console causing the console window to briefly flash
during shutdown even when launched from the new
launcher, the brief flash concerned some users.

This change adjusts the behaviour to restore the
console only when blender was started from the
console.

Reviewed By: LazyDodo
Differential Revision: https://developer.blender.org/D14016
2022-02-07 08:20:12 -07:00
b3bb51dd83 Fix asset-view template ignoring "Asset Indexing" debug option
If the "Asset Indexing" option was disabled in Preferences > Experimental
> Debugging, the asset-view template (used by pose libraries for
example) would still use the indexing.
2022-02-07 12:18:15 +01:00
d9b1bd01f7 Merge branch 'blender-v3.1-release' 2022-02-07 11:13:06 +01:00
3cd686cae8 Fix UI messages (typos etc.). 2022-02-07 11:12:37 +01:00
Dimitry Kaplin
1c5f2e49b7 VSE: Add filter method to strip transform
Previously, nearest interpolation filter was used for preview, because
it offered good performance and bilinear was used for rendering. This
is not always desirable behavior, so filter method can now be chosen by
user. Chosen method will be used for preview and for rendering.

Reviewed By: ISS

Differential Revision: https://developer.blender.org/D12807
2022-02-07 10:41:26 +01:00
6766699530 UV: use grey on black for dashed-line display
Dashed line display was changed since 2.7x, using white on black
instead of grey on black.

This made selection difficult to see as white is brighter
than the default selected color.

Match the grey used in 2.7x.
2022-02-07 15:50:42 +11:00
2b14aa0a39 Cleanup: spelling in comments 2022-02-07 15:33:10 +11:00
7e6066c9c3 Cleanup: clang-format 2022-02-07 15:32:34 +11:00
Henrik Dick
94866ef84f Fix Bevel intersection continuity.
This patch from Henrik Dick improves the continuity between the
grid forming corners and the edge polyons on multisegment bevels.
For details, see patch D13867.
2022-02-06 16:01:57 -05:00
f199f03994 Merge branch 'blender-v3.1-release' 2022-02-06 15:00:21 -05:00
Aras Pranckevicius
1d59a7aa77 Fix T95384: new obj exporter inaccurate roughness value in new exporter.
Fixes T95384. New exporter was missing a fix for T94516 that recently got applied to the python exporter.

Also changed the obj export tests code so that when save_failing_test_output is requested and MTL result is different from the golden expectation, it is saved as well, similar to how it's done for the OBJ file result.
2022-02-06 14:53:07 -05:00
Aras Pranckevicius
9261bc9476 Further speedup of new obj exporter.
This change from Aras further parallelizes wihin large meshes (the previous one
just parallelized over objects).

Some stats: on A Windows machine, AMD Ryzen (32 threads):

(one mesh) Monkey subdivided to level 6: 4.9s -> 1.2s (blender 3.1 was 6.3s; 3.0 was 49.4s).
(one mesh) "Rungholt" minecraft level: 8.5s -> 2.9s (3.1 was 10.5s; 3.0 was 73.7s).
(lots of meshes) Blender 3 splash: 6.2s -> 5.2s (3.1 was 48.9s; 3.0 was 392.3s).

On a Linux machine (Threadripper, 48 threads, writing to SSD):
Monkey - 5.08s -> 1.18s (4.2x speedup)
Rungholt - 9.52s -> 3.22s (2.95x speedup)
Blender 3 splash - 5.91s -> 4.61s (1.28x speedup)

For details see patch D14028.
2022-02-06 14:28:22 -05:00
96cda4da28 GLDebug: Wrap glDispatch function into our debug wrappers 2022-02-06 17:03:05 +01:00
17ffc6c140 Cleanup: remove unnecessary print statements 2022-01-07 18:20:16 +05:30
ccddbec168 Merge branch 'master' into soc-2021-simulation-display 2021-12-01 12:22:06 +05:30
e9ab60e092 Fix: incorrect force vector locations
While taking the weighted average of vector locations, the net normal
force was being used as the denominator. The correct value to use is
the sum of the magnitudes of all normal forces in the timestep.
2021-09-16 19:24:41 +05:30
eef2698182 Fix error while freeing non primitive collisions shape mesh in rigidbody
The function name was changed in master and caused an error during merge
Now it uses a different function to clear the geometry
2021-09-14 16:26:38 +05:30
dacfa8fb23 Merge branch 'master' into soc-2021-simulation-display 2021-09-14 16:24:18 +05:30
3cb9c6efad make format 2021-09-14 14:38:06 +05:30
b31083a008 Constraints: visualisation works with kinematic objects
Used the transforms obtained from bullet instead of creating them using
rigidbody/ object data, which only worked for active rigidbodies
2021-09-14 14:31:40 +05:30
d7dc751a94 Fix memory leak in non primitive collision shape
- The previous commit didn't fix the leak as the mesh data was not being freed every draw call
- Now the mesh is generated during evaluation along with the physics shape.
- The collisions shape draw data mesh is stored in the shared struct, along with the physics references
2021-09-11 11:57:40 +05:30
12e5b9420e Fix: Memory leak in non primitive collision shape drawing functions
The ojects containing the non primitive collision shape meshes are stored in
a GSet along with other draw cache shapes and the meshes are freed using these
object pointers
2021-09-01 18:52:35 +05:30
cfaaf58023 Cleanup: Forces 2021-08-19 01:17:08 +05:30
d4f44e67c4 Fix: Incorrect acceleration. Store velocities of only the last substep, subtract previous velocity from current 2021-08-18 23:47:53 +05:30
b4aafcc368 Cleanup: Constraints and panels 2021-08-18 23:04:29 +05:30
e53880a122 Constraints:Added functions to get transforms from bullet.
- These should be used in the constraint visualisation functions so that they can be drawn for kinematic objects as well
2021-08-18 15:58:16 +05:30
c79955fd28 Fix: Error while storing effectors forces, upto 3 effectors' forces can be stored now. 2021-08-18 12:57:35 +05:30
8be22e2ef1 Fix: Memory issue in store_convex_hull_draw_data: delete the convex hull computer. 2021-08-18 10:14:43 +05:30
e789dd4d4c Cleanup: collision display: faces of box, cone and cylinder
-Moved code for checking for faces of cone and cylinder to same function as the box
-Cached colliding faces
-Removed unneccesary shader files and used GPU batches instead, for drawing  faces
2021-08-17 11:57:31 +05:30
da57f6eb66 Fix: transform matrix for drawing colliding walls on box shape 2021-08-16 22:12:24 +05:30
9b9ff57095 Cleanup: Changed the place of non primitive collision shapes functions to draw_cache.c 2021-08-16 18:43:03 +05:30
045e7b58e4 Fix: Check for colliding faces after stepping through the simulation instead of in the draw engine
-This is a more accurate way to find colliding faces
-Store just the faces instead of the forces
2021-08-16 18:24:18 +05:30
0d04e138b1 Cleanup: Changed the place of the store_draw_data functions of convex hull and trimesh so that they are called from the draw engine instead. 2021-08-15 23:09:24 +05:30
ea208f067f Cleanup: Constraint linear limits visualisation
-created option to enable/disable fading of walls
-simplified variable names and transform matrices
2021-08-15 00:06:02 +05:30
012445eb14 Fix memmory error in function for storing convex hull collision shape mesh data. 2021-08-14 23:40:17 +05:30
94de2bf12c Physics: Changed hinge constraint visualisation so that it uses the transform matrices in the format obtained from bullet, created functions to get transforms from bullet 2021-08-13 18:23:39 +05:30
dc15562b7c Cleanup: Correct variable name while storing effectors force.
No functional changes.
2021-08-12 08:19:42 +05:30
96e5a771fb Cleanup: Hinge constraint visualisation, non primitive collision shape drawing 2021-08-12 07:59:31 +05:30
8256bfacee Cleanup: new function for getting debug draw data after step_simulation is called 2021-08-10 07:06:08 +05:30
0d09f5e486 Fix incorrect position of disks in hinge constraint 2021-08-09 09:23:20 +05:30
5a7f89354b Cleanup: Panels for drawing constraints 2021-08-09 09:12:44 +05:30
ccdb32ab7a Modified slider and hinge constraint and added visualisation for the piston constraint 2021-08-06 13:11:04 +05:30
d6e15033da Fixed error with point cache 2021-08-06 13:10:29 +05:30
f82df13492 Fixed error in python UI code, and error in caching acceleration. 2021-08-05 09:10:16 +05:30
2980e9791f Merge branch 'master' into soc-2021-simulation-display 2021-08-01 19:34:34 +05:30
083082fcc9 make format 2021-08-01 19:33:54 +05:30
fddc6bc5e9 Physics: Implemented caching previous velocity of rigid bodies so that acceleration can be calculated. 2021-08-01 19:31:03 +05:30
1109e900ce Physics: Added visualisation for slider and hinge constraints. 2021-08-01 13:28:46 +05:30
ea2406f249 Physics: Added visualisation for the slider constraint. 2021-07-26 17:27:20 +05:30
ca154310a6 Cleanup: Fixed missed forces bug by taking the average of all forces applied in one timestep. 2021-07-15 14:45:08 +05:30
0ccbeb64f8 Physics: Added visualisation for trimesh collision shape type 2021-07-11 10:22:25 +05:30
3c14b78dac Physics: Implemented darwing convex hull collisions shapes using mesh_batch_cache functions 2021-07-07 13:12:26 +05:30
16cddb290e Physics: enabled drawing for convex hull collision shape and corrected scale of compound child shapes 2021-07-04 12:16:58 +05:30
f36974123b Merge branch 'master' into soc-2021-simulation-display 2021-06-27 20:27:50 +05:30
c604a944df make format 2021-06-27 20:25:02 +05:30
b9903c78c1 Physics: Added visualisation for rigid body states and a small fix for forces 2021-06-27 20:12:46 +05:30
aad804bac0 Cleanup: fixed some issues with collision display and formatted the code
No functional changes
2021-06-22 11:13:53 +05:30
5cb618f828 No new features, just some cleanups to collision display code 2021-06-21 14:55:57 +05:30
1ddeff9999 Physics: Added basic visualisation for collisions, plus some cleanups to the Forces code 2021-06-19 22:59:17 +05:30
b1d04825e0 No new features implemented, added comments to overlay/shaders/vector_vert.glsl 2021-06-16 14:26:27 +05:30
244fab5876 Physics: Added visualisation for rigid bodies' velocities. 2021-06-14 16:00:25 +05:30
337eb4306c Physics: Added visualisation for frictional forces, plus some clean-ups to previous commit 2021-06-14 16:00:25 +05:30
63c8bf807d Pysics: Added visualisation for forces due to effectors, normal forces and gravity. 2021-06-14 16:00:25 +05:30
5f5b1e51a4 learnt basic arrow, ui panels 2021-06-14 16:00:25 +05:30
93f6db102d Merge branch 'master' of https://git.blender.org/blender 2021-06-14 15:59:15 +05:30
fbd14c1c75 Merge branch 'master' of https://git.blender.org/blender 2021-05-21 12:12:28 +05:30
9545f3ec67 Merge branch 'master' of https://git.blender.org/blender 2021-04-28 18:26:14 +05:30
cfe1f39b5f Merge branch 'master' of https://git.blender.org/blender 2021-04-28 16:20:52 +05:30
87e6e4d3ad Merge branch 'master' of https://git.blender.org/blender 2021-04-28 10:07:11 +05:30
4bc0ec4dda Merge branch 'master' of https://git.blender.org/blender 2021-04-27 13:09:13 +05:30
b826df8aa1 make format 2021-04-27 12:44:53 +05:30
338 changed files with 5202 additions and 2251 deletions

View File

@@ -22,7 +22,7 @@ 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
Before going any further it's best to be aware of ID data-blocks in Blender since you will often find properties
relative to them.
@@ -55,9 +55,9 @@ Start by collecting the information where the data is located.
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
Being an API reference, this link often gives little more information than 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.
But you now know that you have to use ``.location`` and that it's an array of three floats.
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.
@@ -154,7 +154,7 @@ The tooltip includes :class:`bpy.types.SubsurfModifier.levels` but you want the
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.
than 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 execute the code, yet.
@@ -252,6 +252,6 @@ Each entry can be selected, then copied :kbd:`Ctrl-C`, usually to paste in the t
.. 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.
zooming the view for example isn't so useful to repeat so it's excluded from the output.
To display *every* operator that runs see :ref:`Show All Operators <info_show_all_operators>`.

View File

@@ -229,7 +229,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.
for use in cases where you can alter the list order without breaking the script's functionality.
This works by swapping two list items, so the item you remove is always last:
.. code-block:: python
@@ -278,7 +278,7 @@ 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.
This is the slowest option, do **not** use this if you can avoid it, especially when writing data in a loop.
>>> file.write(str1 + " " + str2 + " " + str3 + "\n")
@@ -288,7 +288,7 @@ String formatting
>>> 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
Use this 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")))

View File

@@ -12,7 +12,7 @@ that can be troublesome and avoid practices that are known to cause instability.
Using Operators
===============
Blender's operators are tools for users to access, that can access with Python too which is very useful.
Blender's operators are tools for users to access, that can be accessed with Python too which is very useful.
Still operators have limitations that can make them cumbersome to script.
The main limits are:
@@ -20,13 +20,13 @@ 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 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.
- Operators' poll function can fail where an API function would raise an exception giving details on exactly why.
Why does an operator's poll fail?
---------------------------------
When calling an operator gives an error like this:
When calling an operator it gives an error like this:
>>> bpy.ops.action.clean(threshold=0.001)
RuntimeError: Operator bpy.ops.action.clean.poll() failed, context is incorrect
@@ -49,9 +49,9 @@ 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 the API
but it's currently not used much, if you're interested to help improve the API
feel free to add calls to :class:`bpy.types.Operator.poll_message_set` (``CTX_wm_operator_poll_msg_set`` in C)
where its not obvious why poll fails, e.g:
where it's 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
@@ -107,7 +107,7 @@ In this case you need to call :class:`bpy.types.ViewLayer.update` after modifyin
Now all dependent data (child objects, modifiers, drivers, etc.)
has been recalculated and is available to the script within active view layer.
have been recalculated and are available to the script within the active view layer.
Can I redraw during script execution?
@@ -116,13 +116,13 @@ 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:
While a script executes Blender waits for it to finish and is effectively locked until its done,
While a script executes, Blender waits for it to finish and is effectively locked until it's 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 a long time to complete and it would be nice to see progress in the viewport.
When tools lock Blender in a loop redraw are highly discouraged
Tools that 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.
@@ -130,7 +130,7 @@ So the solution here is to write a **modal** operator, which is an operator that
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.
Examples of a modal operators are Transform, Painting, Fly Navigation and File Select.
Examples of modal operators are Transform, Painting, Fly Navigation and File Select.
Writing modal operators takes more effort than a simple ``for`` loop
that contains draw calls but is more flexible and integrates better with Blender's design.
@@ -240,7 +240,7 @@ Editing
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
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 n-gons to be tessellated.
- BMesh-faces are by far the best way to manipulate geometry.
@@ -256,7 +256,7 @@ the choice mostly depends on whether the target format supports n-gons or not.
- 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 it's not the native storage format in Object-Mode.
Edit Bones, Pose Bones, Bone... Bones
@@ -348,7 +348,7 @@ 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
Further access to these will crash Blender so it's important that the script
clearly separates sections of the code which operate in different modes.
This is mainly an issue with Edit-Mode since pose data can be manipulated without having to be in Pose-Mode,
@@ -386,11 +386,11 @@ Or with name assignment:
Data names may not match the assigned values if they exceed the maximum length, are already used or an empty string.
Its better practice not to reference objects by names at all,
It's 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;
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
If you do need to use name references, it's 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.
@@ -414,11 +414,11 @@ Library Collisions
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.
so it's 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
This can be tricky at times and not even Blender handles this correctly in some cases
(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.
but it's 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
@@ -467,11 +467,11 @@ writing a script in ``latin1`` or ``iso-8859-15``.
See `PEP 263 <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
To avoid the problem for Python integration and script authors we have decided that 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.
This means assigning strings with different encodings to an object name, for instance, will raise an error.
Paths are an exception to this rule since the existence of non-UTF-8 paths on user's file system cannot be ignored.
Paths are an exception to this rule since the existence of non-UTF-8 paths on the user's file system cannot be ignored.
This means seemingly harmless expressions can raise errors, e.g:
>>> print(bpy.data.filepath)
@@ -505,7 +505,7 @@ to keep it short about encoding problems -- here are some suggestions:
.. note::
Sometimes it's preferable to avoid string encoding issues by using bytes instead of Python strings,
when reading some input its less trouble to read it as binary data
when reading some input it's less trouble to read it as binary data
though you will still need to decide how to treat any strings you want to use with Blender,
some importers do this.
@@ -679,7 +679,7 @@ Undo/Redo
---------
For safety, you should assume that undo and redo always invalidates all :class:`bpy.types.ID`
instances (Object, Scene, Mesh, Light, etc.), as weel obviously as all of their sub-data.
instances (Object, Scene, Mesh, Light, etc.), as well obviously as all of their sub-data.
This example shows how you can tell undo changes the memory locations:
@@ -716,7 +716,7 @@ Tools in Blender are not allowed to modify library data.
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,
But it's also possible to use a script to make library data point to newly created local data,
which is not supported since a call to undo will remove the local data
but leave the library referencing it and likely crash.

View File

@@ -81,7 +81,7 @@ 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 two line code block.
This is the equivalent to running the script directly, referencing a script's path from a two line code block.
.. code-block:: python
@@ -124,7 +124,7 @@ small script which is often useful for testing different settings quickly.
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
this following example adds the current blend-file's directory to the search path
and then loads the script as a module.
.. code-block:: python
@@ -302,7 +302,7 @@ Python Safety (Build Option)
----------------------------
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.
it can be 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 two times slower

View File

@@ -74,7 +74,7 @@ enum_panorama_types = (
"Similar to most fisheye modern lens, takes sensor dimensions into consideration"),
('MIRRORBALL', "Mirror Ball", "Uses the mirror ball mapping"),
('FISHEYE_LENS_POLYNOMIAL', "Fisheye Lens Polynomial",
"Defines the lens projection as polynomial to allow real world camera lenses to be mimicked."),
"Defines the lens projection as polynomial to allow real world camera lenses to be mimicked"),
)
enum_curve_shape = (
@@ -901,27 +901,27 @@ class CyclesCameraSettings(bpy.types.PropertyGroup):
fisheye_polynomial_k0: FloatProperty(
name="Fisheye Polynomial K0",
description="Coefficient K0 of the lens polinomial",
description="Coefficient K0 of the lens polynomial",
default=camera.default_fisheye_polynomial[0], precision=6, step=0.1, subtype='ANGLE',
)
fisheye_polynomial_k1: FloatProperty(
name="Fisheye Polynomial K1",
description="Coefficient K1 of the lens polinomial",
description="Coefficient K1 of the lens polynomial",
default=camera.default_fisheye_polynomial[1], precision=6, step=0.1, subtype='ANGLE',
)
fisheye_polynomial_k2: FloatProperty(
name="Fisheye Polynomial K2",
description="Coefficient K2 of the lens polinomial",
description="Coefficient K2 of the lens polynomial",
default=camera.default_fisheye_polynomial[2], precision=6, step=0.1, subtype='ANGLE',
)
fisheye_polynomial_k3: FloatProperty(
name="Fisheye Polynomial K3",
description="Coefficient K3 of the lens polinomial",
description="Coefficient K3 of the lens polynomial",
default=camera.default_fisheye_polynomial[3], precision=6, step=0.1, subtype='ANGLE',
)
fisheye_polynomial_k4: FloatProperty(
name="Fisheye Polynomial K4",
description="Coefficient K4 of the lens polinomial",
description="Coefficient K4 of the lens polynomial",
default=camera.default_fisheye_polynomial[4], precision=6, step=0.1, subtype='ANGLE',
)

View File

@@ -626,11 +626,11 @@ void BlenderSync::sync_particle_hair(
}
}
#ifdef WITH_HAIR_NODES
#ifdef WITH_NEW_CURVES_TYPE
static std::optional<BL::FloatAttribute> find_curves_radius_attribute(BL::Hair b_hair)
static std::optional<BL::FloatAttribute> find_curves_radius_attribute(BL::Curves b_curves)
{
for (BL::Attribute &b_attribute : b_hair.attributes) {
for (BL::Attribute &b_attribute : b_curves.attributes) {
if (b_attribute.name() != "radius") {
continue;
}
@@ -645,16 +645,16 @@ static std::optional<BL::FloatAttribute> find_curves_radius_attribute(BL::Hair b
return std::nullopt;
}
static float4 hair_point_as_float4(BL::Hair b_hair,
static float4 hair_point_as_float4(BL::Curves b_curves,
std::optional<BL::FloatAttribute> b_attr_radius,
const int index)
{
float4 mP = float3_to_float4(get_float3(b_hair.position_data[index].vector()));
float4 mP = float3_to_float4(get_float3(b_curves.position_data[index].vector()));
mP.w = b_attr_radius ? b_attr_radius->data[index].value() : 0.0f;
return mP;
}
static float4 interpolate_hair_points(BL::Hair b_hair,
static float4 interpolate_hair_points(BL::Curves b_curves,
std::optional<BL::FloatAttribute> b_attr_radius,
const int first_point_index,
const int num_points,
@@ -664,12 +664,12 @@ static float4 interpolate_hair_points(BL::Hair b_hair,
const int point_a = clamp((int)curve_t, 0, num_points - 1);
const int point_b = min(point_a + 1, num_points - 1);
const float t = curve_t - (float)point_a;
return lerp(hair_point_as_float4(b_hair, b_attr_radius, first_point_index + point_a),
hair_point_as_float4(b_hair, b_attr_radius, first_point_index + point_b),
return lerp(hair_point_as_float4(b_curves, b_attr_radius, first_point_index + point_a),
hair_point_as_float4(b_curves, b_attr_radius, first_point_index + point_b),
t);
}
static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
static void export_hair_curves(Scene *scene, Hair *hair, BL::Curves b_curves)
{
/* TODO: optimize so we can straight memcpy arrays from Blender? */
@@ -689,19 +689,19 @@ static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
}
/* Reserve memory. */
const int num_keys = b_hair.points.length();
const int num_curves = b_hair.curves.length();
const int num_keys = b_curves.points.length();
const int num_curves = b_curves.curves.length();
hair->reserve_curves(num_curves, num_keys);
std::optional<BL::FloatAttribute> b_attr_radius = find_curves_radius_attribute(b_hair);
std::optional<BL::FloatAttribute> b_attr_radius = find_curves_radius_attribute(b_curves);
/* Export curves and points. */
vector<float> points_length;
for (int i = 0; i < num_curves; i++) {
const int first_point_index = b_hair.curve_offset_data[i].value();
const int num_points = b_hair.curve_offset_data[i + 1].value() - first_point_index;
const int first_point_index = b_curves.curve_offset_data[i].value();
const int num_points = b_curves.curve_offset_data[i + 1].value() - first_point_index;
float3 prev_co = zero_float3();
float length = 0.0f;
@@ -712,7 +712,7 @@ static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
/* Position and radius. */
for (int i = 0; i < num_points; i++) {
const float3 co = get_float3(b_hair.position_data[first_point_index + i].vector());
const float3 co = get_float3(b_curves.position_data[first_point_index + i].vector());
const float radius = b_attr_radius ? b_attr_radius->data[first_point_index + i].value() :
0.0f;
hair->add_curve_key(co, radius);
@@ -748,7 +748,7 @@ static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
}
}
static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_step)
static void export_hair_curves_motion(Hair *hair, BL::Curves b_curves, int motion_step)
{
/* Find or add attribute. */
Attribute *attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
@@ -761,17 +761,17 @@ static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_st
/* Export motion keys. */
const int num_keys = hair->get_curve_keys().size();
const int num_curves = b_hair.curves.length();
const int num_curves = b_curves.curves.length();
float4 *mP = attr_mP->data_float4() + motion_step * num_keys;
bool have_motion = false;
int num_motion_keys = 0;
int curve_index = 0;
std::optional<BL::FloatAttribute> b_attr_radius = find_curves_radius_attribute(b_hair);
std::optional<BL::FloatAttribute> b_attr_radius = find_curves_radius_attribute(b_curves);
for (int i = 0; i < num_curves; i++) {
const int first_point_index = b_hair.curve_offset_data[i].value();
const int num_points = b_hair.curve_offset_data[i + 1].value() - first_point_index;
const int first_point_index = b_curves.curve_offset_data[i].value();
const int num_points = b_curves.curve_offset_data[i + 1].value() - first_point_index;
Hair::Curve curve = hair->get_curve(curve_index);
curve_index++;
@@ -782,7 +782,7 @@ static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_st
int point_index = first_point_index + i;
if (point_index < num_keys) {
mP[num_motion_keys] = hair_point_as_float4(b_hair, b_attr_radius, point_index);
mP[num_motion_keys] = hair_point_as_float4(b_curves, b_attr_radius, point_index);
num_motion_keys++;
if (!have_motion) {
@@ -802,7 +802,7 @@ static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_st
for (int i = 0; i < curve.num_keys; i++) {
const float step = i * step_size;
mP[num_motion_keys] = interpolate_hair_points(
b_hair, b_attr_radius, first_point_index, num_points, step);
b_curves, b_attr_radius, first_point_index, num_points, step);
num_motion_keys++;
}
have_motion = true;
@@ -819,12 +819,12 @@ static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_st
void BlenderSync::sync_hair(Hair *hair, BObjectInfo &b_ob_info, bool motion, int motion_step)
{
/* Convert Blender hair to Cycles curves. */
BL::Hair b_hair(b_ob_info.object_data);
BL::Curves b_curves(b_ob_info.object_data);
if (motion) {
export_hair_curves_motion(hair, b_hair, motion_step);
export_hair_curves_motion(hair, b_curves, motion_step);
}
else {
export_hair_curves(scene, hair, b_hair);
export_hair_curves(scene, hair, b_curves);
}
}
#else
@@ -847,8 +847,8 @@ void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, H
new_hair.set_used_shaders(used_shaders);
if (view_layer.use_hair) {
#ifdef WITH_HAIR_NODES
if (b_ob_info.object_data.is_a(&RNA_Hair)) {
#ifdef WITH_NEW_CURVES_TYPE
if (b_ob_info.object_data.is_a(&RNA_Curves)) {
/* Hair object. */
sync_hair(&new_hair, b_ob_info, false);
}
@@ -901,8 +901,8 @@ void BlenderSync::sync_hair_motion(BL::Depsgraph b_depsgraph,
/* Export deformed coordinates. */
if (ccl::BKE_object_is_deform_modified(b_ob_info, b_scene, preview)) {
#ifdef WITH_HAIR_NODES
if (b_ob_info.object_data.is_a(&RNA_Hair)) {
#ifdef WITH_NEW_CURVES_TYPE
if (b_ob_info.object_data.is_a(&RNA_Curves)) {
/* Hair object. */
sync_hair(hair, b_ob_info, true, motion_step);
return;

View File

@@ -32,8 +32,8 @@ CCL_NAMESPACE_BEGIN
static Geometry::Type determine_geom_type(BObjectInfo &b_ob_info, bool use_particle_hair)
{
#ifdef WITH_HAIR_NODES
if (b_ob_info.object_data.is_a(&RNA_Hair) || use_particle_hair) {
#ifdef WITH_NEW_CURVES_TYPE
if (b_ob_info.object_data.is_a(&RNA_Curves) || use_particle_hair) {
#else
if (use_particle_hair) {
#endif
@@ -231,8 +231,8 @@ void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph,
if (progress.get_cancel())
return;
#ifdef WITH_HAIR_NODES
if (b_ob_info.object_data.is_a(&RNA_Hair) || use_particle_hair) {
#ifdef WITH_NEW_CURVES_TYPE
if (b_ob_info.object_data.is_a(&RNA_Curves) || use_particle_hair) {
#else
if (use_particle_hair) {
#endif

View File

@@ -72,7 +72,7 @@ bool BlenderSync::object_is_geometry(BObjectInfo &b_ob_info)
BL::Object::type_enum type = b_ob_info.iter_object.type();
if (type == BL::Object::type_VOLUME || type == BL::Object::type_HAIR ||
if (type == BL::Object::type_VOLUME || type == BL::Object::type_CURVES ||
type == BL::Object::type_POINTCLOUD) {
/* Will be exported attached to mesh. */
return true;
@@ -97,7 +97,7 @@ bool BlenderSync::object_can_have_geometry(BL::Object &b_ob)
case BL::Object::type_SURFACE:
case BL::Object::type_META:
case BL::Object::type_FONT:
case BL::Object::type_HAIR:
case BL::Object::type_CURVES:
case BL::Object::type_POINTCLOUD:
case BL::Object::type_VOLUME:
return true;

View File

@@ -889,16 +889,11 @@ extern char *GHOST_getClipboard(bool selection);
extern void GHOST_putClipboard(const char *buffer, bool selection);
/**
* Toggles console
* \param action:
* - 0: Hides
* - 1: Shows
* - 2: Toggles
* - 3: Hides if it runs not from command line
* - *: Does nothing
* Set the Console State
* \param action: console state
* \return current status (1 -visible, 0 - hidden)
*/
extern int GHOST_toggleConsole(int action);
extern int setConsoleWindowState(GHOST_TConsoleWindowState action);
/**
* Use native pixel size (MacBook pro 'retina'), if supported.

View File

@@ -411,16 +411,11 @@ class GHOST_ISystem {
#endif
/**
* Toggles console
* \param action:
* - 0: Hides.
* - 1: Shows
* - 2: Toggles
* - 3: Hides if it runs not from command line
* - *: Does nothing
* Set the Console State
* \param action: console state
* \return current status (1 -visible, 0 - hidden)
*/
virtual int toggleConsole(int action) = 0;
virtual int setConsoleWindowState(GHOST_TConsoleWindowState action) = 0;
/***************************************************************************************
* Access to clipboard.

View File

@@ -140,6 +140,13 @@ typedef enum {
// GHOST_kWindowStateUnModified,
} GHOST_TWindowState;
typedef enum {
GHOST_kConsoleWindowStateHide = 0,
GHOST_kConsoleWindowStateShow,
GHOST_kConsoleWindowStateToggle,
GHOST_kConsoleWindowStateHideForNonConsoleLaunch
} GHOST_TConsoleWindowState;
typedef enum { GHOST_kWindowOrderTop = 0, GHOST_kWindowOrderBottom } GHOST_TWindowOrder;
typedef enum {

View File

@@ -809,10 +809,10 @@ void GHOST_putClipboard(const char *buffer, bool selection)
system->putClipboard(buffer, selection);
}
int GHOST_toggleConsole(int action)
int setConsoleWindowState(GHOST_TConsoleWindowState action)
{
GHOST_ISystem *system = GHOST_ISystem::getSystem();
return system->toggleConsole(action);
return system->setConsoleWindowState(action);
}
int GHOST_UseNativePixels(void)

View File

@@ -13,11 +13,9 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
* Video mode switching
* Copyright (C) 1997-2001 Id Software, Inc.
* Ported from Quake 2 by Alex Fraser <alex@phatcore.com>
* Copyright 2001-2002 NaN Holding BV. All rights reserved.
* 1997-2001 Id Software, Inc. Video mode switching.
Ported from Quake 2 by Alex Fraser <alex@phatcore.com>.
*/
/** \file

View File

@@ -14,9 +14,6 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (c) 2010 The Chromium Authors. All rights reserved.
* All rights reserved.
*
* The Original Code is: some of this file.
*/
/** \file

View File

@@ -14,9 +14,6 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (c) 2010 The Chromium Authors. All rights reserved.
* All rights reserved.
*
* The Original Code is: some of this file.
*/
/** \file

View File

@@ -244,7 +244,7 @@ class GHOST_SystemCocoa : public GHOST_System {
/**
* \see GHOST_ISystem
*/
int toggleConsole(int action)
int setConsoleWindowState(GHOST_TConsoleWindowState action)
{
return 0;
}

View File

@@ -40,7 +40,7 @@ class GHOST_SystemNULL : public GHOST_System {
{
return false;
}
int toggleConsole(int action)
int setConsoleWindowState(GHOST_TConsoleWindowState action)
{
return 0;
}

View File

@@ -47,7 +47,7 @@ class GHOST_SystemSDL : public GHOST_System {
bool processEvents(bool waitForEvent);
int toggleConsole(int action)
int setConsoleWindowState(GHOST_TConsoleWindowState action)
{
return 0;
}

View File

@@ -1473,7 +1473,7 @@ bool GHOST_SystemWayland::processEvents(bool waitForEvent)
return fired || (getEventManager()->getNumEvents() > 0);
}
int GHOST_SystemWayland::toggleConsole(int /*action*/)
int GHOST_SystemWayland::setConsoleWindowState(GHOST_TConsoleWindowState /*action*/)
{
return 0;
}

View File

@@ -53,7 +53,7 @@ class GHOST_SystemWayland : public GHOST_System {
bool processEvents(bool waitForEvent) override;
int toggleConsole(int action) override;
int setConsoleWindowState(GHOST_TConsoleWindowState action) override;
GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys &keys) const override;

View File

@@ -105,6 +105,8 @@
*/
#define BROKEN_PEEK_TOUCHPAD
static bool isStartedFromCommandPrompt();
static void initRawInput()
{
#ifdef WITH_INPUT_NDOF
@@ -166,7 +168,10 @@ GHOST_SystemWin32::~GHOST_SystemWin32()
{
// Shutdown COM
OleUninitialize();
toggleConsole(1);
if (isStartedFromCommandPrompt()) {
setConsoleWindowState(GHOST_kConsoleWindowStateShow);
}
}
uint64_t GHOST_SystemWin32::performanceCounterToMillis(__int64 perf_ticks) const
@@ -2216,31 +2221,30 @@ static bool isStartedFromCommandPrompt()
return false;
}
int GHOST_SystemWin32::toggleConsole(int action)
int GHOST_SystemWin32::setConsoleWindowState(GHOST_TConsoleWindowState action)
{
HWND wnd = GetConsoleWindow();
switch (action) {
case 3: // startup: hide if not started from command prompt
{
case GHOST_kConsoleWindowStateHideForNonConsoleLaunch: {
if (!isStartedFromCommandPrompt()) {
ShowWindow(wnd, SW_HIDE);
m_consoleStatus = 0;
}
break;
}
case 0: // hide
case GHOST_kConsoleWindowStateHide:
ShowWindow(wnd, SW_HIDE);
m_consoleStatus = 0;
break;
case 1: // show
case GHOST_kConsoleWindowStateShow:
ShowWindow(wnd, SW_SHOW);
if (!isStartedFromCommandPrompt()) {
DeleteMenu(GetSystemMenu(wnd, FALSE), SC_CLOSE, MF_BYCOMMAND);
}
m_consoleStatus = 1;
break;
case 2: // toggle
case GHOST_kConsoleWindowStateToggle:
ShowWindow(wnd, m_consoleStatus ? SW_HIDE : SW_SHOW);
m_consoleStatus = !m_consoleStatus;
if (m_consoleStatus && !isStartedFromCommandPrompt()) {

View File

@@ -436,16 +436,11 @@ class GHOST_SystemWin32 : public GHOST_System {
static LRESULT WINAPI s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
/**
* Toggles console
* \param action:
* - 0 - Hides
* - 1 - Shows
* - 2 - Toggles
* - 3 - Hides if it runs not from command line
* - * - Does nothing
* Set the Console State
* \param action: console state
* \return current status (1 -visible, 0 - hidden)
*/
int toggleConsole(int action);
int setConsoleWindowState(GHOST_TConsoleWindowState action);
/** The current state of the modifier keys. */
GHOST_ModifierKeys m_modifierKeys;

View File

@@ -13,10 +13,9 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
* Part of this code has been taken from Qt, under LGPL license
* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
* Copyright 2001-2002 NaN Holding BV. All rights reserved.
* 2009 Nokia Corporation and/or its subsidiary(-ies).
Part of this code has been taken from Qt, under LGPL license.
*/
/** \file

View File

@@ -269,7 +269,7 @@ class GHOST_SystemX11 : public GHOST_System {
/**
* \see GHOST_ISystem
*/
int toggleConsole(int /*action*/)
int setConsoleWindowState(GHOST_TConsoleWindowState /*action*/)
{
return 0;
}

View File

@@ -15,7 +15,6 @@
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
* Original author: Laurence
*/
/** \file

View File

@@ -15,7 +15,6 @@
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
* Original author: Laurence
*/
/** \file

View File

@@ -15,7 +15,6 @@
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
* Original author: Laurence
*/
/** \file

View File

@@ -15,7 +15,6 @@
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
* Original author: Laurence
*/
/** \file

View File

@@ -29,277 +29,276 @@
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _MSC_VER // [
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]
#ifndef _MSC_VER // [
# error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]
#ifndef _MSC_INTTYPES_H_ // [
#define _MSC_INTTYPES_H_
#ifndef _MSC_INTTYPES_H_ // [
# define _MSC_INTTYPES_H_
#if _MSC_VER > 1000
#pragma once
#endif
# if _MSC_VER > 1000
# pragma once
# endif
#include <stdint.h>
# include <stdint.h>
// 7.8 Format conversion of integer types
typedef struct {
intmax_t quot;
intmax_t rem;
intmax_t quot;
intmax_t rem;
} imaxdiv_t;
// 7.8.1 Macros for format specifiers
#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198
# if !defined(__cplusplus) || \
defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198
// The fprintf macros for signed integers are:
#define PRId8 "d"
#define PRIi8 "i"
#define PRIdLEAST8 "d"
#define PRIiLEAST8 "i"
#define PRIdFAST8 "d"
#define PRIiFAST8 "i"
# define PRId8 "d"
# define PRIi8 "i"
# define PRIdLEAST8 "d"
# define PRIiLEAST8 "i"
# define PRIdFAST8 "d"
# define PRIiFAST8 "i"
#define PRId16 "hd"
#define PRIi16 "hi"
#define PRIdLEAST16 "hd"
#define PRIiLEAST16 "hi"
#define PRIdFAST16 "hd"
#define PRIiFAST16 "hi"
# define PRId16 "hd"
# define PRIi16 "hi"
# define PRIdLEAST16 "hd"
# define PRIiLEAST16 "hi"
# define PRIdFAST16 "hd"
# define PRIiFAST16 "hi"
#define PRId32 "I32d"
#define PRIi32 "I32i"
#define PRIdLEAST32 "I32d"
#define PRIiLEAST32 "I32i"
#define PRIdFAST32 "I32d"
#define PRIiFAST32 "I32i"
# define PRId32 "I32d"
# define PRIi32 "I32i"
# define PRIdLEAST32 "I32d"
# define PRIiLEAST32 "I32i"
# define PRIdFAST32 "I32d"
# define PRIiFAST32 "I32i"
#define PRId64 "I64d"
#define PRIi64 "I64i"
#define PRIdLEAST64 "I64d"
#define PRIiLEAST64 "I64i"
#define PRIdFAST64 "I64d"
#define PRIiFAST64 "I64i"
# define PRId64 "I64d"
# define PRIi64 "I64i"
# define PRIdLEAST64 "I64d"
# define PRIiLEAST64 "I64i"
# define PRIdFAST64 "I64d"
# define PRIiFAST64 "I64i"
#define PRIdMAX "I64d"
#define PRIiMAX "I64i"
# define PRIdMAX "I64d"
# define PRIiMAX "I64i"
#define PRIdPTR "Id"
#define PRIiPTR "Ii"
# define PRIdPTR "Id"
# define PRIiPTR "Ii"
// The fprintf macros for unsigned integers are:
#define PRIo8 "o"
#define PRIu8 "u"
#define PRIx8 "x"
#define PRIX8 "X"
#define PRIoLEAST8 "o"
#define PRIuLEAST8 "u"
#define PRIxLEAST8 "x"
#define PRIXLEAST8 "X"
#define PRIoFAST8 "o"
#define PRIuFAST8 "u"
#define PRIxFAST8 "x"
#define PRIXFAST8 "X"
# define PRIo8 "o"
# define PRIu8 "u"
# define PRIx8 "x"
# define PRIX8 "X"
# define PRIoLEAST8 "o"
# define PRIuLEAST8 "u"
# define PRIxLEAST8 "x"
# define PRIXLEAST8 "X"
# define PRIoFAST8 "o"
# define PRIuFAST8 "u"
# define PRIxFAST8 "x"
# define PRIXFAST8 "X"
#define PRIo16 "ho"
#define PRIu16 "hu"
#define PRIx16 "hx"
#define PRIX16 "hX"
#define PRIoLEAST16 "ho"
#define PRIuLEAST16 "hu"
#define PRIxLEAST16 "hx"
#define PRIXLEAST16 "hX"
#define PRIoFAST16 "ho"
#define PRIuFAST16 "hu"
#define PRIxFAST16 "hx"
#define PRIXFAST16 "hX"
# define PRIo16 "ho"
# define PRIu16 "hu"
# define PRIx16 "hx"
# define PRIX16 "hX"
# define PRIoLEAST16 "ho"
# define PRIuLEAST16 "hu"
# define PRIxLEAST16 "hx"
# define PRIXLEAST16 "hX"
# define PRIoFAST16 "ho"
# define PRIuFAST16 "hu"
# define PRIxFAST16 "hx"
# define PRIXFAST16 "hX"
#define PRIo32 "I32o"
#define PRIu32 "I32u"
#define PRIx32 "I32x"
#define PRIX32 "I32X"
#define PRIoLEAST32 "I32o"
#define PRIuLEAST32 "I32u"
#define PRIxLEAST32 "I32x"
#define PRIXLEAST32 "I32X"
#define PRIoFAST32 "I32o"
#define PRIuFAST32 "I32u"
#define PRIxFAST32 "I32x"
#define PRIXFAST32 "I32X"
# define PRIo32 "I32o"
# define PRIu32 "I32u"
# define PRIx32 "I32x"
# define PRIX32 "I32X"
# define PRIoLEAST32 "I32o"
# define PRIuLEAST32 "I32u"
# define PRIxLEAST32 "I32x"
# define PRIXLEAST32 "I32X"
# define PRIoFAST32 "I32o"
# define PRIuFAST32 "I32u"
# define PRIxFAST32 "I32x"
# define PRIXFAST32 "I32X"
#define PRIo64 "I64o"
#define PRIu64 "I64u"
#define PRIx64 "I64x"
#define PRIX64 "I64X"
#define PRIoLEAST64 "I64o"
#define PRIuLEAST64 "I64u"
#define PRIxLEAST64 "I64x"
#define PRIXLEAST64 "I64X"
#define PRIoFAST64 "I64o"
#define PRIuFAST64 "I64u"
#define PRIxFAST64 "I64x"
#define PRIXFAST64 "I64X"
# define PRIo64 "I64o"
# define PRIu64 "I64u"
# define PRIx64 "I64x"
# define PRIX64 "I64X"
# define PRIoLEAST64 "I64o"
# define PRIuLEAST64 "I64u"
# define PRIxLEAST64 "I64x"
# define PRIXLEAST64 "I64X"
# define PRIoFAST64 "I64o"
# define PRIuFAST64 "I64u"
# define PRIxFAST64 "I64x"
# define PRIXFAST64 "I64X"
#define PRIoMAX "I64o"
#define PRIuMAX "I64u"
#define PRIxMAX "I64x"
#define PRIXMAX "I64X"
# define PRIoMAX "I64o"
# define PRIuMAX "I64u"
# define PRIxMAX "I64x"
# define PRIXMAX "I64X"
#define PRIoPTR "Io"
#define PRIuPTR "Iu"
#define PRIxPTR "Ix"
#define PRIXPTR "IX"
# define PRIoPTR "Io"
# define PRIuPTR "Iu"
# define PRIxPTR "Ix"
# define PRIXPTR "IX"
// The fscanf macros for signed integers are:
#define SCNd8 "d"
#define SCNi8 "i"
#define SCNdLEAST8 "d"
#define SCNiLEAST8 "i"
#define SCNdFAST8 "d"
#define SCNiFAST8 "i"
# define SCNd8 "d"
# define SCNi8 "i"
# define SCNdLEAST8 "d"
# define SCNiLEAST8 "i"
# define SCNdFAST8 "d"
# define SCNiFAST8 "i"
#define SCNd16 "hd"
#define SCNi16 "hi"
#define SCNdLEAST16 "hd"
#define SCNiLEAST16 "hi"
#define SCNdFAST16 "hd"
#define SCNiFAST16 "hi"
# define SCNd16 "hd"
# define SCNi16 "hi"
# define SCNdLEAST16 "hd"
# define SCNiLEAST16 "hi"
# define SCNdFAST16 "hd"
# define SCNiFAST16 "hi"
#define SCNd32 "ld"
#define SCNi32 "li"
#define SCNdLEAST32 "ld"
#define SCNiLEAST32 "li"
#define SCNdFAST32 "ld"
#define SCNiFAST32 "li"
# define SCNd32 "ld"
# define SCNi32 "li"
# define SCNdLEAST32 "ld"
# define SCNiLEAST32 "li"
# define SCNdFAST32 "ld"
# define SCNiFAST32 "li"
#define SCNd64 "I64d"
#define SCNi64 "I64i"
#define SCNdLEAST64 "I64d"
#define SCNiLEAST64 "I64i"
#define SCNdFAST64 "I64d"
#define SCNiFAST64 "I64i"
# define SCNd64 "I64d"
# define SCNi64 "I64i"
# define SCNdLEAST64 "I64d"
# define SCNiLEAST64 "I64i"
# define SCNdFAST64 "I64d"
# define SCNiFAST64 "I64i"
#define SCNdMAX "I64d"
#define SCNiMAX "I64i"
# define SCNdMAX "I64d"
# define SCNiMAX "I64i"
#ifdef _WIN64 // [
# define SCNdPTR "I64d"
# define SCNiPTR "I64i"
#else // _WIN64 ][
# define SCNdPTR "ld"
# define SCNiPTR "li"
#endif // _WIN64 ]
# ifdef _WIN64 // [
# define SCNdPTR "I64d"
# define SCNiPTR "I64i"
# else // _WIN64 ][
# define SCNdPTR "ld"
# define SCNiPTR "li"
# endif // _WIN64 ]
// The fscanf macros for unsigned integers are:
#define SCNo8 "o"
#define SCNu8 "u"
#define SCNx8 "x"
#define SCNX8 "X"
#define SCNoLEAST8 "o"
#define SCNuLEAST8 "u"
#define SCNxLEAST8 "x"
#define SCNXLEAST8 "X"
#define SCNoFAST8 "o"
#define SCNuFAST8 "u"
#define SCNxFAST8 "x"
#define SCNXFAST8 "X"
# define SCNo8 "o"
# define SCNu8 "u"
# define SCNx8 "x"
# define SCNX8 "X"
# define SCNoLEAST8 "o"
# define SCNuLEAST8 "u"
# define SCNxLEAST8 "x"
# define SCNXLEAST8 "X"
# define SCNoFAST8 "o"
# define SCNuFAST8 "u"
# define SCNxFAST8 "x"
# define SCNXFAST8 "X"
#define SCNo16 "ho"
#define SCNu16 "hu"
#define SCNx16 "hx"
#define SCNX16 "hX"
#define SCNoLEAST16 "ho"
#define SCNuLEAST16 "hu"
#define SCNxLEAST16 "hx"
#define SCNXLEAST16 "hX"
#define SCNoFAST16 "ho"
#define SCNuFAST16 "hu"
#define SCNxFAST16 "hx"
#define SCNXFAST16 "hX"
# define SCNo16 "ho"
# define SCNu16 "hu"
# define SCNx16 "hx"
# define SCNX16 "hX"
# define SCNoLEAST16 "ho"
# define SCNuLEAST16 "hu"
# define SCNxLEAST16 "hx"
# define SCNXLEAST16 "hX"
# define SCNoFAST16 "ho"
# define SCNuFAST16 "hu"
# define SCNxFAST16 "hx"
# define SCNXFAST16 "hX"
#define SCNo32 "lo"
#define SCNu32 "lu"
#define SCNx32 "lx"
#define SCNX32 "lX"
#define SCNoLEAST32 "lo"
#define SCNuLEAST32 "lu"
#define SCNxLEAST32 "lx"
#define SCNXLEAST32 "lX"
#define SCNoFAST32 "lo"
#define SCNuFAST32 "lu"
#define SCNxFAST32 "lx"
#define SCNXFAST32 "lX"
# define SCNo32 "lo"
# define SCNu32 "lu"
# define SCNx32 "lx"
# define SCNX32 "lX"
# define SCNoLEAST32 "lo"
# define SCNuLEAST32 "lu"
# define SCNxLEAST32 "lx"
# define SCNXLEAST32 "lX"
# define SCNoFAST32 "lo"
# define SCNuFAST32 "lu"
# define SCNxFAST32 "lx"
# define SCNXFAST32 "lX"
#define SCNo64 "I64o"
#define SCNu64 "I64u"
#define SCNx64 "I64x"
#define SCNX64 "I64X"
#define SCNoLEAST64 "I64o"
#define SCNuLEAST64 "I64u"
#define SCNxLEAST64 "I64x"
#define SCNXLEAST64 "I64X"
#define SCNoFAST64 "I64o"
#define SCNuFAST64 "I64u"
#define SCNxFAST64 "I64x"
#define SCNXFAST64 "I64X"
# define SCNo64 "I64o"
# define SCNu64 "I64u"
# define SCNx64 "I64x"
# define SCNX64 "I64X"
# define SCNoLEAST64 "I64o"
# define SCNuLEAST64 "I64u"
# define SCNxLEAST64 "I64x"
# define SCNXLEAST64 "I64X"
# define SCNoFAST64 "I64o"
# define SCNuFAST64 "I64u"
# define SCNxFAST64 "I64x"
# define SCNXFAST64 "I64X"
#define SCNoMAX "I64o"
#define SCNuMAX "I64u"
#define SCNxMAX "I64x"
#define SCNXMAX "I64X"
# define SCNoMAX "I64o"
# define SCNuMAX "I64u"
# define SCNxMAX "I64x"
# define SCNXMAX "I64X"
#ifdef _WIN64 // [
# define SCNoPTR "I64o"
# define SCNuPTR "I64u"
# define SCNxPTR "I64x"
# define SCNXPTR "I64X"
#else // _WIN64 ][
# define SCNoPTR "lo"
# define SCNuPTR "lu"
# define SCNxPTR "lx"
# define SCNXPTR "lX"
#endif // _WIN64 ]
# ifdef _WIN64 // [
# define SCNoPTR "I64o"
# define SCNuPTR "I64u"
# define SCNxPTR "I64x"
# define SCNXPTR "I64X"
# else // _WIN64 ][
# define SCNoPTR "lo"
# define SCNuPTR "lu"
# define SCNxPTR "lx"
# define SCNXPTR "lX"
# endif // _WIN64 ]
#endif // __STDC_FORMAT_MACROS ]
# endif // __STDC_FORMAT_MACROS ]
// 7.8.2 Functions for greatest-width integer types
// 7.8.2.1 The imaxabs function
#define imaxabs _abs64
# define imaxabs _abs64
// 7.8.2.2 The imaxdiv function
// This is modified version of div() function from Microsoft's div.c found
// in %MSVC.NET%\crt\src\div.c
#ifdef STATIC_IMAXDIV // [
# ifdef STATIC_IMAXDIV // [
static
#else // STATIC_IMAXDIV ][
# else // STATIC_IMAXDIV ][
_inline
#endif // STATIC_IMAXDIV ]
imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
{
imaxdiv_t result;
# endif // STATIC_IMAXDIV ]
imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) {
imaxdiv_t result;
result.quot = numer / denom;
result.rem = numer % denom;
result.quot = numer / denom;
result.rem = numer % denom;
if (numer < 0 && result.rem > 0) {
// did division wrong; must fix up
++result.quot;
result.rem -= denom;
}
if (numer < 0 && result.rem > 0) {
// did division wrong; must fix up
++result.quot;
result.rem -= denom;
}
return result;
return result;
}
// 7.8.2.3 The strtoimax and strtoumax functions
#define strtoimax _strtoi64
#define strtoumax _strtoui64
# define strtoimax _strtoi64
# define strtoumax _strtoui64
// 7.8.2.4 The wcstoimax and wcstoumax functions
#define wcstoimax _wcstoi64
#define wcstoumax _wcstoui64
# define wcstoimax _wcstoi64
# define wcstoumax _wcstoui64
#endif // _MSC_INTTYPES_H_ ]
#endif // _MSC_INTTYPES_H_ ]

View File

@@ -29,40 +29,40 @@
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _MSC_VER // [
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]
#ifndef _MSC_VER // [
# error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]
#ifndef _MSC_STDINT_H_ // [
#define _MSC_STDINT_H_
#ifndef _MSC_STDINT_H_ // [
# define _MSC_STDINT_H_
#if _MSC_VER > 1000
#pragma once
#endif
# if _MSC_VER > 1000
# pragma once
# endif
#include <limits.h>
# include <limits.h>
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
// or compiler give many errors like this:
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
#ifdef __cplusplus
# ifdef __cplusplus
extern "C" {
#endif
# endif
# include <wchar.h>
#ifdef __cplusplus
# ifdef __cplusplus
}
#endif
# endif
// Define _W64 macros to mark types changing their size, like intptr_t.
#ifndef _W64
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
# define _W64 __w64
# else
# define _W64
# ifndef _W64
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && \
_MSC_VER >= 1300
# define _W64 __w64
# else
# define _W64
# endif
# endif
#endif
// 7.18.1 Integer types
@@ -71,177 +71,176 @@ extern "C" {
// Visual Studio 6 and Embedded Visual C++ 4 doesn't
// realize that, e.g. char has the same size as __int8
// so we give up on __intX for them.
#if (_MSC_VER < 1300)
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
#else
typedef signed __int8 int8_t;
typedef signed __int16 int16_t;
typedef signed __int32 int32_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
#endif
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
# if (_MSC_VER < 1300)
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
# else
typedef signed __int8 int8_t;
typedef signed __int16 int16_t;
typedef signed __int32 int32_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
# endif
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
// 7.18.1.2 Minimum-width integer types
typedef int8_t int_least8_t;
typedef int16_t int_least16_t;
typedef int32_t int_least32_t;
typedef int64_t int_least64_t;
typedef uint8_t uint_least8_t;
typedef uint16_t uint_least16_t;
typedef uint32_t uint_least32_t;
typedef uint64_t uint_least64_t;
typedef int8_t int_least8_t;
typedef int16_t int_least16_t;
typedef int32_t int_least32_t;
typedef int64_t int_least64_t;
typedef uint8_t uint_least8_t;
typedef uint16_t uint_least16_t;
typedef uint32_t uint_least32_t;
typedef uint64_t uint_least64_t;
// 7.18.1.3 Fastest minimum-width integer types
typedef int8_t int_fast8_t;
typedef int16_t int_fast16_t;
typedef int32_t int_fast32_t;
typedef int64_t int_fast64_t;
typedef uint8_t uint_fast8_t;
typedef uint16_t uint_fast16_t;
typedef uint32_t uint_fast32_t;
typedef uint64_t uint_fast64_t;
typedef int8_t int_fast8_t;
typedef int16_t int_fast16_t;
typedef int32_t int_fast32_t;
typedef int64_t int_fast64_t;
typedef uint8_t uint_fast8_t;
typedef uint16_t uint_fast16_t;
typedef uint32_t uint_fast32_t;
typedef uint64_t uint_fast64_t;
// 7.18.1.4 Integer types capable of holding object pointers
#ifdef _WIN64 // [
typedef __int64 intptr_t;
typedef unsigned __int64 uintptr_t;
#else // _WIN64 ][
typedef _W64 int intptr_t;
typedef _W64 unsigned int uintptr_t;
#endif // _WIN64 ]
# ifdef _WIN64 // [
typedef __int64 intptr_t;
typedef unsigned __int64 uintptr_t;
# else // _WIN64 ][
typedef _W64 int intptr_t;
typedef _W64 unsigned int uintptr_t;
# endif // _WIN64 ]
// 7.18.1.5 Greatest-width integer types
typedef int64_t intmax_t;
typedef uint64_t uintmax_t;
typedef int64_t intmax_t;
typedef uint64_t uintmax_t;
// 7.18.2 Limits of specified-width integer types
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
# if !defined(__cplusplus) || \
defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and
// footnote 221 at page 259
// 7.18.2.1 Limits of exact-width integer types
#define INT8_MIN ((int8_t)_I8_MIN)
#define INT8_MAX _I8_MAX
#define INT16_MIN ((int16_t)_I16_MIN)
#define INT16_MAX _I16_MAX
#define INT32_MIN ((int32_t)_I32_MIN)
#define INT32_MAX _I32_MAX
#define INT64_MIN ((int64_t)_I64_MIN)
#define INT64_MAX _I64_MAX
#define UINT8_MAX _UI8_MAX
#define UINT16_MAX _UI16_MAX
#define UINT32_MAX _UI32_MAX
#define UINT64_MAX _UI64_MAX
# define INT8_MIN ((int8_t)_I8_MIN)
# define INT8_MAX _I8_MAX
# define INT16_MIN ((int16_t)_I16_MIN)
# define INT16_MAX _I16_MAX
# define INT32_MIN ((int32_t)_I32_MIN)
# define INT32_MAX _I32_MAX
# define INT64_MIN ((int64_t)_I64_MIN)
# define INT64_MAX _I64_MAX
# define UINT8_MAX _UI8_MAX
# define UINT16_MAX _UI16_MAX
# define UINT32_MAX _UI32_MAX
# define UINT64_MAX _UI64_MAX
// 7.18.2.2 Limits of minimum-width integer types
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MIN INT64_MIN
#define INT_LEAST64_MAX INT64_MAX
#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX
# define INT_LEAST8_MIN INT8_MIN
# define INT_LEAST8_MAX INT8_MAX
# define INT_LEAST16_MIN INT16_MIN
# define INT_LEAST16_MAX INT16_MAX
# define INT_LEAST32_MIN INT32_MIN
# define INT_LEAST32_MAX INT32_MAX
# define INT_LEAST64_MIN INT64_MIN
# define INT_LEAST64_MAX INT64_MAX
# define UINT_LEAST8_MAX UINT8_MAX
# define UINT_LEAST16_MAX UINT16_MAX
# define UINT_LEAST32_MAX UINT32_MAX
# define UINT_LEAST64_MAX UINT64_MAX
// 7.18.2.3 Limits of fastest minimum-width integer types
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MIN INT16_MIN
#define INT_FAST16_MAX INT16_MAX
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MIN INT64_MIN
#define INT_FAST64_MAX INT64_MAX
#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT16_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX
# define INT_FAST8_MIN INT8_MIN
# define INT_FAST8_MAX INT8_MAX
# define INT_FAST16_MIN INT16_MIN
# define INT_FAST16_MAX INT16_MAX
# define INT_FAST32_MIN INT32_MIN
# define INT_FAST32_MAX INT32_MAX
# define INT_FAST64_MIN INT64_MIN
# define INT_FAST64_MAX INT64_MAX
# define UINT_FAST8_MAX UINT8_MAX
# define UINT_FAST16_MAX UINT16_MAX
# define UINT_FAST32_MAX UINT32_MAX
# define UINT_FAST64_MAX UINT64_MAX
// 7.18.2.4 Limits of integer types capable of holding object pointers
#ifdef _WIN64 // [
# define INTPTR_MIN INT64_MIN
# define INTPTR_MAX INT64_MAX
# define UINTPTR_MAX UINT64_MAX
#else // _WIN64 ][
# define INTPTR_MIN INT32_MIN
# define INTPTR_MAX INT32_MAX
# define UINTPTR_MAX UINT32_MAX
#endif // _WIN64 ]
# ifdef _WIN64 // [
# define INTPTR_MIN INT64_MIN
# define INTPTR_MAX INT64_MAX
# define UINTPTR_MAX UINT64_MAX
# else // _WIN64 ][
# define INTPTR_MIN INT32_MIN
# define INTPTR_MAX INT32_MAX
# define UINTPTR_MAX UINT32_MAX
# endif // _WIN64 ]
// 7.18.2.5 Limits of greatest-width integer types
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX
# define INTMAX_MIN INT64_MIN
# define INTMAX_MAX INT64_MAX
# define UINTMAX_MAX UINT64_MAX
// 7.18.3 Limits of other integer types
#ifdef _WIN64 // [
# define PTRDIFF_MIN _I64_MIN
# define PTRDIFF_MAX _I64_MAX
#else // _WIN64 ][
# define PTRDIFF_MIN _I32_MIN
# define PTRDIFF_MAX _I32_MAX
#endif // _WIN64 ]
# ifdef _WIN64 // [
# define PTRDIFF_MIN _I64_MIN
# define PTRDIFF_MAX _I64_MAX
# else // _WIN64 ][
# define PTRDIFF_MIN _I32_MIN
# define PTRDIFF_MAX _I32_MAX
# endif // _WIN64 ]
#define SIG_ATOMIC_MIN INT_MIN
#define SIG_ATOMIC_MAX INT_MAX
# define SIG_ATOMIC_MIN INT_MIN
# define SIG_ATOMIC_MAX INT_MAX
#ifndef SIZE_MAX // [
# ifdef _WIN64 // [
# define SIZE_MAX _UI64_MAX
# else // _WIN64 ][
# define SIZE_MAX _UI32_MAX
# endif // _WIN64 ]
#endif // SIZE_MAX ]
# ifndef SIZE_MAX // [
# ifdef _WIN64 // [
# define SIZE_MAX _UI64_MAX
# else // _WIN64 ][
# define SIZE_MAX _UI32_MAX
# endif // _WIN64 ]
# endif // SIZE_MAX ]
// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
#ifndef WCHAR_MIN // [
# define WCHAR_MIN 0
#endif // WCHAR_MIN ]
#ifndef WCHAR_MAX // [
# define WCHAR_MAX _UI16_MAX
#endif // WCHAR_MAX ]
# ifndef WCHAR_MIN // [
# define WCHAR_MIN 0
# endif // WCHAR_MIN ]
# ifndef WCHAR_MAX // [
# define WCHAR_MAX _UI16_MAX
# endif // WCHAR_MAX ]
#define WINT_MIN 0
#define WINT_MAX _UI16_MAX
#endif // __STDC_LIMIT_MACROS ]
# define WINT_MIN 0
# define WINT_MAX _UI16_MAX
# endif // __STDC_LIMIT_MACROS ]
// 7.18.4 Limits of other integer types
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
# if !defined(__cplusplus) || \
defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
// 7.18.4.1 Macros for minimum-width integer constants
#define INT8_C(val) val##i8
#define INT16_C(val) val##i16
#define INT32_C(val) val##i32
#define INT64_C(val) val##i64
# define INT8_C(val) val##i8
# define INT16_C(val) val##i16
# define INT32_C(val) val##i32
# define INT64_C(val) val##i64
#define UINT8_C(val) val##ui8
#define UINT16_C(val) val##ui16
#define UINT32_C(val) val##ui32
#define UINT64_C(val) val##ui64
# define UINT8_C(val) val##ui8
# define UINT16_C(val) val##ui16
# define UINT32_C(val) val##ui32
# define UINT64_C(val) val##ui64
// 7.18.4.2 Macros for greatest-width integer constants
#define INTMAX_C INT64_C
#define UINTMAX_C UINT64_C
# define INTMAX_C INT64_C
# define UINTMAX_C UINT64_C
#endif // __STDC_CONSTANT_MACROS ]
# endif // __STDC_CONSTANT_MACROS ]
#endif // _MSC_STDINT_H_ ]
#endif // _MSC_STDINT_H_ ]

View File

@@ -1,20 +1,20 @@
// Copyright 2019 Blender Foundation. All rights reserved.
//
// 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.
//
// Author: Sebastian Parborg, Pablo Dobarro
/*
* 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.
*
* Copyright 2019 Blender Foundation. All rights reserved.
*/
#include <unordered_map>

View File

@@ -1,20 +1,20 @@
// Copyright 2019 Blender Foundation. All rights reserved.
//
// 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.
//
// Author: Sebastian Parborg, Pablo Dobarro
/*
* 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.
*
* Copyright 2019 Blender Foundation. All rights reserved.
*/
#ifndef QUADRIFLOW_CAPI_HPP
#define QUADRIFLOW_CAPI_HPP

View File

@@ -81,6 +81,16 @@ void RB_dworld_set_solver_iterations(rbDynamicsWorld *world, int num_solver_iter
/* Split Impulse */
void RB_dworld_set_split_impulse(rbDynamicsWorld *world, int split_impulse);
/* Get latest applied impulse */
void RB_dworld_get_impulse(rbDynamicsWorld *world,
rbRigidBody *rbo,
float timeSubStep,
float norm_forces[3][3],
float fric_forces[3][3],
float vec_locations[3][3],
bool norm_flag,
bool fric_flag);
/* Simulation ----------------------- */
/* Step the simulation by the desired amount (in seconds) with extra controls on substep sizes and
@@ -264,6 +274,10 @@ void RB_shape_trimesh_update(rbCollisionShape *shape,
int vert_stride,
float min[3],
float max[3]);
/* Get scale data */
void RB_box_shape_get_half_extents(rbCollisionShape *shape, float *r_half_extents);
void RB_cone_shape_get_half_extents(rbCollisionShape *shape, float *r_half_extents);
void RB_cylinder_shape_get_half_extents(rbCollisionShape *shape, float *r_half_extents);
/* ********************************** */
/* Constraints */
@@ -361,6 +375,20 @@ void RB_constraint_set_target_velocity_motor(rbConstraint *con,
float velocity_lin,
float velocity_ang);
/* Get object transforms */
void RB_constraint_get_transforms_hinge(rbConstraint *con,
float r_ob1_basis[3][3],
float r_ob2_basis[3][3],
float r_ob1_orig[3],
float r_ob2_orig[3]);
void RB_constraint_get_transforms_slider(rbConstraint *con,
float r_ob1_basis[3][3],
float r_ob2_basis[3][3],
float r_ob1_orig[3],
float r_ob2_orig[3],
float r_initial_dist[]);
/* Set number of constraint solver iterations made per step, this overrided world setting
* To use default set it to -1 */
void RB_constraint_set_solver_iterations(rbConstraint *con, int num_solver_iterations);

View File

@@ -204,6 +204,103 @@ void RB_dworld_set_split_impulse(rbDynamicsWorld *world, int split_impulse)
info.m_splitImpulse = split_impulse;
}
/* Get last applied impulse at contact points */
/* TODO: this may not be the most efficient way to do it. get all forces at once and store in a
* lookup table. */
void RB_dworld_get_impulse(rbDynamicsWorld *world,
rbRigidBody *rbo,
float timeSubStep,
float norm_forces[3][3],
float fric_forces[3][3],
float vec_locations[3][3],
bool norm_flag,
bool fric_flag)
{
int numManifolds = world->dispatcher->getNumManifolds();
int num_norm_forces = 0;
int num_fric_forces = 0;
/* Loop through all persisent contact manifolds. The persistant manifold contains all contact points between
* 2 overlapping objects in the world. It can contain between 0 and 4 points. This is the contact point cache
* after reduction of the contact manifold. */
for (int i = 0; i < numManifolds; i++) {
btPersistentManifold *contactManifold = world->dispatcher->getManifoldByIndexInternal(i);
/* The 2 overlapping obejcts. */
const void *obA = contactManifold->getBody0();
const void *obB = contactManifold->getBody1();
/* Break if we cannot store any more forces. upperlimit is 3 */
/* Friction cannot exist without a normal force, so counting number of normal forces stored is enough. */
if (num_norm_forces > 2) {
break;
}
/* Continue to next manifold if this one does not invlove the current rigid body. */
if (obA != rbo->body && obB != rbo->body) {
continue;
}
else {
btVector3 tot_impulse = btVector3(0.0, 0.0, 0.0);
btVector3 final_loc = btVector3(0.0, 0.0, 0.0);
btScalar tot_impulse_magnitude = 0.f;
btVector3 tot_lat_impulse = btVector3(0.0, 0.0, 0.0);
int numContacts = contactManifold->getNumContacts();
int num_impulse_points = 0;
/* Find points where impulse was appplied. */
for (int j = 0; j < numContacts; j++) {
btManifoldPoint &pt = contactManifold->getContactPoint(j);
if (pt.getAppliedImpulse() > 0.f || -pt.getAppliedImpulse() > 0.f) {
num_impulse_points++;
}
}
/* Loop throught contact points and add impulses applied at each point.
* Devide by time to get the equivilant force. */
for (int j = 0; j < numContacts; j++) {
btManifoldPoint &pt = contactManifold->getContactPoint(j);
if (pt.getAppliedImpulse() > 0.f || -pt.getAppliedImpulse() > 0.f) {
const btVector3 &loc = pt.getPositionWorldOnB();
const btVector3 imp = (rbo->body == obB) ?
-pt.m_normalWorldOnB * pt.getAppliedImpulse() / timeSubStep :
pt.m_normalWorldOnB * pt.getAppliedImpulse() / timeSubStep;
tot_impulse_magnitude += pt.getAppliedImpulse() > 0.f? pt.getAppliedImpulse() : -pt.getAppliedImpulse();
tot_impulse += imp;
final_loc += num_impulse_points > 1 ? loc * pt.getAppliedImpulse() : loc;
if (fric_flag) {
const btVector3 lat_imp1 = (rbo->body == obB) ?
-pt.m_appliedImpulseLateral1 *
pt.m_lateralFrictionDir1 / timeSubStep :
pt.m_appliedImpulseLateral1 * pt.m_lateralFrictionDir1 /
timeSubStep;
const btVector3 lat_imp2 = (rbo->body == obB) ?
-pt.m_appliedImpulseLateral2 *
pt.m_lateralFrictionDir2 / timeSubStep :
pt.m_appliedImpulseLateral2 * pt.m_lateralFrictionDir2 /
timeSubStep;
tot_lat_impulse += lat_imp1 + lat_imp2;
}
}
}
/* If impulse was applied at more than one point, the location of the force is taken as average of points
* weighted by the magnitude of impulse applied at each point. */
if(fabsf(tot_impulse_magnitude)==0.0f){
continue;
}
if (num_impulse_points > 1) {
final_loc = final_loc / tot_impulse_magnitude;
}
copy_v3_btvec3(vec_locations[num_norm_forces], final_loc);
if (norm_flag) {
copy_v3_btvec3(norm_forces[num_norm_forces], tot_impulse);
num_norm_forces++;
}
if (fric_flag) {
copy_v3_btvec3(fric_forces[num_fric_forces], tot_lat_impulse);
num_fric_forces++;
}
}
}
}
/* Simulation ----------------------- */
void RB_dworld_step_simulation(rbDynamicsWorld *world,
@@ -930,6 +1027,25 @@ void RB_shape_set_margin(rbCollisionShape *shape, float value)
shape->cshape->setMargin(value);
}
/* Get scale data--------------------------- */
void RB_box_shape_get_half_extents(rbCollisionShape *shape, float *r_half_extents)
{
btBoxShape *box = (btBoxShape*)shape->cshape;
copy_v3_btvec3(r_half_extents, box->getHalfExtentsWithMargin());
}
void RB_cone_shape_get_half_extents(rbCollisionShape *shape, float *r_half_extents)
{
btConeShapeZ *cone = (btConeShapeZ*)shape->cshape;
copy_v3_btvec3(r_half_extents, btVector3(cone->getRadius(), cone->getRadius(), cone->getHeight()*0.5));
}
void RB_cylinder_shape_get_half_extents(rbCollisionShape *shape, float *r_half_extents)
{
btCylinderShapeZ *box = (btCylinderShapeZ*)shape->cshape;
copy_v3_btvec3(r_half_extents, box->getHalfExtentsWithMargin());
}
/* ********************************** */
/* Constraints */
@@ -1302,4 +1418,51 @@ void RB_constraint_set_target_velocity_motor(rbConstraint *con,
constraint->getRotationalLimitMotor(0)->m_targetVelocity = velocity_ang;
}
void RB_constraint_get_transforms_hinge(rbConstraint *con,
float r_ob1_basis[3][3],
float r_ob2_basis[3][3],
float r_ob1_orig[3],
float r_ob2_orig[3]) {
btHingeConstraint *constraint = reinterpret_cast<btHingeConstraint *>(con);
btTransform transform1;
btTransform transform2;
transform1 = constraint->getAFrame();
transform2 = constraint->getBFrame();
for(int i=0; i<3; i++) {
copy_v3_btvec3(r_ob1_basis[i], btVector3(transform1.getBasis()[0][i],transform1.getBasis()[1][i], transform1.getBasis()[2][i]));
copy_v3_btvec3(r_ob2_basis[i], btVector3(transform2.getBasis()[0][i],transform2.getBasis()[1][i], transform2.getBasis()[2][i]));
}
copy_v3_btvec3(r_ob1_orig, btVector3(transform1.getOrigin().x(),transform1.getOrigin().y(), transform1.getOrigin().z()));
copy_v3_btvec3(r_ob2_orig, btVector3(transform2.getOrigin().x() ,transform2.getOrigin().y(), transform2.getOrigin().z()));
}
void RB_constraint_get_transforms_slider(rbConstraint *con,
float r_ob1_basis[3][3],
float r_ob2_basis[3][3],
float r_ob1_orig[3],
float r_ob2_orig[3],
float r_initial_dist[3]) {
btSliderConstraint *constraint = reinterpret_cast<btSliderConstraint *>(con);
btTransform transform1;
btTransform transform2;
transform1 = constraint->getFrameOffsetA();
transform2 = constraint->getFrameOffsetB();
for(int i=0; i<3; i++) {
copy_v3_btvec3(r_ob1_basis[i], btVector3(transform1.getBasis()[0][i],transform1.getBasis()[1][i], transform1.getBasis()[2][i]));
copy_v3_btvec3(r_ob2_basis[i], btVector3(transform2.getBasis()[0][i],transform2.getBasis()[1][i], transform2.getBasis()[2][i]));
}
copy_v3_btvec3(r_ob1_orig, btVector3(transform1.getOrigin().x(),transform1.getOrigin().y(), transform1.getOrigin().z()));
copy_v3_btvec3(r_ob2_orig, btVector3(transform2.getOrigin().x() ,transform2.getOrigin().y(), transform2.getOrigin().z()));
if(r_initial_dist) {
btTransform transform3 = transform1 * transform2.inverse();
copy_v3_btvec3(r_initial_dist, btVector3(transform3.getOrigin().x() ,transform3.getOrigin().y(), transform3.getOrigin().z()));
}
}
/* ********************************** */

View File

@@ -1,32 +1,30 @@
/*
This source is published under the following 3-clause BSD license.
Copyright (c) 2012 - 2013, Lukas Hosek and Alexander Wilkie
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* None of the names of the 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 HOLDERS 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.
*/
* 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.
* * None of the names of the 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 HOLDERS 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.
*
* Copyright (c) 2012 - 2013, Lukas Hosek and Alexander Wilkie
* All rights reserved.
*/
/* ============================================================================

View File

@@ -1,32 +1,30 @@
/*
This source is published under the following 3-clause BSD license.
Copyright (c) 2012 - 2013, Lukas Hosek and Alexander Wilkie
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* None of the names of the 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 HOLDERS 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.
*/
* 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.
* * None of the names of the 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 HOLDERS 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.
*
* Copyright (c) 2012 - 2013, Lukas Hosek and Alexander Wilkie
* All rights reserved.
*/
/* ============================================================================

View File

@@ -1,6 +1,4 @@
/*
* Copyright 2011-2020 Blender Foundation
*
* 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
@@ -12,6 +10,8 @@
* 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.
*
* Copyright 2011-2020 Blender Foundation
*/
/** \file

View File

@@ -356,6 +356,7 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = {
"y",
"y = (Ax + B)",
# Sub-strings.
"and AMD Radeon Pro 21.Q4 driver or newer",
"available with",
"brown fox",
"can't save image while rendering",
@@ -378,6 +379,7 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = {
"image path can't be written to",
"in memory to enable editing!",
"insufficient content",
"into",
"jumps over",
"left",
"local",
@@ -387,6 +389,7 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = {
"performance impact!",
"right",
"the lazy dog",
"to the top level of the tree",
"unable to load movie clip",
"unable to load text",
"unable to open the file",

View File

@@ -76,10 +76,12 @@ class SpellChecker:
"tangency",
"vertices",
"wasn", # wasn't
"zig", "zag",
# Brands etc.
"htc",
"huawei",
"radeon",
"vive",
"xbox",
@@ -136,6 +138,7 @@ class SpellChecker:
"filename", "filenames",
"filepath", "filepaths",
"forcefield", "forcefields",
"framerange",
"fulldome", "fulldomes",
"fullscreen",
"gamepad",
@@ -498,6 +501,7 @@ class SpellChecker:
"framerate",
"gimbal",
"grayscale",
"icosahedron",
"icosphere",
"inpaint",
"kerning",
@@ -556,6 +560,7 @@ class SpellChecker:
"bspline",
"bweight",
"colorband",
"crazyspace",
"datablock", "datablocks",
"despeckle",
"depsgraph",
@@ -730,6 +735,7 @@ class SpellChecker:
"precisa",
"px",
"qmc",
"rdna",
"rdp",
"rgb", "rgba",
"rhs",

View File

@@ -1,5 +1,3 @@
# Copyright (c) 2009 www.stani.be (GPL license)
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
@@ -18,6 +16,8 @@
#
# ##### END GPL LICENSE BLOCK #####
# Copyright (c) 2009 www.stani.be
# <pep8 compliant>
"""Package for console specific modules."""

View File

@@ -1,5 +1,3 @@
# Copyright (c) 2009 www.stani.be (GPL license)
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
@@ -18,6 +16,8 @@
#
# ##### END GPL LICENSE BLOCK #####
# Copyright (c) 2009 www.stani.be
# <pep8-80 compliant>
import inspect

View File

@@ -1,5 +1,3 @@
# Copyright (c) 2009 Fernando Perez, www.stani.be (GPL license)
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
@@ -18,6 +16,8 @@
#
# ##### END GPL LICENSE BLOCK #####
# Copyright (c) 2009 Fernando Perez, www.stani.be
# Original copyright (see docstring):
# ****************************************************************************
# Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>

View File

@@ -1,5 +1,3 @@
# Copyright (c) 2009 www.stani.be (GPL license)
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
@@ -18,6 +16,8 @@
#
# ##### END GPL LICENSE BLOCK #####
# Copyright (c) 2009 www.stani.be
# <pep8-80 compliant>
"""Autocomplete with the standard library"""

View File

@@ -1,5 +1,3 @@
# Copyright (c) 2009 www.stani.be (GPL license)
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
@@ -18,6 +16,8 @@
#
# ##### END GPL LICENSE BLOCK #####
# Copyright (c) 2009 www.stani.be
# <pep8-80 compliant>
"""This module provides intellisense features such as:

View File

@@ -2139,7 +2139,6 @@ url_manual_mapping = (
("bpy.ops.object.origin_set*", "scene_layout/object/origin.html#bpy-ops-object-origin-set"),
("bpy.ops.object.parent_set*", "scene_layout/object/editing/parent.html#bpy-ops-object-parent-set"),
("bpy.ops.object.pointcloud*", "modeling/point_cloud.html#bpy-ops-object-pointcloud"),
("bpy.ops.object.proxy_make*", "files/linked_libraries/library_proxies.html#bpy-ops-object-proxy-make"),
("bpy.ops.object.select_all*", "scene_layout/object/selecting.html#bpy-ops-object-select-all"),
("bpy.ops.object.shade_flat*", "scene_layout/object/editing/shading.html#bpy-ops-object-shade-flat"),
("bpy.ops.pose.group_assign*", "animation/armatures/properties/bone_groups.html#bpy-ops-pose-group-assign"),

View File

@@ -1,5 +1,4 @@
# ##### 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

View File

@@ -33,9 +33,9 @@ _modules = [
"properties_data_bone",
"properties_data_camera",
"properties_data_curve",
"properties_data_curves",
"properties_data_empty",
"properties_data_gpencil",
"properties_data_hair",
"properties_data_light",
"properties_data_lattice",
"properties_data_mesh",

View File

@@ -149,7 +149,6 @@ class DATA_PT_bone_groups(ArmatureButtonsPanel, Panel):
col.operator("pose.group_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
split = layout.split()
split.active = (ob.proxy is None)
col = split.column()
col.prop(group, "color_set")

View File

@@ -30,10 +30,10 @@ class DataButtonsPanel:
@classmethod
def poll(cls, context):
engine = context.scene.render.engine
return hasattr(context, 'hair') and context.hair and (engine in cls.COMPAT_ENGINES)
return hasattr(context, 'curves') and context.curves and (engine in cls.COMPAT_ENGINES)
class DATA_PT_context_hair(DataButtonsPanel, Panel):
class DATA_PT_context_curves(DataButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
@@ -42,21 +42,21 @@ class DATA_PT_context_hair(DataButtonsPanel, Panel):
layout = self.layout
ob = context.object
hair = context.hair
curves = context.curves
space = context.space_data
if ob:
layout.template_ID(ob, "data")
elif hair:
elif curves:
layout.template_ID(space, "pin_id")
class HAIR_MT_add_attribute(Menu):
class CURVES_MT_add_attribute(Menu):
bl_label = "Add Attribute"
@staticmethod
def add_standard_attribute(layout, hair, name, data_type, domain):
exists = hair.attributes.get(name) is not None
def add_standard_attribute(layout, curves, name, data_type, domain):
exists = curves.attributes.get(name) is not None
col = layout.column()
col.enabled = not exists
@@ -69,10 +69,10 @@ class HAIR_MT_add_attribute(Menu):
def draw(self, context):
layout = self.layout
hair = context.hair
curves = context.curves
self.add_standard_attribute(layout, hair, 'Radius', 'FLOAT', 'POINT')
self.add_standard_attribute(layout, hair, 'Color', 'FLOAT_COLOR', 'POINT')
self.add_standard_attribute(layout, curves, 'radius', 'FLOAT', 'POINT')
self.add_standard_attribute(layout, curves, 'color', 'FLOAT_COLOR', 'POINT')
layout.separator()
@@ -80,7 +80,7 @@ class HAIR_MT_add_attribute(Menu):
layout.operator("geometry.attribute_add", text="Custom...")
class HAIR_UL_attributes(UIList):
class CURVES_UL_attributes(UIList):
def draw_item(self, _context, layout, _data, attribute, _icon, _active_data, _active_propname, _index):
data_type = attribute.bl_rna.properties['data_type'].enum_items[attribute.data_type]
domain = attribute.bl_rna.properties['domain'].enum_items[attribute.domain]
@@ -96,44 +96,44 @@ class HAIR_UL_attributes(UIList):
sub.label(text=data_type.name)
class DATA_PT_hair_attributes(DataButtonsPanel, Panel):
class DATA_PT_CURVES_attributes(DataButtonsPanel, Panel):
bl_label = "Attributes"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
def draw(self, context):
hair = context.hair
curves = context.curves
layout = self.layout
row = layout.row()
col = row.column()
col.template_list(
"HAIR_UL_attributes",
"CURVES_UL_attributes",
"attributes",
hair,
curves,
"attributes",
hair.attributes,
curves.attributes,
"active_index",
rows=3,
)
col = row.column(align=True)
col.menu("HAIR_MT_add_attribute", icon='ADD', text="")
col.menu("CURVES_MT_add_attribute", icon='ADD', text="")
col.operator("geometry.attribute_remove", icon='REMOVE', text="")
class DATA_PT_custom_props_hair(DataButtonsPanel, PropertyPanel, Panel):
class DATA_PT_custom_props_curves(DataButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
_context_path = "object.data"
_property_type = bpy.types.Hair if hasattr(bpy.types, "Hair") else None
_property_type = bpy.types.Curves if hasattr(bpy.types, "Curves") else None
classes = (
DATA_PT_context_hair,
DATA_PT_hair_attributes,
DATA_PT_custom_props_hair,
HAIR_MT_add_attribute,
HAIR_UL_attributes,
DATA_PT_context_curves,
DATA_PT_CURVES_attributes,
DATA_PT_custom_props_curves,
CURVES_MT_add_attribute,
CURVES_UL_attributes,
)
if __name__ == "__main__": # only for live edit.

View File

@@ -1,5 +1,4 @@
# ##### 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

View File

@@ -307,6 +307,72 @@ class PHYSICS_PT_rigid_body_dynamics_deactivation(PHYSICS_PT_rigidbody_panel, Pa
# TODO: other params such as time?
class PHYSICS_PT_rigid_body_display_options(PHYSICS_PT_rigidbody_panel, Panel):
bl_label = "Display Options"
bl_parent_id = 'PHYSICS_PT_rigid_body'
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
@classmethod
def poll(cls, context):
obj = context.object
if obj.parent is not None and obj.parent.rigid_body is not None:
return False
return (obj and obj.rigid_body and (context.engine in cls.COMPAT_ENGINES))
def draw(self, context):
layout = self.layout
layout.use_property_split = True
ob = context.object
rbo = ob.rigid_body
if rbo is None:
rigid_body_warning(layout, "Object does not have a Rigid Body")
return
col = layout.column()
if rbo.type == 'ACTIVE' and not rbo.kinematic:
col.prop(rbo, "display_acceleration")
col.prop(rbo, "display_velocity")
col.prop(rbo, "display_collisions")
col.prop(rbo, "display_data_text")
col.prop(rbo, "display_state")
class PHYSICS_PT_rigid_body_display_force_types(PHYSICS_PT_rigidbody_panel, Panel):
bl_label = "Forces"
bl_parent_id = 'PHYSICS_PT_rigid_body_display_options'
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
@classmethod
def poll(cls, context):
obj = context.object
if obj.parent is not None and obj.parent.rigid_body is not None:
return False
return (obj and obj.rigid_body and (context.engine in cls.COMPAT_ENGINES))
def draw_header(self, context):
ob = context.object
rbo = ob.rigid_body
self.layout.prop(rbo, "display_forces", text="")
def draw(self, context):
layout = self.layout
layout.use_property_split = True
ob = context.object
rbo = ob.rigid_body
col = layout.column()
col.active = rbo.display_forces
col.prop(rbo, "show_gravity")
col.prop(rbo, "show_effectors_force")
col.prop(rbo, "show_normal_force")
col.prop(rbo, "show_frictional_force")
col.prop(rbo, "show_net_force")
classes = (
PHYSICS_PT_rigid_body,
PHYSICS_PT_rigid_body_settings,
@@ -316,10 +382,13 @@ classes = (
PHYSICS_PT_rigid_body_collisions_collections,
PHYSICS_PT_rigid_body_dynamics,
PHYSICS_PT_rigid_body_dynamics_deactivation,
PHYSICS_PT_rigid_body_display_options,
PHYSICS_PT_rigid_body_display_force_types,
)
if __name__ == "__main__": # only for live edit.
from bpy.utils import register_class
from bpy.utils import register_class, unregister_class
for cls in classes:
register_class(cls)

View File

@@ -474,6 +474,34 @@ class PHYSICS_PT_rigid_body_constraint_springs_linear(PHYSICS_PT_rigidbody_const
sub.prop(rbc, "spring_stiffness_z", text="Stiffness")
sub.prop(rbc, "spring_damping_z", text="Damping")
class PHYSICS_PT_rigid_body_constraint_debug_draw(PHYSICS_PT_rigidbody_constraint_panel, Panel):
bl_label = "Debug draw"
bl_parent_id = 'PHYSICS_PT_rigid_body_constraint'
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
@classmethod
def poll(cls, context):
ob = context.object
rbc = ob.rigid_body_constraint
return (ob and rbc
and (rbc.type in {'SLIDER', 'HINGE', 'PISTON'})
and context.engine in cls.COMPAT_ENGINES)
def draw(self, context):
layout = self.layout
layout.use_property_split = True
flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
ob = context.object
rbc = ob.rigid_body_constraint
col = flow.column()
col.prop(rbc, "debug_draw_limits", text="Debug draw")
if rbc.type in {'PISTON', 'SLIDER'}:
col = flow.column()
col.prop(rbc, "debug_draw_fade_walls", text="Fade walls")
classes = (
PHYSICS_PT_rigid_body_constraint,
@@ -489,6 +517,7 @@ classes = (
PHYSICS_PT_rigid_body_constraint_springs,
PHYSICS_PT_rigid_body_constraint_springs_angular,
PHYSICS_PT_rigid_body_constraint_springs_linear,
PHYSICS_PT_rigid_body_constraint_debug_draw,
)

View File

@@ -1,5 +1,4 @@
# ##### 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

View File

@@ -127,8 +127,8 @@ class DopesheetFilterPopoverBase:
flow.prop(dopesheet, "show_lattices", text="Lattices")
if bpy.data.metaballs:
flow.prop(dopesheet, "show_metaballs", text="Metaballs")
if hasattr(bpy.data, "hairs") and bpy.data.hairs:
flow.prop(dopesheet, "show_hairs", text="Hairs")
if hasattr(bpy.data, "hair_curves") and bpy.data.hair_curves:
flow.prop(dopesheet, "show_hair_curves", text="Hair Curves")
if hasattr(bpy.data, "pointclouds") and bpy.data.pointclouds:
flow.prop(dopesheet, "show_pointclouds", text="Point Clouds")
if bpy.data.volumes:

View File

@@ -448,7 +448,7 @@ class OUTLINER_PT_filter(Panel):
if (
bpy.data.curves or
bpy.data.metaballs or
(hasattr(bpy.data, "hairs") and bpy.data.hairs) or
(hasattr(bpy.data, "hair_curves") and bpy.data.hair_curves) or
(hasattr(bpy.data, "pointclouds") and bpy.data.pointclouds) or
bpy.data.volumes or
bpy.data.lightprobes or

View File

@@ -2027,6 +2027,9 @@ class SEQUENCER_PT_adjust_transform(SequencerButtonsPanel, Panel):
layout.use_property_split = True
layout.active = not strip.mute
col = layout.column(align=True)
col.prop(strip.transform, "filter", text="Filter")
col = layout.column(align=True)
col.prop(strip.transform, "offset_x", text="Position X")
col.prop(strip.transform, "offset_y", text="Y")

View File

@@ -2295,7 +2295,7 @@ class USERPREF_PT_experimental_prototypes(ExperimentalPanel, Panel):
def draw(self, context):
self._draw_items(
context, (
({"property": "use_new_hair_type"}, "T68981"),
({"property": "use_new_curves_type"}, "T68981"),
({"property": "use_new_point_cloud_type"}, "T75717"),
({"property": "use_full_frame_compositor"}, "T88150"),
),

View File

@@ -2148,8 +2148,8 @@ class VIEW3D_MT_add(Menu):
layout.menu("VIEW3D_MT_surface_add", icon='OUTLINER_OB_SURFACE')
layout.menu("VIEW3D_MT_metaball_add", text="Metaball", icon='OUTLINER_OB_META')
layout.operator("object.text_add", text="Text", icon='OUTLINER_OB_FONT')
if context.preferences.experimental.use_new_hair_type:
layout.operator("object.hair_add", text="Hair", icon='OUTLINER_OB_HAIR')
if context.preferences.experimental.use_new_curves_type:
layout.operator("object.hair_curves_add", text="Hair Curves", icon='OUTLINER_OB_CURVES')
if context.preferences.experimental.use_new_point_cloud_type:
layout.operator("object.pointcloud_add", text="Point Cloud", icon='OUTLINER_OB_POINTCLOUD')
layout.menu("VIEW3D_MT_volume_add", text="Volume", icon='OUTLINER_OB_VOLUME')

View File

@@ -48,7 +48,7 @@ set(SRC_DNA_INC
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpencil_modifier_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpencil_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpu_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_hair_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_curves_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_image_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_ipo_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_key_types.h

View File

@@ -1238,6 +1238,12 @@ FontBLF *blf_font_new(const char *name, const char *filename)
font = (FontBLF *)MEM_callocN(sizeof(FontBLF), "blf_font_new");
err = FT_New_Face(ft_lib, filename, 0, &font->face);
if (err) {
if (ELEM(err, FT_Err_Unknown_File_Format, FT_Err_Unimplemented_Feature)) {
printf("Format of this font file is not supported\n");
}
else {
printf("Error encountered while opening font file\n");
}
MEM_freeN(font);
return NULL;
}

View File

@@ -163,6 +163,30 @@ void BKE_armature_transform(struct bArmature *arm, const float mat[4][4], bool d
/* Bounding box. */
struct BoundBox *BKE_armature_boundbox_get(struct Object *ob);
/**
* Calculate the axis-aligned bounds of `pchan` in world-space,
* taking into account custom transform when set.
*
* `r_min` and `r_max` are expanded to fit `pchan` so the caller must initialize them
* (typically using #INIT_MINMAX).
*
* \note The bounds are calculated based on the head & tail of the bone
* or the custom object's bounds (if the bone uses a custom object).
* Visual elements such as the envelopes radius & bendy-bone spline segments are *not* included,
* making this not so useful for viewport culling.
*/
void BKE_pchan_minmax(const struct Object *ob,
const struct bPoseChannel *pchan,
float r_min[3],
float r_max[3]);
/**
* Calculate the axis aligned bounds of the pose of `ob` in world-space.
* `r_min` and `r_max` are expanded to fit `ob->pose` so the caller must initialize them
* (typically using #INIT_MINMAX).
*
* \note This uses #BKE_pchan_minmax, see its documentation for details on bounds calculation.
*/
bool BKE_pose_minmax(
struct Object *ob, float r_min[3], float r_max[3], bool use_hidden, bool use_select);

View File

@@ -40,11 +40,11 @@ struct ReportList;
/* Attribute.domain */
typedef enum AttributeDomain {
ATTR_DOMAIN_AUTO = -1, /* Use for nodes to choose automatically based on other data. */
ATTR_DOMAIN_POINT = 0, /* Mesh, Hair or PointCloud Point */
ATTR_DOMAIN_POINT = 0, /* Mesh, Curve or Point Cloud Point */
ATTR_DOMAIN_EDGE = 1, /* Mesh Edge */
ATTR_DOMAIN_FACE = 2, /* Mesh Face */
ATTR_DOMAIN_CORNER = 3, /* Mesh Corner */
ATTR_DOMAIN_CURVE = 4, /* Hair Curve */
ATTR_DOMAIN_CURVE = 4, /* A single curve in a larger curve data-block */
ATTR_DOMAIN_INSTANCE = 5, /* Instance */
ATTR_DOMAIN_NUM

View File

@@ -39,7 +39,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 1
#define BLENDER_FILE_SUBVERSION 3
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file

View File

@@ -0,0 +1,68 @@
/*
* 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.
*/
#pragma once
/** \file
* \ingroup bke
* \brief Low-level operations for curves.
*/
#ifdef __cplusplus
extern "C" {
#endif
struct BoundBox;
struct CustomDataLayer;
struct Depsgraph;
struct Curves;
struct Main;
struct Object;
struct Scene;
void *BKE_curves_add(struct Main *bmain, const char *name);
struct BoundBox *BKE_curves_boundbox_get(struct Object *ob);
void BKE_curves_update_customdata_pointers(struct Curves *curves);
bool BKE_curves_customdata_required(struct Curves *curves, struct CustomDataLayer *layer);
/* Depsgraph */
struct Curves *BKE_curves_new_for_eval(const struct Curves *curves_src,
int totpoint,
int totcurve);
struct Curves *BKE_curves_copy_for_eval(struct Curves *curves_src, bool reference);
void BKE_curves_data_update(struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *object);
/* Draw Cache */
enum {
BKE_CURVES_BATCH_DIRTY_ALL = 0,
};
void BKE_curves_batch_cache_dirty_tag(struct Curves *curves, int mode);
void BKE_curves_batch_cache_free(struct Curves *curves);
extern void (*BKE_curves_batch_cache_dirty_tag_cb)(struct Curves *curves, int mode);
extern void (*BKE_curves_batch_cache_free_cb)(struct Curves *curves);
#ifdef __cplusplus
}
#endif

View File

@@ -140,7 +140,8 @@ void BKE_effectors_apply(struct ListBase *effectors,
struct EffectedPoint *point,
float *force,
float *wind_force,
float *impulse);
float *impulse,
float r_eff_forces[3][3]);
void BKE_effectors_free(struct ListBase *lb);
void pd_point_from_particle(struct ParticleSimulationData *sim,

View File

@@ -1,63 +0,0 @@
/*
* 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.
*/
#pragma once
/** \file
* \ingroup bke
* \brief General operations for hairs.
*/
#ifdef __cplusplus
extern "C" {
#endif
struct BoundBox;
struct CustomDataLayer;
struct Depsgraph;
struct Hair;
struct Main;
struct Object;
struct Scene;
void *BKE_hair_add(struct Main *bmain, const char *name);
struct BoundBox *BKE_hair_boundbox_get(struct Object *ob);
void BKE_hair_update_customdata_pointers(struct Hair *hair);
bool BKE_hair_customdata_required(struct Hair *hair, struct CustomDataLayer *layer);
/* Depsgraph */
struct Hair *BKE_hair_new_for_eval(const struct Hair *hair_src, int totpoint, int totcurve);
struct Hair *BKE_hair_copy_for_eval(struct Hair *hair_src, bool reference);
void BKE_hair_data_update(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *object);
/* Draw Cache */
enum {
BKE_HAIR_BATCH_DIRTY_ALL = 0,
};
void BKE_hair_batch_cache_dirty_tag(struct Hair *hair, int mode);
void BKE_hair_batch_cache_free(struct Hair *hair);
extern void (*BKE_hair_batch_cache_dirty_tag_cb)(struct Hair *hair, int mode);
extern void (*BKE_hair_batch_cache_free_cb)(struct Hair *hair);
#ifdef __cplusplus
}
#endif

View File

@@ -278,7 +278,7 @@ extern IDTypeInfo IDType_ID_PC;
extern IDTypeInfo IDType_ID_CF;
extern IDTypeInfo IDType_ID_WS;
extern IDTypeInfo IDType_ID_LP;
extern IDTypeInfo IDType_ID_HA;
extern IDTypeInfo IDType_ID_CV;
extern IDTypeInfo IDType_ID_PT;
extern IDTypeInfo IDType_ID_VO;
extern IDTypeInfo IDType_ID_SIM;

View File

@@ -113,7 +113,7 @@ struct ID *BKE_lib_override_library_create_from_id(struct Main *bmain,
*/
bool BKE_lib_override_library_create_from_tag(struct Main *bmain,
struct Library *owner_library,
const struct Library *reference_library,
const struct ID *id_root_reference,
bool do_no_main);
/**
* Advanced 'smart' function to create fully functional overrides.
@@ -172,6 +172,15 @@ bool BKE_lib_override_library_proxy_convert(struct Main *bmain,
*/
void BKE_lib_override_library_main_proxy_convert(struct Main *bmain,
struct BlendFileReadReport *reports);
/**
* Find and set the 'hierarchy root' ID pointer of all library overrides in given `bmain`.
*
* NOTE: Cannot be called from `do_versions_after_linking` as this code needs a single complete
* Main database, not a split-by-libraries one.
*/
void BKE_lib_override_library_main_hierarchy_root_ensure(struct Main *bmain);
/**
* Advanced 'smart' function to resync, re-create fully functional overrides up-to-date with linked
* data, from an existing override hierarchy.

View File

@@ -182,7 +182,11 @@ typedef struct Main {
ListBase linestyles;
ListBase cachefiles;
ListBase workspaces;
ListBase hairs;
/**
* \note The name `hair_curves` is chosen to be different than `curves`,
* but they are generic curve data-blocks, not just for hair.
*/
ListBase hair_curves;
ListBase pointclouds;
ListBase volumes;
ListBase simulations;

View File

@@ -274,6 +274,9 @@ typedef struct bNodeType {
char *label,
int maxlen);
/** Optional override for node class, used for drawing node header. */
int (*ui_class)(const struct bNode *node);
/** Called when the node is updated in the editor. */
void (*updatefunc)(struct bNodeTree *ntree, struct bNode *node);
/** Check and update if internal ID data has changed. */

View File

@@ -13,11 +13,8 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2007 by Janne Karhu.
* All rights reserved.
* Adaptive time step
* Classical SPH
* Copyright 2011-2012 AutoCRC
* Copyright 2007 Janne Karhu. All rights reserved.
* 2011-2012 AutoCRC (adaptive time step, Classical SPH).
*/
#pragma once

View File

@@ -25,6 +25,7 @@
#include "DNA_boid_types.h" /* for #BoidData */
#include "DNA_pointcache_types.h" /* for #BPHYS_TOT_DATA */
#include "DNA_rigidbody_types.h"
#include <stdio.h> /* for #FILE */
@@ -103,6 +104,12 @@ typedef struct PTCacheData {
float size;
float times[3];
struct BoidData boids;
struct sim_data_vec eff_forces[3];
struct sim_data_vec norm_forces[3];
struct sim_data_vec fric_forces[3];
struct sim_data_vec vec_locations[3];
float pvel[3];
int colliding_faces[3];
} PTCacheData;
typedef struct PTCacheFile {

View File

@@ -244,6 +244,12 @@ void BKE_rigidbody_object_sync_transforms(struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *ob);
/* -------------------- */
/* Debug draw collision shapes */
/* -------------------- */
void BKE_rigidbody_store_convex_hull_draw_data(struct Object *ob);
void BKE_rigidbody_store_trimesh_draw_data(struct Object *ob);
/** \} */
#ifdef __cplusplus

View File

@@ -119,6 +119,7 @@ set(SRC
intern/crazyspace.c
intern/cryptomatte.cc
intern/curve.cc
intern/curves.cc
intern/curve_bevel.c
intern/curve_convert.c
intern/curve_decimate.c
@@ -156,7 +157,6 @@ set(SRC
intern/gpencil_curve.c
intern/gpencil_geom.cc
intern/gpencil_modifier.c
intern/hair.cc
intern/icons.cc
intern/icons_rasterize.c
intern/idprop.c
@@ -356,6 +356,7 @@ set(SRC
BKE_cryptomatte.h
BKE_cryptomatte.hh
BKE_curve.h
BKE_curves.h
BKE_curve_to_mesh.hh
BKE_curveprofile.h
BKE_customdata.h
@@ -384,7 +385,6 @@ set(SRC
BKE_gpencil_curve.h
BKE_gpencil_geom.h
BKE_gpencil_modifier.h
BKE_hair.h
BKE_icons.h
BKE_idprop.h
BKE_idprop.hh

View File

@@ -1284,8 +1284,8 @@ void BKE_animdata_main_cb(Main *bmain, ID_AnimData_Edit_Callback func, void *use
/* cache files */
ANIMDATA_IDS_CB(bmain->cachefiles.first);
/* hairs */
ANIMDATA_IDS_CB(bmain->hairs.first);
/* Hair Curves. */
ANIMDATA_IDS_CB(bmain->hair_curves.first);
/* pointclouds */
ANIMDATA_IDS_CB(bmain->pointclouds.first);
@@ -1413,8 +1413,8 @@ void BKE_animdata_fix_paths_rename_all_ex(Main *bmain,
/* cache files */
RENAMEFIX_ANIM_IDS(bmain->cachefiles.first);
/* hairs */
RENAMEFIX_ANIM_IDS(bmain->hairs.first);
/* Hair Curves. */
RENAMEFIX_ANIM_IDS(bmain->hair_curves.first);
/* pointclouds */
RENAMEFIX_ANIM_IDS(bmain->pointclouds.first);

View File

@@ -3382,8 +3382,8 @@ void BKE_animsys_evaluate_all_animation(Main *main, Depsgraph *depsgraph, float
/* cache files */
EVAL_ANIM_IDS(main->cachefiles.first, ADT_RECALC_ANIM);
/* hairs */
EVAL_ANIM_IDS(main->hairs.first, ADT_RECALC_ANIM);
/* Hair Curves. */
EVAL_ANIM_IDS(main->hair_curves.first, ADT_RECALC_ANIM);
/* pointclouds */
EVAL_ANIM_IDS(main->pointclouds.first, ADT_RECALC_ANIM);

View File

@@ -2679,6 +2679,35 @@ BoundBox *BKE_armature_boundbox_get(Object *ob)
return ob->runtime.bb;
}
void BKE_pchan_minmax(const Object *ob, const bPoseChannel *pchan, float r_min[3], float r_max[3])
{
const bArmature *arm = ob->data;
const bPoseChannel *pchan_tx = (pchan->custom && pchan->custom_tx) ? pchan->custom_tx : pchan;
const BoundBox *bb_custom = ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) ?
BKE_object_boundbox_get(pchan->custom) :
NULL;
if (bb_custom) {
float mat[4][4], smat[4][4], rmat[4][4], tmp[4][4];
scale_m4_fl(smat, PCHAN_CUSTOM_BONE_LENGTH(pchan));
rescale_m4(smat, pchan->custom_scale_xyz);
eulO_to_mat4(rmat, pchan->custom_rotation_euler, ROT_MODE_XYZ);
copy_m4_m4(tmp, pchan_tx->pose_mat);
translate_m4(tmp,
pchan->custom_translation[0],
pchan->custom_translation[1],
pchan->custom_translation[2]);
mul_m4_series(mat, ob->obmat, tmp, rmat, smat);
BKE_boundbox_minmax(bb_custom, mat, r_min, r_max);
}
else {
float vec[3];
mul_v3_m4v3(vec, ob->obmat, pchan_tx->pose_head);
minmax_v3v3_v3(r_min, r_max, vec);
mul_v3_m4v3(vec, ob->obmat, pchan_tx->pose_tail);
minmax_v3v3_v3(r_min, r_max, vec);
}
}
bool BKE_pose_minmax(Object *ob, float r_min[3], float r_max[3], bool use_hidden, bool use_select)
{
bool changed = false;
@@ -2692,31 +2721,8 @@ bool BKE_pose_minmax(Object *ob, float r_min[3], float r_max[3], bool use_hidden
* (editarmature.c:2592)... Skip in this case too! */
if (pchan->bone && (!((use_hidden == false) && (PBONE_VISIBLE(arm, pchan->bone) == false)) &&
!((use_select == true) && ((pchan->bone->flag & BONE_SELECTED) == 0)))) {
bPoseChannel *pchan_tx = (pchan->custom && pchan->custom_tx) ? pchan->custom_tx : pchan;
BoundBox *bb_custom = ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) ?
BKE_object_boundbox_get(pchan->custom) :
NULL;
if (bb_custom) {
float mat[4][4], smat[4][4], rmat[4][4], tmp[4][4];
scale_m4_fl(smat, PCHAN_CUSTOM_BONE_LENGTH(pchan));
rescale_m4(smat, pchan->custom_scale_xyz);
eulO_to_mat4(rmat, pchan->custom_rotation_euler, ROT_MODE_XYZ);
copy_m4_m4(tmp, pchan_tx->pose_mat);
translate_m4(tmp,
pchan->custom_translation[0],
pchan->custom_translation[1],
pchan->custom_translation[2]);
mul_m4_series(mat, ob->obmat, tmp, rmat, smat);
BKE_boundbox_minmax(bb_custom, mat, r_min, r_max);
}
else {
float vec[3];
mul_v3_m4v3(vec, ob->obmat, pchan_tx->pose_head);
minmax_v3v3_v3(r_min, r_max, vec);
mul_v3_m4v3(vec, ob->obmat, pchan_tx->pose_tail);
minmax_v3v3_v3(r_min, r_max, vec);
}
BKE_pchan_minmax(ob, pchan, r_min, r_max);
changed = true;
}
}

View File

@@ -15,8 +15,6 @@
*
* The Original Code is Copyright (C) 2015 Blender Foundation.
* All rights reserved.
*
* Defines and code for core node types
*/
/** \file

View File

@@ -15,8 +15,6 @@
*
* The Original Code is Copyright (C) 2015 Blender Foundation.
* All rights reserved.
*
* Defines and code for core node types
*/
/** \file

View File

@@ -15,13 +15,12 @@
*
* The Original Code is Copyright (C) 2006 Blender Foundation.
* All rights reserved.
*
* Implementation of generic geometry attributes management. This is built
* on top of CustomData, which manages individual domains.
*/
/** \file
* \ingroup bke
* Implementation of generic geometry attributes management. This is built
* on top of CustomData, which manages individual domains.
*/
#include <string.h>
@@ -29,8 +28,8 @@
#include "MEM_guardedalloc.h"
#include "DNA_ID.h"
#include "DNA_curves_types.h"
#include "DNA_customdata_types.h"
#include "DNA_hair_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_pointcloud_types.h"
@@ -38,9 +37,9 @@
#include "BLI_string_utf8.h"
#include "BKE_attribute.h"
#include "BKE_curves.h"
#include "BKE_customdata.h"
#include "BKE_editmesh.h"
#include "BKE_hair.h"
#include "BKE_pointcloud.h"
#include "BKE_report.h"
@@ -88,12 +87,12 @@ static void get_domains(const ID *id, DomainInfo info[ATTR_DOMAIN_NUM])
}
break;
}
case ID_HA: {
Hair *hair = (Hair *)id;
info[ATTR_DOMAIN_POINT].customdata = &hair->geometry.point_data;
info[ATTR_DOMAIN_POINT].length = hair->geometry.point_size;
info[ATTR_DOMAIN_CURVE].customdata = &hair->geometry.curve_data;
info[ATTR_DOMAIN_CURVE].length = hair->geometry.curve_size;
case ID_CV: {
Curves *curves = (Curves *)id;
info[ATTR_DOMAIN_POINT].customdata = &curves->geometry.point_data;
info[ATTR_DOMAIN_POINT].length = curves->geometry.point_size;
info[ATTR_DOMAIN_CURVE].customdata = &curves->geometry.curve_data;
info[ATTR_DOMAIN_CURVE].length = curves->geometry.curve_size;
break;
}
default:
@@ -301,8 +300,8 @@ bool BKE_id_attribute_required(ID *id, CustomDataLayer *layer)
case ID_PT: {
return BKE_pointcloud_customdata_required((PointCloud *)id, layer);
}
case ID_HA: {
return BKE_hair_customdata_required((Hair *)id, layer);
case ID_CV: {
return BKE_curves_customdata_required((Curves *)id, layer);
}
default:
return false;
@@ -372,8 +371,8 @@ int *BKE_id_attributes_active_index_p(ID *id)
case ID_ME: {
return &((Mesh *)id)->attributes_active_index;
}
case ID_HA: {
return &((Hair *)id)->attributes_active_index;
case ID_CV: {
return &((Curves *)id)->attributes_active_index;
}
default:
return NULL;

View File

@@ -374,6 +374,10 @@ static void setup_app_data(bContext *C,
BKE_lib_override_library_main_proxy_convert(bmain, reports);
}
if (mode != LOAD_UNDO && !blendfile_or_libraries_versions_atleast(bmain, 302, 3)) {
BKE_lib_override_library_main_hierarchy_root_ensure(bmain);
}
bmain->recovered = 0;
/* startup.blend or recovered startup */

View File

@@ -1374,6 +1374,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
&epoint,
force,
NULL,
NULL,
NULL);
if (ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)) {

View File

@@ -15,13 +15,12 @@
*
* The Original Code is Copyright (C) 2006 Blender Foundation.
* All rights reserved.
* Implementation of CDDerivedMesh.
*
* BKE_cdderivedmesh.h contains the function prototypes for this file.
*/
/** \file
* \ingroup bke
* Implementation of #CDDerivedMesh.
* BKE_cdderivedmesh.h contains the function prototypes for this file.
*/
#include "atomic_ops.h"

View File

@@ -32,6 +32,7 @@
#include "BLI_ghash.h"
#include "BLI_index_range.hh"
#include "BLI_math.h"
#include "BLI_math_vec_types.hh"
#include "BLI_utildefines.h"
#include "BLT_translation.h"
@@ -59,6 +60,7 @@
#include "BKE_lib_query.h"
#include "BKE_main.h"
#include "BKE_object.h"
#include "BKE_spline.hh"
#include "BKE_vfont.h"
#include "DEG_depsgraph.h"
@@ -68,6 +70,7 @@
#include "BLO_read_write.h"
using blender::float3;
using blender::IndexRange;
/* globals */
@@ -503,7 +506,10 @@ BoundBox *BKE_curve_boundbox_get(Object *ob)
float min[3], max[3];
INIT_MINMAX(min, max);
BKE_curve_minmax(cu, true, min, max);
if (!BKE_curve_minmax(cu, true, min, max)) {
copy_v3_fl(min, -1.0f);
copy_v3_fl(max, 1.0f);
}
if (ob->runtime.bb == nullptr) {
ob->runtime.bb = (BoundBox *)MEM_mallocN(sizeof(*ob->runtime.bb), __func__);
@@ -5066,6 +5072,16 @@ void BKE_curve_nurb_vert_active_validate(Curve *cu)
bool BKE_curve_minmax(Curve *cu, bool use_radius, float min[3], float max[3])
{
if (cu->curve_eval != nullptr) {
float3 eval_min(FLT_MAX);
float3 eval_max(-FLT_MAX);
if (cu->curve_eval->bounds_min_max(eval_min, eval_max, false)) {
copy_v3_v3(min, eval_min);
copy_v3_v3(max, eval_max);
return true;
}
}
ListBase *nurb_lb = BKE_curve_nurbs_get(cu);
ListBase temp_nurb_lb = {nullptr, nullptr};
const bool is_font = (BLI_listbase_is_empty(nurb_lb)) && (cu->len != 0);

View File

@@ -0,0 +1,473 @@
/*
* 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.
*/
/** \file
* \ingroup bke
*/
#include <cmath>
#include <cstring>
#include "MEM_guardedalloc.h"
#include "DNA_curves_types.h"
#include "DNA_defaults.h"
#include "DNA_material_types.h"
#include "DNA_object_types.h"
#include "BLI_index_range.hh"
#include "BLI_listbase.h"
#include "BLI_math_base.h"
#include "BLI_math_vec_types.hh"
#include "BLI_rand.hh"
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BKE_anim_data.h"
#include "BKE_curves.h"
#include "BKE_customdata.h"
#include "BKE_global.h"
#include "BKE_idtype.h"
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
#include "BKE_lib_remap.h"
#include "BKE_main.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BLT_translation.h"
#include "DEG_depsgraph_query.h"
#include "BLO_read_write.h"
using blender::float3;
using blender::IndexRange;
using blender::MutableSpan;
using blender::RandomNumberGenerator;
static const char *ATTR_POSITION = "position";
static const char *ATTR_RADIUS = "radius";
static void curves_random(Curves *curves);
static void curves_init_data(ID *id)
{
Curves *curves = (Curves *)id;
BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(curves, id));
MEMCPY_STRUCT_AFTER(curves, DNA_struct_default_get(Curves), id);
CustomData_reset(&curves->geometry.point_data);
CustomData_reset(&curves->geometry.curve_data);
CustomData_add_layer_named(&curves->geometry.point_data,
CD_PROP_FLOAT3,
CD_CALLOC,
nullptr,
curves->geometry.point_size,
ATTR_POSITION);
CustomData_add_layer_named(&curves->geometry.point_data,
CD_PROP_FLOAT,
CD_CALLOC,
nullptr,
curves->geometry.point_size,
ATTR_RADIUS);
BKE_curves_update_customdata_pointers(curves);
curves_random(curves);
}
static void curves_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int flag)
{
Curves *curves_dst = (Curves *)id_dst;
const Curves *curves_src = (const Curves *)id_src;
curves_dst->mat = static_cast<Material **>(MEM_dupallocN(curves_src->mat));
curves_dst->geometry.point_size = curves_src->geometry.point_size;
curves_dst->geometry.curve_size = curves_src->geometry.curve_size;
const eCDAllocType alloc_type = (flag & LIB_ID_COPY_CD_REFERENCE) ? CD_REFERENCE : CD_DUPLICATE;
CustomData_copy(&curves_src->geometry.point_data,
&curves_dst->geometry.point_data,
CD_MASK_ALL,
alloc_type,
curves_dst->geometry.point_size);
CustomData_copy(&curves_src->geometry.curve_data,
&curves_dst->geometry.curve_data,
CD_MASK_ALL,
alloc_type,
curves_dst->geometry.curve_size);
BKE_curves_update_customdata_pointers(curves_dst);
curves_dst->geometry.offsets = static_cast<int *>(MEM_dupallocN(curves_src->geometry.offsets));
curves_dst->batch_cache = nullptr;
}
static void curves_free_data(ID *id)
{
Curves *curves = (Curves *)id;
BKE_animdata_free(&curves->id, false);
BKE_curves_batch_cache_free(curves);
CustomData_free(&curves->geometry.point_data, curves->geometry.point_size);
CustomData_free(&curves->geometry.curve_data, curves->geometry.curve_size);
MEM_SAFE_FREE(curves->geometry.offsets);
MEM_SAFE_FREE(curves->mat);
}
static void curves_foreach_id(ID *id, LibraryForeachIDData *data)
{
Curves *curves = (Curves *)id;
for (int i = 0; i < curves->totcol; i++) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, curves->mat[i], IDWALK_CB_USER);
}
}
static void curves_blend_write(BlendWriter *writer, ID *id, const void *id_address)
{
Curves *curves = (Curves *)id;
CustomDataLayer *players = nullptr, players_buff[CD_TEMP_CHUNK_SIZE];
CustomDataLayer *clayers = nullptr, clayers_buff[CD_TEMP_CHUNK_SIZE];
CustomData_blend_write_prepare(
&curves->geometry.point_data, &players, players_buff, ARRAY_SIZE(players_buff));
CustomData_blend_write_prepare(
&curves->geometry.curve_data, &clayers, clayers_buff, ARRAY_SIZE(clayers_buff));
/* Write LibData */
BLO_write_id_struct(writer, Curves, id_address, &curves->id);
BKE_id_blend_write(writer, &curves->id);
/* Direct data */
CustomData_blend_write(writer,
&curves->geometry.point_data,
players,
curves->geometry.point_size,
CD_MASK_ALL,
&curves->id);
CustomData_blend_write(writer,
&curves->geometry.curve_data,
clayers,
curves->geometry.curve_size,
CD_MASK_ALL,
&curves->id);
BLO_write_int32_array(writer, curves->geometry.curve_size + 1, curves->geometry.offsets);
BLO_write_pointer_array(writer, curves->totcol, curves->mat);
if (curves->adt) {
BKE_animdata_blend_write(writer, curves->adt);
}
/* Remove temporary data. */
if (players && players != players_buff) {
MEM_freeN(players);
}
if (clayers && clayers != clayers_buff) {
MEM_freeN(clayers);
}
}
static void curves_blend_read_data(BlendDataReader *reader, ID *id)
{
Curves *curves = (Curves *)id;
BLO_read_data_address(reader, &curves->adt);
BKE_animdata_blend_read_data(reader, curves->adt);
/* Geometry */
CustomData_blend_read(reader, &curves->geometry.point_data, curves->geometry.point_size);
CustomData_blend_read(reader, &curves->geometry.curve_data, curves->geometry.point_size);
BKE_curves_update_customdata_pointers(curves);
BLO_read_int32_array(reader, curves->geometry.curve_size + 1, &curves->geometry.offsets);
/* Materials */
BLO_read_pointer_array(reader, (void **)&curves->mat);
}
static void curves_blend_read_lib(BlendLibReader *reader, ID *id)
{
Curves *curves = (Curves *)id;
for (int a = 0; a < curves->totcol; a++) {
BLO_read_id_address(reader, curves->id.lib, &curves->mat[a]);
}
}
static void curves_blend_read_expand(BlendExpander *expander, ID *id)
{
Curves *curves = (Curves *)id;
for (int a = 0; a < curves->totcol; a++) {
BLO_expand(expander, curves->mat[a]);
}
}
IDTypeInfo IDType_ID_CV = {
/*id_code */ ID_CV,
/*id_filter */ FILTER_ID_CV,
/*main_listbase_index */ INDEX_ID_CV,
/*struct_size */ sizeof(Curves),
/*name */ "Hair Curves",
/*name_plural */ "Hair Curves",
/*translation_context */ BLT_I18NCONTEXT_ID_CURVES,
/*flags */ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info */ nullptr,
/*init_data */ curves_init_data,
/*copy_data */ curves_copy_data,
/*free_data */ curves_free_data,
/*make_local */ nullptr,
/*foreach_id */ curves_foreach_id,
/*foreach_cache */ nullptr,
/*foreach_path */ nullptr,
/*owner_get */ nullptr,
/*blend_write */ curves_blend_write,
/*blend_read_data */ curves_blend_read_data,
/*blend_read_lib */ curves_blend_read_lib,
/*blend_read_expand */ curves_blend_read_expand,
/*blend_read_undo_preserve */ nullptr,
/*lib_override_apply_post */ nullptr,
};
static void curves_random(Curves *curves)
{
CurvesGeometry &geometry = curves->geometry;
const int numpoints = 8;
geometry.curve_size = 500;
geometry.curve_size = 500;
geometry.point_size = geometry.curve_size * numpoints;
curves->geometry.offsets = (int *)MEM_calloc_arrayN(
curves->geometry.curve_size + 1, sizeof(int), __func__);
CustomData_realloc(&geometry.point_data, geometry.point_size);
CustomData_realloc(&geometry.curve_data, geometry.curve_size);
BKE_curves_update_customdata_pointers(curves);
MutableSpan<int> offsets{geometry.offsets, geometry.curve_size + 1};
MutableSpan<float3> positions{(float3 *)geometry.position, geometry.point_size};
MutableSpan<float> radii{geometry.radius, geometry.point_size};
for (const int i : offsets.index_range()) {
geometry.offsets[i] = numpoints * i;
}
RandomNumberGenerator rng;
for (int i = 0; i < geometry.curve_size; i++) {
const IndexRange curve_range(offsets[i], offsets[i + 1] - offsets[i]);
MutableSpan<float3> curve_positions = positions.slice(curve_range);
MutableSpan<float> curve_radii = radii.slice(curve_range);
const float theta = 2.0f * M_PI * rng.get_float();
const float phi = saacosf(2.0f * rng.get_float() - 1.0f);
float3 no = {std::sin(theta) * std::sin(phi), std::cos(theta) * std::sin(phi), std::cos(phi)};
no = blender::math::normalize(no);
float3 co = no;
for (int key = 0; key < numpoints; key++) {
float t = key / (float)(numpoints - 1);
curve_positions[key] = co;
curve_radii[key] = 0.02f * (1.0f - t);
float3 offset = float3(rng.get_float(), rng.get_float(), rng.get_float()) * 2.0f - 1.0f;
co += (offset + no) / numpoints;
}
}
}
void *BKE_curves_add(Main *bmain, const char *name)
{
Curves *curves = static_cast<Curves *>(BKE_id_new(bmain, ID_CV, name));
return curves;
}
BoundBox *BKE_curves_boundbox_get(Object *ob)
{
BLI_assert(ob->type == OB_CURVES);
Curves *curves = static_cast<Curves *>(ob->data);
if (ob->runtime.bb != nullptr && (ob->runtime.bb->flag & BOUNDBOX_DIRTY) == 0) {
return ob->runtime.bb;
}
if (ob->runtime.bb == nullptr) {
ob->runtime.bb = MEM_cnew<BoundBox>(__func__);
float min[3], max[3];
INIT_MINMAX(min, max);
float(*curves_co)[3] = curves->geometry.position;
float *curves_radius = curves->geometry.radius;
for (int a = 0; a < curves->geometry.point_size; a++) {
float *co = curves_co[a];
float radius = (curves_radius) ? curves_radius[a] : 0.0f;
const float co_min[3] = {co[0] - radius, co[1] - radius, co[2] - radius};
const float co_max[3] = {co[0] + radius, co[1] + radius, co[2] + radius};
DO_MIN(co_min, min);
DO_MAX(co_max, max);
}
BKE_boundbox_init_from_minmax(ob->runtime.bb, min, max);
}
return ob->runtime.bb;
}
void BKE_curves_update_customdata_pointers(Curves *curves)
{
curves->geometry.position = (float(*)[3])CustomData_get_layer_named(
&curves->geometry.point_data, CD_PROP_FLOAT3, ATTR_POSITION);
curves->geometry.radius = (float *)CustomData_get_layer_named(
&curves->geometry.point_data, CD_PROP_FLOAT, ATTR_RADIUS);
}
bool BKE_curves_customdata_required(Curves *UNUSED(curves), CustomDataLayer *layer)
{
return layer->type == CD_PROP_FLOAT3 && STREQ(layer->name, ATTR_POSITION);
}
/* Dependency Graph */
Curves *BKE_curves_new_for_eval(const Curves *curves_src, int totpoint, int totcurve)
{
Curves *curves_dst = static_cast<Curves *>(BKE_id_new_nomain(ID_CV, nullptr));
STRNCPY(curves_dst->id.name, curves_src->id.name);
curves_dst->mat = static_cast<Material **>(MEM_dupallocN(curves_src->mat));
curves_dst->totcol = curves_src->totcol;
curves_dst->geometry.point_size = totpoint;
curves_dst->geometry.curve_size = totcurve;
CustomData_copy(&curves_src->geometry.point_data,
&curves_dst->geometry.point_data,
CD_MASK_ALL,
CD_CALLOC,
totpoint);
CustomData_copy(&curves_src->geometry.curve_data,
&curves_dst->geometry.curve_data,
CD_MASK_ALL,
CD_CALLOC,
totcurve);
BKE_curves_update_customdata_pointers(curves_dst);
return curves_dst;
}
Curves *BKE_curves_copy_for_eval(Curves *curves_src, bool reference)
{
int flags = LIB_ID_COPY_LOCALIZE;
if (reference) {
flags |= LIB_ID_COPY_CD_REFERENCE;
}
Curves *result = (Curves *)BKE_id_copy_ex(nullptr, &curves_src->id, nullptr, flags);
return result;
}
static Curves *curves_evaluate_modifiers(struct Depsgraph *depsgraph,
struct Scene *scene,
Object *object,
Curves *curves_input)
{
Curves *curves = curves_input;
/* Modifier evaluation modes. */
const bool use_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
const int required_mode = use_render ? eModifierMode_Render : eModifierMode_Realtime;
ModifierApplyFlag apply_flag = use_render ? MOD_APPLY_RENDER : MOD_APPLY_USECACHE;
const ModifierEvalContext mectx = {depsgraph, object, apply_flag};
/* Get effective list of modifiers to execute. Some effects like shape keys
* are added as virtual modifiers before the user created modifiers. */
VirtualModifierData virtualModifierData;
ModifierData *md = BKE_modifiers_get_virtual_modifierlist(object, &virtualModifierData);
/* Evaluate modifiers. */
for (; md; md = md->next) {
const ModifierTypeInfo *mti = BKE_modifier_get_info(static_cast<ModifierType>(md->type));
if (!BKE_modifier_is_enabled(scene, md, required_mode)) {
continue;
}
if ((mti->type == eModifierTypeType_OnlyDeform) &&
(mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly)) {
/* Ensure we are not modifying the input. */
if (curves == curves_input) {
curves = BKE_curves_copy_for_eval(curves, true);
}
/* Ensure we are not overwriting referenced data. */
CustomData_duplicate_referenced_layer_named(&curves->geometry.point_data,
CD_PROP_FLOAT3,
ATTR_POSITION,
curves->geometry.point_size);
BKE_curves_update_customdata_pointers(curves);
/* Created deformed coordinates array on demand. */
mti->deformVerts(
md, &mectx, nullptr, curves->geometry.position, curves->geometry.point_size);
}
}
return curves;
}
void BKE_curves_data_update(struct Depsgraph *depsgraph, struct Scene *scene, Object *object)
{
/* Free any evaluated data and restore original data. */
BKE_object_free_derived_caches(object);
/* Evaluate modifiers. */
Curves *curves = static_cast<Curves *>(object->data);
Curves *curves_eval = curves_evaluate_modifiers(depsgraph, scene, object, curves);
/* Assign evaluated object. */
const bool is_owned = (curves != curves_eval);
BKE_object_eval_assign_data(object, &curves_eval->id, is_owned);
}
/* Draw Cache */
void (*BKE_curves_batch_cache_dirty_tag_cb)(Curves *curves, int mode) = nullptr;
void (*BKE_curves_batch_cache_free_cb)(Curves *curves) = nullptr;
void BKE_curves_batch_cache_dirty_tag(Curves *curves, int mode)
{
if (curves->batch_cache) {
BKE_curves_batch_cache_dirty_tag_cb(curves, mode);
}
}
void BKE_curves_batch_cache_free(Curves *curves)
{
if (curves->batch_cache) {
BKE_curves_batch_cache_free_cb(curves);
}
}

View File

@@ -15,13 +15,13 @@
*
* The Original Code is Copyright (C) 2006 Blender Foundation.
* All rights reserved.
* Implementation of CustomData.
*
* BKE_customdata.h contains the function prototypes for this file.
*/
/** \file
* \ingroup bke
* Implementation of CustomData.
*
* BKE_customdata.h contains the function prototypes for this file.
*/
#include "MEM_guardedalloc.h"
@@ -31,7 +31,6 @@
#include "DNA_ID.h"
#include "DNA_customdata_types.h"
#include "DNA_hair_types.h"
#include "DNA_meshdata_types.h"
#include "BLI_bitmap.h"

View File

@@ -5082,7 +5082,8 @@ static void dynamic_paint_prepare_effect_cb(void *__restrict userdata,
EffectedPoint epoint;
pd_point_from_loc(scene, realCoord[bData->s_pos[index]].v, vel, index, &epoint);
epoint.vel_to_sec = 1.0f;
BKE_effectors_apply(effectors, NULL, surface->effector_weights, &epoint, forc, NULL, NULL);
BKE_effectors_apply(
effectors, NULL, surface->effector_weights, &epoint, forc, NULL, NULL, NULL);
}
/* if global gravity is enabled, add it too */

View File

@@ -1135,7 +1135,8 @@ void BKE_effectors_apply(ListBase *effectors,
EffectedPoint *point,
float *force,
float *wind_force,
float *impulse)
float *impulse,
float r_eff_forces[3][3])
{
/* WARNING(@campbellbarton): historic comment?
* Many of these parameters don't exist!
@@ -1173,6 +1174,8 @@ void BKE_effectors_apply(ListBase *effectors,
/* Cycle through collected objects, get total of (1/(gravity_strength * dist^gravity_power)) */
/* Check for min distance here? (yes would be cool to add that, ton) */
int num_eff_forces = 0;
float out_force[3] = {0, 0, 0};
if (effectors) {
for (eff = effectors->first; eff; eff = eff->next) {
/* object effectors were fully checked to be OK to evaluate! */
@@ -1187,7 +1190,7 @@ void BKE_effectors_apply(ListBase *effectors,
efd.falloff *= eff_calc_visibility(colliders, eff, &efd, point);
}
if (efd.falloff > 0.0f) {
float out_force[3] = {0, 0, 0};
zero_v3(out_force);
if (eff->pd->forcefield == PFIELD_TEXTURE) {
do_texture_effector(eff, &efd, point, out_force);
@@ -1214,6 +1217,11 @@ void BKE_effectors_apply(ListBase *effectors,
/* special case for harmonic effector */
add_v3_v3v3(impulse, impulse, efd.vel);
}
if (r_eff_forces != NULL && num_eff_forces < 3) {
copy_v3_v3(r_eff_forces[num_eff_forces], out_force);
num_eff_forces++;
}
}
}
}

View File

@@ -3195,7 +3195,7 @@ static void update_effectors_task_cb(void *__restrict userdata,
/* Do effectors. */
pd_point_from_loc(data->scene, voxel_center, vel, index, &epoint);
BKE_effectors_apply(
data->effectors, NULL, fds->effector_weights, &epoint, retvel, NULL, NULL);
data->effectors, NULL, fds->effector_weights, &epoint, retvel, NULL, NULL, NULL);
/* Convert retvel to local space. */
mag = len_v3(retvel);

View File

@@ -1,474 +0,0 @@
/*
* 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.
*/
/** \file
* \ingroup bke
*/
#include <cmath>
#include <cstring>
#include "MEM_guardedalloc.h"
#include "DNA_defaults.h"
#include "DNA_hair_types.h"
#include "DNA_material_types.h"
#include "DNA_object_types.h"
#include "BLI_index_range.hh"
#include "BLI_listbase.h"
#include "BLI_math_base.h"
#include "BLI_math_vec_types.hh"
#include "BLI_rand.hh"
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BKE_anim_data.h"
#include "BKE_customdata.h"
#include "BKE_global.h"
#include "BKE_hair.h"
#include "BKE_idtype.h"
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
#include "BKE_lib_remap.h"
#include "BKE_main.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BLT_translation.h"
#include "DEG_depsgraph_query.h"
#include "BLO_read_write.h"
using blender::float3;
using blender::IndexRange;
using blender::MutableSpan;
using blender::RandomNumberGenerator;
static const char *HAIR_ATTR_POSITION = "position";
static const char *HAIR_ATTR_RADIUS = "radius";
/* Hair datablock */
static void hair_random(Hair *hair);
static void hair_init_data(ID *id)
{
Hair *hair = (Hair *)id;
BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(hair, id));
MEMCPY_STRUCT_AFTER(hair, DNA_struct_default_get(Hair), id);
CustomData_reset(&hair->geometry.point_data);
CustomData_reset(&hair->geometry.curve_data);
CustomData_add_layer_named(&hair->geometry.point_data,
CD_PROP_FLOAT3,
CD_CALLOC,
nullptr,
hair->geometry.point_size,
HAIR_ATTR_POSITION);
CustomData_add_layer_named(&hair->geometry.point_data,
CD_PROP_FLOAT,
CD_CALLOC,
nullptr,
hair->geometry.point_size,
HAIR_ATTR_RADIUS);
BKE_hair_update_customdata_pointers(hair);
hair_random(hair);
}
static void hair_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int flag)
{
Hair *hair_dst = (Hair *)id_dst;
const Hair *hair_src = (const Hair *)id_src;
hair_dst->mat = static_cast<Material **>(MEM_dupallocN(hair_src->mat));
hair_dst->geometry.point_size = hair_src->geometry.point_size;
hair_dst->geometry.curve_size = hair_src->geometry.curve_size;
const eCDAllocType alloc_type = (flag & LIB_ID_COPY_CD_REFERENCE) ? CD_REFERENCE : CD_DUPLICATE;
CustomData_copy(&hair_src->geometry.point_data,
&hair_dst->geometry.point_data,
CD_MASK_ALL,
alloc_type,
hair_dst->geometry.point_size);
CustomData_copy(&hair_src->geometry.curve_data,
&hair_dst->geometry.curve_data,
CD_MASK_ALL,
alloc_type,
hair_dst->geometry.curve_size);
BKE_hair_update_customdata_pointers(hair_dst);
hair_dst->geometry.offsets = static_cast<int *>(MEM_dupallocN(hair_src->geometry.offsets));
hair_dst->batch_cache = nullptr;
}
static void hair_free_data(ID *id)
{
Hair *hair = (Hair *)id;
BKE_animdata_free(&hair->id, false);
BKE_hair_batch_cache_free(hair);
CustomData_free(&hair->geometry.point_data, hair->geometry.point_size);
CustomData_free(&hair->geometry.curve_data, hair->geometry.curve_size);
MEM_SAFE_FREE(hair->geometry.offsets);
MEM_SAFE_FREE(hair->mat);
}
static void hair_foreach_id(ID *id, LibraryForeachIDData *data)
{
Hair *hair = (Hair *)id;
for (int i = 0; i < hair->totcol; i++) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, hair->mat[i], IDWALK_CB_USER);
}
}
static void hair_blend_write(BlendWriter *writer, ID *id, const void *id_address)
{
Hair *hair = (Hair *)id;
CustomDataLayer *players = nullptr, players_buff[CD_TEMP_CHUNK_SIZE];
CustomDataLayer *clayers = nullptr, clayers_buff[CD_TEMP_CHUNK_SIZE];
CustomData_blend_write_prepare(
&hair->geometry.point_data, &players, players_buff, ARRAY_SIZE(players_buff));
CustomData_blend_write_prepare(
&hair->geometry.curve_data, &clayers, clayers_buff, ARRAY_SIZE(clayers_buff));
/* Write LibData */
BLO_write_id_struct(writer, Hair, id_address, &hair->id);
BKE_id_blend_write(writer, &hair->id);
/* Direct data */
CustomData_blend_write(writer,
&hair->geometry.point_data,
players,
hair->geometry.point_size,
CD_MASK_ALL,
&hair->id);
CustomData_blend_write(writer,
&hair->geometry.curve_data,
clayers,
hair->geometry.curve_size,
CD_MASK_ALL,
&hair->id);
BLO_write_int32_array(writer, hair->geometry.curve_size + 1, hair->geometry.offsets);
BLO_write_pointer_array(writer, hair->totcol, hair->mat);
if (hair->adt) {
BKE_animdata_blend_write(writer, hair->adt);
}
/* Remove temporary data. */
if (players && players != players_buff) {
MEM_freeN(players);
}
if (clayers && clayers != clayers_buff) {
MEM_freeN(clayers);
}
}
static void hair_blend_read_data(BlendDataReader *reader, ID *id)
{
Hair *hair = (Hair *)id;
BLO_read_data_address(reader, &hair->adt);
BKE_animdata_blend_read_data(reader, hair->adt);
/* Geometry */
CustomData_blend_read(reader, &hair->geometry.point_data, hair->geometry.point_size);
CustomData_blend_read(reader, &hair->geometry.curve_data, hair->geometry.point_size);
BKE_hair_update_customdata_pointers(hair);
BLO_read_int32_array(reader, hair->geometry.curve_size + 1, &hair->geometry.offsets);
/* Materials */
BLO_read_pointer_array(reader, (void **)&hair->mat);
}
static void hair_blend_read_lib(BlendLibReader *reader, ID *id)
{
Hair *hair = (Hair *)id;
for (int a = 0; a < hair->totcol; a++) {
BLO_read_id_address(reader, hair->id.lib, &hair->mat[a]);
}
}
static void hair_blend_read_expand(BlendExpander *expander, ID *id)
{
Hair *hair = (Hair *)id;
for (int a = 0; a < hair->totcol; a++) {
BLO_expand(expander, hair->mat[a]);
}
}
IDTypeInfo IDType_ID_HA = {
/*id_code */ ID_HA,
/*id_filter */ FILTER_ID_HA,
/*main_listbase_index */ INDEX_ID_HA,
/*struct_size */ sizeof(Hair),
/*name */ "Hair",
/*name_plural */ "hairs",
/*translation_context */ BLT_I18NCONTEXT_ID_HAIR,
/*flags */ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info */ nullptr,
/*init_data */ hair_init_data,
/*copy_data */ hair_copy_data,
/*free_data */ hair_free_data,
/*make_local */ nullptr,
/*foreach_id */ hair_foreach_id,
/*foreach_cache */ nullptr,
/*foreach_path */ nullptr,
/*owner_get */ nullptr,
/*blend_write */ hair_blend_write,
/*blend_read_data */ hair_blend_read_data,
/*blend_read_lib */ hair_blend_read_lib,
/*blend_read_expand */ hair_blend_read_expand,
/*blend_read_undo_preserve */ nullptr,
/*lib_override_apply_post */ nullptr,
};
static void hair_random(Hair *hair)
{
CurvesGeometry &geometry = hair->geometry;
const int numpoints = 8;
geometry.curve_size = 500;
geometry.curve_size = 500;
geometry.point_size = geometry.curve_size * numpoints;
hair->geometry.offsets = (int *)MEM_calloc_arrayN(
hair->geometry.curve_size + 1, sizeof(int), __func__);
CustomData_realloc(&geometry.point_data, geometry.point_size);
CustomData_realloc(&geometry.curve_data, geometry.curve_size);
BKE_hair_update_customdata_pointers(hair);
MutableSpan<int> offsets{geometry.offsets, geometry.curve_size + 1};
MutableSpan<float3> positions{(float3 *)geometry.position, geometry.point_size};
MutableSpan<float> radii{geometry.radius, geometry.point_size};
for (const int i : offsets.index_range()) {
geometry.offsets[i] = numpoints * i;
}
RandomNumberGenerator rng;
for (int i = 0; i < geometry.curve_size; i++) {
const IndexRange curve_range(offsets[i], offsets[i + 1] - offsets[i]);
MutableSpan<float3> curve_positions = positions.slice(curve_range);
MutableSpan<float> curve_radii = radii.slice(curve_range);
const float theta = 2.0f * M_PI * rng.get_float();
const float phi = saacosf(2.0f * rng.get_float() - 1.0f);
float3 no = {std::sin(theta) * std::sin(phi), std::cos(theta) * std::sin(phi), std::cos(phi)};
no = blender::math::normalize(no);
float3 co = no;
for (int key = 0; key < numpoints; key++) {
float t = key / (float)(numpoints - 1);
curve_positions[key] = co;
curve_radii[key] = 0.02f * (1.0f - t);
float3 offset = float3(rng.get_float(), rng.get_float(), rng.get_float()) * 2.0f - 1.0f;
co += (offset + no) / numpoints;
}
}
}
void *BKE_hair_add(Main *bmain, const char *name)
{
Hair *hair = static_cast<Hair *>(BKE_id_new(bmain, ID_HA, name));
return hair;
}
BoundBox *BKE_hair_boundbox_get(Object *ob)
{
BLI_assert(ob->type == OB_HAIR);
Hair *hair = static_cast<Hair *>(ob->data);
if (ob->runtime.bb != nullptr && (ob->runtime.bb->flag & BOUNDBOX_DIRTY) == 0) {
return ob->runtime.bb;
}
if (ob->runtime.bb == nullptr) {
ob->runtime.bb = MEM_cnew<BoundBox>(__func__);
float min[3], max[3];
INIT_MINMAX(min, max);
float(*hair_co)[3] = hair->geometry.position;
float *hair_radius = hair->geometry.radius;
for (int a = 0; a < hair->geometry.point_size; a++) {
float *co = hair_co[a];
float radius = (hair_radius) ? hair_radius[a] : 0.0f;
const float co_min[3] = {co[0] - radius, co[1] - radius, co[2] - radius};
const float co_max[3] = {co[0] + radius, co[1] + radius, co[2] + radius};
DO_MIN(co_min, min);
DO_MAX(co_max, max);
}
BKE_boundbox_init_from_minmax(ob->runtime.bb, min, max);
}
return ob->runtime.bb;
}
void BKE_hair_update_customdata_pointers(Hair *hair)
{
hair->geometry.position = (float(*)[3])CustomData_get_layer_named(
&hair->geometry.point_data, CD_PROP_FLOAT3, HAIR_ATTR_POSITION);
hair->geometry.radius = (float *)CustomData_get_layer_named(
&hair->geometry.point_data, CD_PROP_FLOAT, HAIR_ATTR_RADIUS);
}
bool BKE_hair_customdata_required(Hair *UNUSED(hair), CustomDataLayer *layer)
{
return layer->type == CD_PROP_FLOAT3 && STREQ(layer->name, HAIR_ATTR_POSITION);
}
/* Dependency Graph */
Hair *BKE_hair_new_for_eval(const Hair *hair_src, int totpoint, int totcurve)
{
Hair *hair_dst = static_cast<Hair *>(BKE_id_new_nomain(ID_HA, nullptr));
STRNCPY(hair_dst->id.name, hair_src->id.name);
hair_dst->mat = static_cast<Material **>(MEM_dupallocN(hair_src->mat));
hair_dst->totcol = hair_src->totcol;
hair_dst->geometry.point_size = totpoint;
hair_dst->geometry.curve_size = totcurve;
CustomData_copy(&hair_src->geometry.point_data,
&hair_dst->geometry.point_data,
CD_MASK_ALL,
CD_CALLOC,
totpoint);
CustomData_copy(&hair_src->geometry.curve_data,
&hair_dst->geometry.curve_data,
CD_MASK_ALL,
CD_CALLOC,
totcurve);
BKE_hair_update_customdata_pointers(hair_dst);
return hair_dst;
}
Hair *BKE_hair_copy_for_eval(Hair *hair_src, bool reference)
{
int flags = LIB_ID_COPY_LOCALIZE;
if (reference) {
flags |= LIB_ID_COPY_CD_REFERENCE;
}
Hair *result = (Hair *)BKE_id_copy_ex(nullptr, &hair_src->id, nullptr, flags);
return result;
}
static Hair *hair_evaluate_modifiers(struct Depsgraph *depsgraph,
struct Scene *scene,
Object *object,
Hair *hair_input)
{
Hair *hair = hair_input;
/* Modifier evaluation modes. */
const bool use_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
const int required_mode = use_render ? eModifierMode_Render : eModifierMode_Realtime;
ModifierApplyFlag apply_flag = use_render ? MOD_APPLY_RENDER : MOD_APPLY_USECACHE;
const ModifierEvalContext mectx = {depsgraph, object, apply_flag};
/* Get effective list of modifiers to execute. Some effects like shape keys
* are added as virtual modifiers before the user created modifiers. */
VirtualModifierData virtualModifierData;
ModifierData *md = BKE_modifiers_get_virtual_modifierlist(object, &virtualModifierData);
/* Evaluate modifiers. */
for (; md; md = md->next) {
const ModifierTypeInfo *mti = BKE_modifier_get_info(static_cast<ModifierType>(md->type));
if (!BKE_modifier_is_enabled(scene, md, required_mode)) {
continue;
}
if ((mti->type == eModifierTypeType_OnlyDeform) &&
(mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly)) {
/* Ensure we are not modifying the input. */
if (hair == hair_input) {
hair = BKE_hair_copy_for_eval(hair, true);
}
/* Ensure we are not overwriting referenced data. */
CustomData_duplicate_referenced_layer_named(&hair->geometry.point_data,
CD_PROP_FLOAT3,
HAIR_ATTR_POSITION,
hair->geometry.point_size);
BKE_hair_update_customdata_pointers(hair);
/* Created deformed coordinates array on demand. */
mti->deformVerts(md, &mectx, nullptr, hair->geometry.position, hair->geometry.point_size);
}
}
return hair;
}
void BKE_hair_data_update(struct Depsgraph *depsgraph, struct Scene *scene, Object *object)
{
/* Free any evaluated data and restore original data. */
BKE_object_free_derived_caches(object);
/* Evaluate modifiers. */
Hair *hair = static_cast<Hair *>(object->data);
Hair *hair_eval = hair_evaluate_modifiers(depsgraph, scene, object, hair);
/* Assign evaluated object. */
const bool is_owned = (hair != hair_eval);
BKE_object_eval_assign_data(object, &hair_eval->id, is_owned);
}
/* Draw Cache */
void (*BKE_hair_batch_cache_dirty_tag_cb)(Hair *hair, int mode) = nullptr;
void (*BKE_hair_batch_cache_free_cb)(Hair *hair) = nullptr;
void BKE_hair_batch_cache_dirty_tag(Hair *hair, int mode)
{
if (hair->batch_cache) {
BKE_hair_batch_cache_dirty_tag_cb(hair, mode);
}
}
void BKE_hair_batch_cache_free(Hair *hair)
{
if (hair->batch_cache) {
BKE_hair_batch_cache_free_cb(hair);
}
}

View File

@@ -15,9 +15,6 @@
*
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
* All rights reserved.
* Modifier stack implementation.
*
* BKE_modifier.h contains the function prototypes for this file.
*/
/** \file
@@ -110,7 +107,7 @@ static void id_type_init(void)
INIT_TYPE(ID_CF);
INIT_TYPE(ID_WS);
INIT_TYPE(ID_LP);
INIT_TYPE(ID_HA);
INIT_TYPE(ID_CV);
INIT_TYPE(ID_PT);
INIT_TYPE(ID_VO);
INIT_TYPE(ID_SIM);
@@ -237,7 +234,7 @@ uint64_t BKE_idtype_idcode_to_idfilter(const short idcode)
CASE_IDFILTER(CU);
CASE_IDFILTER(GD);
CASE_IDFILTER(GR);
CASE_IDFILTER(HA);
CASE_IDFILTER(CV);
CASE_IDFILTER(IM);
CASE_IDFILTER(LA);
CASE_IDFILTER(LS);
@@ -286,7 +283,7 @@ short BKE_idtype_idcode_from_idfilter(const uint64_t idfilter)
CASE_IDFILTER(CU);
CASE_IDFILTER(GD);
CASE_IDFILTER(GR);
CASE_IDFILTER(HA);
CASE_IDFILTER(CV);
CASE_IDFILTER(IM);
CASE_IDFILTER(LA);
CASE_IDFILTER(LS);
@@ -334,7 +331,7 @@ int BKE_idtype_idcode_to_index(const short idcode)
CASE_IDINDEX(CU);
CASE_IDINDEX(GD);
CASE_IDINDEX(GR);
CASE_IDINDEX(HA);
CASE_IDINDEX(CV);
CASE_IDINDEX(IM);
CASE_IDINDEX(IP);
CASE_IDINDEX(KE);
@@ -393,7 +390,7 @@ short BKE_idtype_idcode_from_index(const int index)
CASE_IDCODE(CU);
CASE_IDCODE(GD);
CASE_IDCODE(GR);
CASE_IDCODE(HA);
CASE_IDCODE(CV);
CASE_IDCODE(IM);
CASE_IDCODE(IP);
CASE_IDCODE(KE);

View File

@@ -161,6 +161,8 @@ void BKE_lib_override_library_copy(ID *dst_id, const ID *src_id, const bool do_f
(ID *)src_id;
id_us_plus(dst_id->override_library->reference);
dst_id->override_library->hierarchy_root = src_id->override_library->hierarchy_root;
if (do_full_copy) {
BLI_duplicatelist(&dst_id->override_library->properties,
&src_id->override_library->properties);
@@ -293,6 +295,7 @@ ID *BKE_lib_override_library_create_from_id(Main *bmain,
* mess in case there are a lot of hidden, non-instantiated, non-properly organized dependencies.
* Ref T94650. */
local_id->override_library->flag |= IDOVERRIDE_LIBRARY_FLAG_NO_HIERARCHY;
local_id->override_library->hierarchy_root = local_id;
if (do_tagged_remap) {
Key *reference_key, *local_key = NULL;
@@ -328,9 +331,11 @@ ID *BKE_lib_override_library_create_from_id(Main *bmain,
bool BKE_lib_override_library_create_from_tag(Main *bmain,
Library *owner_library,
const Library *reference_library,
const ID *id_root_reference,
const bool do_no_main)
{
const Library *reference_library = id_root_reference->lib;
ID *reference_id;
bool success = true;
@@ -383,6 +388,8 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain,
/* Only remap new local ID's pointers, we don't want to force our new overrides onto our whole
* existing linked IDs usages. */
if (success) {
ID *hierarchy_root_id = id_root_reference->newid;
for (todo_id_iter = todo_ids.first; todo_id_iter != NULL; todo_id_iter = todo_id_iter->next) {
reference_id = todo_id_iter->data;
ID *local_id = reference_id->newid;
@@ -391,6 +398,8 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain,
continue;
}
local_id->override_library->hierarchy_root = hierarchy_root_id;
Key *reference_key, *local_key = NULL;
if ((reference_key = BKE_key_from_id(reference_id)) != NULL) {
local_key = BKE_key_from_id(reference_id->newid);
@@ -459,6 +468,7 @@ typedef struct LibOverrideGroupTagData {
Main *bmain;
Scene *scene;
ID *id_root;
ID *hierarchy_root_id;
uint tag;
uint missing_tag;
/* Whether we are looping on override data, or their references (linked) one. */
@@ -769,6 +779,8 @@ static void lib_override_overrides_group_tag_recursive(LibOverrideGroupTagData *
BLI_assert(ID_IS_OVERRIDE_LIBRARY(id_owner));
BLI_assert(data->is_override);
ID *id_hierarchy_root = data->hierarchy_root_id;
if (ID_IS_OVERRIDE_LIBRARY_REAL(id_owner) &&
(id_owner->override_library->flag & IDOVERRIDE_LIBRARY_FLAG_NO_HIERARCHY) != 0) {
return;
@@ -800,9 +812,15 @@ static void lib_override_overrides_group_tag_recursive(LibOverrideGroupTagData *
if (ELEM(to_id, NULL, id_owner)) {
continue;
}
/* Different libraries or different hierarchy roots are break points in override hierarchies.
*/
if (!ID_IS_OVERRIDE_LIBRARY(to_id) || (to_id->lib != id_owner->lib)) {
continue;
}
if (ID_IS_OVERRIDE_LIBRARY_REAL(to_id) &&
to_id->override_library->hierarchy_root != id_hierarchy_root) {
continue;
}
Library *reference_lib = lib_override_get(bmain, id_owner)->reference->lib;
ID *to_id_reference = lib_override_get(bmain, to_id)->reference;
@@ -832,6 +850,11 @@ static void lib_override_overrides_group_tag(LibOverrideGroupTagData *data)
BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_root));
BLI_assert(data->is_override);
ID *id_hierarchy_root = data->hierarchy_root_id;
BLI_assert(id_hierarchy_root != NULL);
BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_hierarchy_root));
UNUSED_VARS_NDEBUG(id_hierarchy_root);
if (id_root->override_library->reference->tag & LIB_TAG_MISSING) {
id_root->tag |= data->missing_tag;
}
@@ -865,7 +888,10 @@ static bool lib_override_library_create_do(Main *bmain,
BKE_main_relations_free(bmain);
lib_override_group_tag_data_clear(&data);
return BKE_lib_override_library_create_from_tag(bmain, owner_library, id_root->lib, false);
const bool success = BKE_lib_override_library_create_from_tag(
bmain, owner_library, id_root, false);
return success;
}
static void lib_override_library_create_post_process(Main *bmain,
@@ -1047,6 +1073,189 @@ bool BKE_lib_override_library_template_create(struct ID *id)
return true;
}
static ID *lib_override_root_find(Main *bmain, ID *id, const int curr_level, int *r_best_level)
{
if (curr_level > 1000) {
CLOG_ERROR(&LOG,
"Levels of dependency relationships between library overrides IDs is way too high, "
"skipping further processing loops (involves at least '%s')",
id->name);
BLI_assert(0);
return NULL;
}
if (!ID_IS_OVERRIDE_LIBRARY(id)) {
BLI_assert(0);
return NULL;
}
MainIDRelationsEntry *entry = BLI_ghash_lookup(bmain->relations->relations_from_pointers, id);
BLI_assert(entry != NULL);
int best_level_candidate = curr_level;
ID *best_root_id_candidate = id;
for (MainIDRelationsEntryItem *from_id_entry = entry->from_ids; from_id_entry != NULL;
from_id_entry = from_id_entry->next) {
if ((from_id_entry->usage_flag & IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE) != 0) {
/* Never consider non-overridable relationships as actual dependencies. */
continue;
}
ID *from_id = from_id_entry->id_pointer.from;
if (ELEM(from_id, NULL, id)) {
continue;
}
if (!ID_IS_OVERRIDE_LIBRARY(from_id) || (from_id->lib != id->lib)) {
continue;
}
int level_candidate = curr_level + 1;
/* Recursively process the parent. */
ID *root_id_candidate = lib_override_root_find(
bmain, from_id, curr_level + 1, &level_candidate);
if (level_candidate > best_level_candidate && root_id_candidate != NULL) {
best_root_id_candidate = root_id_candidate;
best_level_candidate = level_candidate;
}
}
*r_best_level = best_level_candidate;
return best_root_id_candidate;
}
static void lib_override_root_hierarchy_set(Main *bmain, ID *id_root, ID *id, ID *id_from)
{
if (ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
if (id->override_library->hierarchy_root == id_root) {
/* Already set, nothing else to do here, sub-hierarchy is also assumed to be properly set
* then. */
return;
}
/* Hierarchy root already set, and not matching currently propsed one, try to find which is
* best. */
if (id->override_library->hierarchy_root != NULL) {
/* Check if given `id_from` matches with the hierarchy of the linked reference ID, in which
* case we assume that the given hierarchy root is the 'real' one.
*
* NOTE: This can fail if user mixed dependencies between several overrides of a same
* reference linked hierarchy. Not much to be done in that case, it's virtually impossible to
* fix this automatically in a reliable way. */
if (id_from == NULL || !ID_IS_OVERRIDE_LIBRARY_REAL(id_from)) {
/* Too complicated to deal with for now. */
CLOG_WARN(&LOG,
"Inconsistency in library override hierarchy of ID '%s'.\n"
"\tNot enough data to verify validity of current proposed root '%s', assuming "
"already set one '%s' is valid.",
id->name,
id_root->name,
id->override_library->hierarchy_root->name);
return;
}
ID *id_from_ref = id_from->override_library->reference;
MainIDRelationsEntry *entry = BLI_ghash_lookup(bmain->relations->relations_from_pointers,
id->override_library->reference);
BLI_assert(entry != NULL);
bool do_replace_root = false;
for (MainIDRelationsEntryItem *from_id_entry = entry->from_ids; from_id_entry != NULL;
from_id_entry = from_id_entry->next) {
if ((from_id_entry->usage_flag & IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE) != 0) {
/* Never consider non-overridable relationships as actual dependencies. */
continue;
}
if (id_from_ref == from_id_entry->id_pointer.from) {
/* A matching parent was found in reference linked data, assume given hierarchy root is
* the valid one. */
do_replace_root = true;
CLOG_WARN(
&LOG,
"Inconsistency in library override hierarchy of ID '%s'.\n"
"\tCurrent proposed root '%s' detected as valid, will replace already set one '%s'.",
id->name,
id_root->name,
id->override_library->hierarchy_root->name);
break;
}
}
if (!do_replace_root) {
CLOG_WARN(
&LOG,
"Inconsistency in library override hierarchy of ID '%s'.\n"
"\tCurrent proposed root '%s' not detected as valid, keeping already set one '%s'.",
id->name,
id_root->name,
id->override_library->hierarchy_root->name);
return;
}
}
id->override_library->hierarchy_root = id_root;
}
MainIDRelationsEntry *entry = BLI_ghash_lookup(bmain->relations->relations_from_pointers, id);
BLI_assert(entry != NULL);
for (MainIDRelationsEntryItem *to_id_entry = entry->to_ids; to_id_entry != NULL;
to_id_entry = to_id_entry->next) {
if ((to_id_entry->usage_flag & IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE) != 0) {
/* Never consider non-overridable relationships as actual dependencies. */
continue;
}
ID *to_id = *to_id_entry->id_pointer.to;
if (ELEM(to_id, NULL, id)) {
continue;
}
if (!ID_IS_OVERRIDE_LIBRARY(to_id) || (to_id->lib != id->lib)) {
continue;
}
/* Recursively process the sub-hierarchy. */
lib_override_root_hierarchy_set(bmain, id_root, to_id, id);
}
}
void BKE_lib_override_library_main_hierarchy_root_ensure(Main *bmain)
{
ID *id;
BKE_main_relations_create(bmain, 0);
FOREACH_MAIN_ID_BEGIN (bmain, id) {
if (!ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
continue;
}
if (id->override_library->hierarchy_root != NULL) {
continue;
}
int best_level = 0;
ID *id_root = lib_override_root_find(bmain, id, best_level, &best_level);
if (!ELEM(id_root->override_library->hierarchy_root, id_root, NULL)) {
CLOG_WARN(&LOG,
"Potential inconsistency in library override hierarchy of ID '%s', detected as "
"part of the hierarchy of '%s', which has a different root '%s'",
id->name,
id_root->name,
id_root->override_library->hierarchy_root->name);
continue;
}
lib_override_root_hierarchy_set(bmain, id_root, id_root, NULL);
BLI_assert(id->override_library->hierarchy_root != NULL);
}
FOREACH_MAIN_ID_END;
BKE_main_relations_free(bmain);
}
static void lib_override_library_remap(Main *bmain,
const ID *id_root_reference,
GHash *linkedref_to_old_override)
@@ -1112,6 +1321,7 @@ static bool lib_override_library_resync(Main *bmain,
LibOverrideGroupTagData data = {.bmain = bmain,
.scene = scene,
.id_root = id_root,
.hierarchy_root_id = id_root->override_library->hierarchy_root,
.tag = LIB_TAG_DOIT,
.missing_tag = LIB_TAG_MISSING,
.is_override = true,
@@ -1214,7 +1424,7 @@ static bool lib_override_library_resync(Main *bmain,
* override IDs (including within the old overrides themselves, since those are tagged too
* above). */
const bool success = BKE_lib_override_library_create_from_tag(
bmain, NULL, id_root_reference->lib, true);
bmain, NULL, id_root_reference, true);
if (!success) {
return success;
@@ -1533,46 +1743,20 @@ static void lib_override_resync_tagging_finalize_recurse(Main *bmain,
*
* NOTE: Related to `lib_override_resync_tagging_finalize` above.
*/
static ID *lib_override_library_main_resync_find_root_recurse(ID *id, int *level)
static ID *lib_override_library_main_resync_root_get(Main *bmain, ID *id)
{
(*level)++;
ID *return_id = id;
switch (GS(id->name)) {
case ID_GR: {
/* Find the highest valid collection in the parenting hierarchy.
* Note that in practice, in any decent common case there is only one well defined root
* collection anyway. */
int max_level = *level;
Collection *collection = (Collection *)id;
LISTBASE_FOREACH (CollectionParent *, collection_parent_iter, &collection->parents) {
Collection *collection_parent = collection_parent_iter->collection;
if (ID_IS_OVERRIDE_LIBRARY_REAL(collection_parent) &&
collection_parent->id.lib == id->lib) {
int tmp_level = *level;
ID *tmp_id = lib_override_library_main_resync_find_root_recurse(&collection_parent->id,
&tmp_level);
if (tmp_level > max_level) {
max_level = tmp_level;
return_id = tmp_id;
}
}
}
break;
if (!ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id);
if (id_type->owner_get != NULL) {
id = id_type->owner_get(bmain, id);
}
case ID_OB: {
Object *object = (Object *)id;
if (object->parent != NULL && ID_IS_OVERRIDE_LIBRARY_REAL(object->parent) &&
object->parent->id.lib == id->lib) {
return_id = lib_override_library_main_resync_find_root_recurse(&object->parent->id, level);
}
break;
}
default:
break;
BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id));
}
return return_id;
ID *hierarchy_root_id = id->override_library->hierarchy_root;
BLI_assert(hierarchy_root_id != NULL);
BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(hierarchy_root_id));
return hierarchy_root_id;
}
/* Ensure resync of all overrides at one level of indirect usage.
@@ -1714,14 +1898,13 @@ static void lib_override_library_main_resync_on_library_indirect_level(
Library *library = id->lib;
int level = 0;
/* In complex non-supported cases, with several different override hierarchies sharing
* relations between each-other, we may end up not actually updating/replacing the given
* root id (see e.g. pro/shots/110_rextoria/110_0150_A/110_0150_A.anim.blend of sprites
* project repository, r2687).
* This can lead to infinite loop here, at least avoid this. */
id->tag &= ~LIB_TAG_LIB_OVERRIDE_NEED_RESYNC;
id = lib_override_library_main_resync_find_root_recurse(id, &level);
id = lib_override_library_main_resync_root_get(bmain, id);
id->tag &= ~LIB_TAG_LIB_OVERRIDE_NEED_RESYNC;
BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id));
BLI_assert(id->lib == library);
@@ -1879,6 +2062,7 @@ void BKE_lib_override_library_delete(Main *bmain, ID *id_root)
LibOverrideGroupTagData data = {.bmain = bmain,
.scene = NULL,
.id_root = id_root,
.hierarchy_root_id = id_root->override_library->hierarchy_root,
.tag = LIB_TAG_DOIT,
.missing_tag = LIB_TAG_MISSING,
.is_override = true,

View File

@@ -323,6 +323,8 @@ static bool library_foreach_ID_link(Main *bmain,
IDWALK_CB_USER | IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE);
CALLBACK_INVOKE_ID(id->override_library->storage,
IDWALK_CB_USER | IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE);
CALLBACK_INVOKE_ID(id->override_library->hierarchy_root, IDWALK_CB_LOOPBACK);
}
IDP_foreach_property(id->properties,
@@ -471,7 +473,7 @@ bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used)
return ELEM(id_type_used, ID_MA);
case ID_WS:
return ELEM(id_type_used, ID_SCR, ID_SCE);
case ID_HA:
case ID_CV:
return ELEM(id_type_used, ID_MA);
case ID_PT:
return ELEM(id_type_used, ID_MA);

View File

@@ -558,7 +558,7 @@ static void libblock_remap_foreach_idpair_cb(ID *old_id, ID *new_id, void *user_
case ID_ME:
case ID_CU:
case ID_MB:
case ID_HA:
case ID_CV:
case ID_PT:
case ID_VO:
if (new_id) { /* Only affects us in case obdata was relinked (changed). */

View File

@@ -643,8 +643,8 @@ ListBase *which_libbase(Main *bmain, short type)
return &(bmain->cachefiles);
case ID_WS:
return &(bmain->workspaces);
case ID_HA:
return &(bmain->hairs);
case ID_CV:
return &(bmain->hair_curves);
case ID_PT:
return &(bmain->pointclouds);
case ID_VO:
@@ -688,7 +688,7 @@ int set_listbasepointers(Main *bmain, ListBase *lb[/*INDEX_ID_MAX*/])
lb[INDEX_ID_ME] = &(bmain->meshes);
lb[INDEX_ID_CU] = &(bmain->curves);
lb[INDEX_ID_MB] = &(bmain->metaballs);
lb[INDEX_ID_HA] = &(bmain->hairs);
lb[INDEX_ID_CV] = &(bmain->hair_curves);
lb[INDEX_ID_PT] = &(bmain->pointclouds);
lb[INDEX_ID_VO] = &(bmain->volumes);

View File

@@ -36,10 +36,10 @@
#include "DNA_anim_types.h"
#include "DNA_collection_types.h"
#include "DNA_curve_types.h"
#include "DNA_curves_types.h"
#include "DNA_customdata_types.h"
#include "DNA_defaults.h"
#include "DNA_gpencil_types.h"
#include "DNA_hair_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
@@ -341,9 +341,9 @@ Material ***BKE_object_material_array_p(Object *ob)
bGPdata *gpd = ob->data;
return &(gpd->mat);
}
if (ob->type == OB_HAIR) {
Hair *hair = ob->data;
return &(hair->mat);
if (ob->type == OB_CURVES) {
Curves *curves = ob->data;
return &(curves->mat);
}
if (ob->type == OB_POINTCLOUD) {
PointCloud *pointcloud = ob->data;
@@ -374,9 +374,9 @@ short *BKE_object_material_len_p(Object *ob)
bGPdata *gpd = ob->data;
return &(gpd->totcol);
}
if (ob->type == OB_HAIR) {
Hair *hair = ob->data;
return &(hair->totcol);
if (ob->type == OB_CURVES) {
Curves *curves = ob->data;
return &(curves->totcol);
}
if (ob->type == OB_POINTCLOUD) {
PointCloud *pointcloud = ob->data;
@@ -403,8 +403,8 @@ Material ***BKE_id_material_array_p(ID *id)
return &(((MetaBall *)id)->mat);
case ID_GD:
return &(((bGPdata *)id)->mat);
case ID_HA:
return &(((Hair *)id)->mat);
case ID_CV:
return &(((Curves *)id)->mat);
case ID_PT:
return &(((PointCloud *)id)->mat);
case ID_VO:
@@ -429,8 +429,8 @@ short *BKE_id_material_len_p(ID *id)
return &(((MetaBall *)id)->totcol);
case ID_GD:
return &(((bGPdata *)id)->totcol);
case ID_HA:
return &(((Hair *)id)->totcol);
case ID_CV:
return &(((Curves *)id)->totcol);
case ID_PT:
return &(((PointCloud *)id)->totcol);
case ID_VO:
@@ -454,7 +454,7 @@ static void material_data_index_remove_id(ID *id, short index)
BKE_curve_material_index_remove((Curve *)id, index);
break;
case ID_MB:
case ID_HA:
case ID_CV:
case ID_PT:
case ID_VO:
/* No material indices for these object data types. */
@@ -509,7 +509,7 @@ static void material_data_index_clear_id(ID *id)
BKE_curve_material_index_clear((Curve *)id);
break;
case ID_MB:
case ID_HA:
case ID_CV:
case ID_PT:
case ID_VO:
/* No material indices for these object data types. */

View File

@@ -15,6 +15,11 @@
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
/** \file
* \ingroup bke
*
* MetaBalls are created from a single Object (with a name without number in it),
* here the DispList and BoundBox also is located.
* All objects with the same name (but with a number in it) are added to this.
@@ -22,10 +27,6 @@
* texture coordinates are patched within the displist
*/
/** \file
* \ingroup bke
*/
#include <ctype.h>
#include <float.h>
#include <math.h>

View File

@@ -43,6 +43,7 @@
#include "BLI_span.hh"
#include "BLI_stack.h"
#include "BLI_task.h"
#include "BLI_task.hh"
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
@@ -373,22 +374,28 @@ const float (*BKE_mesh_vertex_normals_ensure(const Mesh *mesh))[3]
return (const float(*)[3])CustomData_get_layer(&mesh->vdata, CD_NORMAL);
}
Mesh &mesh_mutable = *const_cast<Mesh *>(mesh);
float(*vert_normals)[3];
float(*poly_normals)[3];
float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(&mesh_mutable);
float(*poly_normals)[3] = BKE_mesh_poly_normals_for_write(&mesh_mutable);
/* Isolate task because a mutex is locked and computing normals is multi-threaded. */
blender::threading::isolate_task([&]() {
Mesh &mesh_mutable = *const_cast<Mesh *>(mesh);
mesh_calc_normals_poly_and_vertex(mesh_mutable.mvert,
mesh_mutable.totvert,
mesh_mutable.mloop,
mesh_mutable.totloop,
mesh_mutable.mpoly,
mesh_mutable.totpoly,
poly_normals,
vert_normals);
vert_normals = BKE_mesh_vertex_normals_for_write(&mesh_mutable);
poly_normals = BKE_mesh_poly_normals_for_write(&mesh_mutable);
BKE_mesh_vertex_normals_clear_dirty(&mesh_mutable);
BKE_mesh_poly_normals_clear_dirty(&mesh_mutable);
mesh_calc_normals_poly_and_vertex(mesh_mutable.mvert,
mesh_mutable.totvert,
mesh_mutable.mloop,
mesh_mutable.totloop,
mesh_mutable.mpoly,
mesh_mutable.totpoly,
poly_normals,
vert_normals);
BKE_mesh_vertex_normals_clear_dirty(&mesh_mutable);
BKE_mesh_poly_normals_clear_dirty(&mesh_mutable);
});
BLI_mutex_unlock(normals_mutex);
return vert_normals;
@@ -413,19 +420,24 @@ const float (*BKE_mesh_poly_normals_ensure(const Mesh *mesh))[3]
return (const float(*)[3])CustomData_get_layer(&mesh->pdata, CD_NORMAL);
}
Mesh &mesh_mutable = *const_cast<Mesh *>(mesh);
float(*poly_normals)[3];
float(*poly_normals)[3] = BKE_mesh_poly_normals_for_write(&mesh_mutable);
/* Isolate task because a mutex is locked and computing normals is multi-threaded. */
blender::threading::isolate_task([&]() {
Mesh &mesh_mutable = *const_cast<Mesh *>(mesh);
BKE_mesh_calc_normals_poly(mesh_mutable.mvert,
mesh_mutable.totvert,
mesh_mutable.mloop,
mesh_mutable.totloop,
mesh_mutable.mpoly,
mesh_mutable.totpoly,
poly_normals);
poly_normals = BKE_mesh_poly_normals_for_write(&mesh_mutable);
BKE_mesh_poly_normals_clear_dirty(&mesh_mutable);
BKE_mesh_calc_normals_poly(mesh_mutable.mvert,
mesh_mutable.totvert,
mesh_mutable.mloop,
mesh_mutable.totloop,
mesh_mutable.mpoly,
mesh_mutable.totpoly,
poly_normals);
BKE_mesh_poly_normals_clear_dirty(&mesh_mutable);
});
BLI_mutex_unlock(normals_mutex);
return poly_normals;

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