Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2005 by the Blender Foundation. 00019 * All rights reserved. 00020 * 00021 * Contributor(s): Daniel Dunbar 00022 * Ton Roosendaal, 00023 * Ben Batt, 00024 * Brecht Van Lommel, 00025 * Campbell Barton 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 * 00029 */ 00030 00036 #include "MEM_guardedalloc.h" 00037 00038 #include "BLI_utildefines.h" 00039 #include "BLI_rand.h" 00040 #include "BLI_ghash.h" 00041 00042 #include "DNA_scene_types.h" 00043 #include "DNA_meshdata_types.h" 00044 00045 #include "BKE_cdderivedmesh.h" 00046 #include "BKE_mesh.h" 00047 #include "BKE_modifier.h" 00048 #include "BKE_object.h" 00049 #include "BKE_particle.h" 00050 #include "BKE_scene.h" 00051 00052 #include "MOD_util.h" 00053 00054 static void initData(ModifierData *md) 00055 { 00056 BuildModifierData *bmd = (BuildModifierData*) md; 00057 00058 bmd->start = 1.0; 00059 bmd->length = 100.0; 00060 } 00061 00062 static void copyData(ModifierData *md, ModifierData *target) 00063 { 00064 BuildModifierData *bmd = (BuildModifierData*) md; 00065 BuildModifierData *tbmd = (BuildModifierData*) target; 00066 00067 tbmd->start = bmd->start; 00068 tbmd->length = bmd->length; 00069 tbmd->randomize = bmd->randomize; 00070 tbmd->seed = bmd->seed; 00071 } 00072 00073 static int dependsOnTime(ModifierData *UNUSED(md)) 00074 { 00075 return 1; 00076 } 00077 00078 static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), 00079 DerivedMesh *derivedData, 00080 int UNUSED(useRenderParams), 00081 int UNUSED(isFinalCalc)) 00082 { 00083 DerivedMesh *dm = derivedData; 00084 DerivedMesh *result; 00085 BuildModifierData *bmd = (BuildModifierData*) md; 00086 int i; 00087 int numFaces, numEdges; 00088 int *vertMap, *edgeMap, *faceMap; 00089 float frac; 00090 GHashIterator *hashIter; 00091 /* maps vert indices in old mesh to indices in new mesh */ 00092 GHash *vertHash = BLI_ghash_new(BLI_ghashutil_inthash, 00093 BLI_ghashutil_intcmp, "build ve apply gh"); 00094 /* maps edge indices in new mesh to indices in old mesh */ 00095 GHash *edgeHash = BLI_ghash_new(BLI_ghashutil_inthash, 00096 BLI_ghashutil_intcmp, "build ed apply gh"); 00097 00098 const int maxVerts= dm->getNumVerts(dm); 00099 const int maxEdges= dm->getNumEdges(dm); 00100 const int maxFaces= dm->getNumFaces(dm); 00101 00102 vertMap = MEM_callocN(sizeof(*vertMap) * maxVerts, "build modifier vertMap"); 00103 for(i = 0; i < maxVerts; ++i) vertMap[i] = i; 00104 edgeMap = MEM_callocN(sizeof(*edgeMap) * maxEdges, "build modifier edgeMap"); 00105 for(i = 0; i < maxEdges; ++i) edgeMap[i] = i; 00106 faceMap = MEM_callocN(sizeof(*faceMap) * maxFaces, "build modifier faceMap"); 00107 for(i = 0; i < maxFaces; ++i) faceMap[i] = i; 00108 00109 frac = (BKE_curframe(md->scene) - bmd->start) / bmd->length; 00110 CLAMP(frac, 0.0f, 1.0f); 00111 00112 numFaces = dm->getNumFaces(dm) * frac; 00113 numEdges = dm->getNumEdges(dm) * frac; 00114 00115 /* if there's at least one face, build based on faces */ 00116 if(numFaces) { 00117 if(bmd->randomize) 00118 BLI_array_randomize(faceMap, sizeof(*faceMap), 00119 maxFaces, bmd->seed); 00120 00121 /* get the set of all vert indices that will be in the final mesh, 00122 * mapped to the new indices 00123 */ 00124 for(i = 0; i < numFaces; ++i) { 00125 MFace mf; 00126 dm->getFace(dm, faceMap[i], &mf); 00127 00128 if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v1))) 00129 BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v1), 00130 SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); 00131 if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v2))) 00132 BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v2), 00133 SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); 00134 if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v3))) 00135 BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v3), 00136 SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); 00137 if(mf.v4 && !BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v4))) 00138 BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v4), 00139 SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); 00140 } 00141 00142 /* get the set of edges that will be in the new mesh (i.e. all edges 00143 * that have both verts in the new mesh) 00144 */ 00145 for(i = 0; i < maxEdges; ++i) { 00146 MEdge me; 00147 dm->getEdge(dm, i, &me); 00148 00149 if(BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1)) 00150 && BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2))) 00151 BLI_ghash_insert(edgeHash, 00152 SET_INT_IN_POINTER(BLI_ghash_size(edgeHash)), SET_INT_IN_POINTER(i)); 00153 } 00154 } else if(numEdges) { 00155 if(bmd->randomize) 00156 BLI_array_randomize(edgeMap, sizeof(*edgeMap), 00157 maxEdges, bmd->seed); 00158 00159 /* get the set of all vert indices that will be in the final mesh, 00160 * mapped to the new indices 00161 */ 00162 for(i = 0; i < numEdges; ++i) { 00163 MEdge me; 00164 dm->getEdge(dm, edgeMap[i], &me); 00165 00166 if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1))) 00167 BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me.v1), 00168 SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); 00169 if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2))) 00170 BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me.v2), 00171 SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); 00172 } 00173 00174 /* get the set of edges that will be in the new mesh 00175 */ 00176 for(i = 0; i < numEdges; ++i) { 00177 MEdge me; 00178 dm->getEdge(dm, edgeMap[i], &me); 00179 00180 BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(BLI_ghash_size(edgeHash)), 00181 SET_INT_IN_POINTER(edgeMap[i])); 00182 } 00183 } else { 00184 int numVerts = dm->getNumVerts(dm) * frac; 00185 00186 if(bmd->randomize) 00187 BLI_array_randomize(vertMap, sizeof(*vertMap), 00188 maxVerts, bmd->seed); 00189 00190 /* get the set of all vert indices that will be in the final mesh, 00191 * mapped to the new indices 00192 */ 00193 for(i = 0; i < numVerts; ++i) 00194 BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(vertMap[i]), SET_INT_IN_POINTER(i)); 00195 } 00196 00197 /* now we know the number of verts, edges and faces, we can create 00198 * the mesh 00199 */ 00200 result = CDDM_from_template(dm, BLI_ghash_size(vertHash), 00201 BLI_ghash_size(edgeHash), numFaces); 00202 00203 /* copy the vertices across */ 00204 for( hashIter = BLI_ghashIterator_new(vertHash); 00205 !BLI_ghashIterator_isDone(hashIter); 00206 BLI_ghashIterator_step(hashIter) 00207 ) { 00208 MVert source; 00209 MVert *dest; 00210 int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter)); 00211 int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter)); 00212 00213 dm->getVert(dm, oldIndex, &source); 00214 dest = CDDM_get_vert(result, newIndex); 00215 00216 DM_copy_vert_data(dm, result, oldIndex, newIndex, 1); 00217 *dest = source; 00218 } 00219 BLI_ghashIterator_free(hashIter); 00220 00221 /* copy the edges across, remapping indices */ 00222 for(i = 0; i < BLI_ghash_size(edgeHash); ++i) { 00223 MEdge source; 00224 MEdge *dest; 00225 int oldIndex = GET_INT_FROM_POINTER(BLI_ghash_lookup(edgeHash, SET_INT_IN_POINTER(i))); 00226 00227 dm->getEdge(dm, oldIndex, &source); 00228 dest = CDDM_get_edge(result, i); 00229 00230 source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1))); 00231 source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2))); 00232 00233 DM_copy_edge_data(dm, result, oldIndex, i, 1); 00234 *dest = source; 00235 } 00236 00237 /* copy the faces across, remapping indices */ 00238 for(i = 0; i < numFaces; ++i) { 00239 MFace source; 00240 MFace *dest; 00241 int orig_v4; 00242 00243 dm->getFace(dm, faceMap[i], &source); 00244 dest = CDDM_get_face(result, i); 00245 00246 orig_v4 = source.v4; 00247 00248 source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1))); 00249 source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2))); 00250 source.v3 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v3))); 00251 if(source.v4) 00252 source.v4 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v4))); 00253 00254 DM_copy_face_data(dm, result, faceMap[i], i, 1); 00255 *dest = source; 00256 00257 test_index_face(dest, &result->faceData, i, (orig_v4 ? 4 : 3)); 00258 } 00259 00260 CDDM_calc_normals(result); 00261 00262 BLI_ghash_free(vertHash, NULL, NULL); 00263 BLI_ghash_free(edgeHash, NULL, NULL); 00264 00265 MEM_freeN(vertMap); 00266 MEM_freeN(edgeMap); 00267 MEM_freeN(faceMap); 00268 00269 return result; 00270 } 00271 00272 00273 ModifierTypeInfo modifierType_Build = { 00274 /* name */ "Build", 00275 /* structName */ "BuildModifierData", 00276 /* structSize */ sizeof(BuildModifierData), 00277 /* type */ eModifierTypeType_Nonconstructive, 00278 /* flags */ eModifierTypeFlag_AcceptsMesh 00279 | eModifierTypeFlag_AcceptsCVs, 00280 /* copyData */ copyData, 00281 /* deformVerts */ NULL, 00282 /* deformMatrices */ NULL, 00283 /* deformVertsEM */ NULL, 00284 /* deformMatricesEM */ NULL, 00285 /* applyModifier */ applyModifier, 00286 /* applyModifierEM */ NULL, 00287 /* initData */ initData, 00288 /* requiredDataMask */ NULL, 00289 /* freeData */ NULL, 00290 /* isDisabled */ NULL, 00291 /* updateDepgraph */ NULL, 00292 /* dependsOnTime */ dependsOnTime, 00293 /* dependsOnNormals */ NULL, 00294 /* foreachObjectLink */ NULL, 00295 /* foreachIDLink */ NULL, 00296 /* foreachTexLink */ NULL, 00297 };