Changeset View
Changeset View
Standalone View
Standalone View
source/blender/nodes/geometry/nodes/node_geo_transform.cc
| Show All 29 Lines | |||||
| #include "BKE_volume.h" | #include "BKE_volume.h" | ||||
| #include "DEG_depsgraph_query.h" | #include "DEG_depsgraph_query.h" | ||||
| #include "node_geometry_util.hh" | #include "node_geometry_util.hh" | ||||
| namespace blender::nodes { | namespace blender::nodes { | ||||
| static void geo_node_transform_declare(NodeDeclarationBuilder &b) | |||||
| { | |||||
| b.add_input<decl::Geometry>(N_("Geometry")); | |||||
| b.add_input<decl::Vector>(N_("Translation")).subtype(PROP_TRANSLATION); | |||||
| b.add_input<decl::Vector>(N_("Rotation")).subtype(PROP_EULER); | |||||
| b.add_input<decl::Vector>(N_("Scale")).default_value({1, 1, 1}).subtype(PROP_XYZ); | |||||
| b.add_output<decl::Geometry>(N_("Geometry")); | |||||
| } | |||||
| static bool use_translate(const float3 rotation, const float3 scale) | static bool use_translate(const float3 rotation, const float3 scale) | ||||
| { | { | ||||
| if (compare_ff(rotation.length_squared(), 0.0f, 1e-9f) != 1) { | if (compare_ff(rotation.length_squared(), 0.0f, 1e-9f) != 1) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| if (compare_ff(scale.x, 1.0f, 1e-9f) != 1 || compare_ff(scale.y, 1.0f, 1e-9f) != 1 || | if (compare_ff(scale.x, 1.0f, 1e-9f) != 1 || compare_ff(scale.y, 1.0f, 1e-9f) != 1 || | ||||
| compare_ff(scale.z, 1.0f, 1e-9f) != 1) { | compare_ff(scale.z, 1.0f, 1e-9f) != 1) { | ||||
| return false; | return false; | ||||
| Show All 9 Lines | |||||
| } | } | ||||
| static void transform_mesh(Mesh &mesh, const float4x4 &transform) | static void transform_mesh(Mesh &mesh, const float4x4 &transform) | ||||
| { | { | ||||
| BKE_mesh_transform(&mesh, transform.values, false); | BKE_mesh_transform(&mesh, transform.values, false); | ||||
| BKE_mesh_normals_tag_dirty(&mesh); | BKE_mesh_normals_tag_dirty(&mesh); | ||||
| } | } | ||||
| void transform_mesh(Mesh &mesh, | |||||
| const float3 translation, | |||||
| const float3 rotation, | |||||
| const float3 scale) | |||||
| { | |||||
| const float4x4 matrix = float4x4::from_loc_eul_scale(translation, rotation, scale); | |||||
| transform_mesh(mesh, matrix); | |||||
| } | |||||
| static void translate_pointcloud(PointCloud &pointcloud, const float3 translation) | static void translate_pointcloud(PointCloud &pointcloud, const float3 translation) | ||||
| { | { | ||||
| CustomData_duplicate_referenced_layer(&pointcloud.pdata, CD_PROP_FLOAT3, pointcloud.totpoint); | CustomData_duplicate_referenced_layer(&pointcloud.pdata, CD_PROP_FLOAT3, pointcloud.totpoint); | ||||
| BKE_pointcloud_update_customdata_pointers(&pointcloud); | BKE_pointcloud_update_customdata_pointers(&pointcloud); | ||||
| for (const int i : IndexRange(pointcloud.totpoint)) { | for (const int i : IndexRange(pointcloud.totpoint)) { | ||||
| add_v3_v3(pointcloud.co[i], translation); | add_v3_v3(pointcloud.co[i], translation); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | |||||
| #endif | #endif | ||||
| } | } | ||||
| static void translate_volume(Volume &volume, const float3 translation, const Depsgraph &depsgraph) | static void translate_volume(Volume &volume, const float3 translation, const Depsgraph &depsgraph) | ||||
| { | { | ||||
| transform_volume(volume, float4x4::from_location(translation), depsgraph); | transform_volume(volume, float4x4::from_location(translation), depsgraph); | ||||
| } | } | ||||
| void transform_geometry_set(GeometrySet &geometry, | static void translate_geometry_set(GeometrySet &geometry, | ||||
| const float4x4 &transform, | const float3 translation, | ||||
| const Depsgraph &depsgraph) | const Depsgraph &depsgraph) | ||||
| { | { | ||||
| if (CurveEval *curve = geometry.get_curve_for_write()) { | if (CurveEval *curve = geometry.get_curve_for_write()) { | ||||
| curve->transform(transform); | curve->translate(translation); | ||||
| } | } | ||||
| if (Mesh *mesh = geometry.get_mesh_for_write()) { | if (Mesh *mesh = geometry.get_mesh_for_write()) { | ||||
| transform_mesh(*mesh, transform); | translate_mesh(*mesh, translation); | ||||
| } | } | ||||
| if (PointCloud *pointcloud = geometry.get_pointcloud_for_write()) { | if (PointCloud *pointcloud = geometry.get_pointcloud_for_write()) { | ||||
| transform_pointcloud(*pointcloud, transform); | translate_pointcloud(*pointcloud, translation); | ||||
| } | } | ||||
| if (Volume *volume = geometry.get_volume_for_write()) { | if (Volume *volume = geometry.get_volume_for_write()) { | ||||
| transform_volume(*volume, transform, depsgraph); | translate_volume(*volume, translation, depsgraph); | ||||
| } | } | ||||
| if (geometry.has_instances()) { | if (geometry.has_instances()) { | ||||
| transform_instances(geometry.get_component_for_write<InstancesComponent>(), transform); | translate_instances(geometry.get_component_for_write<InstancesComponent>(), translation); | ||||
| } | } | ||||
| } | } | ||||
| static void translate_geometry_set(GeometrySet &geometry, | void transform_geometry_set(GeometrySet &geometry, | ||||
| const float3 translation, | const float4x4 &transform, | ||||
| const Depsgraph &depsgraph) | const Depsgraph &depsgraph) | ||||
| { | { | ||||
| if (CurveEval *curve = geometry.get_curve_for_write()) { | if (CurveEval *curve = geometry.get_curve_for_write()) { | ||||
| curve->translate(translation); | curve->transform(transform); | ||||
| } | } | ||||
| if (Mesh *mesh = geometry.get_mesh_for_write()) { | if (Mesh *mesh = geometry.get_mesh_for_write()) { | ||||
| translate_mesh(*mesh, translation); | transform_mesh(*mesh, transform); | ||||
| } | } | ||||
| if (PointCloud *pointcloud = geometry.get_pointcloud_for_write()) { | if (PointCloud *pointcloud = geometry.get_pointcloud_for_write()) { | ||||
| translate_pointcloud(*pointcloud, translation); | transform_pointcloud(*pointcloud, transform); | ||||
| } | } | ||||
| if (Volume *volume = geometry.get_volume_for_write()) { | if (Volume *volume = geometry.get_volume_for_write()) { | ||||
| translate_volume(*volume, translation, depsgraph); | transform_volume(*volume, transform, depsgraph); | ||||
| } | } | ||||
| if (geometry.has_instances()) { | if (geometry.has_instances()) { | ||||
| translate_instances(geometry.get_component_for_write<InstancesComponent>(), translation); | transform_instances(geometry.get_component_for_write<InstancesComponent>(), transform); | ||||
| } | |||||
| } | |||||
| void transform_mesh(Mesh &mesh, | |||||
| const float3 translation, | |||||
| const float3 rotation, | |||||
| const float3 scale) | |||||
| { | |||||
| const float4x4 matrix = float4x4::from_loc_eul_scale(translation, rotation, scale); | |||||
| transform_mesh(mesh, matrix); | |||||
| } | } | ||||
| } // namespace blender::nodes | |||||
| namespace blender::nodes::node_geo_transform_cc { | |||||
| static void geo_node_transform_declare(NodeDeclarationBuilder &b) | |||||
| { | |||||
| b.add_input<decl::Geometry>(N_("Geometry")); | |||||
| b.add_input<decl::Vector>(N_("Translation")).subtype(PROP_TRANSLATION); | |||||
| b.add_input<decl::Vector>(N_("Rotation")).subtype(PROP_EULER); | |||||
| b.add_input<decl::Vector>(N_("Scale")).default_value({1, 1, 1}).subtype(PROP_XYZ); | |||||
| b.add_output<decl::Geometry>(N_("Geometry")); | |||||
| } | } | ||||
| static void geo_node_transform_exec(GeoNodeExecParams params) | static void geo_node_transform_exec(GeoNodeExecParams params) | ||||
| { | { | ||||
| GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry"); | GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry"); | ||||
| const float3 translation = params.extract_input<float3>("Translation"); | const float3 translation = params.extract_input<float3>("Translation"); | ||||
| const float3 rotation = params.extract_input<float3>("Rotation"); | const float3 rotation = params.extract_input<float3>("Rotation"); | ||||
| const float3 scale = params.extract_input<float3>("Scale"); | const float3 scale = params.extract_input<float3>("Scale"); | ||||
| /* Use only translation if rotation and scale don't apply. */ | /* Use only translation if rotation and scale don't apply. */ | ||||
| if (use_translate(rotation, scale)) { | if (use_translate(rotation, scale)) { | ||||
| translate_geometry_set(geometry_set, translation, *params.depsgraph()); | translate_geometry_set(geometry_set, translation, *params.depsgraph()); | ||||
| } | } | ||||
| else { | else { | ||||
| transform_geometry_set(geometry_set, | transform_geometry_set(geometry_set, | ||||
| float4x4::from_loc_eul_scale(translation, rotation, scale), | float4x4::from_loc_eul_scale(translation, rotation, scale), | ||||
| *params.depsgraph()); | *params.depsgraph()); | ||||
| } | } | ||||
| params.set_output("Geometry", std::move(geometry_set)); | params.set_output("Geometry", std::move(geometry_set)); | ||||
| } | } | ||||
| } // namespace blender::nodes | } // namespace blender::nodes::node_geo_transform_cc | ||||
| void register_node_type_geo_transform() | void register_node_type_geo_transform() | ||||
| { | { | ||||
| namespace file_ns = blender::nodes::node_geo_transform_cc; | |||||
| static bNodeType ntype; | static bNodeType ntype; | ||||
| geo_node_type_base(&ntype, GEO_NODE_TRANSFORM, "Transform", NODE_CLASS_GEOMETRY, 0); | geo_node_type_base(&ntype, GEO_NODE_TRANSFORM, "Transform", NODE_CLASS_GEOMETRY, 0); | ||||
| ntype.declare = blender::nodes::geo_node_transform_declare; | ntype.declare = file_ns::geo_node_transform_declare; | ||||
| ntype.geometry_node_execute = blender::nodes::geo_node_transform_exec; | ntype.geometry_node_execute = file_ns::geo_node_transform_exec; | ||||
| nodeRegisterType(&ntype); | nodeRegisterType(&ntype); | ||||
| } | } | ||||