Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/object/object_transform.cc
| /* SPDX-License-Identifier: GPL-2.0-or-later | /* SPDX-License-Identifier: GPL-2.0-or-later | ||||
| * Copyright 2001-2002 NaN Holding BV. All rights reserved. */ | * Copyright 2001-2002 NaN Holding BV. All rights reserved. */ | ||||
| /** \file | /** \file | ||||
| * \ingroup edobj | * \ingroup edobj | ||||
| */ | */ | ||||
| #include <cstdlib> | #include <cstdlib> | ||||
| #include <cstring> | #include <cstring> | ||||
| #include <numeric> | |||||
| #include "DNA_anim_types.h" | #include "DNA_anim_types.h" | ||||
| #include "DNA_armature_types.h" | #include "DNA_armature_types.h" | ||||
| #include "DNA_collection_types.h" | #include "DNA_collection_types.h" | ||||
| #include "DNA_gpencil_types.h" | #include "DNA_gpencil_types.h" | ||||
| #include "DNA_lattice_types.h" | #include "DNA_lattice_types.h" | ||||
| #include "DNA_light_types.h" | #include "DNA_light_types.h" | ||||
| #include "DNA_mesh_types.h" | #include "DNA_mesh_types.h" | ||||
| #include "DNA_meta_types.h" | #include "DNA_meta_types.h" | ||||
| #include "DNA_object_types.h" | #include "DNA_object_types.h" | ||||
| #include "DNA_scene_types.h" | #include "DNA_scene_types.h" | ||||
| #include "BLI_array.hh" | #include "BLI_array.hh" | ||||
| #include "BLI_listbase.h" | #include "BLI_listbase.h" | ||||
| #include "BLI_math.h" | #include "BLI_math.h" | ||||
| #include "BLI_math_vector.hh" | #include "BLI_math_vector.hh" | ||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "BLI_vector.hh" | #include "BLI_vector.hh" | ||||
| #include "BKE_armature.h" | #include "BKE_armature.h" | ||||
| #include "BKE_context.h" | #include "BKE_context.h" | ||||
| #include "BKE_curve.h" | #include "BKE_curve.h" | ||||
| #include "BKE_curves.hh" | |||||
| #include "BKE_editmesh.h" | #include "BKE_editmesh.h" | ||||
| #include "BKE_gpencil.h" | #include "BKE_gpencil.h" | ||||
| #include "BKE_gpencil_geom.h" | #include "BKE_gpencil_geom.h" | ||||
| #include "BKE_idtype.h" | #include "BKE_idtype.h" | ||||
| #include "BKE_lattice.h" | #include "BKE_lattice.h" | ||||
| #include "BKE_layer.h" | #include "BKE_layer.h" | ||||
| #include "BKE_lib_id.h" | #include "BKE_lib_id.h" | ||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| Show All 23 Lines | |||||
| #include "ED_view3d.h" | #include "ED_view3d.h" | ||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "object_intern.h" | #include "object_intern.h" | ||||
| using blender::Array; | using blender::Array; | ||||
| using blender::float2; | using blender::float2; | ||||
| using blender::float3; | |||||
| using blender::Vector; | using blender::Vector; | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Clear Transformation Utilities | /** \name Clear Transformation Utilities | ||||
| * \{ */ | * \{ */ | ||||
| /* clear location of object */ | /* clear location of object */ | ||||
| static void object_clear_loc(Object *ob, const bool clear_delta) | static void object_clear_loc(Object *ob, const bool clear_delta) | ||||
| ▲ Show 20 Lines • Show All 607 Lines • ▼ Show 20 Lines | CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { | ||||
| if (ELEM(ob->type, | if (ELEM(ob->type, | ||||
| OB_MESH, | OB_MESH, | ||||
| OB_ARMATURE, | OB_ARMATURE, | ||||
| OB_LATTICE, | OB_LATTICE, | ||||
| OB_MBALL, | OB_MBALL, | ||||
| OB_CURVES_LEGACY, | OB_CURVES_LEGACY, | ||||
| OB_SURF, | OB_SURF, | ||||
| OB_FONT, | OB_FONT, | ||||
| OB_GPENCIL)) { | OB_GPENCIL, | ||||
| OB_CURVES)) { | |||||
| ID *obdata = static_cast<ID *>(ob->data); | ID *obdata = static_cast<ID *>(ob->data); | ||||
| if (!do_multi_user && ID_REAL_USERS(obdata) > 1) { | if (!do_multi_user && ID_REAL_USERS(obdata) > 1) { | ||||
| BKE_reportf(reports, | BKE_reportf(reports, | ||||
| RPT_ERROR, | RPT_ERROR, | ||||
| R"(Cannot apply to a multi user: Object "%s", %s "%s", aborting)", | R"(Cannot apply to a multi user: Object "%s", %s "%s", aborting)", | ||||
| ob->id.name + 2, | ob->id.name + 2, | ||||
| BKE_idtype_idcode_to_name(GS(obdata->name)), | BKE_idtype_idcode_to_name(GS(obdata->name)), | ||||
| obdata->name + 2); | obdata->name + 2); | ||||
| ▲ Show 20 Lines • Show All 215 Lines • ▼ Show 20 Lines | else if (ob->type == OB_FONT) { | ||||
| if (do_props) { | if (do_props) { | ||||
| cu->fsize *= scale; | cu->fsize *= scale; | ||||
| } | } | ||||
| } | } | ||||
| else if (ob->type == OB_GPENCIL) { | else if (ob->type == OB_GPENCIL) { | ||||
| bGPdata *gpd = static_cast<bGPdata *>(ob->data); | bGPdata *gpd = static_cast<bGPdata *>(ob->data); | ||||
| BKE_gpencil_transform(gpd, mat); | BKE_gpencil_transform(gpd, mat); | ||||
| } | } | ||||
| else if (ob->type == OB_CURVES) { | |||||
| Curves &curves = *static_cast<Curves *>(ob->data); | |||||
| blender::bke::CurvesGeometry::wrap(curves.geometry).transform(mat); | |||||
| blender::bke::CurvesGeometry::wrap(curves.geometry).calculate_bezier_auto_handles(); | |||||
| } | |||||
| else if (ob->type == OB_CAMERA) { | else if (ob->type == OB_CAMERA) { | ||||
| MovieClip *clip = BKE_object_movieclip_get(scene, ob, false); | MovieClip *clip = BKE_object_movieclip_get(scene, ob, false); | ||||
| /* applying scale on camera actually scales clip's reconstruction. | /* applying scale on camera actually scales clip's reconstruction. | ||||
| * of there's clip assigned to camera nothing to do actually. | * of there's clip assigned to camera nothing to do actually. | ||||
| */ | */ | ||||
| if (!clip) { | if (!clip) { | ||||
| continue; | continue; | ||||
| ▲ Show 20 Lines • Show All 246 Lines • ▼ Show 20 Lines | |||||
| static int object_origin_set_exec(bContext *C, wmOperator *op) | static int object_origin_set_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Main *bmain = CTX_data_main(C); | Main *bmain = CTX_data_main(C); | ||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| Object *obact = CTX_data_active_object(C); | Object *obact = CTX_data_active_object(C); | ||||
| Object *obedit = CTX_data_edit_object(C); | Object *obedit = CTX_data_edit_object(C); | ||||
| Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); | Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); | ||||
| float cent[3], cent_neg[3], centn[3]; | float3 cent, cent_neg, centn; | ||||
| const float *cursor = scene->cursor.location; | const float *cursor = scene->cursor.location; | ||||
| int centermode = RNA_enum_get(op->ptr, "type"); | int centermode = RNA_enum_get(op->ptr, "type"); | ||||
| /* keep track of what is changed */ | /* keep track of what is changed */ | ||||
| int tot_change = 0, tot_lib_error = 0, tot_multiuser_arm_error = 0; | int tot_change = 0, tot_lib_error = 0, tot_multiuser_arm_error = 0; | ||||
| if (obedit && centermode != GEOMETRY_TO_ORIGIN) { | if (obedit && centermode != GEOMETRY_TO_ORIGIN) { | ||||
| BKE_report(op->reports, RPT_ERROR, "Operation cannot be performed in edit mode"); | BKE_report(op->reports, RPT_ERROR, "Operation cannot be performed in edit mode"); | ||||
| ▲ Show 20 Lines • Show All 372 Lines • ▼ Show 20 Lines | else if (ob->type == OB_GPENCIL) { | ||||
| } | } | ||||
| else { | else { | ||||
| BKE_report(op->reports, | BKE_report(op->reports, | ||||
| RPT_WARNING, | RPT_WARNING, | ||||
| "Grease Pencil Object does not support this set origin option"); | "Grease Pencil Object does not support this set origin option"); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else if (ob->type == OB_CURVES) { | |||||
| using namespace blender; | |||||
| Curves &curves_id = *static_cast<Curves *>(ob->data); | |||||
| bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); | |||||
| if (ELEM(centermode, ORIGIN_TO_CENTER_OF_MASS_SURFACE, ORIGIN_TO_CENTER_OF_MASS_VOLUME) || | |||||
| !ELEM(around, V3D_AROUND_CENTER_BOUNDS, V3D_AROUND_CENTER_MEDIAN)) { | |||||
| BKE_report( | |||||
| op->reports, RPT_WARNING, "Curves Object does not support this set origin operation"); | |||||
| continue; | |||||
| } | |||||
| if (curves.points_num() == 0) { | |||||
| continue; | |||||
| } | |||||
| if (centermode == ORIGIN_TO_CURSOR) { | |||||
| /* done */ | |||||
| } | |||||
| else if (around == V3D_AROUND_CENTER_BOUNDS) { | |||||
| float3 min; | |||||
| float3 max; | |||||
| if (curves.bounds_min_max(min, max)) { | |||||
JacquesLucke: This case and the case below might need some checks to protect against the case when the curves… | |||||
| cent = math::midpoint(min, max); | |||||
| } | |||||
| } | |||||
| else if (around == V3D_AROUND_CENTER_MEDIAN) { | |||||
| Span<float3> positions = curves.positions(); | |||||
| cent = std::accumulate(positions.begin(), positions.end(), float3(0)) / | |||||
| curves.points_num(); | |||||
| } | |||||
| tot_change++; | |||||
| curves.translate(-cent); | |||||
| curves_id.id.tag |= LIB_TAG_DOIT; | |||||
| do_inverse_offset = true; | |||||
| } | |||||
| /* offset other selected objects */ | /* offset other selected objects */ | ||||
| if (do_inverse_offset && (centermode != GEOMETRY_TO_ORIGIN)) { | if (do_inverse_offset && (centermode != GEOMETRY_TO_ORIGIN)) { | ||||
| float obmat[4][4]; | float obmat[4][4]; | ||||
| /* was the object data modified | /* was the object data modified | ||||
| * NOTE: the functions above must set 'cent'. */ | * NOTE: the functions above must set 'cent'. */ | ||||
| ▲ Show 20 Lines • Show All 600 Lines • Show Last 20 Lines | |||||
This case and the case below might need some checks to protect against the case when the curves object is empty, unless that is handled at a higher level.