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 00035 #include <stdio.h> 00036 00037 #include "DNA_object_types.h" 00038 00039 #include "BLI_utildefines.h" 00040 00041 00042 #include "BKE_cdderivedmesh.h" 00043 #include "BKE_modifier.h" 00044 00045 #include "depsgraph_private.h" 00046 00047 #include "MOD_boolean_util.h" 00048 #include "MOD_util.h" 00049 00050 static void copyData(ModifierData *md, ModifierData *target) 00051 { 00052 BooleanModifierData *bmd = (BooleanModifierData*) md; 00053 BooleanModifierData *tbmd = (BooleanModifierData*) target; 00054 00055 tbmd->object = bmd->object; 00056 tbmd->operation = bmd->operation; 00057 } 00058 00059 static int isDisabled(ModifierData *md, int UNUSED(useRenderParams)) 00060 { 00061 BooleanModifierData *bmd = (BooleanModifierData*) md; 00062 00063 return !bmd->object; 00064 } 00065 00066 static void foreachObjectLink( 00067 ModifierData *md, Object *ob, 00068 void (*walk)(void *userData, Object *ob, Object **obpoin), 00069 void *userData) 00070 { 00071 BooleanModifierData *bmd = (BooleanModifierData*) md; 00072 00073 walk(userData, ob, &bmd->object); 00074 } 00075 00076 static void updateDepgraph(ModifierData *md, DagForest *forest, 00077 struct Scene *UNUSED(scene), 00078 Object *UNUSED(ob), 00079 DagNode *obNode) 00080 { 00081 BooleanModifierData *bmd = (BooleanModifierData*) md; 00082 00083 if(bmd->object) { 00084 DagNode *curNode = dag_get_node(forest, bmd->object); 00085 00086 dag_add_relation(forest, curNode, obNode, 00087 DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Boolean Modifier"); 00088 } 00089 } 00090 00091 #ifdef WITH_MOD_BOOLEAN 00092 static DerivedMesh *get_quick_derivedMesh(DerivedMesh *derivedData, DerivedMesh *dm, int operation) 00093 { 00094 DerivedMesh *result = NULL; 00095 00096 if(derivedData->getNumFaces(derivedData) == 0 || dm->getNumFaces(dm) == 0) { 00097 switch(operation) { 00098 case eBooleanModifierOp_Intersect: 00099 result = CDDM_new(0, 0, 0); 00100 break; 00101 00102 case eBooleanModifierOp_Union: 00103 if(derivedData->getNumFaces(derivedData)) result = derivedData; 00104 else result = CDDM_copy(dm); 00105 00106 break; 00107 00108 case eBooleanModifierOp_Difference: 00109 result = derivedData; 00110 break; 00111 } 00112 } 00113 00114 return result; 00115 } 00116 00117 static DerivedMesh *applyModifier(ModifierData *md, Object *ob, 00118 DerivedMesh *derivedData, 00119 int UNUSED(useRenderParams), 00120 int UNUSED(isFinalCalc)) 00121 { 00122 BooleanModifierData *bmd = (BooleanModifierData*) md; 00123 DerivedMesh *dm; 00124 00125 if(!bmd->object) 00126 return derivedData; 00127 00128 dm = bmd->object->derivedFinal; 00129 00130 if(dm) { 00131 DerivedMesh *result; 00132 00133 /* when one of objects is empty (has got no faces) we could speed up 00134 calculation a bit returning one of objects' derived meshes (or empty one) 00135 Returning mesh is depended on modifieier's operation (sergey) */ 00136 result = get_quick_derivedMesh(derivedData, dm, bmd->operation); 00137 00138 if(result == NULL) { 00139 result = NewBooleanDerivedMesh(dm, bmd->object, derivedData, ob, 00140 1 + bmd->operation); 00141 } 00142 00143 /* if new mesh returned, return it; otherwise there was 00144 * an error, so delete the modifier object */ 00145 if(result) 00146 return result; 00147 else 00148 modifier_setError(md, "Can't execute boolean operation."); 00149 } 00150 00151 return derivedData; 00152 } 00153 #else // WITH_MOD_BOOLEAN 00154 static DerivedMesh *applyModifier(ModifierData *UNUSED(md), Object *UNUSED(ob), 00155 DerivedMesh *derivedData, 00156 int UNUSED(useRenderParams), 00157 int UNUSED(isFinalCalc)) 00158 { 00159 return derivedData; 00160 } 00161 #endif // WITH_MOD_BOOLEAN 00162 00163 static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(md)) 00164 { 00165 CustomDataMask dataMask = CD_MASK_MTFACE | CD_MASK_MEDGE; 00166 00167 dataMask |= CD_MASK_MDEFORMVERT; 00168 00169 return dataMask; 00170 } 00171 00172 00173 ModifierTypeInfo modifierType_Boolean = { 00174 /* name */ "Boolean", 00175 /* structName */ "BooleanModifierData", 00176 /* structSize */ sizeof(BooleanModifierData), 00177 /* type */ eModifierTypeType_Nonconstructive, 00178 /* flags */ eModifierTypeFlag_AcceptsMesh 00179 | eModifierTypeFlag_UsesPointCache, 00180 00181 /* copyData */ copyData, 00182 /* deformVerts */ NULL, 00183 /* deformMatrices */ NULL, 00184 /* deformVertsEM */ NULL, 00185 /* deformMatricesEM */ NULL, 00186 /* applyModifier */ applyModifier, 00187 /* applyModifierEM */ NULL, 00188 /* initData */ NULL, 00189 /* requiredDataMask */ requiredDataMask, 00190 /* freeData */ NULL, 00191 /* isDisabled */ isDisabled, 00192 /* updateDepgraph */ updateDepgraph, 00193 /* dependsOnTime */ NULL, 00194 /* dependsOnNormals */ NULL, 00195 /* foreachObjectLink */ foreachObjectLink, 00196 /* foreachIDLink */ NULL, 00197 /* foreachTexLink */ NULL, 00198 };