|
Blender
V2.59
|
00001 /* 00002 * $Id: MOD_build.c 36276 2011-04-21 15:53:30Z 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 "MEM_guardedalloc.h" 00039 00040 #include "BLI_utildefines.h" 00041 #include "BLI_rand.h" 00042 #include "BLI_ghash.h" 00043 00044 #include "DNA_scene_types.h" 00045 #include "DNA_meshdata_types.h" 00046 00047 #include "BKE_cdderivedmesh.h" 00048 #include "BKE_mesh.h" 00049 #include "BKE_modifier.h" 00050 #include "BKE_object.h" 00051 #include "BKE_particle.h" 00052 #include "BKE_scene.h" 00053 00054 #include "MOD_util.h" 00055 00056 static void initData(ModifierData *md) 00057 { 00058 BuildModifierData *bmd = (BuildModifierData*) md; 00059 00060 bmd->start = 1.0; 00061 bmd->length = 100.0; 00062 } 00063 00064 static void copyData(ModifierData *md, ModifierData *target) 00065 { 00066 BuildModifierData *bmd = (BuildModifierData*) md; 00067 BuildModifierData *tbmd = (BuildModifierData*) target; 00068 00069 tbmd->start = bmd->start; 00070 tbmd->length = bmd->length; 00071 tbmd->randomize = bmd->randomize; 00072 tbmd->seed = bmd->seed; 00073 } 00074 00075 static int dependsOnTime(ModifierData *UNUSED(md)) 00076 { 00077 return 1; 00078 } 00079 00080 static DerivedMesh *applyModifier(ModifierData *md, Object *ob, 00081 DerivedMesh *derivedData, 00082 int UNUSED(useRenderParams), 00083 int UNUSED(isFinalCalc)) 00084 { 00085 DerivedMesh *dm = derivedData; 00086 DerivedMesh *result; 00087 BuildModifierData *bmd = (BuildModifierData*) md; 00088 int i; 00089 int numFaces, numEdges; 00090 int *vertMap, *edgeMap, *faceMap; 00091 float frac; 00092 GHashIterator *hashIter; 00093 /* maps vert indices in old mesh to indices in new mesh */ 00094 GHash *vertHash = BLI_ghash_new(BLI_ghashutil_inthash, 00095 BLI_ghashutil_intcmp, "build ve apply gh"); 00096 /* maps edge indices in new mesh to indices in old mesh */ 00097 GHash *edgeHash = BLI_ghash_new(BLI_ghashutil_inthash, 00098 BLI_ghashutil_intcmp, "build ed apply gh"); 00099 00100 const int maxVerts= dm->getNumVerts(dm); 00101 const int maxEdges= dm->getNumEdges(dm); 00102 const int maxFaces= dm->getNumFaces(dm); 00103 00104 vertMap = MEM_callocN(sizeof(*vertMap) * maxVerts, "build modifier vertMap"); 00105 for(i = 0; i < maxVerts; ++i) vertMap[i] = i; 00106 edgeMap = MEM_callocN(sizeof(*edgeMap) * maxEdges, "build modifier edgeMap"); 00107 for(i = 0; i < maxEdges; ++i) edgeMap[i] = i; 00108 faceMap = MEM_callocN(sizeof(*faceMap) * maxFaces, "build modifier faceMap"); 00109 for(i = 0; i < maxFaces; ++i) faceMap[i] = i; 00110 00111 if (ob) { 00112 frac = bsystem_time(md->scene, ob, md->scene->r.cfra, 00113 bmd->start - 1.0f) / bmd->length; 00114 } else { 00115 frac = BKE_curframe(md->scene) - bmd->start / bmd->length; 00116 } 00117 CLAMP(frac, 0.0f, 1.0f); 00118 00119 numFaces = dm->getNumFaces(dm) * frac; 00120 numEdges = dm->getNumEdges(dm) * frac; 00121 00122 /* if there's at least one face, build based on faces */ 00123 if(numFaces) { 00124 if(bmd->randomize) 00125 BLI_array_randomize(faceMap, sizeof(*faceMap), 00126 maxFaces, bmd->seed); 00127 00128 /* get the set of all vert indices that will be in the final mesh, 00129 * mapped to the new indices 00130 */ 00131 for(i = 0; i < numFaces; ++i) { 00132 MFace mf; 00133 dm->getFace(dm, faceMap[i], &mf); 00134 00135 if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v1))) 00136 BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v1), 00137 SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); 00138 if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v2))) 00139 BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v2), 00140 SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); 00141 if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v3))) 00142 BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v3), 00143 SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); 00144 if(mf.v4 && !BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v4))) 00145 BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v4), 00146 SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); 00147 } 00148 00149 /* get the set of edges that will be in the new mesh (i.e. all edges 00150 * that have both verts in the new mesh) 00151 */ 00152 for(i = 0; i < maxEdges; ++i) { 00153 MEdge me; 00154 dm->getEdge(dm, i, &me); 00155 00156 if(BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1)) 00157 && BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2))) 00158 BLI_ghash_insert(edgeHash, 00159 SET_INT_IN_POINTER(BLI_ghash_size(edgeHash)), SET_INT_IN_POINTER(i)); 00160 } 00161 } else if(numEdges) { 00162 if(bmd->randomize) 00163 BLI_array_randomize(edgeMap, sizeof(*edgeMap), 00164 maxEdges, bmd->seed); 00165 00166 /* get the set of all vert indices that will be in the final mesh, 00167 * mapped to the new indices 00168 */ 00169 for(i = 0; i < numEdges; ++i) { 00170 MEdge me; 00171 dm->getEdge(dm, edgeMap[i], &me); 00172 00173 if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1))) 00174 BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me.v1), 00175 SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); 00176 if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2))) 00177 BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me.v2), 00178 SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); 00179 } 00180 00181 /* get the set of edges that will be in the new mesh 00182 */ 00183 for(i = 0; i < numEdges; ++i) { 00184 MEdge me; 00185 dm->getEdge(dm, edgeMap[i], &me); 00186 00187 BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(BLI_ghash_size(edgeHash)), 00188 SET_INT_IN_POINTER(edgeMap[i])); 00189 } 00190 } else { 00191 int numVerts = dm->getNumVerts(dm) * frac; 00192 00193 if(bmd->randomize) 00194 BLI_array_randomize(vertMap, sizeof(*vertMap), 00195 maxVerts, bmd->seed); 00196 00197 /* get the set of all vert indices that will be in the final mesh, 00198 * mapped to the new indices 00199 */ 00200 for(i = 0; i < numVerts; ++i) 00201 BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(vertMap[i]), SET_INT_IN_POINTER(i)); 00202 } 00203 00204 /* now we know the number of verts, edges and faces, we can create 00205 * the mesh 00206 */ 00207 result = CDDM_from_template(dm, BLI_ghash_size(vertHash), 00208 BLI_ghash_size(edgeHash), numFaces); 00209 00210 /* copy the vertices across */ 00211 for( hashIter = BLI_ghashIterator_new(vertHash); 00212 !BLI_ghashIterator_isDone(hashIter); 00213 BLI_ghashIterator_step(hashIter) 00214 ) { 00215 MVert source; 00216 MVert *dest; 00217 int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter)); 00218 int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter)); 00219 00220 dm->getVert(dm, oldIndex, &source); 00221 dest = CDDM_get_vert(result, newIndex); 00222 00223 DM_copy_vert_data(dm, result, oldIndex, newIndex, 1); 00224 *dest = source; 00225 } 00226 BLI_ghashIterator_free(hashIter); 00227 00228 /* copy the edges across, remapping indices */ 00229 for(i = 0; i < BLI_ghash_size(edgeHash); ++i) { 00230 MEdge source; 00231 MEdge *dest; 00232 int oldIndex = GET_INT_FROM_POINTER(BLI_ghash_lookup(edgeHash, SET_INT_IN_POINTER(i))); 00233 00234 dm->getEdge(dm, oldIndex, &source); 00235 dest = CDDM_get_edge(result, i); 00236 00237 source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1))); 00238 source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2))); 00239 00240 DM_copy_edge_data(dm, result, oldIndex, i, 1); 00241 *dest = source; 00242 } 00243 00244 /* copy the faces across, remapping indices */ 00245 for(i = 0; i < numFaces; ++i) { 00246 MFace source; 00247 MFace *dest; 00248 int orig_v4; 00249 00250 dm->getFace(dm, faceMap[i], &source); 00251 dest = CDDM_get_face(result, i); 00252 00253 orig_v4 = source.v4; 00254 00255 source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1))); 00256 source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2))); 00257 source.v3 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v3))); 00258 if(source.v4) 00259 source.v4 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v4))); 00260 00261 DM_copy_face_data(dm, result, faceMap[i], i, 1); 00262 *dest = source; 00263 00264 test_index_face(dest, &result->faceData, i, (orig_v4 ? 4 : 3)); 00265 } 00266 00267 CDDM_calc_normals(result); 00268 00269 BLI_ghash_free(vertHash, NULL, NULL); 00270 BLI_ghash_free(edgeHash, NULL, NULL); 00271 00272 MEM_freeN(vertMap); 00273 MEM_freeN(edgeMap); 00274 MEM_freeN(faceMap); 00275 00276 return result; 00277 } 00278 00279 00280 ModifierTypeInfo modifierType_Build = { 00281 /* name */ "Build", 00282 /* structName */ "BuildModifierData", 00283 /* structSize */ sizeof(BuildModifierData), 00284 /* type */ eModifierTypeType_Nonconstructive, 00285 /* flags */ eModifierTypeFlag_AcceptsMesh 00286 | eModifierTypeFlag_AcceptsCVs, 00287 /* copyData */ copyData, 00288 /* deformVerts */ NULL, 00289 /* deformMatrices */ NULL, 00290 /* deformVertsEM */ NULL, 00291 /* deformMatricesEM */ NULL, 00292 /* applyModifier */ applyModifier, 00293 /* applyModifierEM */ NULL, 00294 /* initData */ initData, 00295 /* requiredDataMask */ NULL, 00296 /* freeData */ NULL, 00297 /* isDisabled */ NULL, 00298 /* updateDepgraph */ NULL, 00299 /* dependsOnTime */ dependsOnTime, 00300 /* dependsOnNormals */ NULL, 00301 /* foreachObjectLink */ NULL, 00302 /* foreachIDLink */ NULL 00303 };