mirror of
https://projects.blender.org/blender/blender.git
synced 2025-01-22 15:32:15 -05:00
Sculpting on deformed mesh
========================== Removed limitation of armatured-only objects for sculpting -- now all deformation modifiers are allowed in sculpt mode. Use crazyspace corrections like from transformation modules was used to support all deformation modifiers. Internal change: all crazyspace-related functions were noved to crazyspace.c P.S. Brush could make quite unexpected deformation for meshes which are deformed in specified way. Got patch for this and discussing with Brecht if it's really needed or maybe it could be done in better way.
This commit is contained in:
parent
673ac43f2e
commit
d909e61d99
7 changed files with 417 additions and 253 deletions
|
@ -512,8 +512,9 @@ void makeDerivedMesh(struct Scene *scene, struct Object *ob, struct EditMesh *em
|
|||
int editmesh_get_first_deform_matrices(struct Scene *, struct Object *, struct EditMesh *em,
|
||||
float (**deformmats)[3][3], float (**deformcos)[3]);
|
||||
|
||||
/* returns an array of deform matrices for crazyspace correction when sculpting */
|
||||
void sculpt_get_deform_matrices(struct Scene *scene, struct Object *ob,
|
||||
/* returns an array of deform matrices for crazyspace correction when sculpting,
|
||||
and the number of modifiers left */
|
||||
int sculpt_get_deform_matrices(struct Scene *scene, struct Object *ob,
|
||||
float (**deformmats)[3][3], float (**deformcos)[3]);
|
||||
|
||||
void weight_to_rgb(float input, float *fr, float *fg, float *fb);
|
||||
|
|
|
@ -1721,12 +1721,6 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
|
|||
if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue;
|
||||
|
||||
if(mti->type == eModifierTypeType_OnlyDeform) {
|
||||
if(sculpt_mode && !has_multires)
|
||||
if(!ELEM(md->type, eModifierType_Armature, eModifierType_ShapeKey)) {
|
||||
modifier_setError(md, "Not supported in sculpt mode.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!deformedVerts)
|
||||
deformedVerts = mesh_getVertexCos(me, &numVerts);
|
||||
|
||||
|
@ -1780,7 +1774,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
|
|||
continue;
|
||||
}
|
||||
if(sculpt_mode && (!has_multires || multires_applied))
|
||||
if(md->type != eModifierType_Armature || multires_applied) {
|
||||
if(mti->type != eModifierTypeType_OnlyDeform || multires_applied) {
|
||||
modifier_setError(md, "Not supported in sculpt mode.");
|
||||
continue;
|
||||
}
|
||||
|
@ -2485,105 +2479,6 @@ float *mesh_get_mapped_verts_nors(Scene *scene, Object *ob)
|
|||
return vertexcosnos;
|
||||
}
|
||||
|
||||
/* ********* crazyspace *************** */
|
||||
|
||||
int editmesh_get_first_deform_matrices(Scene *scene, Object *ob, EditMesh *em, float (**deformmats)[3][3], float (**deformcos)[3])
|
||||
{
|
||||
ModifierData *md;
|
||||
DerivedMesh *dm;
|
||||
int i, a, numleft = 0, numVerts = 0;
|
||||
int cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1);
|
||||
float (*defmats)[3][3] = NULL, (*deformedVerts)[3] = NULL;
|
||||
|
||||
modifiers_clearErrors(ob);
|
||||
|
||||
dm = NULL;
|
||||
md = modifiers_getVirtualModifierList(ob);
|
||||
|
||||
/* compute the deformation matrices and coordinates for the first
|
||||
modifiers with on cage editing that are enabled and support computing
|
||||
deform matrices */
|
||||
for(i = 0; md && i <= cageIndex; i++, md = md->next) {
|
||||
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
||||
|
||||
if(!editmesh_modifier_is_enabled(scene, md, dm))
|
||||
continue;
|
||||
|
||||
if(mti->type==eModifierTypeType_OnlyDeform && mti->deformMatricesEM) {
|
||||
if(!defmats) {
|
||||
dm= editmesh_get_derived(em, NULL);
|
||||
deformedVerts= editmesh_get_vertex_cos(em, &numVerts);
|
||||
defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats");
|
||||
|
||||
for(a=0; a<numVerts; a++)
|
||||
unit_m3(defmats[a]);
|
||||
}
|
||||
|
||||
mti->deformMatricesEM(md, ob, em, dm, deformedVerts, defmats,
|
||||
numVerts);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
for(; md && i <= cageIndex; md = md->next, i++)
|
||||
if(editmesh_modifier_is_enabled(scene, md, dm) && modifier_isCorrectableDeformed(md))
|
||||
numleft++;
|
||||
|
||||
if(dm)
|
||||
dm->release(dm);
|
||||
|
||||
*deformmats= defmats;
|
||||
*deformcos= deformedVerts;
|
||||
|
||||
return numleft;
|
||||
}
|
||||
|
||||
void sculpt_get_deform_matrices(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
|
||||
{
|
||||
ModifierData *md;
|
||||
DerivedMesh *dm;
|
||||
int a, numVerts= 0;
|
||||
float (*defmats)[3][3]= NULL, (*deformedVerts)[3]= NULL;
|
||||
MultiresModifierData *mmd= get_multires_modifier(scene, ob, 0);
|
||||
int has_multires = mmd != NULL && mmd->sculptlvl > 0;
|
||||
|
||||
if(has_multires) {
|
||||
*deformmats= NULL;
|
||||
*deformcos= NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
dm= NULL;
|
||||
md= modifiers_getVirtualModifierList(ob);
|
||||
|
||||
for(; md; md= md->next) {
|
||||
ModifierTypeInfo *mti= modifierType_getInfo(md->type);
|
||||
|
||||
if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
|
||||
|
||||
if(mti->type==eModifierTypeType_OnlyDeform && mti->deformMatrices) {
|
||||
if(!defmats) {
|
||||
Mesh *me= (Mesh*)ob->data;
|
||||
dm= mesh_create_derived(me, ob, NULL);
|
||||
deformedVerts= mesh_getVertexCos(me, &numVerts);
|
||||
defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats");
|
||||
|
||||
for(a=0; a<numVerts; a++)
|
||||
unit_m3(defmats[a]);
|
||||
}
|
||||
|
||||
mti->deformMatrices(md, ob, dm, deformedVerts, defmats, numVerts);
|
||||
}
|
||||
}
|
||||
|
||||
if(dm)
|
||||
dm->release(dm);
|
||||
|
||||
*deformmats= defmats;
|
||||
*deformcos= deformedVerts;
|
||||
}
|
||||
|
||||
/* ******************* GLSL ******************** */
|
||||
|
||||
void DM_add_tangent_layer(DerivedMesh *dm)
|
||||
|
|
|
@ -28,12 +28,15 @@
|
|||
#ifndef ED_UTIL_H
|
||||
#define ED_UTIL_H
|
||||
|
||||
struct Scene;
|
||||
struct Object;
|
||||
struct bContext;
|
||||
struct ARegion;
|
||||
struct uiBlock;
|
||||
struct wmOperator;
|
||||
struct wmOperatorType;
|
||||
struct EditMesh;
|
||||
struct Mesh;
|
||||
|
||||
/* ed_util.c */
|
||||
|
||||
|
@ -73,6 +76,15 @@ void undo_editmode_menu (struct bContext *C);
|
|||
void undo_editmode_clear (void);
|
||||
void undo_editmode_step (struct bContext *C, int step);
|
||||
|
||||
/* crazyspace.c */
|
||||
float *crazyspace_get_mapped_editverts(struct Scene *scene, struct Object *obedit);
|
||||
void crazyspace_set_quats_editmesh(struct EditMesh *em, float *origcos, float *mappedcos, float *quats);
|
||||
void crazyspace_set_quats_mesh(struct Mesh *me, float *origcos, float *mappedcos, float *quats);
|
||||
int editmesh_get_first_deform_matrices(struct Scene *scene, struct Object *ob, struct EditMesh *em, float (**deformmats)[3][3], float (**deformcos)[3]);
|
||||
int sculpt_get_first_deform_matrices(struct Scene *scene, struct Object *ob, float (**deformmats)[3][3], float (**deformcos)[3]);
|
||||
void crazyspace_build_sculpt(struct Scene *scene, struct Object *ob, float (**deformmats)[3][3], float (**deformcos)[3]);
|
||||
|
||||
|
||||
/* ************** XXX OLD CRUFT WARNING ************* */
|
||||
|
||||
void apply_keyb_grid(int shift, int ctrl, float *val, float fac1, float fac2, float fac3, int invert);
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
#include "WM_types.h"
|
||||
#include "ED_screen.h"
|
||||
#include "ED_view3d.h"
|
||||
#include "ED_util.h" /* for crazyspace correction */
|
||||
#include "paint_intern.h"
|
||||
#include "sculpt_intern.h"
|
||||
|
||||
|
@ -169,7 +170,7 @@ int sculpt_modifiers_active(Scene *scene, Object *ob)
|
|||
if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
|
||||
if(md->type==eModifierType_ShapeKey) continue;
|
||||
|
||||
if(mti->type==eModifierTypeType_OnlyDeform && mti->deformMatrices)
|
||||
if(mti->type==eModifierTypeType_OnlyDeform)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -2642,7 +2643,7 @@ void sculpt_update_mesh_elements(Scene *scene, Object *ob, int need_fmap)
|
|||
if(ss->kb) ss->orig_cos = key_to_vertcos(ob, ss->kb);
|
||||
else ss->orig_cos = mesh_getVertexCos(ob->data, NULL);
|
||||
|
||||
sculpt_get_deform_matrices(scene, ob, &ss->deform_imats, &ss->deform_cos);
|
||||
crazyspace_build_sculpt(scene, ob, &ss->deform_imats, &ss->deform_cos);
|
||||
BLI_pbvh_apply_vertCos(ss->pbvh, ss->deform_cos);
|
||||
|
||||
for(a = 0; a < ((Mesh*)ob->data)->totvert; ++a)
|
||||
|
|
|
@ -85,6 +85,7 @@
|
|||
#include "ED_types.h"
|
||||
#include "ED_uvedit.h"
|
||||
#include "ED_curve.h" /* for ED_curve_editnurbs */
|
||||
#include "ED_util.h" /* for crazyspace correction */
|
||||
|
||||
#include "UI_view2d.h"
|
||||
|
||||
|
@ -1940,147 +1941,6 @@ static void VertsToTransData(TransInfo *t, TransData *td, EditMesh *em, EditVert
|
|||
}
|
||||
}
|
||||
|
||||
/* *********************** CrazySpace correction. Now without doing subsurf optimal ****************** */
|
||||
|
||||
static void make_vertexcos__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
|
||||
{
|
||||
float *vec = userData;
|
||||
|
||||
vec+= 3*index;
|
||||
VECCOPY(vec, co);
|
||||
}
|
||||
|
||||
static int modifiers_disable_subsurf_temporary(Object *ob)
|
||||
{
|
||||
ModifierData *md;
|
||||
int disabled = 0;
|
||||
|
||||
for(md=ob->modifiers.first; md; md=md->next)
|
||||
if(md->type==eModifierType_Subsurf)
|
||||
if(md->mode & eModifierMode_OnCage) {
|
||||
md->mode ^= eModifierMode_DisableTemporary;
|
||||
disabled= 1;
|
||||
}
|
||||
|
||||
return disabled;
|
||||
}
|
||||
|
||||
/* disable subsurf temporal, get mapped cos, and enable it */
|
||||
static float *get_crazy_mapped_editverts(TransInfo *t)
|
||||
{
|
||||
Mesh *me= t->obedit->data;
|
||||
DerivedMesh *dm;
|
||||
float *vertexcos;
|
||||
|
||||
/* disable subsurf temporal, get mapped cos, and enable it */
|
||||
if(modifiers_disable_subsurf_temporary(t->obedit)) {
|
||||
/* need to make new derivemesh */
|
||||
makeDerivedMesh(t->scene, t->obedit, me->edit_mesh, CD_MASK_BAREMESH);
|
||||
}
|
||||
|
||||
/* now get the cage */
|
||||
dm= editmesh_get_derived_cage(t->scene, t->obedit, me->edit_mesh, CD_MASK_BAREMESH);
|
||||
|
||||
vertexcos= MEM_mallocN(3*sizeof(float)*me->edit_mesh->totvert, "vertexcos map");
|
||||
dm->foreachMappedVert(dm, make_vertexcos__mapFunc, vertexcos);
|
||||
|
||||
dm->release(dm);
|
||||
|
||||
/* set back the flag, no new cage needs to be built, transform does it */
|
||||
modifiers_disable_subsurf_temporary(t->obedit);
|
||||
|
||||
return vertexcos;
|
||||
}
|
||||
|
||||
#define TAN_MAKE_VEC(a, b, c) a[0]= b[0] + 0.2f*(b[0]-c[0]); a[1]= b[1] + 0.2f*(b[1]-c[1]); a[2]= b[2] + 0.2f*(b[2]-c[2])
|
||||
static void set_crazy_vertex_quat(float *quat, float *v1, float *v2, float *v3, float *def1, float *def2, float *def3)
|
||||
{
|
||||
float vecu[3], vecv[3];
|
||||
float q1[4], q2[4];
|
||||
|
||||
TAN_MAKE_VEC(vecu, v1, v2);
|
||||
TAN_MAKE_VEC(vecv, v1, v3);
|
||||
tri_to_quat( q1,v1, vecu, vecv);
|
||||
|
||||
TAN_MAKE_VEC(vecu, def1, def2);
|
||||
TAN_MAKE_VEC(vecv, def1, def3);
|
||||
tri_to_quat( q2,def1, vecu, vecv);
|
||||
|
||||
sub_qt_qtqt(quat, q2, q1);
|
||||
}
|
||||
#undef TAN_MAKE_VEC
|
||||
|
||||
static void set_crazyspace_quats(EditMesh *em, float *origcos, float *mappedcos, float *quats)
|
||||
{
|
||||
EditVert *eve, *prev;
|
||||
EditFace *efa;
|
||||
float *v1, *v2, *v3, *v4, *co1, *co2, *co3, *co4;
|
||||
intptr_t index= 0;
|
||||
|
||||
/* two abused locations in vertices */
|
||||
for(eve= em->verts.first; eve; eve= eve->next, index++) {
|
||||
eve->tmp.p = NULL;
|
||||
eve->prev= (EditVert *)index;
|
||||
}
|
||||
|
||||
/* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */
|
||||
for(efa= em->faces.first; efa; efa= efa->next) {
|
||||
|
||||
/* retrieve mapped coordinates */
|
||||
v1= mappedcos + 3*(intptr_t)(efa->v1->prev);
|
||||
v2= mappedcos + 3*(intptr_t)(efa->v2->prev);
|
||||
v3= mappedcos + 3*(intptr_t)(efa->v3->prev);
|
||||
|
||||
co1= (origcos)? origcos + 3*(intptr_t)(efa->v1->prev): efa->v1->co;
|
||||
co2= (origcos)? origcos + 3*(intptr_t)(efa->v2->prev): efa->v2->co;
|
||||
co3= (origcos)? origcos + 3*(intptr_t)(efa->v3->prev): efa->v3->co;
|
||||
|
||||
if(efa->v2->tmp.p==NULL && efa->v2->f1) {
|
||||
set_crazy_vertex_quat(quats, co2, co3, co1, v2, v3, v1);
|
||||
efa->v2->tmp.p= (void*)quats;
|
||||
quats+= 4;
|
||||
}
|
||||
|
||||
if(efa->v4) {
|
||||
v4= mappedcos + 3*(intptr_t)(efa->v4->prev);
|
||||
co4= (origcos)? origcos + 3*(intptr_t)(efa->v4->prev): efa->v4->co;
|
||||
|
||||
if(efa->v1->tmp.p==NULL && efa->v1->f1) {
|
||||
set_crazy_vertex_quat(quats, co1, co2, co4, v1, v2, v4);
|
||||
efa->v1->tmp.p= (void*)quats;
|
||||
quats+= 4;
|
||||
}
|
||||
if(efa->v3->tmp.p==NULL && efa->v3->f1) {
|
||||
set_crazy_vertex_quat(quats, co3, co4, co2, v3, v4, v2);
|
||||
efa->v3->tmp.p= (void*)quats;
|
||||
quats+= 4;
|
||||
}
|
||||
if(efa->v4->tmp.p==NULL && efa->v4->f1) {
|
||||
set_crazy_vertex_quat(quats, co4, co1, co3, v4, v1, v3);
|
||||
efa->v4->tmp.p= (void*)quats;
|
||||
quats+= 4;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(efa->v1->tmp.p==NULL && efa->v1->f1) {
|
||||
set_crazy_vertex_quat(quats, co1, co2, co3, v1, v2, v3);
|
||||
efa->v1->tmp.p= (void*)quats;
|
||||
quats+= 4;
|
||||
}
|
||||
if(efa->v3->tmp.p==NULL && efa->v3->f1) {
|
||||
set_crazy_vertex_quat(quats, co3, co1, co2, v3, v1, v2);
|
||||
efa->v3->tmp.p= (void*)quats;
|
||||
quats+= 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* restore abused prev pointer */
|
||||
for(prev= NULL, eve= em->verts.first; eve; prev= eve, eve= eve->next)
|
||||
eve->prev= prev;
|
||||
|
||||
}
|
||||
|
||||
void createTransBMeshVerts(TransInfo *t, BME_Mesh *bm, BME_TransData_Head *td) {
|
||||
BME_Vert *v;
|
||||
BME_TransData *vtd;
|
||||
|
@ -2200,9 +2060,9 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
|
|||
correction with quats, relative to the coordinates after
|
||||
the modifiers that support deform matrices (defcos) */
|
||||
if(totleft > 0) {
|
||||
mappedcos= get_crazy_mapped_editverts(t);
|
||||
mappedcos= crazyspace_get_mapped_editverts(t->scene, t->obedit);
|
||||
quats= MEM_mallocN( (t->total)*sizeof(float)*4, "crazy quats");
|
||||
set_crazyspace_quats(em, (float*)defcos, mappedcos, quats);
|
||||
crazyspace_set_quats_editmesh(em, (float*)defcos, mappedcos, quats);
|
||||
if(mappedcos)
|
||||
MEM_freeN(mappedcos);
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ set(SRC
|
|||
editmode_undo.c
|
||||
numinput.c
|
||||
undo.c
|
||||
crazyspace.c
|
||||
|
||||
util_intern.h
|
||||
# general includes
|
||||
|
|
394
source/blender/editors/util/crazyspace.c
Normal file
394
source/blender/editors/util/crazyspace.c
Normal file
|
@ -0,0 +1,394 @@
|
|||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2005 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Contributor(s): Blender Foundation,
|
||||
* Sergey Sharybin
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
|
||||
#include "BKE_DerivedMesh.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_multires.h"
|
||||
#include "BKE_mesh.h"
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_editVert.h"
|
||||
|
||||
#define TAN_MAKE_VEC(a, b, c) a[0]= b[0] + 0.2f*(b[0]-c[0]); a[1]= b[1] + 0.2f*(b[1]-c[1]); a[2]= b[2] + 0.2f*(b[2]-c[2])
|
||||
static void set_crazy_vertex_quat(float *quat, float *v1, float *v2, float *v3, float *def1, float *def2, float *def3)
|
||||
{
|
||||
float vecu[3], vecv[3];
|
||||
float q1[4], q2[4];
|
||||
|
||||
TAN_MAKE_VEC(vecu, v1, v2);
|
||||
TAN_MAKE_VEC(vecv, v1, v3);
|
||||
tri_to_quat( q1,v1, vecu, vecv);
|
||||
|
||||
TAN_MAKE_VEC(vecu, def1, def2);
|
||||
TAN_MAKE_VEC(vecv, def1, def3);
|
||||
tri_to_quat( q2,def1, vecu, vecv);
|
||||
|
||||
sub_qt_qtqt(quat, q2, q1);
|
||||
}
|
||||
#undef TAN_MAKE_VEC
|
||||
|
||||
static void make_vertexcos__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
|
||||
{
|
||||
float *vec = userData;
|
||||
|
||||
vec+= 3*index;
|
||||
VECCOPY(vec, co);
|
||||
}
|
||||
|
||||
static int modifiers_disable_subsurf_temporary(Object *ob)
|
||||
{
|
||||
ModifierData *md;
|
||||
int disabled = 0;
|
||||
|
||||
for(md=ob->modifiers.first; md; md=md->next)
|
||||
if(md->type==eModifierType_Subsurf)
|
||||
if(md->mode & eModifierMode_OnCage) {
|
||||
md->mode ^= eModifierMode_DisableTemporary;
|
||||
disabled= 1;
|
||||
}
|
||||
|
||||
return disabled;
|
||||
}
|
||||
|
||||
/* disable subsurf temporal, get mapped cos, and enable it */
|
||||
float *crazyspace_get_mapped_editverts(Scene *scene, Object *obedit)
|
||||
{
|
||||
Mesh *me= obedit->data;
|
||||
DerivedMesh *dm;
|
||||
float *vertexcos;
|
||||
|
||||
/* disable subsurf temporal, get mapped cos, and enable it */
|
||||
if(modifiers_disable_subsurf_temporary(obedit)) {
|
||||
/* need to make new derivemesh */
|
||||
makeDerivedMesh(scene, obedit, me->edit_mesh, CD_MASK_BAREMESH);
|
||||
}
|
||||
|
||||
/* now get the cage */
|
||||
dm= editmesh_get_derived_cage(scene, obedit, me->edit_mesh, CD_MASK_BAREMESH);
|
||||
|
||||
vertexcos= MEM_mallocN(3*sizeof(float)*me->edit_mesh->totvert, "vertexcos map");
|
||||
dm->foreachMappedVert(dm, make_vertexcos__mapFunc, vertexcos);
|
||||
|
||||
dm->release(dm);
|
||||
|
||||
/* set back the flag, no new cage needs to be built, transform does it */
|
||||
modifiers_disable_subsurf_temporary(obedit);
|
||||
|
||||
return vertexcos;
|
||||
}
|
||||
|
||||
void crazyspace_set_quats_editmesh(EditMesh *em, float *origcos, float *mappedcos, float *quats)
|
||||
{
|
||||
EditVert *eve, *prev;
|
||||
EditFace *efa;
|
||||
float *v1, *v2, *v3, *v4, *co1, *co2, *co3, *co4;
|
||||
intptr_t index= 0;
|
||||
|
||||
/* two abused locations in vertices */
|
||||
for(eve= em->verts.first; eve; eve= eve->next, index++) {
|
||||
eve->tmp.p = NULL;
|
||||
eve->prev= (EditVert *)index;
|
||||
}
|
||||
|
||||
/* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */
|
||||
for(efa= em->faces.first; efa; efa= efa->next) {
|
||||
|
||||
/* retrieve mapped coordinates */
|
||||
v1= mappedcos + 3*(intptr_t)(efa->v1->prev);
|
||||
v2= mappedcos + 3*(intptr_t)(efa->v2->prev);
|
||||
v3= mappedcos + 3*(intptr_t)(efa->v3->prev);
|
||||
|
||||
co1= (origcos)? origcos + 3*(intptr_t)(efa->v1->prev): efa->v1->co;
|
||||
co2= (origcos)? origcos + 3*(intptr_t)(efa->v2->prev): efa->v2->co;
|
||||
co3= (origcos)? origcos + 3*(intptr_t)(efa->v3->prev): efa->v3->co;
|
||||
|
||||
if(efa->v2->tmp.p==NULL && efa->v2->f1) {
|
||||
set_crazy_vertex_quat(quats, co2, co3, co1, v2, v3, v1);
|
||||
efa->v2->tmp.p= (void*)quats;
|
||||
quats+= 4;
|
||||
}
|
||||
|
||||
if(efa->v4) {
|
||||
v4= mappedcos + 3*(intptr_t)(efa->v4->prev);
|
||||
co4= (origcos)? origcos + 3*(intptr_t)(efa->v4->prev): efa->v4->co;
|
||||
|
||||
if(efa->v1->tmp.p==NULL && efa->v1->f1) {
|
||||
set_crazy_vertex_quat(quats, co1, co2, co4, v1, v2, v4);
|
||||
efa->v1->tmp.p= (void*)quats;
|
||||
quats+= 4;
|
||||
}
|
||||
if(efa->v3->tmp.p==NULL && efa->v3->f1) {
|
||||
set_crazy_vertex_quat(quats, co3, co4, co2, v3, v4, v2);
|
||||
efa->v3->tmp.p= (void*)quats;
|
||||
quats+= 4;
|
||||
}
|
||||
if(efa->v4->tmp.p==NULL && efa->v4->f1) {
|
||||
set_crazy_vertex_quat(quats, co4, co1, co3, v4, v1, v3);
|
||||
efa->v4->tmp.p= (void*)quats;
|
||||
quats+= 4;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(efa->v1->tmp.p==NULL && efa->v1->f1) {
|
||||
set_crazy_vertex_quat(quats, co1, co2, co3, v1, v2, v3);
|
||||
efa->v1->tmp.p= (void*)quats;
|
||||
quats+= 4;
|
||||
}
|
||||
if(efa->v3->tmp.p==NULL && efa->v3->f1) {
|
||||
set_crazy_vertex_quat(quats, co3, co1, co2, v3, v1, v2);
|
||||
efa->v3->tmp.p= (void*)quats;
|
||||
quats+= 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* restore abused prev pointer */
|
||||
for(prev= NULL, eve= em->verts.first; eve; prev= eve, eve= eve->next)
|
||||
eve->prev= prev;
|
||||
|
||||
}
|
||||
|
||||
void crazyspace_set_quats_mesh(Mesh *me, float *origcos, float *mappedcos, float *quats)
|
||||
{
|
||||
int i;
|
||||
MVert *mvert;
|
||||
MFace *mface;
|
||||
float *v1, *v2, *v3, *v4, *co1, *co2, *co3, *co4;
|
||||
|
||||
mvert= me->mvert;
|
||||
for(i=0; i<me->totvert; i++, mvert++)
|
||||
mvert->flag&= ~ME_VERT_TMP_TAG;
|
||||
|
||||
/* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */
|
||||
mvert= me->mvert;
|
||||
mface= me->mface;
|
||||
for(i=0; i<me->totface; i++, mface++) {
|
||||
|
||||
/* retrieve mapped coordinates */
|
||||
v1= mappedcos + 3*mface->v1;
|
||||
v2= mappedcos + 3*mface->v2;
|
||||
v3= mappedcos + 3*mface->v3;
|
||||
|
||||
co1= (origcos)? origcos + 3*mface->v1: mvert[mface->v1].co;
|
||||
co2= (origcos)? origcos + 3*mface->v2: mvert[mface->v2].co;
|
||||
co3= (origcos)? origcos + 3*mface->v3: mvert[mface->v3].co;
|
||||
|
||||
if((mvert[mface->v2].flag&ME_VERT_TMP_TAG)==0) {
|
||||
set_crazy_vertex_quat(&quats[mface->v2*4], co2, co3, co1, v2, v3, v1);
|
||||
mvert[mface->v2].flag|= ME_VERT_TMP_TAG;
|
||||
}
|
||||
|
||||
if(mface->v4) {
|
||||
v4= mappedcos + 3*mface->v4;
|
||||
co4= (origcos)? origcos + 3*mface->v4: mvert[mface->v4].co;
|
||||
|
||||
if((mvert[mface->v1].flag&ME_VERT_TMP_TAG)==0) {
|
||||
set_crazy_vertex_quat(&quats[mface->v1*4], co1, co2, co4, v1, v2, v4);
|
||||
mvert[mface->v1].flag|= ME_VERT_TMP_TAG;
|
||||
}
|
||||
if((mvert[mface->v3].flag&ME_VERT_TMP_TAG)==0) {
|
||||
set_crazy_vertex_quat(&quats[mface->v3*4], co3, co4, co2, v3, v4, v2);
|
||||
mvert[mface->v3].flag|= ME_VERT_TMP_TAG;
|
||||
}
|
||||
if((mvert[mface->v4].flag&ME_VERT_TMP_TAG)==0) {
|
||||
set_crazy_vertex_quat(&quats[mface->v4*4], co4, co1, co3, v4, v1, v3);
|
||||
mvert[mface->v4].flag|= ME_VERT_TMP_TAG;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if((mvert[mface->v1].flag&ME_VERT_TMP_TAG)==0) {
|
||||
set_crazy_vertex_quat(&quats[mface->v1*4], co1, co2, co3, v1, v2, v3);
|
||||
mvert[mface->v1].flag|= ME_VERT_TMP_TAG;
|
||||
}
|
||||
if((mvert[mface->v3].flag&ME_VERT_TMP_TAG)==0) {
|
||||
set_crazy_vertex_quat(&quats[mface->v3*4], co3, co1, co2, v3, v1, v2);
|
||||
mvert[mface->v3].flag|= ME_VERT_TMP_TAG;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int editmesh_get_first_deform_matrices(Scene *scene, Object *ob, EditMesh *em, float (**deformmats)[3][3], float (**deformcos)[3])
|
||||
{
|
||||
ModifierData *md;
|
||||
DerivedMesh *dm;
|
||||
int i, a, numleft = 0, numVerts = 0;
|
||||
int cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1);
|
||||
float (*defmats)[3][3] = NULL, (*deformedVerts)[3] = NULL;
|
||||
|
||||
modifiers_clearErrors(ob);
|
||||
|
||||
dm = NULL;
|
||||
md = modifiers_getVirtualModifierList(ob);
|
||||
|
||||
/* compute the deformation matrices and coordinates for the first
|
||||
modifiers with on cage editing that are enabled and support computing
|
||||
deform matrices */
|
||||
for(i = 0; md && i <= cageIndex; i++, md = md->next) {
|
||||
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
||||
|
||||
if(!editmesh_modifier_is_enabled(scene, md, dm))
|
||||
continue;
|
||||
|
||||
if(mti->type==eModifierTypeType_OnlyDeform && mti->deformMatricesEM) {
|
||||
if(!defmats) {
|
||||
dm= editmesh_get_derived(em, NULL);
|
||||
deformedVerts= editmesh_get_vertex_cos(em, &numVerts);
|
||||
defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats");
|
||||
|
||||
for(a=0; a<numVerts; a++)
|
||||
unit_m3(defmats[a]);
|
||||
}
|
||||
|
||||
mti->deformMatricesEM(md, ob, em, dm, deformedVerts, defmats,
|
||||
numVerts);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
for(; md && i <= cageIndex; md = md->next, i++)
|
||||
if(editmesh_modifier_is_enabled(scene, md, dm) && modifier_isCorrectableDeformed(md))
|
||||
numleft++;
|
||||
|
||||
if(dm)
|
||||
dm->release(dm);
|
||||
|
||||
*deformmats= defmats;
|
||||
*deformcos= deformedVerts;
|
||||
|
||||
return numleft;
|
||||
}
|
||||
|
||||
int sculpt_get_first_deform_matrices(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
|
||||
{
|
||||
ModifierData *md;
|
||||
DerivedMesh *dm;
|
||||
int a, numVerts= 0;
|
||||
float (*defmats)[3][3]= NULL, (*deformedVerts)[3]= NULL;
|
||||
MultiresModifierData *mmd= get_multires_modifier(scene, ob, 0);
|
||||
int has_multires = mmd != NULL && mmd->sculptlvl > 0;
|
||||
int numleft= 0;
|
||||
|
||||
if(has_multires) {
|
||||
*deformmats= NULL;
|
||||
*deformcos= NULL;
|
||||
return numleft;
|
||||
}
|
||||
|
||||
dm= NULL;
|
||||
md= modifiers_getVirtualModifierList(ob);
|
||||
|
||||
for(; md; md= md->next) {
|
||||
ModifierTypeInfo *mti= modifierType_getInfo(md->type);
|
||||
|
||||
if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
|
||||
|
||||
if(mti->type==eModifierTypeType_OnlyDeform) {
|
||||
if(!defmats) {
|
||||
Mesh *me= (Mesh*)ob->data;
|
||||
dm= mesh_create_derived(me, ob, NULL);
|
||||
deformedVerts= mesh_getVertexCos(me, &numVerts);
|
||||
defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats");
|
||||
|
||||
for(a=0; a<numVerts; a++)
|
||||
unit_m3(defmats[a]);
|
||||
}
|
||||
|
||||
if(mti->deformMatrices) mti->deformMatrices(md, ob, dm, deformedVerts, defmats, numVerts);
|
||||
else break;
|
||||
}
|
||||
}
|
||||
|
||||
for(; md; md= md->next) {
|
||||
ModifierTypeInfo *mti= modifierType_getInfo(md->type);
|
||||
|
||||
if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
|
||||
|
||||
if(mti->type==eModifierTypeType_OnlyDeform)
|
||||
numleft++;
|
||||
}
|
||||
|
||||
if(dm)
|
||||
dm->release(dm);
|
||||
|
||||
*deformmats= defmats;
|
||||
*deformcos= deformedVerts;
|
||||
|
||||
return numleft;
|
||||
}
|
||||
|
||||
void crazyspace_build_sculpt(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
|
||||
{
|
||||
int totleft= sculpt_get_first_deform_matrices(scene, ob, deformmats, deformcos);
|
||||
|
||||
if(totleft) {
|
||||
/* there are deformation modifier which doesn't support deformation matricies
|
||||
calculation. Need additional crazyspace correction */
|
||||
|
||||
float (*deformedVerts)[3]= *deformcos;
|
||||
float (*origVerts)[3]= MEM_dupallocN(deformedVerts);
|
||||
float *quats= NULL;
|
||||
int i;
|
||||
ModifierData *md= modifiers_getVirtualModifierList(ob);
|
||||
Mesh *me= (Mesh*)ob->data;
|
||||
|
||||
for(; md; md= md->next) {
|
||||
ModifierTypeInfo *mti= modifierType_getInfo(md->type);
|
||||
|
||||
if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
|
||||
|
||||
if(mti->type==eModifierTypeType_OnlyDeform)
|
||||
mti->deformVerts(md, ob, NULL, deformedVerts, me->totvert, 0, 0);
|
||||
}
|
||||
|
||||
quats= MEM_mallocN(me->totvert*sizeof(float)*4, "crazy quats");
|
||||
|
||||
crazyspace_set_quats_mesh(me, (float*)origVerts, (float*)deformedVerts, quats);
|
||||
|
||||
for(i=0; i<me->totvert; i++) {
|
||||
float qmat[3][3], tmat[3][3];
|
||||
|
||||
quat_to_mat3(qmat, &quats[i*4]);
|
||||
mul_m3_m3m3(tmat, qmat, (*deformmats)[i]);
|
||||
copy_m3_m3((*deformmats)[i], tmat);
|
||||
}
|
||||
|
||||
MEM_freeN(origVerts);
|
||||
MEM_freeN(quats);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue