1
1

Compare commits

..

138 Commits

Author SHA1 Message Date
83d7dd528d Geometry Nodes: Update boilerplate code for attributes 2020-11-17 09:22:33 -05:00
46e2f4761c Merge branch 'geometry-nodes' into geometry-nodes-attribute-nodes 2020-11-17 09:03:04 -05:00
b26cbb5d53 Merge branch 'master' into geometry-nodes 2020-11-16 12:03:01 -05:00
52e3608fe9 Geometry Nodes: simplify GeometrySet ownership handling
Previously, GeometrySets and GeometryComponents has reference
counters and could be shared. This commit changes it so that
only GeometryComponents are shared. A GeometrySet is a fairly
small type that is cheap to copy.

A lot of code simplifies when we can assume that GeometrySet
is cheap to copy.
2020-11-16 13:48:33 +01:00
6ba6e97407 Geometry Nodes: Move GeometrySet classes to global namespace
Brecht and I decided to move the GeometrySet classes
to the global namespace for now. This way we can use
the same type in C and C++ and don't have to use
reinterpret_cast as often.
2020-11-16 12:07:51 +01:00
4913b624d8 Merge branch 'master' into geometry-nodes 2020-11-16 11:49:14 +01:00
96ce1e9a95 Geometry Nodes: Improve node group output modifier error
More than output for the modifier's node group is fine, because the
node group may be used in other situations, but the modifier will
not work if there is no geometry output socket.
2020-11-14 20:09:27 -05:00
a3efa1d798 Merge branch 'master' into geometry-nodes 2020-11-14 15:17:46 -05:00
e50553c61a Empty Modifier: Fix build and put in the right order
Bypassing the macro that creates modifiers to allow the enum to be
referring to the Empty modifier, but the internal struct in the code to
be Nodes.

Also fix the name of the new created modifiers to be "Empty".

Fix was built with rBb458ea6b23381a9acb90dbbd73ced678e1d404c5.
2020-11-14 01:51:06 +01:00
b458ea6b23 Rename: "Nodes" modifier to "Empty" (take 2)
Leave the internal DNA data struct as "Nodes", and only rename the
modifier and user interface to Empty.

See 4a2734a835 for the original take and the reasoning
for renaming from Nodes to Empty.
2020-11-13 23:29:09 +01:00
056d7bb175 Revert "Rename: "Nodes" modifier to "Empty""
This reverts commit 4a2734a835.

Reverting this so that all we change is the UI name, not the DNA struct
and the internal variable names.
2020-11-13 23:19:40 +01:00
Léo Depoix
9769cf1ee6 Geometry Nodes : Removing "Combine Strings" and Group Instance ID from UI
This diff remove "Combine Strings" and "Group Instance ID" nodes from the UI (but keep them in the source code to be able to bring them back if needed).

This is part of "Cleanup 1st Sprint Nodes" (https://developer.blender.org/T82370).

Differential Revision: https://developer.blender.org/D9558
2020-11-13 22:23:37 +01:00
4a2734a835 Rename: "Nodes" modifier to "Empty"
This introduces a regression. Users need to re-create their modifiers
and set their values again. The NodeGroups are intact so all they need
is to create new "Empty" modifiers and set the node group.

---

Original problem: Eventually most modifiers will be node-based, so naming
this new modifier "Nodes" will get outdated pretty quickly.

Calling it "Empty" it's fairly descriptive, since the node tree simply connects
the modifier Input to an Output, without any effect.

There is a potential problem, that it could be associated with the
Empty object type. Like some sort of Hook.

This is the task T82700, and the design task T82537.
2020-11-13 22:16:28 +01:00
1ddd717803 Geometry Nodes: Improve error messages for property mismatches
Related to T82438. This adds some basic checks for common errors and
currently unsupported socket types in the modifier.
2020-11-13 12:35:10 -05:00
0066e59f2d Merge branch 'master' into geometry-nodes 2020-11-13 11:54:29 -05:00
ec7fffb033 Cleanup: Remove unused variable 2020-11-12 20:38:51 -05:00
956cf9a48d Cleanup: Clang Tidy 2020-11-12 16:06:12 -05:00
c27095b5cb Cleanup: Spelling
Also move some input extraction after the special case check.
2020-11-12 16:04:45 -05:00
Léo Depoix
8ef8cb7e34 Geometry Nodes: Add method enums to mesh triangulate node
This commit adds the remaining "method" enums from the triangulate modifier.

Differential Revision: https://developer.blender.org/D9502
2020-11-12 15:49:59 -05:00
0f6bee8e54 Merge branch 'master' into geometry-nodes 2020-11-12 15:19:09 -05:00
3093f89498 Geometry Nodes: Add null check for modifier property UI functions
An ID IDProperty exposed to the modifier  (object, material, etc) does not
have min, max, etc. values, so they should not be required.
2020-11-12 14:47:17 -05:00
f211030344 Cleanup: Fix typo 2020-11-12 12:19:44 -05:00
b277025d8e Geometry Nodes: Add modifier disabled check 2020-11-12 12:16:32 -05:00
94572a4e30 Geometry Nodes: use density attribute name instead of index as node input
This implements a workaround for the issue that (for historical reasons)
the names of vertex groups are stored on the object while the actual vertex
group data is stored on the mesh.

The solution is to copy the vertex group names from the object into
the `MeshComponent` so that the information is not lost, when the
object cannot be accessed.
2020-11-12 16:58:30 +01:00
bc2230df71 Geometry Nodes: cleanup geometry node interface
Previously, the execution function of a geometry node has three parameters.
Now it has only one. This makes it easier to pass more information to the
execution function, that might only be used by a few nodes, because we
don't have to add more parameters that are unused in most cases.
2020-11-12 16:31:32 +01:00
caa942b033 Geometry Nodes: actually create instances in Point Instance node 2020-11-12 13:28:33 +01:00
5dff952b67 Geometry Nodes: support instances in Transform node 2020-11-12 13:27:56 +01:00
5877e34eb4 Geometry Nodes: new DupliGenerator for instances component
With this, instances generated in a node tree can be rendered.
2020-11-12 13:27:20 +01:00
770bcfac9b Geometry Nodes: improve point distribute node
* Support vertex weights to control density.
* O(n) performance instead of O(n^2).
* More stable when density weights are changed.

The vertex group has to be specified using an index for now.
This is a technical limitation that will resolved a bit later.
2020-11-12 13:24:46 +01:00
b081108819 Geometry Nodes: support geometry components in depsgraph object iterator
Objects can evaluate to a geometry set instead of a single ID (only point cloud
objects for now). In the depsgraph object iterator, those geometry components
are expanded into temporary objects.

It's important to note that instanced objects can also contain geometry
components. Therefore, they have to be split up into multiple objects
as well in some cases.

At a high level the iterator works like so:
```
for object in depsgraph:
    for component in object:
        yield object_from_component(component)
    for dupli in make_duplis_list(object):
        for component in dupli:
            yield object_from_component(component)
```

DEG_iterator_objects_next has been cleaned up, to make this structure
a bit more apparent.
2020-11-12 13:20:23 +01:00
2be7b2aaf9 Geometry Nodes: better handle link cycles 2020-11-12 12:58:27 +01:00
912b38001f Geometry Nodes: use GeometrySet when evaluating pointcloud modifiers
This changes the signature of the modifyPointCloud function.
I'm doing that instead of making a new callback, because it requires
changes to significantly fewer files. Eventually it would be good
combine modifyMesh, modifyHair, modifyPointCloud and modifyVolume
into one modifyGeometrySet.

I temporarily disabled the displacement only modifiers for point clouds.
Support can be added back a bit later. I assume those have not been
used anywhere anyway.

The output of point cloud modifiers can not only be another point cloud,
but also a mesh and/or some instances. I added a new geometry_set_eval
field to Object_Runtime. For point cloud objects, the final geometry is
now referenced by that pointer instead of data_eval. The data_eval field
is still initialized after modifier evaluation to make some other code happy.

The evaluated geometry set is not yet passed to the renderer, so a point
cloud is currently rendered empty.
2020-11-12 12:57:52 +01:00
c4352f44bc Geometry Nodes: initial Object Info node
This node takes an object as input and outputs its location, rotation,
scale and geometry. Right now the loc/rot/scale are extracted from the
objects `obmat`. The geometry is just the mesh in the local space of the
source object.

We will likely need some more control over space transformations
using enums in the node, but those can be added a bit later.
2020-11-12 12:24:07 +01:00
0feca5f07d Geometry Nodes: initial object socket support
The fundamental difference between object sockets and the
other existing data sockets is that an object is an ID data block.
Changing the value of an object socket also changes the depsgraph.

The modifier has to analyse the node tree to figure out which other
objects it depends on. Currently, this is done very simply by just
looping over all sockets and collecting the objects. In the future
this can be improved by also figuring out what components of
an object are needed.

Instead of passing object pointers around in the node tree, we actually
use a handle. This handle is just a number internally that identifies
a specific object. The conversion between handles and object pointers
is done using a map that is provided by the modifier.

This approach has a couple of benefits. It protects us a bit from passing
around pointers that are not known to the modifier and therefore are
not in the depsgraph. Furthermore, the object pointer can change
while the handle stays the same. This is not important right now, but
is not unlikely to become useful in the future.

The API for how nodes access object pointers is not ideal yet and
will be improved in the future.
2020-11-12 12:20:59 +01:00
2984fb2b49 Geometry Nodes: crash when using Vector Math node 2020-11-12 11:51:12 +01:00
9e6553c0d4 Geometry Nodes: change color of object socket 2020-11-12 11:50:23 +01:00
107a0894cc Geometry Nodes: improve GeometrySet
This commits implements multiple changes:
* Adds a simple C API.
* Improves the ownership handling by introducing GeometryOwnershipType.
* Adds an InstancesComponent that stores positions and Object pointers.
2020-11-12 11:47:48 +01:00
8ecc1bea4c Nodes: add utility to check for link cycles in derived node trees 2020-11-12 11:35:46 +01:00
91ad33ef8f Merge branch 'master' into geometry-nodes 2020-11-12 11:25:25 +01:00
fa5190e742 fix after merge 2020-11-09 15:55:24 +01:00
74ed591f62 Merge branch 'master' into geometry-nodes 2020-11-09 15:48:18 +01:00
3d5efb4335 Geometry Nodes: rename Geometry type to GeometrySet
This should not change any functionality.

After talking to Brecht, we agreed that it might be good
not to have a class called Geometry for now. In the future
we might want to use a Geometry class as base class for
meshes, curves, etc.

This commit renames the Geometry class to GeometrySet,
because it is essentially a container that can contain
multiple geometries of different types.
2020-11-09 13:08:17 +01:00
Léo Depoix
140b7cfe0d Geometry Nodes: cleanup Subdivision Surface node inputs
Ref T82370.

Differential Revision: https://developer.blender.org/D9487
2020-11-09 12:49:33 +01:00
af7cc3f8bb Fix merge issues 2020-11-09 12:46:04 +01:00
d2c4af9865 Merge branch 'master' into geometry-nodes 2020-11-09 12:44:45 +01:00
e5c637f5fe Merge remote-tracking branch 'origin/master' into geometry-nodes 2020-11-06 18:22:36 +01:00
11d12d543d Fix build error on windows: Don't use designated initializers in C++ 2020-11-02 08:20:54 -06:00
2c6114b238 Merge branch 'master' into geometry-nodes 2020-11-02 08:15:15 -06:00
152bd43ae1 Merge branch 'master' into geometry-nodes 2020-11-02 11:44:46 +01:00
24474a60b6 Geometry Nodes: Use std::string for string sockets 2020-10-31 23:57:14 -05:00
0bd0e08790 Merge branch 'geometry-nodes' into geometry-nodes-attribute-nodes 2020-10-31 23:24:22 -05:00
45012c3309 Geometry Nodes: Fix property values reset when input socket is added
The names of the IDProperties are the socket identifiers, not their names.
2020-10-31 23:24:06 -05:00
faac263d97 Merge branch 'geometry-nodes' into geometry-nodes-attribute-nodes 2020-10-31 23:01:31 -05:00
5177c35498 Merge branch 'master' into geometry-nodes 2020-10-31 22:58:39 -05:00
49c8042f29 Merge branch 'master' into geometry-nodes 2020-10-31 14:21:14 +01:00
Léo Depoix
f8c52590c0 Geometry Nodes: new Subdivision Surface node
This node is similar to the subdivision surface modifier. It subdivides
the mesh component of a geometry. The options have the same meaning
as in the modifier.

Differential Revision: https://developer.blender.org/D9364
2020-10-31 10:51:09 +01:00
0b897e0308 Merge branch 'master' into geometry-nodes 2020-10-31 10:43:52 +01:00
97c0158cda Merge branch 'geometry-nodes' into geometry-nodes-attribute-nodes 2020-10-31 00:37:41 -05:00
c34438dd78 Geometry Nodes: Rename node category based on functionality
Naming based on supported geometry components only works in some cases.
For nodes that work with multiple data types, it's better to categorize
them based on their functionality.
2020-10-31 00:37:04 -05:00
e0a4dc9396 Merge branch 'master' into geometry-nodes 2020-10-31 00:30:10 -05:00
97a9576959 Geometry Nodes: Add initial empty nodes for basic attribute workflow
This adds the boilerplate code for three nodes: "Create Attribute,"
"Random Attribute," and "Attribute Math." Combined, they should
be enough for the process of creating randomized "Rotation" and
"Scale" attributes on point clouds for instancing done later. The
implementation details are not resolved at this point, but this
starting point should make sense.
2020-10-31 00:21:05 -05:00
51fa44522f Geometry Nodes: Add errors for out of sync sockets and properties
Theoretically the modifier's properties could be changed or removed by
Python, so it may be useful to have errors printed and added to the
modifier in that case.

I kept the check as a separate step from the `compute_geometry`
pass because the object is needed to set the modifier error message.
But it could easily be moved there in the future.
2020-10-30 11:42:11 -05:00
343e13f464 Geometry Nodes: change geometry socket color
Ref T81848.
2020-10-30 17:29:36 +01:00
1103809fab Merge branch 'master' into geometry-nodes 2020-10-30 16:40:41 +01:00
5b89d49b0d Geometry Nodes: Allow node group inputs with the same name
If we add the "name" label manually with uiItemR, we can use the socket
identifier instead of the name for the IDProperty name. This will also
allow us more flexibility in how to draw the settings in the future, and
removes the empty _RNA_UI proprety that was drawn before.
2020-10-30 09:57:54 -05:00
e805bfc768 Cleanup: Return early in edge split node 2020-10-29 15:53:32 -05:00
67cb4fdbdc Cleanup: Don't use unsupported struct initialization
Although this worked for me, it appears this isn't supported until C++20.
2020-10-29 15:48:38 -05:00
8ed74c9daf Geometry Nodes: Use UI settings for properties in modifier
The system for exposing property settings like min, max, default, subtype,
etc. for ID properties is quite convoluted currently, so I won't give a
full description here, but this commit creates the tree of ID properties
needed to store that information. This means that property subtypes like
"angle" or "XYZ" will affect the display in the modifier.

Limitations:
 - The _RNA_UI property is displayed in the modifier. This may require a
   modification to uiDefAutoButsRNA to fix.
 - IDProperties must have unique names, but node sockets don't have
   that limitation. This can be solved by adding a "UI name" field to
   IDProperties.
2020-10-29 14:11:32 -05:00
d7cb25e028 Fixup for cmake header cleanup
Issue introduced on f73a420e5a.
2020-10-29 18:27:31 +01:00
e3395093ff Geometry Nodes: Create the node group when adding a new Nodes modifier 2020-10-29 17:36:16 +01:00
f73a420e5a Cleanup: Nodes Modifier header to its proper location 2020-10-29 17:36:16 +01:00
b8b240b329 Geometry Nodes: do not reference custom data layers when copying mesh
We can't use that for now, because the original mesh might be freed
before the new copied mesh. When the original mesh is freed, the shared
layers will be freed as well.

This can probably be improved in the future, so that we can actually
share attribute arrays between meshes. An approach similar to how
geometries and components are shared should work as well.
2020-10-29 15:47:19 +01:00
ae2827bb52 Geometry Nodes: add comment mentioning that custom data might be shared 2020-10-29 15:42:01 +01:00
bb97284f8a Geometry Nodes: refactor Geometry type
A geometry now contains zero or more geometry components.
A geometry component is a subclass off GeometryComponent.
Currently, there is a MeshComponent and PointCloudComponent.

A geometry contains at most one component of each type.
Individual components can be shared between multiple geometries
to avoid unnecessary copies. For that, each component has a user
count that determines when the component will be freed and whether
it is mutable.

Code working with geometries can either work with the components
directly, or use the utility functions on the geometry that cover the
most common operations.

In the future, additional component types can be added. For example,
we'll probably need components for curves and volumes.
Furthermore, something like an InstancesComponent can be added,
which contains points with attributes and references a geometry/object/collection
that is instanced on all the points.
2020-10-29 15:38:15 +01:00
209e82da45 Merge branch 'master' into geometry-nodes 2020-10-29 15:22:59 +01:00
e63d43e6b9 Merge branch 'master' into geometry-nodes 2020-10-29 11:31:55 +01:00
802ba35654 Geometry Nodes: make default group output node active
Otherwise some updates were missing when sockets are changed.
2020-10-28 20:27:57 +01:00
79c9c11b35 Merge branch 'master' into geometry-nodes 2020-10-28 20:21:52 +01:00
e1d0ab2dbc Geometry Nodes: fix missing update when inserting a node between two nodes 2020-10-28 14:53:06 +01:00
687f994251 Geometry Nodes: improve api for nodes
The execute callback of a geometry node gets more domain specific
types as parameters now: GeoNodeInputs and GeoNodeOutputs.

Those types are also aware of what node is being executed and can
provide better error messages when they are used incorrectly.
2020-10-28 14:05:07 +01:00
5c7767e0e0 Merge branch 'master' into geometry-nodes 2020-10-28 14:01:05 +01:00
af9ee8e2bc Merge branch 'master' into geometry-nodes 2020-10-28 10:40:35 +01:00
562f2e604a Merge branch 'master' into geometry-nodes 2020-10-27 21:21:03 -05:00
84e81b8cc3 Merge branch 'master' into geometry-nodes 2020-10-27 14:01:48 -05:00
5ae9527770 Geometry Nodes: Support pointcloud in transform node
This is likely not the final implementation of the transform node, but
it's  a good trivial case for supporting multiple geometry data types.
2020-10-27 12:59:58 -05:00
082c17a2d2 Fix group input is resetting in modifier 2020-10-27 17:01:03 +01:00
09677d737c Fix missing null check in recent commit 2020-10-27 15:53:17 +01:00
bec7248178 Cleanup: Use proper C++ types 2020-10-27 09:43:38 -05:00
0103cb2051 Geometry Nodes: initial support for bool group inputs
Still need to work on the uilayout inside the modifier.
2020-10-27 14:59:26 +01:00
9f38ebefcb Geometry Nodes: support vector inputs to geometry group 2020-10-27 14:54:41 +01:00
8f934852f0 Geometry Nodes: initial support for displaying group inputs in modifier
This uses the previously added id properties on the nodes modifier
to store values that are passed into the geometry node group.
2020-10-27 13:44:46 +01:00
cb16db7803 Geometry Nodes: enable nodes modifier in edit mode 2020-10-27 12:09:13 +01:00
f8965f12a1 Geometry Nodes: Fix memory leak 2020-10-26 23:15:05 -05:00
7f2a20f89b Merge branch 'master' into geometry-nodes 2020-10-26 23:12:45 -05:00
5566818603 Geometry Nodes: Add initial scattering nodes
The first is a "Point Distribute" node, which takes a mesh and outputs a
pointcloud, scattering points randomly on the surface based on the input
density. The distribution algorithm is extremely basic at this point, and
doesn't take into account an attribute weight at each vertex.

The second node is a "Point Instance" node, which is mainly a placeholder
until the engineering design for how to work with instancing in geometry
nodes is decided. For now it just runs the same code that the convert
pointcloud to mesh operator uses.
2020-10-26 23:00:31 -05:00
9a06c6a040 Geometry Nodes: Add function to create a temporary pointcloud
We needed a "nomain" funciton similar to the one we have for meshes in
order to add a working pointcloud for the geometry nodes.
2020-10-26 22:54:55 -05:00
e097116072 Geometry Nodes: Add utility to position point randomly on 3D triangle 2020-10-26 22:44:35 -05:00
b844caca6d Geometry Nodes: Add pointcloud support to geometry class
This adds another set of the same mesh functions but for pointclouds.
There are probably better ways to generalize this functionality, but that
may have to be rethought in the future anyway if we want to store
multiple of each type. And anyway it's handy to have a specific set of
"pointcloud" functions available in the node implementations.
2020-10-26 22:41:57 -05:00
046ac5fccd Geometry Nodes: Initial mesh boolean node
This uses the code from the rewritten boolean modifier from 2.91 as a node.
The implementation is about as minimal as it can get, since for now the use
case of this node is mostly to test multiple geometry outputs and inputs.

The boolean code requires a BMesh, so the node converts the input meshes
to BMesh, so the bmesh is added as a dependency to the nodes module.
2020-10-26 14:27:19 -05:00
ef4fbba596 Cleanup: remove unused modifier property 2020-10-26 18:27:44 +01:00
aa8360d0fa Geometry Nodes: initial test trying to use id properties to initialize group inputs
The settings can only be set via Python currently. The matching between properties
and group inputs is based on the socket identifier (which is e.g. `Input_5`).
Maybe we'll have to use a different matching strategy in the future, will see.
2020-10-26 18:23:51 +01:00
76c356c12e Geometry Nodes: store id properties in nodes modifier
The properties are not used yet, but can already be accessed with Python
using `modifier.settings['setting name']`.

The plan is to use id properties to store the parameters that the modifier
passes into the geometry node group.
2020-10-26 17:53:51 +01:00
e04491073d Geometry Nodes: support evaluation with more than one group input
Group inputs are not yet exposed in the modifier. For now I just added
a simple float setting that will be passed to every float input of the group.
Inputs of other types have some default value.
2020-10-26 14:16:26 +01:00
a5dda5996e Geometry Nodes: connect group input and output by default 2020-10-26 13:29:03 +01:00
c48e4b7a44 Geometry Nodes: improve node tree evaluation
This change reduces the number of unnecessary copies of data
and avoids computing the same value more than once.
2020-10-26 13:27:02 +01:00
4ae2d6206a Geometry Nodes: initial Transform node
Most of this code has been written by @HooglyBoogly.
I just changed the exec funtion so that it does not have to make
a copy of the mesh.
2020-10-26 12:27:51 +01:00
47f5a635da Geometry Nodes: add utility method to check if a geometry has a mesh 2020-10-26 12:25:46 +01:00
eb8574bc8b Merge branch 'master' into geometry-nodes 2020-10-26 12:10:12 +01:00
bc4e31afb6 Merge branch 'master' into geometry-nodes 2020-10-24 14:38:00 +02:00
9d7672be71 Merge branch 'master' into geometry-nodes 2020-10-23 15:18:20 +02:00
994e7178bb Geometry Nodes: make some function nodes available
We might not want to have all those nodes in a final version.
Some of them have been added with particle nodes in mind.
However, to test the evaluation system it is useful to have a
couple of nodes available.

Those nodes should "just" work, because their implementation
is reused from the particle nodes project.
2020-10-23 15:13:19 +02:00
1719743066 Geometry Nodes: improve node group evaluation
This adds support for nodes that have a multi-function implementation.
That includes various function nodes like Math, Combine Vector, ...

Furthermore, there is support for implicit conversions now. So it should
work when one connects e.g. a float to an integer and vice versa.
2020-10-23 15:09:55 +02:00
8910033f57 Nodes: add utility methods 2020-10-23 15:05:01 +02:00
2a4c6c612a Functions: add utility method 2020-10-23 15:01:07 +02:00
b062b922f9 Geometry Nodes: Resolve some missing 3D viewport updates
These two functions "snode_notify" and "ED_node_tag_update_id" appear to
be mostly duplicates. However, there is already a case for each type of
built-in node tree, so it makes sense to add one for the geometry node
tree as well. This doesn't solve the update issues for changing number
in buttons, that must be handled somewhere else.
2020-10-22 22:59:40 -05:00
895f4620a0 Merge branch 'master' into geometry-nodes 2020-10-22 22:03:28 -05:00
fafed6234b Geometry Nodes: Add edge split node functionality 2020-10-22 13:48:56 -05:00
7ff8094a8b Geometry Nodes: expose minimum vertices input of Triangulate node 2020-10-22 18:24:05 +02:00
5aabf67a9c Fix error in previous commit
That should not have happened -.-
2020-10-22 18:23:39 +02:00
ab8c7fe946 Fix previous comment 2020-10-22 18:20:17 +02:00
a05012d500 Geometry Nodes: simplify and deduplicate callbacks on sockets
This adds a layer of abstraction between the code calling callbacks
on sockets and the implementation of those callbacks.
This abstraction layer allows some sockets to not implement all
callbacks when those can be derived from some other callback.
2020-10-22 18:08:27 +02:00
97a93566e9 Geometry Nodes: change "Node Tree" to "Node Group" 2020-10-22 15:52:15 +02:00
da4d697772 Geometry Nodes: initial support for evaluating geometry node groups
This is still very basic and does quite a few unnecessary computations.
Also the error handling is quite weak currently, so when invalid things are
connected, it will probably just crash.

Also the interface that individual nodes have to implement will have to change,
but the current solution is a good starting point.

Only the triangulate node is implemented for now.
2020-10-22 15:05:41 +02:00
87218899be Geometry Nodes: add an initial geometry class 2020-10-22 15:02:27 +02:00
ffa0a6df9d Functions: add generic pointer class
This class represents a pointer whose type is only known at runtime.
2020-10-22 15:01:31 +02:00
706fa5ad76 Functions: add move operations to CPPType 2020-10-22 15:00:07 +02:00
b7f6de490d Geometry Nodes: Add initial node definition for edge split
This is just based on rBa7dba81aab22, and contains no funcionality at all.
2020-10-21 16:11:09 -05:00
7e485b4620 Merge branch 'master' into geometry-nodes 2020-10-21 08:54:39 -05:00
a7dba81aab Nodes: add initial UI for Triangulate node 2020-10-21 14:14:09 +02:00
4606e83a75 Merge branch 'master' into geometry-nodes 2020-10-21 14:00:32 +02:00
1d28de57a4 Nodes: improve dependency between modifier and node group 2020-10-21 13:16:19 +02:00
3cfcfb938d Nodes: support creating geometry node groups 2020-10-21 12:32:02 +02:00
bcdc6910a0 Nodes: show header in geometry node editor 2020-10-21 12:16:57 +02:00
7793e8c884 Modifiers: add node_tree to NodesModifierData 2020-10-21 12:13:13 +02:00
05d9bd7c4a Modifiers: rename Simulation to Nodes modifier 2020-10-21 12:03:06 +02:00
9255ce9247 Nodes: rename Simulation to Geometry node tree 2020-10-21 11:39:42 +02:00
a0ce0154e7 Merge branch 'master' into geometry-nodes 2020-10-21 11:11:16 +02:00
0cd7f7ddd1 Nodes: add geometry socket type
We still have to pick a color for this socket.

Ref T81848.
2020-10-20 15:31:59 +02:00
1969 changed files with 35355 additions and 61916 deletions

View File

@@ -29,19 +29,23 @@ Checks: >
-bugprone-sizeof-expression,
-bugprone-integer-division,
-bugprone-exception-escape,
-bugprone-redundant-branch-condition,
modernize-*,
-modernize-use-auto,
-modernize-use-trailing-return-type,
-modernize-deprecated-headers,
-modernize-avoid-c-arrays,
-modernize-use-equals-default,
-modernize-use-nodiscard,
-modernize-use-using,
-modernize-loop-convert,
-modernize-pass-by-value,
-modernize-use-default-member-init,
-modernize-raw-string-literal,
-modernize-avoid-bind,
-modernize-use-override,
-modernize-use-transparent-functors,
WarningsAsErrors: '*'

View File

@@ -91,79 +91,3 @@ c42a6b77b52560d257279de2cb624b4ef2c0d24c
# Cleanup: use doxy sections for imbuf
c207f7c22e1439e0b285fba5d2c072bdae23f981
# Cleanup: Clang-Tidy, modernize-use-bool-literals
af35ada2f3fa8da4d46b3a71de724d353d716820
# Cleanup: Use nullptr everywhere in fluid code
311031ecd03dbfbf43e1df672a395f24b2e7d4d3
# Cleanup: Clang-Tidy, modernize-redundant-void-arg
a331d5c99299c4514ca33c843b1c79b872f2728d
# Cleanup: Clang-Tidy modernize-use-nullptr
16732def37c5a66f3ea28dbe247b09cc6bca6677
# Cleanup: Clang-tidy, modernize-concat-nested-namespaces
4525049aa0cf818f6483dce589ac9791eb562338
# Cleanup: Clang-tidy else-after-return
ae342ed4511cf2e144dcd27ce2c635d3d536f9ad
# Cleanup: Clang-Tidy, readability-redundant-member-init
190170d4cc92ff34abe1744a10474ac4f1074086
# Cleanup: use 'filepath' instead of 'name' for ImBuf utilities
99f56b4c16323f96c0cbf54e392fb509fcac5bda
# Cleanup: clang-format
c4d8f6a4a8ddc29ed27311ed7578b3c8c31399d2
b5d310b569e07a937798a2d38539cfd290149f1c
8c846cccd6bdfd3e90a695fabbf05f53e5466a57
40d4a4cb1a6b4c3c2a486e8f2868f547530e0811
4eac03d821fa17546f562485f7d073813a5e5943
# Cleanup: use preprocessor version check for PyTypeObject declaration
cd9acfed4f7674b84be965d469a367aef96f8af3
# Cycles: fix compilation of OSL shaders following API change
b980cd163a9d5d77eeffc2e353333e739fa9e719
# Cleanup: clang-tidy suppress warnings for PyTypeObject.tp_print
efd71aad4f22ec0073d80b8dd296015d3f395aa8
# Cleanup: fix wrong merge, remove extra unique_ptr.
6507449e54a167c63a72229e4d0119dd2af68ae5
# Cleanup: fix some clang tidy issues
525a042c5c7513c41240b118acca002f6c60cc12
# Fix T82520: error building freestyle with Python3.8
e118426e4695a97d67e65d69677f3c4e2db50a56
# Cleanup: Clang-tidy, readability-else-after-return
7be47dadea5066ae095c644e0b4f1f10d75f5ab3
# Cleanup: Add `r_` to return parameter
45dca05b1cd2a5ead59144c93d790fdfe7c35ee6
# Cleanup: Typo in `print_default_info` function name.
41a73909dec716642f044e60b40a28335c9fdb10
# Cleanup: Reduce indentation
1cc3a0e2cf73a5ff4f9e0a7f5338eda77266b300
# Build-system: Force C linkage for all DNA type headers
ad4b7741dba45a2be210942c18af6b6e4438f129
# Cleanup: Move function to proper section
c126e27cdc8b28365a9d5f9fafc4d521d1eb83df
# Cleanup: remove break after return statements
bbdfeb751e16d939482d2e4b95c4d470f53f18a5
# Cleanup: clang-tidy
af013ff76feef7e8b8ba642279c62a5dc275d59f
# Cleanup: Make panel type flag names more clear
9d28353b525ecfbcca1501be72e4276dfb2bbc2a

View File

@@ -178,7 +178,6 @@ mark_as_advanced(BUILDINFO_OVERRIDE_TIME)
option(WITH_IK_ITASC "Enable ITASC IK solver (only disable for development & for incompatible C++ compilers)" ON)
option(WITH_IK_SOLVER "Enable Legacy IK solver (only disable for development)" ON)
option(WITH_FFTW3 "Enable FFTW3 support (Used for smoke, ocean sim, and audio effects)" ON)
option(WITH_PUGIXML "Enable PugiXML support (Used for OpenImageIO, Grease Pencil SVG export)" ON)
option(WITH_BULLET "Enable Bullet (Physics Engine)" ON)
option(WITH_SYSTEM_BULLET "Use the systems bullet library (currently unsupported due to missing features in upstream!)" )
mark_as_advanced(WITH_SYSTEM_BULLET)
@@ -347,21 +346,16 @@ if(UNIX AND NOT APPLE)
endif()
option(WITH_PYTHON_INSTALL "Copy system python into the blender install folder" ON)
if((WITH_AUDASPACE AND NOT WITH_SYSTEM_AUDASPACE) OR WITH_MOD_FLUID)
option(WITH_PYTHON_NUMPY "Include NumPy in Blender (used by Audaspace and Mantaflow)" ON)
endif()
if(WIN32 OR APPLE)
# Windows and macOS have this bundled with Python libraries.
elseif(WITH_PYTHON_INSTALL OR WITH_PYTHON_NUMPY)
elseif(WITH_PYTHON_INSTALL OR (WITH_AUDASPACE AND NOT WITH_SYSTEM_AUDASPACE))
set(PYTHON_NUMPY_PATH "" CACHE PATH "Path to python site-packages or dist-packages containing 'numpy' module")
mark_as_advanced(PYTHON_NUMPY_PATH)
set(PYTHON_NUMPY_INCLUDE_DIRS "" CACHE PATH "Path to the include directory of the NumPy module")
set(PYTHON_NUMPY_INCLUDE_DIRS ${PYTHON_NUMPY_PATH}/numpy/core/include CACHE PATH "Path to the include directory of the numpy module")
mark_as_advanced(PYTHON_NUMPY_INCLUDE_DIRS)
endif()
if(WITH_PYTHON_INSTALL)
option(WITH_PYTHON_INSTALL_NUMPY "Copy system NumPy into the blender install folder" ON)
option(WITH_PYTHON_INSTALL_NUMPY "Copy system numpy into the blender install folder" ON)
if(UNIX AND NOT APPLE)
option(WITH_PYTHON_INSTALL_REQUESTS "Copy system requests into the blender install folder" ON)
@@ -383,7 +377,6 @@ option(WITH_CYCLES_CUDA_BINARIES "Build Cycles CUDA binaries" OFF)
option(WITH_CYCLES_CUBIN_COMPILER "Build cubins with nvrtc based compiler instead of nvcc" OFF)
option(WITH_CYCLES_CUDA_BUILD_SERIAL "Build cubins one after another (useful on machines with limited RAM)" OFF)
mark_as_advanced(WITH_CYCLES_CUDA_BUILD_SERIAL)
set(CYCLES_TEST_DEVICES CPU CACHE STRING "Run regression tests on the specified device types (CPU CUDA OPTIX OPENCL)" )
set(CYCLES_CUDA_BINARIES_ARCH sm_30 sm_35 sm_37 sm_50 sm_52 sm_60 sm_61 sm_70 sm_75 sm_86 compute_75 CACHE STRING "CUDA architectures to build binaries for")
mark_as_advanced(CYCLES_CUDA_BINARIES_ARCH)
unset(PLATFORM_DEFAULT)
@@ -432,8 +425,8 @@ mark_as_advanced(WITH_CXX_GUARDEDALLOC)
option(WITH_ASSERT_ABORT "Call abort() when raising an assertion through BLI_assert()" ON)
mark_as_advanced(WITH_ASSERT_ABORT)
if((UNIX AND NOT APPLE) OR (CMAKE_GENERATOR MATCHES "^Visual Studio.+"))
option(WITH_CLANG_TIDY "Use Clang Tidy to analyze the source code (only enable for development on Linux using Clang, or Windows using the Visual Studio IDE)" OFF)
if(UNIX AND NOT APPLE)
option(WITH_CLANG_TIDY "Use Clang Tidy to analyze the source code (only enable for development on Linux using Clang)" OFF)
mark_as_advanced(WITH_CLANG_TIDY)
endif()
@@ -610,11 +603,6 @@ if(WIN32)
endif()
if(UNIX)
# See WITH_WINDOWS_SCCACHE for Windows.
option(WITH_COMPILER_CCACHE "Use ccache to improve rebuild times (Works with Ninja, Makefiles and Xcode)" OFF)
endif()
# The following only works with the Ninja generator in CMake >= 3.0.
if("${CMAKE_GENERATOR}" MATCHES "Ninja")
option(WITH_NINJA_POOL_JOBS
@@ -709,8 +697,6 @@ set_and_warn_dependency(WITH_BOOST WITH_OPENCOLORIO OFF)
set_and_warn_dependency(WITH_BOOST WITH_QUADRIFLOW OFF)
set_and_warn_dependency(WITH_BOOST WITH_USD OFF)
set_and_warn_dependency(WITH_BOOST WITH_ALEMBIC OFF)
set_and_warn_dependency(WITH_PUGIXML WITH_CYCLES_OSL OFF)
set_and_warn_dependency(WITH_PUGIXML WITH_OPENIMAGEIO OFF)
if(WITH_BOOST AND NOT (WITH_CYCLES OR WITH_OPENIMAGEIO OR WITH_INTERNATIONAL OR
WITH_OPENVDB OR WITH_OPENCOLORIO OR WITH_USD OR WITH_ALEMBIC))
@@ -889,11 +875,9 @@ if(NOT CMAKE_BUILD_TYPE MATCHES "Release")
if(APPLE AND COMPILER_ASAN_LIBRARY)
string(REPLACE " " ";" _list_COMPILER_ASAN_CFLAGS ${COMPILER_ASAN_CFLAGS})
set(_is_CONFIG_DEBUG "$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>")
add_compile_options("$<${_is_CONFIG_DEBUG}:${_list_COMPILER_ASAN_CFLAGS}>")
add_link_options("$<${_is_CONFIG_DEBUG}:-fno-omit-frame-pointer;-fsanitize=address>")
add_compile_options("$<$<NOT:$<CONFIG:Release>>:${_list_COMPILER_ASAN_CFLAGS}>")
add_link_options("$<$<NOT:$<CONFIG:Release>>:-fno-omit-frame-pointer;-fsanitize=address>")
unset(_list_COMPILER_ASAN_CFLAGS)
unset(_is_CONFIG_DEBUG)
elseif(COMPILER_ASAN_LIBRARY)
set(PLATFORM_LINKLIBS "${PLATFORM_LINKLIBS};${COMPILER_ASAN_LIBRARY}")
set(PLATFORM_LINKFLAGS "${COMPILER_ASAN_LIBRARY} ${COMPILER_ASAN_LINKER_FLAGS}")
@@ -1631,16 +1615,19 @@ if(WITH_PYTHON)
if(WIN32 OR APPLE)
# Windows and macOS have this bundled with Python libraries.
elseif((WITH_PYTHON_INSTALL AND WITH_PYTHON_INSTALL_NUMPY) OR WITH_PYTHON_NUMPY)
elseif((WITH_PYTHON_INSTALL AND WITH_PYTHON_INSTALL_NUMPY) OR (WITH_AUDASPACE AND NOT WITH_SYSTEM_AUDASPACE))
if(("${PYTHON_NUMPY_PATH}" STREQUAL "") OR (${PYTHON_NUMPY_PATH} MATCHES NOTFOUND))
find_python_package(numpy "core/include")
find_python_package(numpy)
unset(PYTHON_NUMPY_INCLUDE_DIRS CACHE)
set(PYTHON_NUMPY_INCLUDE_DIRS ${PYTHON_NUMPY_PATH}/numpy/core/include CACHE PATH "Path to the include directory of the numpy module")
mark_as_advanced(PYTHON_NUMPY_INCLUDE_DIRS)
endif()
endif()
if(WIN32 OR APPLE)
# pass, we have this in lib/python/site-packages
elseif(WITH_PYTHON_INSTALL_REQUESTS)
find_python_package(requests "")
find_python_package(requests)
endif()
endif()
@@ -1773,10 +1760,6 @@ elseif(WITH_CYCLES_STANDALONE)
endif()
endif()
#-----------------------------------------------------------------------------
# Testing
add_subdirectory(tests)
#-----------------------------------------------------------------------------
# Blender Application
if(WITH_BLENDER)
@@ -1784,6 +1767,11 @@ if(WITH_BLENDER)
endif()
#-----------------------------------------------------------------------------
# Testing
add_subdirectory(tests)
#-----------------------------------------------------------------------------
# Define 'heavy' submodules (for Ninja builder when using pools).
setup_heavy_lib_pool()

View File

@@ -41,7 +41,6 @@ Convenience Targets
* developer: Enable faster builds, error checking and tests, recommended for developers.
* config: Run cmake configuration tool to set build options.
* ninja: Use ninja build tool for faster builds.
* ccache: Use ccache for faster rebuilds.
Note: passing the argument 'BUILD_DIR=path' when calling make will override the default build dir.
Note: passing the argument 'BUILD_CMAKE_ARGS=args' lets you add cmake arguments.
@@ -242,10 +241,6 @@ ifneq "$(findstring developer, $(MAKECMDGOALS))" ""
CMAKE_CONFIG_ARGS:=-C"$(BLENDER_DIR)/build_files/cmake/config/blender_developer.cmake" $(CMAKE_CONFIG_ARGS)
endif
ifneq "$(findstring ccache, $(MAKECMDGOALS))" ""
CMAKE_CONFIG_ARGS:=-DWITH_COMPILER_CCACHE=YES $(CMAKE_CONFIG_ARGS)
endif
# -----------------------------------------------------------------------------
# build tool
@@ -345,7 +340,6 @@ headless: all
bpy: all
developer: all
ninja: all
ccache: all
# -----------------------------------------------------------------------------
# Build dependencies

View File

@@ -94,7 +94,11 @@ include(cmake/usd.cmake)
include(cmake/potrace.cmake)
# Boost needs to be included after python.cmake due to the PYTHON_BINARY variable being needed.
include(cmake/boost.cmake)
include(cmake/pugixml.cmake)
if(UNIX)
# Rely on PugiXML compiled with OpenImageIO
else()
include(cmake/pugixml.cmake)
endif()
if((NOT APPLE) OR ("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "x86_64"))
include(cmake/ispc.cmake)
include(cmake/openimagedenoise.cmake)

View File

@@ -42,13 +42,7 @@ if(UNIX)
endforeach()
if(APPLE)
# Homebrew has different default locations for ARM and Intel macOS.
if("${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "arm64")
set(HOMEBREW_LOCATION "/opt/homebrew")
else()
set(HOMEBREW_LOCATION "/usr/local")
endif()
if(NOT EXISTS "${HOMEBREW_LOCATION}/opt/bison/bin/bison")
if(NOT EXISTS "/usr/local/opt/bison/bin/bison")
string(APPEND _software_missing " bison")
endif()
endif()

View File

@@ -17,14 +17,13 @@
# ***** END GPL LICENSE BLOCK *****
set(CLANG_EXTRA_ARGS
-DLLVM_DIR="${LIBDIR}/llvm/lib/cmake/llvm/"
-DCLANG_PATH_TO_LLVM_SOURCE=${BUILD_DIR}/ll/src/ll
-DCLANG_PATH_TO_LLVM_BUILD=${LIBDIR}/llvm
-DLLVM_USE_CRT_RELEASE=MD
-DLLVM_USE_CRT_DEBUG=MDd
-DLLVM_CONFIG=${LIBDIR}/llvm/bin/llvm-config
)
set(BUILD_CLANG_TOOLS OFF)
if(WIN32)
set(CLANG_GENERATOR "Ninja")
else()
@@ -32,32 +31,11 @@ else()
endif()
if(APPLE)
set(BUILD_CLANG_TOOLS ON)
set(CLANG_EXTRA_ARGS ${CLANG_EXTRA_ARGS}
-DLIBXML2_LIBRARY=${LIBDIR}/xml2/lib/libxml2.a
)
endif()
if(BUILD_CLANG_TOOLS)
# ExternalProject_Add does not allow multiple tarballs to be
# downloaded. Work around this by having an empty build action
# for the extra tools, and referring the clang build to the location
# of the clang-tools-extra source.
ExternalProject_Add(external_clang_tools
URL ${CLANG_TOOLS_URI}
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH MD5=${CLANG_TOOLS_HASH}
INSTALL_DIR ${LIBDIR}/clang_tools
PREFIX ${BUILD_DIR}/clang_tools
CONFIGURE_COMMAND echo "."
BUILD_COMMAND echo "."
INSTALL_COMMAND echo "."
)
list(APPEND CLANG_EXTRA_ARGS
-DLLVM_EXTERNAL_CLANG_TOOLS_EXTRA_SOURCE_DIR=${BUILD_DIR}/clang_tools/src/external_clang_tools/
)
endif()
ExternalProject_Add(external_clang
URL ${CLANG_URI}
DOWNLOAD_DIR ${DOWNLOAD_DIR}
@@ -87,14 +65,6 @@ add_dependencies(
ll
)
if(BUILD_CLANG_TOOLS)
# `external_clang_tools` is for downloading the source, not compiling it.
add_dependencies(
external_clang
external_clang_tools
)
endif()
# We currently do not build libxml2 on Windows.
if(NOT WIN32)
add_dependencies(

View File

@@ -98,10 +98,6 @@ harvest(jpg/include jpeg/include "*.h")
harvest(jpg/lib jpeg/lib "libjpeg.a")
harvest(lame/lib ffmpeg/lib "*.a")
harvest(clang/bin llvm/bin "clang-format")
if(BUILD_CLANG_TOOLS)
harvest(clang/bin llvm/bin "clang-tidy")
harvest(clang/share/clang llvm/share "run-clang-tidy.py")
endif()
harvest(clang/include llvm/include "*")
harvest(llvm/include llvm/include "*")
harvest(llvm/bin llvm/bin "llvm-config")
@@ -160,8 +156,6 @@ harvest(osl/lib osl/lib "*.a")
harvest(osl/shaders osl/shaders "*.h")
harvest(png/include png/include "*.h")
harvest(png/lib png/lib "*.a")
harvest(pugixml/include pugixml/include "*.hpp")
harvest(pugixml/lib pugixml/lib "*.a")
harvest(python/bin python/bin "python${PYTHON_SHORT_VERSION}m")
harvest(python/include python/include "*h")
harvest(python/lib python/lib "*")

View File

@@ -25,13 +25,8 @@ if(WIN32)
elseif(APPLE)
# Use bison installed via Homebrew.
# The one which comes which Xcode toolset is too old.
if("${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "arm64")
set(HOMEBREW_LOCATION "/opt/homebrew")
else()
set(HOMEBREW_LOCATION "/usr/local")
endif()
set(ISPC_EXTRA_ARGS_APPLE
-DBISON_EXECUTABLE=${HOMEBREW_LOCATION}/opt/bison/bin/bison
-DBISON_EXECUTABLE=/usr/local/opt/bison/bin/bison
)
elseif(UNIX)
set(ISPC_EXTRA_ARGS_UNIX

View File

@@ -112,9 +112,6 @@ set(OPENIMAGEIO_EXTRA_ARGS
-DOPENEXR_IEX_LIBRARY=${LIBDIR}/openexr/lib/${LIBPREFIX}Iex${OPENEXR_VERSION_POSTFIX}${LIBEXT}
-DOPENEXR_ILMIMF_LIBRARY=${LIBDIR}/openexr/lib/${LIBPREFIX}IlmImf${OPENEXR_VERSION_POSTFIX}${LIBEXT}
-DSTOP_ON_WARNING=OFF
-DUSE_EXTERNAL_PUGIXML=ON
-DPUGIXML_LIBRARY=${LIBDIR}/pugixml/lib/${LIBPREFIX}pugixml${LIBEXT}
-DPUGIXML_INCLUDE_DIR=${LIBDIR}/pugixml/include/
${WEBP_FLAGS}
${OIIO_SIMD_FLAGS}
)
@@ -137,7 +134,6 @@ add_dependencies(
external_jpeg
external_boost
external_tiff
external_pugixml
external_openjpeg${OPENJPEG_POSTFIX}
${WEBP_DEP}
)

View File

@@ -78,10 +78,14 @@ set(OSL_EXTRA_ARGS
-DINSTALL_DOCS=OFF
${OSL_SIMD_FLAGS}
-DPARTIO_LIBRARIES=
-DPUGIXML_HOME=${LIBDIR}/pugixml
)
if(APPLE)
if(WIN32)
set(OSL_EXTRA_ARGS
${OSL_EXTRA_ARGS}
-DPUGIXML_HOME=${LIBDIR}/pugixml
)
elseif(APPLE)
# Make symbol hiding consistent with OIIO which defaults to OFF,
# avoids linker warnings on macOS
set(OSL_EXTRA_ARGS
@@ -110,9 +114,17 @@ add_dependencies(
external_zlib
external_flexbison
external_openimageio
external_pugixml
)
if(UNIX)
# Rely on PugiXML compiled with OpenImageIO
else()
add_dependencies(
external_osl
external_pugixml
)
endif()
if(WIN32)
if(BUILD_MODE STREQUAL Release)
ExternalProject_Add_Step(external_osl after_install

View File

@@ -30,13 +30,13 @@ ExternalProject_Add(external_pugixml
if(WIN32)
if(BUILD_MODE STREQUAL Release)
ExternalProject_Add_Step(external_pugixml after_install
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/pugixml ${HARVEST_TARGET}/pugixml
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/pugixml/lib/pugixml.lib ${HARVEST_TARGET}/osl/lib/pugixml.lib
DEPENDEES install
)
endif()
if(BUILD_MODE STREQUAL Debug)
ExternalProject_Add_Step(external_pugixml after_install
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/pugixml/lib/pugixml.lib ${HARVEST_TARGET}/pugixml/lib/pugixml_d.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/pugixml/lib/pugixml.lib ${HARVEST_TARGET}/osl/lib/pugixml_d.lib
DEPENDEES install
)
endif()

View File

@@ -120,9 +120,6 @@ set(LLVM_HASH 31eb9ce73dd2a0f8dcab8319fb03f8fc)
set(CLANG_URI https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVM_VERSION}/clang-${LLVM_VERSION}.src.tar.xz)
set(CLANG_HASH 13468e4a44940efef1b75e8641752f90)
set(CLANG_TOOLS_URI https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVM_VERSION}/clang-tools-extra-${LLVM_VERSION}.src.tar.xz)
set(CLANG_TOOLS_HASH c76293870b564c6a7968622b475b7646)
set(OPENMP_URI https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVM_VERSION}/openmp-${LLVM_VERSION}.src.tar.xz)
set(OPENMP_HASH 6eade16057edbdecb3c4eef9daa2bfcf)

View File

@@ -2086,7 +2086,7 @@ compile_OIIO() {
cmake_d="$cmake_d -D USE_OPENCV=OFF"
cmake_d="$cmake_d -D BUILD_TESTING=OFF"
cmake_d="$cmake_d -D OIIO_BUILD_TESTS=OFF"
cmake_d="$cmake_d -D OIIO_BUILD_TOOLS=ON"
cmake_d="$cmake_d -D OIIO_BUILD_TOOLS=OFF"
cmake_d="$cmake_d -D TXT2MAN="
#cmake_d="$cmake_d -D CMAKE_EXPORT_COMPILE_COMMANDS=ON"
#cmake_d="$cmake_d -D CMAKE_VERBOSE_MAKEFILE=ON"
@@ -4072,7 +4072,7 @@ install_DEB() {
else
check_package_version_ge_lt_DEB libopenimageio-dev $OIIO_VERSION_MIN $OIIO_VERSION_MAX
if [ $? -eq 0 -a "$_with_built_openexr" = false ]; then
install_packages_DEB libopenimageio-dev openimageio-tools
install_packages_DEB libopenimageio-dev
clean_OIIO
else
compile_OIIO
@@ -4714,13 +4714,13 @@ install_RPM() {
INFO "Forced OpenImageIO building, as requested..."
compile_OIIO
else
check_package_version_ge_lt_RPM OpenImageIO-devel $OIIO_VERSION_MIN $OIIO_VERSION_MAX
if [ $? -eq 0 -a $_with_built_openexr == false ]; then
install_packages_RPM OpenImageIO-devel OpenImageIO-utils
clean_OIIO
else
#check_package_version_ge_lt_RPM OpenImageIO-devel $OIIO_VERSION_MIN $OIIO_VERSION_MAX
#if [ $? -eq 0 -a $_with_built_openexr == false ]; then
# install_packages_RPM OpenImageIO-devel
# clean_OIIO
#else
compile_OIIO
fi
#fi
fi

View File

@@ -34,24 +34,3 @@ diff -Naur orig/src/include/OpenImageIO/platform.h external_openimageio/src/incl
# include <windows.h>
#endif
diff -Naur orig/src/libutil/ustring.cpp external_openimageio/src/libutil/ustring.cpp
--- orig/src/libutil/ustring.cpp 2020-05-11 05:43:52.000000000 +0200
+++ external_openimageio/src/libutil/ustring.cpp 2020-11-26 12:06:08.000000000 +0100
@@ -337,6 +337,8 @@
// the std::string to make it point to our chars! In such a case, the
// destructor will be careful not to allow a deallocation.
+ // Disable internal std::string for Apple silicon based Macs
+#if !(defined(__APPLE__) && defined(__arm64__))
#if defined(__GNUC__) && !defined(_LIBCPP_VERSION) \
&& defined(_GLIBCXX_USE_CXX11_ABI) && _GLIBCXX_USE_CXX11_ABI
// NEW gcc ABI
@@ -382,7 +384,7 @@
return;
}
#endif
-
+#endif
// Remaining cases - just assign the internal string. This may result
// in double allocation for the chars. If you care about that, do
// something special for your platform, much like we did for gcc and

View File

@@ -64,12 +64,7 @@ class WindowsCodeSigner(BaseCodeSigner):
def run_codesign_tool(self, filepath: Path) -> None:
command = self.get_sign_command_prefix() + [filepath]
try:
codesign_output = self.check_output_or_mock(command, util.Platform.WINDOWS)
except subprocess.CalledProcessError as e:
raise SigntoolException(f'Error running signtool {e}')
codesign_output = self.check_output_or_mock(command, util.Platform.WINDOWS)
logger_server.info(f'signtool output:\n{codesign_output}')
got_number_of_success = False

View File

@@ -49,7 +49,7 @@ FIND_LIBRARY(PUGIXML_LIBRARY
# handle the QUIETLY and REQUIRED arguments and set PUGIXML_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PugiXML DEFAULT_MSG
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PUGIXML DEFAULT_MSG
PUGIXML_LIBRARY PUGIXML_INCLUDE_DIR)
IF(PUGIXML_FOUND)

View File

@@ -330,9 +330,6 @@ function(gtest_add_tests)
set(gtest_case_name_regex ".*\\( *([A-Za-z_0-9]+) *, *([A-Za-z_0-9]+) *\\).*")
set(gtest_test_type_regex "(TYPED_TEST|TEST_?[FP]?)")
# This will get a filter for each test suite.
set(test_filters "")
foreach(source IN LISTS ARGS_SOURCES)
if(NOT ARGS_SKIP_DEPENDENCY)
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${source})
@@ -379,32 +376,175 @@ function(gtest_add_tests)
list(APPEND testList ${ctest_test_name})
endif()
else()
# BLENDER: collect tests named "suite.testcase" as list of "suite.*" filters.
string(REGEX REPLACE "\\..*$" "" gtest_suite_name ${gtest_test_name})
list(APPEND test_filters "${gtest_suite_name}.*")
set(ctest_test_name ${ARGS_TEST_PREFIX}${gtest_test_name}${ARGS_TEST_SUFFIX})
add_test(NAME ${ctest_test_name}
${workDir}
COMMAND ${ARGS_TARGET}
--gtest_filter=${gtest_test_name}
${ARGS_EXTRA_ARGS}
)
list(APPEND testList ${ctest_test_name})
endif()
endforeach()
endforeach()
# Join all found GTest suite names into one big filter.
list(REMOVE_DUPLICATES test_filters)
list(JOIN test_filters ":" gtest_filter)
add_test(NAME ${ARGS_TEST_PREFIX}
${workDir}
COMMAND ${ARGS_TARGET}
--gtest_filter=${gtest_filter}
${ARGS_EXTRA_ARGS}
)
list(APPEND testList ${ARGS_TEST_PREFIX})
if(ARGS_TEST_LIST)
set(${ARGS_TEST_LIST} ${testList} PARENT_SCOPE)
endif()
endfunction()
# BLENDER: remove the discovery function gtest_discover_tests(). It's not used,
# as it generates too many test invocations.
#------------------------------------------------------------------------------
function(gtest_discover_tests TARGET)
cmake_parse_arguments(
""
"NO_PRETTY_TYPES;NO_PRETTY_VALUES"
"TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;DISCOVERY_TIMEOUT;XML_OUTPUT_DIR;DISCOVERY_MODE"
"EXTRA_ARGS;PROPERTIES"
${ARGN}
)
if(NOT _WORKING_DIRECTORY)
set(_WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
endif()
if(NOT _TEST_LIST)
set(_TEST_LIST ${TARGET}_TESTS)
endif()
if(NOT _DISCOVERY_TIMEOUT)
set(_DISCOVERY_TIMEOUT 5)
endif()
if(NOT _DISCOVERY_MODE)
if(NOT CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE)
set(CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE "POST_BUILD")
endif()
set(_DISCOVERY_MODE ${CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE})
endif()
get_property(
has_counter
TARGET ${TARGET}
PROPERTY CTEST_DISCOVERED_TEST_COUNTER
SET
)
if(has_counter)
get_property(
counter
TARGET ${TARGET}
PROPERTY CTEST_DISCOVERED_TEST_COUNTER
)
math(EXPR counter "${counter} + 1")
else()
set(counter 1)
endif()
set_property(
TARGET ${TARGET}
PROPERTY CTEST_DISCOVERED_TEST_COUNTER
${counter}
)
# Define rule to generate test list for aforementioned test executable
# Blender: use _ instead of [] to avoid problems with zsh regex.
set(ctest_file_base "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_${counter}_")
set(ctest_include_file "${ctest_file_base}_include.cmake")
set(ctest_tests_file "${ctest_file_base}_tests.cmake")
get_property(crosscompiling_emulator
TARGET ${TARGET}
PROPERTY CROSSCOMPILING_EMULATOR
)
if(_DISCOVERY_MODE STREQUAL "POST_BUILD")
add_custom_command(
TARGET ${TARGET} POST_BUILD
BYPRODUCTS "${ctest_tests_file}"
COMMAND "${CMAKE_COMMAND}"
-D "TEST_TARGET=${TARGET}"
-D "TEST_EXECUTABLE=$<TARGET_FILE:${TARGET}>"
-D "TEST_EXECUTOR=${crosscompiling_emulator}"
-D "TEST_WORKING_DIR=${_WORKING_DIRECTORY}"
-D "TEST_EXTRA_ARGS=${_EXTRA_ARGS}"
-D "TEST_PROPERTIES=${_PROPERTIES}"
-D "TEST_PREFIX=${_TEST_PREFIX}"
-D "TEST_SUFFIX=${_TEST_SUFFIX}"
-D "NO_PRETTY_TYPES=${_NO_PRETTY_TYPES}"
-D "NO_PRETTY_VALUES=${_NO_PRETTY_VALUES}"
-D "TEST_LIST=${_TEST_LIST}"
-D "CTEST_FILE=${ctest_tests_file}"
-D "TEST_DISCOVERY_TIMEOUT=${_DISCOVERY_TIMEOUT}"
-D "TEST_XML_OUTPUT_DIR=${_XML_OUTPUT_DIR}"
-P "${_GOOGLETEST_DISCOVER_TESTS_SCRIPT}"
VERBATIM
)
file(WRITE "${ctest_include_file}"
"if(EXISTS \"${ctest_tests_file}\")\n"
" include(\"${ctest_tests_file}\")\n"
"else()\n"
" add_test(${TARGET}_NOT_BUILT ${TARGET}_NOT_BUILT)\n"
"endif()\n"
)
elseif(_DISCOVERY_MODE STREQUAL "PRE_TEST")
get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL
PROPERTY GENERATOR_IS_MULTI_CONFIG
)
if(GENERATOR_IS_MULTI_CONFIG)
set(ctest_tests_file "${ctest_file_base}_tests-$<CONFIG>.cmake")
endif()
string(CONCAT ctest_include_content
"if(EXISTS \"$<TARGET_FILE:${TARGET}>\")" "\n"
" if(\"$<TARGET_FILE:${TARGET}>\" IS_NEWER_THAN \"${ctest_tests_file}\")" "\n"
" include(\"${_GOOGLETEST_DISCOVER_TESTS_SCRIPT}\")" "\n"
" gtest_discover_tests_impl(" "\n"
" TEST_EXECUTABLE" " [==[" "$<TARGET_FILE:${TARGET}>" "]==]" "\n"
" TEST_EXECUTOR" " [==[" "${crosscompiling_emulator}" "]==]" "\n"
" TEST_WORKING_DIR" " [==[" "${_WORKING_DIRECTORY}" "]==]" "\n"
" TEST_EXTRA_ARGS" " [==[" "${_EXTRA_ARGS}" "]==]" "\n"
" TEST_PROPERTIES" " [==[" "${_PROPERTIES}" "]==]" "\n"
" TEST_PREFIX" " [==[" "${_TEST_PREFIX}" "]==]" "\n"
" TEST_SUFFIX" " [==[" "${_TEST_SUFFIX}" "]==]" "\n"
" NO_PRETTY_TYPES" " [==[" "${_NO_PRETTY_TYPES}" "]==]" "\n"
" NO_PRETTY_VALUES" " [==[" "${_NO_PRETTY_VALUES}" "]==]" "\n"
" TEST_LIST" " [==[" "${_TEST_LIST}" "]==]" "\n"
" CTEST_FILE" " [==[" "${ctest_tests_file}" "]==]" "\n"
" TEST_DISCOVERY_TIMEOUT" " [==[" "${_DISCOVERY_TIMEOUT}" "]==]" "\n"
" TEST_XML_OUTPUT_DIR" " [==[" "${_XML_OUTPUT_DIR}" "]==]" "\n"
" )" "\n"
" endif()" "\n"
" include(\"${ctest_tests_file}\")" "\n"
"else()" "\n"
" add_test(${TARGET}_NOT_BUILT ${TARGET}_NOT_BUILT)" "\n"
"endif()" "\n"
)
if(GENERATOR_IS_MULTI_CONFIG)
foreach(_config ${CMAKE_CONFIGURATION_TYPES})
file(GENERATE OUTPUT "${ctest_file_base}_include-${_config}.cmake" CONTENT "${ctest_include_content}" CONDITION $<CONFIG:${_config}>)
endforeach()
file(WRITE "${ctest_include_file}" "include(\"${ctest_file_base}_include-\${CTEST_CONFIGURATION_TYPE}.cmake\")")
else()
file(GENERATE OUTPUT "${ctest_file_base}_include.cmake" CONTENT "${ctest_include_content}")
file(WRITE "${ctest_include_file}" "include(\"${ctest_file_base}_include.cmake\")")
endif()
else()
message(FATAL_ERROR "Unknown DISCOVERY_MODE: ${_DISCOVERY_MODE}")
endif()
# Add discovered tests to directory TEST_INCLUDE_FILES
set_property(DIRECTORY
APPEND PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}"
)
endfunction()
###############################################################################
set(_GOOGLETEST_DISCOVER_TESTS_SCRIPT
${CMAKE_CURRENT_LIST_DIR}/GTestAddTests.cmake
)
# Restore project's policies
cmake_policy(POP)

View File

@@ -0,0 +1,191 @@
# Distributed under the OSI-approved BSD 3-Clause License,
# see accompanying file BSD-3-Clause-license.txt for details.
# Blender: disable ASAN leak detection when trying to discover tests.
set(ENV{ASAN_OPTIONS} "detect_leaks=0")
cmake_minimum_required(VERSION ${CMAKE_VERSION})
# Overwrite possibly existing ${_CTEST_FILE} with empty file
set(flush_tests_MODE WRITE)
# Flushes script to ${_CTEST_FILE}
macro(flush_script)
file(${flush_tests_MODE} "${_CTEST_FILE}" "${script}")
set(flush_tests_MODE APPEND)
set(script "")
endmacro()
# Flushes tests_buffer to tests
macro(flush_tests_buffer)
list(APPEND tests "${tests_buffer}")
set(tests_buffer "")
endmacro()
macro(add_command NAME)
set(_args "")
foreach(_arg ${ARGN})
if(_arg MATCHES "[^-./:a-zA-Z0-9_]")
string(APPEND _args " [==[${_arg}]==]")
else()
string(APPEND _args " ${_arg}")
endif()
endforeach()
string(APPEND script "${NAME}(${_args})\n")
string(LENGTH "${script}" _script_len)
if(${_script_len} GREATER "50000")
flush_script()
endif()
# Unsets macro local variables to prevent leakage outside of this macro.
unset(_args)
unset(_script_len)
endmacro()
function(gtest_discover_tests_impl)
cmake_parse_arguments(
""
""
"NO_PRETTY_TYPES;NO_PRETTY_VALUES;TEST_EXECUTABLE;TEST_EXECUTOR;TEST_WORKING_DIR;TEST_PREFIX;TEST_SUFFIX;TEST_LIST;CTEST_FILE;TEST_DISCOVERY_TIMEOUT;TEST_XML_OUTPUT_DIR"
"TEST_EXTRA_ARGS;TEST_PROPERTIES"
${ARGN}
)
set(prefix "${_TEST_PREFIX}")
set(suffix "${_TEST_SUFFIX}")
set(extra_args ${_TEST_EXTRA_ARGS})
set(properties ${_TEST_PROPERTIES})
set(script)
set(suite)
set(tests)
set(tests_buffer)
# Run test executable to get list of available tests
if(NOT EXISTS "${_TEST_EXECUTABLE}")
message(FATAL_ERROR
"Specified test executable does not exist.\n"
" Path: '${_TEST_EXECUTABLE}'"
)
endif()
execute_process(
COMMAND ${_TEST_EXECUTOR} "${_TEST_EXECUTABLE}" --gtest_list_tests
WORKING_DIRECTORY "${_TEST_WORKING_DIR}"
TIMEOUT ${_TEST_DISCOVERY_TIMEOUT}
OUTPUT_VARIABLE output
RESULT_VARIABLE result
)
if(NOT ${result} EQUAL 0)
string(REPLACE "\n" "\n " output "${output}")
message(FATAL_ERROR
"Error running test executable.\n"
" Path: '${_TEST_EXECUTABLE}'\n"
" Result: ${result}\n"
" Output:\n"
" ${output}\n"
)
endif()
# Preserve semicolon in test-parameters
string(REPLACE [[;]] [[\;]] output "${output}")
string(REPLACE "\n" ";" output "${output}")
# Parse output
foreach(line ${output})
# Skip header
if(NOT line MATCHES "gtest_main\\.cc")
# Do we have a module name or a test name?
if(NOT line MATCHES "^ ")
# Module; remove trailing '.' to get just the name...
string(REGEX REPLACE "\\.( *#.*)?" "" suite "${line}")
if(line MATCHES "#" AND NOT _NO_PRETTY_TYPES)
string(REGEX REPLACE "/[0-9]\\.+ +#.*= +" "/" pretty_suite "${line}")
else()
set(pretty_suite "${suite}")
endif()
string(REGEX REPLACE "^DISABLED_" "" pretty_suite "${pretty_suite}")
else()
# Test name; strip spaces and comments to get just the name...
string(REGEX REPLACE " +" "" test "${line}")
if(test MATCHES "#" AND NOT _NO_PRETTY_VALUES)
string(REGEX REPLACE "/[0-9]+#GetParam..=" "/" pretty_test "${test}")
else()
string(REGEX REPLACE "#.*" "" pretty_test "${test}")
endif()
string(REGEX REPLACE "^DISABLED_" "" pretty_test "${pretty_test}")
string(REGEX REPLACE "#.*" "" test "${test}")
if(NOT "${_TEST_XML_OUTPUT_DIR}" STREQUAL "")
set(TEST_XML_OUTPUT_PARAM "--gtest_output=xml:${_TEST_XML_OUTPUT_DIR}/${prefix}${suite}.${test}${suffix}.xml")
else()
unset(TEST_XML_OUTPUT_PARAM)
endif()
# sanitize test name for further processing downstream
set(testname "${prefix}${pretty_suite}.${pretty_test}${suffix}")
# escape \
string(REPLACE [[\]] [[\\]] testname "${testname}")
# escape ;
string(REPLACE [[;]] [[\;]] testname "${testname}")
# escape $
string(REPLACE [[$]] [[\$]] testname "${testname}")
# ...and add to script
add_command(add_test
"${testname}"
${_TEST_EXECUTOR}
"${_TEST_EXECUTABLE}"
"--gtest_filter=${suite}.${test}"
"--gtest_also_run_disabled_tests"
${TEST_XML_OUTPUT_PARAM}
${extra_args}
)
if(suite MATCHES "^DISABLED" OR test MATCHES "^DISABLED")
add_command(set_tests_properties
"${testname}"
PROPERTIES DISABLED TRUE
)
endif()
add_command(set_tests_properties
"${testname}"
PROPERTIES
WORKING_DIRECTORY "${_TEST_WORKING_DIR}"
SKIP_REGULAR_EXPRESSION "\\\\[ SKIPPED \\\\]"
${properties}
)
list(APPEND tests_buffer "${testname}")
list(LENGTH tests_buffer tests_buffer_length)
if(${tests_buffer_length} GREATER "250")
flush_tests_buffer()
endif()
endif()
endif()
endforeach()
# Create a list of all discovered tests, which users may use to e.g. set
# properties on the tests
flush_tests_buffer()
add_command(set ${_TEST_LIST} ${tests})
# Write CTest script
flush_script()
endfunction()
if(CMAKE_SCRIPT_MODE_FILE)
gtest_discover_tests_impl(
NO_PRETTY_TYPES ${NO_PRETTY_TYPES}
NO_PRETTY_VALUES ${NO_PRETTY_VALUES}
TEST_EXECUTABLE ${TEST_EXECUTABLE}
TEST_EXECUTOR ${TEST_EXECUTOR}
TEST_WORKING_DIR ${TEST_WORKING_DIR}
TEST_PREFIX ${TEST_PREFIX}
TEST_SUFFIX ${TEST_SUFFIX}
TEST_LIST ${TEST_LIST}
CTEST_FILE ${CTEST_FILE}
TEST_DISCOVERY_TIMEOUT ${TEST_DISCOVERY_TIMEOUT}
TEST_XML_OUTPUT_DIR ${TEST_XML_OUTPUT_DIR}
TEST_EXTRA_ARGS ${TEST_EXTRA_ARGS}
TEST_PROPERTIES ${TEST_PROPERTIES}
)
endif()

View File

@@ -8,17 +8,6 @@
#
#=============================================================================
function(GET_BLENDER_TEST_INSTALL_DIR VARIABLE_NAME)
get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(GENERATOR_IS_MULTI_CONFIG)
string(REPLACE "\${BUILD_TYPE}" "$<CONFIG>" TEST_INSTALL_DIR ${CMAKE_INSTALL_PREFIX})
else()
string(REPLACE "\${BUILD_TYPE}" "" TEST_INSTALL_DIR ${CMAKE_INSTALL_PREFIX})
endif()
set(${VARIABLE_NAME} "${TEST_INSTALL_DIR}" PARENT_SCOPE)
endfunction()
macro(BLENDER_SRC_GTEST_EX)
if(WITH_GTESTS)
set(options SKIP_ADD_TEST)
@@ -86,7 +75,13 @@ macro(BLENDER_SRC_GTEST_EX)
target_link_libraries(${TARGET_NAME} ${GMP_LIBRARIES})
endif()
GET_BLENDER_TEST_INSTALL_DIR(TEST_INSTALL_DIR)
get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(GENERATOR_IS_MULTI_CONFIG)
string(REPLACE "\${BUILD_TYPE}" "$<CONFIG>" TEST_INSTALL_DIR ${CMAKE_INSTALL_PREFIX})
else()
string(REPLACE "\${BUILD_TYPE}" "" TEST_INSTALL_DIR ${CMAKE_INSTALL_PREFIX})
endif()
set_target_properties(${TARGET_NAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${TESTS_OUTPUT_DIR}"
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${TESTS_OUTPUT_DIR}"

View File

@@ -13,7 +13,7 @@ Invocation:
export CLANG_BIND_DIR="/dsk/src/llvm/tools/clang/bindings/python"
export CLANG_LIB_DIR="/opt/llvm/lib"
python clang_array_check.py somefile.c -DSOME_DEFINE -I/some/include
python2 clang_array_check.py somefile.c -DSOME_DEFINE -I/some/include
... defines and includes are optional
@@ -76,32 +76,6 @@ defs_precalc = {
"glNormal3bv": {0: 3},
"glNormal3iv": {0: 3},
"glNormal3sv": {0: 3},
# GPU immediate mode.
"immVertex2iv": {1: 2},
"immVertex2fv": {1: 2},
"immVertex3fv": {1: 3},
"immAttr2fv": {1: 2},
"immAttr3fv": {1: 3},
"immAttr4fv": {1: 4},
"immAttr3ubv": {1: 3},
"immAttr4ubv": {1: 4},
"immUniform2fv": {1: 2},
"immUniform3fv": {1: 3},
"immUniform4fv": {1: 4},
"immUniformColor3fv": {0: 3},
"immUniformColor4fv": {0: 4},
"immUniformColor3ubv": {1: 3},
"immUniformColor4ubv": {1: 4},
"immUniformColor3fvAlpha": {0: 3},
"immUniformColor4fvAlpha": {0: 4},
}
# -----------------------------------------------------------------------------
@@ -126,8 +100,7 @@ else:
if CLANG_LIB_DIR is None:
print("$CLANG_LIB_DIR clang lib dir not set")
if CLANG_BIND_DIR:
sys.path.append(CLANG_BIND_DIR)
sys.path.append(CLANG_BIND_DIR)
import clang
import clang.cindex
@@ -135,8 +108,7 @@ from clang.cindex import (CursorKind,
TypeKind,
TokenKind)
if CLANG_LIB_DIR:
clang.cindex.Config.set_library_path(CLANG_LIB_DIR)
clang.cindex.Config.set_library_path(CLANG_LIB_DIR)
index = clang.cindex.Index.create()

View File

@@ -32,7 +32,7 @@ CHECKER_IGNORE_PREFIX = [
"intern/moto",
]
CHECKER_BIN = "python3"
CHECKER_BIN = "python2"
CHECKER_ARGS = [
os.path.join(os.path.dirname(__file__), "clang_array_check.py"),

View File

@@ -388,43 +388,6 @@ function(blender_add_lib
set_property(GLOBAL APPEND PROPERTY BLENDER_LINK_LIBS ${name})
endfunction()
function(blender_add_test_suite)
if (ARGC LESS 1)
message(FATAL_ERROR "No arguments supplied to blender_add_test_suite()")
endif()
# Parse the arguments
set(oneValueArgs TARGET SUITE_NAME)
set(multiValueArgs SOURCES)
cmake_parse_arguments(ARGS "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
# Figure out the release dir, as some tests need files from there.
GET_BLENDER_TEST_INSTALL_DIR(TEST_INSTALL_DIR)
if(APPLE)
set(_test_release_dir ${TEST_INSTALL_DIR}/Blender.app/Contents/Resources/${BLENDER_VERSION})
else()
if(WIN32 OR WITH_INSTALL_PORTABLE)
set(_test_release_dir ${TEST_INSTALL_DIR}/${BLENDER_VERSION})
else()
set(_test_release_dir ${TEST_INSTALL_DIR}/share/blender/${BLENDER_VERSION})
endif()
endif()
# Define a test case with our custom gtest_add_tests() command.
include(GTest)
gtest_add_tests(
TARGET ${ARGS_TARGET}
SOURCES "${ARGS_SOURCES}"
TEST_PREFIX ${ARGS_SUITE_NAME}
WORKING_DIRECTORY "${TEST_INSTALL_DIR}"
EXTRA_ARGS
--test-assets-dir "${CMAKE_SOURCE_DIR}/../lib/tests"
--test-release-dir "${_test_release_dir}"
)
unset(_test_release_dir)
endfunction()
# Add tests for a Blender library, to be called in tandem with blender_add_lib().
# The tests will be part of the blender_test executable (see tests/gtests/runner).
function(blender_add_test_lib
@@ -458,12 +421,6 @@ function(blender_add_test_lib
blender_add_lib__impl(${name} "${sources}" "${includes}" "${includes_sys}" "${library_deps}")
set_property(GLOBAL APPEND PROPERTY BLENDER_TEST_LIBS ${name})
blender_add_test_suite(
TARGET blender_test
SUITE_NAME ${name}
SOURCES "${sources}"
)
endfunction()
@@ -497,10 +454,14 @@ function(blender_add_test_executable
SKIP_ADD_TEST
)
blender_add_test_suite(
TARGET ${name}_test
SUITE_NAME ${name}
SOURCES "${sources}"
include(GTest)
set(_GOOGLETEST_DISCOVER_TESTS_SCRIPT
${CMAKE_SOURCE_DIR}/build_files/cmake/Modules/GTestAddTests.cmake
)
gtest_discover_tests(${name}_test
DISCOVERY_MODE PRE_TEST
WORKING_DIRECTORY "${TEST_INSTALL_DIR}"
)
endfunction()
@@ -1178,7 +1139,6 @@ endfunction()
function(find_python_package
package
relative_include_dir
)
string(TOUPPER ${package} _upper_package)
@@ -1210,10 +1170,7 @@ function(find_python_package
dist-packages
vendor-packages
NO_DEFAULT_PATH
DOC
"Path to python site-packages or dist-packages containing '${package}' module"
)
mark_as_advanced(PYTHON_${_upper_package}_PATH)
if(NOT EXISTS "${PYTHON_${_upper_package}_PATH}")
message(WARNING
@@ -1231,50 +1188,6 @@ function(find_python_package
set(WITH_PYTHON_INSTALL_${_upper_package} OFF PARENT_SCOPE)
else()
message(STATUS "${package} found at '${PYTHON_${_upper_package}_PATH}'")
if(NOT "${relative_include_dir}" STREQUAL "")
set(_relative_include_dir "${package}/${relative_include_dir}")
unset(PYTHON_${_upper_package}_INCLUDE_DIRS CACHE)
find_path(PYTHON_${_upper_package}_INCLUDE_DIRS
NAMES
"${_relative_include_dir}"
HINTS
"${PYTHON_LIBPATH}/"
"${PYTHON_LIBPATH}/python${PYTHON_VERSION}/"
"${PYTHON_LIBPATH}/python${_PY_VER_MAJOR}/"
PATH_SUFFIXES
"site-packages/"
"dist-packages/"
"vendor-packages/"
NO_DEFAULT_PATH
DOC
"Path to python site-packages or dist-packages containing '${package}' module header files"
)
mark_as_advanced(PYTHON_${_upper_package}_INCLUDE_DIRS)
if(NOT EXISTS "${PYTHON_${_upper_package}_INCLUDE_DIRS}")
message(WARNING
"Python package '${package}' include dir path could not be found in:\n"
"'${PYTHON_LIBPATH}/python${PYTHON_VERSION}/site-packages/${_relative_include_dir}', "
"'${PYTHON_LIBPATH}/python${_PY_VER_MAJOR}/site-packages/${_relative_include_dir}', "
"'${PYTHON_LIBPATH}/python${PYTHON_VERSION}/dist-packages/${_relative_include_dir}', "
"'${PYTHON_LIBPATH}/python${_PY_VER_MAJOR}/dist-packages/${_relative_include_dir}', "
"'${PYTHON_LIBPATH}/python${PYTHON_VERSION}/vendor-packages/${_relative_include_dir}', "
"'${PYTHON_LIBPATH}/python${_PY_VER_MAJOR}/vendor-packages/${_relative_include_dir}', "
"\n"
"The 'WITH_PYTHON_${_upper_package}' option will be disabled.\n"
"The build will be usable, only add-ons that depend on this package won't be functional."
)
set(WITH_PYTHON_${_upper_package} OFF PARENT_SCOPE)
else()
set(_temp "${PYTHON_${_upper_package}_INCLUDE_DIRS}/${package}/${relative_include_dir}")
unset(PYTHON_${_upper_package}_INCLUDE_DIRS CACHE)
set(PYTHON_${_upper_package}_INCLUDE_DIRS "${_temp}"
CACHE PATH "Path to the include directory of the ${package} module")
message(STATUS "${package} include files found at '${PYTHON_${_upper_package}_INCLUDE_DIRS}'")
endif()
endif()
endif()
endif()
endfunction()

View File

@@ -73,6 +73,9 @@ endif()
if(NOT DEFINED LIBDIR)
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin)
# Prefer lib directory paths
file(GLOB LIB_SUBDIRS ${LIBDIR}/*)
set(CMAKE_PREFIX_PATH ${LIB_SUBDIRS})
else()
message(STATUS "Using pre-compiled LIBDIR: ${LIBDIR}")
endif()
@@ -80,10 +83,6 @@ if(NOT EXISTS "${LIBDIR}/")
message(FATAL_ERROR "Mac OSX requires pre-compiled libs at: '${LIBDIR}'")
endif()
# Prefer lib directory paths
file(GLOB LIB_SUBDIRS ${LIBDIR}/*)
set(CMAKE_PREFIX_PATH ${LIB_SUBDIRS})
# -------------------------------------------------------------------------
# Find precompiled libraries, and avoid system or user-installed ones.
@@ -270,14 +269,6 @@ if(WITH_INTERNATIONAL OR WITH_CODEC_FFMPEG)
string(APPEND PLATFORM_LINKFLAGS " -liconv") # boost_locale and ffmpeg needs it !
endif()
if(WITH_PUGIXML)
find_package(PugiXML)
if(NOT PUGIXML_FOUND)
message(WARNING "PugiXML not found, disabling WITH_PUGIXML")
set(WITH_PUGIXML OFF)
endif()
endif()
if(WITH_OPENIMAGEIO)
find_package(OpenImageIO)
list(APPEND OPENIMAGEIO_LIBRARIES
@@ -346,7 +337,7 @@ if(WITH_CYCLES_EMBREE)
find_package(Embree 3.8.0 REQUIRED)
# Increase stack size for Embree, only works for executables.
if(NOT WITH_PYTHON_MODULE)
string(APPEND PLATFORM_LINKFLAGS " -Wl,-stack_size,0x100000")
string(APPEND PLATFORM_LINKFLAGS " -Xlinker -stack_size -Xlinker 0x100000")
endif()
# Embree static library linking can mix up SSE and AVX symbols, causing
@@ -458,8 +449,8 @@ endif()
# Avoid conflicts with Luxrender, and other plug-ins that may use the same
# libraries as Blender with a different version or build options.
string(APPEND PLATFORM_LINKFLAGS
" -Wl,-unexported_symbols_list,'${CMAKE_SOURCE_DIR}/source/creator/osx_locals.map'"
set(PLATFORM_LINKFLAGS
"${PLATFORM_LINKFLAGS} -Xlinker -unexported_symbols_list -Xlinker '${CMAKE_SOURCE_DIR}/source/creator/osx_locals.map'"
)
string(APPEND CMAKE_CXX_FLAGS " -stdlib=libc++")
@@ -470,17 +461,3 @@ set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
set(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
set(CMAKE_CXX_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
if(WITH_COMPILER_CCACHE)
if(NOT CMAKE_GENERATOR STREQUAL "Xcode")
find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
# Makefiles and ninja
set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}" CACHE STRING "" FORCE)
set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}" CACHE STRING "" FORCE)
else()
message(WARNING "Ccache NOT found, disabling WITH_COMPILER_CCACHE")
set(WITH_COMPILER_CCACHE OFF)
endif()
endif()
endif()

View File

@@ -154,32 +154,3 @@ if(NOT ${CMAKE_GENERATOR} MATCHES "Xcode")
string(APPEND CMAKE_CXX_FLAGS " -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}")
add_definitions("-DMACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}")
endif()
if(WITH_COMPILER_CCACHE)
if(CMAKE_GENERATOR STREQUAL "Xcode")
find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
get_filename_component(ccompiler "${CMAKE_C_COMPILER}" NAME)
get_filename_component(cxxcompiler "${CMAKE_CXX_COMPILER}" NAME)
# Ccache can figure out which compiler to use if it's invoked from
# a symlink with the name of the compiler.
# https://ccache.dev/manual/4.1.html#_run_modes
set(_fake_compiler_dir "${CMAKE_BINARY_DIR}/ccache")
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${_fake_compiler_dir})
set(_fake_C_COMPILER "${_fake_compiler_dir}/${ccompiler}")
set(_fake_CXX_COMPILER "${_fake_compiler_dir}/${cxxcompiler}")
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${CCACHE_PROGRAM}" ${_fake_C_COMPILER})
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${CCACHE_PROGRAM}" ${_fake_CXX_COMPILER})
set(CMAKE_XCODE_ATTRIBUTE_CC ${_fake_C_COMPILER} CACHE STRING "" FORCE)
set(CMAKE_XCODE_ATTRIBUTE_CXX ${_fake_CXX_COMPILER} CACHE STRING "" FORCE)
set(CMAKE_XCODE_ATTRIBUTE_LD ${_fake_C_COMPILER} CACHE STRING "" FORCE)
set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS ${_fake_CXX_COMPILER} CACHE STRING "" FORCE)
unset(_fake_compiler_dir)
unset(_fake_C_COMPILER)
unset(_fake_CXX_COMPILER)
else()
message(WARNING "Ccache NOT found, disabling WITH_COMPILER_CCACHE")
set(WITH_COMPILER_CCACHE OFF)
endif()
endif()
endif()

View File

@@ -350,12 +350,15 @@ if(WITH_BOOST)
endif()
endif()
if(WITH_PUGIXML)
find_package_wrapper(PugiXML)
endif()
if(WITH_OPENIMAGEIO)
find_package_wrapper(OpenImageIO)
if(NOT OPENIMAGEIO_PUGIXML_FOUND AND WITH_CYCLES_STANDALONE)
find_package_wrapper(PugiXML)
else()
set(PUGIXML_INCLUDE_DIR "${OPENIMAGEIO_INCLUDE_DIR/OpenImageIO}")
set(PUGIXML_LIBRARIES "")
endif()
set(OPENIMAGEIO_LIBRARIES
${OPENIMAGEIO_LIBRARIES}
${PNG_LIBRARIES}
@@ -684,15 +687,3 @@ set(PLATFORM_LINKFLAGS
if(WITH_INSTALL_PORTABLE)
string(APPEND CMAKE_EXE_LINKER_FLAGS " -no-pie")
endif()
if(WITH_COMPILER_CCACHE)
find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
# Makefiles and ninja
set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}" CACHE STRING "" FORCE)
set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}" CACHE STRING "" FORCE)
else()
message(WARNING "Ccache NOT found, disabling WITH_COMPILER_CCACHE")
set(WITH_COMPILER_CCACHE OFF)
endif()
endif()

View File

@@ -239,24 +239,9 @@ if(NOT EXISTS "${LIBDIR}/")
message(FATAL_ERROR "\n\nWindows requires pre-compiled libs at: '${LIBDIR}'. Please run `make update` in the blender source folder to obtain them.")
endif()
if(CMAKE_GENERATOR MATCHES "^Visual Studio.+" AND # Only supported in the VS IDE
MSVC_VERSION GREATER_EQUAL 1924 AND # Supported for 16.4+
WITH_CLANG_TIDY # And Clang Tidy needs to be on
)
set(CMAKE_VS_GLOBALS
"RunCodeAnalysis=false"
"EnableMicrosoftCodeAnalysis=false"
"EnableClangTidyCodeAnalysis=true"
)
set(VS_CLANG_TIDY On)
endif()
# Mark libdir as system headers with a lower warn level, to resolve some warnings
# that we have very little control over
if(MSVC_VERSION GREATER_EQUAL 1914 AND # Available with 15.7+
NOT MSVC_CLANG AND # But not for clang
NOT WITH_WINDOWS_SCCACHE AND # And not when sccache is enabled
NOT VS_CLANG_TIDY) # Clang-tidy does not like these options
if(MSVC_VERSION GREATER_EQUAL 1914 AND NOT MSVC_CLANG AND NOT WITH_WINDOWS_SCCACHE)
add_compile_options(/experimental:external /external:templates- /external:I "${LIBDIR}" /external:W0)
endif()
@@ -268,11 +253,6 @@ foreach(child ${children})
endif()
endforeach()
if(WITH_PUGIXML)
set(PUGIXML_LIBRARIES optimized ${LIBDIR}/pugixml/lib/pugixml.lib debug ${LIBDIR}/pugixml/lib/pugixml_d.lib)
set(PUGIXML_INCLUDE_DIR ${LIBDIR}/pugixml/include)
endif()
set(ZLIB_INCLUDE_DIRS ${LIBDIR}/zlib/include)
set(ZLIB_LIBRARIES ${LIBDIR}/zlib/lib/libz_st.lib)
set(ZLIB_INCLUDE_DIR ${LIBDIR}/zlib/include)
@@ -671,10 +651,11 @@ if(WITH_CYCLES_OSL)
optimized ${OSL_LIB_COMP}
optimized ${OSL_LIB_EXEC}
optimized ${OSL_LIB_QUERY}
optimized ${CYCLES_OSL}/lib/pugixml.lib
debug ${OSL_LIB_EXEC_DEBUG}
debug ${OSL_LIB_COMP_DEBUG}
debug ${OSL_LIB_QUERY_DEBUG}
${PUGIXML_LIBRARIES}
debug ${CYCLES_OSL}/lib/pugixml_d.lib
)
find_path(OSL_INCLUDE_DIR OSL/oslclosure.h PATHS ${CYCLES_OSL}/include)
find_program(OSL_COMPILER NAMES oslc PATHS ${CYCLES_OSL}/bin)
@@ -739,7 +720,7 @@ if(WINDOWS_PYTHON_DEBUG)
string(REPLACE "/" "\\" _group_path "${_source_path}")
source_group("${_group_path}" FILES "${_source}")
endforeach()
# If the user scripts env var is set, include scripts from there otherwise
# include user scripts in the profile folder.
if(DEFINED ENV{BLENDER_USER_SCRIPTS})
@@ -750,7 +731,7 @@ if(WINDOWS_PYTHON_DEBUG)
# Include the user scripts from the profile folder in the blender_python_user_scripts project.
set(USER_SCRIPTS_ROOT "$ENV{appdata}/blender foundation/blender/${BLENDER_VERSION}/scripts")
endif()
file(TO_CMAKE_PATH ${USER_SCRIPTS_ROOT} USER_SCRIPTS_ROOT)
FILE(GLOB_RECURSE inFiles "${USER_SCRIPTS_ROOT}/*.*" )
ADD_CUSTOM_TARGET(blender_python_user_scripts SOURCES ${inFiles})

View File

@@ -92,5 +92,5 @@ echo if "%%VSCMD_VER%%" == "" ^( >> %BUILD_DIR%\rebuild.cmd
echo call "%VCVARS%" %BUILD_ARCH% >> %BUILD_DIR%\rebuild.cmd
echo ^) >> %BUILD_DIR%\rebuild.cmd
echo echo %%TIME%% ^> buildtime.txt >> %BUILD_DIR%\rebuild.cmd
echo ninja install %%* >> %BUILD_DIR%\rebuild.cmd
echo ninja install >> %BUILD_DIR%\rebuild.cmd
echo echo %%TIME%% ^>^> buildtime.txt >> %BUILD_DIR%\rebuild.cmd

View File

@@ -453,7 +453,7 @@ TYPEDEF_HIDES_STRUCT = NO
# the optimal cache size from a speed point of view.
# Minimum value: 0, maximum value: 9, default value: 0.
LOOKUP_CACHE_SIZE = 3
LOOKUP_CACHE_SIZE = 0
#---------------------------------------------------------------------------
# Build related configuration options
@@ -1321,7 +1321,7 @@ DOCSET_PUBLISHER_NAME = Publisher
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
GENERATE_HTMLHELP = NO
GENERATE_HTMLHELP = YES
# The CHM_FILE tag can be used to specify the file name of the resulting .chm
# file. You can add a path in front of the file if the result should not be

View File

@@ -121,10 +121,6 @@
* \ingroup editors
*/
/** \defgroup edasset asset
* \ingroup editors
*/
/** \defgroup edcurve curve
* \ingroup editors
*/

View File

@@ -1,30 +0,0 @@
"""
.. note::
Properties defined at run-time store the values of the properties as custom-properties.
This method checks if the underlying data exists, causing the property to be considered *set*.
A common pattern for operators is to calculate a value for the properties
that have not had their values explicitly set by the caller
(where the caller could be a key-binding, menu-items or Python script for example).
In the case of executing operators multiple times, values are re-used from the previous execution.
For example: subdividing a mesh with a smooth value of 1.0 will keep using
that value on subsequent calls to subdivision, unless the operator is called with
that property set to a different value.
This behavior can be disabled using the ``SKIP_SAVE`` option when the property is declared (see: :mod:`bpy.props`).
The ``ghost`` argument allows detecting how a value from a previous execution is handled.
- When true: The property is considered unset even if the value from a previous call is used.
- When false: The existence of any values causes ``is_property_set`` to return true.
While this argument should typically be omitted, there are times when
it's important to know if a value is anything besides the default.
For example, the previous value may have been scaled by the scene's unit scale.
In this case scaling the value multiple times would cause problems, so the ``ghost`` argument should be false.
"""

View File

@@ -163,13 +163,13 @@ Now in the button's context menu select *Copy Data Path*, then paste the result
.. code-block:: python
bpy.context.active_object.modifiers["Subdivision"].levels
bpy.context.active_object.modifiers["Subsurf"].levels
Press :kbd:`Return` and you'll get the current value of 1. Now try changing the value to 2:
.. code-block:: python
bpy.context.active_object.modifiers["Subdivision"].levels = 2
bpy.context.active_object.modifiers["Subsurf"].levels = 2
You can see the value update in the Subdivision Surface modifier's UI as well as the cube.
@@ -185,31 +185,43 @@ For example, if you want to access the texture of a brush via Python to adjust i
#. Start in the default scene and enable Sculpt Mode from the 3D Viewport header.
#. From the Sidebar expand the Brush Settings panel's *Texture* subpanel and add a new texture.
*Notice the texture data-block menu itself doesn't have very useful links (you can check the tooltips).*
#. The contrast setting isn't exposed in the Sidebar, so view the texture in the
:ref:`Properties Editor <blender_manual:bpy.types.Texture.contrast`
#. The contrast setting isn't exposed in the Sidebar, so view the texture in the properties editor:
- In the properties editor select the Texture tab.
- Select brush texture.
- Expand the *Colors* panel to locate the *Contrast* number field.
#. Open the context menu of the contrast field and select *Online Python Reference*.
This takes you to ``bpy.types.Texture.contrast``. Now you can see that ``contrast`` is a property of texture.
#. To find out how to access the texture from the brush check on the references at the bottom of the page.
Sometimes there are many references, and it may take some guesswork to find the right one,
but in this case it's ``tool_settings.sculpt.brush.texture``.
but in this case it's ``Brush.texture``.
#. Now you know that the texture can be accessed from ``bpy.data.brushes["BrushName"].texture``
but normally you *won't* want to access the brush by name, instead you want to access the active brush.
So the next step is to check on where brushes are accessed from via the references.
In this case there it is simply ``bpy.context.brush``.
Now you can use the Python console to form the nested properties needed to access brush textures contrast:
:menuselection:`Context --> Tool Settings --> Sculpt --> Brush --> Texture --> Contrast`.
*Context -> Brush -> Texture -> Contrast*.
Since the attribute for each is given along the way you can compose the data path in the Python console:
.. code-block:: python
bpy.context.tool_settings.sculpt.brush.texture.contrast
bpy.context.brush.texture.contrast
There can be multiple ways to access the same data, which you choose often depends on the task.
An alternate path to access the same setting is:
.. code-block:: python
bpy.context.sculpt.brush.texture.contrast
Or access the brush directly:
.. code-block:: python
bpy.data.textures["Texture"].contrast
bpy.data.brushes["BrushName"].texture.contrast
If you are writing a user tool normally you want to use the :mod:`bpy.context` since the user normally expects

View File

@@ -35,13 +35,12 @@ but not to fully cover each topic.
A quick list of helpful things to know before starting:
- Enable :ref:`Developer Extra <blender_manual:prefs-interface-dev-extras`
and :ref:`Python Tooltips <blender_manual:prefs-interface-tooltips-python>`.
- The :ref:`Python Console <blender_manual:bpy.types.SpaceConsole>`
is great for testing one-liners; it has autocompletion so you can inspect the API quickly.
- Button tooltips show Python attributes and operator names (when enabled see above).
- The context menu of buttons directly links to this API documentation (when enabled see above).
- Many python examples can be found in the text editor's template menu.
- Blender uses Python 3.x; some online documentation still assumes version 2.x.
- The interactive console is great for testing one-liners.
It also has autocompletion so you can inspect the API quickly.
- Button tooltips show Python attributes and operator names.
- The context menu of buttons directly links to this API documentation.
- More operator examples can be found in the text editor's template menu.
- To examine further scripts distributed with Blender, see:
- ``scripts/startup/bl_ui`` for the user interface.
@@ -238,7 +237,7 @@ Examples:
{'FINISHED'}
>>> bpy.ops.mesh.hide(unselected=False)
{'FINISHED'}
>>> bpy.ops.object.transform_apply()
>>> bpy.ops.object.scale_apply()
{'FINISHED'}
.. tip::

View File

@@ -24,9 +24,10 @@ The three main use cases for the terminal are:
- If the script runs for too long or you accidentally enter an infinite loop,
:kbd:`Ctrl-C` in the terminal (:kbd:`Ctrl-Break` on Windows) will quit the script early.
.. seealso::
.. note::
:ref:`blender_manual:command_line-launch-index`.
For Linux and macOS users this means starting the terminal first, then running Blender from within it.
On Windows the terminal can be enabled from the Help menu.
Interface Tricks

View File

@@ -551,7 +551,7 @@ def example_extract_docstring(filepath):
file.close()
return "", 0
for line in file:
for line in file.readlines():
line_no += 1
if line.startswith('"""'):
break
@@ -559,13 +559,6 @@ def example_extract_docstring(filepath):
text.append(line.rstrip())
line_no += 1
# Skip over blank lines so the Python code doesn't have blank lines at the top.
for line in file:
if line.strip():
break
line_no += 1
file.close()
return "\n".join(text), line_no
@@ -2195,20 +2188,9 @@ def setup_blender():
# Remove handlers since the functions get included
# in the doc-string and don't have meaningful names.
lists_to_restore = []
for var in bpy.app.handlers:
if isinstance(var, list):
lists_to_restore.append((var[:], var))
var.clear()
return {
"lists_to_restore": lists_to_restore,
}
def teardown_blender(setup_data):
for var_src, var_dst in setup_data["lists_to_restore"]:
var_dst[:] = var_src
for ls in bpy.app.handlers:
if isinstance(ls, list):
ls.clear()
def main():
@@ -2217,7 +2199,7 @@ def main():
setup_monkey_patch()
# Perform changes to Blender it's self.
setup_data = setup_blender()
setup_blender()
# eventually, create the dirs
for dir_path in [ARGS.output_dir, SPHINX_IN]:
@@ -2323,8 +2305,6 @@ def main():
shutil.copy(os.path.join(SPHINX_OUT_PDF, "contents.pdf"),
os.path.join(REFERENCE_PATH, BLENDER_PDF_FILENAME))
teardown_blender(setup_data)
sys.exit()

View File

@@ -1,5 +1,7 @@
/* T76453: Prevent Long enum lists */
.field-list li {
/* Prevent Long enum lists */
.field-body {
display: block;
width: 100%;
max-height: 245px;
overflow-y: auto !important;
}

4
extern/README vendored
View File

@@ -1,4 +0,0 @@
When updating a library remember to:
* Update the README.blender with the corresponding version.
* Update the THIRD-PARTY-LICENSE.txt document

View File

@@ -1,5 +0,0 @@
Project: Audaspace
URL: https://audaspace.github.io/
License: Apache 2.0
Upstream version: 1.3 (Last Release)
Local modifications: None

View File

@@ -24,6 +24,6 @@ set(JACK_FOUND ${WITH_JACK})
set(LIBSNDFILE_FOUND ${WITH_CODEC_SNDFILE})
set(OPENAL_FOUND ${WITH_OPENAL})
set(PYTHONLIBS_FOUND TRUE)
set(NUMPY_FOUND ${WITH_PYTHON_NUMPY})
set(NUMPY_FOUND TRUE)
set(NUMPY_INCLUDE_DIRS ${PYTHON_NUMPY_INCLUDE_DIRS})
set(SDL_FOUND ${WITH_SDL})

View File

@@ -72,9 +72,6 @@ protected:
/// The channel mapper reader in between.
std::shared_ptr<ChannelMapperReader> m_mapper;
/// Whether the source is being read for the first time.
bool m_first_reading;
/// Whether to keep the source if end of it is reached.
bool m_keep;

View File

@@ -78,7 +78,7 @@ bool SoftwareDevice::SoftwareHandle::pause(bool keep)
}
SoftwareDevice::SoftwareHandle::SoftwareHandle(SoftwareDevice* device, std::shared_ptr<IReader> reader, std::shared_ptr<PitchReader> pitch, std::shared_ptr<ResampleReader> resampler, std::shared_ptr<ChannelMapperReader> mapper, bool keep) :
m_reader(reader), m_pitch(pitch), m_resampler(resampler), m_mapper(mapper), m_first_reading(true), m_keep(keep), m_user_pitch(1.0f), m_user_volume(1.0f), m_user_pan(0.0f), m_volume(0.0f), m_old_volume(0.0f), m_loopcount(0),
m_reader(reader), m_pitch(pitch), m_resampler(resampler), m_mapper(mapper), m_keep(keep), m_user_pitch(1.0f), m_user_volume(1.0f), m_user_pan(0.0f), m_volume(0.0f), m_old_volume(0.0f), m_loopcount(0),
m_relative(true), m_volume_max(1.0f), m_volume_min(0), m_distance_max(std::numeric_limits<float>::max()),
m_distance_reference(1.0f), m_attenuation(1.0f), m_cone_angle_outer(M_PI), m_cone_angle_inner(M_PI), m_cone_volume_outer(0),
m_flags(RENDER_CONE), m_stop(nullptr), m_stop_data(nullptr), m_status(STATUS_PLAYING), m_device(device)
@@ -106,14 +106,6 @@ void SoftwareDevice::SoftwareHandle::update()
if(m_pitch->getSpecs().channels != CHANNELS_MONO)
{
m_volume = m_user_volume;
// we don't know a previous volume if this source has never been read before
if(m_first_reading)
{
m_old_volume = m_volume;
m_first_reading = false;
}
m_pitch->setPitch(m_user_pitch);
return;
}
@@ -222,13 +214,6 @@ void SoftwareDevice::SoftwareHandle::update()
m_volume *= m_user_volume;
}
// we don't know a previous volume if this source has never been read before
if(m_first_reading)
{
m_old_volume = m_volume;
m_first_reading = false;
}
// 3D Cue
Quaternion orientation;
@@ -769,8 +754,6 @@ void SoftwareDevice::mix(data_t* buffer, int length)
{
m_mixer->mix(buf, pos, len, sound->m_volume, sound->m_old_volume);
sound->m_old_volume = sound->m_volume;
pos += len;
if(sound->m_loopcount > 0)

View File

@@ -22,7 +22,6 @@
#include <mutex>
#define KEEP_TIME 10
#define POSITION_EPSILON (1.0 / static_cast<double>(RATE_48000))
AUD_NAMESPACE_BEGIN
@@ -65,7 +64,7 @@ bool SequenceHandle::updatePosition(double position)
if(m_handle.get())
{
// we currently have a handle, let's check where we are
if(position - POSITION_EPSILON >= m_entry->m_end)
if(position >= m_entry->m_end)
{
if(position >= m_entry->m_end + KEEP_TIME)
// far end, stopping
@@ -77,7 +76,7 @@ bool SequenceHandle::updatePosition(double position)
return true;
}
}
else if(position + POSITION_EPSILON >= m_entry->m_begin)
else if(position >= m_entry->m_begin)
{
// inside, resuming
m_handle->resume();
@@ -99,7 +98,7 @@ bool SequenceHandle::updatePosition(double position)
else
{
// we don't have a handle, let's start if we should be playing
if(position + POSITION_EPSILON >= m_entry->m_begin && position - POSITION_EPSILON <= m_entry->m_end)
if(position >= m_entry->m_begin && position <= m_entry->m_end)
{
start();
return m_valid;

View File

@@ -1,5 +0,0 @@
Project: Bullet Continuous Collision Detection and Physics Library
URL: http://bulletphysics.org
License: zlib
Upstream version: 3.07
Local modifications: Fixed inertia

View File

@@ -1,5 +1,4 @@
Project: Ceres Solver
URL: http://ceres-solver.org/
License: BSD 3-Clause
Upstream version 2.0.0
Local modifications: None

View File

@@ -1,5 +1,5 @@
Project: Curve-Fit-nD
URL: https://github.com/ideasman42/curve-fit-nd
License: BSD 3-Clause
Upstream version: ddcd5bd (Last Release)
Upstream version: Unknown (Last Release)
Local modifications: None

View File

@@ -19,24 +19,20 @@
# ***** END GPL LICENSE BLOCK *****
# Build Draco library.
add_subdirectory(draco)
add_subdirectory(dracoenc)
# Build Draco-Blender bridging module.
# Build blender-draco-exporter module.
set(SRC
src/common.cpp
src/common.h
src/decoder.cpp
src/decoder.h
src/encoder.cpp
src/encoder.h
src/draco-compressor.cpp
src/draco-compressor.h
)
set(INC
draco/src
dracoenc/src
)
set(LIB
draco
dracoenc
)
add_library(extern_draco SHARED "${SRC}")

View File

@@ -1,5 +0,0 @@
Project: Draco
URL: https://google.github.io/draco/
License: Apache 2.0
Upstream version: 1.3.6
Local modifications: None

View File

@@ -1,10 +0,0 @@
#ifndef DRACO_FEATURES_H_
#define DRACO_FEATURES_H_
#define DRACO_MESH_COMPRESSION_SUPPORTED
#define DRACO_NORMAL_ENCODING_SUPPORTED
#define DRACO_STANDARD_EDGEBREAKER_SUPPORTED
#define DRACO_ATTRIBUTE_INDICES_DEDUPLICATION_SUPPORTED
#define DRACO_ATTRIBUTE_VALUES_DEDUPLICATION_SUPPORTED
#endif // DRACO_FEATURES_H_

View File

@@ -2,165 +2,103 @@ remove_strict_flags()
set(SRC
src/draco/animation/keyframe_animation.cc
src/draco/animation/keyframe_animation.h
src/draco/animation/keyframe_animation_decoder.cc
src/draco/animation/keyframe_animation_decoder.h
src/draco/animation/keyframe_animation_encoder.cc
src/draco/animation/keyframe_animation_encoder.h
src/draco/animation/keyframe_animation.h
src/draco/attributes/attribute_octahedron_transform.cc
src/draco/attributes/attribute_octahedron_transform.h
src/draco/attributes/attribute_quantization_transform.cc
src/draco/attributes/attribute_quantization_transform.h
src/draco/attributes/attribute_transform.cc
src/draco/attributes/attribute_transform.h
src/draco/attributes/attribute_transform_data.h
src/draco/attributes/attribute_transform.h
src/draco/attributes/attribute_transform_type.h
src/draco/attributes/geometry_attribute.cc
src/draco/attributes/geometry_attribute.h
src/draco/attributes/geometry_indices.h
src/draco/attributes/point_attribute.cc
src/draco/attributes/point_attribute.h
src/draco/compression/attributes/attributes_decoder.cc
src/draco/compression/attributes/attributes_decoder.h
src/draco/compression/attributes/attributes_decoder_interface.h
src/draco/compression/attributes/attributes_encoder.cc
src/draco/compression/attributes/attributes_encoder.h
src/draco/compression/attributes/kd_tree_attributes_decoder.cc
src/draco/compression/attributes/kd_tree_attributes_decoder.h
src/draco/compression/attributes/kd_tree_attributes_encoder.cc
src/draco/compression/attributes/kd_tree_attributes_encoder.h
src/draco/compression/attributes/kd_tree_attributes_shared.h
src/draco/compression/attributes/linear_sequencer.h
src/draco/compression/attributes/mesh_attribute_indices_encoding_data.h
src/draco/compression/attributes/normal_compression_utils.h
src/draco/compression/attributes/point_d_vector.h
src/draco/compression/attributes/points_sequencer.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_encoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_shared.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_data.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_encoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_encoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_area.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_base.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_encoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_encoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_encoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_encoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_predictor.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_factory.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_interface.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_decoder.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_encoder.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.cc
src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_interface.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_factory.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_interface.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_decoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_encoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_base.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_decoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_encoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_base.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_decoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_encoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_transform_base.h
src/draco/compression/attributes/sequential_attribute_decoder.cc
src/draco/compression/attributes/sequential_attribute_decoder.h
src/draco/compression/attributes/sequential_attribute_decoders_controller.cc
src/draco/compression/attributes/sequential_attribute_decoders_controller.h
src/draco/compression/attributes/sequential_attribute_encoder.cc
src/draco/compression/attributes/sequential_attribute_encoder.h
src/draco/compression/attributes/sequential_attribute_encoders_controller.cc
src/draco/compression/attributes/sequential_attribute_encoders_controller.h
src/draco/compression/attributes/sequential_integer_attribute_decoder.cc
src/draco/compression/attributes/sequential_integer_attribute_decoder.h
src/draco/compression/attributes/sequential_integer_attribute_encoder.cc
src/draco/compression/attributes/sequential_integer_attribute_encoder.h
src/draco/compression/attributes/sequential_normal_attribute_decoder.cc
src/draco/compression/attributes/sequential_normal_attribute_decoder.h
src/draco/compression/attributes/sequential_normal_attribute_encoder.cc
src/draco/compression/attributes/sequential_normal_attribute_encoder.h
src/draco/compression/attributes/sequential_quantization_attribute_decoder.cc
src/draco/compression/attributes/sequential_quantization_attribute_decoder.h
src/draco/compression/attributes/sequential_quantization_attribute_encoder.cc
src/draco/compression/attributes/sequential_quantization_attribute_encoder.h
src/draco/compression/bit_coders/adaptive_rans_bit_coding_shared.h
src/draco/compression/bit_coders/adaptive_rans_bit_decoder.cc
src/draco/compression/bit_coders/adaptive_rans_bit_decoder.h
src/draco/compression/bit_coders/adaptive_rans_bit_encoder.cc
src/draco/compression/bit_coders/adaptive_rans_bit_encoder.h
src/draco/compression/bit_coders/direct_bit_decoder.cc
src/draco/compression/bit_coders/direct_bit_decoder.h
src/draco/compression/bit_coders/direct_bit_encoder.cc
src/draco/compression/bit_coders/direct_bit_encoder.h
src/draco/compression/bit_coders/folded_integer_bit_decoder.h
src/draco/compression/bit_coders/folded_integer_bit_encoder.h
src/draco/compression/bit_coders/rans_bit_decoder.cc
src/draco/compression/bit_coders/rans_bit_decoder.h
src/draco/compression/bit_coders/rans_bit_encoder.cc
src/draco/compression/bit_coders/rans_bit_encoder.h
src/draco/compression/bit_coders/symbol_bit_decoder.cc
src/draco/compression/bit_coders/symbol_bit_decoder.h
src/draco/compression/bit_coders/symbol_bit_encoder.cc
src/draco/compression/bit_coders/symbol_bit_encoder.h
src/draco/compression/config/compression_shared.h
src/draco/compression/config/decoder_options.h
src/draco/compression/config/draco_options.h
src/draco/compression/config/encoder_options.h
src/draco/compression/config/encoding_features.h
src/draco/compression/decode.cc
src/draco/compression/decode.h
src/draco/compression/encode_base.h
src/draco/compression/encode.cc
src/draco/compression/encode.h
src/draco/compression/encode_base.h
src/draco/compression/entropy/ans.h
src/draco/compression/entropy/rans_symbol_coding.h
src/draco/compression/entropy/rans_symbol_decoder.h
src/draco/compression/entropy/rans_symbol_encoder.h
src/draco/compression/entropy/shannon_entropy.cc
src/draco/compression/entropy/shannon_entropy.h
src/draco/compression/entropy/symbol_decoding.cc
src/draco/compression/entropy/symbol_decoding.h
src/draco/compression/entropy/symbol_encoding.cc
src/draco/compression/entropy/symbol_encoding.h
src/draco/compression/expert_encode.cc
src/draco/compression/expert_encode.h
src/draco/compression/mesh/mesh_decoder.cc
src/draco/compression/mesh/mesh_decoder.h
src/draco/compression/mesh/mesh_edgebreaker_decoder.cc
src/draco/compression/mesh/mesh_edgebreaker_decoder.h
src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc
src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.h
src/draco/compression/mesh/mesh_edgebreaker_decoder_impl_interface.h
src/draco/compression/mesh/mesh_edgebreaker_encoder.cc
src/draco/compression/mesh/mesh_edgebreaker_encoder.h
src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.cc
src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.h
src/draco/compression/mesh/mesh_edgebreaker_encoder_impl_interface.h
src/draco/compression/mesh/mesh_edgebreaker_shared.h
src/draco/compression/mesh/mesh_edgebreaker_traversal_decoder.h
src/draco/compression/mesh/mesh_edgebreaker_traversal_encoder.h
src/draco/compression/mesh/mesh_edgebreaker_traversal_predictive_decoder.h
src/draco/compression/mesh/mesh_edgebreaker_traversal_predictive_encoder.h
src/draco/compression/mesh/mesh_edgebreaker_traversal_valence_decoder.h
src/draco/compression/mesh/mesh_edgebreaker_traversal_valence_encoder.h
src/draco/compression/mesh/mesh_encoder.cc
src/draco/compression/mesh/mesh_encoder.h
src/draco/compression/mesh/mesh_sequential_decoder.cc
src/draco/compression/mesh/mesh_sequential_decoder.h
src/draco/compression/mesh/mesh_encoder_helpers.h
src/draco/compression/mesh/mesh_sequential_encoder.cc
src/draco/compression/mesh/mesh_sequential_encoder.h
src/draco/compression/mesh/traverser/depth_first_traverser.h
@@ -168,32 +106,18 @@ set(SRC
src/draco/compression/mesh/traverser/mesh_attribute_indices_encoding_observer.h
src/draco/compression/mesh/traverser/mesh_traversal_sequencer.h
src/draco/compression/mesh/traverser/traverser_base.h
src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.cc
src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.h
src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.cc
src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.h
src/draco/compression/point_cloud/algorithms/float_points_tree_decoder.cc
src/draco/compression/point_cloud/algorithms/float_points_tree_decoder.h
src/draco/compression/point_cloud/algorithms/float_points_tree_encoder.cc
src/draco/compression/point_cloud/algorithms/float_points_tree_encoder.h
src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.cc
src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.h
src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_encoder.cc
src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_encoder.h
src/draco/compression/point_cloud/algorithms/point_cloud_compression_method.h
src/draco/compression/point_cloud/algorithms/point_cloud_types.h
src/draco/compression/point_cloud/algorithms/quantize_points_3.h
src/draco/compression/point_cloud/algorithms/queuing_policy.h
src/draco/compression/point_cloud/point_cloud_decoder.cc
src/draco/compression/point_cloud/point_cloud_decoder.h
src/draco/compression/point_cloud/point_cloud_encoder.cc
src/draco/compression/point_cloud/point_cloud_encoder.h
src/draco/compression/point_cloud/point_cloud_kd_tree_decoder.cc
src/draco/compression/point_cloud/point_cloud_kd_tree_decoder.h
src/draco/compression/point_cloud/point_cloud_kd_tree_encoder.cc
src/draco/compression/point_cloud/point_cloud_kd_tree_encoder.h
src/draco/compression/point_cloud/point_cloud_sequential_decoder.cc
src/draco/compression/point_cloud/point_cloud_sequential_decoder.h
src/draco/compression/point_cloud/point_cloud_sequential_encoder.cc
src/draco/compression/point_cloud/point_cloud_sequential_encoder.h
src/draco/core/bit_utils.cc
@@ -204,15 +128,12 @@ set(SRC
src/draco/core/cycle_timer.h
src/draco/core/data_buffer.cc
src/draco/core/data_buffer.h
src/draco/core/decoder_buffer.cc
src/draco/core/decoder_buffer.h
src/draco/core/divide.cc
src/draco/core/divide.h
src/draco/core/draco_index_type.h
src/draco/core/draco_index_type_vector.h
src/draco/core/draco_types.cc
src/draco/core/draco_types.h
src/draco/core/draco_version.h
src/draco/core/encoder_buffer.cc
src/draco/core/encoder_buffer.h
src/draco/core/hash_utils.cc
@@ -224,21 +145,20 @@ set(SRC
src/draco/core/quantization_utils.cc
src/draco/core/quantization_utils.h
src/draco/core/status.h
src/draco/core/status_or.h
src/draco/core/varint_decoding.h
src/draco/core/statusor.h
src/draco/core/varint_encoding.h
src/draco/core/vector_d.h
src/draco/mesh/corner_table.cc
src/draco/mesh/corner_table.h
src/draco/mesh/corner_table_iterators.h
src/draco/mesh/mesh.cc
src/draco/mesh/mesh.h
src/draco/mesh/mesh_are_equivalent.cc
src/draco/mesh/mesh_are_equivalent.h
src/draco/mesh/mesh_attribute_corner_table.cc
src/draco/mesh/mesh_attribute_corner_table.h
src/draco/mesh/mesh.cc
src/draco/mesh/mesh_cleanup.cc
src/draco/mesh/mesh_cleanup.h
src/draco/mesh/mesh.h
src/draco/mesh/mesh_misc_functions.cc
src/draco/mesh/mesh_misc_functions.h
src/draco/mesh/mesh_stripifier.cc
@@ -249,15 +169,13 @@ set(SRC
src/draco/metadata/geometry_metadata.cc
src/draco/metadata/geometry_metadata.h
src/draco/metadata/metadata.cc
src/draco/metadata/metadata.h
src/draco/metadata/metadata_decoder.cc
src/draco/metadata/metadata_decoder.h
src/draco/metadata/metadata_encoder.cc
src/draco/metadata/metadata_encoder.h
src/draco/point_cloud/point_cloud.cc
src/draco/point_cloud/point_cloud.h
src/draco/metadata/metadata.h
src/draco/point_cloud/point_cloud_builder.cc
src/draco/point_cloud/point_cloud_builder.h
src/draco/point_cloud/point_cloud.cc
src/draco/point_cloud/point_cloud.h
)
set(LIB
@@ -267,4 +185,4 @@ set(INC
src
)
blender_add_lib(draco "${SRC}" "${INC}" "" "${LIB}")
blender_add_lib(dracoenc "${SRC}" "${INC}" "" "${LIB}")

View File

@@ -0,0 +1,3 @@
@PACKAGE_INIT@
set_and_check(draco_INCLUDE_DIR "@PACKAGE_draco_include_install_dir@")
set_and_check(draco_LIBRARY_DIR "@PACKAGE_draco_lib_install_dir@")

View File

@@ -0,0 +1,58 @@
# Finddraco
#
# Locates draco and sets the following variables:
#
# draco_FOUND
# draco_INCLUDE_DIRS
# draco_LIBARY_DIRS
# draco_LIBRARIES
# draco_VERSION_STRING
#
# draco_FOUND is set to YES only when all other variables are successfully
# configured.
unset(draco_FOUND)
unset(draco_INCLUDE_DIRS)
unset(draco_LIBRARY_DIRS)
unset(draco_LIBRARIES)
unset(draco_VERSION_STRING)
mark_as_advanced(draco_FOUND)
mark_as_advanced(draco_INCLUDE_DIRS)
mark_as_advanced(draco_LIBRARY_DIRS)
mark_as_advanced(draco_LIBRARIES)
mark_as_advanced(draco_VERSION_STRING)
set(draco_version_file_no_prefix "draco/src/draco/core/draco_version.h")
# Set draco_INCLUDE_DIRS
find_path(draco_INCLUDE_DIRS NAMES "${draco_version_file_no_prefix}")
# Extract the version string from draco_version.h.
if (draco_INCLUDE_DIRS)
set(draco_version_file
"${draco_INCLUDE_DIRS}/draco/src/draco/core/draco_version.h")
file(STRINGS "${draco_version_file}" draco_version
REGEX "kdracoVersion")
list(GET draco_version 0 draco_version)
string(REPLACE "static const char kdracoVersion[] = " "" draco_version
"${draco_version}")
string(REPLACE ";" "" draco_version "${draco_version}")
string(REPLACE "\"" "" draco_version "${draco_version}")
set(draco_VERSION_STRING ${draco_version})
endif ()
# Find the library.
if (BUILD_SHARED_LIBS)
find_library(draco_LIBRARIES NAMES draco.dll libdraco.dylib libdraco.so)
else ()
find_library(draco_LIBRARIES NAMES draco.lib libdraco.a)
endif ()
# Store path to library.
get_filename_component(draco_LIBRARY_DIRS ${draco_LIBRARIES} DIRECTORY)
if (draco_INCLUDE_DIRS AND draco_LIBRARY_DIRS AND draco_LIBRARIES AND
draco_VERSION_STRING)
set(draco_FOUND YES)
endif ()

View File

@@ -0,0 +1,216 @@
if (NOT DRACO_CMAKE_COMPILER_FLAGS_CMAKE_)
set(DRACO_CMAKE_COMPILER_FLAGS_CMAKE_ 1)
include(CheckCCompilerFlag)
include(CheckCXXCompilerFlag)
include("${draco_root}/cmake/compiler_tests.cmake")
# Strings used to cache failed C/CXX flags.
set(DRACO_FAILED_C_FLAGS)
set(DRACO_FAILED_CXX_FLAGS)
# Checks C compiler for support of $c_flag. Adds $c_flag to $CMAKE_C_FLAGS when
# the compile test passes. Caches $c_flag in $DRACO_FAILED_C_FLAGS when the test
# fails.
macro (add_c_flag_if_supported c_flag)
unset(C_FLAG_FOUND CACHE)
string(FIND "${CMAKE_C_FLAGS}" "${c_flag}" C_FLAG_FOUND)
unset(C_FLAG_FAILED CACHE)
string(FIND "${DRACO_FAILED_C_FLAGS}" "${c_flag}" C_FLAG_FAILED)
if (${C_FLAG_FOUND} EQUAL -1 AND ${C_FLAG_FAILED} EQUAL -1)
unset(C_FLAG_SUPPORTED CACHE)
message("Checking C compiler flag support for: " ${c_flag})
check_c_compiler_flag("${c_flag}" C_FLAG_SUPPORTED)
if (${C_FLAG_SUPPORTED})
string(APPEND CMAKE_C_FLAGS " ${c_flag}" CACHE STRING "")
else ()
string(APPEND DRACO_FAILED_C_FLAGS " ${c_flag}" CACHE STRING
"" FORCE)
endif ()
endif ()
endmacro ()
# Checks C++ compiler for support of $cxx_flag. Adds $cxx_flag to
# $CMAKE_CXX_FLAGS when the compile test passes. Caches $c_flag in
# $DRACO_FAILED_CXX_FLAGS when the test fails.
macro (add_cxx_flag_if_supported cxx_flag)
unset(CXX_FLAG_FOUND CACHE)
string(FIND "${CMAKE_CXX_FLAGS}" "${cxx_flag}" CXX_FLAG_FOUND)
unset(CXX_FLAG_FAILED CACHE)
string(FIND "${DRACO_FAILED_CXX_FLAGS}" "${cxx_flag}" CXX_FLAG_FAILED)
if (${CXX_FLAG_FOUND} EQUAL -1 AND ${CXX_FLAG_FAILED} EQUAL -1)
unset(CXX_FLAG_SUPPORTED CACHE)
message("Checking CXX compiler flag support for: " ${cxx_flag})
check_cxx_compiler_flag("${cxx_flag}" CXX_FLAG_SUPPORTED)
if (${CXX_FLAG_SUPPORTED})
string(APPEND CMAKE_CXX_FLAGS " ${cxx_flag}" CACHE STRING "")
else()
string(APPEND DRACO_FAILED_CXX_FLAGS " ${cxx_flag}" CACHE
STRING "" FORCE)
endif ()
endif ()
endmacro ()
# Convenience method for adding a flag to both the C and C++ compiler command
# lines.
macro (add_compiler_flag_if_supported flag)
add_c_flag_if_supported(${flag})
add_cxx_flag_if_supported(${flag})
endmacro ()
# Checks C compiler for support of $c_flag and terminates generation when
# support is not present.
macro (require_c_flag c_flag update_c_flags)
unset(C_FLAG_FOUND CACHE)
string(FIND "${CMAKE_C_FLAGS}" "${c_flag}" C_FLAG_FOUND)
if (${C_FLAG_FOUND} EQUAL -1)
unset(HAVE_C_FLAG CACHE)
message("Checking C compiler flag support for: " ${c_flag})
check_c_compiler_flag("${c_flag}" HAVE_C_FLAG)
if (NOT ${HAVE_C_FLAG})
message(FATAL_ERROR
"${PROJECT_NAME} requires support for C flag: ${c_flag}.")
endif ()
if (${update_c_flags})
set(CMAKE_C_FLAGS "${c_flag} ${CMAKE_C_FLAGS}" CACHE STRING "" FORCE)
endif ()
endif ()
endmacro ()
# Checks CXX compiler for support of $cxx_flag and terminates generation when
# support is not present.
macro (require_cxx_flag cxx_flag update_cxx_flags)
unset(CXX_FLAG_FOUND CACHE)
string(FIND "${CMAKE_CXX_FLAGS}" "${cxx_flag}" CXX_FLAG_FOUND)
if (${CXX_FLAG_FOUND} EQUAL -1)
unset(HAVE_CXX_FLAG CACHE)
message("Checking CXX compiler flag support for: " ${cxx_flag})
check_cxx_compiler_flag("${cxx_flag}" HAVE_CXX_FLAG)
if (NOT ${HAVE_CXX_FLAG})
message(FATAL_ERROR
"${PROJECT_NAME} requires support for CXX flag: ${cxx_flag}.")
endif ()
if (${update_cxx_flags})
set(CMAKE_CXX_FLAGS "${cxx_flag} ${CMAKE_CXX_FLAGS}" CACHE STRING ""
FORCE)
endif ()
endif ()
endmacro ()
# Checks for support of $flag by both the C and CXX compilers. Terminates
# generation when support is not present in both compilers.
macro (require_compiler_flag flag update_cmake_flags)
require_c_flag(${flag} ${update_cmake_flags})
require_cxx_flag(${flag} ${update_cmake_flags})
endmacro ()
# Checks only non-MSVC targets for support of $c_flag and terminates generation
# when support is not present.
macro (require_c_flag_nomsvc c_flag update_c_flags)
if (NOT MSVC)
require_c_flag(${c_flag} ${update_c_flags})
endif ()
endmacro ()
# Checks only non-MSVC targets for support of $cxx_flag and terminates
# generation when support is not present.
macro (require_cxx_flag_nomsvc cxx_flag update_cxx_flags)
if (NOT MSVC)
require_cxx_flag(${cxx_flag} ${update_cxx_flags})
endif ()
endmacro ()
# Checks only non-MSVC targets for support of $flag by both the C and CXX
# compilers. Terminates generation when support is not present in both
# compilers.
macro (require_compiler_flag_nomsvc flag update_cmake_flags)
require_c_flag_nomsvc(${flag} ${update_cmake_flags})
require_cxx_flag_nomsvc(${flag} ${update_cmake_flags})
endmacro ()
# Adds $flag to assembler command line.
macro (append_as_flag flag)
unset(AS_FLAG_FOUND CACHE)
string(FIND "${DRACO_AS_FLAGS}" "${flag}" AS_FLAG_FOUND)
if (${AS_FLAG_FOUND} EQUAL -1)
string(APPEND DRACO_AS_FLAGS " ${flag}")
endif ()
endmacro ()
# Adds $flag to the C compiler command line.
macro (append_c_flag flag)
unset(C_FLAG_FOUND CACHE)
string(FIND "${CMAKE_C_FLAGS}" "${flag}" C_FLAG_FOUND)
if (${C_FLAG_FOUND} EQUAL -1)
string(APPEND CMAKE_C_FLAGS " ${flag}")
endif ()
endmacro ()
# Adds $flag to the CXX compiler command line.
macro (append_cxx_flag flag)
unset(CXX_FLAG_FOUND CACHE)
string(FIND "${CMAKE_CXX_FLAGS}" "${flag}" CXX_FLAG_FOUND)
if (${CXX_FLAG_FOUND} EQUAL -1)
string(APPEND CMAKE_CXX_FLAGS " ${flag}")
endif ()
endmacro ()
# Adds $flag to the C and CXX compiler command lines.
macro (append_compiler_flag flag)
append_c_flag(${flag})
append_cxx_flag(${flag})
endmacro ()
# Adds $flag to the executable linker command line.
macro (append_exe_linker_flag flag)
unset(LINKER_FLAG_FOUND CACHE)
string(FIND "${CMAKE_EXE_LINKER_FLAGS}" "${flag}" LINKER_FLAG_FOUND)
if (${LINKER_FLAG_FOUND} EQUAL -1)
string(APPEND CMAKE_EXE_LINKER_FLAGS " ${flag}")
endif ()
endmacro ()
# Adds $flag to the link flags for $target.
function (append_link_flag_to_target target flags)
unset(target_link_flags)
get_target_property(target_link_flags ${target} LINK_FLAGS)
if (target_link_flags)
unset(link_flag_found)
string(FIND "${target_link_flags}" "${flags}" link_flag_found)
if (NOT ${link_flag_found} EQUAL -1)
return()
endif ()
string(APPEND target_link_flags " ${flags}")
else ()
set(target_link_flags "${flags}")
endif ()
set_target_properties(${target} PROPERTIES LINK_FLAGS ${target_link_flags})
endfunction ()
# Adds $flag to executable linker flags, and makes sure C/CXX builds still work.
macro (require_linker_flag flag)
append_exe_linker_flag(${flag})
unset(c_passed)
draco_check_c_compiles("LINKER_FLAG_C_TEST(${flag})" "" c_passed)
unset(cxx_passed)
draco_check_cxx_compiles("LINKER_FLAG_CXX_TEST(${flag})" "" cxx_passed)
if (NOT c_passed OR NOT cxx_passed)
message(FATAL_ERROR "Linker flag test for ${flag} failed.")
endif ()
endmacro ()
endif () # DRACO_CMAKE_COMPILER_FLAGS_CMAKE_

View File

@@ -0,0 +1,124 @@
if (NOT DRACO_CMAKE_COMPILER_TESTS_CMAKE_)
set(DRACO_CMAKE_COMPILER_TESTS_CMAKE_ 1)
include(CheckCSourceCompiles)
include(CheckCXXSourceCompiles)
# The basic main() macro used in all compile tests.
set(DRACO_C_MAIN "\nint main(void) { return 0; }")
set(DRACO_CXX_MAIN "\nint main() { return 0; }")
# Strings containing the names of passed and failed tests.
set(DRACO_C_PASSED_TESTS)
set(DRACO_C_FAILED_TESTS)
set(DRACO_CXX_PASSED_TESTS)
set(DRACO_CXX_FAILED_TESTS)
macro(draco_push_var var new_value)
set(SAVED_${var} ${var})
set(${var} ${new_value})
endmacro ()
macro(draco_pop_var var)
set(var ${SAVED_${var}})
unset(SAVED_${var})
endmacro ()
# Confirms $test_source compiles and stores $test_name in one of
# $DRACO_C_PASSED_TESTS or $DRACO_C_FAILED_TESTS depending on out come. When the
# test passes $result_var is set to 1. When it fails $result_var is unset.
# The test is not run if the test name is found in either of the passed or
# failed test variables.
macro(draco_check_c_compiles test_name test_source result_var)
unset(C_TEST_PASSED CACHE)
unset(C_TEST_FAILED CACHE)
string(FIND "${DRACO_C_PASSED_TESTS}" "${test_name}" C_TEST_PASSED)
string(FIND "${DRACO_C_FAILED_TESTS}" "${test_name}" C_TEST_FAILED)
if (${C_TEST_PASSED} EQUAL -1 AND ${C_TEST_FAILED} EQUAL -1)
unset(C_TEST_COMPILED CACHE)
message("Running C compiler test: ${test_name}")
check_c_source_compiles("${test_source} ${DRACO_C_MAIN}" C_TEST_COMPILED)
set(${result_var} ${C_TEST_COMPILED})
if (${C_TEST_COMPILED})
string(APPEND DRACO_C_PASSED_TESTS " ${test_name}")
else ()
string(APPEND DRACO_C_FAILED_TESTS " ${test_name}")
message("C Compiler test ${test_name} failed.")
endif ()
elseif (NOT ${C_TEST_PASSED} EQUAL -1)
set(${result_var} 1)
else () # ${C_TEST_FAILED} NOT EQUAL -1
unset(${result_var})
endif ()
endmacro ()
# Confirms $test_source compiles and stores $test_name in one of
# $DRACO_CXX_PASSED_TESTS or $DRACO_CXX_FAILED_TESTS depending on out come. When
# the test passes $result_var is set to 1. When it fails $result_var is unset.
# The test is not run if the test name is found in either of the passed or
# failed test variables.
macro(draco_check_cxx_compiles test_name test_source result_var)
unset(CXX_TEST_PASSED CACHE)
unset(CXX_TEST_FAILED CACHE)
string(FIND "${DRACO_CXX_PASSED_TESTS}" "${test_name}" CXX_TEST_PASSED)
string(FIND "${DRACO_CXX_FAILED_TESTS}" "${test_name}" CXX_TEST_FAILED)
if (${CXX_TEST_PASSED} EQUAL -1 AND ${CXX_TEST_FAILED} EQUAL -1)
unset(CXX_TEST_COMPILED CACHE)
message("Running CXX compiler test: ${test_name}")
check_cxx_source_compiles("${test_source} ${DRACO_CXX_MAIN}"
CXX_TEST_COMPILED)
set(${result_var} ${CXX_TEST_COMPILED})
if (${CXX_TEST_COMPILED})
string(APPEND DRACO_CXX_PASSED_TESTS " ${test_name}")
else ()
string(APPEND DRACO_CXX_FAILED_TESTS " ${test_name}")
message("CXX Compiler test ${test_name} failed.")
endif ()
elseif (NOT ${CXX_TEST_PASSED} EQUAL -1)
set(${result_var} 1)
else () # ${CXX_TEST_FAILED} NOT EQUAL -1
unset(${result_var})
endif ()
endmacro ()
# Convenience macro that confirms $test_source compiles as C and C++.
# $result_var is set to 1 when both tests are successful, and 0 when one or both
# tests fail.
# Note: This macro is intended to be used to write to result variables that
# are expanded via configure_file(). $result_var is set to 1 or 0 to allow
# direct usage of the value in generated source files.
macro(draco_check_source_compiles test_name test_source result_var)
unset(C_PASSED)
unset(CXX_PASSED)
draco_check_c_compiles(${test_name} ${test_source} C_PASSED)
draco_check_cxx_compiles(${test_name} ${test_source} CXX_PASSED)
if (${C_PASSED} AND ${CXX_PASSED})
set(${result_var} 1)
else ()
set(${result_var} 0)
endif ()
endmacro ()
# When inline support is detected for the current compiler the supported
# inlining keyword is written to $result in caller scope.
macro (draco_get_inline result)
draco_check_source_compiles("inline_check_1"
"static inline void macro(void) {}"
HAVE_INLINE_1)
if (HAVE_INLINE_1 EQUAL 1)
set(${result} "inline")
return()
endif ()
# Check __inline.
draco_check_source_compiles("inline_check_2"
"static __inline void macro(void) {}"
HAVE_INLINE_2)
if (HAVE_INLINE_2 EQUAL 1)
set(${result} "__inline")
endif ()
endmacro ()
endif () # DRACO_CMAKE_COMPILER_TESTS_CMAKE_

View File

@@ -0,0 +1,57 @@
if (NOT DRACO_CMAKE_DRACO_FEATURES_CMAKE_)
set(DRACO_CMAKE_DRACO_FEATURES_CMAKE_ 1)
set(draco_features_file_name "${draco_build_dir}/draco/draco_features.h")
set(draco_features_list)
# Macro that handles tracking of Draco preprocessor symbols for the purpose of
# producing draco_features.h.
#
# draco_enable_feature(FEATURE <feature_name> [TARGETS <target_name>])
# FEATURE is required. It should be a Draco preprocessor symbol.
# TARGETS is optional. It can be one or more draco targets.
#
# When the TARGETS argument is not present the preproc symbol is added to
# draco_features.h. When it is draco_features.h is unchanged, and
# target_compile_options() is called for each target specified.
macro (draco_enable_feature)
set(def_flags)
set(def_single_arg_opts FEATURE)
set(def_multi_arg_opts TARGETS)
cmake_parse_arguments(DEF "${def_flags}" "${def_single_arg_opts}"
"${def_multi_arg_opts}" ${ARGN})
if ("${DEF_FEATURE}" STREQUAL "")
message(FATAL_ERROR "Empty FEATURE passed to draco_enable_feature().")
endif ()
# Do nothing/return early if $DEF_FEATURE is already in the list.
list(FIND draco_features_list ${DEF_FEATURE} df_index)
if (NOT df_index EQUAL -1)
return ()
endif ()
list(LENGTH DEF_TARGETS df_targets_list_length)
if (${df_targets_list_length} EQUAL 0)
list(APPEND draco_features_list ${DEF_FEATURE})
else ()
foreach (target ${DEF_TARGETS})
target_compile_definitions(${target} PRIVATE ${DEF_FEATURE})
endforeach ()
endif ()
endmacro ()
# Function for generating draco_features.h.
function (draco_generate_features_h)
file(WRITE "${draco_features_file_name}"
"// GENERATED FILE -- DO NOT EDIT\n\n"
"#ifndef DRACO_FEATURES_H_\n"
"#define DRACO_FEATURES_H_\n\n")
foreach (feature ${draco_features_list})
file(APPEND "${draco_features_file_name}" "#define ${feature}\n")
endforeach ()
file(APPEND "${draco_features_file_name}" "\n#endif // DRACO_FEATURES_H_")
endfunction ()
endif () # DRACO_CMAKE_DRACO_FEATURES_CMAKE_

View File

@@ -0,0 +1,13 @@
#ifndef DRACO_TESTING_DRACO_TEST_CONFIG_H_
#define DRACO_TESTING_DRACO_TEST_CONFIG_H_
// If this file is named draco_test_config.h.cmake:
// This file is used as input at cmake generation time.
// If this file is named draco_test_config.h:
// GENERATED FILE, DO NOT EDIT. SEE ABOVE.
#define DRACO_TEST_DATA_DIR "${DRACO_TEST_DATA_DIR}"
#define DRACO_TEST_TEMP_DIR "${DRACO_TEST_TEMP_DIR}"
#endif // DRACO_TESTING_DRACO_TEST_CONFIG_H_

View File

@@ -0,0 +1,21 @@
// If this file is named draco_version.cc.cmake:
// This file is used as input at cmake generation time.
// If this file is named draco_version.cc:
// GENERATED FILE, DO NOT EDIT. SEE ABOVE.
#include "draco_version.h"
static const char kDracoGitHash[] = "${draco_git_hash}";
static const char kDracoGitDesc[] = "${draco_git_desc}";
const char *draco_git_hash() {
return kDracoGitHash;
}
const char *draco_git_version() {
return kDracoGitDesc;
}
const char* draco_version() {
return draco::Version();
}

View File

@@ -0,0 +1,21 @@
// If this file is named draco_version.h.cmake:
// This file is used as input at cmake generation time.
// If this file is named draco_version.h:
// GENERATED FILE, DO NOT EDIT. SEE ABOVE.
#ifndef DRACO_DRACO_VERSION_H_
#define DRACO_DRACO_VERSION_H_
#include "draco/core/draco_version.h"
// Returns git hash of Draco git repository.
const char *draco_git_hash();
// Returns the output of the git describe command when run from the Draco git
// repository.
const char *draco_git_version();
// Returns the version string from core/draco_version.h.
const char* draco_version();
#endif // DRACO_DRACO_VERSION_H_

View File

@@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 3.2)
if (MSVC)
# Use statically linked versions of the MS standard libraries.
if (NOT "${MSVC_RUNTIME}" STREQUAL "dll")
foreach (flag_var
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if (${flag_var} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
endif ()
endforeach ()
endif ()
endif ()

View File

@@ -0,0 +1,19 @@
if (NOT DRACO_CMAKE_SANITIZERS_CMAKE_)
set(DRACO_CMAKE_SANITIZERS_CMAKE_ 1)
if (MSVC OR NOT SANITIZE)
return ()
endif ()
include("${draco_root}/cmake/compiler_flags.cmake")
string(TOLOWER ${SANITIZE} SANITIZE)
# Require the sanitizer requested.
require_linker_flag("-fsanitize=${SANITIZE}")
require_compiler_flag("-fsanitize=${SANITIZE}" YES)
# Make callstacks accurate.
require_compiler_flag("-fno-omit-frame-pointer -fno-optimize-sibling-calls" YES)
endif() # DRACO_CMAKE_SANITIZERS_CMAKE_

View File

@@ -0,0 +1,13 @@
if (NOT DRACO_CMAKE_TOOLCHAINS_ARM_IOS_COMMON_CMAKE_)
set(DRACO_CMAKE_ARM_IOS_COMMON_CMAKE_ 1)
set(CMAKE_SYSTEM_NAME "Darwin")
set(CMAKE_OSX_SYSROOT iphoneos)
set(CMAKE_C_COMPILER clang)
set(CMAKE_C_COMPILER_ARG1 "-arch ${CMAKE_SYSTEM_PROCESSOR}")
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_CXX_COMPILER_ARG1 "-arch ${CMAKE_SYSTEM_PROCESSOR}")
# TODO(tomfinegan): Handle bit code embedding.
endif () # DRACO_CMAKE_TOOLCHAINS_ARM_IOS_COMMON_CMAKE_

View File

@@ -0,0 +1,12 @@
if (NOT DRACO_CMAKE_TOOLCHAINS_ARM64_ANDROID_NDK_LIBCPP_CMAKE_)
set(DRACO_CMAKE_TOOLCHAINS_ARM64_ANDROID_NDK_LIBCPP_CMAKE_ 1)
include("${CMAKE_CURRENT_LIST_DIR}/../util.cmake")
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_ANDROID_ARCH_ABI arm64-v8a)
require_variable(CMAKE_ANDROID_NDK)
set_variable_if_unset(CMAKE_SYSTEM_VERSION 21)
set_variable_if_unset(CMAKE_ANDROID_STL_TYPE c++_static)
endif () # DRACO_CMAKE_TOOLCHAINS_ARM64_ANDROID_NDK_LIBCPP_CMAKE_

View File

@@ -0,0 +1,14 @@
if (NOT DRACO_CMAKE_TOOLCHAINS_ARM64_IOS_CMAKE_)
set(DRACO_CMAKE_TOOLCHAINS_ARM64_IOS_CMAKE_ 1)
if (XCODE)
# TODO(tomfinegan): Handle arm builds in Xcode.
message(FATAL_ERROR "This toolchain does not support Xcode.")
endif ()
set(CMAKE_SYSTEM_PROCESSOR "arm64")
set(CMAKE_OSX_ARCHITECTURES "arm64")
include("${CMAKE_CURRENT_LIST_DIR}/arm-ios-common.cmake")
endif () # DRACO_CMAKE_TOOLCHAINS_ARM64_IOS_CMAKE_

View File

@@ -0,0 +1,18 @@
if (NOT DRACO_CMAKE_TOOLCHAINS_ARM64_LINUX_GCC_CMAKE_)
set(DRACO_CMAKE_TOOLCHAINS_ARM64_LINUX_GCC_CMAKE_ 1)
set(CMAKE_SYSTEM_NAME "Linux")
if ("${CROSS}" STREQUAL "")
# Default the cross compiler prefix to something known to work.
set(CROSS aarch64-linux-gnu-)
endif ()
set(CMAKE_C_COMPILER ${CROSS}gcc)
set(CMAKE_CXX_COMPILER ${CROSS}g++)
set(AS_EXECUTABLE ${CROSS}as)
set(CMAKE_C_COMPILER_ARG1 "-march=armv8-a")
set(CMAKE_CXX_COMPILER_ARG1 "-march=armv8-a")
set(CMAKE_SYSTEM_PROCESSOR "arm64")
endif () # DRACO_CMAKE_TOOLCHAINS_ARM64_LINUX_GCC_CMAKE_

View File

@@ -0,0 +1,12 @@
if (NOT DRACO_CMAKE_TOOLCHAINS_ARMV7_ANDROID_NDK_LIBCPP_CMAKE_)
set(DRACO_CMAKE_TOOLCHAINS_ARMV7_ANDROID_NDK_LIBCPP_CMAKE_ 1)
include("${CMAKE_CURRENT_LIST_DIR}/../util.cmake")
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_ANDROID_ARCH_ABI armeabi-v7a)
require_variable(CMAKE_ANDROID_NDK)
set_variable_if_unset(CMAKE_SYSTEM_VERSION 18)
set_variable_if_unset(CMAKE_ANDROID_STL_TYPE c++_static)
endif () # DRACO_CMAKE_TOOLCHAINS_ARMV7_ANDROID_NDK_LIBCPP_CMAKE_

View File

@@ -0,0 +1,14 @@
if (NOT DRACO_CMAKE_TOOLCHAINS_ARMV7_IOS_CMAKE_)
set(DRACO_CMAKE_TOOLCHAINS_ARMV7_IOS_CMAKE_ 1)
if (XCODE)
# TODO(tomfinegan): Handle arm builds in Xcode.
message(FATAL_ERROR "This toolchain does not support Xcode.")
endif ()
set(CMAKE_SYSTEM_PROCESSOR "armv7")
set(CMAKE_OSX_ARCHITECTURES "armv7")
include("${CMAKE_CURRENT_LIST_DIR}/arm-ios-common.cmake")
endif () # DRACO_CMAKE_TOOLCHAINS_ARMV7_IOS_CMAKE_

View File

@@ -0,0 +1,24 @@
if (NOT DRACO_CMAKE_TOOLCHAINS_ARMV7_LINUX_GCC_CMAKE_)
set(DRACO_CMAKE_TOOLCHAINS_ARMV7_LINUX_GCC_CMAKE_ 1)
set(CMAKE_SYSTEM_NAME "Linux")
if ("${CROSS}" STREQUAL "")
# Default the cross compiler prefix to something known to work.
set(CROSS arm-linux-gnueabihf-)
endif ()
if (NOT ${CROSS} MATCHES hf-$)
set(DRACO_EXTRA_TOOLCHAIN_FLAGS "-mfloat-abi=softfp")
endif ()
set(CMAKE_C_COMPILER ${CROSS}gcc)
set(CMAKE_CXX_COMPILER ${CROSS}g++)
set(AS_EXECUTABLE ${CROSS}as)
set(CMAKE_C_COMPILER_ARG1
"-march=armv7-a -mfpu=neon ${DRACO_EXTRA_TOOLCHAIN_FLAGS}")
set(CMAKE_CXX_COMPILER_ARG1
"-march=armv7-a -mfpu=neon ${DRACO_EXTRA_TOOLCHAIN_FLAGS}")
set(CMAKE_SYSTEM_PROCESSOR "armv7")
endif () # DRACO_CMAKE_TOOLCHAINS_ARMV7_LINUX_GCC_CMAKE_

View File

@@ -0,0 +1,14 @@
if (NOT DRACO_CMAKE_TOOLCHAINS_ARMV7S_IOS_CMAKE_)
set(DRACO_CMAKE_TOOLCHAINS_ARMV7S_IOS_CMAKE_ 1)
if (XCODE)
# TODO(tomfinegan): Handle arm builds in Xcode.
message(FATAL_ERROR "This toolchain does not support Xcode.")
endif ()
set(CMAKE_SYSTEM_PROCESSOR "armv7s")
set(CMAKE_OSX_ARCHITECTURES "armv7s")
include("${CMAKE_CURRENT_LIST_DIR}/arm-ios-common.cmake")
endif () # DRACO_CMAKE_TOOLCHAINS_ARMV7S_IOS_CMAKE_

View File

@@ -0,0 +1,12 @@
if (NOT DRACO_CMAKE_TOOLCHAINS_X86_ANDROID_NDK_LIBCPP_CMAKE_)
set(DRACO_CMAKE_TOOLCHAINS_X86_ANDROID_NDK_LIBCPP_CMAKE_ 1)
include("${CMAKE_CURRENT_LIST_DIR}/../util.cmake")
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_ANDROID_ARCH_ABI x86)
require_variable(CMAKE_ANDROID_NDK)
set_variable_if_unset(CMAKE_SYSTEM_VERSION 18)
set_variable_if_unset(CMAKE_ANDROID_STL_TYPE c++_static)
endif () # DRACO_CMAKE_TOOLCHAINS_X86_ANDROID_NDK_LIBCPP_CMAKE_

View File

@@ -0,0 +1,12 @@
if (NOT DRACO_CMAKE_TOOLCHAINS_X86_64_ANDROID_NDK_LIBCPP_CMAKE_)
set(DRACO_CMAKE_TOOLCHAINS_X86_64_ANDROID_NDK_LIBCPP_CMAKE_ 1)
include("${CMAKE_CURRENT_LIST_DIR}/../util.cmake")
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_ANDROID_ARCH_ABI x86_64)
require_variable(CMAKE_ANDROID_NDK)
set_variable_if_unset(CMAKE_SYSTEM_VERSION 21)
set_variable_if_unset(CMAKE_ANDROID_STL_TYPE c++_static)
endif () # DRACO_CMAKE_TOOLCHAINS_X86_64_ANDROID_NDK_LIBCPP_CMAKE_

73
extern/draco/dracoenc/cmake/util.cmake vendored Normal file
View File

@@ -0,0 +1,73 @@
if (NOT DRACO_CMAKE_UTIL_CMAKE_)
set(DRACO_CMAKE_UTIL_CMAKE_ 1)
# Creates dummy source file in $draco_build_dir named $basename.$extension and
# returns the full path to the dummy source file via the $out_file_path
# parameter.
function (create_dummy_source_file basename extension out_file_path)
set(dummy_source_file "${draco_build_dir}/${basename}.${extension}")
file(WRITE "${dummy_source_file}"
"// Generated file. DO NOT EDIT!\n"
"// ${target_name} needs a ${extension} file to force link language, \n"
"// or to silence a harmless CMake warning: Ignore me.\n"
"void ${target_name}_dummy_function(void) {}\n")
set(${out_file_path} ${dummy_source_file} PARENT_SCOPE)
endfunction ()
# Convenience function for adding a dummy source file to $target_name using
# $extension as the file extension. Wraps create_dummy_source_file().
function (add_dummy_source_file_to_target target_name extension)
create_dummy_source_file("${target_name}" "${extension}" "dummy_source_file")
target_sources(${target_name} PRIVATE ${dummy_source_file})
endfunction ()
# Extracts the version number from $version_file and returns it to the user via
# $version_string_out_var. This is achieved by finding the first instance of
# the kDracoVersion variable and then removing everything but the string literal
# assigned to the variable. Quotes and semicolon are stripped from the returned
# string.
function (extract_version_string version_file version_string_out_var)
file(STRINGS "${version_file}" draco_version REGEX "kDracoVersion")
list(GET draco_version 0 draco_version)
string(REPLACE "static const char kDracoVersion[] = " "" draco_version
"${draco_version}")
string(REPLACE ";" "" draco_version "${draco_version}")
string(REPLACE "\"" "" draco_version "${draco_version}")
set("${version_string_out_var}" "${draco_version}" PARENT_SCOPE)
endfunction ()
# Sets CMake compiler launcher to $launcher_name when $launcher_name is found in
# $PATH. Warns user about ignoring build flag $launcher_flag when $launcher_name
# is not found in $PATH.
function (set_compiler_launcher launcher_flag launcher_name)
find_program(launcher_path "${launcher_name}")
if (launcher_path)
set(CMAKE_C_COMPILER_LAUNCHER "${launcher_path}" PARENT_SCOPE)
set(CMAKE_CXX_COMPILER_LAUNCHER "${launcher_path}" PARENT_SCOPE)
message("--- Using ${launcher_name} as compiler launcher.")
else ()
message(WARNING
"--- Cannot find ${launcher_name}, ${launcher_flag} ignored.")
endif ()
endfunction ()
# Terminates CMake execution when $var_name is unset in the environment. Sets
# CMake variable to the value of the environment variable when the variable is
# present in the environment.
macro(require_variable var_name)
if ("$ENV{${var_name}}" STREQUAL "")
message(FATAL_ERROR "${var_name} must be set in environment.")
endif ()
set_variable_if_unset(${var_name} "")
endmacro ()
# Sets $var_name to $default_value if not already set in the environment.
macro (set_variable_if_unset var_name default_value)
if (NOT "$ENV{${var_name}}" STREQUAL "")
set(${var_name} $ENV{${var_name}})
else ()
set(${var_name} ${default_value})
endif ()
endmacro ()
endif() # DRACO_CMAKE_UTIL_CMAKE_

View File

@@ -29,9 +29,8 @@ bool KeyframeAnimation::SetTimestamps(
} else {
// Check if the number of frames is consistent with
// the existing keyframes.
if (num_frames != num_points()) {
if (num_frames != num_points())
return false;
}
}
} else {
// This is the first attribute.
@@ -41,8 +40,10 @@ bool KeyframeAnimation::SetTimestamps(
// Add attribute for time stamp data.
std::unique_ptr<PointAttribute> timestamp_att =
std::unique_ptr<PointAttribute>(new PointAttribute());
timestamp_att->Init(GeometryAttribute::GENERIC, 1, DT_FLOAT32, false,
num_frames);
timestamp_att->Init(GeometryAttribute::GENERIC, nullptr, 1, DT_FLOAT32, false,
sizeof(float), 0);
timestamp_att->SetIdentityMapping();
timestamp_att->Reset(num_frames);
for (PointIndex i(0); i < num_frames; ++i) {
timestamp_att->SetAttributeValue(timestamp_att->mapped_index(i),
&timestamp[i.value()]);

View File

@@ -71,29 +71,30 @@ int32_t KeyframeAnimation::AddKeyframes(DataType data_type,
uint32_t num_components,
const std::vector<T> &data) {
// TODO(draco-eng): Verify T is consistent with |data_type|.
if (num_components == 0) {
if (num_components == 0)
return -1;
}
// If timestamps is not added yet, then reserve attribute 0 for timestamps.
if (!num_attributes()) {
// Add a temporary attribute with 0 points to fill attribute id 0.
std::unique_ptr<PointAttribute> temp_att =
std::unique_ptr<PointAttribute>(new PointAttribute());
temp_att->Init(GeometryAttribute::GENERIC, num_components, data_type, false,
0);
temp_att->Init(GeometryAttribute::GENERIC, nullptr, num_components,
data_type, false, DataTypeLength(data_type), 0);
temp_att->Reset(0);
this->AddAttribute(std::move(temp_att));
set_num_frames(data.size() / num_components);
}
if (data.size() != num_components * num_frames()) {
if (data.size() != num_components * num_frames())
return -1;
}
std::unique_ptr<PointAttribute> keyframe_att =
std::unique_ptr<PointAttribute>(new PointAttribute());
keyframe_att->Init(GeometryAttribute::GENERIC, num_components, data_type,
false, num_frames());
keyframe_att->Init(GeometryAttribute::GENERIC, nullptr, num_components,
data_type, false, DataTypeLength(data_type), 0);
keyframe_att->SetIdentityMapping();
keyframe_att->Reset(num_frames());
const size_t stride = num_components;
for (PointIndex i(0); i < num_frames(); ++i) {
keyframe_att->SetAttributeValue(keyframe_att->mapped_index(i),

View File

@@ -21,9 +21,8 @@ Status KeyframeAnimationDecoder::Decode(const DecoderOptions &options,
KeyframeAnimation *animation) {
const auto status = PointCloudSequentialDecoder::Decode(
options, in_buffer, static_cast<PointCloud *>(animation));
if (!status.ok()) {
if (!status.ok())
return status;
}
return OkStatus();
}

View File

@@ -0,0 +1,168 @@
// Copyright 2017 The Draco Authors.
//
// 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
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "draco/animation/keyframe_animation.h"
#include "draco/animation/keyframe_animation_decoder.h"
#include "draco/animation/keyframe_animation_encoder.h"
#include "draco/core/draco_test_base.h"
#include "draco/core/draco_test_utils.h"
namespace draco {
class KeyframeAnimationEncodingTest : public ::testing::Test {
protected:
KeyframeAnimationEncodingTest() {}
bool CreateAndAddTimestamps(int32_t num_frames) {
timestamps_.resize(num_frames);
for (int i = 0; i < timestamps_.size(); ++i)
timestamps_[i] = static_cast<draco::KeyframeAnimation::TimestampType>(i);
return keyframe_animation_.SetTimestamps(timestamps_);
}
int32_t CreateAndAddAnimationData(int32_t num_frames,
uint32_t num_components) {
// Create and add animation data with.
animation_data_.resize(num_frames * num_components);
for (int i = 0; i < animation_data_.size(); ++i)
animation_data_[i] = static_cast<float>(i);
return keyframe_animation_.AddKeyframes(draco::DT_FLOAT32, num_components,
animation_data_);
}
template <int num_components_t>
void CompareAnimationData(const KeyframeAnimation &animation0,
const KeyframeAnimation &animation1,
bool quantized) {
ASSERT_EQ(animation0.num_frames(), animation1.num_frames());
ASSERT_EQ(animation0.num_animations(), animation1.num_animations());
if (quantized) {
// TODO(hemmer) : Add test for stable quantization.
// Quantization will result in slightly different values.
// Skip comparing values.
return;
}
// Compare time stamp.
const auto timestamp_att0 = animation0.timestamps();
const auto timestamp_att1 = animation0.timestamps();
for (int i = 0; i < animation0.num_frames(); ++i) {
std::array<float, 1> att_value0;
std::array<float, 1> att_value1;
ASSERT_TRUE((timestamp_att0->GetValue<float, 1>(
draco::AttributeValueIndex(i), &att_value0)));
ASSERT_TRUE((timestamp_att1->GetValue<float, 1>(
draco::AttributeValueIndex(i), &att_value1)));
ASSERT_FLOAT_EQ(att_value0[0], att_value1[0]);
}
for (int animation_id = 1; animation_id < animation0.num_animations();
++animation_id) {
// Compare keyframe data.
const auto keyframe_att0 = animation0.keyframes(animation_id);
const auto keyframe_att1 = animation1.keyframes(animation_id);
ASSERT_EQ(keyframe_att0->num_components(),
keyframe_att1->num_components());
for (int i = 0; i < animation0.num_frames(); ++i) {
std::array<float, num_components_t> att_value0;
std::array<float, num_components_t> att_value1;
ASSERT_TRUE((keyframe_att0->GetValue<float, num_components_t>(
draco::AttributeValueIndex(i), &att_value0)));
ASSERT_TRUE((keyframe_att1->GetValue<float, num_components_t>(
draco::AttributeValueIndex(i), &att_value1)));
for (int j = 0; j < att_value0.size(); ++j) {
ASSERT_FLOAT_EQ(att_value0[j], att_value1[j]);
}
}
}
}
template <int num_components_t>
void TestKeyframeAnimationEncoding() {
TestKeyframeAnimationEncoding<num_components_t>(false);
}
template <int num_components_t>
void TestKeyframeAnimationEncoding(bool quantized) {
// Encode animation class.
draco::EncoderBuffer buffer;
draco::KeyframeAnimationEncoder encoder;
EncoderOptions options = EncoderOptions::CreateDefaultOptions();
if (quantized) {
// Set quantization for timestamps.
options.SetAttributeInt(0, "quantization_bits", 20);
// Set quantization for keyframes.
for (int i = 1; i <= keyframe_animation_.num_animations(); ++i) {
options.SetAttributeInt(i, "quantization_bits", 20);
}
}
ASSERT_TRUE(
encoder.EncodeKeyframeAnimation(keyframe_animation_, options, &buffer)
.ok());
draco::DecoderBuffer dec_decoder;
draco::KeyframeAnimationDecoder decoder;
DecoderBuffer dec_buffer;
dec_buffer.Init(buffer.data(), buffer.size());
// Decode animation class.
std::unique_ptr<KeyframeAnimation> decoded_animation(
new KeyframeAnimation());
DecoderOptions dec_options;
ASSERT_TRUE(
decoder.Decode(dec_options, &dec_buffer, decoded_animation.get()).ok());
// Verify if animation before and after compression is identical.
CompareAnimationData<num_components_t>(keyframe_animation_,
*decoded_animation, quantized);
}
draco::KeyframeAnimation keyframe_animation_;
std::vector<draco::KeyframeAnimation::TimestampType> timestamps_;
std::vector<float> animation_data_;
};
TEST_F(KeyframeAnimationEncodingTest, OneComponent) {
const int num_frames = 1;
ASSERT_TRUE(CreateAndAddTimestamps(num_frames));
ASSERT_EQ(CreateAndAddAnimationData(num_frames, 1), 1);
TestKeyframeAnimationEncoding<1>();
}
TEST_F(KeyframeAnimationEncodingTest, ManyComponents) {
const int num_frames = 100;
ASSERT_TRUE(CreateAndAddTimestamps(num_frames));
ASSERT_EQ(CreateAndAddAnimationData(num_frames, 100), 1);
TestKeyframeAnimationEncoding<100>();
}
TEST_F(KeyframeAnimationEncodingTest, ManyComponentsWithQuantization) {
const int num_frames = 100;
ASSERT_TRUE(CreateAndAddTimestamps(num_frames));
ASSERT_EQ(CreateAndAddAnimationData(num_frames, 4), 1);
// Test compression with quantization.
TestKeyframeAnimationEncoding<4>(true);
}
TEST_F(KeyframeAnimationEncodingTest, MultipleAnimations) {
const int num_frames = 5;
ASSERT_TRUE(CreateAndAddTimestamps(num_frames));
ASSERT_EQ(CreateAndAddAnimationData(num_frames, 3), 1);
ASSERT_EQ(CreateAndAddAnimationData(num_frames, 3), 2);
TestKeyframeAnimationEncoding<3>();
}
} // namespace draco

View File

@@ -0,0 +1,102 @@
// Copyright 2017 The Draco Authors.
//
// 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
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "draco/animation/keyframe_animation.h"
#include "draco/core/draco_test_base.h"
namespace {
class KeyframeAnimationTest : public ::testing::Test {
protected:
KeyframeAnimationTest() {}
bool CreateAndAddTimestamps(int32_t num_frames) {
timestamps_.resize(num_frames);
for (int i = 0; i < timestamps_.size(); ++i)
timestamps_[i] = static_cast<draco::KeyframeAnimation::TimestampType>(i);
return keyframe_animation_.SetTimestamps(timestamps_);
}
int32_t CreateAndAddAnimationData(int32_t num_frames,
uint32_t num_components) {
// Create and add animation data with.
animation_data_.resize(num_frames * num_components);
for (int i = 0; i < animation_data_.size(); ++i)
animation_data_[i] = static_cast<float>(i);
return keyframe_animation_.AddKeyframes(draco::DT_FLOAT32, num_components,
animation_data_);
}
template <int num_components_t>
void CompareAnimationData() {
// Compare time stamp.
const auto timestamp_att = keyframe_animation_.timestamps();
for (int i = 0; i < timestamps_.size(); ++i) {
std::array<float, 1> att_value;
ASSERT_TRUE((timestamp_att->GetValue<float, 1>(
draco::AttributeValueIndex(i), &att_value)));
ASSERT_FLOAT_EQ(att_value[0], i);
}
// Compare keyframe data.
const auto keyframe_att = keyframe_animation_.keyframes(1);
for (int i = 0; i < animation_data_.size() / num_components_t; ++i) {
std::array<float, num_components_t> att_value;
ASSERT_TRUE((keyframe_att->GetValue<float, num_components_t>(
draco::AttributeValueIndex(i), &att_value)));
for (int j = 0; j < num_components_t; ++j) {
ASSERT_FLOAT_EQ(att_value[j], i * num_components_t + j);
}
}
}
template <int num_components_t>
void TestKeyframeAnimation(int32_t num_frames) {
ASSERT_TRUE(CreateAndAddTimestamps(num_frames));
ASSERT_EQ(CreateAndAddAnimationData(num_frames, num_components_t), 1);
CompareAnimationData<num_components_t>();
}
draco::KeyframeAnimation keyframe_animation_;
std::vector<draco::KeyframeAnimation::TimestampType> timestamps_;
std::vector<float> animation_data_;
};
// Test animation with 1 component and 10 frames.
TEST_F(KeyframeAnimationTest, OneComponent) { TestKeyframeAnimation<1>(10); }
// Test animation with 4 component and 10 frames.
TEST_F(KeyframeAnimationTest, FourComponent) { TestKeyframeAnimation<4>(10); }
// Test adding animation data before timestamp.
TEST_F(KeyframeAnimationTest, AddingAnimationFirst) {
ASSERT_EQ(CreateAndAddAnimationData(5, 1), 1);
ASSERT_TRUE(CreateAndAddTimestamps(5));
}
// Test adding timestamp more than once.
TEST_F(KeyframeAnimationTest, ErrorAddingTimestampsTwice) {
ASSERT_TRUE(CreateAndAddTimestamps(5));
ASSERT_FALSE(CreateAndAddTimestamps(5));
}
// Test animation with multiple animation data.
TEST_F(KeyframeAnimationTest, MultipleAnimationData) {
const int num_frames = 5;
ASSERT_TRUE(CreateAndAddTimestamps(num_frames));
ASSERT_EQ(CreateAndAddAnimationData(num_frames, 1), 1);
ASSERT_EQ(CreateAndAddAnimationData(num_frames, 2), 2);
}
} // namespace

View File

@@ -25,9 +25,8 @@ bool AttributeOctahedronTransform::InitFromAttribute(
const AttributeTransformData *const transform_data =
attribute.GetAttributeTransformData();
if (!transform_data ||
transform_data->transform_type() != ATTRIBUTE_OCTAHEDRON_TRANSFORM) {
transform_data->transform_type() != ATTRIBUTE_OCTAHEDRON_TRANSFORM)
return false; // Wrong transform type.
}
quantization_bits_ = transform_data->GetParameterValue<int32_t>(0);
return true;
}
@@ -69,9 +68,8 @@ AttributeOctahedronTransform::GeneratePortableAttribute(
float att_val[3];
int32_t dst_index = 0;
OctahedronToolBox converter;
if (!converter.SetQuantizationBits(quantization_bits_)) {
if (!converter.SetQuantizationBits(quantization_bits_))
return nullptr;
}
for (uint32_t i = 0; i < point_ids.size(); ++i) {
const AttributeValueIndex att_val_id = attribute.mapped_index(point_ids[i]);
attribute.GetValue(att_val_id, att_val);

View File

@@ -25,9 +25,8 @@ bool AttributeQuantizationTransform::InitFromAttribute(
const AttributeTransformData *const transform_data =
attribute.GetAttributeTransformData();
if (!transform_data ||
transform_data->transform_type() != ATTRIBUTE_QUANTIZATION_TRANSFORM) {
transform_data->transform_type() != ATTRIBUTE_QUANTIZATION_TRANSFORM)
return false; // Wrong transform type.
}
int32_t byte_offset = 0;
quantization_bits_ = transform_data->GetParameterValue<int32_t>(byte_offset);
byte_offset += 4;
@@ -81,30 +80,22 @@ bool AttributeQuantizationTransform::ComputeParameters(
++i) {
attribute.GetValue(i, att_val.get());
for (int c = 0; c < num_components; ++c) {
if (min_values_[c] > att_val[c]) {
if (min_values_[c] > att_val[c])
min_values_[c] = att_val[c];
}
if (max_values[c] < att_val[c]) {
if (max_values[c] < att_val[c])
max_values[c] = att_val[c];
}
}
}
for (int c = 0; c < num_components; ++c) {
if (std::isnan(min_values_[c]) || std::isinf(min_values_[c]) ||
std::isnan(max_values[c]) || std::isinf(max_values[c])) {
return false;
}
const float dif = max_values[c] - min_values_[c];
if (dif > range_) {
if (dif > range_)
range_ = dif;
}
}
// In case all values are the same, initialize the range to unit length. This
// will ensure that all values are quantized properly to the same value.
if (range_ == 0.f) {
if (range_ == 0.f)
range_ = 1.f;
}
return true;
}

View File

@@ -14,6 +14,8 @@
//
#include "draco/attributes/geometry_attribute.h"
using std::array;
namespace draco {
GeometryAttribute::GeometryAttribute()
@@ -43,9 +45,8 @@ void GeometryAttribute::Init(GeometryAttribute::Type attribute_type,
}
bool GeometryAttribute::CopyFrom(const GeometryAttribute &src_att) {
if (buffer_ == nullptr || src_att.buffer_ == nullptr) {
if (buffer_ == nullptr || src_att.buffer_ == nullptr)
return false;
}
buffer_->Update(src_att.buffer_->data(), src_att.buffer_->data_size());
num_components_ = src_att.num_components_;
data_type_ = src_att.data_type_;
@@ -54,35 +55,27 @@ bool GeometryAttribute::CopyFrom(const GeometryAttribute &src_att) {
byte_offset_ = src_att.byte_offset_;
attribute_type_ = src_att.attribute_type_;
buffer_descriptor_ = src_att.buffer_descriptor_;
unique_id_ = src_att.unique_id_;
return true;
}
bool GeometryAttribute::operator==(const GeometryAttribute &va) const {
if (attribute_type_ != va.attribute_type_) {
if (attribute_type_ != va.attribute_type_)
return false;
}
// It's OK to compare just the buffer descriptors here. We don't need to
// compare the buffers themselves.
if (buffer_descriptor_.buffer_id != va.buffer_descriptor_.buffer_id) {
if (buffer_descriptor_.buffer_id != va.buffer_descriptor_.buffer_id)
return false;
}
if (buffer_descriptor_.buffer_update_count !=
va.buffer_descriptor_.buffer_update_count) {
va.buffer_descriptor_.buffer_update_count)
return false;
}
if (num_components_ != va.num_components_) {
if (num_components_ != va.num_components_)
return false;
}
if (data_type_ != va.data_type_) {
if (data_type_ != va.data_type_)
return false;
}
if (byte_stride_ != va.byte_stride_) {
if (byte_stride_ != va.byte_stride_)
return false;
}
if (byte_offset_ != va.byte_offset_) {
if (byte_offset_ != va.byte_offset_)
return false;
}
return true;
}

View File

@@ -91,9 +91,8 @@ class GeometryAttribute {
// Byte address of the attribute index.
const int64_t byte_pos = byte_offset_ + byte_stride_ * att_index.value();
// Check we are not reading past end of data.
if (byte_pos + sizeof(*out) > buffer_->data_size()) {
if (byte_pos + sizeof(*out) > buffer_->data_size())
return false;
}
buffer_->Read(byte_pos, &((*out)[0]), sizeof(*out));
return true;
}
@@ -119,13 +118,6 @@ class GeometryAttribute {
buffer_->Read(byte_pos, out_data, byte_stride_);
}
// Sets a value of an attribute entry. The input value must be allocated to
// cover all components of a single attribute entry.
void SetAttributeValue(AttributeValueIndex entry_index, const void *value) {
const int64_t byte_pos = entry_index.value() * byte_stride();
buffer_->Write(byte_pos, value, byte_stride());
}
// DEPRECATED: Use
// ConvertValue(AttributeValueIndex att_id,
// int out_num_components,
@@ -147,9 +139,8 @@ class GeometryAttribute {
template <typename OutT>
bool ConvertValue(AttributeValueIndex att_id, int8_t out_num_components,
OutT *out_val) const {
if (out_val == nullptr) {
if (out_val == nullptr)
return false;
}
switch (data_type_) {
case DT_INT8:
return ConvertTypedValue<int8_t, OutT>(att_id, out_num_components,
@@ -200,26 +191,6 @@ class GeometryAttribute {
return ConvertValue<OutT>(att_index, num_components_, out_value);
}
// Utility function. Returns |attribute_type| as std::string.
static std::string TypeToString(Type attribute_type) {
switch (attribute_type) {
case INVALID:
return "INVALID";
case POSITION:
return "POSITION";
case NORMAL:
return "NORMAL";
case COLOR:
return "COLOR";
case TEX_COORD:
return "TEX_COORD";
case GENERIC:
return "GENERIC";
default:
return "UNKNOWN";
}
}
bool operator==(const GeometryAttribute &va) const;
// Returns the type of the attribute indicating the nature of the attribute.
@@ -314,8 +285,8 @@ struct GeometryAttributeHasher {
size_t hash = HashCombine(va.buffer_descriptor_.buffer_id,
va.buffer_descriptor_.buffer_update_count);
hash = HashCombine(va.num_components_, hash);
hash = HashCombine(static_cast<int8_t>(va.data_type_), hash);
hash = HashCombine(static_cast<int8_t>(va.attribute_type_), hash);
hash = HashCombine((int8_t)va.data_type_, hash);
hash = HashCombine((int8_t)va.attribute_type_, hash);
hash = HashCombine(va.byte_stride_, hash);
return HashCombine(va.byte_offset_, hash);
}

View File

@@ -32,32 +32,20 @@ PointAttribute::PointAttribute(const GeometryAttribute &att)
num_unique_entries_(0),
identity_mapping_(false) {}
void PointAttribute::Init(Type attribute_type, int8_t num_components,
DataType data_type, bool normalized,
size_t num_attribute_values) {
attribute_buffer_ = std::unique_ptr<DataBuffer>(new DataBuffer());
GeometryAttribute::Init(attribute_type, attribute_buffer_.get(),
num_components, data_type, normalized,
DataTypeLength(data_type) * num_components, 0);
Reset(num_attribute_values);
SetIdentityMapping();
}
void PointAttribute::CopyFrom(const PointAttribute &src_att) {
if (buffer() == nullptr) {
// If the destination attribute doesn't have a valid buffer, create it.
attribute_buffer_ = std::unique_ptr<DataBuffer>(new DataBuffer());
ResetBuffer(attribute_buffer_.get(), 0, 0);
}
if (!GeometryAttribute::CopyFrom(src_att)) {
if (!GeometryAttribute::CopyFrom(src_att))
return;
}
identity_mapping_ = src_att.identity_mapping_;
num_unique_entries_ = src_att.num_unique_entries_;
indices_map_ = src_att.indices_map_;
if (src_att.attribute_transform_data_) {
attribute_transform_data_ = std::unique_ptr<AttributeTransformData>(
new AttributeTransformData(*src_att.attribute_transform_data_));
new AttributeTransformData(*src_att.attribute_transform_data_.get()));
} else {
attribute_transform_data_ = nullptr;
}
@@ -68,20 +56,14 @@ bool PointAttribute::Reset(size_t num_attribute_values) {
attribute_buffer_ = std::unique_ptr<DataBuffer>(new DataBuffer());
}
const int64_t entry_size = DataTypeLength(data_type()) * num_components();
if (!attribute_buffer_->Update(nullptr, num_attribute_values * entry_size)) {
if (!attribute_buffer_->Update(nullptr, num_attribute_values * entry_size))
return false;
}
// Assign the new buffer to the parent attribute.
ResetBuffer(attribute_buffer_.get(), entry_size, 0);
num_unique_entries_ = static_cast<uint32_t>(num_attribute_values);
return true;
}
void PointAttribute::Resize(size_t new_num_unique_entries) {
num_unique_entries_ = static_cast<uint32_t>(new_num_unique_entries);
attribute_buffer_->Resize(new_num_unique_entries * byte_stride());
}
#ifdef DRACO_ATTRIBUTE_VALUES_DEDUPLICATION_SUPPORTED
AttributeValueIndex::ValueType PointAttribute::DeduplicateValues(
const GeometryAttribute &in_att) {
@@ -118,9 +100,8 @@ AttributeValueIndex::ValueType PointAttribute::DeduplicateValues(
default:
return -1; // Unsupported data type.
}
if (unique_vals == 0) {
if (unique_vals == 0)
return -1; // Unexpected error.
}
return unique_vals;
}
@@ -200,9 +181,8 @@ AttributeValueIndex::ValueType PointAttribute::DeduplicateFormattedValues(
++unique_vals;
}
}
if (unique_vals == num_unique_entries_) {
if (unique_vals == num_unique_entries_)
return unique_vals.value(); // Nothing has changed.
}
if (is_mapping_identity()) {
// Change identity mapping to the explicit one.
// The number of points is equal to the number of old unique values.

View File

@@ -17,12 +17,13 @@
#include <memory>
#include "draco/draco_features.h"
#include "draco/attributes/attribute_transform_data.h"
#include "draco/attributes/geometry_attribute.h"
#include "draco/core/draco_index_type_vector.h"
#include "draco/core/hash_utils.h"
#include "draco/core/macros.h"
#include "draco/draco_features.h"
namespace draco {
@@ -40,12 +41,6 @@ class PointAttribute : public GeometryAttribute {
PointAttribute(PointAttribute &&attribute) = default;
PointAttribute &operator=(PointAttribute &&attribute) = default;
// Initializes a point attribute. By default the attribute will be set to
// identity mapping between point indices and attribute values. To set custom
// mapping use SetExplicitMapping() function.
void Init(Type attribute_type, int8_t num_components, DataType data_type,
bool normalized, size_t num_attribute_values);
// Copies attribute data from the provided |src_att| attribute.
void CopyFrom(const PointAttribute &src_att);
@@ -54,17 +49,15 @@ class PointAttribute : public GeometryAttribute {
size_t size() const { return num_unique_entries_; }
AttributeValueIndex mapped_index(PointIndex point_index) const {
if (identity_mapping_) {
if (identity_mapping_)
return AttributeValueIndex(point_index.value());
}
return indices_map_[point_index];
}
DataBuffer *buffer() const { return attribute_buffer_.get(); }
bool is_mapping_identity() const { return identity_mapping_; }
size_t indices_map_size() const {
if (is_mapping_identity()) {
if (is_mapping_identity())
return 0;
}
return indices_map_.size();
}
@@ -72,14 +65,10 @@ class PointAttribute : public GeometryAttribute {
return GetAddress(mapped_index(point_index));
}
// Sets the new number of unique attribute entries for the attribute. The
// function resizes the attribute storage to hold |num_attribute_values|
// entries.
// All previous entries with AttributeValueIndex < |num_attribute_values|
// are preserved. Caller needs to ensure that the PointAttribute is still
// valid after the resizing operation (that is, each point is mapped to a
// valid attribute value).
void Resize(size_t new_num_unique_entries);
// Sets the new number of unique attribute entries for the attribute.
void Resize(size_t new_num_unique_entries) {
num_unique_entries_ = static_cast<uint32_t>(new_num_unique_entries);
}
// Functions for setting the type of mapping between point indices and
// attribute entry ids.
@@ -103,6 +92,13 @@ class PointAttribute : public GeometryAttribute {
indices_map_[point_index] = entry_index;
}
// Sets a value of an attribute entry. The input value must be allocated to
// cover all components of a single attribute entry.
void SetAttributeValue(AttributeValueIndex entry_index, const void *value) {
const int64_t byte_pos = entry_index.value() * byte_stride();
buffer()->Write(byte_pos, value, byte_stride());
}
// Same as GeometryAttribute::GetValue(), but using point id as the input.
// Mapping to attribute value index is performed automatically.
void GetMappedValue(PointIndex point_index, void *out_data) const {
@@ -169,7 +165,7 @@ struct PointAttributeHasher {
hash = HashCombine(attribute.identity_mapping_, hash);
hash = HashCombine(attribute.num_unique_entries_, hash);
hash = HashCombine(attribute.indices_map_.size(), hash);
if (!attribute.indices_map_.empty()) {
if (attribute.indices_map_.size() > 0) {
const uint64_t indices_hash = FingerprintString(
reinterpret_cast<const char *>(attribute.indices_map_.data()),
attribute.indices_map_.size());

View File

@@ -0,0 +1,129 @@
// Copyright 2017 The Draco Authors.
//
// 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
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "draco/attributes/point_attribute.h"
#include "draco/core/draco_test_base.h"
namespace {
class PointAttributeTest : public ::testing::Test {
protected:
PointAttributeTest() {}
};
TEST_F(PointAttributeTest, TestCopy) {
// This test verifies that PointAttribute can copy data from another point
// attribute.
draco::GeometryAttribute pos_att;
pos_att.Init(draco::GeometryAttribute::POSITION, nullptr, 1, draco::DT_INT32,
false, 4, 0);
draco::PointAttribute pa(pos_att);
pa.SetIdentityMapping();
pa.Reset(10);
for (int32_t i = 0; i < 10; ++i) {
pa.SetAttributeValue(draco::AttributeValueIndex(i), &i);
}
draco::PointAttribute other_pa;
other_pa.CopyFrom(pa);
draco::PointAttributeHasher hasher;
ASSERT_EQ(hasher(pa), hasher(other_pa));
// The hash function does not actually compute the hash from attribute values,
// so ensure the data got copied correctly as well.
for (int32_t i = 0; i < 10; ++i) {
int32_t data;
other_pa.GetValue(draco::AttributeValueIndex(i), &data);
ASSERT_EQ(data, i);
}
}
TEST_F(PointAttributeTest, TestGetValueFloat) {
draco::GeometryAttribute pos_att;
pos_att.Init(draco::GeometryAttribute::POSITION, nullptr, 3,
draco::DT_FLOAT32, false, 4, 0);
draco::PointAttribute pa(pos_att);
pa.SetIdentityMapping();
pa.Reset(5);
float points[3];
for (int32_t i = 0; i < 5; ++i) {
points[0] = i * 3.0;
points[1] = (i * 3.0) + 1.0;
points[2] = (i * 3.0) + 2.0;
pa.SetAttributeValue(draco::AttributeValueIndex(i), &points);
}
for (int32_t i = 0; i < 5; ++i) {
pa.GetValue(draco::AttributeValueIndex(i), &points);
ASSERT_FLOAT_EQ(points[0], i * 3.0);
ASSERT_FLOAT_EQ(points[1], (i * 3.0) + 1.0);
ASSERT_FLOAT_EQ(points[2], (i * 3.0) + 2.0);
}
}
TEST_F(PointAttributeTest, TestGetArray) {
draco::GeometryAttribute pos_att;
pos_att.Init(draco::GeometryAttribute::POSITION, nullptr, 3,
draco::DT_FLOAT32, false, 4, 0);
draco::PointAttribute pa(pos_att);
pa.SetIdentityMapping();
pa.Reset(5);
float points[3];
for (int32_t i = 0; i < 5; ++i) {
points[0] = i * 3.0;
points[1] = (i * 3.0) + 1.0;
points[2] = (i * 3.0) + 2.0;
pa.SetAttributeValue(draco::AttributeValueIndex(i), &points);
}
for (int32_t i = 0; i < 5; ++i) {
std::array<float, 3> att_value;
att_value = pa.GetValue<float, 3>(draco::AttributeValueIndex(i));
ASSERT_FLOAT_EQ(att_value[0], i * 3.0);
ASSERT_FLOAT_EQ(att_value[1], (i * 3.0) + 1.0);
ASSERT_FLOAT_EQ(att_value[2], (i * 3.0) + 2.0);
}
for (int32_t i = 0; i < 5; ++i) {
std::array<float, 3> att_value;
EXPECT_TRUE(
(pa.GetValue<float, 3>(draco::AttributeValueIndex(i), &att_value)));
ASSERT_FLOAT_EQ(att_value[0], i * 3.0);
ASSERT_FLOAT_EQ(att_value[1], (i * 3.0) + 1.0);
ASSERT_FLOAT_EQ(att_value[2], (i * 3.0) + 2.0);
}
}
TEST_F(PointAttributeTest, TestArrayReadError) {
draco::GeometryAttribute pos_att;
pos_att.Init(draco::GeometryAttribute::POSITION, nullptr, 3,
draco::DT_FLOAT32, false, 4, 0);
draco::PointAttribute pa(pos_att);
pa.SetIdentityMapping();
pa.Reset(5);
float points[3];
for (int32_t i = 0; i < 5; ++i) {
points[0] = i * 3.0;
points[1] = (i * 3.0) + 1.0;
points[2] = (i * 3.0) + 2.0;
pa.SetAttributeValue(draco::AttributeValueIndex(i), &points);
}
std::array<float, 3> att_value;
EXPECT_FALSE(
(pa.GetValue<float, 3>(draco::AttributeValueIndex(5), &att_value)));
}
} // namespace

View File

@@ -33,42 +33,31 @@ bool AttributesDecoder::DecodeAttributesDecoderData(DecoderBuffer *in_buffer) {
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (point_cloud_decoder_->bitstream_version() <
DRACO_BITSTREAM_VERSION(2, 0)) {
if (!in_buffer->Decode(&num_attributes)) {
if (!in_buffer->Decode(&num_attributes))
return false;
}
} else
#endif
{
if (!DecodeVarint(&num_attributes, in_buffer)) {
if (!DecodeVarint(&num_attributes, in_buffer))
return false;
}
}
if (num_attributes == 0) {
if (num_attributes == 0)
return false;
}
point_attribute_ids_.resize(num_attributes);
PointCloud *pc = point_cloud_;
for (uint32_t i = 0; i < num_attributes; ++i) {
// Decode attribute descriptor data.
uint8_t att_type, data_type, num_components, normalized;
if (!in_buffer->Decode(&att_type)) {
if (!in_buffer->Decode(&att_type))
return false;
}
if (!in_buffer->Decode(&data_type)) {
if (!in_buffer->Decode(&data_type))
return false;
}
if (!in_buffer->Decode(&num_components)) {
if (!in_buffer->Decode(&num_components))
return false;
}
if (!in_buffer->Decode(&normalized)) {
if (!in_buffer->Decode(&normalized))
return false;
}
if (att_type >= GeometryAttribute::NAMED_ATTRIBUTES_COUNT) {
if (data_type <= DT_INVALID || data_type >= DT_TYPES_COUNT)
return false;
}
if (data_type == DT_INVALID || data_type >= DT_TYPES_COUNT) {
return false;
}
const DataType draco_dt = static_cast<DataType>(data_type);
// Add the attribute to the point cloud
@@ -81,9 +70,8 @@ bool AttributesDecoder::DecodeAttributesDecoderData(DecoderBuffer *in_buffer) {
if (point_cloud_decoder_->bitstream_version() <
DRACO_BITSTREAM_VERSION(1, 3)) {
uint16_t custom_id;
if (!in_buffer->Decode(&custom_id)) {
if (!in_buffer->Decode(&custom_id))
return false;
}
// TODO(draco-eng): Add "custom_id" to attribute metadata.
unique_id = static_cast<uint32_t>(custom_id);
ga.set_unique_id(unique_id);
@@ -99,10 +87,8 @@ bool AttributesDecoder::DecodeAttributesDecoderData(DecoderBuffer *in_buffer) {
point_attribute_ids_[i] = att_id;
// Update the inverse map.
if (att_id >=
static_cast<int32_t>(point_attribute_to_local_id_map_.size())) {
if (att_id >= static_cast<int32_t>(point_attribute_to_local_id_map_.size()))
point_attribute_to_local_id_map_.resize(att_id + 1, -1);
}
point_attribute_to_local_id_map_[att_id] = i;
}
return true;

View File

@@ -17,10 +17,11 @@
#include <vector>
#include "draco/draco_features.h"
#include "draco/compression/attributes/attributes_decoder_interface.h"
#include "draco/compression/point_cloud/point_cloud_decoder.h"
#include "draco/core/decoder_buffer.h"
#include "draco/draco_features.h"
#include "draco/point_cloud/point_cloud.h"
namespace draco {
@@ -53,15 +54,12 @@ class AttributesDecoder : public AttributesDecoderInterface {
// Decodes attribute data from the source buffer.
bool DecodeAttributes(DecoderBuffer *in_buffer) override {
if (!DecodePortableAttributes(in_buffer)) {
if (!DecodePortableAttributes(in_buffer))
return false;
}
if (!DecodeDataNeededByPortableTransforms(in_buffer)) {
if (!DecodeDataNeededByPortableTransforms(in_buffer))
return false;
}
if (!TransformAttributesToOriginalFormat()) {
if (!TransformAttributesToOriginalFormat())
return false;
}
return true;
}
@@ -69,9 +67,8 @@ class AttributesDecoder : public AttributesDecoderInterface {
int32_t GetLocalIdForPointAttribute(int32_t point_attribute_id) const {
const int id_map_size =
static_cast<int>(point_attribute_to_local_id_map_.size());
if (point_attribute_id >= id_map_size) {
if (point_attribute_id >= id_map_size)
return -1;
}
return point_attribute_to_local_id_map_[point_attribute_id];
}
virtual bool DecodePortableAttributes(DecoderBuffer *in_buffer) = 0;

View File

@@ -48,18 +48,15 @@ class AttributesEncoder {
// Encode attribute data to the target buffer.
virtual bool EncodeAttributes(EncoderBuffer *out_buffer) {
if (!TransformAttributesToPortableFormat()) {
if (!TransformAttributesToPortableFormat())
return false;
}
if (!EncodePortableAttributes(out_buffer)) {
if (!EncodePortableAttributes(out_buffer))
return false;
}
// Encode data needed by portable transforms after the attribute is encoded.
// This corresponds to the order in which the data is going to be decoded by
// the decoder.
if (!EncodeDataNeededByPortableTransforms(out_buffer)) {
if (!EncodeDataNeededByPortableTransforms(out_buffer))
return false;
}
return true;
}
@@ -90,9 +87,8 @@ class AttributesEncoder {
void AddAttributeId(int32_t id) {
point_attribute_ids_.push_back(id);
if (id >= static_cast<int32_t>(point_attribute_to_local_id_map_.size())) {
if (id >= static_cast<int32_t>(point_attribute_to_local_id_map_.size()))
point_attribute_to_local_id_map_.resize(id + 1, -1);
}
point_attribute_to_local_id_map_[id] =
static_cast<int32_t>(point_attribute_ids_.size()) - 1;
}
@@ -131,9 +127,8 @@ class AttributesEncoder {
int32_t GetLocalIdForPointAttribute(int32_t point_attribute_id) const {
const int id_map_size =
static_cast<int>(point_attribute_to_local_id_map_.size());
if (point_attribute_id >= id_map_size) {
if (point_attribute_id >= id_map_size)
return -1;
}
return point_attribute_to_local_id_map_[point_attribute_id];
}

View File

@@ -13,7 +13,6 @@
// limitations under the License.
//
#include "draco/compression/attributes/kd_tree_attributes_decoder.h"
#include "draco/compression/attributes/kd_tree_attributes_shared.h"
#include "draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.h"
#include "draco/compression/point_cloud/algorithms/float_points_tree_decoder.h"
@@ -93,7 +92,7 @@ class PointAttributeVectorOutputIterator {
const uint32_t &data_size = std::get<3>(att);
const uint32_t &num_components = std::get<4>(att);
const uint32_t *data_source = val.data() + offset;
if (data_size < 4) { // handle uint16_t, uint8_t
if (data_size != 4) { // handle uint16_t, uint8_t
// selectively copy data bytes
uint8_t *data_counter = data_;
for (uint32_t index = 0; index < num_components;
@@ -104,9 +103,8 @@ class PointAttributeVectorOutputIterator {
data_source = reinterpret_cast<uint32_t *>(data_);
}
const AttributeValueIndex avi = attribute->mapped_index(point_id_);
if (avi >= static_cast<uint32_t>(attribute->size())) {
if (avi >= static_cast<uint32_t>(attribute->size()))
return *this;
}
attribute->SetAttributeValue(avi, data_source);
}
return *this;
@@ -136,9 +134,8 @@ bool KdTreeAttributesDecoder::DecodePortableAttributes(
return true;
}
uint8_t compression_level = 0;
if (!in_buffer->Decode(&compression_level)) {
if (!in_buffer->Decode(&compression_level))
return false;
}
const int32_t num_points = GetDecoder()->point_cloud()->num_points();
// Decode data using the kd tree decoding into integer (portable) attributes.
@@ -200,51 +197,44 @@ bool KdTreeAttributesDecoder::DecodePortableAttributes(
switch (compression_level) {
case 0: {
DynamicIntegerPointsKdTreeDecoder<0> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
case 1: {
DynamicIntegerPointsKdTreeDecoder<1> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
case 2: {
DynamicIntegerPointsKdTreeDecoder<2> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
case 3: {
DynamicIntegerPointsKdTreeDecoder<3> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
case 4: {
DynamicIntegerPointsKdTreeDecoder<4> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
case 5: {
DynamicIntegerPointsKdTreeDecoder<5> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
case 6: {
DynamicIntegerPointsKdTreeDecoder<6> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
default:
@@ -266,26 +256,22 @@ bool KdTreeAttributesDecoder::DecodeDataNeededByPortableTransforms(
if (att->data_type() == DT_FLOAT32) {
const int num_components = att->num_components();
min_value.resize(num_components);
if (!in_buffer->Decode(&min_value[0], sizeof(float) * num_components)) {
if (!in_buffer->Decode(&min_value[0], sizeof(float) * num_components))
return false;
}
float max_value_dif;
if (!in_buffer->Decode(&max_value_dif)) {
if (!in_buffer->Decode(&max_value_dif))
return false;
}
uint8_t quantization_bits;
if (!in_buffer->Decode(&quantization_bits) || quantization_bits > 31) {
if (!in_buffer->Decode(&quantization_bits) || quantization_bits > 31)
return false;
}
AttributeQuantizationTransform transform;
transform.SetParameters(quantization_bits, min_value.data(),
num_components, max_value_dif);
const int num_transforms =
static_cast<int>(attribute_quantization_transforms_.size());
if (!transform.TransferToAttribute(
quantized_portable_attributes_[num_transforms].get())) {
quantized_portable_attributes_[num_transforms].get()))
return false;
}
attribute_quantization_transforms_.push_back(transform);
}
}
@@ -313,10 +299,6 @@ bool KdTreeAttributesDecoder::DecodeDataNeededByPortableTransforms(
const DataType data_type = att->data_type();
const uint32_t data_size = (std::max)(0, DataTypeLength(data_type));
const uint32_t num_components = att->num_components();
if (data_size > 4) {
return false;
}
atts[attribute_index] = std::make_tuple(
att, total_dimensionality, data_type, data_size, num_components);
// everything is treated as 32bit in the encoder.
@@ -328,30 +310,24 @@ bool KdTreeAttributesDecoder::DecodeDataNeededByPortableTransforms(
att->SetIdentityMapping();
// Decode method
uint8_t method;
if (!in_buffer->Decode(&method)) {
if (!in_buffer->Decode(&method))
return false;
}
if (method == KdTreeAttributesEncodingMethod::kKdTreeQuantizationEncoding) {
uint8_t compression_level = 0;
if (!in_buffer->Decode(&compression_level)) {
if (!in_buffer->Decode(&compression_level))
return false;
}
uint32_t num_points = 0;
if (!in_buffer->Decode(&num_points)) {
if (!in_buffer->Decode(&num_points))
return false;
}
att->Reset(num_points);
FloatPointsTreeDecoder decoder;
decoder.set_num_points_from_header(num_points);
PointAttributeVectorOutputIterator<float> out_it(atts);
if (!decoder.DecodePointCloud(in_buffer, out_it)) {
if (!decoder.DecodePointCloud(in_buffer, out_it))
return false;
}
} else if (method == KdTreeAttributesEncodingMethod::kKdTreeIntegerEncoding) {
uint8_t compression_level = 0;
if (!in_buffer->Decode(&compression_level)) {
if (!in_buffer->Decode(&compression_level))
return false;
}
if (6 < compression_level) {
LOGE("KdTreeAttributesDecoder: compression level %i not supported.\n",
compression_level);
@@ -359,9 +335,8 @@ bool KdTreeAttributesDecoder::DecodeDataNeededByPortableTransforms(
}
uint32_t num_points;
if (!in_buffer->Decode(&num_points)) {
if (!in_buffer->Decode(&num_points))
return false;
}
for (auto attribute_index = 0;
static_cast<uint32_t>(attribute_index) < attribute_count;
@@ -378,51 +353,44 @@ bool KdTreeAttributesDecoder::DecodeDataNeededByPortableTransforms(
switch (compression_level) {
case 0: {
DynamicIntegerPointsKdTreeDecoder<0> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
case 1: {
DynamicIntegerPointsKdTreeDecoder<1> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
case 2: {
DynamicIntegerPointsKdTreeDecoder<2> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
case 3: {
DynamicIntegerPointsKdTreeDecoder<3> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
case 4: {
DynamicIntegerPointsKdTreeDecoder<4> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
case 5: {
DynamicIntegerPointsKdTreeDecoder<5> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
case 6: {
DynamicIntegerPointsKdTreeDecoder<6> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
default:
@@ -477,19 +445,16 @@ bool KdTreeAttributesDecoder::TransformAttributesToOriginalFormat() {
// Values are stored as unsigned in the attribute, make them signed again.
if (att->data_type() == DT_INT32) {
if (!TransformAttributeBackToSignedType<int32_t>(
att, num_processed_signed_components)) {
att, num_processed_signed_components))
return false;
}
} else if (att->data_type() == DT_INT16) {
if (!TransformAttributeBackToSignedType<int16_t>(
att, num_processed_signed_components)) {
att, num_processed_signed_components))
return false;
}
} else if (att->data_type() == DT_INT8) {
if (!TransformAttributeBackToSignedType<int8_t>(
att, num_processed_signed_components)) {
att, num_processed_signed_components))
return false;
}
}
num_processed_signed_components += att->num_components();
} else if (att->data_type() == DT_FLOAT32) {
@@ -526,9 +491,8 @@ bool KdTreeAttributesDecoder::TransformAttributesToOriginalFormat() {
int quant_val_id = 0;
int out_byte_pos = 0;
Dequantizer dequantizer;
if (!dequantizer.Init(transform.range(), max_quantized_value)) {
if (!dequantizer.Init(transform.range(), max_quantized_value))
return false;
}
const uint32_t *const portable_attribute_data =
reinterpret_cast<const uint32_t *>(
src_att->GetAddress(AttributeValueIndex(0)));

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