Blender  V2.59
MOD_shrinkwrap.c
Go to the documentation of this file.
00001 /*
00002 * $Id: MOD_shrinkwrap.c 35362 2011-03-05 10:29:10Z campbellbarton $
00003 *
00004 * ***** BEGIN GPL LICENSE BLOCK *****
00005 *
00006 * This program is free software; you can redistribute it and/or
00007 * modify it under the terms of the GNU General Public License
00008 * as published by the Free Software Foundation; either version 2
00009 * of the License, or (at your option) any later version.
00010 *
00011 * This program is distributed in the hope that it will be useful,
00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 * GNU General Public License for more details.
00015 *
00016 * You should have received a copy of the GNU General Public License
00017 * along with this program; if not, write to the Free Software  Foundation,
00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019 *
00020 * The Original Code is Copyright (C) 2005 by the Blender Foundation.
00021 * All rights reserved.
00022 *
00023 * Contributor(s): Daniel Dunbar
00024 *                 Ton Roosendaal,
00025 *                 Ben Batt,
00026 *                 Brecht Van Lommel,
00027 *                 Campbell Barton
00028 *
00029 * ***** END GPL LICENSE BLOCK *****
00030 *
00031 */
00032 
00038 #include <string.h>
00039 
00040 #include "BLI_string.h"
00041 #include "BLI_utildefines.h"
00042 
00043 #include "BKE_cdderivedmesh.h"
00044 #include "BKE_modifier.h"
00045 #include "BKE_shrinkwrap.h"
00046 
00047 #include "DNA_object_types.h"
00048 
00049 #include "depsgraph_private.h"
00050 
00051 #include "MOD_util.h"
00052 
00053 
00054 static void initData(ModifierData *md)
00055 {
00056         ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
00057         smd->shrinkType = MOD_SHRINKWRAP_NEAREST_SURFACE;
00058         smd->shrinkOpts = MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR;
00059         smd->keepDist   = 0.0f;
00060 
00061         smd->target             = NULL;
00062         smd->auxTarget  = NULL;
00063 }
00064 
00065 static void copyData(ModifierData *md, ModifierData *target)
00066 {
00067         ShrinkwrapModifierData *smd  = (ShrinkwrapModifierData*)md;
00068         ShrinkwrapModifierData *tsmd = (ShrinkwrapModifierData*)target;
00069 
00070         tsmd->target    = smd->target;
00071         tsmd->auxTarget = smd->auxTarget;
00072 
00073         BLI_strncpy(tsmd->vgroup_name, smd->vgroup_name, sizeof(tsmd->vgroup_name));
00074 
00075         tsmd->keepDist  = smd->keepDist;
00076         tsmd->shrinkType= smd->shrinkType;
00077         tsmd->shrinkOpts= smd->shrinkOpts;
00078         tsmd->projAxis = smd->projAxis;
00079         tsmd->subsurfLevels = smd->subsurfLevels;
00080 }
00081 
00082 static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
00083 {
00084         ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
00085         CustomDataMask dataMask = 0;
00086 
00087         /* ask for vertexgroups if we need them */
00088         if(smd->vgroup_name[0])
00089                 dataMask |= CD_MASK_MDEFORMVERT;
00090 
00091         if(smd->shrinkType == MOD_SHRINKWRAP_PROJECT
00092         && smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL)
00093                 dataMask |= CD_MASK_MVERT;
00094                 
00095         return dataMask;
00096 }
00097 
00098 static int isDisabled(ModifierData *md, int UNUSED(useRenderParams))
00099 {
00100         ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
00101         return !smd->target;
00102 }
00103 
00104 
00105 static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
00106 {
00107         ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
00108 
00109         walk(userData, ob, &smd->target);
00110         walk(userData, ob, &smd->auxTarget);
00111 }
00112 
00113 static void deformVerts(ModifierData *md, Object *ob,
00114                                                 DerivedMesh *derivedData,
00115                                                 float (*vertexCos)[3],
00116                                                 int numVerts,
00117                                                 int UNUSED(useRenderParams),
00118                                                 int UNUSED(isFinalCalc))
00119 {
00120         DerivedMesh *dm = derivedData;
00121         CustomDataMask dataMask = requiredDataMask(ob, md);
00122 
00123         /* ensure we get a CDDM with applied vertex coords */
00124         if(dataMask)
00125                 dm= get_cddm(ob, NULL, dm, vertexCos);
00126 
00127         shrinkwrapModifier_deform((ShrinkwrapModifierData*)md, ob, dm, vertexCos, numVerts);
00128 
00129         if(dm != derivedData)
00130                 dm->release(dm);
00131 }
00132 
00133 static void deformVertsEM(ModifierData *md, Object *ob, struct EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
00134 {
00135         DerivedMesh *dm = derivedData;
00136         CustomDataMask dataMask = requiredDataMask(ob, md);
00137 
00138         /* ensure we get a CDDM with applied vertex coords */
00139         if(dataMask)
00140                 dm= get_cddm(ob, editData, dm, vertexCos);
00141 
00142         shrinkwrapModifier_deform((ShrinkwrapModifierData*)md, ob, dm, vertexCos, numVerts);
00143 
00144         if(dm != derivedData)
00145                 dm->release(dm);
00146 }
00147 
00148 static void updateDepgraph(ModifierData *md, DagForest *forest,
00149                                                 struct Scene *UNUSED(scene),
00150                                                 Object *UNUSED(ob),
00151                                                 DagNode *obNode)
00152 {
00153         ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
00154 
00155         if (smd->target)
00156                 dag_add_relation(forest, dag_get_node(forest, smd->target),   obNode, DAG_RL_OB_DATA | DAG_RL_DATA_DATA, "Shrinkwrap Modifier");
00157 
00158         if (smd->auxTarget)
00159                 dag_add_relation(forest, dag_get_node(forest, smd->auxTarget), obNode, DAG_RL_OB_DATA | DAG_RL_DATA_DATA, "Shrinkwrap Modifier");
00160 }
00161 
00162 
00163 ModifierTypeInfo modifierType_Shrinkwrap = {
00164         /* name */              "Shrinkwrap",
00165         /* structName */        "ShrinkwrapModifierData",
00166         /* structSize */        sizeof(ShrinkwrapModifierData),
00167         /* type */              eModifierTypeType_OnlyDeform,
00168         /* flags */             eModifierTypeFlag_AcceptsMesh
00169                                                         | eModifierTypeFlag_AcceptsCVs
00170                                                         | eModifierTypeFlag_SupportsEditmode
00171                                                         | eModifierTypeFlag_EnableInEditmode,
00172 
00173         /* copyData */          copyData,
00174         /* deformVerts */       deformVerts,
00175         /* deformMatrices */    NULL,
00176         /* deformVertsEM */     deformVertsEM,
00177         /* deformMatricesEM */  NULL,
00178         /* applyModifier */     NULL,
00179         /* applyModifierEM */   NULL,
00180         /* initData */          initData,
00181         /* requiredDataMask */  requiredDataMask,
00182         /* freeData */          NULL,
00183         /* isDisabled */        isDisabled,
00184         /* updateDepgraph */    updateDepgraph,
00185         /* dependsOnTime */     NULL,
00186         /* dependsOnNormals */  NULL,
00187         /* foreachObjectLink */ foreachObjectLink,
00188         /* foreachIDLink */     NULL,
00189 };