Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/curve/editcurve.c
| /* 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 edcurve | * \ingroup edcurve | ||||
| */ | */ | ||||
| #include "DNA_anim_types.h" | #include "DNA_anim_types.h" | ||||
| #include "DNA_key_types.h" | #include "DNA_key_types.h" | ||||
| #include "DNA_material_types.h" | |||||
| #include "DNA_object_types.h" | #include "DNA_object_types.h" | ||||
| #include "DNA_scene_types.h" | #include "DNA_scene_types.h" | ||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "BLI_array_utils.h" | #include "BLI_array_utils.h" | ||||
| #include "BLI_blenlib.h" | #include "BLI_blenlib.h" | ||||
| #include "BLI_ghash.h" | #include "BLI_ghash.h" | ||||
| #include "BLI_math.h" | #include "BLI_math.h" | ||||
| #include "BLT_translation.h" | #include "BLT_translation.h" | ||||
| #include "BKE_action.h" | #include "BKE_action.h" | ||||
| #include "BKE_anim_data.h" | #include "BKE_anim_data.h" | ||||
| #include "BKE_context.h" | #include "BKE_context.h" | ||||
| #include "BKE_curve.h" | #include "BKE_curve.h" | ||||
| #include "BKE_displist.h" | #include "BKE_displist.h" | ||||
| #include "BKE_fcurve.h" | #include "BKE_fcurve.h" | ||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "BKE_key.h" | #include "BKE_key.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" | ||||
| #include "BKE_material.h" | |||||
| #include "BKE_modifier.h" | #include "BKE_modifier.h" | ||||
| #include "BKE_report.h" | #include "BKE_report.h" | ||||
| #include "DEG_depsgraph.h" | #include "DEG_depsgraph.h" | ||||
| #include "DEG_depsgraph_build.h" | #include "DEG_depsgraph_build.h" | ||||
| #include "DEG_depsgraph_query.h" | #include "DEG_depsgraph_query.h" | ||||
| #include "WM_api.h" | #include "WM_api.h" | ||||
| ▲ Show 20 Lines • Show All 6,741 Lines • ▼ Show 20 Lines | |||||
| /** \name Join Operator | /** \name Join Operator | ||||
| * \{ */ | * \{ */ | ||||
| int ED_curve_join_objects_exec(bContext *C, wmOperator *op) | int ED_curve_join_objects_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 *ob_active = CTX_data_active_object(C); | Object *ob_active = CTX_data_active_object(C); | ||||
| Material **matar = NULL, *ma; | |||||
| Curve *cu; | Curve *cu; | ||||
| BezTriple *bezt; | BezTriple *bezt; | ||||
| BPoint *bp; | BPoint *bp; | ||||
| ListBase tempbase; | ListBase tempbase; | ||||
| float imat[4][4], cmat[4][4]; | float imat[4][4], cmat[4][4]; | ||||
| int a; | int a, b, totcol, totmat = 0, *matmap = NULL; | ||||
| bool ok = false; | bool ok = false; | ||||
| CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) { | CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) { | ||||
| if (ob_iter->type == ob_active->type) { | |||||
| totmat += ob_iter->totcol; | |||||
| } | |||||
| if (ob_iter == ob_active) { | if (ob_iter == ob_active) { | ||||
| ok = true; | ok = true; | ||||
| break; | |||||
| } | } | ||||
| } | } | ||||
| CTX_DATA_END; | CTX_DATA_END; | ||||
| /* that way the active object is always selected */ | /* that way the active object is always selected */ | ||||
| if (ok == false) { | if (ok == false) { | ||||
| BKE_report(op->reports, RPT_WARNING, "Active object is not a selected curve"); | BKE_report(op->reports, RPT_WARNING, "Active object is not a selected curve"); | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| BLI_listbase_clear(&tempbase); | BLI_listbase_clear(&tempbase); | ||||
| if (totmat) { | |||||
| matar = MEM_callocN(sizeof(*matar) * totmat, "join_curve matar"); | |||||
| matmap = MEM_callocN(sizeof(*matmap) * totmat, "join_curve matmap"); | |||||
| } | |||||
| totcol = ob_active->totcol; | |||||
| /* active object materials in new main array, is nicer start! */ | |||||
| for (a = 0; a < ob_active->totcol; a++) { | |||||
| matar[a] = BKE_object_material_get(ob_active, a + 1); | |||||
| id_us_plus((ID *)matar[a]); | |||||
| /* increase id->us : will be lowered later */ | |||||
| } | |||||
| /* Inverse transform for all selected curves in this object, | /* Inverse transform for all selected curves in this object, | ||||
| * See #object_join_exec for detailed comment on why the safe version is used. */ | * See #object_join_exec for detailed comment on why the safe version is used. */ | ||||
| invert_m4_m4_safe_ortho(imat, ob_active->obmat); | invert_m4_m4_safe_ortho(imat, ob_active->obmat); | ||||
| Curve *cu_active = ob_active->data; | Curve *cu_active = ob_active->data; | ||||
| CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) { | CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) { | ||||
| if (ob_iter->type == ob_active->type) { | if (ob_iter->type == ob_active->type) { | ||||
| Show All 9 Lines | if (ob_iter->type == ob_active->type) { | ||||
| bool do_radius = false; | bool do_radius = false; | ||||
| float compensate_radius = 0.0f; | float compensate_radius = 0.0f; | ||||
| if (cu->bevel_radius != 0.0f && cu_active->bevel_radius != 0.0f) { | if (cu->bevel_radius != 0.0f && cu_active->bevel_radius != 0.0f) { | ||||
| float compensate_scale = mat4_to_scale(cmat); | float compensate_scale = mat4_to_scale(cmat); | ||||
| compensate_radius = cu->bevel_radius / cu_active->bevel_radius * compensate_scale; | compensate_radius = cu->bevel_radius / cu_active->bevel_radius * compensate_scale; | ||||
| do_radius = true; | do_radius = true; | ||||
| } | } | ||||
| LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) { | if (totcol < MAXMAT) { | ||||
| Nurb *newnu = BKE_nurb_duplicate(nu); | for (a = 1; a <= ob_iter->totcol; a++) { | ||||
| if (ob_active->totcol) { /* TODO: merge material lists. */ | ma = BKE_object_material_get(ob_iter, a); | ||||
| CLAMP(newnu->mat_nr, 0, ob_active->totcol - 1); | |||||
| for (b = 0; b < totcol; b++) { | |||||
| if (ma == matar[b]) { | |||||
| matmap[a - 1] = b; | |||||
| break; | |||||
| } | } | ||||
| else { | |||||
| newnu->mat_nr = 0; | |||||
| } | } | ||||
| if (b == totcol) { | |||||
| matar[b] = ma; | |||||
| matmap[a - 1] = b; | |||||
| if (ma) { | |||||
| id_us_plus(&ma->id); | |||||
| } | |||||
| totcol++; | |||||
| } | |||||
| if (totcol >= MAXMAT) { | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) { | |||||
| Nurb *newnu = BKE_nurb_duplicate(nu); | |||||
| newnu->mat_nr = matmap ? matmap[newnu->mat_nr] : 0; | |||||
| BLI_addtail(&tempbase, newnu); | BLI_addtail(&tempbase, newnu); | ||||
| if ((bezt = newnu->bezt)) { | if ((bezt = newnu->bezt)) { | ||||
| a = newnu->pntsu; | a = newnu->pntsu; | ||||
| while (a--) { | while (a--) { | ||||
| /* Compensate for different bevel depth. */ | /* Compensate for different bevel depth. */ | ||||
| if (do_radius) { | if (do_radius) { | ||||
| bezt->radius *= compensate_radius; | bezt->radius *= compensate_radius; | ||||
| Show All 20 Lines | if (ob_iter->type == ob_active->type) { | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| CTX_DATA_END; | CTX_DATA_END; | ||||
| cu = ob_active->data; | cu = ob_active->data; | ||||
| BLI_movelisttolist(&cu->nurb, &tempbase); | BLI_movelisttolist(&cu->nurb, &tempbase); | ||||
| /* old material array */ | |||||
| for (a = 1; a <= ob_active->totcol; a++) { | |||||
| ma = ob_active->mat[a - 1]; | |||||
| if (ma) { | |||||
| id_us_min(&ma->id); | |||||
| } | |||||
| } | |||||
| for (a = 1; a <= cu->totcol; a++) { | |||||
| ma = cu->mat[a - 1]; | |||||
| if (ma) { | |||||
| id_us_min(&ma->id); | |||||
| } | |||||
| } | |||||
| MEM_SAFE_FREE(ob_active->mat); | |||||
| MEM_SAFE_FREE(ob_active->matbits); | |||||
| MEM_SAFE_FREE(cu->mat); | |||||
| if (totcol) { | |||||
| cu->mat = matar; | |||||
| ob_active->mat = MEM_callocN(sizeof(*ob_active->mat) * totcol, "join obmatar"); | |||||
| ob_active->matbits = MEM_callocN(sizeof(*ob_active->matbits) * totcol, "join obmatbits"); | |||||
| MEM_freeN(matmap); | |||||
| } | |||||
| ob_active->totcol = cu->totcol = totcol; | |||||
| /* other curve users */ | |||||
| BKE_objects_materials_test_all(bmain, (ID *)cu); | |||||
| if (ob_active->type == OB_CURVES_LEGACY && CU_IS_2D(cu)) { | if (ob_active->type == OB_CURVES_LEGACY && CU_IS_2D(cu)) { | ||||
| /* Account for mixed 2D/3D curves when joining */ | /* Account for mixed 2D/3D curves when joining */ | ||||
| BKE_curve_dimension_update(cu); | BKE_curve_dimension_update(cu); | ||||
| } | } | ||||
| DEG_relations_tag_update(bmain); /* because we removed object(s), call before editmode! */ | DEG_relations_tag_update(bmain); /* because we removed object(s), call before editmode! */ | ||||
| DEG_id_tag_update(&ob_active->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); | DEG_id_tag_update(&ob_active->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); | ||||
| ▲ Show 20 Lines • Show All 168 Lines • Show Last 20 Lines | |||||