tornavis/source/blender/editors/transform/transform_convert_mball.cc

146 lines
3.6 KiB
C++

/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup edtransform
*/
#include "DNA_meta_types.h"
#include "MEM_guardedalloc.h"
#include "BLI_math_matrix.h"
#include "BLI_math_rotation.h"
#include "BLI_math_vector.h"
#include "BKE_context.hh"
#include "transform.hh"
#include "transform_snap.hh"
#include "transform_convert.hh"
/* -------------------------------------------------------------------- */
/** \name Meta Elements Transform Creation
* \{ */
static void createTransMBallVerts(bContext * /*C*/, TransInfo *t)
{
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
MetaBall *mb = (MetaBall *)tc->obedit->data;
TransData *td;
TransDataExtension *tx;
float mtx[3][3], smtx[3][3];
int count = 0, countsel = 0;
const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
const bool is_prop_connected = (t->flag & T_PROP_CONNECTED) != 0;
/* count totals */
LISTBASE_FOREACH (MetaElem *, ml, mb->editelems) {
if (ml->flag & SELECT) {
countsel++;
}
if (is_prop_edit) {
count++;
}
}
/* Support other objects using proportional editing to adjust these, unless connected is
* enabled. */
if (((is_prop_edit && !is_prop_connected) ? count : countsel) == 0) {
tc->data_len = 0;
continue;
}
if (is_prop_edit) {
tc->data_len = count;
}
else {
tc->data_len = countsel;
}
td = tc->data = static_cast<TransData *>(
MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(MBall EditMode)"));
tx = tc->data_ext = static_cast<TransDataExtension *>(
MEM_callocN(tc->data_len * sizeof(TransDataExtension), "MetaElement_TransExtension"));
copy_m3_m4(mtx, tc->obedit->object_to_world);
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
LISTBASE_FOREACH (MetaElem *, ml, mb->editelems) {
if (is_prop_edit || (ml->flag & SELECT)) {
td->loc = &ml->x;
copy_v3_v3(td->iloc, td->loc);
copy_v3_v3(td->center, td->loc);
quat_to_mat3(td->axismtx, ml->quat);
if (ml->flag & SELECT) {
td->flag = TD_SELECTED | TD_USEQUAT | TD_SINGLESIZE;
}
else {
td->flag = TD_USEQUAT;
}
copy_m3_m3(td->smtx, smtx);
copy_m3_m3(td->mtx, mtx);
td->ext = tx;
/* Radius of MetaElem (mass of MetaElem influence) */
if (ml->flag & MB_SCALE_RAD) {
td->val = &ml->rad;
td->ival = ml->rad;
}
else {
td->val = &ml->s;
td->ival = ml->s;
}
/* expx/expy/expz determine "shape" of some MetaElem types */
tx->size = &ml->expx;
tx->isize[0] = ml->expx;
tx->isize[1] = ml->expy;
tx->isize[2] = ml->expz;
/* quat is used for rotation of MetaElem */
tx->quat = ml->quat;
copy_qt_qt(tx->iquat, ml->quat);
tx->rot = nullptr;
td++;
tx++;
}
}
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Recalc Meta Ball
* \{ */
static void recalcData_mball(TransInfo *t)
{
if (t->state != TRANS_CANCEL) {
transform_snap_project_individual_apply(t);
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
if (tc->data_len) {
DEG_id_tag_update(static_cast<ID *>(tc->obedit->data), ID_RECALC_GEOMETRY);
}
}
}
/** \} */
TransConvertTypeInfo TransConvertType_MBall = {
/*flags*/ (T_EDIT | T_POINTS),
/*create_trans_data*/ createTransMBallVerts,
/*recalc_data*/ recalcData_mball,
/*special_aftertrans_update*/ nullptr,
};