Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2011-02-12 20:51:02 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2011-02-12 20:51:02 +0300
commitd909e61d99d760e9c5ae0c9e29804ac609bf7b5f (patch)
tree046c921a0670861cd0aca6813700001e052c19f9
parent673ac43f2ef06002d67f266ad2066b722654b5fc (diff)
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.
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h5
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c107
-rw-r--r--source/blender/editors/include/ED_util.h12
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c5
-rw-r--r--source/blender/editors/transform/transform_conversions.c146
-rw-r--r--source/blender/editors/util/CMakeLists.txt1
-rw-r--r--source/blender/editors/util/crazyspace.c394
7 files changed, 417 insertions, 253 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index e7ce3f27431..79e9b11d4db 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -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);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index be9cda6c58f..eedc2636991 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -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)
diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h
index 1cbf1d0e998..473d889c731 100644
--- a/source/blender/editors/include/ED_util.h
+++ b/source/blender/editors/include/ED_util.h
@@ -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);
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index f109340d827..7e72aad8adb 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -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)
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 86da5e0a4b5..20374cb8dbe 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -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);
}
diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt
index a2e0525cb0e..38c0dd7f0ba 100644
--- a/source/blender/editors/util/CMakeLists.txt
+++ b/source/blender/editors/util/CMakeLists.txt
@@ -34,6 +34,7 @@ set(SRC
editmode_undo.c
numinput.c
undo.c
+ crazyspace.c
util_intern.h
# general includes
diff --git a/source/blender/editors/util/crazyspace.c b/source/blender/editors/util/crazyspace.c
new file mode 100644
index 00000000000..8b03f1826e4
--- /dev/null
+++ b/source/blender/editors/util/crazyspace.c
@@ -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);
+ }
+}