Shrinkwrap skeleton code
authorAndre Susano Pinto <andresusanopinto@gmail.com>
Fri, 25 Apr 2008 18:22:20 +0000 (18:22 +0000)
committerAndre Susano Pinto <andresusanopinto@gmail.com>
Fri, 25 Apr 2008 18:22:20 +0000 (18:22 +0000)
+vertex weights supported
+target object now saves to file: load/save works :)

for now simple moves objects vertexs to the nearest vertexs on target object
(so that I can test if its working correctly with the modifier API)

source/blender/blenkernel/BKE_shrinkwrap.h [new file with mode: 0644]
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/shrinkwrap.c [new file with mode: 0644]
source/blender/makesdna/DNA_modifier_types.h
source/blender/src/buttons_editing.c

diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h
new file mode 100644 (file)
index 0000000..4fd1ae3
--- /dev/null
@@ -0,0 +1,40 @@
+/**
+ * shrinkwrap.c
+ *
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef BKE_SHRINKWRAP_H
+#define BKE_SHRINKWRAP_H
+
+struct Object;
+struct DerivedMesh;
+struct ShrinkwrapModifierData;
+
+struct DerivedMesh *shrinkwrapModifier_do(struct ShrinkwrapModifierData *smd, struct Object *ob, struct DerivedMesh *dm, int useRenderParams, int isFinalCalc);
+
+#endif
+
+
index 8903bfd310605ad7581384075c7d3b36f44c54fe..a34a9133021bbb6a9b18f38627b2d5d4b3b038c5 100644 (file)
@@ -97,6 +97,7 @@
 #include "BKE_utildefines.h"
 #include "depsgraph_private.h"
 #include "BKE_bmesh.h"
+#include "BKE_shrinkwrap.h"
 
 #include "LOD_DependKludge.h"
 #include "LOD_decimation.h"
@@ -6973,11 +6974,39 @@ static void meshdeformModifier_deformVertsEM(
 
 /* Shrinkwrap */
 
-static DerivedMesh *shrinkwrapModifier_applyModifier(
-               ModifierData *md, Object *ob, DerivedMesh *derivedData,
-  int useRenderParams, int isFinalCalc)
+static void shrinkwrapModifier_initData(ModifierData *md)
 {
-       return derivedData;
+       ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
+       smd->shrinkType = MOD_SHRINKWRAP_NEAREST;
+}
+
+static void shrinkwrapModifier_copyData(ModifierData *md, ModifierData *target)
+{
+       memcpy(target, md, sizeof(MeshDeformModifierData));
+}
+
+static void shrinkwrapModifier_foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
+{
+       ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
+
+       walk(userData, ob, &smd->target);
+}
+
+static DerivedMesh *shrinkwrapModifier_applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData, int useRenderParams, int isFinalCalc)
+{
+       return shrinkwrapModifier_do((ShrinkwrapModifierData*)md,ob,derivedData,useRenderParams,isFinalCalc);
+}
+
+static void shrinkwrapModifier_updateDepgraph(ModifierData *md, DagForest *forest, Object *ob, DagNode *obNode)
+{
+       ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
+
+       if (smd->target) {
+               DagNode *curNode = dag_get_node(forest, smd->target);
+
+               dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA,
+                       "Shrinkwrap Modifier");
+       }
 }
 
 
@@ -7302,10 +7331,14 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                mti->applyModifier = explodeModifier_applyModifier;
 
                mti = INIT_TYPE(Shrinkwrap);
-               mti->type = eModifierTypeType_Constructive;
-               mti->flags = eModifierTypeFlag_AcceptsMesh
-                               | eModifierTypeFlag_SupportsMapping;
+               mti->type = eModifierTypeType_Nonconstructive;
+               mti->flags = eModifierTypeFlag_AcceptsMesh;
+               /*| eModifierTypeFlag_SupportsMapping; Not yet X'D */
+               mti->initData = shrinkwrapModifier_initData;
+               mti->copyData = shrinkwrapModifier_copyData;
+               mti->foreachObjectLink = shrinkwrapModifier_foreachObjectLink;
                mti->applyModifier = shrinkwrapModifier_applyModifier;
+               mti->updateDepgraph = shrinkwrapModifier_updateDepgraph;
 
                typeArrInit = 0;
 #undef INIT_TYPE
diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
new file mode 100644 (file)
index 0000000..18f36f6
--- /dev/null
@@ -0,0 +1,157 @@
+/**
+ * shrinkwrap.c
+ *
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#include <string.h>
+#include <float.h>
+#include <assert.h>
+//TODO: its late and I don't fill like adding ifs() printfs (I'll remove them on end)
+
+#include "DNA_object_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BKE_shrinkwrap.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_utildefines.h"
+#include "BKE_deform.h"
+#include "BKE_cdderivedmesh.h"
+
+#include "BLI_arithb.h"
+
+/* Projects the vertex on the normal direction over the target mesh */
+static void shrinkwrap_calc_normal_projection(DerivedMesh *target, float *co, short *no)
+{
+}
+
+/* Nearest surface point on target mesh */
+static void shrinkwrap_calc_nearest_point(DerivedMesh *target, float *co, short *no)
+{
+       //TODO: For now its only doing a nearest vertex on target mesh (just for testing other things)
+       float minDist = FLT_MAX;
+       float orig_co[3];
+
+       int i;
+       int     numVerts = target->getNumVerts(target);
+       MVert *vert = target->getVertDataArray(target, CD_MVERT);
+
+       VECCOPY(orig_co, co);
+
+       for (i = 0; i < numVerts; i++)
+       {
+               float diff[3], sdist;
+               VECSUB(diff, orig_co, vert[i].co);
+               sdist = Inpf(diff, diff);
+               
+               if(sdist < minDist)
+               {
+                       minDist = sdist;
+                       VECCOPY(co, vert[i].co);
+               }
+       }
+}
+
+DerivedMesh *shrinkwrapModifier_do(ShrinkwrapModifierData *smd, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
+{
+
+       DerivedMesh *result = CDDM_copy(dm);
+
+       //Projecting target defined - lets work!
+       if(smd->target)
+       {
+               int i, j;
+
+               int vgroup              = get_named_vertexgroup_num(ob, smd->vgroup_name);
+               int     numVerts        = 0;
+
+               MDeformVert *dvert = NULL;
+               MVert           *vert  = NULL;
+
+               float local2target[4][4], target2local[4][4];
+
+               DerivedMesh *target_dm = (DerivedMesh *)smd->target->derivedFinal;
+
+               numVerts = result->getNumVerts(result);
+               dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);       //TODO: cddm doens't supports vertex groups :S
+               vert  = result->getVertDataArray(result, CD_MVERT);
+
+               /* TODO: Check about editMesh stuff :S */
+               /*
+               if(G.obedit && G.editMesh)
+                       target_dm = CDDM_from_editmesh(G.editMesh, smd->target->data); // Needs release before returning
+               else
+               */
+
+
+               //Calculate matrixs for local <-> target
+
+               //Update inverse matrixs
+               Mat4Invert (ob->imat, ob->obmat);
+               Mat4Invert (smd->target->imat, smd->target->obmat);
+
+               Mat4MulSerie(local2target, ob->obmat, smd->target->imat, 0, 0, 0, 0, 0, 0);
+               Mat4MulSerie(target2local, smd->target->obmat, ob->imat, 0, 0, 0, 0, 0, 0);
+
+
+               //Shrink (calculate each vertex final position)
+               for(i = 0; i<numVerts; i++)
+               {
+                       float weight;
+                       float orig[3], final[3]; //Coords relative to target_dm
+
+                       if(dvert && vgroup >= 0)
+                       {
+                               weight = 0.0f;
+                               for(j = 0; j < dvert[i].totweight; j++)
+                                       if(dvert[i].dw[j].def_nr == vgroup)
+                                       {
+                                               weight = dvert[i].dw[j].weight;
+                                               break;
+                                       }
+                       }
+                       else weight = 1.0f;
+
+                       VecMat4MulVecfl(orig, local2target, vert[i].co);
+                       
+                       VECCOPY(final, orig);
+                       shrinkwrap_calc_nearest_point(target_dm, final, vert[i].no);
+
+                       //TODO linear interpolation: theres probably somewhere a function for this
+                       final[0] = orig[0] + weight * (final[0] - orig[0]);
+                       final[1] = orig[1] + weight * (final[1] - orig[1]);
+                       final[2] = orig[2] + weight * (final[2] - orig[2]);
+
+                       VecMat4MulVecfl(vert[i].co, target2local, final);
+               }
+
+               //Destroy faces, edges and stuff
+               //Since we aren't yet constructing/destructing geom nothing todo for now
+       }
+       
+       return result;
+}
+
index 416bb58ab531c5d570354759016f2a6518adb4a7..bbc066cdb86659465f0ca016515ef2be93b6acea 100644 (file)
@@ -492,7 +492,8 @@ typedef struct ExplodeModifierData {
 typedef struct ShrinkwrapModifierData {
        ModifierData modifier;
 
-       char name[32];                  /* optional vertexgroup name */
+       struct Object *target;  /* shrink target */
+       char vgroup_name[32];   /* optional vertexgroup name */
        short shrinkType;               /* shrink type projection */
        short pad[3];
 } ShrinkwrapModifierData;
index 8f1b8e56df7f5ebd6567e9789296144113fec073..425dbaf603d1b91ff403f8664ecc2f4db817d518 100644 (file)
@@ -1821,7 +1821,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
                } else if (md->type==eModifierType_Explode) {
                        height = 94;
                } else if (md->type==eModifierType_Shrinkwrap) {
-                       height = 48;
+                       height = 48+19;
                }
                                                        /* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
                uiDefBut(block, ROUNDBOX, 0, "", x-10, y-height-2, width, height-2, NULL, 5.0, 0.0, 12, 40, ""); 
@@ -2440,8 +2440,10 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
                        char shrinktypemenu[]="Shrinkwrap type%t|nearest point %x0|normal projection %x1";
                        uiDefButS(block, MENU, B_MODIFIER_RECALC, shrinktypemenu, lx,(cy-=19),buttonWidth,19, &smd->shrinkType, 0, 0, 0, 0, "Selects type of shrinkwrap algorithm for target position.");
 
-                       but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ",         lx, (cy-=19), buttonWidth,19, &smd->name, 0.0, 31.0, 0, 0, "Vertex Group name");
+                       but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ",         lx, (cy-=19), buttonWidth,19, &smd->vgroup_name, 0.0, 31.0, 0, 0, "Vertex Group name");
                        uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
+
+                       uiDefIDPoinBut(block, modifier_testMeshObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &smd->target, "Target to shrink to");
                }
 
                uiBlockEndAlign(block);