Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/pointcloud.cc
| Show All 19 Lines | |||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "DNA_defaults.h" | #include "DNA_defaults.h" | ||||
| #include "DNA_material_types.h" | #include "DNA_material_types.h" | ||||
| #include "DNA_object_types.h" | #include "DNA_object_types.h" | ||||
| #include "DNA_pointcloud_types.h" | #include "DNA_pointcloud_types.h" | ||||
| #include "BLI_float3.hh" | |||||
| #include "BLI_index_range.hh" | |||||
| #include "BLI_listbase.h" | #include "BLI_listbase.h" | ||||
| #include "BLI_math.h" | |||||
| #include "BLI_rand.h" | #include "BLI_rand.h" | ||||
| #include "BLI_span.hh" | |||||
| #include "BLI_string.h" | #include "BLI_string.h" | ||||
| #include "BLI_task.hh" | |||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "BKE_anim_data.h" | #include "BKE_anim_data.h" | ||||
| #include "BKE_customdata.h" | #include "BKE_customdata.h" | ||||
| #include "BKE_geometry_set.hh" | #include "BKE_geometry_set.hh" | ||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "BKE_idtype.h" | #include "BKE_idtype.h" | ||||
| #include "BKE_lib_id.h" | #include "BKE_lib_id.h" | ||||
| #include "BKE_lib_query.h" | #include "BKE_lib_query.h" | ||||
| #include "BKE_lib_remap.h" | #include "BKE_lib_remap.h" | ||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| #include "BKE_mesh_wrapper.h" | #include "BKE_mesh_wrapper.h" | ||||
| #include "BKE_modifier.h" | #include "BKE_modifier.h" | ||||
| #include "BKE_object.h" | #include "BKE_object.h" | ||||
| #include "BKE_pointcloud.h" | #include "BKE_pointcloud.h" | ||||
| #include "BLT_translation.h" | #include "BLT_translation.h" | ||||
| #include "DEG_depsgraph_query.h" | #include "DEG_depsgraph_query.h" | ||||
| #include "BLO_read_write.h" | #include "BLO_read_write.h" | ||||
| using blender::float3; | |||||
| using blender::IndexRange; | |||||
| using blender::Span; | |||||
| /* PointCloud datablock */ | /* PointCloud datablock */ | ||||
| static void pointcloud_random(PointCloud *pointcloud); | static void pointcloud_random(PointCloud *pointcloud); | ||||
| const char *POINTCLOUD_ATTR_POSITION = "position"; | const char *POINTCLOUD_ATTR_POSITION = "position"; | ||||
| const char *POINTCLOUD_ATTR_RADIUS = "radius"; | const char *POINTCLOUD_ATTR_RADIUS = "radius"; | ||||
| static void pointcloud_init_data(ID *id) | static void pointcloud_init_data(ID *id) | ||||
| ▲ Show 20 Lines • Show All 194 Lines • ▼ Show 20 Lines | PointCloud *BKE_pointcloud_new_nomain(const int totpoint) | ||||
| pointcloud->totpoint = totpoint; | pointcloud->totpoint = totpoint; | ||||
| CustomData_realloc(&pointcloud->pdata, pointcloud->totpoint); | CustomData_realloc(&pointcloud->pdata, pointcloud->totpoint); | ||||
| BKE_pointcloud_update_customdata_pointers(pointcloud); | BKE_pointcloud_update_customdata_pointers(pointcloud); | ||||
| return pointcloud; | return pointcloud; | ||||
| } | } | ||||
| void BKE_pointcloud_minmax(const struct PointCloud *pointcloud, float r_min[3], float r_max[3]) | struct MinMaxResult { | ||||
| float3 min; | |||||
| float3 max; | |||||
| }; | |||||
| static MinMaxResult min_max_no_radii(Span<float3> positions) | |||||
| { | { | ||||
| float(*pointcloud_co)[3] = pointcloud->co; | return blender::threading::parallel_reduce( | ||||
| float *pointcloud_radius = pointcloud->radius; | positions.index_range(), | ||||
| for (int a = 0; a < pointcloud->totpoint; a++) { | 1024, | ||||
| float *co = pointcloud_co[a]; | MinMaxResult{float3(FLT_MAX), float3(-FLT_MAX)}, | ||||
| float radius = (pointcloud_radius) ? pointcloud_radius[a] : 0.0f; | [&](IndexRange range, const MinMaxResult &init) { | ||||
| const float co_min[3] = {co[0] - radius, co[1] - radius, co[2] - radius}; | MinMaxResult result = init; | ||||
| const float co_max[3] = {co[0] + radius, co[1] + radius, co[2] + radius}; | for (const int i : range) { | ||||
| DO_MIN(co_min, r_min); | float3::min_max(positions[i], result.min, result.max); | ||||
| DO_MAX(co_max, r_max); | } | ||||
| return result; | |||||
| }, | |||||
| [](const MinMaxResult &a, const MinMaxResult &b) { | |||||
| return MinMaxResult{float3::min(a.min, b.min), float3::max(a.max, b.max)}; | |||||
| }); | |||||
| } | |||||
| static MinMaxResult min_max_with_radii(Span<float3> positions, Span<float> radii) | |||||
| { | |||||
| return blender::threading::parallel_reduce( | |||||
| positions.index_range(), | |||||
| 1024, | |||||
| MinMaxResult{float3(FLT_MAX), float3(-FLT_MAX)}, | |||||
| [&](IndexRange range, const MinMaxResult &init) { | |||||
| MinMaxResult result = init; | |||||
| for (const int i : range) { | |||||
| result.min = float3::min(positions[i] - radii[i], result.min); | |||||
| result.max = float3::max(positions[i] + radii[i], result.max); | |||||
| } | |||||
| return result; | |||||
| }, | |||||
| [](const MinMaxResult &a, const MinMaxResult &b) { | |||||
| return MinMaxResult{float3::min(a.min, b.min), float3::max(a.max, b.max)}; | |||||
| }); | |||||
| } | } | ||||
| bool BKE_pointcloud_minmax(const PointCloud *pointcloud, float r_min[3], float r_max[3]) | |||||
| { | |||||
| if (!pointcloud->totpoint) { | |||||
| return false; | |||||
| } | |||||
| Span<float3> positions{reinterpret_cast<float3 *>(pointcloud->co), pointcloud->totpoint}; | |||||
| const MinMaxResult min_max = (pointcloud->radius) ? | |||||
| min_max_with_radii(positions, | |||||
| {pointcloud->radius, pointcloud->totpoint}) : | |||||
| min_max_no_radii(positions); | |||||
| copy_v3_v3(r_min, float3::min(min_max.min, r_min)); | |||||
| copy_v3_v3(r_max, float3::max(min_max.max, r_max)); | |||||
| return true; | |||||
| } | } | ||||
| BoundBox *BKE_pointcloud_boundbox_get(Object *ob) | BoundBox *BKE_pointcloud_boundbox_get(Object *ob) | ||||
| { | { | ||||
| BLI_assert(ob->type == OB_POINTCLOUD); | BLI_assert(ob->type == OB_POINTCLOUD); | ||||
| if (ob->runtime.bb != nullptr && (ob->runtime.bb->flag & BOUNDBOX_DIRTY) == 0) { | if (ob->runtime.bb != nullptr && (ob->runtime.bb->flag & BOUNDBOX_DIRTY) == 0) { | ||||
| return ob->runtime.bb; | return ob->runtime.bb; | ||||
| ▲ Show 20 Lines • Show All 155 Lines • Show Last 20 Lines | |||||