This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/source/blender/blenkernel/BKE_mesh_sample.hh
Jacques Lucke b876ce2a4a Geometry Nodes: new geometry attribute API
Currently, there are two attribute API. The first, defined in `BKE_attribute.h` is
accessible from RNA and C code. The second is implemented with `GeometryComponent`
and is only accessible in C++ code. The second is widely used, but only being
accessible through the `GeometrySet` API makes it awkward to use, and even impossible
for types that don't correspond directly to a geometry component like `CurvesGeometry`.

This patch adds a new attribute API, designed to replace the `GeometryComponent`
attribute API now, and to eventually replace or be the basis of the other one.

The basic idea is that there is an `AttributeAccessor` class that allows code to
interact with a set of attributes owned by some geometry. The accessor itself has
no ownership. `AttributeAccessor` is a simple type that can be passed around by
value. That makes it easy to return it from functions and to store it in containers.

For const-correctness, there is also a `MutableAttributeAccessor` that allows
changing individual and can add or remove attributes.

Currently, `AttributeAccessor` is composed of two pointers. The first is a pointer
to the owner of the attribute data. The second is a pointer to a struct with
function pointers, that is similar to a virtual function table. The functions
know how to access attributes on the owner.

The actual attribute access for geometries is still implemented with the `AttributeProvider`
pattern, which makes it easy to support different sources of attributes on a
geometry and simplifies dealing with built-in attributes.

There are different ways to get an attribute accessor for a geometry:
* `GeometryComponent.attributes()`
* `CurvesGeometry.attributes()`
* `bke::mesh_attributes(const Mesh &)`
* `bke::pointcloud_attributes(const PointCloud &)`

All of these also have a `_for_write` variant that returns a `MutabelAttributeAccessor`.

Differential Revision: https://developer.blender.org/D15280
2022-07-08 16:16:56 +02:00

141 lines
4.9 KiB
C++

/* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
/** \file
* \ingroup bke
*/
#include "BLI_function_ref.hh"
#include "BLI_generic_virtual_array.hh"
#include "BLI_math_vec_types.hh"
#include "DNA_meshdata_types.h"
#include "BKE_attribute.h"
#include "BKE_attribute.hh"
struct Mesh;
struct BVHTreeFromMesh;
namespace blender {
class RandomNumberGenerator;
}
namespace blender::bke::mesh_surface_sample {
void sample_point_attribute(const Mesh &mesh,
Span<int> looptri_indices,
Span<float3> bary_coords,
const GVArray &data_in,
const IndexMask mask,
GMutableSpan data_out);
void sample_corner_attribute(const Mesh &mesh,
Span<int> looptri_indices,
Span<float3> bary_coords,
const GVArray &data_in,
const IndexMask mask,
GMutableSpan data_out);
void sample_face_attribute(const Mesh &mesh,
Span<int> looptri_indices,
const GVArray &data_in,
const IndexMask mask,
GMutableSpan data_out);
enum class eAttributeMapMode {
INTERPOLATED,
NEAREST,
};
/**
* A utility class that performs attribute interpolation from a source mesh.
*
* The interpolator is only valid as long as the mesh is valid.
* Barycentric weights are needed when interpolating point or corner domain attributes,
* these are computed lazily when needed and re-used.
*/
class MeshAttributeInterpolator {
private:
const Mesh *mesh_;
const IndexMask mask_;
const Span<float3> positions_;
const Span<int> looptri_indices_;
Array<float3> bary_coords_;
Array<float3> nearest_weights_;
public:
MeshAttributeInterpolator(const Mesh *mesh,
const IndexMask mask,
const Span<float3> positions,
const Span<int> looptri_indices);
void sample_data(const GVArray &src,
eAttrDomain domain,
eAttributeMapMode mode,
const GMutableSpan dst);
void sample_attribute(const GAttributeReader &src_attribute,
GSpanAttributeWriter &dst_attribute,
eAttributeMapMode mode);
protected:
Span<float3> ensure_barycentric_coords();
Span<float3> ensure_nearest_weights();
};
/**
* Find randomly distributed points on the surface of a mesh within a 3D sphere. This does not
* sample an exact number of points because it comes with extra overhead to avoid bias that is only
* required in some cases. If an exact number of points is required, that has to be implemented at
* a higher level.
*
* \param approximate_density: Roughly the number of points per unit of area.
* \return The number of added points.
*/
int sample_surface_points_spherical(RandomNumberGenerator &rng,
const Mesh &mesh,
Span<int> looptri_indices_to_sample,
const float3 &sample_pos,
float sample_radius,
float approximate_density,
Vector<float3> &r_bary_coords,
Vector<int> &r_looptri_indices,
Vector<float3> &r_positions);
/**
* Find randomly distributed points on the surface of a mesh within a circle that is projected on
* the mesh. This does not result in an exact number of points because that would come with extra
* overhead and is not always possible. If an exact number of points is required, that has to be
* implemented at a higher level.
*
* \param region_position_to_ray: Function that converts a 2D position into a 3D ray that is used
* to find positions on the mesh.
* \param mesh_bvhtree: BVH tree of the triangles in the mesh. Passed in so that it does not have
* to be retrieved again.
* \param tries_num: Number of 2d positions that are sampled. The maximum
* number of new samples.
* \return The number of added points.
*/
int sample_surface_points_projected(
RandomNumberGenerator &rng,
const Mesh &mesh,
BVHTreeFromMesh &mesh_bvhtree,
const float2 &sample_pos_re,
float sample_radius_re,
FunctionRef<void(const float2 &pos_re, float3 &r_start, float3 &r_end)> region_position_to_ray,
bool front_face_only,
int tries_num,
int max_points,
Vector<float3> &r_bary_coords,
Vector<int> &r_looptri_indices,
Vector<float3> &r_positions);
float3 compute_bary_coord_in_triangle(const Mesh &mesh,
const MLoopTri &looptri,
const float3 &position);
} // namespace blender::bke::mesh_surface_sample