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